	title	CONSOLE I/O ROUTINES for Lattice C programs -- CONIO.ASM
;*****************************************************************************
;
;     CONIO.ASM       (c) 1983 Knowledge Engineering, Inc.	CONIO.ASM
;
;	Assembled using:
;
;		masm conio conio nul.lst nul.crf
;
;*****************************************************************************
;
        subttl  IBM DOS ENTRY DEFINITIONS
	page
;
;       IBM DOS INTERRUPT CODES
;
DOS_FUNC equ	21h			;DOS function interrupt
DIR_CON	equ	07h			;Direct console input w/o echo
DIR_IO  equ	06h			;Direct i/o from keyboard
;
;	CONSTANTS
;
EOF	equ	-1			;EOF indicator
TRUE	equ	1
FALSE	equ	0
;
;	DATA SEGEMENT
;
dgroup	group	data
data	segment word public 'data'
	assume	ds:dgroup
	public	pushback
ch_ready db	FALSE			;TRUE if character pushed back
pushback db	0			;Character save for `ungetch'
data	ends
;
;
;
pgroup	group	prog
;
; Dynamic storage layout for user callable functions from Lattice C
;
dyns	struc
old_bp	dw	?			;Caller's BP save
retn	dw	?			;Return address from call
arg1	dw	?			;First argument
arg2	dw	?			;Second argument
dyns	ends
prog	segment	byte public 'prog'
	assume	cs:pgroup
        subttl  bdos call
        page
;
; NAME
;
;	kbhit -- check if character waiting at keyboard queue
;
; SYNOPSIS
;
;	iret = kbhit();
;	int iret;		non-zero if a character was typed,
;				zero otherwise
;
; DESCRIPTION
;
;	Returns a non-zero if a character is waiting in the input queue,
;	otherwise a zero is returned.
;
;	This function first checks to see if a character has been pushed back
;	via `ungetch', if so a non-zero is returned.  If a character has not
;	been pushed back, then the DOS function 0x6 is used to retrieve a
;	character from the keyboard.  If no character is waiting a zero is
;	returned, otherwise the character is passed to `ungetch' to push it
;	back returning a non-zero value.
;
;	DOS function 0x6 is used so that CTRL-P, CTRL-Q, CTRL-S, CTRL-C, and
;	(for the IBM-PCs) CTRL-BREAK will not be trapped by MS-DOS.
;
; RETURNS
;
;	iret = non-zero if a character has been entered at the keyboard and
;	       not read, otherwise a zero is returned.
;
; CAUTIONS
;
;	A character cannot be pushed back via `ungetch' if a character is
;	ready at the keyboard and this has been acknowledged by `kbhit'
;	because the variable `pushback' will already have character stored
;	from the `kbhit' routine.
;
; SEE ALSO
;
;	getch(), ungetch()
;
; AUTHOR
;
;	James A. McLaughlin
;
	public	kbhit
kbhit	proc    near
	push	bp
	mov	bp,sp
	cmp	ch_ready,TRUE		;See if a char has been pushed back
	je	kb_ready
	mov	ah,DIR_IO		;Do direct console I/O
	mov	dl,0ffh			;Get a character
	int	DOS_FUNC
	jz	kb_non			;Character is not ready
	xor	ah,ah
	push	ax			;Put character in `pushback'
	call	ungetch
	mov	sp,bp
kb_ready: mov	ax,1			;Character is ready
	jmp	kb_ex
kb_non:	xor	ax,ax			;Character not ready
kb_ex:	pop	bp
	ret
kbhit	endp
;
; NAME
;
;	getch -- get character directly from the console
;
; SYNOPSIS
;
;	c = getch();
;	int c;		chracter received from console
;
; DESCRIPTION
;
;	Gets a character from the console, first checking `ch_ready'
;	to see if a character has been pushed back, if so then the
;	character in `pushedback' is returned.  Otherwise a character
;	is read from the console.
;
; RETURNS
;
;	c = character received
;
; CAUTIONS
;
;	There is no notion of an end of file of error status.
;
; SEE ALSO
;
;	kbhit(), ungetch()
;
; AUTHOR
;
;	James A. McLaughlin
;
	public	getch
getch	proc	near
	push	bp
	mov	bp,sp
	cmp	ch_ready,TRUE		;See if a character is ready
	je	gt_ready
	mov	ah,DIR_CON		;Get character from keyboard
	int	DOS_FUNC
	jmp	gt_ex
gt_ready: mov	al,pushback		;Get character previously saved
	mov	ch_ready,FALSE		;Clear the ready flag
gt_ex:	xor	ah,ah			;Clear the high byte
	pop	bp
	ret
getch	endp
;
; NAME
;
;	ungetch -- push character back to console
;
; SYNOPSIS
;
;	iret = ungetch(c);
;	int r;		return code
;	char c;		character to be pushed back
;
; DESCRIPTION
;
;	Pushes the indicated character back on the console.  Only a
;	single level of pushback is allowed.  The effect is to cause
;	'getch' to return the pushed-back character next time it is
;	called or for `kbhit' to return a status that a character is
;	waiting.
;
;	`ch_ready' is used to indicate that a character is ready because
;	with the IBM-PC a character of value 0x0 (zero) is valid as a prefix
;	for functions keys.  Thus `pushback' could have a value of zero.
;
; RETURNS
;
;	iret = EOF if a character has already been pushed back
;	     = c if successful
;
; SEE ALSO
;
;	kbhit(), getch()
;
; AUTHOR
;
;	James A. McLaughlin
;
	public	ungetch
ungetch	proc	near
	push	bp
	mov	bp,sp
	cmp	ch_ready,FALSE		;See if a character already saved
	je	un_ch
	mov	ax,EOF			;Character already saved, return error
	jmp	un_ex
un_ch:	mov	ax,[bp].arg1		;Save character
	mov	pushback,al
	mov	ch_ready,TRUE
un_ex:	pop	bp
	ret
ungetch	endp
prog	ends
	end
