diff options
Diffstat (limited to '')
-rw-r--r-- | private/mvdm/dos/v86/cmd/keyb/keybi9c.asm | 1768 |
1 files changed, 1768 insertions, 0 deletions
diff --git a/private/mvdm/dos/v86/cmd/keyb/keybi9c.asm b/private/mvdm/dos/v86/cmd/keyb/keybi9c.asm new file mode 100644 index 000000000..a30c30082 --- /dev/null +++ b/private/mvdm/dos/v86/cmd/keyb/keybi9c.asm @@ -0,0 +1,1768 @@ +PAGE ,132 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; (C) Copyright Microsoft Corp. 1987-1990 +;; MS-DOS 5.00 - NLS Support - KEYB Command +;; +; File Name: KEYBI9C.ASM +; ---------- +; +; +; Description: +; ------------ +; Interrupt 9 mainline. +; This routine handles all US keyboard support for the following +; system units: PC, PC-XT, PC-AT, PC Convertible, PC-XT/286 +; Models 25 and 30 (PALACE), +; PS/2's - all 8042 based 80286, 80386 and 80486. +; - all PATRIOT and SEBRING based systems. +; KEYB_STATE_PROCESSOR is called for non-US keyboard support. +; +; +; +; 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: +; --------------- +; ; - DCR 478 - KEYBOARD INT SPLICING Nick Savage ;deleted by AN005 +; ; - PTM 3090 ENABLING RIGHT CTL FOR RE-BOOTING +; ; - PTM 60XX PICK UP ALL KEYBOARD BIOS PTR's AND DCR's TO BRING +; INT 9h UP TO THE TOPHAT (80486) SUPPORT LEVEL. '89 jwg +; PTR 6600736 Keep INT's disabled till after PORT 60h read. +; PTR 6600756 EXTRA EOI ISSUED IF INTERRUPTS SATURATED ********** +; NOTE: This is a fix for a BIOS bug that goes all +; the way back to the first AT. The rationale for +; the fix is as follows: +; (deleted AN005) A stack frame is created upon entry (BP) and +; CHK_EOI is called to check the frame. If no +; EOI has been issued, CHK_EOI does it and +; resets the frame, preventing any additinal +; EOI's from being issued on subsequent calls +; to CHK_EOI. All direct EOI's in the code +; have been replaced with calls to CHK_EOI. +; +; ;Ax004; - PTM 2555 KEYB command locks keyboard. 10/5/89;cja +; ; jwg 11/09/98 Updates - Wild Mouse, etc workaround..... +; ; - PTM 5802 Restructure Interrupt Splicing to correct lost Mouse +; interrupt when LED's are updated. Make it apply to +; all systems. Essentially remove all code added by AN001. +; Remove stack frame logic of AN003 and PTR 6600756 and do +; an early EOI. Requires a CLI at K38B and other places. +; Remove Chk_ibf before 60h. +; Re-write ERROR_BEEP to make processor speed independent +; for AT and PS/2 systems and right tone if interrupts. +; Make SHIP_IT handle call on PC machines. +; Use BP to hold system flags during interrupt processing. +; PTR 6602049 Fix problem with Pause Key hanging system if Mouse +; driver is using polled mode. (Port 60h hangs.) +; PTR 6602247 Change JMP at K40 to stop extra Enable Keyboard cmd. +; PTR 6602319 Fix interrupt window on System Request key allowing +; following scan code(s) to be processed out of sequence. +; PTR 6602355 Fix Print Screen clearing E0 state flags too late. +; ; - ;deleted Add code the clear "Wild Mouse" condition at PAUSE wait. +; ; - PTM 6660 Move determination code for original PC1 to COMMSUBS.ASM +; - ;jwg 2/90 Add Patriot/Sebring HOT REPLUG code so keyboard can be +; switched back to Scan Code Set 1 if repluged. LIB LITE +; ; - PTM 6680 Remove code attempting to re-sync BIOS flags with reset +; Keyboard. Test case simulators can/are sending invalid +; sequence of AA,AA. Must leave BIOS flags alone on POR. +; ; - PTM 6716 MicroSoft WORKS (German version) reentrancy problem with +; - ;jwg 3/90 NLS state processor and save scan code. LED update ACK +; overlays memory before NLS processing of scan code. +; Remove AN006 "Wild Mouse" reset code, field tests done. +; ; - PTM ???? Fix read ID logic to recognize 122 keyboards and set the +; ;jwg 8/90 KBX flag on any enhansed keyboard. +; ; - PTM ???? Add 122 Keyboard key support tables. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + 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 + +include bop.inc +include vint.inc + + PUBLIC KEYB_INT_9 + PUBLIC K8 ; CTRL case tables + PUBLIC SCAN_CODE + PUBLIC BUFFER_FILL + PUBLIC COUNTRY_FLAG + + + PUBLIC COPY_NLS1_FLAG ;; (YST) + + + PUBLIC BEEP_PENDING + PUBLIC ERROR_BEEP + PUBLIC CHK_IBF + + + +ID_1 EQU 0ABH ; 1ST ID CHARACTER FOR KBX +TID_2 EQU 041H ; US G-LAYOUT +TID_2A EQU 054H ; US P-LAYOUT + +;UNTRANSLATED 2ND ID CHAR FOR KBDX +ID_2U EQU 083H ; US G-LAYOUT (PATRIOT) +ID_2AU EQU 084H ; US P-LAYOUT (PATRIOT) +ID_122 EQU 086H ; 2ND ID CHARACTER FOR 122-KEYBOARD +ID_2JG EQU 090H ; JPN G-LAYOUT +ID_2JP EQU 091H ; JPN P-LAYOUT +ID_2JA EQU 092H ; JPN A-LAYOUT + + +DIAGS SEGMENT AT 0FFFFH + ORG 0 +RESET LABEL FAR +DIAGS ENDS + + +CODE SEGMENT PUBLIC 'CODE' + ASSUME CS:CODE,DS:DATA + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; 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,44,45,46,47,48 + DB 49,50 +K30_LEN EQU $-K30-10 + +;------ ALT-INPUT-FUNCTION-TABLE 53H - 7EH +K30A LABEL BYTE + DB -1,-1,-1,-1,139,140 ; Del, SysReq, Undef, WT, F11, F12 + DB -1,235,218,219,220 ; Undef, PA1, F13, F14, F15 + DB -1,-1,-1,-1,-1 ; Pause, Undef 5F-62 + DB 221,222,223,226,227 ; F16, F17, F18, F19, F20, + DB 228,229,230,231 ; F21, F22, F23, F24, + DB -1,243,-1,-1 ; K#69, ErEOF, Break, Play, + DB -1,-1,-1,-1,-1 ; Undef, Attn, CrSel, K#56, ExSel + DB -1,253 ; K#74, Clear, +ifdef NOT_NTVDM +;;* DB -1,-1,-1 ; Undef, K#109, Undef +;;* DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, Undef +else + DB -1,-1,-1 ; Undef, K#109, Undef + DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, K#107 +endif + +H_LAST_SCAN EQU $-K30A+52h ; Largest valid scan code in table + ; K30A K8 K15 K14 must have same ends + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 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 + ;---------- 122 KEYBOARD not overlaid + DB -1,234,206,207,208 ; Undef, PA1, F13, F14, F15 + DB -1,-1,-1,-1,-1 ; Pause, Undef 5F-62 + DB 209,210,211,212,213 ; F16, F17, F18, F19, F20, + DB 214,215,216,217 ; F21, F22, F23, F24, + DB -1,242,-1,-1 ; K#69, ErEOF, Break, Play, + DB -1,-1,-1,-1,-1 ; Undef, Attn, CrSel, K#56, ExSel + DB -1,252 ; K#74, Clear, +ifdef NOT_NTVDM +;;* DB -1,-1,-1 ; Undef, K#109, Undef +;;* DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, Undef +else + DB -1,-1,-1 ; Undef, K#109, Undef + DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, K#107 +endif + +;----- 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 ; Home, Up, PgUp, -1, Left, -1 + DB 77,-1,79,80,81,82 ; Right, -1, End, Down, PgDn, Ins + DB 83 ; Del + DB -1,-1,'\',133,134 ; SysRq, Undef, WT, F11, F12 + DB -1,232,182,183,184 ; Undef, PA1, F13, F14, F15 + DB -1,-1,-1,-1,-1 ; Pause, Undef 5F-62 + DB 185,186,187,188,189 ; F16, F17, F18, F19, F20, + DB 190,191,192,193 ; F21, F22, F23, F24, + DB -1,240,-1,-1 ; K#69, ErEOF, Break, Play, + DB -1,-1,-1,-1,-1 ; Undef, Attn, CrSel, K#56, ExSel + DB -1,251 ; K#74, Clear, +ifdef NOT_NTVDM +;;* DB -1,-1,-1 ; Undef, K#109, Undef +;;* DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, Undef +else + DB -1,-1,-1 ; Undef, K#109, Undef + DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, K#107 +endif + +;------- 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 + DB -1,233,194,195,196 ; Undef, PA1, F13, F14, F15 + DB -1,-1,-1,-1,-1 ; Pause, Undef 5F-62 + DB 197,198,199,200,201 ; F16, F17, F18, F19, F20, + DB 202,203,204,205 ; F21, F22, F23, F24, + DB -1,241,-1,-1 ; K#69, ErEOF, Break, Play, + DB -1,-1,-1,-1,-1 ; Undef, Attn, CrSel, K#56, ExSel + DB -1,251 ; K#74, Clear, +ifdef NOT_NTVDM +;;* DB -1,-1,-1 ; Undef, K#109, Undef +;;* DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, Undef +else + DB -1,-1,-1 ; Undef, K#109, Undef + DB -1,-1,-1,-1,-1 ; Undef, Undef, K#94, K#14, K#107 +endif +PAGE +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Procedure: KEYB_INT_9 +; +; Description: +; Entry point for interrupt 9 processing. +; +; Input Registers: +; None +; +; Output Registers: +; None +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + EVEN ; Keep KEYB_INT_9 entry on even boundry +BEEP_PENDING DB NO ; YES if a beep is needed +SCAN_CODE DB 0 ; Last SCAN code read + +KEYB_INT_9 PROC NEAR + + JMP SHORT KB_INT_1 ;; (YST) +COPY_NLS1_FLAG DB 0 ;; (YST) +COUNTRY_FLAG DB -1 ; WHERE THE INT9 VECTOR POINTS + +KB_INT_1: + + ; Do NOT enable interrupts untill after + ; PORT 60h has been read. INT 15h has + ; interrupt window, do EOI, fast pass. + PUSH BP ; Reserved in KEYBi9c for SD.SYSTEM_FLAG + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + CLD ; FORWARD DIRECTION + MOV BX,DATA ; SET UP ADDRESSING + MOV DS,BX ; DS POINTS AT THE ROM BIOS DATA AREA + MOV BP,CS:SD.SYSTEM_FLAG ; GET CS:SD.SYSTEM_FLAG, AND USE BP + + +ifdef NOT_NTVDM +;/* -- WAIT TILL KEYBOARD DISABLE COMMAND CAN BE ACCEPTED + MOV AL,DIS_KBD ; DISABLE THE KEYBOARD COMMAND + CALL SHIP_IT ; EXECUTE DISABLE +else + mov ah, 1 ; notify I9 entry to softpc + BOP 09h + nop ; Carbon copy traces for + nop ; "in al,PORT_A" +endif ; keep it traceable + + IN AL,PORT_A ; READ IN THE CHARACTER + + +;/* -- 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 + +ifdef NOT_NTVDM + ; EARLY EOI for all interrupts done + ; after INT 15h to prevent re-entrancy + XCHG BX,AX ; SAVE SCAN CODE + MOV AL,EOI ; END OF INTERRUPT COMMAND (EARLY EOI) + OUT INTA00,AL ; SEND EOI TO INTERRUPT CONTROL PORT + XCHG BX,AX ; RECOVER SCAN CODE +endif + + JC KB_INT_02 ; CONTINUE IF CARRY FLAG SET ((AL)=CODE) + JMP K26 ; EXIT IF SYSTEM HANDLED SCAN CODE + ; EXIT HANDLES ENABLE + +;/* --- CHECK FOR A POSSIBLE HOT REPLUG AND A POR COMPLETE CODE +KB_INT_02: ; (AL)= SCAN CODE + +ifdef NOT_NTVDM +; ntvdm we don't do keyboard resets\power on stuff +; + ; CHECK FOR POR + CMP AL,KB_OK ; CHECK FOR POSSIBLE KEYBOARD POR CHAR + JNE KB_INT_03 ; CONTINUE NOT A POR OF AA + ; CHECK FOR ENHANSED KEYB + TEST KB_FLAG_3,LC_E0 ; WAS E0h LAST SCAN CODE? DCR467 + JNZ KB_INT_03 ; SKIP KB POR IF IT WAS + ; CHECK FOR LEFT SHIFT BREAK + TEST KB_FLAG,LEFT_SHIFT ; IS LEFT SHIFT ACTIVE? + JNZ KB_INT_03 ; SKIP KB POR IF IT WAS + ; KEYBOARD POWER ON DETECTED + MOV CS:BEEP_PENDING,YES ; INDICATE WE NEED A BEEP + MOV KB_FLAG_2,0 ; CLEAR ALL LED FLAGS TO FORCE UPDATE + ; LEAVE OTHERS SO KB SIMULATORS WORK + + TEST BP,PS_8042 ; SYSTEM USING 8042 & SCAN CODE SET 01? + JZ KB_INT_03 ; SKIP IF SYSTEM USES DEFAULT SCS 02 + ; PATRIOT/SEBRING 8042 GATE ARRAY + MOV AL,SCAN_CODE_CMD ; SELECT SCAN CODE SET COMMAND + CALL SND_DATA ; SEND IT DIRECTLY TO THE KEYBOARD + MOV AL,01h ; SELECT SCAN CODE SET 01 + CALL SND_DATA ; SEND IT TO THE KEYBOARD + MOV AL,KB_OK ; RESTORE POR SCAN CODE IN (AL) +endif + +KB_INT_03: + +;/* --- CHECK FOR A RESEND COMMAND TO KEYBOARD + + ;; NTVDM 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 + + ;; NTVDM CLI ; DISABLE INTERRUPTS + OR KB_FLAG_2,KB_FA ; INDICATE ACK RECEIVED + JMP K26 ; RETURN IF NOT (ACK RETURNED FOR DATA) + +;/* --- RESEND THE LAST BYTE + +KB_INT_4: + ;; NTVDM CLI ; DISABLE INTERRUPTS + OR KB_FLAG_2,KB_FE ; INDICATE RESEND RECEIVED + JMP K26 ; 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,KB_LEDS ; ISOLATE INDICATOR BITS + JZ UP0 ; IF NO CHANGE BYPASS UPDATE + CALL SND_LED ; GO TURN ON MODE INDICATORS +UP0: POP AX ; RESTORE DATA IN + +;--------------------------------------------------------------------- +; START OF KEY PROCESSING - +;--------------------------------------------------------------------- + + MOV AH,AL ; SAVE SCAN CODE IN AH ALSO + ; END OF RE-ENTRANT CODE PATHS + MOV CS:SCAN_CODE,AL ; SAVE SCAN CODE TO BE PROCESSED BY KEYB + +;------ TEST FOR OVERRUN SCAN CODE FROM KEYBOARD + + CMP AL,KB_OVER_RUN ; IS THIS AN OVERRUN CHAR? + JNZ K16 ; NO, TEST FOR SHIFT KEY + + MOV CS:BEEP_PENDING,YES + JMP K26 ; BUFFER_FULL_BEEP, EXIT + +K16: + + PUSH CS + POP ES ; ESTABLISH ADDRESS OF TABLES + MOV BH, KB_FLAG_3 ; LOAD FLAGS FOR TESTING + +;------ TEST TO SEE IF A READ_ID IS IN PROGRESS + + TEST BH,RD_ID+LC_AB ; ARE WE DOING A READ ID? + 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 + + +;------ CHECK 2ND US KBD ID - FOR SETTING NUM LOCK ON +TST_ID_2: + AND KB_FLAG_3,NOT LC_AB ; RESET FLAG + OR KB_FLAG_3,KBX ; INDICATE ENHANCED KEYBOARD WAS FOUND + CMP AL,TID_2 ; IS THIS US G-LAYOUT KBD w 8042 + JE NUM_LOCK_000 ; JUMP IF SO + CMP AL,ID_2U ; IS THIS US G-LAYOUT KBD w/o 8042 + JE NUM_LOCK_000 ; JUMP IF SO + CMP AL,ID_122 ; IS THIS THE 122 KEY ENHANCED KEYBOARD + JE NUM_LOCK_000 ; JUMP IF SO + +;------ CHECK 2ND JAPANESE KBD ID ;DCR355 + + CMP AL,ID_2JG ; IS THIS JPN KBD - G ? + JE NUM_LOCK_000 ; JUMP IF SO + CMP AL,ID_2JA ; IS THIS JPN KBD - A ? + JNE ID_EX ; EXIT IF NUM LOCK NOT REQUIRED + ; These ID's do not set NUM LOCK ON + ; ID_2AU = US P-LAYOUT KBD w/o 8042 + ; TID_2A = US P-LAYOUT KBD w 8042 + ; ID_2JP = JPN KBD - P + +;------ A READ ID SAID THAT IT WAS ENHANCED KEYBOARD + +NUM_LOCK_000: + TEST BH,SET_NUM_LK ; SHOULD WE SET NUM LOCK? + JZ ID_EX ; EXIT IF NOT + OR KB_FLAG,NUM_STATE ; FORCE NUM LOCK ON + CALL SND_LED ; GO SET THE NUM LOCK INDICATOR +ID_EX: + JMP K26 ; EXIT +PAGE +NOT_ID: + CMP AL,MC_E0 ; IS THIS THE GENERAL MARKER CODE? + JNE TEST_E1 + OR KB_FLAG_3,LC_E0+KBX ; SET FLAG BIT, SET KBX, AND + JMP SHORT EXIT ; THROW AWAY THIS CODE + +TEST_E1: + CMP AL,MC_E1 ; IS THIS THE PAUSE KEY? + JNE NOT_HC + OR KB_FLAG_3,LC_E1+KBX ; SET FLAG, PAUSE KEY MARKER CODE +EXIT: JMP K26A ; THROW AWAY THIS CODE + +NOT_HC: + AND AL,07FH ; TURN OFF THE BREAK BIT + TEST BH,LC_E0 ; LAST CODE THE E0 MARKER CODE? + JZ NOT_LC_E0 ; JUMP IF NOT + + MOV CX,2 ; LENGTH OF SEARCH + MOV DI,OFFSET K6+6 ; IS THIS A SHIFT KEY? + REPNE SCASB ; CHECK IT + JNE K16A ; NO, CONTINUE KEY PROCESSING + JMP SHORT K16B ; YES, THROW AWAY & RESET FLAG + +NOT_LC_E0: + TEST BH,LC_E1 ; LAST CODE THE E1 MARKER CODE? + JZ T_SYS_KEY ; JUMP IF NOT + + MOV CX,4 ; LENGTH OF SEARCH + MOV DI,OFFSET K6+4 ; IS THIS AN ALT, CTL, OR SHIFT? + REPNE SCASB ; CHECK IT + JE EXIT ; THROW AWAY IF SO + + CMP AL,NUM_KEY ; IS IT THE PAUSE KEY? + JNE K16B ; NO, THROW AWAY & RESET FLAG + TEST AH,80H ; YES, IS IT THE BREAK OF THE KEY? + JNZ K16B ; YES, THROW THIS AWAY, TOO + TEST KB_FLAG_1,HOLD_STATE ; NO, ARE WE PAUSED ALREADY? + JNZ K16B ; YES, THROW AWAY + JMP K39P ; NO, THIS IS THE REAL PAUSE STATE +PAGE +;------ TEST FOR SYSTEM KEY + +T_SYS_KEY: + CMP AL,SYS_KEY ; IS IT THE SYSTEM KEY? + JNE K16A ; CONTINUE IF NOT + + TEST AH,080H ; CHECK IF THIS A BREAK CODE + ;; NTVDM CLI ; DISABLE INTERRUPTS PTR 6602319 + 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 + +ifdef NOT_NTVDM + MOV AL,ENA_KBD ; INSURE KEYBOARD IS ENABLED + CALL SHIP_IT ; EXECUTE ENABLE +else + mov ah, 3 ; K27A exit notify + BOP 09h +endif + MOV AX,08500H ; FUNCTION VALUE FOR MAKE OF SYSTEM KEY + INT 15H ; USER INTERRUPT + JMP K27A ; END PROCESSING + +K16B: JMP K26 ; IGNORE SYSTEM KEY + +K16C: AND KB_FLAG_1,NOT SYS_SHIFT; TURN OFF SHIFT KEY HELD DOWN + +ifdef NOT_NTVDM + MOV AL,ENA_KBD ; INSURE KEYBOARD IS ENABLED + CALL SHIP_IT ; EXECUTE ENABLE +else + mov ah, 3 ; K27A exit notify + BOP 09h +endif + + MOV AX,08501H ; FUNCTION VALUE FOR BREAK OF SYSTEM KEY + INT 15H ; USER INTERRUPT + JMP K27A ; IGNORE SYSTEM KEY +PAGE +;------ TEST FOR SHIFT KEYS +; +; HERE IS WHERE KB_FLAGS 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 TOP 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 + 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 + TEST AL,80H ; TEST FOR BREAK KEY + JZ K17C + JMP K23 ; JUMP IF BREAK + +;------ 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? + JNE K17C1 ; NO, US MODE, JUMP + CMP AL,ALT_KEY ; IS THIS THE ALT KEY? + JNE K17C1 ; NO, NORMAL KEY + ;**CNS + +K17C1: OR KB_FLAG,AH ; TURN ON SHIFT BIT +K17C2: TEST AH,CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL? + JZ K17F ; NO, JUMP +K17D: TEST BH,LC_E0 ; IS THIS ONE OF THE NEW KEYS? + JZ K17E ; NO, JUMP + OR KB_FLAG_3,AH ; SET BITS FOR RIGHT CTRL, ALT +; JMP K26 ; INTERRUPT_RETURN + jmp short K17G ; (YST) + +K17E: SHR AH,CL ; MOVE FLAG BITS TWO POSITIONS + OR KB_FLAG_1,AH ; SET BITS FOR LEFT CTRL, ALT +; JMP K26 ; INTERRUPT RETURN + jmp short K17G ; (YST) + +K17F: + TEST CS:SD.SPECIAL_FEATURES,TYPEWRITER_CAPS_LK + JZ K17G ; N..all done + CMP COUNTRY_FLAG,0FFh ; ARE WE IN LANG MODE? + JNE K17G ; NO, ALL DONE WITH SHIFT KEY + +;------ If keyboard is P12 then we still need to release caps_lk + + TEST BP,PC_LAP ; IS THIS A P12 KEYBOARD? + JNZ REMOVE_CAPS_SHIFT + + TEST BH,KBX ; THIS THE ENHANCED KEYBOARD? + JZ K17G ; NO, ALL DONE WITH SHIFT KEY +REMOVE_CAPS_SHIFT: + AND KB_FLAG,NOT CAPS_SHIFT ; YES, TAKE KB OUT OF C_L STATE + CALL SND_LED ; AND UPDATE THE LED INDICATORS +K17G: + + +; =========================================== +; Russian Keyboard (YST) +; =========================================== + CMP COUNTRY_FLAG,0FFh ; ARE WE IN FOREIGN LANG MODE? (YST) + JNE K17H ; NO, US MODE, RETURN (YST) + TEST CS:SD.SPECIAL_FEATURES,SHIFTS_TO_LOGIC; CAN OUR STATE (YST) + ; LOGIC SUPPORT THIS CALL? (YST) + JZ K17H ; NO, RETURN (YST) + OR CS:FLAGS_TO_TEST[EXT_KB_FLAG_ID],SHIFTS_PRESSED; (YST) + ; SET FLAG FOR STATE LOGIC (YST) + CALL KEYB_STATE_PROCESSOR ; ******** (YST) + AND CS:FLAGS_TO_TEST[EXT_KB_FLAG_ID],NOT SHIFTS_PRESSED; (YST) + ; CLEAR FLAG AFTER USE (YST) +; =========================================== +; End of Russian Keyboard (YST) +; =========================================== + + +K17H: JMP K26 ; RETURN + +;------ TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT + +K18: ; SHIFT-TOGGLE + TEST BL,CTL_SHIFT ; CHECK CTL SHIFT STATE + 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 + JZ K18B ; JUMP IF NOT ALTERNATE SHIFT + JMP K25 ; JUMP IF ALTERNATE SHIFT +K18B: TEST BH,LC_E0 ; IS THIS THE NEW INSERT KEY? + JNZ K22 ; YES, THIS ONE'S NEVER A "0" +K19: TEST BL,NUM_STATE ; CHECK FOR BASE STATE + JNZ K21 ; JUMP IF NUM LOCK IS ON + TEST BL,LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE + JZ K22 ; JUMP IF BASE STATE +K20: MOV AH,AL ; PUT SCAN CODE BACK IN AH + JMP K25 ; NUMERAL "0", STNDRD. PROCESSING + +K21: TEST BL,LEFT_SHIFT+RIGHT_SHIFT ; MIGHT BE NUMERIC + JZ K20 ; IS NUMERIC, STD. PROC. + +K22: ; SHIFT TOGGLE KEY HIT; PROCESS IT + TEST AH, KB_FLAG_1 ; IS KEY ALREADY DEPRESSED? + JZ K22A + JMP K26 ; 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 + + TEST BP,PC_LAP ; IS THIS A P12 KEYBOARD? + JNZ LAP_SO_DONT_TOGGLE + + TEST BH,KBX ; THIS THE ENHANCED KEYBOARD? + JZ K22C ; NO, ALL DONE WITH TOGGLE KEYS + +LAP_SO_DONT_TOGGLE: + CMP CS:COUNTRY_FLAG,0FFh ; ARE WE IN FOREIGN LANG MODE? + JNE K22C ; NO, NO SPECIAL STUFF FOR U.S. + TEST AH,CAPS_SHIFT ; IS IT THE CAPS_LOCK KEY? + JZ K22C ; NO, NOTHING ELSE TO DO + OR KB_FLAG,AH ; YES, SET CAPS_LOCK (NOT TOGGLE) + +K22C: + +;------ 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 + JNE K26 ; JUMP IF NOT INSERT KEY + MOV AH,AL ; SCAN CODE IN BOTH HALVES OF AX + JMP K28 ; FLAGS UPDATED, PROC. FOR BUFFER + +;------ 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? + JA K23D ; NO, ALL DONE + + TEST BH,LC_E0 ; 2ND ALT OR CTL? + JZ K23A ; NO, HANDLE NORMALLY + AND KB_FLAG_3,AH ; RESET BIT FOR RIGHT ALT OR CTL + JMP SHORT K23B ; CONTINUE +K23A: SAR AH,CL ; MOVE THE MASK BIT TWO POSITIONS + AND KB_FLAG_1,AH ; RESET BIT FOR LEFT ALT OR CTL +K23B: MOV AH,AL ; SAVE SCAN CODE + MOV AL, KB_FLAG_3 ; GET RIGHT ALT & CTRL FLAGS + CMP COUNTRY_FLAG,0FFH ; ARE WE IN LANGUAGE MODE? + JNE K23C ; NO, LEAVE RIGHT FLAGS AS IS +;**CNS + AND AL,NOT GRAPH_ON ; YES, FILTER OUT THE ALT_GR KEY +;**CNS +K23C: SHR AL,CL ; MOVE TO BITS 1 & 0 + OR AL, KB_FLAG_1 ; PUT IN LEFT ALT & CTL FLAGS + SHL AL,CL ; MOVE BACK TO BITS 3 & 2 + AND AL,ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE + OR KB_FLAG,AL ; PUT RESULT IN THE REAL FLAGS + MOV AL,AH ; RECOVER SAVED SCAN CODE + +K23D: CMP AL,ALT_KEY+80H ; IS THIS ALTERNATE SHIFT RELEASE + JNE K26 ; INTERRUPT_RETURN + +;------ ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER + + MOV AL, ALT_INPUT + xor ah,ah ; scan code of 0 + MOV ALT_INPUT,AH ; ZERO OUT THE FIELD + or al,al ; was the input = 0? + JE K26 ; INTERRUPT_RETURN + CALL BUFFER_FILL_ANY_CHAR ; Put in buffer, but use this + ; entry point to avoid trashing + ; an ASCII code of 255 + JMP SHORT K26 ; INTERRUPT_RETURN + +K24: ; BREAK-TOGGLE + AND KB_FLAG_1,AH ; INDICATE NO LONGER DEPRESSED + JMP SHORT K26 ; INTERRUPT_RETURN + +;------ TEST FOR HOLD STATE + ; AL, AH = SCAN CODE +K25: ; NO-SHIFT-FOUND + CMP AL,80H ; TEST FOR BREAK KEY + JAE K26 ; NOTHING FOR BREAK CHARS FROM HERE ON + TEST KB_FLAG_1,HOLD_STATE ; ARE WE IN HOLD STATE + JZ K28 ; BRANCH AROUND TEST IF NOT + CMP AL,NUM_KEY + JE K26 ; CAN'T END HOLD ON NUM_LOCK + AND KB_FLAG_1,NOT HOLD_STATE ; TURN OFF THE HOLD STATE BIT + +K26: + AND KB_FLAG_3,NOT LC_E0+LC_E1 ; RESET LAST CHAR H.C. FLAG + +K26A: ; INTERRUPT-RETURN +ifdef NOT_NTVDM + ;; NTVDM CLI ; TURN OFF INTERRUPTS + CALL ERROR_BEEP ; CHECK FOR ERROR BEEP PENDING + + CMP CS:BUFFER_ENTRY_OK,YES ; HAS A CHARACTER BEEN PLACED IN BUFFER + JNE K27 ; NO, SKIP POST + + MOV byte ptr CS:BUFFER_ENTRY_OK,NO ; CLEAR POST CHARACTER IN BUFFER FLAG + MOV AX,09102H ; MOVE IN POST CODE & TYPE + INT 15H ; PERFORM OTHER FUNCTION +K27: + MOV AL,ENA_KBD ; ENSURE KEYBOARD IS ENABLED (AT PS/2) + CALL SHIP_IT ; EXECUTE ENABLE +else + + mov ah, 2 + mov bh, CS:BEEP_PENDING + mov bl, CS:BUFFER_ENTRY_OK + MOV byte ptr CS:BUFFER_ENTRY_OK,NO + MOV byte ptr CS:BEEP_PENDING,NO + BOP 09h +endif + + +K27A: ;; NTVDM CLI ; DISABLE INTERRUPTS + POP ES ; RESTORE REGISTERS + POP DS ; * + POP DI ; * + POP SI ; * + POP DX ; * + POP CX ; * + POP BX ; * + POP AX ; * + POP BP ; * + + jmp DOIRET ; RETURN +PAGE +;------ NOT IN HOLD STATE + ; AL, AH = SCAN CODE (ALL MAKES) +K28: ; NO-HOLD-STATE + CMP AL,H_LAST_SCAN ; TEST FOR OUT-OF-RANGE SCAN CODES + JA SHORT K26 ; IGNORE IF OUT-OF-RANGE + + TEST BP,EXT_122 ; IS EXTENDED 122 KEYBOARD SUPPORT OK + JNZ K28_122 ; SKIP NON-122 OUT-OF-RANGE CHECK + +ifdef NOT_NTVDM + CMP AL,88 ; TEST FOR OUT-OF-RANGE SCAN CODES +else + CMP AL,7Eh ; MAX SCANCODE ON BRAZILIAN ABNT KBD +endif + JA K26 ; IGNORE IF OUT-OF-RANGE + +K28_122: + TEST BL,ALT_SHIFT ; ARE WE IN ALTERNATE SHIFT? + JZ K28A ; JUMP IF NOT ALTERNATE + + TEST BH,KBX ; IS THIS THE ENHANCED KEYBOARD? + JZ K29 ; NO, ALT STATE IS REAL + + TEST KB_FLAG_1,SYS_SHIFT ; YES, IS SYSREQ KEY DOWN? + JZ K29 ; NO, ALT STATE IS REAL +;**CNS + TEST AH,LC_E0 ; IS IT THE ALT_GR KEY? + JZ K28A ; YES, DON'T SET KB_FLAG + + TEST AL,R_ALT_SHIFT ; TURN ON SHIFT BIT + JNZ K29 ; TURN ON SHIFT BIT +;**CNS + +K28A: JMP K38 ; YES, THIS IS PHONY ALT STATE + ; DUE TO PRESSING SYSREQ + +;------ TEST FOR RESET KEY SEQUENCE (CTL ALT DEL) OR HOT KEY DEPRESSED + +K29: ; TEST-RESET + TEST BL,CTL_SHIFT ; ARE WE IN CONTROL SHIFT ALSO? + 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 + JC K26 ; TRANSLATIONS FOUND - EXIT + + CMP AL,57 ; TEST FOR SPACE KEY + JNE K311 ; NOT THERE + MOV AL,' ' ; SET SPACE CHAR + JMP K57 ; BUFFER_FILL +K311: + TEST BP,EXT_16 ; IS EXTENDED INT 16 LOADED? + JZ K32 ; NO, SKIP THIS EXTENDED STUFF + CMP AL,15 ; TEST FOR TAB KEY + JNE K312 ; NOT THERE + MOV AX,0A500h ; SET SPECIAL CODE FOR ALT-TAB + JMP K57 ; BUFFER_FILL +K312: + CMP AL,74 ; TEST FOR KEYPAD - + JE K312A ; GO PROCESS + CMP AL,78 ; TEST FOR KEYPAD + + JNE K32 ; SKIP TEST FOR LANG SWAP & CONT. +K312A: JMP K37B ; GO PROCESS + +;------ 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 + JMP K26 ; 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 + JMP K26 ; INTERRUPT RETURN + + +;------ ALT, CTRL DOWN ; NO HOT KEY + +K31C: CMP CS:COUNTRY_FLAG,0FFH + JNE K32 ; TRY ALT_KEY_PAD + CALL KEYB_STATE_PROCESSOR + JC K32A ;K26 ; 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? + JNZ K37C ; YES, JUMP, NOT NUMPAD KEY + 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: JMP K26 ; 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 + ; TO THE ";" KEY BEING "M" + REPNE SCASB ; LOOK FOR MATCH IN ALPHABET + JE K37A ; MATCH FOUND, GO FILL THE BUFFER + +;------ LOOK FOR TOP ROW OF ALTERNATE SHIFT + +K34: ; ALT-TOP-ROW + CMP AL,2 ; KEY WITH '1' ON IT + JB K37B ; MUST BE ESCAPE + 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 + +;------ TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES + +K35: ; ALT-FUNCTION + CMP AL,F11_M ; IS IT F11 or GREATER ? + JB K35A ; NO, BRANCH + SUB AL,52h ; SET UP TO SEARCH ALT-FUNCTION-TABLE + MOV BX,OFFSET K30A ; BASE CASE TABLE + JMP K64 ; CONVERT TO PSEUDO SCAN + +K35A: TEST BH,LC_E0 ; DO WE HAVE ONE OF THE NEW KEYS? + JZ K37 ; NO, JUMP + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 LOADED? + JZ K37 ; NO, DO COMPATIBLE OUTPUT + CMP AL,28 ; TEST FOR KEYPAD ENTER + JNE K35B ; NOT THERE + MOV AX,0A600h ; SPECIAL CODE + JMP K57 ; BUFFER FILL +K35B: CMP AL,83 ; TEST FOR DELETE KEY + JE K37C ; HANDLE WITH OTHER EDIT KEYS + CMP AL,53 ; TEST FOR KEYPAD / + JNE K32A ; NOT THERE, NO OTHER E0 SPECIALS + MOV AX,0A400h ; SPECIAL CODE + JMP K57 ; BUFFER FILL + +K37: CMP AL,59 ; TEST FOR FUNCTION KEYS (F1) + JB K37B ; NO FN, HANDLE W/OTHER EXTENDED + CMP AL,68 ; IN KEYPAD REGION? + ; OR NUMLOCK, SCROLLOCK? + JA K32A ; IF SO, IGNORE + ADD AH,45 ; CONVERT TO PSEUDO SCAN CODE + +K37A: xor al,al ; ASCII CODE OF ZERO + JMP K57 ; PUT IT IN THE BUFFER + +K37B: + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 LOADED? + JZ K32A ;K26 ; NO, IGNORE THIS ONE + MOV AL,0F0h ; USE SPECIAL ASCII CODE + JMP K57 ; PUT IT IN THE BUFFER + +K37C: + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 LOADED? + JZ K37A ; NO, DO COMPATIBLE OUTPUT + ADD AL,80 ; CONVERT SCAN CODE (EDIT KEYS) + MOV AH,AL ; (SCAN CODE NOT IN AH FOR INSERT) + JMP K37A ; PUT IT IN THE BUFFER +PAGE +;------ NOT IN ALTERNATE SHIFT + +K38: ; NOT-ALT-SHIFT + ; BL STILL HAS SHIFT FLAGS + TEST BL,CTL_SHIFT ; ARE WE IN CONTROL SHIFT? + JNZ K38A ; YES, START PROCESSING + 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 BP,PC_LAP ; IS THIS THE LAP COMPUTER? + JNZ K38B ; YES, THIS IS CTRL-BREAK + TEST BH,KBX ; IS THIS THE ENHANCED KEYBOARD? + JZ K38B ; NO, BREAK IS VALID + TEST BH,LC_E0 ; YES, WAS LAST CODE AN E0? + JZ K39 ; NO-BREAK, TEST FOR PAUSE + +K38B: + ;; NTVDM CLI ; Disable interrupts because EOI issued + MOV BX, BUFFER_HEAD ; RESET BUFFER TAIL TO BUFFER HEAD + MOV BUFFER_TAIL,BX + MOV BIOS_BREAK,80H ; TURN ON BIOS_BREAK BIT + +;-------- ENABLE KEYBOARD + +ifdef NOT_NTVDM + MOV AL,ENA_KBD ; ENABLE KEYBOARD + CALL SHIP_IT ; EXECUTE ENABLE +else + mov ah, 4 + BOP 09h +endif + 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? + JZ K39P ; NO, THIS IS A VALID PAUSE + TEST BP,PC_LAP ; IS THIS THE LAP COMPUTER? + JZ K41 ; NO, IT'S NOT PAUSE THIS TIME +K39P: OR KB_FLAG_1,HOLD_STATE ; TURN ON THE HOLD FLAG + +;-------- ENABLE KEYBOARD + + MOV AL,ENA_KBD ; ENABLE KEYBOARD + CALL SHIP_IT ; EXECUTE ENABLE + +ifdef NOT_NTVDM + +;------ DURING PAUSE INTERVAL, TURN CRT BACK ON + + CMP CRT_MODE,7 ; IS THIS BLACK AND WHITE CARD + JAE K40 ; YES, NOT CGA MODES 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 + TEST BP,PC_LAP ; IS THIS THE LAP COMPUTER? + JZ K40A ; NO, SKIP THE BATTERY LIFE STUFF + MOV AX,4104H ; FUNCTION 41, AL=04=RETURN IF 0 + MOV BX,HOLD_STATE*100H ; BH=HOLD_STATE, BL=0=NO TIME OUT + PUSH DS ; MAKE ES:DI POINT TO KB_FLAG_1 + POP ES + MOV DI,OFFSET KB_FLAG_1 + INT 15H ; SLEEP UNTIL OUT OF HOLD + +;------ CHECK FOR AUX ADAPTER INPUT PENDING +K40A: + MOV CX,100 ; COUNT FOR WAIT LOOP +else + mov ah, 3 ; K27A exit notify + BOP 09h + call DOSTI +K40A: + mov cx, 16 + xor ax, ax + BOP BOP_WAITIFIDLE ; idle bop +endif +K40B: + TEST KB_FLAG_1,HOLD_STATE ; ARE WE IN HOLD STATE + JZ K40E ; EXIT IF NOT + +ifdef NOT_NTVDM + TEST BP,PC_XT+PC_LAP ; Check for systems without AUX BIOS + JNZ K40B ; For them, just loop on hold flag + + IN AL,STATUS_PORT ; READ CURRENT STATUS + AND AL,MOUSE_OBF+OUT_BUF_FULL ; MASK OFF ALL BUT MOUSE DATA BITS + CMP AL,MOUSE_OBF+OUT_BUF_FULL ; IS THERE STILL MOUSE DATA PENDING? +endif + LOOPE K40B ; WAIT FOR MOUSE DATA TO GO + JNE K40A ; CONTINUE IF PAUSE STATE ;an005 +K40E: +ifndef NOT_NTVDM + call DOCLI +endif + AND KB_FLAG_1,NOT HOLD_STATE ; CLEAR HOLD STATE FLAG + JMP K27A ; INTERRUPT_RETURN_NO_EOI PTR 2247 + +;------ TEST SPECIAL CASE KEY 55 + +K41: ; NO-PAUSE + CMP AL,55 ; TEST FOR */PRTSC KEY + JNE K42 ; NOT-KEY-55 + TEST BP,PC_LAP ; IS THIS THE LAP COMPUTER? + JZ K41B ; NO, JUMP + TEST BH,LC_E0 ; YES, WAS LAST CODE AN E0? + JZ K41A ; NO, THIS IS THE PRTSC KEY + JMP SHORT K42B ; YES, E0 MEANS THE "*" KEY + +K41B: TEST BH,KBX ; IS THIS THE ENHANCED KEYBOARD? + JZ K41A ; NO, CTL-PRTSC IS VALID + TEST BH,LC_E0 ; YES, WAS LAST CODE AN E0? + JZ K42B ; NO, TRANSLATE TO A FUNCTION +K41A: MOV AX,114*256 ; START/STOP PRINTING SWITCH + JMP K57 ; BUFFER_FILL + +;------ SET UP TO TRANSLATE CONTROL SHIFT + +K42: ; NOT-KEY-55 + CALL KEYB_STATE_PROCESSOR + JC K449 ;K26 ; TRANSLATIONS FOUND - EXIT + + CMP AL,15 ; IS IT THE TAB KEY? + JE K42B ; YES, XLATE TO FUNCTION CODE + CMP AL,53 ; IS IT THE / KEY? + JNE K42A ; NO, NO MORE SPECIAL CASES + TEST BH,LC_E0 ; YES, IS IT FROM THE KEYPAD? + JZ K42A ; NO, JUST TRANSLATE + MOV AX,9500h ; YES, SPECIAL CODE FOR THIS ONE + JMP K57 ; BUFFER FILL + +K42A: MOV BX,OFFSET K8 ; SET UP TO TRANSLATE CTL + CMP AL,59 ; IS IT IN CHARACTER TABLE? + JB K45F ; YES, GO TRANSLATE CHAR +K42B: MOV BX,OFFSET K8 ; SET UP TO TRANSLATE CTL + JMP K64 ; NO, GO TRANSLATE_SCAN +PAGE +;------ NOT IN CONTROL SHIFT + +K44: + CALL KEYB_STATE_PROCESSOR + JC K449 ;K26 ; TRANSLATIONS FOUND - EXIT + + CMP AL,55 ; PRINT SCREEN KEY? + JNE K45 ; NOT-PRINT-SCREEN + TEST BP,PC_LAP ; IS THIS THE LAP COMPUTER? + JZ K441 ; NO, JUMP + TEST BH,LC_E0 ; YES, WAS LAST CODE THE MARKER? + JZ K44A ; NO, TEST THE SHIFT STATE + JMP SHORT K45C ; YES, XLATE TO "*" CHAR +K441: TEST BH,KBX ; IS THIS ENHANCED KEYBOARD? + JZ K44A ; NO, TEST FOR SHIFT STATE + TEST BH,LC_E0 ; YES, LAST CODE A MARKER? + JNZ K44B ; YES, IS PRINT SCREEN + JMP SHORT K45C ; NO, XLATE TO "*" CHARACTER +K44A: TEST BL,LEFT_SHIFT+RIGHT_SHIFT ;NOT 101 KBD, SHIFT KEY DOWN? + JZ K45C ; NO, XLATE TO "*" CHARACTER + +;------ ISSUE INTERRUPT TO PERFORM PRINT SCREEN FUNCTION +K44B: + ;; NTVDM CLI ; DISABLE INTERRUPTS PTR 2355 + AND KB_FLAG_3,NOT LC_E0+LC_E1 ;ZERO OUT THESE FLAGS + +ifdef NOT_NTVDM + MOV AL,ENA_KBD ; INSURE KEYBOARD IS ENABLED + CALL SHIP_IT ; EXECUTE ENABLE +else + mov ah, 3 ; K27A exit notify + BOP 09h +endif + PUSH BP ; SAVE POINTER (compatibility) + INT 5H ; ISSUE PRINT SCREEN INTERRUPT + POP BP ; RESTORE POINTER + JMP K27A ; EXIT WITHOUT EXTRA EOI OR ENABLE + +K449: + JMP K26 ; EXIT + +;------ HANDLE THE IN-CORE KEYS +K45: ; NOT-PRINT-SCREEN + CMP AL,58 ; TEST FOR IN-CORE AREA + JA K46 ; JUMP IF NOT + + TEST BH,GRAPH_ON ; IS ALT GRAPHICS ON? AEV + JNZ K449 ;K26 ; YES, TRASH KEYSTROKE + + CMP AL,53 ; IS THIS THE "/" KEY? + JNE K45A ; NO, JUMP + TEST BH,LC_E0 ; WAS LAST CODE THE MARKER? + JNZ K45C ; YES, TRANSLATE TO CHARACTER + +K45A: MOV CX,K30_LEN ; LENGTH OF SEARCH + MOV DI,OFFSET K30+10 ; POINT TO TABLE OF A-Z CHARS + REPNE SCASB ; IS THIS A LETTER KEY? + JNE K45B ; NO, SYMBOL KEY + + TEST BL,CAPS_STATE ; ARE WE IN CAPS_LOCK? + JNZ K45D ; TEST FOR SURE +K45B: TEST BL,LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE? + JNZ K45E ; YES, UPPERCASE + ; NO, LOWERCASE +K45C: MOV BX,OFFSET K10 ; TRANSLATE TO LOWERCASE LETTERS + JMP SHORT K56 +K45D: ; ALMOST-CAPS-STATE + TEST BL,LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO? + JNZ K45C ; SHIFTED TEMP OUT OF CAPS STATE +K45E: MOV BX,OFFSET K11 ; TRANSLATE TO UPPERCASE LETTERS +K45F: JMP SHORT K56 + + +;------ TEST FOR KEYS F1 - F10 +K46: ; NOT IN-CORE AREA + CMP AL,68 ; TEST FOR F1 - F10 + JA K47 ; JUMP IF NOT + JMP SHORT K53A ; YES, GO DO FN KEY PROCESS + + +;------ HANDLE THE NUMERIC PAD KEYS + +K47: ; NOT F1 - F10 + CMP AL,83 ; TEST FOR NUMPAD KEYS + JA K52 ; JUMP IF NOT + +;------ KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION +K48: CMP AL,74 ; SPECIAL CASE FOR MINUS + JE K45E ; GO TRANSLATE (US & WT ARE SAME) + CMP AL,78 ; SPECIAL CASE FOR PLUS + JE K45E ; GO TRANSLATE (US & WT ARE SAME) + TEST BH,LC_E0 ; IS THIS ONE OF THE NEW KEYS? + JNZ K49 ; YES, TRANSLATE TO BASE STATE + + TEST BL,NUM_STATE ; ARE WE IN NUM_LOCK? + JNZ K50 ; TEST FOR SURE + TEST BL,LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE? + JNZ K51 ; IF SHIFTED, REALLY NUM STATE + +;------ BASE CASE FOR KEYPAD +K49: CMP AL,76 ; SPECIAL CASE FOR BASE STATE 5 + JNE K49A ; CONTINUE IF NOT KEYPAD 5 + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 LOADED? + JZ K59 ;K26 ; NO, INGORE + + MOV AL,0F0h ; SPECIAL ASCII CODE + JMP SHORT K57 ; BUFFER FILL +K49A: MOV BX,OFFSET K10 ; BASE CASE TABLE + JMP SHORT K64 ; CONVERT TO PSEUDO SCAN + +;------ MIGHT BE NUM LOCK, TEST SHIFT STATUS +K50: TEST BL,LEFT_SHIFT+RIGHT_SHIFT ;ALMOST-NUM-STATE + JNZ K49 ; SHIFTED TEMP OUT OF NUM STATE +K51: JMP SHORT K45E ; REALLY_NUM_STATE + ; (US & WT ARE SAME) + +;------ TEST FOR THE NEW KEY ON WT KEYBOARDS + +K52: ; NOT A NUMPAD KEY + CMP AL,86 ; IS IT THE NEW WT KEY? + JNE K53 ; JUMP IF NOT + MOV AL,58 ; WE'RE GOING TO PULL A SNEAKY + 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. + +;------ MUST BE F11 OR F12 + +K53: TEST BP,EXT_16 ; IS THE EXTENDED INT 16 THERE? + JZ K59 ; NO, INGORE F11 & F12 (NEAR RET) + ; F1 - F10 COME HERE, TOO +K53A: TEST BL,LEFT_SHIFT+RIGHT_SHIFT ;TEST SHIFT STATE + JZ K49 ; JUMP, LOWERCASE PSEUDO SC'S + + 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 + TEST KB_FLAG_3,LC_E0 ; IS THIS A NEW KEY? + JZ K57 ; NO, GO FILL BUFFER + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 THERE? + JZ K57 ; NO, DO COMPATIBLE OUTPUT + MOV AH,MC_E0 ; YES, PUT SPECIAL MARKER IN AH + JMP SHORT K57 ; PUT IT INTO THE BUFFER + +;------ TRANSLATE SCAN FOR PSEUDO SCAN CODES + +K64: ; TRANSLATE-SCAN-ORGD + DEC AL ; CONVERT ORIGIN + XLAT CS:K8 ; CTL TABLE SCAN + MOV AH,AL ; PUT VALUE INTO AH + xor al,al ; ZERO ASCII CODE + TEST KB_FLAG_3,LC_E0 ; IS THIS A NEW KEY? + JZ K57 ; NO, GO FILL BUFFER + TEST BP,EXT_16 ; IS THE EXTENDED INT 16 THERE? + JZ K57 ; NO, DO COMPATIBLE OUTPUT + MOV AL,MC_E0 ; YES, PUT SPECIAL MARKER IN AL + +;------ PUT CHARACTER INTO BUFFER + +K57: ; BUFFER-FILL + CALL BUFFER_FILL +K59: + JMP K26 ;-- 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_ENTRY_OK DB NO ; YES if character put into buffer + +BUFFER_FILL PROC NEAR + +; CMP AL,-1 ; IS THIS AN IGNORE CHAR +; JE K61B ; YES, EXIT (commented YST) + 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 + ; externally so make sure DS points + MOV BX,DATA ; to BIOS data + MOV DS,BX + + ;; NTVDM cli ; disable interrupts P724 + 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 + + TEST BP,PC_81 ; CHECK FOR '81 DATE FLAG SET + 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 SHORT 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 +K61A: + POP DS + POP BX + POP SI + ;; NTVDM sti ; enable interrupts P724 +K61B: + RET +BUFFER_FILL ENDP + +PAGE +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Procedure: ERROR_BEEP +; +; Description: +; General routine to generate beep tones +; +; Input Registers: +; None +; +; Output Registers: +; None +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +ERROR_BEEP PROC NEAR + + CMP CS:BEEP_PENDING,YES ; Q..SHOULD WE BEEP? + JNE NO_BEEP + + MOV CS:BEEP_PENDING,NO ; Reset BEEP required +ifndef NOT_NTVDM + mov ah, 0eh + mov al, 07h + int 10h + +else + MOV CX,216-32 ; NUMBER OF CYCLES FOR 1/8 SECOND TONE + IN AL,PORT_B ; Get control info + PUSH AX +LOOP01: + AND AL,0FCH ; Turn off timer gate and speaker + OUT PORT_B,AL ; output to control - speaker off + CALL WAITFB ; half cycle time for tone + OR AL,2 ; turn on speaker + CLI ; Disable interrupts for 1/2 cycle, 300u + OUT PORT_B,AL ; output to control + CALL WAITFB ; another half cycle + STI ; Enable interrupts between 1/2 cycle + LOOP LOOP01 + + POP AX + OUT PORT_B,AL ; Restore control + MOV CX,32*2 ; Short delay count of 32 cycles +LOOP02: + CALL WAITFB ; Add a short delay to complete 1/8 sec + LOOP LOOP02 ; Repeat + CLI ; Disable interrupts +endif + +NO_BEEP: + RET ; RETURN +ERROR_BEEP ENDP + + +ifdef NOT_NTVDM +WAITFB PROC NEAR ; DELAY FOR (CX)*15.085737 US + PUSH AX ; SAVE WORK REGISTER (AH) + PUSH CX ; SAVE COUNT + MOV CX,19 ; The half cycle time for 1745 hz + TEST BP,PC_AT+PC_386 ; IF THE SYSTEM IS AN 80x86 + JNZ WAITF1 ; SKIP TO REFRESH BIT DELAY + +WAITF0: + NOP ; Force two fetch cycles on Model 30 + LOOP WAITF0 ; SOFTWARE DELAY LOOP ON 808x MACHINES + + JMP SHORT WAITFE ; EXIT + +WAITF1: ; USE TIMER 1 OUTPUT BITS + IN AL,PORT_B ; READ CURRENT COUNTER OUTPUT STATUS + AND AL,REFRESH_BIT ; MASK FOR REFRESH DETERMINE BIT + CMP AL,AH ; DID IT JUST CHANGE + JE WAITF1 ; WAIT FOR A CHANGE IN OUTPUT LINE + + MOV AH,AL ; SAVE NEW FLAG STATE + LOOP WAITF1 ; DECREMENT HALF CYCLES TILL COUNT END +WAITFE: + + POP CX ; RESTORE COUNT + POP AX ; RESTORE (AH) + RET ; RETURN (CX)= 0 + +WAITFB ENDP +endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; SHIP_IT +; +; THIS ROUTINE HANDLES TRANSMISSION OF COMMAND AND DATA BYTES +; TO THE KEYBOARD CONTROLLER. +; +; On entry the AL contains the command byte. +; On Enable keyboard commands, the reset keyboard input latch is done +; if the system is the old PC type. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SHIP_IT PROC NEAR + +ifdef NOT_NTVDM +;------- TEST SYSTEM TYPE + PUSHF ; SAVE FLAGS P725 + CLI ; DISABLE INTERRUPTS TILL DATA SENT + + TEST BP,PC_XT+PC_LAP + JZ SI5 ; USE AT 8042 COMMAND IF NOT PC TYPE + + CMP AL,ENA_KBD ; CHECK FOR ENABLE KEYBOARD COMMAND + JNE SI9 ; SKIP ENABLE RESET + ; FOR PC, XT, P12: RESET THE KEYBOARD + PUSH AX ; SAVE AX + IN AL,KB_CTL ; GET THE CONTROL PORT + MOV AH,AL ; SAVE VALUE + OR AL,80H ; RESET BIT FOR KEYBOARD ON PC/PC-XT + OUT KB_CTL,AL + XCHG AH,AL ; GET BACK ORIGINAL CONTROL + OUT KB_CTL,AL ; KB HAS BEEN RESET + POP AX ; RESTORE AX + ; EXIT as NOT next system +SI5: + TEST BP,PC_AT+PC_386 ; IF THE SYSTEM IS NOT AN 80x86 + JZ SI9 ; MACHINE, EXIT THIS PROC. + +;------- WAIT FOR COMMAND TO BE ACCEPTED; + + CALL chk_ibf ; GO READ KEYBOARD CONTROLLER STATUS +endif + + OUT STATUS_PORT,AL ; SEND TO KEYBOARD CONTROLLER + +ifdef NOT_NTVDM +SI9: ; ENABLE INTERRUPTS AGAIN + POPF ; RESTORE FLAGS P725 +endif + RET ; RETURN TO CALLER +SHIP_IT ENDP + +ifdef NOT_NTVDM +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; 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 BYTE FOR RETRIES + + MOV BL,3 ; LOAD RETRY COUNT +SD0: + CLI ; DISABLE INTERRUPTS + AND KB_FLAG_2,NOT (KB_FE+KB_FA+kb_err) ; CLEAR ACK, RESEND and + ; error flags + + CALL CHK_IBF ; Wait for command accepted + + MOV AL,BH ; REESTABLISH BYTE TO TRANSMIT + OUT PORT_A,AL ; SEND BYTE + STI ; ENABLE INTERRUPTS + MOV CX,DLY_15MS ; DELAY FOR 15 ms TIMEOUT +SD1: TEST KB_FLAG_2,KB_FE+KB_FA ; SEE IF EITHER BIT SET + JNZ SD3 ; IF SET, SOMETHING RECEIVED GO PROCESS + IN AL,PORT_B ; WAIT LOOP USING REFRESH BIT + AND AL,REFRESH_BIT + CMP AL,AH + JE SD1 ; KEEP TESTING + MOV AH,AL ; DEC CX ON REFRESH TIC + LOOP SD1 ; KEEP TESTING + ; !! TIMEOUT !! + +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 +endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; SND_LED +; +; THIS ROUTINE TURNS ON THE MODE INDICATORS. +; +; NTVDM - we do not need to update led's as this is controlled +; by the host\system. We also assume that interrupts are +; off upon entry +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SND_LED PROC NEAR +ifdef NOT_NTVDM + CLI ; TURN OFF INTERRUPTS + + TEST BP,PC_AT+PC_386 ; IF THE SYSTEM IS NOT A 80x86 + JZ SL1 ; MACHINE, EXIT THIS PROC +endif + + 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 +ifdef NOT_NTVDM + MOV AL,LED_CMD ; LED CMD BYTE + CALL SND_DATA ; SEND DATA TO KEYBOARD + CLI +endif + 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 FOR NEXT TIME + + mov ah, 3 ; inform softpc to set lights + BOP 16h + + +ifdef NOT_NTVDM + TEST KB_FLAG_2,KB_ERR ; TRANSMIT ERROR DETECTED + JNZ SL2 ; 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 +endif + +SL3: AND KB_FLAG_2,NOT(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR + ; UPDATE AND TRANSMIT ERROR FLAG +SL1: +ifdef NOT_NTVDM + STI ; ENABLE INTERRUPTS +endif + 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 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; CHK_IBF +; +; Description: +; Waits for a keyboard command to be accepted +; wait until ibf = 0 (empty) +; +; Input Registers: +; None +; +; Output Registers: +; ZF=0 time out & IBF still full +; ZF=1 IBF is empty +; +; --------------------------------------------------------------- +; This procedure replaces the previous one which used a software +; timing loop. (For 80286, 80386 and 80486 based machines.) +; --------------------------------------------------------------- +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +chk_ibf proc near + + push ax ; Save register used + push cx + mov cx,DLY_15MS ; Timeout 15 milleseconds (15000/15.086; +chk_ibfl: + in al,PORT_B ; Read current refresh output bit + and al,refresh_bit ; Mask all but refresh bit + cmp al,ah ; Did it change? (or first pass thru) + jz short chk_ibfl ; No, wait for change, else continue + + mov ah,al ; Save new refresh bit state + in al,status_port ; Read status port + test al,inpt_buf_full ; Check for input buffer empty + loopnz chk_ibfl ; Loop until input buf empty or timeout; + + pop cx + pop ax ; Restore register used + ret ; Return to caller + +chk_ibf endp + + + +DOSTI proc near + FSTI + ret +DOSTI endp + +DOCLI proc near + FCLI + ret +DOCLI endp + +DOIRET: + FIRET + +CODE ENDS + END |