	TITLE	GLASSTTY
	PAGE	60,131

; Test driver for COM_PKG2 -- dumb terminal emulator program of sorts
; Calls all the entry points
; Exit with control-break
; May be copied and used freely -- This is a public domain program
; Programmed by Richard Gillmann
; Please send all comments to GILLMANN@USC-ISIB.ARPA

STACK   SEGMENT PARA STACK 'STACK'
        DW      100 DUP(0)	; WORDS RESERVED FOR RUNTIME STACK
STACK   ENDS

DATA    SEGMENT PARA PUBLIC 'DATA'
PORT	DB	1		; CURRENT PORT (COM1 OR COM2)
DATA    ENDS
        PAGE
CODE    SEGMENT PARA PUBLIC 'CODE'

; INTERFACE TO THE COM_PKG2 ASYNCHRONOUS COMMUNICATIONS PACKAGE
	EXTRN	SELECT_PORT:NEAR ; SELECT ACTIVE PORT
	EXTRN	SAVE_COM:NEAR	 ; SAVE OLD INTERRUPT VECTOR
        EXTRN   INSTALL_COM:NEAR ; INSTALL INTERRUPT VECTOR
        EXTRN   RESTORE_COM:NEAR ; RESTORE OLD INTERRUPT VECTOR
        EXTRN   OPEN_COM:NEAR	; RE-INITIALIZE PORT
        EXTRN   CLOSE_COM:NEAR	; TURN OFF INTERRUPTS FROM PORT
        EXTRN   DTR_OFF:NEAR	; TURN OFF DTR
        EXTRN   DTR_ON:NEAR	; TURN ON DTR
        EXTRN   R_COUNT:NEAR	; RETURN NO. OF CHARACTERS IN INPUT BUFFER
        EXTRN   RECEIVE:NEAR	; READ NEXT CHARACTER IN INPUT BUFFER
        EXTRN   S_COUNT:NEAR	; RETURN NO. OF FREE BYTES IN OUTPUT BUFFER
        EXTRN   SEND:NEAR	; WRITE A CHARACTER TO OUTPUT BUFFER
	EXTRN	SENDI:NEAR	; SEND IMMEDIATE
        EXTRN   S_LOCAL:NEAR	; WRITE A CHARACTER TO THE INPUT BUFFER
        EXTRN   BREAK:NEAR	; SEND A BREAK
	EXTRN	COM_ERRORS:NEAR	; RETURN POINTER TO ERROR COUNTS
	PAGE
        ASSUME  CS:CODE,SS:STACK,DS:DATA
START	PROC	FAR
	PUSH	DS		; SAVE PREFIX SEGMENT
	MOV	AX,0		; ZERO OFFSET IN IT
	PUSH	AX		; IS WHERE INT 20H IS LOCATED
	MOV	AX,DATA		; OUR DATA SEGMENT
	MOV	DS,AX		; TO DS
	MOV	AL,1		; COM1
	CALL	SELECT_PORT	; SELECT IT
	CALL	SAVE_COM	; SAVE OLD INTERRUPT VECTOR
	CALL	INSTALL_COM	; INSTALL INTERRUPT VECTOR
	JC	OOPS1		; JUMP IF ERROR
	MOV	AX,1200		; BAUD RATE
	MOV	BH,'D'		; MODEM OR DIRECT
	MOV	BL,'N'		; NO PARITY
	MOV	CH,'1'		; ONE STOP BIT
	MOV	CL,'E'		; FLOW CONTROL
	CALL	OPEN_COM	; INIT COM
OOPS1:	MOV	AL,2		; COM2
	CALL	SELECT_PORT	; SELECT IT
	CALL	SAVE_COM	; SAVE OLD INTERRUPT VECTOR
	CALL	INSTALL_COM	; INSTALL INTERRUPT VECTORS
	JC	OOPS2		; JUMP IF ERROR
	MOV	AX,1200		; BAUD RATE
	MOV	BH,'D'		; MODEM OR DIRECT
	MOV	BL,'N'		; NO PARITY
	MOV	CH,'1'		; ONE STOP BIT
	MOV	CL,'E'		; FLOW CONTROL
	CALL	OPEN_COM	; INIT COM
OOPS2:	MOV	AL,PORT		; CURRENT PORT
	CALL	SELECT_PORT	; SELECT IT
	CALL	DTR_ON		; NOT NECESSARY BUT WHAT THE HECK
; PRINT HERALD
	MOV	AL,'!'		; I'M GONNA SIT RIGHT DOWN AND WRITE MYSELF A
	CALL	S_LOCAL		; LETTER AND MAKE BELIEVE IT CAME FROM YOU
; SEND A CARRIAGE RETURN
	MOV	AL,13		; CARRIAGE RETURN
	CALL	SENDI		; SEND IMMEDIATE JUST THIS ONCE
; MAIN LOOP
TOP:	MOV	AH,1		; CHARACTER TYPED?
	INT	16H		; BIOS KBD
	JZ	NOKEY		; JUMP IF NOT
	MOV	AH,0		; READ CHAR TYPED
	INT	16H		; BIOS KBD
	OR	AX,AX		; CONTROL BREAK?
	JZ	OUT		; EXIT IF SO
	CMP	AX,4400H	; F10?
	JNE	NOT_F10		; JUMP IF NOT
	MOV	AL,3		; 3
	SUB	AL,PORT		; - PORT
	MOV	PORT,AL		; IS NEW PORT
	CALL	SELECT_PORT	; TOGGLE SELECTED PORT
	JMP	SHORT NOKEY	; CONTINUE
NOT_F10:CMP	AX,4300H	; F9?
	JNE	NOT_F9		; JUMP IF NOT
	CALL	BREAK		; SEND A BREAK
	JMP	SHORT NOKEY	; CONTINUE
NOT_F9:	AND	AL,7FH		; STRIP PARITY
	JZ	NOKEY		; IGNORE NULS
	PUSH	AX		; SAVE CHAR
	CALL	S_COUNT		; GET COUNT OF FREE BUFFER SPACE
	CMP	AX,0		; TOO FULL?
	POP	AX		; RESTORE CHAR
	JE	NOKEY		; IF SO, PUNT
	CALL	SEND		; SEND CHAR
NOKEY:	CALL	R_COUNT		; GET READ BUFFER COUNT
	CMP	AX,0		; ANY CHARS RECEIVED?
	JZ	TOP		; LOOP IF NOT
	CALL	RECEIVE		; RECEIVE CHAR
	AND	AL,7FH		; STRIP PARITY
	JZ	TOP		; IGNORE NULS
	MOV	AH,14		; WRITE TTY
	INT	10H		; BIOS VIDEO
	JMP	TOP		; BACK FOR MORE
OUT:	MOV	AL,1		; COM1
	CALL	SELECT_PORT	; SELECT IT
	CALL	COM_ERRORS	; ERROR STATISTICS
	CALL	DTR_OFF		; HANG UP
	CALL	CLOSE_COM	; TURN OFF INTERRUPTS
	CALL	RESTORE_COM	; RESTORE VECTOR
	MOV	AL,2		; COM2
	CALL	SELECT_PORT	; SELECT IT
	CALL	COM_ERRORS	; ERROR STATISTICS
	CALL	DTR_OFF		; HANG UP
	CALL	CLOSE_COM	; TURN OFF INTERRUPTS
	CALL	RESTORE_COM	; RESTORE VECTOR
	RET			; DONE
START	ENDP
CODE	ENDS
	END	START
