
	PAGE	,132
	TITLE	DOS KEYB Command  -  Interrupt 9 (US support)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DOS - NLS Support - KEYB Command
;; (C) Copyright 1988 Microsoft
;;
;; File Name:  KEYBI9C.ASM
;; ----------
;;
;; Description:
;; ------------
;;	 Interrupt 9 mainline.
;;	 This routine handles all US keyboard support for the following
;;	 system units: PCjr, PC, PCXT, PCAT, PALACE, ROUNDUP, PC Convertible
;;	 KEYB_STATE_PROCESSOR is called for non-US keyboard support.
;;
;;
;; Documentation Reference:
;; ------------------------
;;	 PC DOS 3.3 Detailed Design Document - May 1986
;;
;; Procedures Contained in This File:
;; ----------------------------------
;;	 KEYB_INT_9 - Interrupt 9
;;
;; External Procedure References:
;; ------------------------------
;;	 FROM FILE  KEYBI9.ASM:
;;	      KEYB_STATE_PROCESSOR - Non US keyboard support.
;;
;; Linkage Information:  Refer to file KEYB.ASM
;; --------------------
;;
;; Change History:
;; ---------------
;; ;AN001; - DCR 478 - KEYBOARD INT SPLICING NickS
;; ;AN002; - PTM 3090  ENABLING RIGHT CTL FOR RE-BOOTING
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
	INCLUDE KEYBEQU.INC	       ;;
	INCLUDE DSEG.inc	       ;; System data segments
	INCLUDE POSTEQU.inc	       ;; System equates
	INCLUDE KEYBSHAR.INC	       ;;
	INCLUDE KEYBI2F.INC	       ;;
	INCLUDE KEYBI9.INC	       ;;
	INCLUDE KEYBCPSD.INC	       ;;
	INCLUDE KEYBCMD.INC	       ;;
				       ;;
	PUBLIC KEYB_INT_9	       ;;
	PUBLIC K8		       ;; CTRL case tables
	PUBLIC BUFFER_FILL	       ;;
	PUBLIC COUNTRY_FLAG	       ;;
	PUBLIC BEEP_PENDING	       ;;
	PUBLIC SCAN_CODE	       ;;
	PUBLIC ERROR_BEEP	       ;;
	PUBLIC TEMP_HEAD	       ;;
	PUBLIC TEMP_TAIL	       ;;
	PUBLIC BUSY_TFLAG	       ;;
	PUBLIC MYBUFF		       ;;
	PUBLIC ENABLE_FL	       ;;
	PUBLIC NEW_BUFF_CTR	       ;;


ROM_SEG 	EQU	0F000H	       ;; BIOS ROM SEGMENT
PC1DATE_ID	EQU	03138H	       ;; YEAR ROM WAS RELEASED IN ASCII
SYSROM_DATE	EQU	0FFFBH	       ;; OFFSET OF ROM YEAR DIGIT
				       ;;
DIAGS	SEGMENT AT 0FFFFH	       ;;
	ORG	0		       ;;
RESET	LABEL	FAR		       ;;
DIAGS	ENDS			       ;;
				       ;;
				       ;;
				       ;;
CODE	SEGMENT PUBLIC 'CODE'          ;;
	ASSUME	CS:CODE,DS:DATA        ;;
				       ;;

;CNS***
	END_OF_BUFF	EQU	 16		 ;AN000;END OF TEMP BUFF VALUE
	ACTIVE_ON	EQU	-1		;AN000;
	ACTIVE_OFF	EQU	 0		;AN000;
	TEMP_HEAD	DW	 0		;AN000;
	TEMP_TAIL	DW	 0		;AN000;
	BUSY_TFLAG	DB	ACTIVE_OFF	;AN000;FLAG TO CHECK BUFFER ACTIVITY
	MYBUFF	DB	16 DUP(0)		;AN000;
	ENABLE_FL	DB	0			    ;NEW BUFFER TO BE USED
	NEW_BUFF_CTR	DB	0		;ON THE FRONT END OF THE
;CNS***


BEEP_PENDING	 DB    0	       ;;
BUFFER_ENTRY_OK  DB    0	       ;;
SCAN_CODE	 DB    0	       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;  TABLE OF SHIFT KEYS AND MASK VALUES
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
;------ KEY_TABLE		       ;;
K6	LABEL	BYTE		       ;;
	DB	INS_KEY 	       ;; INSERT KEY
	DB	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
	DB	LEFT_KEY,RIGHT_KEY     ;;
K6L	EQU	$-K6		       ;;
				       ;;
;------ MASK_TABLE		       ;;
K7	LABEL	BYTE		       ;;
	DB	INS_SHIFT	       ;; INSERT MODE SHIFT
	DB	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
	DB	LEFT_SHIFT,RIGHT_SHIFT ;;
				       ;;
;----------  TABLES FOR ALT CASE  -----;;
;------ ALT-INPUT-TABLE 	       ;;
K30	LABEL	BYTE		       ;;
	DB	82,79,80,81,75	       ;;
	DB	76,77,71,72,73	       ;; 10 NUMBERS ON KEYPAD
;------ SUPER-SHIFT-TABLE	       ;;
	DB	16,17,18,19,20,21      ;; A-Z TYPEWRITER CHARS
	DB	22,23,24,25,30,31      ;;
	DB	32,33,34,35,36,37      ;;
	DB	38		       ;;
	DB	44,45,46,47,48,49      ;;
	DB	50		       ;;
K30_LEN 	EQU	$-K30-10       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; K8 is overlaid by K8_RPL (from module KEYB_COMMAND)
;; if extended INT 16 support is available
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
K8	LABEL	BYTE		       ;;-------- CHARACTERS ---------
	DB	27,-1,00,-1,-1,-1      ;; Esc, 1, 2, 3, 4, 5
	DB	30,-1,-1,-1,-1,31      ;; 6, 7, 8, 9, 0, -
	DB	-1,127,-1,17,23,5      ;; =, Bksp, Tab, Q, W, E
	DB	18,20,25,21,09,15      ;; R, T, Y, U, I, O
	DB	16,27,29,10,-1,01      ;; P, [, ], Enter, Ctrl, A
	DB	19,04,06,07,08,10      ;; S, D, F, G, H, J
	DB	11,12,-1,-1,-1,-1      ;; K, L, ;, ', `, LShift
	DB	28,26,24,03,22,02      ;; \, Z, X, C, V, B
	DB	14,13,-1,-1,-1,-1      ;; N, M, ,, ., /, RShift
	DB	'*',-1,' ',-1          ;; *, Alt, Space, CL
				       ;;--------- FUNCTIONS ---------
	DB	94,95,96,97,98,99      ;; F1 - F6
	DB	100,101,102,103,-1,-1  ;; F7 - F10, NL, SL
	DB	119,-1,132,-1,115,-1   ;; Home, Up, PgUp, -, Left, Pad5
	DB	116,-1,117,-1,118,-1   ;; Right, +, End, Down, PgDn, Ins
	DB	-1,-1,-1,-1,137,138    ;; Del, SysReq, Undef, WT, F11, F12
PAGE				       ;;
;-----	TABLES FOR LOWER CASE (USA)  --;;
				       ;;
K10	LABEL	BYTE		       ;;
	DB	27,'12345'             ;;
	DB	'67890-'               ;;
	DB	'=',08,09,'qwe'        ;;
	DB	'rtyuio'               ;;
	DB	'p[]',0DH,-1,'a'       ;; LETTERS, Return, Ctrl
	DB	'sdfghj'               ;;
	DB	"kl;'`",-1             ;; LETTERS, L Shift
	DB	'\zxcvb'               ;;
	DB	'nm,./'                ;;
	DB	-1,'*',-1,' \'         ;; R Shift, *, Alt, Sp, CL (REALLY WT KEY)
				       ;;
;------ LC TABLE SCAN		       ;;
	DB	59,60,61,62,63	       ;; BASE STATE OF F1 - F10
	DB	64,65,66,67,68	       ;;
	DB	-1,-1		       ;; NL, SL
				       ;;
;------ KEYPAD TABLE		       ;;
K15	LABEL	BYTE		       ;;
	DB	71,72,73,-1,75,-1      ;; BASE STATE OF KEYPAD KEYS
	DB	77,-1,79,80,81,82      ;;
	DB	83		       ;;
	DB	-1,-1,'\',133,134      ;; SysRq, Undef, WT, F11, F12
				       ;;
;-------  TABLES FOR UPPER CASE (USA)  ;;
				       ;;
K11	LABEL	BYTE		       ;;
	DB	27,'!@#$%'             ;;
	DB	'^&*()_'               ;;
	DB	'+',08,00,'QWE'        ;;
	DB	'RTYUIO'               ;;
	DB	'P{}',0DH,-1,'A'       ;; LETTERS, Return, Ctrl
	DB	'SDFGHJ'               ;;
	DB	'KL:"~',-1             ;; LETTERS, L Shift
	DB	'|ZXCVB'               ;;
	DB	'NM<>?'                ;;
	DB	-1,'*',-1,' |'         ;; R Shift, *, Alt, Sp, CL (REALLY WT KEY)
				       ;;
;------ UC TABLE SCAN		       ;;
K12	LABEL	BYTE		       ;;
	DB	84,85,86,87,88	       ;; SHIFTED STATE OF F1 - F10
	DB	89,90,91,92,93	       ;;
	DB	-1,-1		       ;; NL, SL
				       ;;
;------ NUM STATE TABLE 	       ;;
K14	LABEL	BYTE		       ;;
	DB	'789-456+1230.'        ;; NUMLOCK STATE OF KEYPAD KEYS
	DB	-1,-1,'|',135,136      ;; SysRq, Undef, WT, F11, F12
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: KEYB_INT_9
;;
;; Description:
;;     Entry point for interrupt 9 processing.
;;
;; Input Registers:
;;     None
;;
;; Output Registers:
;;     None
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
KEYB_INT_9    PROC   NEAR	       ;;
	JMP	KB_INT_1	; THIS JUMP AND ENSUING BYTE MUST BE HERE TO BE
 COUNTRY_FLAG	 DB	 -1	;  COMPATIBLE WITH APL.  APL WILL FORCE THIS
				;  BYTE TO BE ZERO, ONLY BECAUSE IT'S 3 BYTES
KB_INT_1:			;  AWAY FROM WHERE THE INT9 VECTOR POINTS

;    PUSH    DS 		 ;ICE
;    push    bx 		     ;ICE
;    push    ax 		     ;ICE
;    mov     bx,0140H		     ;ICE
;    xor     ax,ax		     ;ICE
;    mov     ds,ax		     ;ICE
;    mov     ax,word ptr ds:[bx]     ;ICE
;    mov     word ptr ds:[bx],ax     ;ICE
;    POP     ax 		     ;ICE
;    pop     bx 		     ;ICE
;    pop     ds 		     ;ICE

	PUSH	BP
	PUSH	AX
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	SI
	PUSH	DI
	PUSH	DS
	PUSH	ES
	STI			; ENABLE INTERRUPTS
	CLD				; FORWARD DIRECTION

	MOV	BX,DATA 		; SET UP ADDRESSING
	MOV	DS,BX		       ;; DS POINTS AT THE
	MOV	CS:BEEP_PENDING,NO     ;; ROM DATA AREA
	MOV	CS:BUFFER_ENTRY_OK,NO  ;; INITIALIZE ALL FLAGS
;***CNS 			       ;; FOR LOADING AND UNLOADING THE
	CMP	CS:BUSY_TFLAG,ACTIVE_ON
	JE	NO_INIT

	MOV	DI,OFFSET CS:MYBUFF
	MOV	CS:TEMP_HEAD,DI
	MOV	CS:TEMP_TAIL,DI
	MOV	CS:ENABLE_FL,0
;	MOV	CS:NEW_BUFF_CTR,0	  ;;CLEAR OUT NEW BUFFER CTR
;***CNS
				       ;; BUFFER
NO_INIT:
;------- TEST SYSTEM TYPE			 ;CHECK TO SEE IF THE SYSTEM IS
						 ;NEW ******



	TEST	CS:SD.SYSTEM_FLAG,PC_AT+PC_386	  ; IF THE SYSTEM WE'RE RUNNING ON IS A
	JNZ	KB_INT_00			  ;  PC3, THEN DO PC3 CODE

;------ PC1, XT, HOME COMPUTER POST CODE

	TEST   CS:SD.SYSTEM_FLAG,PC_JR	  ;; Q..PCjr?
	JZ     READ_CHAR_PORT	       ;; N..go read port
	MOV    BL,CS:SD.JR_KB_FLAG     ;; Its a JR so incorporate flag bits
	OR     KB_FLAG,BL	       ;;  from INT 48 preprocessor
	MOV    CS:SD.JR_KB_FLAG,0      ;; Clear JR KB_Flag
	JMP    UP1MORE;UP1		       ;; Skip to key processing
EVEN				       ;;
READ_CHAR_PORT: 		       ;;
	IN	AL,KB_DATA	       ;; READ IN THE CHARACTER
				       ;; FOR PC, XT, P12: RESET THE KEYBOARD
	TEST	CS:SD.SYSTEM_FLAG,PC_XT+PC_LAP
	JZ	SYSTEM_HOOK	       ;;
	PUSH	AX			; SAVE IT
	IN	AL,KB_CTL		; GET THE CONTROL PORT
	MOV	AH,AL			; SAVE VALUE
	OR	AL,80H			; RESET BIT FOR KEYBOARD
	OUT	KB_CTL,AL
	XCHG	AH,AL			; GET BACK ORIGINAL CONTROL
	OUT	KB_CTL,AL		; KB HAS BEEN RESET
	POP	AX			; GET SCAN CODE BACK		   RWV 11-06-85

;-----	SYSTEM HOOK  INT 15H - FUNCTION 4FH  (ON HARDWARE INTERRUPT LEVEL 9H)

SYSTEM_HOOK:			       ;;
	MOV	AH,04FH 		; SYSTEM INTERCEPT - KEY CODE FUNCTION
	STC				; SET CY= 1 (IN CASE OF IRET)
	INT	15H			; CASSETTE CALL   (AL)= KEY SCAN CODE
					;  RETURNS CY= 1 FOR INVALID FUNCTION
	STI				; MAKE SURE INT'S STAY ENABLED     RWV 11-11-85
	JC	UP1MORE 		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
	JMP	PREP_EXIT		      ; EXIT IF SYSTEM HANDLED SCAN CODE
					;  EXIT HANDLES HARDWARE EOI AND ENABLE

UP1MORE:


	CALL	DUMBJMP
	JMP	EXIT_CHK



;------ PCAT POST CODE

;------ WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
KB_INT_00:
	MOV	AL,DIS_KBD		; DISABLE THE KEYBOARD COMMAND
	CALL	SHIP_IT 		; EXECUTE DISABLE
	CLI				; DISABLE INTERRUPTS
;	 SUB	 CX,CX			 ; SET MAXIMUM TIMEOUT
;KB_INT_01:
;	 IN	 AL,STATUS_PORT 	 ; READ ADAPTER STATUS
;	 TEST	 AL,INPT_BUF_FULL	 ; CHECK INPUT BUFFER FULL STATUS BIT
;	 LOOPNZ  KB_INT_01		 ; WAIT FOR COMMAND TO BE ACCEPTED
				       ;;
	CALL   WAIT_ON_STATUS_PORT     ;;

;-----	READ CHARACTER FROM KEYBOARD INTERFACE



	IN	AL,PORT_A	       ;;AN000;GET SCAN CODE VALUE FROM PORT 60H

;   PUSH    DS			    ;ICE
;   push    bx			    ;ICE
;   push    ax			    ;ICE
;   mov     bx,0140H		    ;ICE
;   xor     ax,ax		    ;ICE
;   mov     ds,ax		    ;ICE
;   mov     ax,word ptr ds:[bx]     ;ICE
;   mov     word ptr ds:[bx],ax     ;ICE
;   POP     ax			    ;ICE
;   pop     bx			    ;ICE
;   pop     ds			    ;ICE

;-----	SYSTEM HOOK  INT 15H - FUNCTION 4FH  (ON HARDWARE INTERRUPT LEVEL 9H)

	MOV	AH,04FH 		; SYSTEM INTERCEPT - KEY CODE FUNCTION
	STC				; SET CY= 1 (IN CASE OF IRET)
	INT	15H			; CASSETTE CALL   (AL)= KEY SCAN CODE
					;  RETURNS CY= 1 FOR INVALID FUNCTION
	JC	LOAD_TBUFF		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
	JMP	PREP_EXIT		      ; EXIT IF SYSTEM HANDLED SCAN CODE
					;  EXIT HANDLES HARDWARE EOI AND ENABLE



LOAD_TBUFF:

	CMP	CS:NEW_BUFF_CTR,END_OF_BUFF+1	      ;;AN000;CHECK TO SEE IF THE SECONDARY BUFFER IS FULL
	JB	LOAD_CHAR

;***CNS
	PUSH	DI				      ;;
	PUSH	AX				      ;;
	CALL	CLEAR_BUFFER			      ;;CLEAR OUT NEW BUFFER
	POP	AX				      ;;
	POP	DI				      ;;
	MOV	CS:TEMP_HEAD,DI        ;;AN000;RESET POINTER BACK TO THE BEGINNING
	MOV	CS:TEMP_TAIL,DI        ;;AN000;RESET POINTER BACK TO THE BEGINNING
	MOV	CS:BUSY_TFLAG,ACTIVE_OFF  ;;AN000;
	MOV	CS:NEW_BUFF_CTR,0		      ;;CLEAR OUT NEW BUFFER CTR
;***CNS

LOAD_CHAR:

	MOV	DI,CS:TEMP_TAIL 	;;AN003;MOVE PTR TO LATEST INSERT POSITION
	MOV	BYTE PTR CS:[DI],AL	;;AN000;LOAD CHARACTER INTO MY BUFFER
	INC	CS:NEW_BUFF_CTR 	;;AN000;
	INC	DI			;;AN000;TAIL POINTER NEEDS TO BE ADVANCED
	MOV	CS:TEMP_TAIL,DI 	   ;;AN000;ADD ONE TO TAIL POINTER
					;;AN000;GET ANOTHER CHAR. IF AVAILABLE
	TEST	CS:BUSY_TFLAG,ACTIVE_ON    ;;AN000;CHECK TO SEE IF WE ARE IN A BUSY STATE
	JZ	KEEP_BUSY		;;AN000;IF YES ROUTINE TO UNLOAD TEMP BUFFER
	CLI				; TURN OFF INTERRUPTS
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT
;***CNS
	JMP	SHORT $+2
;***CNS
;   PUSH    DS			    ;ICE
;   push    bx			    ;ICE
;   push    ax			    ;ICE
;   mov     bx,0140H		    ;ICE
;   xor     ax,ax		    ;ICE
;   mov     ds,ax		    ;ICE
;   mov     ax,word ptr ds:[bx]     ;ICE
;   mov     word ptr ds:[bx],ax     ;ICE
;   POP     ax			    ;ICE
;   pop     bx			    ;ICE
;   pop     ds			    ;ICE
					;;AN000;OTHERWISE FREE UP THE PROCESSOR
	MOV	CS:BUSY_TFLAG,ACTIVE_OFF  ;;AN000;
	JMP	KEY_EXIT		; KEY_EXIT

EXIT_CHK:

	 CMP	 CS:ENABLE_FL,1
	 JE	 ENABLE_CHK

	 CMP	 CS:ENABLE_FL,2
	 JE	 KEY_EXIT

	 CMP	 CS:ENABLE_FL,-1
	 JE	 CHK_BEEPER


PREP_EXIT:

	AND	KB_FLAG_3,NOT LC_E0+LC_E1  ; RESET LAST CHAR H.C. FLAG	   RWV 7-23-85


CHK_BEEPER:				; INTERRUPT-RETURN

	CMP	CS:BEEP_PENDING,YES    ;; Q..SHOULD WE BEEP?
	JNE	JR_EXIT 		     ;;
	MOV	CS:BEEP_PENDING,NO     ;;
	CALL	ERROR_BEEP	       ;;

JR_EXIT:			       ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_JR   ;;
	JNZ	KEY_EXIT  ;K27A 		  ;;
	CLI				; TURN OFF INTERRUPTS
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT

ENABLE_CHK:				; INTERRUPT-RETURN-NO-EOI

	MOV	AL,ENA_KBD		; ENSURE KEYBOARD IS ENABLED (AT ONLY)
	CALL	SHIP_IT 		; EXECUTE ENABLE
	CMP	CS:BUFFER_ENTRY_OK,YES ;; ENTRY IN BUFFER?
	JNE	GOOD_ENTRY ;K271		   ;;  NO, SKIP POST
	MOV	AX,09102H		; MOVE IN POST CODE & TYPE
	INT	15H			; PERFORM OTHER FUNCTION

GOOD_ENTRY:			       ;;

KEY_EXIT:


	    CLI 			    ; DISABLE INTERRUPTS
	    POP     ES			    ; RESTORE REGISTERS
	    POP     DS			    ; *
	    POP     DI			    ; *
	    POP     SI			    ; *
	    POP     DX			    ; *
	    POP     CX			    ; *
	    POP     BX			    ; *
	    POP     AX			    ; *
	    POP     BP
	    IRET			    ; RETURN, INTERRUPTS BACK ON WITH FLAG CHANGE
					    ;;AND RETURN INT OFF OF THE STACK



KEEP_BUSY:

	CALL	CLEAR_BUFFER		;;UNLOAD THE TEMPORARY BUFFER

TBUFF_EMPTY:
	JMP	EXIT_CHK

;	RET

;(*EQUIVALENT TO PREP_EXIT*)
;; Procedure: CLEAR_BUFFER
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
				       ;;
CLEAR_BUFFER:			       ;;
				       ;;
				       ;;
	MOV	DI,CS:TEMP_HEAD 	  ;;AN000;RESET POINTER BACK TO THE BEGINNING
	MOV	CS:BUSY_TFLAG,ACTIVE_ON   ;;AN000;
				       ;;
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI		       ;;AN000; END OF INTERRUPT COMMAND
	OUT	020H,AL 	       ;;AN000; SEND COMMAND TO INTERRUPT CONTROL PORT
;***CNS
	JMP	SHORT $+2
;***CNS
				       ;;
				       ;;
				       ;;AN000; INTERRUPT-RETURN-NO-EOI
GET_KB: 			       ;;AN000;AN000;
	XOR	BX,BX		       ;;AN000;
	CLI			       ;;AN000;DO NOT PROCESS UNTIL UNLOADED
				       ;;AN000;
	MOV	AL,BYTE PTR CS:[DI]    ;;AN000;TEMPORARY BUFFER
	STI			       ;;AN000;ENABLE SO I CAN KEEP PROCESSING
	PUSH	AX
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	DS
	PUSH	ES
	PUSH	SI
	PUSH	DI		       ;;AN000;SAVE THE POINTER
	PUSH	CS:TEMP_TAIL
	CALL	OLD_METHOD	       ;;AN000;LOAD USING EXISTING METHOD
	POP	CS:TEMP_TAIL
	POP	DI		       ;;AN000;RESTORE THE POINTER
	POP	SI
	POP	ES
	POP	DS
	POP	DX
	POP	CX
	POP	BX
	POP	AX

CHK_BUFF_EMPTY:

	INC	DI		       ;;AN000;INCREMENT POINTER
	CMP	DI,CS:TEMP_TAIL 	  ;;AN000;IS THE BUFFER EMPTY YET?
	JE	EMPTY_BUFF	       ;;AN000;YES - MARK INACTIVE & RETURN
				       ;;AN000;
				       ;;AN000;
				       ;;AN000;
	JMP	GET_KB		       ;;AN000;NO - GET ANOTHER CHARACTER



EMPTY_BUFF:

	CLI			       ;;AN000;OTHERWISE DISABLE INTERRUPTS
	MOV	CS:BUSY_TFLAG,ACTIVE_OFF  ;;AN000;LET SYSTEM KNOW NOT BUSY ANYMORE
	MOV	CS:NEW_BUFF_CTR,0	  ;;CLEAR OUT NEW BUFFER CTR



	RET			       ;;AN000;


OLD_METHOD:


KB_INT_02:				;	(AL)= SCAN CODE
	STI				; ENABLE INTERRUPTS AGAIN
	CMP	AL,KB_RESEND		; IS THE INPUT A RESEND
	JE	KB_INT_4		; GO IF RESEND

;------ CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD

	CMP	AL,KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
	JNZ	KB_INT_2		; GO IF NOT

;------ A COMMAND TO THE KEYBOARD WAS ISSUED

	CLI				; DISABLE INTERRUPTS
	OR	KB_FLAG_2,KB_FA 	; INDICATE ACK RECEIVED
	RET
;	JMP	PREP_EXIT		      ; RETURN IF NOT (ACK RETURNED FOR DATA)

;------ RESEND THE LAST BYTE

KB_INT_4:
	CLI				; DISABLE INTERRUPTS
	OR	KB_FLAG_2,KB_FE 	; INDICATE RESEND RECEIVED
	RET
;	JMP	PREP_EXIT		      ; RETURN IF NOT (ACK RETURNED FOR DATA)


;------ UPDATE MODE INDICATORS IF CHANGE IN STATE

KB_INT_2:
	PUSH	AX			; SAVE DATA IN
	CALL	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
	MOV	BL,KB_FLAG_2		; GET PREVIOUS BITS
	XOR	BL,AL			; SEE IF ANY DIFFERENT
	AND	BL,07H			; ISOLATE INDICATOR BITS
	JZ	UP0			; IF NO CHANGE BYPASS UPDATE
	CALL	SND_LED 		; GO TURN ON MODE INDICATORS

;------ PROCESSING COMES BACK TOGETHER HERE

UP0:	POP	AX			; RESTORE DATA IN
PAGE
;---------------------------------------------------------------------
;	      START OF KEY PROCESSING				     -
;---------------------------------------------------------------------

UP1:	MOV	AH,AL			; SAVE SCAN CODE IN AH ALSO
	MOV	CS:SCAN_CODE,AL        ;; SAVE SCAN CODE

;------ TEST FOR OVERRUN SCAN CODE FROM KEYBOARD

	CMP	AL,0FFH 		; IS THIS AN OVERRUN CHAR?
	JNZ	K16			; NO, TEST FOR SHIFT KEY
	MOV	CS:BEEP_PENDING,YES    ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_JR ;; ON JR WE HAVE TO CLEAR SOME FLAGS
	JZ	OVERRUN 	       ;;
	AND	KB_FLAG,0F0H	       ;; CLEAR SHIFTS
	AND	KB_FLAG_1,0FH	       ;;
	AND	KB_FLAG_2,1FH	       ;; CLEAR FUNCTION STATES
OVERRUN:			       ;;
	RET
;	JMP	PREP_EXIT		      ; BUFFER_FULL_BEEP

K16:	PUSH	CS
	POP	ES			; ESTABLISH ADDRESS OF TABLES
	MOV	BH,KB_FLAG_3		; LOAD FLAGS FOR TESTING	   RWV 10-08-85

;------ TEST TO SEE IF A READ_ID IS IN PROGRESS

	TEST	BH,RD_ID+LC_AB		; ARE WE DOING A READ ID?	   RWV 10-08-85
	JZ	NOT_ID			; CONTINUE IF NOT
	JNS	TST_ID_2		; IS THE RD_ID FLAG ON?
	CMP	AL,ID_1 		; IS THIS THE 1ST ID CHARACTER?
	JNE	RST_RD_ID
	OR	KB_FLAG_3,LC_AB 	; INDICATE 1ST ID WAS OK
RST_RD_ID:
	AND	KB_FLAG_3,NOT RD_ID	; RESET THE READ ID FLAG
	JMP	SHORT ID_EX		; AND EXIT			   RWV 8-02-85

TST_ID_2:
	AND	KB_FLAG_3,NOT LC_AB	; RESET FLAG
	CMP	AL,ID_2A		; IS THIS THE 2ND ID CHARACTER?
	JE	KX_BIT			;  JUMP IF SO
	CMP	AL,ID_2 		; IS THIS THE 2ND ID CHARACTER?
	JNE	ID_EX			;  LEAVE IF NOT

;------ A READ ID SAID THAT IT WAS ENHANCED KEYBOARD

	TEST	BH,SET_NUM_LK		; SHOULD WE SET NUM LOCK?	   RWV 10-08-85
	JZ	KX_BIT			; EXIT IF NOT
	OR	KB_FLAG,NUM_STATE	; FORCE NUM LOCK ON
	CALL	SND_LED 		; GO SET THE NUM LOCK INDICATOR
KX_BIT: OR	KB_FLAG_3,KBX		; INDICATE ENHANCED KEYBOARD WAS FOUND
ID_EX:	;JMP	 PREP_EXIT		       ; EXIT
	RET
PAGE
NOT_ID:
	CMP	AL,MC_E0		; IS THIS THE GENERAL MARKER CODE? RWV 7-19-85
	JNE	TEST_E1 		;				   RWV 7-19-85
	OR	KB_FLAG_3,LC_E0+KBX	; SET FLAG BIT, SET KBX, AND	   RWV 7-19-85
	JMP	SHORT EXIT		; THROW AWAY THIS CODE		   RWV 7-19-85

TEST_E1:
	CMP	AL,MC_E1		; IS THIS THE PAUSE KEY?	   RWV 7-19-85
	JNE	NOT_HC			;				   RWV 7-19-85
	OR	KB_FLAG_3,LC_E1+KBX	; SET FLAG, PAUSE KEY MARKER CODE  RWV 7-19-85
EXIT:
;***CNS
       MOV     CS:ENABLE_FL,-1
       RET;JMP	   CHK_BEEPER			 ; THROW AWAY THIS CODE 	    RWV 7-19-85
;***CNS
NOT_HC:
	AND	AL,07FH 		; TURN OFF THE BREAK BIT	   RWV 7-28-85
	TEST	BH,LC_E0		; LAST CODE THE E0 MARKER CODE?    RWV 10-08-85
	JZ	NOT_LC_E0		; JUMP IF NOT			    RWV

	MOV	CX,2			; LENGTH OF SEARCH		    RWV
	MOV	DI,OFFSET K6+6		; IS THIS A SHIFT KEY?		    RWV
	REPNE	SCASB			; CHECK IT			    RWV
	JNE	K16A			; NO, CONTINUE KEY PROCESSING	    RWV
	JMP	SHORT K16B		; YES, THROW AWAY & RESET FLAG	    RWV

NOT_LC_E0:
	TEST	BH,LC_E1		; LAST CODE THE E1 MARKER CODE?    RWV 10-08-85
	JZ	T_SYS_KEY		; JUMP IF NOT			    RWV

	MOV	CX,4			; LENGTH OF SEARCH		    RWV
	MOV	DI,OFFSET K6+4		; IS THIS AN ALT, CTL, OR SHIFT?    RWV
	REPNE	SCASB			; CHECK IT			    RWV
	JE	EXIT			; THROW AWAY IF SO		    RWV

	CMP	AL,NUM_KEY		; IS IT THE PAUSE KEY?		    RWV
	JNE	K16B			; NO, THROW AWAY & RESET FLAG	    RWV
	TEST	AH,80H			; YES, IS IT THE BREAK OF THE KEY?  RWV
	JNZ	K16B			;  YES, THROW THIS AWAY, TOO	    RWV
	TEST	KB_FLAG_1,HOLD_STATE	;  NO, ARE WE PAUSED ALREADY?	    PED 6-25-86
	JNZ	K16B			;   YES, THROW AWAY		    PED 6-25-86
	JMP	K39P			;  NO, THIS IS THE REAL PAUSE STATE RWV
PAGE
;------ TEST FOR SYSTEM KEY

T_SYS_KEY:
	CMP	AL,SYS_KEY		; IS IT THE SYSTEM KEY?
	JNE	K16A			; CONTINUE IF NOT

;;;;;;	TEST	cs:SD.SYSTEM_FLAG,PC_AT+PC_386	  ; LET ALL SYSTEMS ISSUE INT15      RWV 8-02-85
;;;;;;	JZ	K16A			; IGNORE SYSTEM KEY IF NOT PC3

	TEST	AH,080H 		; CHECK IF THIS A BREAK CODE
	JNZ	K16C			; DON'T TOUCH SYSTEM INDICATOR IF TRUE

	TEST	KB_FLAG_1,SYS_SHIFT	; SEE IF IN SYSTEM KEY HELD DOWN
	JNZ	K16B			; IF YES, DON'T PROCESS SYSTEM INDICATOR

	OR	KB_FLAG_1,SYS_SHIFT	; INDICATE SYSTEM KEY DEPRESSED
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT
;***CNS
	JMP	SHORT $+2
;***CNS
					; INTERRUPT-RETURN-NO-EOI
				       ;;
	MOV	AL,ENA_KBD		; INSURE KEYBOARD IS ENABLED
	CALL	SHIP_IT 		; EXECUTE ENABLE

	MOV	AX,08500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
	STI				; MAKE SURE INTERRUPTS ENABLED
	INT	15H			; USER INTERRUPT
;***CNS
	MOV	CS:ENABLE_FL,2
	RET;JMP     KEY_EXIT		    ; END PROCESSING
;***CNS
K16B:	;JMP	 PREP_EXIT		       ; IGNORE SYSTEM KEY
	RET
K16C:	AND	KB_FLAG_1,NOT SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI			; END OF INTERRUPT COMMAND
	OUT	020H,AL 		; SEND COMMAND TO INTERRUPT CONTROL PORT
;***CNS
	JMP	SHORT $+2
;***CNS
					; INTERRUPT-RETURN-NO-EOI
	MOV	AL,ENA_KBD		; ENSURE KEYBOARD IS ENABLED
	CALL	SHIP_IT 		; EXECUTE ENABLE

	MOV	AX,08501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
	STI				; MAKE SURE INTERRUPTS ENABLED
	INT	15H			; USER INTERRUPT
;***CNS
	MOV	CS:ENABLE_FL,2
	RET;JMP     KEY_EXIT		    ; IGNORE SYSTEM KEY
;***CNS
PAGE
;------ TEST FOR SHIFT KEYS
;
; HERE IS WHERE KBFLAGS ARE SET.  WHAT HAPPENS IS, THE SYSTEM SEARCHES TABLE
; 'K6' FOR THE KEY.  IF FOUND, IT GETS THE APPROPRIATE BIT FROM TABLE 'K7'
; AND SETS IT ON. (TABLES ARE ALL AT THE END OF THIS ROUTINE)  FLAGS FOR THE
; SECOND ALT AND CTRL ARE SET IN KB_FLAG_3 AND HAVE THE SAME BIT POSITIONS AS
; THEIR ORIGINAL COUNTERPARTS IN KB_FLAG

K16A:	MOV	BL,KB_FLAG		; PUT STATE FLAGS IN BL 	   RWV 8-28-85
	MOV	DI,OFFSET K6		; SHIFT KEY TABLE
	MOV	CX,K6L			; LENGTH
	REPNE	SCASB			; LOOK THROUGH THE TABLE FOR A MATCH
	MOV	AL,AH			; RECOVER SCAN CODE
	JE	K17			; JUMP IF MATCH FOUND
	JMP	K25			; IF NO MATCH, THEN SHIFT NOT FOUND

;------ SHIFT KEY FOUND

K17:	SUB	DI,OFFSET K6+1		; ADJUST PTR TO SCAN CODE MTCH
	MOV	AH,CS:K7[DI]		; GET MASK INTO AH
	MOV	CL,2			; SET UP COUNT FOR FLAG SHIFTS	   RWV 9-11-85
	TEST	AL,80H			; TEST FOR BREAK KEY
	JZ	K17C
	JMP	K23			; JUMP IF BREAK 		   RWV 8-14-85

;------ SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE

K17C:	CMP	AH,SCROLL_SHIFT
	JAE	K18			; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY

;------ PLAIN SHIFT KEY, SET SHIFT ON

	CMP	COUNTRY_FLAG,0FFh	; ARE WE IN FOREIGN LANG MODE?	   RWV 8-29-85
	JNE	K17C1			;  NO, US MODE, JUMP		   RWV 8-29-85
	CMP	AL,ALT_KEY		; IS THIS THE ALT KEY?		   RWV 8-29-85
	JNE	K17C1			;  NO, NORMAL KEY		   RWV 8-29-85
				 ;**CNS
;;AD000TEST    KB_FLAG_3,LC_E0	       ;  IS IT THE ALT_GR KEY? 	   RWV 8-29-85
;;AD000JNZ     K17C2		       ;   YES, DON'T SET KB_FLAG          RWV 8-29-85


K17C1:	OR	KB_FLAG,AH		; TURN ON SHIFT BIT		   RWV 8-28-85
K17C2:	TEST	AH,CTL_SHIFT+ALT_SHIFT	; IS IT ALT OR CTRL?		   RWV 8-28-85
	JZ	K17F			;  NO, JUMP			   RWV 8-28-85
K17D:	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?	   RWV 10-08-85
	JZ	K17E			;  NO, JUMP			   RWV 7-22-85
	OR	KB_FLAG_3,AH		; SET BITS FOR RIGHT CTRL, ALT	   RWV 7-22-85
	RET
;	JMP	PREP_EXIT		      ; INTERRUPT_RETURN		 RWV 7-22-85
K17E:	SHR	AH,CL			; MOVE FLAG BITS TWO POSITIONS	   RWV 8-28-85
	OR	KB_FLAG_1,AH		; SET BITS FOR LEFT CTRL, ALT	   RWV 7-22-85
	RET
;	 JMP	 PREP_EXIT		      ;;
				       ;; Q..typewriter caps locks
K17F:				       ;;
	TEST	CS:SD.SPECIAL_FEATURES,TYPEWRITER_CAPS_LK
	JZ	K17G		       ;; N..all done
	CMP	COUNTRY_FLAG,0FFh	; ARE WE IN LANG MODE?		   RWV 8-28-85
	JNE	K17G			;  NO, ALL DONE WITH SHIFT KEY	   RWV 8-28-85

;;  If keyboard is P12 then we still need to release caps_lk		***RPS 10-3-86

	TEST	CS:SD.SYSTEM_FLAG,PC_LAP ;; IS THIS A P12 KEYBOARD?	***RPS 10-3-86
	JNZ	REMOVE_CAPS_SHIFT	 ;;				***RPS 10-3-86

	TEST	BH,KBX			; THIS THE ENHANCED KEYBOARD?	   RWV 11-06-85
	JZ	K17G			;  NO, ALL DONE WITH SHIFT KEY	   RWV 8-13-85
REMOVE_CAPS_SHIFT:			 ;;				***RPS 10-3-86
	AND	KB_FLAG,NOT CAPS_SHIFT	;  YES, TAKE KB OUT OF C_L STATE   RWV 8-13-85
	TEST	CS:SD.SYSTEM_FLAG,PC_AT+PC_386	  ; IF THIS IS A PC1 OR XT,	     RWV 9-18-85
	JZ	K17G			;  THEN SKIP THE LEDs		   RWV 9-18-85
	CALL	SND_LED 		;      AND UPDATE THE INDICATOR    RWV 8-13-85
K17G:	RET;JMP     PREP_EXIT

;------ TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT

K18:					; SHIFT-TOGGLE
	TEST	BL,CTL_SHIFT		; CHECK CTL SHIFT STATE 	   RWV 7-30-85
	JZ	K18A			; JUMP IF NOT CTL STATE
	JMP	K25			; JUMP IF CTL STATE
K18A:	CMP	AL,INS_KEY		; CHECK FOR INSERT KEY
	JNE	K22			; JUMP IF NOT INSERT KEY
	TEST	BL,ALT_SHIFT		; CHECK FOR ALTERNATE SHIFT	   RWV 7-30-85
	JZ	K18B			; JUMP IF NOT ALTERNATE SHIFT	   RWV 7-30-85
	JMP	K25			; JUMP IF ALTERNATE SHIFT
K18B:	TEST	BH,LC_E0		; IS THIS THE NEW INSERT KEY?	   RWV 10-08-85
	JNZ	K22			; YES, THIS ONE'S NEVER A "0"      RWV 7-23-85
K19:	TEST	BL,NUM_STATE		; CHECK FOR BASE STATE		   RWV 7-30-85
	JNZ	K21			; JUMP IF NUM LOCK IS ON
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; TEST FOR SHIFT STATE	   RWV 7-30-85
	JZ	K22			   ; JUMP IF BASE STATE
K20:	MOV	AH,AL			; PUT SCAN CODE BACK IN AH	   RWV 11-07-85
	JMP	K25			; NUMERAL "0", STNDRD. PROCESSING  RWV 7-22-85

K21:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; MIGHT BE NUMERIC		   RWV 7-30-85
	JZ	K20			   ; IS NUMERIC, STD. PROC.	   RWV 7-23-85

K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
	TEST	AH,KB_FLAG_1		; IS KEY ALREADY DEPRESSED?
	JZ	K22A
	RET;JMP     PREP_EXIT			  ; JUMP IF KEY ALREADY DEPRESSED
K22A:	OR	KB_FLAG_1,AH		; INDICATE THAT THE KEY IS DEPRESSED
	XOR	KB_FLAG,AH		; TOGGLE THE SHIFT STATE

	TEST	CS:SD.SPECIAL_FEATURES,TYPEWRITER_CAPS_LK
	JZ	K22C		       ;; N..all done

;;  If keyboard is P12 then we do not toggle				***RPS 10-3-86

	TEST	CS:SD.SYSTEM_FLAG,PC_LAP ;; IS THIS A P12 KEYBOARD?	***RPS 10-3-86
	JNZ	LAP_SO_DONT_TOGGLE	 ;;				***RPS 10-3-86

	TEST	BH,KBX			; THIS THE ENHANCED KEYBOARD?	   RWV 11-06-85
	JZ	K22C			;  NO, ALL DONE WITH TOGGLE KEYS   RWV 8-13-85

LAP_SO_DONT_TOGGLE:		       ;;				***RPS 10-3-86
	CMP	CS:COUNTRY_FLAG,0FFh	; ARE WE IN FOREIGN LANG MODE?	   RWV 9-11-85
	JNE	K22C			;  NO, NO SPECIAL STUFF FOR U.S.   RWV 9-11-85
	TEST	AH,CAPS_SHIFT		; IS IT THE CAPS_LOCK KEY?	   RWV 8-13-85
	JZ	K22C			;  NO, NOTHING ELSE TO DO	   RWV 8-13-85
	OR	KB_FLAG,AH		;  YES, SET CAPS_LOCK (NOT TOGGLE) RWV 8-13-85

;------- TEST SYSTEM TYPE

K22C:	TEST	CS:SD.SYSTEM_FLAG,PC_AT+PC_386	  ; IF THE SYSTEM WE'RE RUNNING ON IS
	JZ	K22B			; A PC1 OR XT, THEN SKIP THE LEDs

;------ TOGGLE LED IF CAPS, NUM, OR SCROLL KEY DEPRESSED

	TEST	AH,CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
	JZ	K22B			; GO IF NOT
	PUSH	AX			; SAVE SCAN CODE AND SHIFT MASK
	CALL	SND_LED 		; GO TURN MODE INDICATORS ON
	POP	AX			; RESTORE SCAN CODE

K22B:	CMP	AL,INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
;**CNS
	JE	INS_CHK 		      ; JUMP IF NOT INSERT KEY
	RET;JMP     PREP_EXIT


;**CNS
INS_CHK:

	MOV	AH,AL			; SCAN CODE IN BOTH HALVES OF AX   RWV 7-24-85
	JMP	K28			; FLAGS UPDATED, PROC. FOR BUFFER  RWV 7-23-85

;------ BREAK SHIFT FOUND

K23:					; BREAK-SHIFT-FOUND
	CMP	AH,SCROLL_SHIFT 	; IS THIS A TOGGLE KEY?
	NOT	AH			; INVERT MASK
	JAE	K24			; YES, HANDLE BREAK TOGGLE
	AND	KB_FLAG,AH		; TURN OFF SHIFT BIT
	CMP	AH,NOT CTL_SHIFT	; IS THIS ALT OR CTL?		   RWV 8-29-85
	JA	K23D			;  NO, ALL DONE 		   RWV 8-29-85



	TEST	BH,LC_E0		; 2ND ALT OR CTL?		   RWV 10-08-85
	JZ	K23A			; NO, HANDLE NORMALLY		   RWV 7-22-85
	AND	KB_FLAG_3,AH		; RESET BIT FOR RIGHT ALT OR CTL   RWV 7-22-85
	JMP	SHORT K23B		; CONTINUE			   RWV 7-22-85
K23A:	SAR	AH,CL			; MOVE THE MASK BIT TWO POSITIONS  RWV 8-28-85
	AND	KB_FLAG_1,AH		; RESET BIT FOR LEFT ALT OR CTL    RWV 8-28-85
K23B:	MOV	AH,AL			; SAVE SCAN CODE		   RWV 8-28-85
	MOV	AL,KB_FLAG_3		; GET RIGHT ALT & CTRL FLAGS	   RWV 8-28-85
	CMP	COUNTRY_FLAG,0FFH	; ARE WE IN LANGUAGE MODE?	   RWV 8-28-85
	JNE	K23C			;  NO, LEAVE RIGHT FLAGS AS IS	   RWV 8-28-85
;**CNS
	AND	AL,NOT GRAPH_ON 	;  YES, FILTER OUT THE ALT_GR KEY  RWV 8-28-85
;**CNS
K23C:	SHR	AL,CL			; MOVE TO BITS 1 & 0		   RWV 8-28-85
	OR	AL,KB_FLAG_1		; PUT IN LEFT ALT & CTL FLAGS	   RWV 8-28-85
	SHL	AL,CL			; MOVE BACK TO BITS 3 & 2	   RWV 8-28-85
	AND	AL,ALT_SHIFT+CTL_SHIFT	; FILTER OUT OTHER GARBAGE	   RWV 8-28-85
	OR	KB_FLAG,AL		; PUT RESULT IN THE REAL FLAGS	   RWV 8-28-85
	MOV	AL,AH			; RECOVER SAVED SCAN CODE	   RWV 8-28-85

K23D:	CMP	AL,ALT_KEY+80H		; IS THIS ALTERNATE SHIFT RELEASE
	JE	ALT_SHFT		      ; INTERRUPT_RETURN
	RET;JMP     PREP_EXIT

;------ ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER

ALT_SHFT:

	MOV	AL,ALT_INPUT
	MOV	AH,0			; SCAN CODE OF 0
	MOV	ALT_INPUT,AH		; ZERO OUT THE FIELD
	CMP	AL,0			; WAS THE INPUT = 0?
	JNE	GOOD_ALTCHAR		; INTERRUPT_RETURN
	RET;JMP     PREP_EXIT

GOOD_ALTCHAR:

	CALL	BUFFER_FILL_ANY_CHAR   ;; Put in buffer, but use this
				       ;;  entry point to avoid trashing
				       ;;   an ASCII code of 255
	RET;JMP     PREP_EXIT			  ; INTERRUPT_RETURN

K24:					; BREAK-TOGGLE
	AND	KB_FLAG_1,AH		; INDICATE NO LONGER DEPRESSED
	RET;JMP     PREP_EXIT		    ; INTERRUPT_RETURN

;------ TEST FOR HOLD STATE
					; AL, AH = SCAN CODE
K25:					; NO-SHIFT-FOUND
	CMP	AL,80H			; TEST FOR BREAK KEY
	JB	NO_BREAK		     ; NOTHING FOR BREAK CHARS FROM HERE ON
	RET;JMP     PREP_EXIT

NO_BREAK:

	TEST	KB_FLAG_1,HOLD_STATE	; ARE WE IN HOLD STATE
	JZ	K28			; BRANCH AROUND TEST IF NOT
	CMP	AL,NUM_KEY
	JNE	HOLD_OFF		      ; CAN'T END HOLD ON NUM_LOCK
	RET;JMP     PREP_EXIT

HOLD_OFF:

	AND	KB_FLAG_1,NOT HOLD_STATE   ; TURN OFF THE HOLD STATE BIT

;------ EXIT POINT		       ;;

	RET;JMP     PREP_EXIT

PAGE
;------ NOT IN HOLD STATE
					; AL, AH = SCAN CODE (ALL MAKES)
K28:					; NO-HOLD-STATE
	CMP	AL,88			; TEST FOR OUT-OF-RANGE SCAN CODES RWV 8-01-85
	JBE	SCAN_INRANGE		      ; IGNORE IF OUT-OF-RANGE		 RWV 8-01-85
	RET;JMP     PREP_EXIT


SCAN_INRANGE:

	TEST	BL,ALT_SHIFT		; ARE WE IN ALTERNATE SHIFT?	   RWV 7-30-85
	JZ	K28A			; JUMP IF NOT ALTERNATE 	   RWV 7-26-85

	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?   RWV 10-08-85
	JZ	K29			; NO, ALT STATE IS REAL 	   RWV 7-24-85

	TEST	KB_FLAG_1,SYS_SHIFT	; YES, IS SYSREQ KEY DOWN?	   RWV 7-24-85
	JZ	K29			;  NO, ALT STATE IS REAL	   RWV 7-24-85
;**CNS

	 TEST	 AH,LC_E0	  ; IS IT THE ALT_GR KEY?	     RWV 8-29-85
	 JZ	 K28A			  ; YES,   DON'T SET KB_FLAG          RWV 8-29-85

	 TEST	 AL,R_ALT_SHIFT       ; TURN ON SHIFT BIT		 RWV 8-28-85
	 JNZ	 K29			 ; TURN ON SHIFT BIT		    RWV 8-28-85

;**CNS

K28A:	JMP	K38			;  YES, THIS IS PHONY ALT STATE    RWV 7-24-85
					;	DUE TO PRESSING SYSREQ	   RWV 7-24-85

;------ TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)

K29:					; TEST-RESET
	TEST	BL,CTL_SHIFT		; ARE WE IN CONTROL SHIFT ALSO?    RWV 7-30-85
	JZ	K31			; NO_RESET
	CMP	AL,DEL_KEY		; SHIFT STATE IS THERE, TEST KEY
	JNE	K31A			; NO_RESET,  TRANSLATE TABLE SWAP

;------ CTL-ALT-DEL HAS BEEN FOUND, DO I/O CLEANUP

	MOV	RESET_FLAG,1234H	; SET FLAG FOR RESET FUNCTION
	AND	WORD PTR KB_FLAG_3,KBX	; CLEAR ALL FLAG BITS EXCEPT KBX   PED 6-25-86
	JMP	RESET			; JUMP TO POWER ON DIAGNOSTICS

;------ IN ALTERNATE SHIFT, RESET NOT FOUND

K31:					; NO-RESET
	CALL	KEYB_STATE_PROCESSOR   ;;
	JNC	K3105		       ;; NO TRANSLATIONS FOUND - CONTINUE
	RET;JMP     PREP_EXIT			 ;; TRANSLATIONS FOUND - EXIT
K3105:				       ;;
				       ;;
	CMP	AL,57			; TEST FOR SPACE KEY
	JNE	K311			; NOT THERE
	MOV	AL,' '                  ; SET SPACE CHAR
	JMP	K57			; BUFFER_FILL
K311:
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS EXTENDED INT 16 LOADED?       RWV 11-06-85
	JZ	K32			;  NO, SKIP THIS EXTENDED STUFF    RWV 11-06-85
	CMP	AL,15			; TEST FOR TAB KEY		   RWV 10-04-85
	JNE	K312			; NOT THERE			   RWV 10-04-85
	MOV	AX,0A500h		; SET SPECIAL CODE FOR ALT-TAB	   RWV 10-04-85
	JMP	K57			; BUFFER_FILL			   RWV 10-04-85
K312:
	CMP	AL,74			; TEST FOR KEYPAD -		   RWV 10-04-85
	JE	K312A			; GO PROCESS			   RWV 10-04-85
	CMP	AL,78			; TEST FOR KEYPAD +		   RWV 10-04-85
	JNE	K32			; SKIP TEST FOR LANG SWAP & CONT.  RWV 11-06-85
K312A:	JMP	K37B			; GO PROCESS			   RWV 10-04-85

;------ SET COUNTRY FLAG TO INDICATE WHICH TABLE WE'RE USING, FOREIGN OR DOMESTIC

K31A:	CMP	AL,CS:SD.HOT_KEY_ON_SCAN  ; TEST FOR HOT KEY TO US
	JNE	K31B			;
	MOV	CS:COUNTRY_FLAG,00	; SET FLAG FOR DOMESTIC KEY'S
	RET;JMP     PREP_EXIT			  ; INTERRUPT RETURN

K31B:	CMP	AL,CS:SD.HOT_KEY_OFF_SCAN ; TEST FOR HOT KEY TO FOREIGN
	JNE	K31C			; IF NOT TEST FOR FRONT ENGRAV
	MOV	CS:COUNTRY_FLAG,0FFH	; SET FLAGS FOR FOREIGN KEY'S
	RET;JMP     PREP_EXIT			  ; INTERRUPT RETURN


;------ ALT, CTRL DOWN ; NO HOT KEY

K31C:	CMP	CS:COUNTRY_FLAG,0FFH
	JNE	K32			; TRY ALT_KEY_PAD
	CALL	KEYB_STATE_PROCESSOR   ;;
	JNC	K32		       ;; NO TRANSLATIONS FOUND - CONTINUE
	RET;JMP     PREP_EXIT			 ;; TRANSLATIONS FOUND - EXIT


;------ LOOK FOR KEY PAD ENTRY

K32:					; ALT-KEY-PAD
	MOV	DI,OFFSET K30		; ALT-INPUT-TABLE
	MOV	CX,10			; LOOK FOR ENTRY USING KEYPAD
	REPNE	SCASB			; LOOK FOR MATCH
	JNE	K33			; NO_ALT_KEYPAD
	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?	   RWV 10-08-85
	JZ	K321			;  NO, PROCESS AS ALT-NUMPAD	   RWV 11-06-85
	JMP	K37C			;  YES, JUMP, NOT NUMPAD KEY	   RWV 7-24-85
K321:	SUB	DI,OFFSET K30+1 	; DI NOW HAS ENTRY VALUE
	MOV	AL,ALT_INPUT		; GET THE CURRENT BYTE
	MOV	AH,10			; MULTIPLY BY 10
	MUL	AH
	ADD	AX,DI			; ADD IN THE LATEST ENTRY
	MOV	ALT_INPUT,AL		; STORE IT AWAY
K32A:	RET;JMP     PREP_EXIT			  ; THROW AWAY THAT KEYSTROKE

;------ LOOK FOR SUPERSHIFT ENTRY

K33:					; NO-ALT-KEYPAD
	MOV	ALT_INPUT,0		; ZERO ANY PREVIOUS ENTRY INTO INPUT
					; DI,ES ALREADY POINTING
	MOV	CX, K30_LEN	; NORMALLY 26, BUT 27 FOR FR, DUE  RWV 8-06-85
					;  TO THE ";" KEY BEING "M"        RWV 8-06-85
	REPNE	SCASB			; LOOK FOR MATCH IN ALPHABET
	JNE	K34			; NOT FOUND, FUNCTION KEY OR OTHER
	JMP	SHORT K37A		; PUT IT IN THE BUFFER		   RWV 8-06-85

;------ LOOK FOR TOP ROW OF ALTERNATE SHIFT

K34:					; ALT-TOP-ROW
	CMP	AL,2			; KEY WITH '1' ON IT
	JB	K37B			; MUST BE ESCAPE		   RWV 10-04-85
	CMP	AL,13			; IS IT IN THE REGION
	JA	K35			;  NO, ALT-SOMETHING ELSE
	ADD	AH,118			; CONVERT PSEUDO SCAN CODE TO RANGE
	JMP	SHORT K37A		; GO FILL THE BUFFER		   RWV 8-06-85

;------ TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES

K35:					; ALT-FUNCTION
	CMP	AL,F11_M		; IS IT F11?			   RWV 7-24-85
	JB	K35A			;  NO, BRANCH			   RWV 7-24-85
	CMP	AL,F12_M		; IS IT F12?			   RWV 7-24-85
	JA	K35A			;  NO, BRANCH			   RWV 7-24-85
	ADD	AH,52			; CONVERT TO PSEUDO SCAN CODE	   RWV 7-24-85
	JMP	SHORT K37A		; GO FILL THE BUFFER		   RWV 8-06-85

K35A:	TEST	BH,LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?  RWV 10-08-85
	JZ	K37			;  NO, JUMP			   RWV 10-04-85
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 LOADED?   RWV 11-06-85
	JZ	K37			;  NO, DO COMPATIBLE OUTPUT	   RWV 11-06-85
	CMP	AL,28			; TEST FOR KEYPAD ENTER 	   RWV 10-04-85
	JNE	K35B			; NOT THERE			   RWV 10-04-85
	MOV	AX,0A600h		; SPECIAL CODE			   RWV 10-04-85
	JMP	K57			; BUFFER FILL			   RWV 10-04-85
K35B:	CMP	AL,83			; TEST FOR DELETE KEY		   RWV 10-04-85
	JE	K37C			; HANDLE WITH OTHER EDIT KEYS	   RWV 10-04-85
	CMP	AL,53			; TEST FOR KEYPAD /		   RWV 10-04-85
	JNE	K32A			; NOT THERE, NO OTHER E0 SPECIALS  RWV 10-04-85
	MOV	AX,0A400h		; SPECIAL CODE			   RWV 10-04-85
	JMP	K57			; BUFFER FILL			   RWV 10-04-85

K37:	CMP	AL,59			; TEST FOR FUNCTION KEYS (F1)	   RWV 10-04-85
	JB	K37B			;  NO FN, HANDLE W/OTHER EXTENDED  RWV 10-04-85
	CMP	AL,68			; IN KEYPAD REGION?		   RWV 7-26-85
					; OR NUMLOCK, SCROLLOCK?	   RWV 7-26-85
	JA	K32A			; IF SO, IGNORE
	ADD	AH,45			; CONVERT TO PSEUDO SCAN CODE	   RWV 8-06-85

K37A:	MOV	AL,0			; ASCII CODE OF ZERO		   RWV 8-06-85
	JMP	K57			; PUT IT IN THE BUFFER		   RWV 8-06-85

K37B:
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 LOADED?   RWV 11-06-85
	JNZ	K37B1			;  YES, TRANSLATE AS EXTENDED	   RWV 11-06-85
	RET;JMP     PREP_EXIT			  ;  NO, INGORE THIS ONE	     RWV 11-06-85
K37B1:	MOV	AL,0F0h 		; USE SPECIAL ASCII CODE	   RWV 10-04-85
	JMP	K57			; PUT IT IN THE BUFFER		   RWV 10-04-85

K37C:
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 LOADED?   RWV 11-06-85
	JZ	K37A			;  NO, DO COMPATIBLE OUTPUT	   RWV 11-06-85
	ADD	AL,80			; CONVERT SCAN CODE (EDIT KEYS)    RWV 10-07-85
	MOV	AH,AL			; (SCAN CODE NOT IN AH FOR INSERT) RWV 10-07-85
	JMP	K37A			; PUT IT IN THE BUFFER		   RWV 10-07-85
PAGE
;------ NOT IN ALTERNATE SHIFT

K38:					; NOT-ALT-SHIFT
					; BL STILL HAS SHIFT FLAGS	   RWV 7-26-85
	TEST	BL,CTL_SHIFT		; ARE WE IN CONTROL SHIFT?	   RWV 7-26-85
	JNZ	K38A			;  YES, START PROCESSING	   RWV 8-01-85
	JMP	K44			; NOT-CTL-SHIFT

;------ CONTROL SHIFT, TEST SPECIAL CHARACTERS

;------ TEST FOR BREAK

K38A:	CMP	AL,SCROLL_KEY		; TEST FOR BREAK
	JNE	K39			; JUMP, NO-BREAK
	TEST	CS:SD.SYSTEM_FLAG,PC_LAP   ; IS THIS THE LAP COMPUTER?	      RWV 12-02-85
	JNZ	K38B			;  YES, THIS IS CTRL-BREAK	   RWV 12-02-85
	TEST	BH,KBX			;  NO, IS THIS THE ENHANCED KBD?   RWV 10-08-85
	JZ	K38B			;   NO, BREAK IS VALID		   RWV 7-26-85
	TEST	BH,LC_E0		;   YES, WAS LAST CODE AN E0?	   RWV 10-08-85
	JZ	K39			;    NO-BREAK, TEST FOR PAUSE	   RWV 7-26-85

K38B:	MOV	BX,BUFFER_HEAD		; RESET BUFFER TO EMPTY 	   RWV 10-23-85
	MOV	BUFFER_TAIL,BX		;
	MOV	BIOS_BREAK,80H		; TURN ON BIOS_BREAK BIT

;-------- ENABLE KEYBOARD

	MOV	AL,ENA_KBD		; ENABLE KEYBOARD
	CALL	SHIP_IT 		; EXECUTE ENABLE
	INT	1BH			; BREAK INTERRUPT VECTOR
	SUB	AX,AX			; PUT OUT DUMMY CHARACTER
	JMP	K57			; BUFFER_FILL

;-------- TEST FOR PAUSE

K39:					; NO-BREAK
	CMP	AL,NUM_KEY		; LOOK FOR PAUSE KEY
	JNE	K41			; NO-PAUSE
	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?   RWV 10-08-85
	JZ	K39P			;  NO, THIS IS A VALID PAUSE	   RWV 9-26-85
	TEST	CS:SD.SYSTEM_FLAG,PC_LAP   ; IS THIS THE LAP COMPUTER?	      RWV 9-26-85
	JZ	K41			;  NO, IT'S NOT PAUSE THIS TIME    RWV 9-26-85
K39P:	OR	KB_FLAG_1,HOLD_STATE	; TURN ON THE HOLD FLAG
	MOV	BUSY_TFLAG,ACTIVE_OFF	;TURN THE BUSY FLAG OFF - THIS IS
					;A SPECIAL CASE FOR THE SPLICER
	DEC	CS:TEMP_TAIL		;DELETE THE PAUSE KEY FROM THE BUFFER
					;IN CASE A INTERRUPT COMES IN
					;SO IT IS NOT DONE REPEATEDLY
;-------- ENABLE KEYBOARD

	MOV	AL,ENA_KBD		; ENABLE KEYBOARD
	CALL	SHIP_IT 		; EXECUTE ENABLE
K39A:
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI			; END OF INTERRUPT TO CONTROL PORT
	OUT	020H,AL 		; ALLOW FURTHER KEYSTROKE INTS
;***CNS
	JMP	SHORT $+2
;***CNS

;------ DURING PAUSE INTERVAL, TURN CRT BACK ON

	CMP	CRT_MODE,7		; IS THIS BLACK AND WHITE CARD
	JE	K40			; YES, NOTHING TO DO
	MOV	DX,03D8H		; PORT FOR COLOR CARD
	MOV	AL,CRT_MODE_SET 	; GET THE VALUE OF THE CURRENT MODE
	OUT	DX,AL			; SET THE CRT MODE, SO THAT CRT IS ON
K40:					; PAUSE-LOOP

;   PUSH    DS			    ;ICE
;   push    bx			    ;ICE
;   push    ax			    ;ICE
;   mov     bx,0140H		    ;ICE
;   xor     ax,ax		    ;ICE
;   mov     ds,ax		    ;ICE
;   mov     ax,word ptr ds:[bx]     ;ICE
;   mov     word ptr ds:[bx],ax     ;ICE
;   POP     ax			    ;ICE
;   pop     bx			    ;ICE
;   pop     ds			    ;ICE

	TEST	CS:SD.SYSTEM_FLAG,PC_LAP   ; IS THIS THE LAP COMPUTER?	      RWV 9-26-85
	JZ	K40A			;  NO, SKIP THE BATTERY LIFE STUFF RWV 9-26-85
	MOV	AX,4104H		; FUNCTION 41, AL=04=RETURN IF 0   RWV from AAD
	MOV	BX,HOLD_STATE*100H	; BH=HOLD_STATE, BL=0=NO TIME OUT  RWV from AAD
	PUSH	DS			; MAKE ES:DI POINT TO KB_FLAG_1    RWV from AAD
	POP	ES			;				   RWV from AAD
	MOV	DI,OFFSET KB_FLAG_1	;				   RWV from AAD
	INT	15H			; SLEEP UNTIL OUT OF HOLD	   RWV from AAD
K40A:


	TEST	KB_FLAG_1,HOLD_STATE
	JNZ	K40			; LOOP UNTIL FLAG TURNED OFF
;***CNS
	MOV	CS:ENABLE_FL,1
	RET;JMP     ENABLE_CHK		    ; INTERRUPT_RETURN_NO_EOI
;***CNS
;------ TEST SPECIAL CASE KEY 55

K41:					; NO-PAUSE
	CMP	AL,55			; TEST FOR */PRTSC KEY
	JNE	K42			; NOT-KEY-55
	TEST	CS:SD.SYSTEM_FLAG,PC_LAP   ; IS THIS THE LAP COMPUTER?	      RWV 9-23-85
	JZ	K41B			;  NO, JUMP			   RWV 9-23-85
	TEST	BH,LC_E0		;  YES, WAS LAST CODE AN E0?	   RWV 10-24-85
	JZ	K41A			;    NO, THIS IS THE PRTSC KEY	   RWV 9-23-85
	JMP	SHORT K42B		;    YES, E0 MEANS THE "*" KEY     RWV 9-23-85

K41B:	TEST	BH,KBX			; IS THIS THE ENHANCED KEYBOARD?   RWV 10-08-85
	JZ	K41A			;  NO, CTL-PRTSC IS VALID	   RWV 8-01-85
	TEST	BH,LC_E0		;  YES, WAS LAST CODE AN E0?	   RWV 10-08-85
	JZ	K42B			;   NO, TRANSLATE TO A FUNCTION    RWV 10-04-85
K41A:	MOV	AX,114*256		; START/STOP PRINTING SWITCH
	JMP	K57			; BUFFER_FILL

;------ SET UP TO TRANSLATE CONTROL SHIFT

K42:
	CALL	KEYB_STATE_PROCESSOR   ;;
	JNC	K421		       ;; NO TRANSLATIONS FOUND - CONTINUE
	RET;JMP     PREP_EXIT			 ;; TRANSLATIONS FOUND - EXIT

K421:					; NOT-KEY-55
	CMP	AL,15			; IS IT THE TAB KEY?		   RWV 10-04-85
	JE	K42B			;  YES, XLATE TO FUNCTION CODE	   RWV 10-04-85
	CMP	AL,53			; IS IT THE / KEY?		   RWV 10-04-85
	JNE	K42A			;  NO, NO MORE SPECIAL CASES	   RWV 10-04-85
	TEST	BH,LC_E0		;  YES, IS IT FROM THE KEYPAD?	   RWV 10-08-85
	JZ	K42A			;   NO, JUST TRANSLATE		   RWV 10-04-85
	MOV	AX,9500h		;   YES, SPECIAL CODE FOR THIS ONE RWV 10-04-85
	JMP	K57			;   BUFFER FILL 		   RWV 10-04-85

K42A:	MOV	BX,OFFSET K8		; SET UP TO TRANSLATE CTL
	CMP	AL,59			; IS IT IN CHARACTER TABLE?
	JAE	K42B			;  NO, CTL-TABLE-TRANSLATE-SCAN    RWV 11-06-85
	JMP	K56			;	GO TRANSLATE CHAR
K42B:	MOV	BX,OFFSET K8		; SET UP TO TRANSLATE CTL	   RWV 10-07-85
	JMP	K64			;      GO TRANSLATE_SCAN	   RWV 8-06-85
PAGE
;------ NOT IN CONTROL SHIFT

K44:
	CALL	KEYB_STATE_PROCESSOR   ;;
	JNC	K4401		       ;; NO TRANSLATIONS FOUND - CONTINUE
	RET;JMP     PREP_EXIT			 ;; TRANSLATIONS FOUND - EXIT
K4401:
	CMP	AL,55			; PRINT SCREEN KEY?
	JNE	K45			; NOT-PRINT-SCREEN
	TEST	CS:SD.SYSTEM_FLAG,PC_LAP   ; IS THIS THE LAP COMPUTER?	      RWV 9-12-85
	JZ	K441			;  NO, JUMP			   RWV 9-12-85
	TEST	BH,LC_E0		;  YES, WAS LAST CODE THE MARKER?  RWV 10-08-85
	JZ	K44A			;	NO, TEST THE SHIFT STATE   RWV 9-12-85
	JMP	K45C			;	YES, XLATE TO "*" CHAR     RWV 9-12-85
K441:	TEST	BH,KBX			; IS THIS ENHANCED KEYBOARD?	   RWV 10-08-85
	JZ	K44A			; NO, TEST FOR SHIFT STATE	   RWV 7-30-85
	TEST	BH,LC_E0		; YES, LAST CODE A MARKER?	   RWV 10-08-85
	JNZ	K44B			;  YES, IS PRINT SCREEN 	   RWV 7-30-85
	JMP	SHORT K45C		;  NO, XLATE TO "*" CHARACTER      RWV 7-31-85
K44A:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ;NOT 101 KBD, SHIFT KEY DOWN?   RWV 7-30-85
	JZ	K45C			   ; NO, XLATE TO "*" CHARACTER    RWV 7-30-85

;------ ISSUE INTERRUPT TO PERFORM PRINT SCREEN FUNCTION
K44B:	MOV	AL,ENA_KBD		; INSURE KEYBOARD IS ENABLED
	CALL	SHIP_IT 		; EXECUTE ENABLE
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI			; END OF CURRENT INTERRUPT
	OUT	020H,AL 		;  SO FURTHER THINGS CAN HAPPEN
;***CNS
	JMP	SHORT $+2
;***CNS
	PUSH	BP			; SAVE POINTER
	INT	5H			; ISSUE PRINT SCREEN INTERRUPT
	POP	BP			; RESTORE POINTER
	AND	KB_FLAG_3,NOT LC_E0+LC_E1 ;ZERO OUT THESE FLAGS 	   RWV 8-13-85
;***CNS
	MOV	CS:ENABLE_FL,1
	RET;JMP     ENABLE_CHK		    ; GO BACK WITHOUT EOI OCCURRING
;***CNS


;------ HANDLE THE IN-CORE KEYS
K45:					; NOT-PRINT-SCREEN
	CMP	AL,58			; TEST FOR IN-CORE AREA 	   RWV 7-30-85
	JA	K46			; JUMP IF NOT			   RWV 8-13-85

K450:	TEST	BH,GRAPH_ON		; IS ALT GRAPHICS ON?		   AEV
	JZ	K456			; GO ON IF NOT			   AEV
	RET;JMP     PREP_EXIT			 ;; YES, TRASH KEYSTROKE

K456:	CMP	AL,53			; IS THIS THE "/" KEY?             RWV 8-01-85
	JNE	K45A			;  NO, JUMP			   RWV 8-01-85
	TEST	BH,LC_E0		; WAS LAST CODE THE MARKER?	   RWV 10-08-85
	JNZ	K45C1			;  YES, TRANSLATE TO US CHARACTER  RWV 8-01-85

K45A:

K45A1:	MOV	CX,K30_LEN	; LENGTH OF SEARCH		   RWV 7-30-85
	MOV	DI,OFFSET K30+10	; POINT TO TABLE OF A-Z CHARS	   RWV 7-30-85
	REPNE	SCASB			; IS THIS A LETTER KEY? 	   RWV 7-30-85
	JNE	K45B			;  NO, SYMBOL KEY		   RWV 7-30-85

K45A2:	TEST	BL,CAPS_STATE		; ARE WE IN CAPS_LOCK?		   RWV 7-30-85
	JNZ	K45D			; TEST FOR SURE 		   RWV 7-30-85
K45B:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?	   RWV 7-30-85
	JNZ	K45E			  ; YES, UPPERCASE		   RWV 7-30-85
					  ; NO, LOWERCASE		   RWV 7-30-85
K45C:				       ;;
K45C1:	MOV	BX,OFFSET K10		; XLATE TO LOWERCASE US LETTERS    RWV 8-06-85
	JMP	SHORT K45E2
K45D:					; ALMOST-CAPS-STATE		   RWV 7-30-85
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?	   RWV 7-30-85
	JNZ	K45C1			; SHIFTED TEMP OUT OF CAPS STATE   RWV 7-30-85
K45E:
K45E1:	MOV	BX,OFFSET K11		; XLATE TO UPPERCASE US LETTERS    RWV 8-06-85
K45E2:	JMP	SHORT K56		; GO TRANSLATE			   RWV 8-06-85


;------ TEST FOR KEYS F1 - F10
K46:					; NOT IN-CORE AREA		   RWV 7-30-85
	CMP	AL,68			; TEST FOR F1 - F10		   RWV 7-30-85
	JA	K47			; JUMP IF NOT			   RWV 7-30-85
	JMP	SHORT K53A		; YES, GO DO FN KEY PROCESS	   RWV 7-30-85


;------ HANDLE THE NUMERIC PAD KEYS

K47:					; NOT F1 - F10			   RWV 7-30-85
	CMP	AL,83			; TEST FOR NUMPAD KEYS		   RWV 7-30-85
	JA	K52			; JUMP IF NOT			   RWV 7-30-85

;------ KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
K48:	CMP	AL,74			; SPECIAL CASE FOR MINUS
	JE	K45E1			; GO TRANSLATE (US & WT ARE SAME)  RWV 8-06-85
	CMP	AL,78			; SPECIAL CASE FOR PLUS
	JE	K45E1			; GO TRANSLATE (US & WT ARE SAME)  RWV 8-06-85
	TEST	BH,LC_E0		; IS THIS ONE OF THE NEW KEYS?	   RWV 10-08-85
	JNZ	K49			;  YES, TRANSLATE TO BASE STATE    RWV 8-06-85

	TEST	BL,NUM_STATE		; ARE WE IN NUM_LOCK?		   RWV 7-30-85
	JNZ	K50			; TEST FOR SURE
	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT  ; ARE WE IN SHIFT STATE?	   RWV 7-30-85
	JNZ	K51			   ; IF SHIFTED, REALLY NUM STATE

;------ BASE CASE FOR KEYPAD
K49:	CMP	AL,76			; SPECIAL CASE FOR BASE STATE 5    RWV 10-04-85
	JNE	K49A			; CONTINUE IF NOT KEYPAD 5	   RWV 10-04-85
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 LOADED?   RWV 11-06-85
	JNZ	K491			;  YES, TRANSLATE AS EXTENDED	   RWV 11-06-85
	RET;JMP     PREP_EXIT			  ;  NO, INGORE 		     RWV 11-06-85

K491:	MOV	AL,0F0h 		; SPECIAL ASCII CODE		   RWV 10-04-85
	JMP	K57			; BUFFER FILL			   RWV 10-04-85
K49A:	MOV	BX,OFFSET K10		; BASE CASE TABLE		   RWV 7-30-85
	JMP	SHORT K64		; CONVERT TO PSEUDO SCAN

;------ MIGHT BE NUM LOCK, TEST SHIFT STATUS
K50:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT	;ALMOST-NUM-STATE	   RWV 7-30-85
	JNZ	K49			; SHIFTED TEMP OUT OF NUM STATE
K51:					; REALLY_NUM_STATE		   RWV 8-06-85
	JMP	SHORT K45E1		; (US & WT ARE SAME)		   RWV 8-06-85

;------ TEST FOR THE NEW KEY ON WT KEYBOARDS

K52:					; NOT A NUMPAD KEY		   RWV 7-30-85
	CMP	AL,86			; IS IT THE NEW WT KEY? 	   RWV 7-30-85
	JNE	K53			; JUMP IF NOT			   RWV 7-30-85
	MOV	AL,58			; WE'RE GOING TO PULL A SNEAKY     RWV 8-06-85
	JMP	K45			; TRICK HERE. WT TABLES ARE TOO SHORT TO
					; XLATE 86, SO WE'LL CHANGE IT TO CAPS_LOCK
					; AND PUT THE CHAR IN THE TABLES IN THE C_L
					; POSITION, SINCE C_L SCAN CODES NEVER GET
					; HERE ANYWAY.			   RWV 8-06-85

;------ MUST BE F11 OR F12

K53:	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 THERE?    RWV 11-06-85
;*** CNS
	JZ	K59			;  NO, INGORE F11 & F12 (NEAR RET) RWV 11-06-85
					; F1 - F10 COME HERE, TOO	   RWV 7-30-85
K53A:	TEST	BL,LEFT_SHIFT+RIGHT_SHIFT ;TEST SHIFT STATE		   RWV 7-30-85
	JZ	K49			  ; JUMP, LOWERCASE PSEUDO SC'S    RWV 7-30-85

	MOV	BX,OFFSET K11		; UPPER CASE PSEUDO SCAN CODES
	JMP	SHORT K64		; TRANSLATE_SCAN
PAGE
;------ TRANSLATE THE CHARACTER

K56:					; TRANSLATE-CHAR
	DEC	AL			; CONVERT ORIGIN
	XLAT	CS:K11			; CONVERT THE SCAN CODE TO ASCII
K56C:	TEST	KB_FLAG_3,LC_E0 	; IS THIS A NEW KEY?		   RWV 10-08-85
	JZ	K57			;  NO, GO FILL BUFFER		   RWV 10-04-85
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 THERE?    RWV 11-06-85
	JZ	K57			;  NO, DO COMPATIBLE OUTPUT	   RWV 11-06-85
	MOV	AH,MC_E0		;  YES, PUT SPECIAL MARKER IN AH   RWV 10-04-85
	JMP	SHORT K57		; PUT IT INTO THE BUFFER

;------ TRANSLATE SCAN FOR PSEUDO SCAN CODES

K64:					; TRANSLATE-SCAN-ORGD
	DEC	AL			; CONVERT ORIGIN		   RWV 8-06-85
	XLAT	CS:K8			; CTL TABLE SCAN
	MOV	AH,AL			; PUT VALUE INTO AH
	MOV	AL,0			; ZERO ASCII CODE
	TEST	KB_FLAG_3,LC_E0 	; IS THIS A NEW KEY?		   RWV 10-08-85
	JZ	K57			;  NO, GO FILL BUFFER		   RWV 10-04-85
	TEST	CS:SD.SYSTEM_FLAG,EXT_16   ; IS THE EXTENDED INT 16 THERE?    RWV 11-06-85
	JZ	K57			;  NO, DO COMPATIBLE OUTPUT	   RWV 11-06-85
	MOV	AL,MC_E0		;  YES, PUT SPECIAL MARKER IN AL   RWV 10-04-85

;------ PUT CHARACTER INTO BUFFER

K57:					; BUFFER-FILL
	CALL	BUFFER_FILL	       ;;
K59:				       ;;
	RET			       ;; return to unload the buffer
;OLDK59:
;	 JMP	 PREP_EXIT		      ;; THAT'S ALL FOLKS

				       ;;
				       ;;
KEYB_INT_9   ENDP		       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: BUFFER_FILL
;;
;; Description:
;;     Generate keyboard buffer entry
;;
;; Input Registers:
;;     AX - the buffer entry
;;     DS - BIOS data segment
;;
;; Output Registers:
;;     None
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
BUFFER_FILL	PROC   NEAR	       ;;
				       ;;
	CMP	AL,-1		       ;; IS THIS AN IGNORE CHAR
	JE	K61B		       ;; YES, EXIT
	CMP	AH,-1		       ;; LOOK FOR -1 PSEUDO SCAN
	JE	K61B		       ;; EXIT
;;
;; BUFFER_FILL_ANY_CHAR is an alternate entry point to this PROC.
;; Entry at this point will avoid trashing ASCII values of 255.
;;
BUFFER_FILL_ANY_CHAR  LABEL  NEAR      ;;
				       ;;
	PUSH	SI		       ;;
	PUSH	BX		       ;;
	PUSH	DS		       ;; This routine may be called
	PUSH	AX		       ;;  externally so make sure DS points
	MOV	AX,DATA 	       ;;   to BIOS data
	MOV	DS,AX		       ;;
	POP	AX		       ;;
				       ;;
	CLC			       ;;

	MOV	BX,BUFFER_TAIL		; GET THE END POINTER TO THE BUFFER
	MOV	SI,BX			; SAVE THE VALUE
	INC	BX		       ;; MOVE TO NEXT WORD IN LIST
	INC	BX		       ;;
				       ;;
;; VERIFY IF THE CURRENT ROM LEVEL IN THE SYSTEM IS FOR THE ORIGINAL PC1
				       ;;
	PUSH	AX		       ;; SAVE AX,DS
	PUSH	DS		       ;;
	MOV	AX,ROM_SEG	       ;; SET DS TO POINT AT BIOS ROM SEGMENT
	MOV	DS,AX		       ;; TEST FOR PC1 ROM INSTALLED
	CMP	WORD PTR DS:SYSROM_DATE,PC1DATE_ID
	POP	DS		       ;; RESTORE DS,AX
	POP	AX		       ;;
	JNE	NOT_PC1 	       ;; IF IT'S A LATER ROM RELEASE, BRANCH
				       ;;
	CMP	BX,OFFSET KB_BUFFER_END ; AT END OF BUFFER?
	JNE	K5		       ;; NO, CONTINUE
	MOV	BX,OFFSET KB_BUFFER    ;; YES, RESET TO BUFFER BEGINNING
	JMP	K5		       ;;
NOT_PC1:			       ;;
	CMP	BX,BUFFER_END	       ;; AT END OF BUFFER?
	JNE	K5		       ;; NO, CONTINUE
	MOV	BX,BUFFER_START        ;; YES, RESET TO BUFFER BEGINNING
K5:				       ;;
	CMP	BX,BUFFER_HEAD	       ;; HAS THE BUFFER WRAPPED AROUND
	JE	K62		       ;; BUFFER_FULL_BEEP
	MOV	[SI],AX 	       ;; STORE THE VALUE
	MOV	BUFFER_TAIL,BX	       ;; MOVE THE POINTER UP
	MOV	CS:BUFFER_ENTRY_OK,YES ;; INDICATE WE PUT SOMETHING IN BUFFER
	JMP	SHORT K61A
K62:
	MOV	CS:BEEP_PENDING,YES    ;; INDICATE WE NEED A BEEP
	TEST	CS:SD.SYSTEM_FLAG,PC_JR ;; ON JR WE HAVE TO CLEAR SOME FLAGS
	JZ	K61A		       ;;
	AND	KB_FLAG,0F0H	       ;; CLEAR SHIFTS
	AND	KB_FLAG_1,0FH	       ;;
	AND	KB_FLAG_2,1FH	       ;; CLEAR FUNCTION STATES
K61A:				       ;;
	POP	DS		       ;;
	POP	BX		       ;;
	POP	SI		       ;;
K61B:				       ;;
	RET			       ;;
BUFFER_FILL	ENDP		       ;;
PAGE				       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: KB_NOISE
;;
;; Description:
;;     General routine to generate beep tones
;;
;; Input Registers:
;;     BX - length of tone
;;     CX - tone frequency (larger CX = lower pitch)
;;
;; Output Registers:
;;     AX,BX,CX trashed
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
BEEPING 	DB	0	       ;; 1 if beep already in progress
				       ;;
KB_NOISE    PROC		       ;;
	CMP	CS:BEEPING,0	       ;; ARE WE BEEPING?
	JE	NOT_BEEPING_YET        ;;
	RET			       ;; YES - RETURN
NOT_BEEPING_YET:		       ;;
	MOV	CS:BEEPING,1	       ;; beep in progress
				       ;;
	STI			       ;;
				       ;;
	IN     AL,061H		       ;; Get control info
	PUSH   AX		       ;;
LOOP01: 			       ;;
	AND    AL,0FCH		       ;; Turn off timer gate and speaker
	OUT    061H,AL		       ;; output to control
	PUSH   CX		       ;; half cycle time for tone
LOOP02: 			       ;;
	LOOP   LOOP02		       ;; speaker off
	OR     AL,2		       ;; turn on speaker
	OUT    061H,AL		       ;; output to control
	POP    CX		       ;;
	PUSH   CX		       ;;
LOOP03: 			       ;;
	LOOP   LOOP03		       ;; another half cycle
	DEC    BX		       ;; time count
	POP    CX		       ;; another cycle
	JNZ    LOOP01		       ;;
	POP    AX		       ;;
	OUT    061H,AL		       ;; restore control
				       ;;
				       ;;
	MOV	CS:BEEPING,0	       ;; indicate beep over
	RET			       ;;
KB_NOISE    ENDP		       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: DUMBJMP
;;
;; Description:
;;     Dummy JUMP used to allow smooth exit
;;     for XT & older machines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
DUMBJMP     PROC		       ;;
	JMP	UP1		       ;; ARE WE BEEPING?
DUMBJMP    ENDP 		      ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: ERROR_BEEP
;;
;; Description:
;;     Call KB_NOISE to generate a beep.
;;
;; Input Registers:
;;     None
;;
;; Output Registers:
;;     None
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
				       ;;
ERROR_BEEP	PROC	NEAR	       ;;
				       ;;
	PUSH	AX		       ;; SAVE REGS
	PUSH	BX		       ;;
	PUSH	CX		       ;;
				       ;;
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI		       ;; ENABLE INTR. CTL. CHIP
	OUT	INTA00,AL	       ;;
;***CNS
	JMP	SHORT $+2
;***CNS
				       ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_JR
	JZ	EB_TEST_1	       ;; The JR
	MOV	BX,80H		       ;; NUMBER OF CYCLES FOR 1/8 SECOND TONE
	MOV	CX,021H 	       ;; FREQUENCY
	JMP	SHORT BEEP_IT	       ;;
EB_TEST_1:			       ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_XT+PC_PAL+PC_LAP
	JZ	EB_TEST_2	       ;; 8088/8886 MACHINE
	MOV	BX,80H		       ;; NUMBER OF CYCLES FOR 1/8 SECOND TONE
	MOV	CX,048H 	       ;; FREQUENCY
	JMP	SHORT BEEP_IT	       ;;
EB_TEST_2:			       ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_386
	JZ	EB_TEST_3	       ;; 386 MACHINE
	MOV	BX,80H		       ;;
	MOV	CX,19CH 	       ;; FREQUENCY
	JMP	SHORT BEEP_IT	       ;;
EB_TEST_3:			       ;;
	MOV	BX,80H		       ;; DEFAULT TO 286 MACHINE
	MOV	CX,0CEH 	       ;; FREQUENCY
BEEP_IT:			       ;;
	CALL	KB_NOISE	       ;;
				       ;;
	POP	CX		       ;; RESTORE REGS
	POP	BX		       ;;
	POP	AX		       ;;
	RET			       ;; RETURN
ERROR_BEEP	ENDP		       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;	SHIP_IT
;;
;;	THIS ROUTINE HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
;;	TO THE KEYBOARD CONTROLLER.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
SHIP_IT PROC	NEAR		       ;;
				       ;;
;------- TEST SYSTEM TYPE	       ;;
				       ;;
	TEST	CS:SD.SYSTEM_FLAG,PC_AT+PC_386	  ; IF THE SYSTEM WE'RE RUNNING ON IS A
	JNZ	SI1		       ;; PCAT, EXECUTE THIS ROUTINE,
	RET			       ;; ELSE RET
				       ;;
				       ;;
SI1:	PUSH	AX		       ;; SAVE DATA TO SEND
				       ;;
;;;-- WAIT FOR COMMAND TO BE ACCEPTED  ;;
	CLI			       ;; DISABLE INTERRUPTS
				       ;;
	CALL   WAIT_ON_STATUS_PORT     ;;
				       ;;
	POP	AX		       ;; GET DATA TO SEND
	OUT	STATUS_PORT,AL	       ;; SEND TO KEYBOARD CONTROLLER
	STI			       ;; ENABLE INTERRUPTS AGAIN
	RET			       ;; RETURN TO CALLER
SHIP_IT ENDP			       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Procedure: WAIT_ON_STATUS_PORT
;;
;; Description:
;;     Waits for a keyboard command to be accepted
;;
;; Input Registers:
;;     None
;;
;; Output Registers:
;;     None
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
WAIT_ON_STATUS_PORT   PROC NEAR        ;;
				       ;;
;---- WAIT FOR COMMAND TO BE ACCEPTED  ;;
				       ;;
	MOV	CX,CS:SD.TIMING_FACTOR ;; PROCESSOR SCALE FACTOR; PCAT = 1
W01:				       ;;
	PUSH	CX		       ;;
	SUB	CX,CX		       ;;
W02:				       ;;
	IN	AL,STATUS_PORT	       ;;
	TEST	AL,INPT_BUF_FULL       ;;
	LOOPNZ	W02		       ;; WAIT FOR COMMAND TO BE ACCEPTED
	POP	CX		       ;;
	LOOPNZ	W01		       ;;
				       ;;
	RET			       ;;
				       ;;
WAIT_ON_STATUS_PORT   ENDP	       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;	SND_DATA
;;
;;	THIS ROUTINE HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
;;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS.  IT ALSO
;;	HANDLES ANY RETRIES IF REQUIRED
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
SND_DATA PROC	NEAR		       ;;
	PUSH	AX		       ;; SAVE REGISTERS
	PUSH	BX		       ;; *
	PUSH	CX		       ;;
	MOV	BH,AL		       ;; SAVE TRANSMITTED BY FOR RETRIES
	MOV	BL,3		       ;; LOAD RETRY COUNT
SD0:	CLI			       ;; DISABLE INTERRUPTS
	AND	KB_FLAG_2,NOT (KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
				       ;;
	CALL	WAIT_ON_STATUS_PORT    ;;
				       ;;
	MOV	AL,BH		       ;; REESTABLISH BYTE TO TRANSMIT
	OUT	PORT_A,AL	       ;; SEND BYTE
	STI			       ;; ENABLE INTERRUPTS
	MOV	AX,01A00H	       ;; LOAD COUNT FOR 10mS+
	MUL	CS:SD.TIMING_FACTOR    ;; ACCOUNT FOR PROCESSOR SPEED
	MOV	CX,AX		       ;;
SD1:	TEST	KB_FLAG_2,KB_FE+KB_FA  ;; SEE IF EITHER BIT SET
	JNZ	SD3		       ;; IF SET, SOMETHING RECEIVED GO PROCESS
				       ;;
	LOOP	SD1		       ;; OTHERWISE WAIT
				       ;;
SD2:	DEC	BL		       ;; DECREMENT RETRY COUNT
	JNZ	SD0		       ;; RETRY TRANSMISSION
				       ;;
	OR	KB_FLAG_2,KB_ERR       ;; TURN ON TRANSMIT ERROR FLAG
	JMP	SHORT SD4	       ;; RETRIES EXHAUSTED FORGET TRANSMISSION
				       ;;
SD3:	TEST	KB_FLAG_2,KB_FA        ;; SEE IF THIS IS AN ACKNOWLEDGE
	JZ	SD2		       ;; IF NOT, GO RESEND
				       ;;
SD4:	POP	CX		       ;; RESTORE REGISTERS
	POP	BX		       ;;
	POP	AX		       ;; *
	RET			       ;; RETURN, GOOD TRANSMISSION
SND_DATA ENDP			       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;	SND_LED
;;
;;	THIS ROUTINE TURNS ON THE MODE INDICATORS.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
SND_LED PROC	NEAR		       ;;
	CLI			       ;; TURN OFF INTERRUPTS
	TEST	KB_FLAG_2,KB_PR_LED    ;; CHECK FOR MODE INDICATOR UPDATE
	JNZ	SL1		       ;; DONT UPDATE AGAIN IF UPDATE UNDERWAY
				       ;;
	OR	KB_FLAG_2,KB_PR_LED    ;; TURN ON UPDATE IN PROCESS
;***CNS
	JMP	SHORT $+2
;***CNS
	MOV	AL,EOI		       ;; END OF INTERRUPT COMMAND
	OUT	020H,AL 	       ;; SEND COMMAND TO INTERRUPT CONTROL PORT
;***CNS
	JMP	SHORT $+2
;***CNS
	JMP	SHORT SL0	       ;; GO SEND MODE INDICATOR COMMAND
				       ;;
SND_LED1:			       ;;
	CLI			       ;; TURN OFF INTERRUPTS
	TEST	KB_FLAG_2,KB_PR_LED    ;; CHECK FOR MODE INDICATOR UPDATE
	JNZ	SL1		       ;; DONT UPDATE AGAIN IF UPDATE UNDERWAY
				       ;;
	OR	KB_FLAG_2,KB_PR_LED    ;; TURN ON UPDATE IN PROCESS
SL0:	MOV	AL,LED_CMD	       ;; LED CMD BYTE
	CALL	SND_DATA	       ;; SEND DATA TO KEYBOARD
	CLI			       ;;
	CALL	MAKE_LED	       ;; GO FORM INDICATOR DATA BYTE
	AND	KB_FLAG_2,0F8H	       ;; CLEAR MODE INDICATOR BITS
	OR	KB_FLAG_2,AL	       ;; SAVE PRESENT INDICATORS STATES FOR NEXT TIME
	TEST	KB_FLAG_2,KB_ERR       ;; TRANSMIT ERROR DETECTED
	JNZ	SL2		       ;; IF YES, BYPASS SECOND BYTE TRANSMISSION
				       ;;
	CALL	SND_DATA	       ;; SEND DATA TO KEYBOARD
	CLI			       ;; TURN OFF INTERRUPTS
	TEST	KB_FLAG_2,KB_ERR       ;; TRANSMIT ERROR DETECTED
	JZ	SL3		       ;; IF NOT, DONT SEND AN ENABLE COMMAND
				       ;;
SL2:	MOV	AL,KB_ENABLE	       ;; GET KEYBOARD CSA ENABLE COMMAND
	CALL	SND_DATA	       ;; SEND DATA TO KEYBOARD
	CLI			       ;; TURN OFF INTERRUPTS
SL3:	AND	KB_FLAG_2,NOT(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
				       ;; UPDATE AND TRANSMIT ERROR FLAG
SL1:	STI			       ;; ENABLE INTERRUPTS
	RET			       ;; RETURN TO CALLER
SND_LED ENDP			       ;;
PAGE				       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;	MAKE_LED
;;
;;	THIS ROUTINE FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
;;	THE MODE INDICATORS
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				       ;;
MAKE_LED PROC	NEAR		       ;;
	PUSH	CX		       ;; SAVE CX
	MOV	AL,KB_FLAG	       ;; GET CAPS & NUM LOCK INDICATORS
	AND	AL,CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
	MOV	CL,4		       ;; SHIFT COUNT
	ROL	AL,CL		       ;; SHIFT BITS OVER TO TURN ON INDICATORS
	AND	AL,07H		       ;; MAKE SURE ONLY MODE BITS ON
	POP	CX		       ;;
	RET			       ;; RETURN TO CALLER
MAKE_LED ENDP			       ;;
				       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;CNS***

CODE	ENDS
	END
