/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 16-Nov-85 | [1.56] Created
* 23-Nov-85 | [1.91] Wait for mouse cursor up; hide mouse cursor during bit
*           | flip
* 11-Dec-85 | [1.164] ^L refreshes screen
* 11-Jan-86 | [1.290] Handle user hitting function keys...support mouseless
*           | system
* 11-Jan-86 | [1.296] No longer avoid getkey when running
* 23-Jan-86 | [1.305] Introduce read_keyboard_char to handle cursor in
*           | non-mouse mode
* 23-Jan-86 | [1.306] Recognize ^C in scan loop
* 23-Feb-86 | [1.367] include <> => include ""
* 29-Jul-86 | [1.385] Added C-P option to do screen dump
*-----------+-----------------------------------------------------------------
* 31-Jul-86 | [1.405] Cloned keyboard routines from ENTER.C
* 31-Jul-86 | [1.405] Support ^S pausing, allow ^S or ^Q to re-enable
* 31-Jul-86 | [1.405] Made char variable unsigned
*  6-Aug-86 | [1.410] utrdykey cast arg 1 to char
*  6-Aug-86 | [1.410] Call dokey with correct arg
*  6-Aug-86 | [1.410] Undid utrdykey change because of error
*           | kbd.c 70 Warning 94: uninitialized auto variable "pch"
* 18-Aug-86 | [1.415] utinkey -> kbin; use bkeybd.h as well
* 18-Aug-86 | [1.415] utrdykey -> kbready
*  7-Dec-91 | [1.475] <jmn> use new keybindings structure
* 23-Dec-91 | [1.521] <jmn> added pragmas for check_stack
* 23-Dec-91 | [1.545] <jmn> added 'about' call on ?
*****************************************************************************/


/*****************************************************************************
				1401 Simulation

			      PC keyboard polling module

This module handles the mouseless mode of the simulator by polling the
keyboard

*****************************************************************************/

#include "boolean.h"
#include "conio.h"
#include "mouse.h"

#include "btypes.h"

#include "stdio.h"
#include "keys.h"
#include "diag.h"
#include "kb.h"
#include "scan.h"
#include "display.h"
#include "pr.h"
#include "print.h"
#include "button.h"
#include "printers.h"
#include "1401.h"

extern boolean mousing;
extern int lastkey;
extern boolean tracking;
extern boolean color_printer;

extern void get_keyboard_char();

static boolean pause_mode;

/****************************************************************************
*                                    iskey
* Result: boolean
*       true if keyboard input pending
*	false if not pending
* Effect:
*       Uses the BIOS call for higher performance; does it as inline
*	ASM for fastest performance (this performance really affects
*	the inner loop time!)
****************************************************************************/

#ifndef __BORLANDC__
#pragma check_stack(off)
boolean iskey()
    {

    int silly;

     _asm {
	   mov ah,1;
	   int 0x16;
	   jz  none;
	   mov ax,1;
	   jmp done;
    none:  mov ax,0;
    done:  ;

	  }
    }
#pragma check_stack(on)
#endif

#ifdef __BORLANDC__

/* #pragma inline */

boolean iskey()
{

	asm {
		mov ah,1;
		int 0x16;
		jz  none;
		mov ax,1;
		jmp done;
	}
	none:
	   asm	mov ax,0;
	done:	;

}
#endif

/****************************************************************************
*                                    ctlp
* Result: void
*
* Effect:
*       Handles ^P (print screen) requests
****************************************************************************/

void ctlp()
    {
     if(!color_printer)
	return;
     dump_color_screen(current_printer);
     lastkey = 0;
    }

/****************************************************************************
*                                    ctlc
* Result: void
*
* Effect:
*       Sets KEYHALT
****************************************************************************/

void ctlc(void)
    {
     lastkey = KEYHALT;
    }

/****************************************************************************
*                                    ctlq
* Result: void
*
* Effect: 
*       Sets pause mode
****************************************************************************/

void ctlq()
    {
     pause_mode = false;
    }

/****************************************************************************
*                                    ctls
* Result: void
*
* Effect: 
*       Releases pause mode
****************************************************************************/

void ctls()
    {
     if(!(diagnostics_on & display_on) ) 
	return;
     pause_mode = !pause_mode;
    }

/****************************************************************************
*                              read_keyboard_char
* Inputs:
*	keybindings * kb: key binding table
* Effect:
*	Read a keyboard character
*
*	Leave the character in 'lastkey'
****************************************************************************/

#ifndef __BORLANDC__
#pragma check_stack(off)
#endif

void read_keyboard_char(keybindings * kb)
    {
     unsigned char pch;
     int scan;
     int key;
     boolean old_pause_mode = pause_mode;

     pause_mode = false;

     do
	{ /* read keyboard */

	 if(iskey())
	    { /* hit key */

	     key = getch();

	     if(key == '\0')
		{ /* scan code */
		 dokey((unsigned char) getch(),kb);
		 pause_mode = old_pause_mode;
		 return;
		} /* scan code */

	     if(key < ' ' && kb != NULL)
		{ /* control char */
		 if(kb->ctl[key] != NULL)
		    { /* callable */
		     (*kb->ctl[key])();
		    } /* callable */
		 return;
		} /* control char */
	     if(key == '?')
		{ /* about */
		 about();
		 return;
		} /* about */

	     clear_off();

	    } /* hit key */
	} /* read keyboard */
	 while(pause_mode);
     pause_mode = old_pause_mode;
    }

#ifndef __BORLANDC__
#pragma check_stack(on)
#endif

/****************************************************************************
*                              get_keyboard_char
* Inputs:
*	keybindings * kb:
* Effect:
*       Reads the keyboard and takes appropriate action
*	If not mousing, handle cursor movement properly
****************************************************************************/

#pragma check_stack(off)
void get_keyboard_char(keybindings * kb)
    {
     read_keyboard_char(kb);
    }
#pragma check_stack(on)
