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