/*  checkx.c -- direct bios input/output without bdos interaction
 *              plus other operating system dependent functions
 */

/*  copyright (c) 1986 by Jim Woolley and WoolleyWare, San Jose, CA          */

/*  vers. 1.0, 12/85 thru 4/86
 *
 *  vers. 1.2, 8/86
 *  getchar(): add _Keymap, _Leadin, _Funkey, _Newkey, and _Savech
 */

/*  this file contains:
 *      getchar()
 *      char ungetch( c)
 *      putchar( c)
 *      puts( s)
 *      setlst()
 *      resetlst()
 *      kbhit()
 *      resetdsk()
 *      defdsk()
 *  for use with the check register program
 */

#include    "a:checks.h"                /*  see this file for further info   */

getchar()                               /*  substitute for library function  */
{
    char c;
    int i, j, n;

    if ( _Lastch)
    {
        c = _Lastch;
        _Lastch = 0;
        return ( c);
    }    
    if ( _Savech[ 0])
    {
        c = _Savech[ 0];
        _Savech[ 0] = _Savech[ 1];
        _Savech[ 1] = 0;
        return ( c);
    }
    if (( c = bios( 3)) < 32)           /*  direct keyboard input            */
        c = _Keymap[ c];                /*  translate CTRL key               */
    if ( c == _Leadin || c == ESC)      /*  check for _Funkey or BackTAB     */
    {
        _Savech[ 1] = 0;                /*  match when _Funkey[ n][ 1] = 0   */
        for ( j = 0; j < 2; ++j)
        {
            for ( i = Dloop; i && !kbhit(); --i)
                continue;               /*  wait up to 0.1 sec for key       */
            if ( !i)                    /*  if no key                        */
                break;                  /*  no match                         */
            else if (( _Savech[ j] = bios( 3)) < 32)
                _Savech[ j] = _Keymap[ _Savech[ j]];
            if ( c != _Leadin)
                break;                  /*  possible BackTAB                 */
            for ( n = 0; n < 10; ++n)
            {
                if ( _Savech[ 0] == _Funkey[ n][ 0] &&
                     _Savech[ 1] == _Funkey[ n][ 1])
                {
                    j = 1;              /*  force end of j loop              */
                    break;              /*  matched _Funkey[ n]              */
                }
                if ( n == 10)           /*  if tried all                     */
                    break;              /*  no match                         */
            }
        }
        if ( j == 2)                    /*  if matched                       */
        {
            c = _Newkey[ n][ 0];
            _Savech[ 0] = _Newkey[ n][ 1];
            _Savech[ 1] = 0;
        }
        else if ( c == ESC && _Savech[ 0] == 'I')
        {
            c = CTRLA;                  /*  BackTAB                          */
            _Savech[ 0] = 0;
        }
    }
    return ( c);
}

char ungetch( c)                        /*  substitute for library function  */
char c;
{
    char a;

    a = _Lastch;
    _Lastch = c;
    return ( a);
}

putchar( c)                             /*  substitute for library function  */
char c;  
{
    if ( c == '\n')
        bios( _Outdev, CR);             /*  _Outdev is CONOUT or LSTOUT      */
    bios( _Outdev, c);
}

puts( s)                                /*  display string                   */
char *s;
{
    while ( *s)
        putchar( *s++);
}

setlst()                                /*  optionally redirect to printer   */
{                                       /*  return TRUE if redirected        */
                                        /*  else, return FALSE               */
    prompt(
"Press RETURN when printer is ready, or any other key to abandon print function"
           );
    if ( getchar() == CR)
    {
        prompt( "Printing ... ");
        Printing = TRUE;
        _Outdev = LSTOUT;               /*  direct putchar() to printer      */
        return ( TRUE);
    }
    else return ( FALSE);
}

resetlst()                              /*  redirect from list to console    */
{
    if ( Printing)
    {
        putchar( '\n');
        putchar( FF);
        Printing = FALSE;
    }
    _Outdev = CONOUT;                   /*  redirect putchar() to screen     */
}

kbhit()                                 /*  return TRUE if key pressed       */
{                                       /*  else, return FALSE               */
    return ( bios( 2));
}

resetdsk()                              /*  reset & reselect default disk    */
{
    int d;

    d = defdsk();                       /*  get default disk                 */
    bdos( 13, 0);                       /*  reset disk system                */
    bdos( 14, d);                       /*  reselect default disk            */
}

defdsk()                                /*  return default disk number       */
{
    return ( bdos( 25, 0) & 0x0f);      /*  result will be 0 thru 15         */
}
