Listing 2.  Rudimentary version of the KEYIN utility for
filling the keyboard buffer in KEYBIOS.

; Program:		KEYIN
; Author:		Jay Sage
; Date:			October 1, 1991

; This program manages the keyboard inbut buffer in the
; special version of the NZCOM virtual BIOS called KEYBIOS.
; It interprets the command tail and adds the indicated
; input to the keyboard buffer (if it fits).

sigoff	equ	97H		; Offset to signature

cr	equ	0dh
lf	equ	0ah
bell	equ	07h
tab	equ	09h

; Library routines

	extrn	z3init, eprint

keyin:
	jp	start
	db	'Z3ENV'
	db	1
env:	dw	0		; Filled in by ZCPR33+
	dw	keyin		; For type-4 version

; Target signature that identifies KEYBIOS.

sign:	db	'KEYIN'		; KEYBIOS signature string
nsign	equ	$ - sign	; Length of signature

; Signon message

signon:
	call	eprint
	db	'KEYIN, version 1.1 (10/01/91)'
	db	cr,lf
	db	0
	ret

; Show help message.

help:
	call	eprint
	db	'  Syntax: KEYIN string',cr,lf
	db	0
	ret

; We get here if the signature is not right.  Report problem
; to user and terminate.

badbios:
	call	eprint
	db	'  KEYBIOS not present!',cr,lf
	db	0
	ret

start:

; Initialize environment

	ld	hl,(env)
	call	Z3init

; Display signon message

	call	signon

; See if there is a command tail.

	ld	hl,80h		; Point to tail buffer
	ld	a,(hl)		; Get count
	or	a		; Test for zero
	jr	z,help		; If zero, show help screen

; Make sure that the KEYBIOS is running by checking for the
; signature.

	ld	hl,(1)		; Get warmboot address
	ld	de,sigoff-3	; Offset to signature from
				; ..warmboot entry
	add	hl,de
	ld	de,sign		; Point to signature
	ld	b,nsign		; Length of signature
sigtest:
	ld	a,(de)
	cp	(hl)
	jr	nz,badbios	; Jump if no match
	inc	hl		; Bump pointers
	inc	de
	djnz	sigtest		; Test whole signature

; Now we are ready for the real task

	ld	a,(hl)		; Save the size of
	ld	(kbufsize),a	; .. the keyboard buffer
	inc	hl		; Point to pointer
	ld	(kptradr),hl	; Save its address
	ld	e,(hl)		; Get its value into DE
	inc	hl
	ld	d,(hl)
	inc	hl		; Point to start of buffer
	ld	(keybuf),hl	; Save the address

	ld	hl,buffer	; Point to working buffer
	ld	bc,0		; Initialize count

; Copy any remaining contents of keyboard buffer to working
; buffer

copy1:
	ld	a,(de)		; Get next character from
				; ..key buffer
	ld	(hl),a		; Write to working buffer
	or	a		; Set flag
	jr	z,copy2		; If null, break out of loop
	inc	de		; Otherwise bump pointers
	inc	hl
	inc	c		; Increment count
	jr	copy1		; Loop back for next char

; Now we have to add the new characters from the command
; line.  HL still points to working buffer. This code needs
; to be extended with the full functionality of ECHO.COM so
; that control characters and other special characters (such
; as semicolons) can be entered.

copy2:
	ld	de,82h		; Point to second char (if
				; ..any) in command tail
copy2a:
	ld	a,(de)		; Get the character
	ld	(hl),a		; Store it in working buffer
	or	a		; Set flag
	jr	z,fillkey	; If null, we're done
	inc	de		; Otherwise, bump pointers
	inc	hl
	inc	c		; Increment the count
	jr	z,overflow	; If we reach zero,
				; ..definitely too many
	jr	copy2a		; Else loop back for more

; Now we have to copy the contents of the work buffer back
; into the keyboard input buffer.

fillkey:
	ld	a,(kbufsize)	; Make sure there is room
	cp	c
	jr	c,overflow	; Too many characters

	ld	de,(keybuf)	; Get start of buffer
	ld	hl,(kptradr)	; Address of pointer
	ld	(hl),e		; Set pointer to beginning
	inc	hl
	ld	(hl),d
	ld	hl,buffer	; Point to working buffer
	inc	bc		; Adjust counter to include
				; ..trailing null
	ldir			; Copy it all
	ret			; We're done

; We get here if the keyboard buffer is too small to hold
; all the characters. For the moment we just give a message,
; but the code should call the error handler if possible. If
; there is no error handler, then the MCL should probably be
; cleared.

overflow:
	call	eprint
	db	'Too many characters for '
	db	'keyboard input buffer.'
	db	cr,lf
	db	0
	ret

; Data items

	dseg

kbufsize:	ds	1	; Size of keyboard buffer
kptradr:	ds	2	; Address of next-char ptr
keybuf:		ds	2	; Address of beg of buffer
buffer:		ds	257	; Working buffer

	end
                                                   