From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/KEYB/COMMSUBS.ASM | 603 ++++++++++++ v4.0/src/CMD/KEYB/COMMSUBS.INC | 30 + v4.0/src/CMD/KEYB/KBMSG.INC | 21 + v4.0/src/CMD/KEYB/KEYB.ASM | 71 ++ v4.0/src/CMD/KEYB/KEYB.LNK | 3 + v4.0/src/CMD/KEYB/KEYB.SKL | 37 + v4.0/src/CMD/KEYB/KEYBCMD.ASM | 2072 ++++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/KEYB/KEYBCMD.INC | 53 + v4.0/src/CMD/KEYB/KEYBCPSD.ASM | 128 +++ v4.0/src/CMD/KEYB/KEYBCPSD.INC | 29 + v4.0/src/CMD/KEYB/KEYBDCL.INC | 50 + v4.0/src/CMD/KEYB/KEYBEQU.INC | 31 + v4.0/src/CMD/KEYB/KEYBI2F.ASM | 225 +++++ v4.0/src/CMD/KEYB/KEYBI2F.INC | 26 + v4.0/src/CMD/KEYB/KEYBI48.ASM | 174 ++++ v4.0/src/CMD/KEYB/KEYBI48.INC | 27 + v4.0/src/CMD/KEYB/KEYBI9.ASM | 672 +++++++++++++ v4.0/src/CMD/KEYB/KEYBI9.INC | 29 + v4.0/src/CMD/KEYB/KEYBI9C.ASM | 1894 ++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/KEYB/KEYBI9C.INC | 41 + v4.0/src/CMD/KEYB/KEYBMAC.INC | 319 +++++++ v4.0/src/CMD/KEYB/KEYBMSG.INC | 44 + v4.0/src/CMD/KEYB/KEYBSHAR.INC | 307 ++++++ v4.0/src/CMD/KEYB/KEYBSYS.INC | 137 +++ v4.0/src/CMD/KEYB/KEYBTBBL.ASM | 855 +++++++++++++++++ v4.0/src/CMD/KEYB/KEYBTBBL.INC | 33 + v4.0/src/CMD/KEYB/MAKEFILE | 72 ++ v4.0/src/CMD/KEYB/PARSER.ASM | 517 ++++++++++ 28 files changed, 8500 insertions(+) create mode 100644 v4.0/src/CMD/KEYB/COMMSUBS.ASM create mode 100644 v4.0/src/CMD/KEYB/COMMSUBS.INC create mode 100644 v4.0/src/CMD/KEYB/KBMSG.INC create mode 100644 v4.0/src/CMD/KEYB/KEYB.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYB.LNK create mode 100644 v4.0/src/CMD/KEYB/KEYB.SKL create mode 100644 v4.0/src/CMD/KEYB/KEYBCMD.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBCMD.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBCPSD.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBCPSD.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBDCL.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBEQU.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBI2F.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBI2F.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBI48.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBI48.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBI9.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBI9.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBI9C.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBI9C.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBMAC.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBMSG.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBSHAR.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBSYS.INC create mode 100644 v4.0/src/CMD/KEYB/KEYBTBBL.ASM create mode 100644 v4.0/src/CMD/KEYB/KEYBTBBL.INC create mode 100644 v4.0/src/CMD/KEYB/MAKEFILE create mode 100644 v4.0/src/CMD/KEYB/PARSER.ASM (limited to 'v4.0/src/CMD/KEYB') diff --git a/v4.0/src/CMD/KEYB/COMMSUBS.ASM b/v4.0/src/CMD/KEYB/COMMSUBS.ASM new file mode 100644 index 0000000..3810ed2 --- /dev/null +++ b/v4.0/src/CMD/KEYB/COMMSUBS.ASM @@ -0,0 +1,603 @@ + PAGE ,132 + TITLE DOS - KEYB Command - Transient Command Processing + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: COMMSUBS.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Common subroutines used by NLS support +;; +;; Documentation Reference: +;; ------------------------ +;; None +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; +;; FIND_HW_TYPE - Determine the keyboard and system unit types and +;; set the corresponding flags. +;; +;; Include Files Required: +;; ----------------------- +;; None +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE ????????.ASM: +;; ????????? - ???????????????????????????????????????????? +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + PUBLIC FIND_SYS_TYPE ;; + PUBLIC FIND_KEYB_TYPE ;; + PUBLIC HW_TYPE ;; + PUBLIC SECURE_FL ;; + + ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBCPSD.INC ;; + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBCMD.INC ;; + INCLUDE DSEG.INC ;; + INCLUDE POSTEQU.INC ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: FIND_SYS_TYPE +;; +;; Description: +;; Determine the type of system we are running on. +;; SYSTEM_FLAG (in active SHARED_DATA) are set to +;; indicate the system type. +;; This routine is only called the first time KEYB is being installed. +;; +;; +;; Input Registers: +;; DS - points to our data segment +;; +;; Output Registers: +;; NONE +;; +;; Logic: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +ROM SEGMENT AT 0F000H ;; + ORG 0FFFEH ;; +ROMID DB ? ;; + ;; SEGMENT F000. (F000:FFFE) + ;; +ROMPC1 EQU 0FFH ;; ID OF PC1 hardware +ROMXT EQU 0FEH ;; ID OF PC-XT/PORTABLE hardware +ROMJR EQU 0FDH ;; ID OF PCjr & Optional ROM +ROMAT EQU 0FCH ;; ID OF PCAT +ROMXT_ENHAN EQU 0FBH ;; ID OF ENHANCED PCXT +ROMPAL EQU 0FAH ;; ID FOR PALACE +ROMLAP EQU 0F9H ;; ID FOR PC LAP (P-14) +ROM_RU_386 EQU 0F8H ;; ID FOR ROUNDUP-386 + ;; +ROM ENDS ;; + ;; + ;; ******** CNS + ROMEXT SEGMENT AT 00000H ;; ADDRESS SHOULD NOT BE FIXED AT + ORG 0003BH ;;AT 09FC0H -- This is just a ;; + KEYBID1 DB ? ;;a dummy value of 000H INT 15H call + ;; will load dynamically depending + ;; upon system mem size- 9FC0 was only for 640K system + ;; *** UNTRUE SEGMENT 9FC0. (9FC0:003B) + ROMEXT ENDS ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;***CNS + + + + + + + + +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FIND_SYS_TYPE PROC NEAR ;; + ;; + MOV AX,ROM ;; Set segmant to look at ROM + MOV DS,AX ;; using the data segment + ASSUME DS:ROM ;; + ;; + MOV AL,ROMID ;; Get hardware ID + PUSH AX ;; save it + ;; + PUSH CS ;; Set data seg back to code + POP DS ;; + ASSUME DS:CODE ;; + ;; + MOV AH,92H ;; SET INVALID CALL FOR INT16 + INT 16H ;; CALL BIOS + CMP AH,80H ;; IS EXTENDED INTERFACE THERE? + JA CHECK_PC_NET ;; NO, SKIP FLAG + OR SD.SYSTEM_FLAG,EXT_16 ;; default is extended INT 16 support + ;; +CHECK_PC_NET: ;; + MOV AH,30H ;; GET DOS VERSION NUMBER + INT 21H ;; MAJOR # IN AL, MINOR # IN AH + CMP AX,0A03H ;; SENSITIVE TO 3.10 OR > + JB CHECK_SYSTEM ;; EARLIER VERSION OF DOS NOTHING + ;; WAS ESTABLISHED FOR THIS SITUATION + PUSH ES ;; Save ES just in case + MOV AX,3509H ;; GET INT VECTOR 9 CONTENTS + INT 21H ;; ES:BX WILL = CURRENT INT9 VECTOR + ;; WE WANT TO SEE IF WE ARE THE 1ST ONES LOADED + MOV CX,ES ;; INTO THE INT VECTOR 9. WITH DOS 3.1 WE CAN + POP ES ;; + CMP CX,0F000H ;; HANDSHAKE WITH THE PC NETWORK BUT NO ONE ELSE + JE CHECK_SYSTEM ;; INT VECTOR 9 POINTS TO ROM, OK + MOV AX,0B800H ;; ASK IF PC NETWORK IS INSTALLED + INT 2FH ;; + CMP AL,0 ;; NOT INSTALLED IF AL=0 + JE CHECK_SYSTEM ;; SOMEBODY ELSE HAS LINKED INTO THE INT VECTOR + ;; 9 & I'M GOING TO DROP RIGHT IN AS USUAL + OR SD.SYSTEM_FLAG,PC_NET ;; INDICATE PC NET IS RUNNING + ;; +CHECK_SYSTEM: ;; + POP AX ;; get code back + ;; Is the hardware a PCjr + CMP AL,ROMJR ;; + JNE TEST_PC_XT ;; IF not then check for next type + OR SD.SYSTEM_FLAG,PC_JR ;; system type + JMP FIND_SYS_END ;; Done + ;; +TEST_PC_XT: ;; + ;; Is the hardware a PC1 or XT ? + CMP AL,ROMXT ;; + JAE ITS_AN_XT ;; IF FE OR FF THEN ITS AN XT + CMP AL,ROMXT_ENHAN ;; IF FB IT IS ALSO AN XT + JNE TEST_PC_AT ;; IF not then check for next type +ITS_AN_XT: ;; + OR SD.SYSTEM_FLAG,PC_XT ;; system type + JMP FIND_SYS_END ;; + ;; +TEST_PC_AT: ;; + ;; Is the hardware an AT ? + CMP AL,ROMAT ;; + JNE TEST_P12 ;; IF not then check for next type + ;; + OR SD.SYSTEM_FLAG,PC_AT ;; system type + ;; + JMP FIND_SYS_END ;; + ;; +TEST_P12: ;; + CMP AL,ROMLAP ;; IS this a P12? + JNE TEST_PAL ;; IF not then check for next type + OR SD.SYSTEM_FLAG,PC_LAP ;; system type + JMP FIND_SYS_END ;; + ;; +TEST_PAL: ;; + CMP AL,ROMPAL ;; IS this a PALACE? + JNE TEST_RU_386 ;; IF not then check for next type + OR SD.SYSTEM_FLAG,PC_PAL ;; system type + JMP FIND_SYS_END ;; + ;; +TEST_RU_386: ;; + CMP AL,ROM_RU_386 ;; IS this a ROUNDUP with a 386? + JNE FIND_SYS_END ;; IF not then check for next type + OR SD.SYSTEM_FLAG,PC_386 ;; system type + MOV SD.TIMING_FACTOR,2 ;; Bump scale factor to account for 386 + ;; +FIND_SYS_END: ;; + ;; + RET ;; + ;; +FIND_SYS_TYPE ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: FIND_KEYB_TYPE +;; +;; Description: +;; Determine the type of keyboard we are running on. +;; KEYB_TYPE (in SHARED_DATA) is set to +;; indicate the keyboard type. +;; This routine is only called the first time KEYB is being installed. +;; +;; +;; Input Registers: +;; DS - points to our data segment +;; +;; Output Registers: +;; NONE +;; +;; Logic: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +HW_TYPE DW 0 ;; +;***CNS ;; + +SECURE_FL DB 0 +;RESERVED ADDRESS 013h BITS 1 & 2 + + PASS_MODE equ 00000001B ;AN000; + SERVER_MODE equ 00000010B ;AN000; + SECRET_ADD equ 13h ;AN000; + PORT_70 equ 70h ;AN000; + PORT_71 equ 71h ;AN000; + +;***CNS +G_KEYBOARD EQU 0AB41h ;;????? ;; Keyboard ID for FERRARI_G +P_KEYBOARD EQU 0AB54h ;;????? ;; Keyboard ID for FERRARI_P + ;; +P_KB_ID DB 08 ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FIND_KEYB_TYPE PROC NEAR ;; + ;; + PUSH ES ;; + PUSH DS ;; + ;; + MOV AX,ROM ;; Set segmant to look at ROM + MOV DS,AX ;; using the data segment + ASSUME DS:ROM ;; + ;; + MOV AX,DATA ;; + MOV ES,AX ;; ES points to BIOS data + ;; + MOV AL,ROMID ;; Get hardware ID + ;; + PUSH CS ;; Set data seg back to code + POP DS ;; + ASSUME DS:CODE ;; + ;; + ;; + MOV HW_TYPE,G_KB ;; Default keyboard is G_KB + ;; + ;; Is the hardware a PCjr + CMP AL,ROMJR ;; + JNE TEST_PC_XT_2 ;; IF not then check for next type + MOV HW_TYPE,JR_KB ;; keyboard type + JMP FIND_KEYB_END ;; Done + ;; +TEST_PC_XT_2: ;; + ;; Is the hardware a PC1 or XT ? + CMP AL,ROMXT ;; + JAE ITS_AN_XT_2 ;; IF FE OR FF THEN ITS AN XT + CMP AL,ROMXT_ENHAN ;; IF FB IT IS ALSO AN XT + JNE TEST_PC_AT_2 ;; IF not then check for next type +ITS_AN_XT_2: ;; + TEST ES:KB_FLAG_3,KBX ;; IS THE ENHANCED KEYBOARD INSTALLED? + JZ ITS_AN_XT_3 ;; + JMP FIND_KEYB_END ;; Yes, exit + ;; +ITS_AN_XT_3: ;; + MOV HW_TYPE,XT_KB ;; NO, normal XT keyboard + JMP FIND_KEYB_END ;; + ;; +TEST_PC_AT_2: ;; + ;; Is the hardware an AT ? + CMP AL,ROMAT ;; + JNE TEST_P12_2 ;; IF not then check for next type + ;; + ;; CHECK FOR ENHANCED KEYBOARD... + OR ES:KB_FLAG_2,08H ;; FROM COMNBODY.ASM - DON'T KNOW WHY + ;; + ;; READ ID COMMAND TO TEST FOR A KBX + ;; + MOV ES:KB_FLAG_3,RD_ID ;; INDICATE THAT A READ ID IS BEING + ;; DONE + MOV AL,0F2H ;; SEND THE READ ID COMMAND + CALL SND_DATA_AT ;; + ;; + MOV CX,03F00H ;; LOAD COUNT FOR ABOUT 37MS +WT_ID: TEST ES:KB_FLAG_3,KBX ;; TEST FOR KBX SET + LOOPZ WT_ID ;; WAIT OTHERWISE + ;; BE SURE FLAGS GOT RESET +;***CNS + ;; SAVE ALL REGISTERS BEFORE ENTRY + ;; INTO CHECKING KEYBOARD SECURITY + PUSH AX ;AN000; ;SAVE THE CURRENT ENVIRONMENT + PUSH BX ;AN000; + PUSH CX ;AN000; + PUSH DX ;AN000; + PUSH DS ;AN000; + PUSH ES ;AN000; + PUSH SI ;AN000; + PUSH DI ;AN000; + + + + CALL KEYB_SECURE ;SEE IF THE KEYBOARD SECURITY IS + ;ACTIVATED AT THIS POINT + + + POP DI ;AN000; + POP SI ;AN000; + POP ES ;AN000; + POP DS ;AN000; + POP DX ;AN000; + POP CX ;AN000; + POP BX ;AN000; + POP AX ;AN000;SAVE THE CURRENT ENVIRONMENT + + JNC ASSUME_AT ;AN000;SECURITY UNAVAILABLE OR AN AT KB + + + MOV SECURE_FL,1 ;AN000;SECURITY IS ACTIVE + JMP FIND_KEYB_END ;AN000;ASSUME IT IS A G_KB WITH + ;AN000;NUM LOCK OFF +ASSUME_AT: +;***CNS + AND ES:KB_FLAG_3,NOT RD_ID+LC_AB + ;; + TEST ES:KB_FLAG_3,KBX ;; WAS IT A KBX? + JNZ DONE_AT_2 ;; YES, WE ARE DONE + ;; + MOV HW_TYPE,AT_KB ;; NO, AT KBD +DONE_AT_2: ;; + JMP FIND_KEYB_END ;; + ;; +TEST_P12_2: ;; + CMP AL,ROMLAP ;; IS this a P12? + JNE TEST_XT_ENH_OR_NEWER ;; IF not then check for next type + MOV HW_TYPE,P12_KB ;; IF yes then set flag + ;; +TEST_XT_ENH_OR_NEWER: ;; + CMP AL,ROMXT_ENHAN ;; + JNA GET_KEYB_ID ;; ** assume all new systems will have ext + JMP FIND_KEYB_END ;; ** ROM or else test previous to this + ;; +GET_KEYB_ID: ;; +;***************************** CNS **************************************** +;* This area has been Revised to allow the extended ROM support added +;* flexibility for the PALACE or FLASHLIGHT with less than 640k; AN extended +;* BIOS DATA call is to be made returning the segment of the extended +;* BIOS area which should be in maximum memory - 1k area. +;*************************************************************************** + + MOV AH,0C1H ;; Make the extended bios data area + INT 15H ;; call to get the segment address for + JNC NEW_SYSTEM ;; accessing the keyboard byte area + JMP FIND_KEYB_END ;; JNC SOMEWHERE&REPORT + ;; otherwise EXTENDED BIOS DATA RETURNED + ;; in the ES + ;; save the starting seg address value + ;; needs to start at locale 0003BH +;**************************************************************************** +NEW_SYSTEM: +;**CNS + ;; Set segment to look at extended ROM + ;; using the data segment + PUSH ES ;; SEG value returned from INT15h -- C1 call + POP DS + ASSUME DS:ROMEXT ;; + ;; + MOV AX,DATA ;; + MOV ES,AX ;; BP points to BIOS data + + ;; + MOV AL,KEYBID1 ;; Get keyboard ID ********** CNS +;**CNS +;***************************************************************************** +;old MOV AX,ROMEXT ;; Set segment to look at extended ROM +;code MOV DS,AX ;; using the data segment +; ASSUME DS:ROMEXT ;; +; ;; +; MOV AX,DATA ;; +;old MOV ES,AX ;; ES points to BIOS data +;code ;; +; MOV AL,KEYBID1 ;; Get keyboard ID +;****************************************************************************** + PUSH CS ;; Set data seg back to code + POP DS ;; + ASSUME DS:CODE ;; + ;; + AND AL,0FH ;; Remove high nibble + CMP AL,P_KB_ID ;; IF keyboard is a FERRARI P THEN + JNE FIND_KEYB_END ;; + OR HW_TYPE,P_KB ;; Set the HW_TYPE flag + ;; +FIND_KEYB_END: ;; ELSE + MOV AX,HW_TYPE ;; Leave default alone + MOV SD.KEYB_TYPE,AX ;; + ;; + POP DS ;; + POP ES ;; + RET ;; + ;; +FIND_KEYB_TYPE ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: SND_DATA_AT +;; +;; Description: +;; THIS ROUTINE HANDLES TRANSMISSION OF PC/AT COMMAND AND DATA BYTES +;; TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO +;; HANDLES ANY RETRIES IF REQUIRED +;; +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to the BIOS data segment +;; +;; Output Registers: +;; +;; Logic: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SND_DATA_AT 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 ES:KB_FLAG_2,NOT (KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS + +;------- WAIT FOR COMMAND TO BE ACCEPTED + + SUB CX,CX +SD5: + IN AL,STATUS_PORT + TEST AL,INPT_BUF_FULL + LOOPNZ SD5 ; WAIT FOR COMMAND TO BE ACCEPTED +; + MOV AL,BH ; REESTABLISH BYTE TO TRANSMIT + OUT PORT_A,AL ; SEND BYTE + STI ; ENABLE INTERRUPTS + MOV CX,01A00H ; LOAD COUNT FOR 10mS+ +SD1: TEST ES: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 ES:KB_FLAG_2,KB_ERR ; TURN ON TRANSMIT ERROR FLAG + JMP SHORT SD4 ; RETRIES EXHAUSTED FORGET TRANSMISSION +; +SD3: TEST ES:KB_FLAG_2,KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE + JZ SD2 ; IF NOT, GO RESEND +; + ;; If this was an acknowledge, determine*RPS + ;; if keyboard is FERRARI G or P *RPS + MOV CX,1000 ;; +IO_DELAY1: ;; + LOOP IO_DELAY1 ;; + JMP SHORT $+2 ;; Allow for recovery time + IN AL,PORT_A ;; READ IN THE CHARACTER *RPS + MOV CX,1000 ;; +IO_DELAY2: ;; + LOOP IO_DELAY2 ;; + JMP SHORT $+2 ;; Allow for recovery time + MOV BH,AL ;; *RPS + ;; + IN AL,PORT_A ;; READ IN THE CHARACTER *RPS + MOV BL,AL ;; *RPS + ;; *RPS + CMP BX,P_KEYBOARD ;; Set HW_TYPE appropriately *RPS + JNE SD4 ;; *RPS + OR HW_TYPE,P_KB ;; *RPS + ;; +SD4: POP CX ; RESTORE REGISTERS + POP BX + POP AX ; * + RET ; RETURN, GOOD TRANSMISSION +SND_DATA_AT ENDP + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;************************************************************************ +; KEYBOARD SECURITY LOGIC +; CHECK THE CMOS RAM @ ADDRESS HEX 013H +; CHECK TO SEE IF EITHER BITS 1 (PASSWORD) OR 2 (SERVER MODE) ARE SET ON +; IF EITHER BIT IS SET ON THE SYSTEM IS A MOD 50 on up +; REPORT MESSAGE KEYBOARD LOCKED UNABLE TO LOAD KEYBOARD TABLES +; OTHERWISE AN INVALID RESPONSE OR ZERO SHOULD BE RETURNED +; PROCEED AS WITH LOADING OF THE CORRECT TABLES + +; PROPOSED KEYBOARD SYNTAX + +; KEYB [lang],[cp],[[d:][path]KEYBOARD.SYS][/ID:id] + + + +;************************************************************************ + +KEYB_SECURE PROC NEAR + + + +;RESERVED ADDRESS 013h BITS 1 & 2 + +; PASS_MODE equ 00000001B ;AN000; +; SERVER_MODE equ 00000010B ;AN000; + + + +; SECRET_ADD equ 13h ;AN000; +; PORT_70 equ 70h ;AN000; +; PORT_71 equ 71h ;AN000; + +; PUSH AX ;AN000; ;SAVE THE CURRENT ENVIRONMENT +; PUSH BX ;AN000; +; PUSH CX ;AN000; +; PUSH DX ;AN000; +; PUSH CS ;AN000; +; PUSH DS ;AN000; +; PUSH ES ;AN000; +; PUSH SI ;AN000; +; PUSH DI ;AN000; + CLI ;AN000;;DISABLE THE INTERRUPT TO AVOID + ;AN000;;THE CMOS REGISTER BEFORE + ;AN000;;THE READ & WRITE IS DONE + + XOR AX,AX + MOV AL,SECRET_ADD + OUT PORT_70,AL ;AN000;;SEND THE ADDRESS CONTAINING THE + ;BITS FOR THE PASSWORD AND SERVER + ;MODE STATE TO PORT 70H + + + + + + IN AL,PORT_71 ;AN000;;READ THE DATA IN TO GET THE + ;RESULTS OF THE CHECK FOR THE + ;EXISTENCE OF SECURITY. + + MOV DX,AX + + TEST DL,PASS_MODE+SERVER_MODE ;AN000;;CHECK & SEE IF THE BITS ARE ON + JNZ KEYB_LOCKED ;AN000;;YES THEY ARE ON SO EXIT AND REPORT + CLC ;XOR AX,AX ;ASSUME THIS IS AN AT KEYBOARD + JMP SECURE_RET + +KEYB_LOCKED: + + STC ; MOV AX,1 ;AN000;SET THE SECURITY FLAG + ;ON; + ;PROCEED - EITHER SYSTEM IS AN + ;AT OR THE SYSTEM IS UNLOCKED +SECURE_RET: + + STI ;AN000;;ENABLE THE INTERRUPT + + +; POP DI ;AN000; +; POP SI ;AN000; +; POP ES ;AN000; +; POP DS ;AN000; +; POP CS ;AN000; +; POP DX ;AN000; +; POP CX ;AN000; +; POP BX ;AN000; +; POP AX ;AN000; ;SAVE THE CURRENT ENVIRONMENT + + + RET + + +KEYB_SECURE ENDP + + + + +CODE ENDS + END diff --git a/v4.0/src/CMD/KEYB/COMMSUBS.INC b/v4.0/src/CMD/KEYB/COMMSUBS.INC new file mode 100644 index 0000000..96bea5d --- /dev/null +++ b/v4.0/src/CMD/KEYB/COMMSUBS.INC @@ -0,0 +1,30 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: CONVERT.INC +;; ---------- +;; +;; Root File Name: KEYBCMD.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; External declarations for procedures in file KEYBCMD.ASM. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN FIND_SYS_TYPE :NEAR ;; + EXTRN FIND_KEYB_TYPE :NEAR ;; + ;; + EXTRN HW_TYPE :WORD ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST diff --git a/v4.0/src/CMD/KEYB/KBMSG.INC b/v4.0/src/CMD/KEYB/KBMSG.INC new file mode 100644 index 0000000..f7beb54 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KBMSG.INC @@ -0,0 +1,21 @@ + ;; +ACT_KEYB DB 'Current keyboard code: ','$' ;; +ACT_KEYB_CP DB ' code page: ','$' ;; +ACT_CON_CP DB 'Current CON code page: ','$' ;; +INV_L DB 'Invalid keyboard code specified',10,13,'$' ;; +INV_I DB 'Invalid keyboard ID specified',10,13,'$' ;; +INV_CP DB 'Invalid code page specified',10,13,'$' ;; +INV_S DB 'Invalid syntax',10,13,'$' ;; +INV_FN DB 'Bad or missing Keyboard Definition File',10,13,'$' ;; +INV_KEYB_Q DB 'KEYB has not been installed',10,13,'$' ;; +INV_CON_Q DB 'Active code page not available from CON device',10,13,'$' ;; +NOT_DESIG DB 'Code page specified has not been prepared',10,13,'$' ;; +NOT_SUPP DB 'One or more CON code pages invalid for given keyboard code',10,13,'$' ;; +NOT_VALID1 DB 'Code page requested (','$' ;; +NOT_VALID2 DB ') is not valid for given keyboard code',10,13,'$' ;; +WARNING_1 DB 'Code page specified is inconsistent with the selected code page',10,13,'$' ;; +INV_COMBO DB 'ID code specified is inconsistent with the selected keyboard code',13,'$' ;; +MEMORY_OVERF DB 'Unable to create KEYB table in resident memory',10,13,'$' ;; +CR_LF DB 10,13,'$' ;; + ;; + \ No newline at end of file diff --git a/v4.0/src/CMD/KEYB/KEYB.ASM b/v4.0/src/CMD/KEYB/KEYB.ASM new file mode 100644 index 0000000..fffce04 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYB.ASM @@ -0,0 +1,71 @@ + + PAGE ,132 + TITLE DOS - KEYB Command - Root Module + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (c) Copyright 1988 Microsoft +;; +;; File Name: KEYB.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Contains root module for KEYB command. This module is the +;; KEYB command entry point. KEYB is an external command included +;; with PC DOS 3.3 to provide keyboard support for 14 languages. +;; KEYB will jump immediately into the command processing in +;; file KEYBCMD. All resident code is included before KEYBCMD +;; in the linkage list. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 NLS Interface Specification - May ?? 1986 +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; +;; +;; Include Files Required: +;; ----------------------- +;; KEYBCMD.INC - External declarations for transient command +;; processing routines +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE KEYCMD.ASM: +;; KEYB_COMMAND - Main routine for transient command processing. +;; +;; Linkage Instructions: +;; -------------------- +;; Link in .COM format. Resident code/data is in files KEYB thru +;; KEYBCPSD. +;; +;; LINK KEYB+KEYBI9+KEYBI9C+KEYBI2F+KEYBI48+KEYBCPSD+KEYBMSG+ +;; COMMSUBS+KEYBTBBL+KEYBCMD; +;; EXE2BIN KEYB.EXE KEYB.COM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + ;; +CODE SEGMENT PUBLIC 'CODE' BYTE ;; + ;; + INCLUDE KEYBCMD.INC ;; Bring in external declarations + ;; for transient command processing + ASSUME CS:CODE,DS:CODE ;; + ORG 100H ;; required for .COM + ;; + ;; +START: ;; + ;; + JMP KEYB_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +CODE ENDS + END START diff --git a/v4.0/src/CMD/KEYB/KEYB.LNK b/v4.0/src/CMD/KEYB/KEYB.LNK new file mode 100644 index 0000000..4ef13e5 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYB.LNK @@ -0,0 +1,3 @@ +Keyb+keybi9+KEYBI9C+keybi2f+keybi48+ +keybcpsd+commsubs+keybtbbl+parser+KEYBCMD; + \ No newline at end of file diff --git a/v4.0/src/CMD/KEYB/KEYB.SKL b/v4.0/src/CMD/KEYB/KEYB.SKL new file mode 100644 index 0000000..7bb2b5c --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYB.SKL @@ -0,0 +1,37 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Message Skeleton file for KEYB.COM +; +; Author: WGR +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +:util KEYB ;AN000;ty name +:class 2 +:use PARSE1 ;AN000; +:use PARSE2 ;AN000; +:use PARSE3 ;AN000; +:use PARSE4 ;AN000; +:use PARSE6 ;AN000; +:use PARSE7 ;AN000; +:use PARSE10 ;AN003; +:class A +:use 1 COMMON1 ;AN000;rrect DOS version' +:def 2 "Current keyboard code: %1" ;AN000; +:def 3 "Current keyboard ID: %1" ;AN000; +:def 4 " code page: %1",CR,LF ;AN000; +:def 5 "Current CON code page: %1",CR,LF ;AN000; +:def 6 "Invalid keyboard code specified",CR,LF ;AN000; +:def 7 "Invalid keyboard ID specified",CR,LF ;AN000; +:def 8 "Invalid code page specified",CR,LF ;AN000; +:def 9 "Bad or missing Keyboard Definition File",CR,LF ;AN000; +:def 10 "KEYB has not been installed",CR,LF ;AN000; +:def 11 "Active code page not available from CON device",CR,LF ;AN000; +:def 12 "Code page specified has not been prepared",CR,LF ;AN000; +:def 13 "One or more CON code pages invalid for given keyboard code",CR,LF ;AN000; +:def 14 "Code page requested (%1) is not valid for given keyboard code",CR,LF ;AN000; +:def 15 "Code page specified is inconsistent with the selected code page",CR,LF ;AN000; +:def 16 "ID code specified is inconsistent with the selected keyboard code",CR,LF ;AN000; +:def 17 "Unable to create KEYB table in resident memory",CR,LF ;AN000; +:use 18 PARSE8 ; 'Parameter format not correct' ;AN000; +:end ;AN000; diff --git a/v4.0/src/CMD/KEYB/KEYBCMD.ASM b/v4.0/src/CMD/KEYB/KEYBCMD.ASM new file mode 100644 index 0000000..57033f3 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBCMD.ASM @@ -0,0 +1,2072 @@ + + PAGE ,132 + TITLE DOS - KEYB Command - Transient Command Processing + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBCMD.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Contains transient command processing modules for KEYB command. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; Procedures contained in this file: +;; ---------------------------------- +;; KEYB_COMMAND: Main routine for command processing. +;; PARSE_PARAMETERS: Validate syntax of parameters included +;; on command line. +;; BUILD_PATH: Find KEYBOARD.SYS file and validate language and/or +;; code page. +;; INSTALL_INT_VECTORS: Install our INT 9, INT 2F, INT48 Drivers +;; REMOVE_INT_VECTORS: Remove our INT 9, INT 2F, INT48 Drivers +;; NUMLK_ON: Turn on the NUM LOCK LED +;; FIND_FIRST_CP: Determine first code page for given language in the +;; Keyboard Definition file. +;; +;; Include Files Required: +;; ----------------------- +;; KEYBMSG.INC +;; KEYBEQU.INC +;; KEYBSYS.INC +;; KEYBI9C.INC +;; KEYBI9.INC +;; KEYBI2F.INC +;; KEYBI48.INC +;; KEYBSHAR.INC +;; KEYBDCL.INC +;; KEYBTBBL.INC +;; COMMSUBS.INC +;; KEYBCPSD.INC +;; POSTEQU.INC +;; DSEG.INC +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE KEYBTBBL.ASM: +;; TABLE_BUILD - Create the shared area containing all keyboard tables. +;; STATE_BUILD - Build all states within the table area +;; FROM FILE KEYBMSG.ASM: +;; KEYB_MESSAGES - All messages +;; +;; Change History: +;; +;; Revised for DOS 4.00 - NickS +;; A000 - WilfR +;; AN002- DCR ???? -KEYBAORD SECURITY LOCK - CNS +;; +;; +;; an003 PTM 3906 - KEYB messages do not conform +;; to spec. Error message does +;; 3/24/88 not pass back the bogus command +;; line argument. - CNS +;; +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + PUBLIC KEYB_COMMAND ;; + ;; +;*****************CNS******************** + PUBLIC ID_TAB_OFFSET ;AN000; +;*****************CNS******************** + PUBLIC CP_TAB_OFFSET ;; + PUBLIC STATE_LOGIC_OFFSET ;; + PUBLIC SYS_CODE_PAGE ;; + PUBLIC KEYBCMD_LANG_ENTRY_PTR ;; + PUBLIC DESIG_CP_BUFFER ;; + PUBLIC DESIG_CP_OFFSET ;; + PUBLIC KEYBSYS_FILE_HANDLE ;; + PUBLIC NUM_DESIG_CP ;; + PUBLIC TB_RETURN_CODE ;; + PUBLIC FILE_BUFFER ;; + PUBLIC FILE_BUFFER_SIZE + PUBLIC FB ;; +;*****************CNS******************** + PUBLIC ID_PTR_SIZE ;AN000; + PUBLIC LANG_PTR_SIZE ;AN000; + PUBLIC CP_PTR_SIZE ;AN000; + PUBLIC NUM_ID ;AN000; + PUBLIC NUM_LANG ;AN000; + PUBLIC NUM_CP ;AN000; + PUBLIC SHARED_AREA_PTR ;; +;*****************CNS******************** + PUBLIC SD_SOURCE_PTR ;; + PUBLIC TEMP_SHARED_DATA ;; + ;; + PUBLIC FOURTH_PARM ;AN000; ;AN000 + PUBLIC ONE_PARMID ;AN000; ;AN000 + PUBLIC FTH_PARMID ;AN000; ;AN000 + PUBLIC ID_FOUND ;AN000; ;AN000 + PUBLIC BAD_ID ;AN000; ;AN000 + PUBLIC ALPHA ;AN000; ;AN000 + EXTRN PARSE_PARAMETERS:NEAR ;AN000; ;AN000 +;***CNS + EXTRN SECURE_FL:BYTE ;an002; + EXTRN CUR_PTR:WORD ;an003; + EXTRN OLD_PTR:WORD ;an003; + EXTRN ERR_PART:WORD ;an003; +;***CNS +.xlist + INCLUDE STRUC.INC ;AN000;;; WGR structured macros ;AN000 + INCLUDE SYSMSG.INC ;AN000;;; WGR message retriever ;AN000 +.list + ;; +MSG_UTILNAME ;AN000;;; WGR identify to message retriever ;AN000 + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; +.xlist ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBSYS.INC ;; + INCLUDE KEYBI9.INC ;; + INCLUDE KEYBI9C.INC ;; + INCLUDE KEYBI2F.INC ;; + INCLUDE KEYBI48.INC ;; + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBDCL.INC ;; + INCLUDE KEYBTBBL.INC ;; + INCLUDE COMMSUBS.INC ;; + INCLUDE KEYBCPSD.INC ;; +.xlist + INCLUDE POSTEQU.INC ;; + INCLUDE DSEG.INC ;; + ;; +.list + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: KEYB_COMMAND +;; +;; Description: +;; Main routine for transient command processing. +;; +;; Input Registers: +;; DS - points to our data segment +;; +;; Output Registers: +;; Upon termination, if an error has occurred in which a keyboard table +;; was not loaded, the AL register will contain the a error flag. This +;; flag is defined as follows: +;; AL:= 1 - Invalid language, code page, or syntax +;; 2 - Bad or missing Keyboard Definition File +;; 3 - KEYB could not create a table in resident memory +;; 4 - An error condition was received when communicating +;; with the CON device +;; 5 - Code page requested has not been designated +;; 6 - The keyboard table for the requested code page cannot +;; be found in resident keyboard table. +;; +;; Logic: +;; IF KEYB has NOT been previously loaded THEN +;; Set SHARED_AREA_PTR to TEMP_SHARED_AREA +;; INSTALLED_KEYB := 0 +;; Get HW_TYPE (set local variable) +;; ELSE +;; Set SHARED_AREA_PTR to ES:SHARED_AREA +;; Get HW_TYPE (set local variable) +;; Set TABLE_OK := 0 +;; INSTALLED_KEYB := 1 +;; +;; IF CPS-CON has been loaded THEN +;; INSTALLED_CON := 1 +;; +;;*********************************** CNS ************************************* +;; Call PARSE_PARAMETERS := Edit ID or language, code page, +;; and path parameters,ID on command line +;;*********************************** CNS ************************************* +;; Check all return codes: +;; IF any parameters are invalid THEN +;; Display ERROR message +;; ELSE +;; IF no language parm specified +;; AND code page is not invalid +;; AND syntax is valid THEN +;; Process QUERY: +;; IF KEYB is installed THEN +;; Get and display active language from SHARED_DATA_AREA +;; Get invoked code page from SHARED_DATA_AREA +;; Convert to ASCII +;; Display ASCII representation of code page, CR/LF +;;*********************************** CNS ************************************* +;; IF ALTERNATE FLAG SET +;; Get and display active ID from SHARED_DATA_AREA +;; Convert to ASCII +;; Display ASCII representation of ID, CR/LF +;;*********************************** CNS ************************************* +;; IF CPS-CON is installed THEN +;; Get selected code page info from CON +;; Convert to ASCII +;; Display ASCII representation of code page, CR/LF +;; EXIT without staying resident +;; +;; ELSE +;; Call BUILD_PATH := Determine location of Keyboard definition file +;; Open the file +;; IF error in opening file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Save handle +;; Set address of buffer +;; READ header of Keyboard definition file +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Check signature for correct file +;; IF file signature is correct THEN +;; READ language table +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Use table to verify language parm +;; Set pointer values +;; IF code page was specified +;; READ language entry +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; READ Code page table +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Use table to verify code page parm +;; Set pointer values +;; IF CPS-CON is not installed THEN +;; Set number of code pages = 1 +;; IF CODE_PAGE_PARM was specified THEN +;; Copy CODE_PAGE_PARM into table of code pages to build +;; ELSE +;; Call FIND_FIRST_CP := Define the system code page (1st in Keyb Def file) +;; Copy SYSTEM_CP into table of code pages to build +;; ELSE +;; Issue INT 2F ; 0AD03H to get table of Designated code pages +;; Set number of designated code pages (HWCP + Desig CP) +;; Issue INT 2F ; 0AD02H to get invoked code page +;; IF CODE_PAGE_PARM was specified THEN +;; Check that CODE_PAGE_PARM is in the list of designated code pages +;; IF CODE_PAGE_PARM is in the list of designated code pages THEN +;; Copy specified CP into table of code pages to build +;; IF a CP has been selected AND is inconsistent with specified CP +;; Issue WARNING message +;; ELSE +;; Display ERROR message +;; ELSE +;; IF a code page has been invoked THEN +;; Copy invoked code page into table of code pages to build +;; ELSE +;; Call FIND_FIRST_CP := Define the system code page (1st in Keyb Def file) +;; Copy SYSTEM_CP into table of code pages to build +;; +;; IF KEYB has not been previously installed THEN +;; Call FIND_SYS_TYPE := Determine system type +;; IF system type is PCjr THEN +;; IF multilingual ROM is present THEN +;; Set language code +;; EXIT without staying resident +;; Call INSTALL_INT_9 := Install INT 9 handler +;; Call FIND_KEYB_TYPE := Determine the keyboard type +;; +;; Call TABLE_BUILD := Build the TEMP_SHARED_DATA_AREA +;; +;; IF return codes from TABLE_BUILD are INVALID THEN +;; IF KEYB_INSTALLED := 0 THEN +;; Call REMOVE_INT_9 +;; Display corresponding ERROR message +;; EXIT without staying resident +;; ELSE +;; IF any of the designated CPs were invalid in the build THEN +;; Issue WARNING message +;; Close the Keyboard definition file +;; IF KEYB had NOT already been installed THEN +;; IF keyboard is a Ferrari_G AND system is not an XT THEN +;; Call NUMLK_ON := Turn the NUM LOCK LED on +;; IF extended INT 16 support required THEN +;; Install extended INT 16 support +;; Call INSTALL_INT_9_NET := Let network know about INT 9 +;; Call INSTALL_INT_2F_48 := Install the INT 2F and INT 48 drivers +;; Activate language +;; Get resident end and copy TEMP_SHARED_DATA_AREA into SHARED_DATA_AREA +;; EXIT but stay resident +;; ELSE +;; IF this was not a query call AND exit code was valid THEN +;; Activate language +;; Get resident end and copy TEMP_SHARED_DATA_AREA into SHARED_DATA_AREA +;; EXIT without staying resident +;; END +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INVALID_PARMS EQU 1 ;; EXIT return codes +BAD_KEYB_DEF_FILE EQU 2 ;; +MEMORY_OVERFLOW EQU 3 ;; +CONSOLE_ERROR EQU 4 ;; +CP_NOT_DESIGNATED EQU 5 ;; +KEYB_TABLE_NOT_LOAD EQU 6 ;; +BAD_DOS_VER EQU 7 ;AN000;;; WGR ;AN000 + ;; +EXIT_RET_CODE DB 0 ;; +;******************** CNS *********** ;AN000;;; +ID_VALID EQU 0 ;AN000;;; +ID_INVALID EQU 1 ;AN000;;; +NO_ID EQU 2 ;AN000;;; +LANGUAGE_VALID EQU 0 ;AN000;;; +LANGUAGE_INVALID EQU 1 ;AN000;;; Return Codes +NO_LANGUAGE EQU 2 ;AN000;;; from +NO_IDLANG EQU 3 ;AN000;;; +;******************** CNS *********** ;; +CODE_PAGE_VALID EQU 0 ;; EDIT_LANGUAGE_CODE +CODE_PAGE_INVALID EQU 1 ;; +NO_CODE_PAGE EQU 2 ;; +VALID_SYNTAX EQU 0 ;; +INVALID_SYNTAX EQU 1 ;;;;;;; + ;; +ACT_KEYB EQU 2 ;AC000;;; WGR ;AN000 +ACT_ID EQU 3 ;AC000;;; WGR ;AN000 +ACT_KEYB_CP EQU 4 ;AC000;;; WGR ;AN000 +ACT_CON_CP EQU 5 ;AC000;;; WGR ;AN000 +INV_L EQU 6 ;AC000;;; WGR message numbers... ;AN000 +INV_I EQU 7 ;AC000;;; WGR ;AN000 +INV_CP EQU 8 ;AC000;;; WGR ;AN000 +INV_S EQU 18 ;AC000;;; WGR ;AN000 +INV_FN EQU 9 ;AC000;;; WGR ;AN000 +INV_KEYB_Q EQU 10 ;AC000;;; WGR ;AN000 +INV_CON_Q EQU 11 ;AC000;;; WGR ;AN000 +NOT_DESIG EQU 12 ;AC000;;; WGR ;AN000 +NOT_SUPP EQU 13 ;AC000;;; WGR ;AN000 +NOT_VALID EQU 14 ;AC000;;; WGR ;AN000 +WARNING_1 EQU 15 ;AC000;;; WGR ;AN000 +INV_COMBO EQU 16 ;AC000;;; WGR ;AN000 +MEMORY_OVERF EQU 17 ;AC000;;; WGR ;AN000 +CR_LF DB 10,13,'$' ;; WGR ;AN000 + ;; +FOURTH_PARM DB 0 ;AN000;;; WGR switch was specified ;AN000 +ONE_PARMID DB 0 ;AN000;;; WGR id given as positional ;AN000 +FTH_PARMID DB 0 ;AN000;;; WGR id given as switch ;AN000 +ID_FOUND DB 0 ;AN000;;; WGR id was good (in k.d. file) ;AN000 +BAD_ID DB 0 ;AN000;;; WGR id was bad (from parse) ;AN000 +ALPHA DB 0 ;AN000;;; WGR first parm a language id ;AN000 + ;; +ID_DISPLAYED DB 0 ;AN000;;; WGR Indicating ID already displayed ;AN000 + ;; WGR ;AN000 +SUBLIST_NUMBER LABEL BYTE ;AN000;;; WGR sublist for numbers ;AN000 + DB 11 ;AN000;;; WGR size ;AN000 + DB 0 ;AN000;;; WGR ;AN000 +PTR_TO_NUMBER DW ? ;AN000;;; WGR offset ptr ;AN000 +SEG_OF_NUMBER DW ? ;AN000;;; WGR segment ;AN000 + DB 1 ;AN000;;; WGR ;AN000 + DB 10100001B ;AN000;;; WGR flag ;AN000 + DB 3 ;AN000;;; WGR max width ;AN000 + DB 1 ;AN000;;; WGR min width ;AN000 + DB " " ;AN000;;; WGR filler ;AN000 + ;AN000;;; WGR + ;AN000;;; WGR +SUBLIST_ASCIIZ LABEL BYTE ;AN000;;; WGR sublist for asciiz ;AN000 + DB 11 ;AN000;;; WGR size ;AN000 + DB 0 ;AN000;;; WGR ;AN000 +PTR_TO_ASCIIZ DW ? ;AN000;;; WGR offset ptr ;AN000 +SEG_OF_ASCIIZ DW ? ;AN000;;; WGR segment ;AN000 + DB 1 ;AN000;;; WGR ;AN000 + DB 00010000B ;AN000;;; WGR flag ;AN000 + DB 2 ;AN000;;; WGR max width ;AN000 + DB 2 ;AN000;;; WGR min width ;AN000 + DB " " ;AN000;;; WGR filler ;AN000 + ;AN000;;; WGR ;AN000 +NUMBER_HOLDER DW ? ;AN000;;; WGR used for message retriever ;AN000 +;***CNS +SUBLIST_COMLIN LABEL BYTE ;an003;;; WGR sublist for asciiz ;AN000 + DB 11 ;an003;;; WGR size ;AN000 + DB 0 ;an003;;; WGR ;AN000 +PTR_TO_COMLIN DW ? ;an003;;; WGR offset ptr ;AN000 +SEG_OF_COMLIN DW ? + DB 0 ;an003;;; WGR ;AN000 + DB LEFT_ALIGN+CHAR_FIELD_ASCIIZ ;AN000;;; WGR flag ;AN000 + + DB 0 ;an003;;; WGR max width ;AN000 + DB 1 ;an003;;; WGR min width ;AN000 + DB " " ;an003;;; WGR filler ;AN000 + + +STRING_HOLDER DB 64 DUP(0) +;***CNS ;; + ;; +FILE_BUFFER_SIZE EQU 50*6 +FILE_BUFFER DB FILE_BUFFER_SIZE DUP(0) ;AC000;;; Buffer for Keyboard Def file +FB EQU FILE_BUFFER ;AC000;m for 32 language entries) +DESIG_CP_BUFFER DW 28 DUP(?) ;; (Room for 25 code pages) +DESIG_CP_BUF_LEN DW $-DESIG_CP_BUFFER ;; Length of code page buffer +NUM_DESIG_CP DW 0 ;; +CP_TAB_OFFSET DD ? ;; +;****************** CNS ******************;AN000; +TOTAL_SIZE DW 0 ;AN000; +PASS_LANG DW 0 ;AN000; +ID_TAB_OFFSET DD ? ;AN000; +;****************** CNS ******************;; +STATE_LOGIC_OFFSET DD -1 ;; +KEYBSYS_FILE_HANDLE DW ? ;;;;;;;;;;; +TB_RETURN_CODE DW 1 ;; +DESIG_CP_OFFSET DW OFFSET DESIG_CP_BUFFER ;; +SYS_CODE_PAGE DW 0 ;; +DESIG_LIST DW 0 ;; +QUERY_CALL DB 0 ;; + ;; +KB_MASK EQU 02h ;; + ;; +SIGNATURE DB 0FFh,'KEYB ' ;; +SIGNATURE_LENGTH DW 8 ;; +;****************** CNS ***************************;AN000; +NUM_ID DW 0 ;AN000; +ERR4ID DB 0 ;AN000; +NUM_LANG DW 0 ;AN000; +NUM_CP DW 0 ;AN000; +ID_PTR_SIZE DW SIZE KEYBSYS_ID_PTRS ;AN000; +;****************** CNS ***************************** +LANG_PTR_SIZE DW SIZE KEYBSYS_LANG_PTRS ;; +CP_PTR_SIZE DW SIZE KEYBSYS_CP_PTRS ;; +KEYBCMD_LANG_ENTRY_PTR DD ? ;; + ;; +KEYB_INSTALLED DW 0 ;; +CON_INSTALLED DW 0 ;; +SHARED_AREA_PTR DD 0 ;; +GOOD_MATCH DW 0 ;; +;****************** CNS ***************************;; +LANGUAGE_ASCII DB '??',0 ;; WGR ;AC000 + ;; +CMD_PARM_LIST PARM_LIST <> ;; + ;; +JR_LANGUAGE_CODES DW 'FR','GR','IT','SP','UK' ;; + ;; +JR_NUM_CODES EQU 5 ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;---------- TABLES FOR EXTENDED KEYBOARD SUPPORT CTRL CASE --------- RWV 11-06-85 ;; + ;; +RPL_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,148,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 150,-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,141,132,142,115,143 ; Home, Up, PgUp, -, Left, Pad5 ;; + DB 116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins ;; + DB 147,-1,-1,-1,137,138 ; Del, SysReq, Undef, WT, F11, F12 ;; +L_CTRL_TAB EQU $-RPL_K8 ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYB_COMMAND PROC NEAR ;; + ;; + CALL SYSLOADMSG ;AN000;load messages ;AN000 + JNC VERSION_OK ;AN000;if no carry then version ok ;AN000 + CALL SYSDISPMSG ;AN000;error..display version error ;AN000 + MOV AL,BAD_DOS_VER ;AN000;bad DOS version ;AN000 + MOV EXIT_RET_CODE,AL ;AN000; ;AN000 + JMP KEYB_EXIT_NOT_RESIDENT ;AN000;exit..non resident ;AN000 +VERSION_OK: ;; WGR ;AN000 + MOV SEG_OF_NUMBER,CS ;AN000;initialize.. ;AN000 + MOV SEG_OF_ASCIIZ,CS ;AN000; ..sublists ;AN000 + MOV BP,OFFSET CMD_PARM_LIST ;AN000;pointer for parm list + MOV WORD PTR SHARED_AREA_PTR,ES ;AN000; ES segment + ;; +KEYB_INSTALL_CHECK: ;; + MOV AX,0AD80H ;; KEYB install check + INT 2FH ;; + CMP AL,-1 ;; If flag is not 0FFh THEN + JE INSTALLED_KEYB ;; + MOV WORD PTR SHARED_AREA_PTR+2,OFFSET TSD ;; + JMP CON_INSTALL_CHECK ;; + ;;;;;;;;;; +INSTALLED_KEYB: ;; + MOV KEYB_INSTALLED,1 ;; Set KEYB_INSTALLED flag = YES + MOV WORD PTR SHARED_AREA_PTR,ES ;; Save segment of SHARED_DATA_AREA + MOV WORD PTR SHARED_AREA_PTR+2,DI ;; Save offset of SHARED_DATA_AREA + MOV AX,ES:[DI].KEYB_TYPE ;; + MOV HW_TYPE,AX ;; + MOV ES:[DI].TABLE_OK,0 ;; Do not allow processing + PUSH CS ;; while building table + POP ES ;; Reset ES until required + ;; +CON_INSTALL_CHECK: ;;;;;;; + MOV AX,0AD00H ;; CONSOLE install check + INT 2FH ;; + CMP AL,-1 ;; If flag is not 0FFh THEN + JE INSTALLED_CON ;; + JMP CALL_FIRST_STAGE ;; + ;; +INSTALLED_CON: ;; + MOV CON_INSTALLED,1 ;; Set CON_INSTALLED flag = YES + ;; +CALL_FIRST_STAGE: ;; + PUSH CS ;; + POP ES ;; + CALL PARSE_PARAMETERS ;; Validate parameter list + ;; +BEGIN_PARM_CHECK: ;; CHECK ALL RETURN CODES + MOV DL,[BP].RET_CODE_3 ;; + CMP DL,1 ;; Check for invalid syntax + JNE VALID1 ;; + JMP ERROR3 ;; + ;; +VALID1: ;; + MOV DL,[BP].RET_CODE_1 ;; Check for invalid language parm + CMP DL,1 ;; + JNE VALID2 ;; + JMP ERROR1 ;; + ;; +VALID2: ;; + MOV DL,[BP].RET_CODE_2 ;; Check for invalid code page parm + CMP DL,1 ;; + JNE VALID3 ;; + JMP ERROR2 ;; + ;; +VALID3: ;; + MOV DL,[BP].RET_CODE_1 ;; Check for query command + CMP DL,2 ;; + JE QUERY ;; +;******************************* CNS **;; + MOV DL,[BP].RET_CODE_1 ;AN000;k for query command + CMP DL,3 ;AN000;;; Get a status of the codepage + JE QUERY ;AN000;;; language, and possible ID code +;******************************* CNS **;; + JMP NOT_QUERY ;; + ;; IF QUERY is requested THEN +QUERY: ;; + MOV QUERY_CALL,DL ;; + MOV AX,KEYB_INSTALLED ;; If KEYB is installed THEN + CMP AX,0 ;; + JE QUERY_CONTINUE1 ;;;;;;;;;;;;;;;; + ;; + MOV DI,WORD PTR SHARED_AREA_PTR+2 ;; Get offset of + MOV ES,WORD PTR SHARED_AREA_PTR ;; shared area + MOV BX,WORD PTR ES:[DI].ACTIVE_LANGUAGE ;; Get active language + CMP BX,0 ;; WGR if no language.. ;AN000 + JE I_MESSAGE ;; WGR then id was specified ;AN000 + ;; + ;;;;;;;;;;;; +L_MESSAGE: ;; + MOV WORD PTR LANGUAGE_ASCII,BX ;AC000;;; Display Language + LEA SI,LANGUAGE_ASCII ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_ASCIIZ,SI ;AN000;;; WGR language code asciiz string ;AN000 + MOV AX,ACT_KEYB ;AC000;;; WGR display 'Current keyboard code' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_ASCIIZ ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_L_FINISHED ;; + ;;;;;;; +I_MESSAGE: ;; + MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID;AN000;;; WGR get id code. ;AN000 + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_ID ;AN000;;; WGR display 'Current ID: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV ID_DISPLAYED,1 ;AN000;;; WGR ID was displayed. ;AN000 + JMP KEYB_L_FINISHED ;AN000;;; WGR ;AN000 + ;;;;;;;;;;; +QUERY_CONTINUE1: ;; + MOV AX,INV_KEYB_Q ;AC000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR Else ;AN000 + XOR CX,CX ;AC000;;; WGR Display message that KEYB ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR has not been installed ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_CP_FINISHED ;AC000;;; + ;;;;;;;;;;; +KEYB_L_FINISHED: ;; + MOV BX,ES:[DI].INVOKED_CP_TABLE ;; Get invoked code page + ;; + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_KEYB_CP ;AC000;;; WGR display ' code page: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + CMP ID_DISPLAYED,1 ;AN000;;; WGR was id displayed? ;AN000 + JE KEYB_CP_FINISHED ;AN000;;; WGR yes..continue. ;AN000 + ;; + MOV BX,WORD PTR ES:[DI].INVOKED_KBD_ID;AN000;;; WGR get id code. ;AN000 + CMP BX,0 ;AN000;;; WGR no id given.. ;AN000 + JE KEYB_CP_FINISHED ;AN000;;; WGR ;AN000 + ;; + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,ACT_ID ;AC000;;; WGR display 'Current ID: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV AH,09H ;AC000;;; WGR need a CR_LF here. ;AN000 + MOV DX,OFFSET CR_LF ;AC000;;; WGR ;AN000 + INT 21H ;; WGR ;AN000 + ;;;;;;;;;;; +KEYB_CP_FINISHED: ;; + MOV AX,CON_INSTALLED ;; If CON has been installed THEN + CMP AX,0 ;; + JNE GET_ACTIVE_CP ;; + JMP CON_NOT_INSTALLED ;; + ;; +GET_ACTIVE_CP: ;; + MOV AX,0AD02H ;; Get active code page + INT 2FH ;; information from the console + JNC DISPLAY_ACTIVE_CP ;; + JMP ERROR5 ;; + ;; +DISPLAY_ACTIVE_CP: ;; + MOV NUMBER_HOLDER,BX ;AC000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AC000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AC000;;; WGR code page word ;AN000 + MOV AX,ACT_CON_CP ;AN000;;; WGR display 'Current CON code page: ' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + ;; + JMP KEYB_EXIT_NOT_RESIDENT ;; Exit from Proc + ;; +CON_NOT_INSTALLED: ;; ELSE + MOV AX,INV_CON_Q ;AC000;WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR Else ;AN000 + XOR CX,CX ;AN000;;; WGR Display message that CON does ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR not have active code page ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + JMP KEYB_EXIT_NOT_RESIDENT ;; Exit from Proc + ;; +NOT_QUERY: ;; IF not a query function requested + CALL BUILD_PATH ;; Determine location of KEYBOARD.SYS + ;; WGR ...and open file. ;AC000 + ;; + JNC VALID4 ;; If no error in opening file then + JMP ERROR4 ;; + ;; +VALID4: ;; + MOV KEYBSYS_FILE_HANDLE,AX ;; Save handle + MOV BP,OFFSET CMD_PARM_LIST ;; Set base pointer for structures + MOV BX,KEYBSYS_FILE_HANDLE ;; Retrieve the file handle + MOV DX,OFFSET FILE_BUFFER ;; Set address of buffer +;************************* CNS ********;; + cmp [BP].RET_CODE_4,ID_VALID ;AN000; ;; CNS is there an ID available + je ID_TYPED ;AN000; ;; if so go find out if it is + jmp GET_LANG ;AN000; ;; a 1st or 4th parm, if not must + ;AN000; ;; must be a language +ID_TYPED: ;AN000; + + call SCAN_ID ;AN000; ;; scan the table for the ID + cmp ID_FOUND,1 ;AN000; ;; if a legal ID check and see if + jne LOST_ID ;AN000; ;; it is a first or fourth parm + cmp FTH_PARMID,1 ;AN000; ;; if it is a fourth parm go + je GET_ID ;AN000; ;; check for language compatibility + jmp Language_found ;AN000; ;; otherwise it must be a first + ;; parm id value + +LOST_ID: ;AN000; ;; otherwise must be a bogus match + ;; between language and ID codes + ;; or the ID code does not exist + jmp ERR1ID ;AN000; ;; in the table +;************************* CNS ***********;; +GET_LANG: ;; Must be a language/or a 1st parm ID + ;;;;; + ;; + XOR DI,DI ;; Set number + LEA CX,[DI].KH_NUM_LANG+2 ;; bytes to read header + ;; + MOV AH,3FH ;; Read header of the Keyb Def file + INT 21H ;; + JNC VALID5 ;; If no error in opening file then + JMP ERROR4 ;; + ;;;; +VALID5: ;; + CLD ;; WGR all moves/scans forward ;AN000 + MOV CX,SIGNATURE_LENGTH ;; + MOV DI,OFFSET SIGNATURE ;; Verify matching + MOV SI,OFFSET FB.KH_SIGNATURE ;; signatures + REPE CMPSB ;; + JE LANGUAGE_SPECIFIED ;; + JMP ERROR4 ;;;; + ;; READ the language table +LANGUAGE_SPECIFIED: ;; + MOV AX,FB.KH_NUM_LANG ;; + MOV NUM_LANG,AX ;; Save the number of languages + MUL LANG_PTR_SIZE ;; Determine # of bytes to read + MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer + MOV CX,AX ;; + CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small + JBE READ_LANG_TAB ;; + JMP ERROR4 ;; + ;; +READ_LANG_TAB: ;; + MOV AH,3FH ;; Read language table from + INT 21H ;; Keyb Def file + JNC READ_VALID ;; If no error in opening file then + JMP ERROR4 ;; Else display ERROR message + ;; +READ_VALID: ;; + MOV CX,NUM_LANG ;; Number of valid codes + MOV DI,OFFSET FILE_BUFFER ;; Point to correct word in table + ;; +SCAN_LANG_TABLE: ;; FOR language parm + MOV AX,[BP].LANGUAGe_PARM ;; Get parameter + CMP [DI].KP_LANG_CODE,AX ;; Valid Code ?? + JE LANGUAGE_FOUND ;; If not found AND more entries THEN + ADD DI,LANG_PTR_SIZE ;; Check next entry + DEC CX ;; Decrement count of entries + JNE SCAN_LANG_TABLE ;; Else + JMP ERROR1 ;; Display error message + ;;;;;;;;;;;;;; +;**************************** CNS ****;;;; +GET_ID: ;AN000;;; CNS - Must be an ID value + mov cx,1 ;AN000;;; initialize ctr value for # of ids + ;; +SEARCH_ID: ;AN000;;; minimum per country +;.WHILE ;AN000;;; There is atleast 1 ID for each country + cmp cx,0 ;AN000;;; Check for any more IDs left to check + jne FINDID ;AN000;;; Country has more than one ID check + jmp END_IDCHK ;AN000;;; Country & ID has been found or value + ;; is zero +FINDID: ;AN000; + + push di ;AN000;;; save the current language entry ptr + push cx ;AN000;;; save the minimum # of ids before + ;; reading the table data from the disk +;**************************** CNS *****************;; +LANGUAGE_FOUND: ;; + MOV CX,WORD PTR [DI].KP_ENTRY_PTR+2 ;; Get offset of lang entry + MOV DX,WORD PTR [DI].KP_ENTRY_PTR ;; in the Keyb Def file + MOV WORD PTR KEYBCMD_LANG_ENTRY_PTR,DX ;; Save + MOV WORD PTR KEYBCMD_LANG_ENTRY_PTR+2,CX ;; offset + MOV AH,42H ;; Move file pointer to + MOV AL,0 ;;;;;;; location of language + INT 21H ;; entry + JNC LSEEK_VALID ;; + JMP ERROR4 ;; + ;; +LSEEK_VALID: ;; + MOV DI,AX ;; + MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ;; Set number + ;; bytes to read header + MOV DX,OFFSET FILE_BUFFER ;;;;;;;;; + MOV AH,3FH ;; Read language entry in + INT 21H ;; Keyb Def file + JNC VALID6a ;; If no error in file then + JMP ERROR4 ;;;;;;;;;; +;**************************** CNS ********************************************** + + +valid6a: + cmp FOURTH_PARM,1 ;AN000;;; Is the ID a 4th Parm + jne VALID6 ;AN000;;; if not get out of routine, otherwise + pop cx ;AN000;;;restore # of ids for the country + ; .IF ;AN000;;;Check to see if this is the first + ;AN000;;;time checking the primary ID + cmp cx,1 ;AN000;;;if there is just one ID check to make + jne CHK4PARM ;AN000;;;sure both flags are not set + ;AN000;;; this should not be necessary w/ new parser + cmp FTH_PARMID,1 ;AN000;;; is the ID flag for switch set + jne CHK1N4 ;AN000;;; is the flag set only for the 4th + cmp FOURTH_PARM,1 ;AN000;;; if set only for the switch proceed + jne CHK1N4 ;AN000;;; if not must be a positional + mov cl,fb.kl_num_id ;AN000;;; get the number of IDs available from the table + mov FTH_PARMID,0 ;AN000;;; turn switch flag off so the table + ;AN000;;; counter will not be reset + + ;;ids available for the +CHK1N4: ;AN000; ;;country + cmp ONE_PARMID,1 ;AN000; ;; this was to be done if + jne CHK4PARM ;AN000; ;; two the positional + cmp FOURTH_PARM,0 ;AN000; ;; and switch was specified + jne CHK4PARM ;AN000; ;; this should never happen + pop di ;AN000; ;; if the parser is intact + jmp error3 ;AN000; ;; report error & exit + +CHK4PARM: ;AN000; ;; check on the first ID + ; .IF ;AN000; ;;switch specified + ; call IDLANG_CHK ;AN000; ;;check the lang-id combo + ; .ELSE ;AN000; + ; xor cx,cx ;AN000; ;;clear to exit loop + ; .ENDIF ;AN000; + ; + cmp FOURTH_PARM,1 ;AN000; ;; ID was a switch + jne ABORT_LOOP ;AN000; ;; otherwise get out of routine + call IDLANG_CHK ;AN000; ;; check the ID + jmp ADVANCE_PTR ;AN000; ;; advance to the next position + +ABORT_LOOP: ;AN000; + xor cx,cx ;AN000; ;; end loop + +ADVANCE_PTR: ;AN000; + pop di ;AN000; ;;restore entry value + + dec cx ;AN000; ;;# of ids left to check + cmp cx,0 ;AN000; ;; if at 0 don't advance to next + je NO_ADVANCE ;AN000; ;; table position + cmp GOOD_MATCH,1 ;AN000; ;; check to see if ID matched language + je NO_ADVANCE ;AN000; ;; if equal do not advance + add di,LANG_PTR_SIZE ;AN000; ;;step to the next entry + ;;in the table + +NO_ADVANCE: ;AN000; + + jmp SEARCH_ID ;AN000; ;;for the country + +;.ENDWHILE ;;end of ID check for country + +END_IDCHK: ;AN000; + + cmp FOURTH_PARM,1 ;AN000; ;; see if id was found + jne VALID6 ;AN000; + cmp GOOD_MATCH,0 ;AN000; ;; none found + jne VALID6 ;AN000; ;; report error + mov [bp].ret_code_4,1 ;AN000; ;; incompatible lang code + mov al,[bp].ret_code_4 ;AN000; ;; id combo + jmp err2id ;AN000; + + ;; otherwise found it + ;; continue to build tbl +;**************************** CNS ********************************************** + ;; +VALID6: ;; + MOV AX,WORD PTR FB.KL_LOGIC_PTR ;; Save the offset of the state + MOV WORD PTR STATE_LOGIC_OFFSET,AX ;; logic section + MOV AX,WORD PTR FB.KL_LOGIC_PTR+2 ;; Save the offset of the state + MOV WORD PTR STATE_LOGIC_OFFSET+2,AX ;; logic section + ;; + MOV DL,[BP].RET_CODE_2 ;;;;;;;;;; IF code page was specified + CMP DL,2 ;; + JNE CODE_PAGE_SPECIFIED ;; + JMP DONE ;; + ;; +CODE_PAGE_SPECIFIED: ;; Then +;************************** CNS *********************************************** + xor ah,ah ;AN000; + MOV Al,FB.KL_NUM_CP ;AN000;;; +;************************** CNS *********************************************** + MOV NUM_CP,AX ;; Save the number of code pages + MUL CP_PTR_SIZE ;; Determine # of bytes to read + MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer + MOV CX,AX ;; + CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small + JBE VALID7 ;; + JMP ERROR4 ;; + ;; +VALID7: ;; + MOV AH,3FH ;; Read code page table from + INT 21H ;; Keyb Def file + JNC VALID8 ;; If no error in opening file then + JMP ERROR4 ;; + ;; +VALID8: ;; + MOV CX,NUM_CP ;; Number of valid codes + MOV DI,OFFSET FILE_BUFFER ;; Point to correct word in table + ;; +SCAN_CP_TABLE: ;; FOR code page parm + MOV AX,[BP].CODE_PAGE_PARM ;; Get parameter + CMP [DI].KC_CODE_PAGE,AX ;; Valid Code ?? + JE CODE_PAGE_FOUND ;; If not found AND more entries THEN + ADD DI,CP_PTR_SIZE ;; Check next entry + DEC CX ;; Decrement count of entries + JNE SCAN_CP_TABLE ;; Else + JMP ERROR2 ;; Display error message + ;;;;;;;;; +CODE_PAGE_FOUND: ;; + MOV AX,WORD PTR [DI].KC_ENTRY_PTR ;; + MOV WORD PTR CP_TAB_OFFSET,AX ;; + MOV AX,WORD PTR [DI].KC_ENTRY_PTR+2 ;; + MOV WORD PTR CP_TAB_OFFSET+2,AX ;; + ;;;;;; +DONE: ;; + MOV SI,OFFSET DESIG_CP_BUFFER ;; + ;; + MOV AX,CON_INSTALLED ;;;;; If CON is NOT installed THEN + CMP AX,0 ;; + JE SYSTEM_CP ;; + JMP GET_DESIG_CPS ;; + ;; +SYSTEM_CP: ;; + MOV CX,1 ;; + MOV NUM_DESIG_CP,CX ;; Set number of CPs = 1 + MOV [SI].NUM_DESIGNATES,CX ;; + ;; + MOV DL,[BP].RET_CODE_2 ;; Check if code page parm + CMP DL,0 ;; was specified + JNE SET_TO_SYSTEM_CP ;; + MOV DX,[BP].CODE_PAGE_PARM ;; + MOV [SI].DESIG_CP_ENTRY,DX ;; Load specified code page into + JMP READY_TO_BUILD_TABLE ;; designated code page list + ;; +SET_TO_SYSTEM_CP: ;; + CALL FIND_FIRST_CP ;; Call routine that sets the first + CMP AX,0 ;; table found in the Keyb Def file + JE SET_TO_SYSTEM_CP2 ;; to the system code page + JMP ERROR4 ;; + ;; +SET_TO_SYSTEM_CP2: ;; + MOV SYS_CODE_PAGE,BX ;; + MOV [BP].CODE_PAGE_PARM,BX ;; + MOV [SI].DESIG_CP_ENTRY,BX ;; Move sys CP into desig list + JMP READY_TO_BUILD_TABLE ;; + ;; +GET_DESIG_CPS: ;; ELSE + MOV AX,0AD03H ;; + PUSH CS ;; Make sure ES is set + POP ES ;; + LEA DI,DESIG_CP_BUFFER ;; + MOV CX,DESIG_CP_BUF_LEN ;; + INT 2FH ;; Get all designated code pages + JNC SET_DESIG_VARIABLES ;; from console + JMP ERROR5 ;; + ;; +SET_DESIG_VARIABLES: ;; + MOV CX,[SI].NUM_DESIGNATES ;; + ADD CX,[SI].NUM_HW_CPS ;; + MOV NUM_DESIG_CP,CX ;; Set number of Designated CPs + ;; +BUFFER_CREATED: ;; + MOV AX,0AD02H ;; + INT 2FH ;; Get invoked code page + ;; +SET_TO_CP_INVOKED: ;; + MOV DL,[BP].RET_CODE_2 ;; IF code page parm was specified + CMP DL,0 ;; + JNE SET_TO_INVOKED_CP ;; + MOV CX,NUM_DESIG_CP ;; + MOV DESIG_LIST,SI ;; + JMP TEST_IF_DESIGNATED ;; + ;; +SET_TO_INVOKED_CP: ;; + CMP AX,1 ;; IF a code page has been invoked + JNE SET_TO_INVOKED_CP3 ;; + CALL FIND_FIRST_CP ;; Call the routine that sets the + CMP AX,0 ;; first code page in the Keyb Def + JE SET_TO_INVOKED_CP2 ;; file to the system code page + JMP ERROR4 ;; + ;; +SET_TO_INVOKED_CP2: ;; + MOV [BP].CODE_PAGE_PARM,BX ;; + MOV SYS_CODE_PAGE,BX ;; + ;; + JMP TEST_IF_DESIGNATED ;; + ;; +SET_TO_INVOKED_CP3: ;; + MOV [BP].CODE_PAGE_PARM,BX ;; + ;; +TEST_IF_DESIGNATED: ;; + MOV DX,[BP].CODE_PAGE_PARM ;; + CMP [SI].DESIG_CP_ENTRY,DX ;; Is Code page specified in the list + JE CODE_PAGE_DESIGNATED ;; of designated code pages ? + ;; +NEXT_DESIG_CP: ;; + ADD SI,2 ;; Check next code page + DEC CX ;; If all designated code pages have + JNZ TEST_IF_DESIGNATED ;; been checked Then ERROR + JMP ERROR6 ;; + ;; +CODE_PAGE_DESIGNATED: ;; + CMP SYS_CODE_PAGE,0 ;; + JNE READY_TO_BUILD_TABLE ;; + CMP AX,1 ;; IF a code page has been invoked + JE READY_TO_BUILD_TABLE ;; + CMP [BP].CODE_PAGE_PARM,BX ;; IF Invoked CP <> Specified CP + JE READY_TO_BUILD_TABLE ;; Issue warning +;;*************************************************************************** + PUSH BX ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + MOV AX,WARNING_1 ;AN000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR ;AN000 + XOR CX,CX ;AN000;;; WGR ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP BX ;AN000;;; WGR ;AN000 +;;*************************************************************************** + ;; +READY_TO_BUILD_TABLE: ;; + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; Else if KEYB has not been installed + JNE BUILD_THE_TABLE ;; + ;; + CALL FIND_SYS_TYPE ;; Determine system type for INT 9 use + ;; + TEST SD.SYSTEM_FLAG,PC_JR ;; IS THIS ROM MULTILINGUAL? (JR.) AAD + JZ CONTINUE_INSTALL ; NO, LOAD THE NEW INT9 CODE + ; SEE IF MULTILINGUAL OPTION IS PRESENT + MOV AH,5 ; ADDRESS THE MULTILINGUAL SUPPORT + MOV AL,80H ; REQUEST CURRENT LANGUAGE BE IDENTIFIED + INT 16H ; CALL KEYBOARD TO IDENTIFY ITSELF + +;IF THE MULTILINGUAL OPTION IS NOT PRESENT, THE ROM DOES NOT RECOGNIZE THE +;OPTION 5 AND JUST RETURNS THE REGS INTACT. +;RESPONSE IN AL INDICATES THE CURRENT LANGUAGE: + + CMP AL,80H ; DID I GET BACK JUST WHAT I SENT? + JE CONTINUE_INSTALL ; SINCE RESPONSE WAS THE SAME MUST NOT BE + ; MULTILINGUAL, RELOCATE RESIDENT KBD ROUTINE + +;I AM GOING TO IGNORE WHAT LANGUAGE IS CURRENTLY SET. I WILL SET THE +;MULTILINGUAL KEYBOARD TO BECOME MY LANGUAGE. + + MOV AX,[BP].LANGUAGE_PARM ;; + XCHG AH,AL ;; + MOV DI,OFFSET JR_LANGUAGE_CODES ;; + MOV CX,JR_NUM_CODES ;; + PUSH CS ;; + POP ES ;; + REPNE SCASW ;; + JNE CONTINUE_INSTALL ;; + ;; + MOV AH,5 ; ADDRESS THE MULTILINGUAL KEYBOARD + MOV AL,JR_NUM_CODES ; SELECT MY LANGUAGE + SUB AL,CL ;; + INT 16H ; SET THE KEYBOARD ACCORDINGLY + INT 20H ; JOB DONE, ROM IS MULTILINGUAL + ; NO NEED TO STAY RESIDENT + ;; +;------ LOAD IN SPECIAL INT 9 HANDLER AND SPECIAL TABLES (IF NEEDED) + +CONTINUE_INSTALL: ;; + CALL INSTALL_INT_9 ;; Install INT 9 + ;; + CALL FIND_KEYB_TYPE ;; Determine keyboard type table use + ;; +BUILD_THE_TABLE: ;; + CALL TABLE_BUILD ;; Build the TEMP_SHARED_DATA_AREA + ;; +CHECK_ERRORS: ;; + XOR CX,CX ;; Take appropriate action considering + MOV CX,TB_RETURN_CODE ;; return codes from TABLE_BUILD + CMP CX,0 ;; + JE CHECK_FOR_INV_CP ;; If return code is not 0 + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; If KEYB has not been installed + JNE CHECK_ERROR_CONTINUE ;; + CALL REMOVE_INT_9 ;; remove installed vector + ;; +CHECK_ERROR_CONTINUE: ;; + CMP CX,1 ;; If return code = 1 + JNE CHECK_ERROR2 ;; + JMP ERROR1 ;; display error message + ;; +CHECK_ERROR2: ;; + CMP CX,2 ;; If return code = 2 + JNE CHECK_ERROR3 ;; + JMP ERROR2 ;; + ;; +CHECK_ERROR3: ;; + CMP CX,3 ;; If return code = 3 + JNE CHECK_ERROR4 ;; + JMP ERROR3 ;; display error message + ;; +CHECK_ERROR4: ;; + CMP CX,4 ;; If return code = 4 + JNE CHECK_ERROR5A ;; + JMP ERROR4 ;; display error message + ;; +CHECK_ERROR5A: ;; + CMP CX,5 ;; If return code = 5 + JNE CHECK_ERROR6A ;; + JMP ERROR5A ;; display error message + ;; +CHECK_ERROR6A: ;; + JMP ERROR6A ;; If return code not 0,1,2,3,4 then + ;; display error message +CHECK_FOR_INV_CP: ;; + MOV CX,CPN_INVALID ;; Check if any CPs were not loaded + CMP CX,0 ;; + JE TERMINATE ;; If some were invalid, issue + ;; warning message +;;*************************************************************************** + PUSH BX ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + MOV AX,NOT_SUPP ;AN000;;; WGR ;AN000 + MOV BX,STDOUT ;AN000;;; WGR WARNING ;AN000 + XOR CX,CX ;AN000;;; WGR MESSAGE ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR ;AN000 + XOR DL,DL ;AN000;;; WGR ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP BX ;AN000;;; WGR ;AN000 +;;*************************************************************************** + ;; +TERMINATE: ;; + MOV AH,3EH ;; Close the KEYBOARD.SYS file + MOV BX,KEYBSYS_FILE_HANDLE ;; if open + CMP BX,0 ;; + JE KEYB_EXIT ;; + INT 21H ;; + ;; + MOV AX,KEYB_INSTALLED ;; + CMP AX,0 ;; + JE KEYB_EXIT ;; + JMP KEYB_EXIT_NOT_RESIDENT ;; + ;; +KEYB_EXIT: ;; + TEST SD.KEYB_TYPE,G_KB ;; Q..FERRARI G?? + JZ NO_FERRARI_G ;; N..LEAVE NUMLK ALONE + TEST SD.SYSTEM_FLAG,PC_XT ;; Q..PC/XT? + JNZ NO_FERRARI_G ;; Y..LEAVE NUMLK ALONE + TEST SD.KEYB_TYPE,P_KB ;; Q..FERRARI P?? ***RPS + JNZ NO_FERRARI_G ;; Y..LEAVE NUMLK ALONE ***RPS +;***CNS + CMP SECURE_FL,1 ;AN002;; IF SECURITY FLAG SET + JNE NO_FERRARI_G ;AN002;; DON'T TURN ON NUM_LK + +;***CNS + CALL NUMLK_ON ;; N..TURN NUMLK ON + ;; +NO_FERRARI_G: ;; + TEST SD.SYSTEM_FLAG,EXT_16 ;; extended INT 16 support? + JZ SKIP_CTRL_COPY ;; + ;; Yes, load extened CTRL case table + MOV CX,L_CTRL_TAB ;; CX = LENGTH OF EXTENDED TABLE + MOV SI,OFFSET CS:RPL_K8 ;; POINT TO EXT. CTRL TABLES + MOV DI,OFFSET CS:K8 ;; POINT TO REGULAR CTRL TABLE + CLD ;; + REP MOVSB ;; OVERLAY WITH EXT. CTRL TABLE + ;; +SKIP_CTRL_COPY: ;; + CALL INSTALL_INT_9_NET ;; Let the network know about INT 9 + ;; (if the network is installed) + CALL INSTALL_INT_2F_48 ;; Install INT 2F and INT 48 (If PCjr) + ;; + MOV AX,0AD82H ;; Activate language + MOV BL,-1 ;; + INT 2FH ;; + ;; + MOV DX,ES:TSD.RESIDENT_END ;; Get resident end + MOV CL,4 ;; Convert into paragrahs + SHR DX,CL ;; + INC DX ;; + MOV AH,31H ;; Function call to terminate but stay + XOR AL,AL ;; resident + ;; + MOV DI,OFFSET SD_DEST_PTR ;; Initialize destination ptr + MOV SI,OFFSET SD_SOURCE_PTR ;; Initialize source ptr + XOR BP,BP ;; + LEA BX,[BP].ACTIVE_LANGUAGE ;; + ADD DI,BX ;; Adjust for portion not copied + ADD SI,BX ;; Adjust for portion not copied + ;; + MOV CX,SD_LENGTH ;; Set length of SHARED_DATA_AREA + SUB CX,BX ;; Adjust for portion not copied + ;; + JMP COPY_SD_AREA ;; Jump to proc that copies area in new + ;; part of memory +;***************************** CNS ********************************************* +ERR1ID: ;AN000; +;;*************************************************************************** + MOV AX,INV_I ;AN000;;; WGR invalid ID message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERR2ID: +;;*************************************************************************** + MOV AX,INV_COMBO ;AN000;;; WGR invalid combination message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +;***************************** CNS ********************************************* +ERROR1: +;;*************************************************************************** + MOV AX,INV_L ;AN000;;; WGR invalid language code ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR2: +;;*************************************************************************** + MOV AX,INV_CP ;AN000;;; WGR invalid code page message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR3: +;;*************************************************************************** + MOV AX,INV_S ;AN000;;; WGR invalid syntax message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 +;***CNS + + LEA DI,STRING_HOLDER ;AN003;Set PTR to look at the STRING + PUSH SI ;AN003;Save current SI index + PUSH AX + MOV AX,OLD_PTR ;AN003;Last locale of the end of a PARAM + SUB CUR_PTR,AX ;AN003;Get the length via the PSP + MOV SI,CUR_PTR + MOV CX,SI ;AN003;Save it in CX to move in the chars + POP AX ;AN003;Restore the PTR to the command line position + + MOV SI,OLD_PTR ;AN003;Last locale of the end of a PARAM + REP MOVSB ;AN003;Move in the chars until no more + + LEA DI,STRING_HOLDER ;AN003;Set PTR to look at the STRING + + + POP SI ;AN003;Restore the PTR to the command line position + + MOV CX,1 ;AN003;One replacement + MOV PTR_TO_COMLIN,DI ;AN003;;; WGR language code asciiz string ;AN000 + + + PUSH AX ;AN003; + MOV AX,DS ;AN003;;; WGR language code asciiz string ;AN000 + MOV SEG_OF_COMLIN,AX ;AN003; + POP AX ;AN003; + ;XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + + MOV AX,ERR_PART ;AN003; + LEA SI,SUBLIST_COMLIN ;AN003; +; MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR parse error message ;AN000 + MOV DH,PARSE_ERR_CLASS ;AN000;;; WGR parse error message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,INVALID_PARMS ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR4: +;;*************************************************************************** + MOV AX,INV_FN ;AN000;;; WGR bad or missing file message ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,BAD_KEYB_DEF_FILE ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR5: +;;*************************************************************************** + MOV AX,INV_CON_Q ;AC000;;; WGR CON code page not available. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,CONSOLE_ERROR ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR5A: +;;*************************************************************************** + MOV AX,MEMORY_OVERF ;AC000;;; WGR not enough resident memory. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,MEMORY_OVERFLOW ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR6: +;;*************************************************************************** + MOV AX,NOT_DESIG ;AC000;;; WGR code page not prepared. ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + XOR CX,CX ;AN000;;; WGR no substitutions ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR display message ;AN000 + MOV AL,CP_NOT_DESIGNATED ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + JMP KEYB_EXIT_NOT_RESIDENT ;; +ERROR6A: +;;*************************************************************************** + MOV NUMBER_HOLDER,BX ;AN000;;; WGR transfer number to temp loc. ;AN000 + LEA SI,NUMBER_HOLDER ;AN000;;; WGR sublist points to... ;AN000 + MOV PTR_TO_NUMBER,SI ;AN000;;; WGR code page word ;AN000 + MOV AX,NOT_VALID ;AN000;;; WGR display 'Code page requested....' ;AN000 + MOV BX,STDOUT ;AN000;;; WGR to standard out ;AN000 + MOV CX,1 ;AN000;;; WGR one replacement ;AN000 + MOV DH,UTILITY_MSG_CLASS ;AN000;;; WGR utility message ;AN000 + XOR DL,DL ;AN000;;; WGR no input ;AN000 + LEA SI,SUBLIST_NUMBER ;AN000;;; WGR ptr to sublist ;AN000 + CALL SYSDISPMSG ;AN000;;; WGR ;AN000 + MOV AL,KEYB_TABLE_NOT_LOAD ;AN000;;; | + MOV EXIT_RET_CODE,AL ;AN000;;; | +;;*************************************************************************** + ;; +KEYB_EXIT_NOT_RESIDENT: ;; + MOV AH,04CH ;; + MOV AL,QUERY_CALL ;; Check if this was a query call + CMP AL,0 ;; + JNE KEYB_EXIT3 ;; IF yes then EXIT + MOV AL,EXIT_RET_CODE ;; Check if return code was valid + CMP AL,0 ;; + JNE KEYB_EXIT3 ;; IF not then EXIT + ;; +COPY_INTO_SDA: ;; + MOV AX,0AD82H ;; Activate language + MOV BL,-1 ;; + INT 2FH ;; + ;; + MOV AH,04CH ;;;;;;;;;;; + MOV AL,EXIT_RET_CODE ;; + MOV DI,WORD PTR SHARED_AREA_PTR+2 ;; Initialize destination ptr + MOV ES,WORD PTR SHARED_AREA_PTR ;; + MOV DX,[BP].RESIDENT_END ;;;;;;;;;;; + MOV CL,4 ;; Calculate resident end in paragraphs + SHR DX,CL ;; + INC DX ;; + ;; + MOV SI,OFFSET SD_SOURCE_PTR ;; Initialize source ptr + XOR BP,BP ;; + LEA BX,[BP].ACTIVE_LANGUAGE ;; + ADD DI,BX ;; + ADD SI,BX ;; + MOV CX,SD_LENGTH ;; Set length of SHARED_DATA_AREA + SUB CX,BX ;; + ;; + JMP COPY_SD_AREA ;; Jump to proc that copies area in new + ;; +KEYB_EXIT3: ;;;;;;;;;;; + MOV AL,EXIT_RET_CODE ;; + MOV DI,WORD PTR SHARED_AREA_PTR+2 ;; Initialize destination ptr + MOV ES,WORD PTR SHARED_AREA_PTR ;; + MOV ES:[DI].TABLE_OK,1 ;; + INT 21H ;;;;;;;;;;; + ;; +KEYB_COMMAND ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Procedure: NUMLK_ON +;; +;; Description: +;; Turn Num Lock On. +;; +;; Input Registers: +;; N/A +;; +;; Output Registers: +;; N/A +;; +;; Logic: +;; Set Num Lock bit in BIOS KB_FLAG +;; Issue Int 16 to update lights +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +NUMLK_ON PROC ;; + ;; + PUSH ES ;; + PUSH AX ;; + ;; + MOV AX,DATA ;; + MOV ES,AX ;; + ;; + OR ES:KB_FLAG,NUM_STATE ;; Num Lock state active + MOV AH,1 ;; Issue keyboard query call to + INT 16H ;; have BIOS update the lights + ;; + POP AX ;; + POP ES ;; + RET ;; + ;; +NUMLK_ON ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: INSTALL_INT_9 +;; +;; Description: +;; Install our INT 9 driver. +;; +;; Input Registers: +;; DS - points to our data segment +;; BP - points to ES to find SHARED_DATA_AREA +;; +;; Output Registers: +;; DS - points to our data segment +;; AX, BX, DX, ES Trashed +;; +;; Logic: +;; Get existing vector +;; Install our vector +;; Return +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +REPLACE_INT_SEGMENT1 DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_9 PROC ;; + ;; + PUSH ES ;; + ;; + MOV AH,35H ;; Get int 9 vector + MOV AL,9 ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT1,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_9,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT1 ;; + MOV WORD PTR ES:SD.OLD_INT_9+2,AX ;; Segment + MOV AH,25H ;; + MOV AL,9 ;; + MOV DX,OFFSET KEYB_INT_9 ;; Let DOS know about our handler + INT 21H ;; + ;; + POP ES ;; + RET ;; + ;; +INSTALL_INT_9 ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: INSTALL_INT_9_NET +;; +;; Description: +;; +;; +;; Input Registers: +;; DS - points to our data segment +;; BP - points to ES to find SHARED_DATA_AREA +;; +;; Output Registers: +;; DS - points to our data segment +;; AX, BX, DX, ES Trashed +;; +;; Logic: +;; IF network is installed THEN +;; Let it know about our INT 9 +;; Return +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_9_NET PROC ;; + ;; + PUSH ES ;; + ;; + TEST SD.SYSTEM_FLAG,PC_NET ;; TEST FOR PC_NETWORK + JNZ NET_HAND_SHAKE ;; JUMP IF NETWORK INSTALLED + JMP INSTALL_9_DONE_NET ;; SKIP THE PC NETWORK HANDSHAKE + ;; +NET_HAND_SHAKE: ;; + ;; ES:BX TO CONTAIN INT 9 ADDR + MOV BX,OFFSET KEYB_INT_9 ;; + MOV AX,0B808H ;; FUNCTION FOR PC NETWORK TO INSTALL + ;; THIS ADDRESS FOR THEIR JUMP TABLE + INT 02FH ;; TELL PC_NET TO USE MY ADDR TO CHAIN TO + ;; +INSTALL_9_DONE_NET: ;; + POP ES ;; + RET ;; + ;; +INSTALL_INT_9_NET ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: INSTALL_INT_2F_48 +;; +;; Description: +;; Install our INT 2F, INT 48 drivers. +;; +;; Input Registers: +;; DS - points to our data segment +;; BP - points to ES to find SHARED_DATA_AREA +;; +;; Output Registers: +;; DS - points to our data segment +;; AX, BX, DX, ES Trashed +;; +;; Logic: +;; Get existing vectors +;; Install our vectors +;; Return +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +REPLACE_INT_SEGMENT2 DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INSTALL_INT_2F_48 PROC ;; + ;; + MOV AH,35H ;; Get int 2f vector + MOV AL,2FH ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT2,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_2F,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT2 ;; + MOV WORD PTR ES:SD.OLD_INT_2F+2,AX ;; Segment + MOV AH,25H ;; Set int 9 vector + MOV AL,2FH ;; + MOV DX,OFFSET KEYB_INT_2F ;; Vector in DS:DX + INT 21H ;; + ;; +ARE_WE_A_PCJR: ;; + ;; + MOV AX,SD.SYSTEM_FLAG ;; Test if we are a PCjr + CMP AX,PC_JR ;; + JNE INSTALL_DONE ;; IF yes then + MOV AH,35H ;; Get int 48 vector + MOV AL,48H ;; + INT 21H ;; Vector in ES:BX + MOV REPLACE_INT_SEGMENT2,ES ;; + PUSH CS ;; + POP ES ;; + MOV WORD PTR ES:SD.OLD_INT_48,BX ;; Offset + MOV AX,REPLACE_INT_SEGMENT2 ;; + MOV WORD PTR ES:SD.OLD_INT_48+2,AX ;; Segment + MOV AH,25H ;; Set int 48 vector + MOV AL,48H ;; + MOV DX,OFFSET KEYB_INT_48 ;; Vector in DS:DX + INT 21H ;; + ;; +INSTALL_DONE: ;; + + + RET ;; + ;; +INSTALL_INT_2F_48 ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: REMOVE_INT_9 +;; +;; Description: +;; Remove our INT 9 driver. +;; +;; Input Registers: +;; DS - points to our data segment +;; BP - points to ES to find SHARED_DATA_AREA +;; +;; Output Registers: +;; DS - points to our data segment +;; AX, BX, DX, ES Trashed +;; +;; Logic: +;; Get old vector +;; Install old vector +;; Return +;; +;; Notes: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +REMOVE_INT_9 PROC ;; + ;; + PUSH DS ;; + PUSH ES ;; + MOV ES,WORD PTR SHARED_AREA_PTR ;; + MOV AX,WORD PTR ES:SD.OLD_INT_9+2 ;; int 9 vector - segment + MOV DS,AX ;; + MOV DX,WORD PTR ES:SD.OLD_INT_9 ;; int 9 vector - offset + ;; + MOV AH,25H ;;;;;;;;; Set int 9 vector + MOV AL,9 ;; + INT 21H ;; + ;; +REMOVE_9_DONE: ;; + POP ES ;; + POP DS ;; + RET ;; + ;; +REMOVE_INT_9 ENDP ;; + ;; +;*********************** CNS **********;; +PURPOSE: ;; +INPUT: ;; +OUTPUT: ;; +;**************************************;; + ;AN000;;; + ;AN000;;; + ;AN000;;; + IDLANG_CHK PROC NEAR ;AN000;;; + ;AN000;;; + mov ax,fb.kl_id_code ;AN000;;;get the id code from the table + cmp ax,[bp].id_parm ;AN000;;;;;;;;;;;compare it to value taken + jne end_match ;AN000; ;from the switch-- if found + cmp ALPHA,0 ;AN000; ;a keyboard code was specified + je a_match ;AN000; ;no lang & a match + ;AN000; ; + mov ax,fb.kl_lang_code ;AN000; ;compare lang codes + cmp ax,[BP].LANGUAGE_PARM ;AN000; ;they are equal + je a_match ;AN000; ; + ;AN000; ; + jmp end_match ;AN000; ;if not found go check next + ;AN000; ;id for the same country + ;AN000; ; + a_match: ;AN000; ; + ; + mov good_match,1 ;AN000; ;report the ids match + ; + end_match: ;AN000; ; + ; + ret ;AN000; ; + ; + IDLANG_CHK ENDP ;AN000; ; +;*********************** CNS *******************; +;**********************************SCAN_ID***********************; +; New variables defined - NUM_ID,ADRSS_LANG,ID_PTR_SIZE,ID_FOUND ; +;****************************************************************; + ; + ; + SCAN_ID PROC NEAR ; + ; + xor di,di ;AN000;;clear di to set at the + ;AN000;;beginning of KEYBSYS STRUCTURE + ;;;;;;;;;; + ; + lea cx,[di].kh_num_ID+4 ;AN000;; set number of bytes to read header + ; + mov ah,3fh ;AN000;; + int 21h ;AN000;; + jnc VAL5ID ;AN000;; + jmp BAD_TAB ;AN000;;;bad table message + ; + VAL5ID: ;AN000; ; + ; + mov cx,SIGNATURE_LENGTH ;AN000; ; + mov di,offset SIGNATURE ;AN000; ; + mov si,offset FB.KH_SIGNATURE;AN000; ; + repe CMPSB ;AN000; ; + je ID_SPECIFIED ;AN000; ; + jmp BAD_TAB ;AN000; ; + ; + ; + ; + ID_SPECIFIED: ;AN000; ; + ; + mov ax,FB.KH_NUM_ID ;AN000; ;;;;;;;;;;;;;;; + mov NUM_ID,ax ;AN000; ;save # of IDs + mul ID_PTR_SIZE ;AN000; ;determine # of bytes to read + push ax ;AN000; ;save current # of bytes to read for + ;AN000; ;ID values only + mov ax,FB.KH_NUM_LANG ;AN000; ;add on lang data in table + mul LANG_PTR_SIZE ;AN000; ;data that comes before the ID data + mov cx,ax ;AN000; ;save that value for the size compare + mov PASS_LANG,cx ;AN000; ; + pop ax ;AN000; ;restore the info for # of ID bytes to read + add cx,ax ;AN000; ;add that value to get total in CX + mov TOTAL_SIZE,cx ;AN000; ;save the total size + cmp cx,FILE_BUFFER_SIZE ;AN000; ; + jbe READ_ID_TAB ;AN000; ; + jmp BAD_TAB ;AN000; ; + ; + ; + READ_ID_TAB: ;AN000; ; + ; + mov dx,offset FILE_BUFFER ;AN000; ; + mov ah,3fh ;;AN000;read language table from + int 21h ;;AN000;keyb defn file + jnc READ_IDVAL ;;AN000; + jmp BAD_TAB ;;AN000; + ; + READ_IDVAL: ;;AN000; + ;;AN000; + mov cx,NUM_ID ;;AN000; + mov di,offset FILE_BUFFER ;;AN000;;;;;;;;;; + add di,PASS_LANG ;AN000; ; + ; + SCAN_ID_TAB: ;AN000; ; + ; + mov ax,[bp].ID_PARM ;AN000; ; + cmp [di].KP_ID_CODE,ax ;AN000; ; + je ID_HERE ;AN000; ; + add di,ID_PTR_SIZE ;AN000; ; + dec cx ;AN000; ; + jne SCAN_ID_TAB ;AN000; ; + jmp FINALE ;AN000; ; + ; + BAD_TAB: ;AN000;; + ; + mov ERR4ID,1 ;AN000; ; + jmp FINALE ;AN000; ; + ; + ; + ; + ID_HERE: ;AN000; ; + ; + mov ID_FOUND,1 ;AN000;;reset ptr for ; + ;AN000;;current country ; + ; + + ; + FINALE: ;AN000; ; + ; + ret ;AN000; ; + ; + ; + SCAN_ID ENDP ;AN000; ; + ; +;*******************************SCAN_ID END******; +;; +;; Module: BUILD_PATH +;; +;; Description: +;; Build the complete filename of the Keyboard Definition File +;;*************************************WGR********************* +;; and open the file. +;;+++++++++++++++++++++++++++++++++++++WGR+++++++++++++++++++++ +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to our data segment +;; BP - offset of parmeter list +;; +;; Output Registers: +;;************************************WGR********************** +;; CARRY CLEAR +;; AX = HANDLE +;; CARRY SET (ERROR) +;; NONE +;;++++++++++++++++++++++++++++++++++++WGR++++++++++++++++++++++ +;; The complete filename will be available in FILE_NAME +;; +;; Logic: +;; +;; Determine whether path parameter was specified +;; IF length is zero THEN +;;****************************************WGR****************** +;; Try to open file in ACTIVE directory +;; IF failed THEN +;; Try to open file in ARGV(0) directory +;; IF failed THEN +;; Try to open file in ROOT directory (for DOS 3.3 compatibility) +;; ENDIF +;; ENDIF +;; ENDIF +;; ELSE +;; Copy path from PSP to FILE_NAME memory area +;; Try to open USER SPECIFIED file +;;++++++++++++++++++++++++++++++++++++++++WGR++++++++++++++++++ +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBOARD_SYS DB '\KEYBOARD.SYS',00 ;AN000;;; +KEYB_SYS_ACTIVE DB 'KEYBOARD.SYS',00 ;AN000;;; WGR ;AN000 +KEYB_SYS_LENG EQU 14 ;AN000;;; +KEYB_SYS_A_LENG EQU 13 ;AN000;;; WGR ;AN000 + ;; +FILE_NAME DB 128 DUP(0) ;AN000;;; + ;; +FILE_NOT_FOUND EQU 2 ;AN000;;; WGR ;AN000 +PATH_NOT_FOUND EQU 3 ;AN000;;; WGR ;AN000 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +BUILD_PATH PROC NEAR ;; + CLD ;AN000;;; WGR ;AN000 + MOV DI,OFFSET FILE_NAME ;; Get the offset of the filename + MOV CX,[BP].PATH_LENGTH ;; If path is specified then + CMP CX,0 ;; + JE APPEND_KEYB_SYS ;; + MOV SI,[BP].PATH_OFFSET ;; Get the offset of the path + ;; + REPE MOVSB ;AC000;;; Copy each char of the specified + MOV AX,3D00H ;AC000;;; WGR Open the KEYBOARD.SYS file ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + RET ;; path into the filename location + ;; +APPEND_KEYB_SYS: ;;;;; + MOV SI,OFFSET KEYB_SYS_ACTIVE ;AC000;;; WGR copy name for active directory ;AN000 + MOV CX,KEYB_SYS_A_LENG ;AC000;;;;;; WGR to file name variable. ;AN000 + REPE MOVSB ;AC000;;; WGR ;AN000 + MOV AX,3D00H ;AC000;;; WGR try to open it. ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .IF C ;AC000;;; WGR error in opening...was it.. ;AN000 + .IF OR ;AN000;;; WGR path or.. ;AN000 + .IF ;AN000;;; WGR file not found?... ;AN000 + CALL COPY_ARGV0 ;AC000;;; WGR yes....try ARGV(0) directory. ;AN000 + MOV AX,3D00H ;AC000;;; WGR ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .IF C ;AC000;;; WGR error in opening....was it.. ;AN000 + .IF OR ;AC000;;; WGR path or.. ;AN000 + .IF ;AC000;;; WGR file not found? ;AN000 + MOV SI,OFFSET KEYBOARD_SYS ;AC000;;; WGR try ROOT directory. ;AN000 + MOV DI,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + MOV CX,KEYB_SYS_LENG ;AC000;;; WGR ;AN000 + REPE MOVSB ;AC000;;; WGR ;AN000 + MOV AX,3D00H ;AC000;;; WGR ;AN000 + MOV DX,OFFSET FILE_NAME ;AC000;;; WGR ;AN000 + INT 21H ;AC000;;; WGR ;AN000 + .ELSE ;AC000;;; WGR if failed then carry set.. ;AN000 + STC ;AC000;;; WGR some other error..set flag ;AN000 + .ENDIF ;AC000;;; WGR ;AN000 + .ENDIF ;AC000;;; WGR ;AN000 + .ELSE ;AN000;;; WGR ;AN000 + STC ;AN000;;; WGR some other error..set flag. ;AN000 + .ENDIF ;AN000;;; WGR ;AN000 + .ENDIF ;AN000;;; WGR ;AN000 + ;; + RET ;AN000;;; + ;; +BUILD_PATH ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WGR +;; WGR +;; Module Name: WGR +;; COPY_ARGV0 WGR +;; WGR +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WGR + ;; WGR + ;; WGR +COPY_ARGV0 PROC ;; WGR ;AN000 + ;; WGR ;AN000 + PUSH ES ;AN000;;; WGR ;AN000 + PUSH DI ;AN000;;; WGR ;AN000 + PUSH SI ;AN000;;; WGR ;AN000 + PUSH CX ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 + MOV DI,2CH ;AN000;;; WGR Locate environment string ;AN000 + MOV ES,[DI] ;AN000;;; WGR ;AN000 + XOR SI,SI ;AN000;;; WGR ;AN000 + .WHILE < NE 0> ;AN000;;; WGR find ARGV(0) string. ;AN000 + INC SI ;AN000;;; WGR ;AN000 + .ENDWHILE ;AN000;;; WGR ;AN000 + ADD SI,4 ;AN000;;; WGR ;AN000 + LEA DI,FILE_NAME ;AN000;;; WGR move string to work area ;AN000 + .REPEAT ;AN000;;; WGR ;AN000 + MOV AL,ES:[SI] ;AN000;;; WGR ;AN000 + MOV [DI],AL ;AN000;;; WGR ;AN000 + INC SI ;AN000;;; WGR ;AN000 + INC DI ;AN000;;; WGR ;AN000 + .UNTIL < EQ 0> ;AN000;;; WGR ;AN000 + .REPEAT ;AN000;;; WGR ;AN000 + DEC DI ;AN000;;; WGR ;AN000 + .UNTIL < EQ '\'> OR ;AN000;;; WGR ;AN000 + .UNTIL < EQ 0> ;AN000;;; WGR scan back to.. ;AN000 + INC DI ;AN000;;; WGR first character after "\" ;AN000 + PUSH CS ;AN000;;; WGR ;AN000 + POP ES ;AN000;;; WGR ;AN000 + LEA SI,KEYB_SYS_ACTIVE ;AN000;;; WGR copy in "KEYBOARD.SYS" ;AN000 + MOV CX,KEYB_SYS_A_LENG ;AN000;;; WGR ;AN000 + REPE MOVSB ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 + POP CX ;AN000;;; WGR ;AN000 + POP SI ;AN000;;; WGR ;AN000 + POP DI ;AN000;;; WGR ;AN000 + POP ES ;AN000;;; WGR ;AN000 + RET ;AN000;;; WGR ;AN000 + ;AN000;;; WGR ;AN000 +COPY_ARGV0 ENDP ;AN000;;; + ;AN000;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: FIND_FIRST_CP +;; +;; Description: +;; Check the keyboard definition file for the first code page +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to our data segment +;; BP - offset of parmeter list +;; +;; Output Registers: +;; NONE +;; +;; Logic: +;; Open the file +;; IF error in opening file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Save handle +;; Set address of buffer +;; READ header of Keyboard definition file +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Check signature for correct file +;; IF file signature is correct THEN +;; READ language table +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Use table to verify language parm +;; Set pointer values +;; IF code page was specified +;; READ language entry +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; READ first code page +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; RET +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FIND_FIRST_CP PROC NEAR ;; + ;; + PUSH CX ;; Save everything that + PUSH DX ;; that will be changed + PUSH SI ;; + PUSH DI ;; + ;; + MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle + MOV DX,WORD PTR KEYBCMD_LANG_ENTRY_PTR ;; LSEEK file pointer + MOV CX,WORD PTR KEYBCMD_LANG_ENTRY_PTR+2 ;; to top of language entry + MOV AH,42H ;; + MOV AL,0 ;;;;;;;;;;;;;; If no problem with + INT 21H ;; Keyb Def file Then + JNC FIND_FIRST_BEGIN ;; + JMP FIND_FIRST_CP_ERROR4 ;; + ;;;;;;;;; +FIND_FIRST_BEGIN: ;; + MOV DI,AX ;; + MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ;; Set number + ;; bytes to read header + MOV DX,OFFSET FILE_BUFFER ;;;;;;;;; + MOV AH,3FH ;; Read language entry in + INT 21H ;; keyboard definition file + JNC FIND_FIRST_VALID4 ;; If no error in opening file then + JMP FIND_FIRST_CP_ERROR4 ;; + ;; +FIND_FIRST_VALID4: ;; +;************************** CNS *******;; + xor ah,ah ;AC000;;; + MOV Al,FB.KL_NUM_CP ;AC000;;; +;************************** CNS *******;; + MUL CP_PTR_SIZE ;; Determine # of bytes to read + MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer + MOV CX,AX ;; + CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small + JBE FIND_FIRST_VALID5 ;; + JMP FIND_FIRST_CP_ERROR4 ;; + ;; +FIND_FIRST_VALID5: ;; + MOV AH,3FH ;; Read code page table from + INT 21H ;; keyboard definition file + JNC FIND_FIRST_VALID6 ;; If no error in opening file then + JMP FIND_FIRST_CP_ERROR4 ;; + ;; +FIND_FIRST_VALID6: ;; + MOV CX,NUM_CP ;; Number of valid codes + MOV DI,OFFSET FILE_BUFFER ;; Point to correct word in table + ;; + MOV BX,[DI].KC_CODE_PAGE ;; Get parameter + XOR AX,AX ;; + JMP FIND_FIRST_RETURN ;; + ;; +FIND_FIRST_CP_ERROR4: ;; + MOV AX,4 ;; + ;; +FIND_FIRST_RETURN: ;; + POP DI ;; + POP SI ;; + POP DX ;; + POP CX ;; + ;; + RET ;; + ;; +FIND_FIRST_CP ENDP ;; + ;;;;;;;;;;;;; +.xlist ;; +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +MSG_SERVICES ;AN000;;; WGR ;AN000 +.list ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Temp Shared Data Area +;; Contains data which is required by +;; both the resident and transient KEYB code. +;; All keyboard tables are stored in this area +;; Structures for this area are in file KEYBSHAR.INC +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + ;; + db 'TEMP SHARED DATA' ;; +SD_SOURCE_PTR LABEL BYTE ;; +TEMP_SHARED_DATA SHARED_DATA_STR <> ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +CODE ENDS + +include msgdcl.inc + + END + \ No newline at end of file diff --git a/v4.0/src/CMD/KEYB/KEYBCMD.INC b/v4.0/src/CMD/KEYB/KEYBCMD.INC new file mode 100644 index 0000000..ac40fe5 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBCMD.INC @@ -0,0 +1,53 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBCMD.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; External declarations for procedures in file KEYCMD.ASM. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN KEYB_COMMAND :NEAR ;; + ;; + EXTRN KEYBSYS_FILE_HANDLE:WORD ;; + EXTRN CP_TAB_OFFSET:DWORD ;; + EXTRN STATE_LOGIC_OFFSET:DWORD ;; + EXTRN SYS_CODE_PAGE:WORD ;; + EXTRN KEYBCMD_LANG_ENTRY_PTR:DWORD ;; + EXTRN DESIG_CP_BUFFER:WORD ;; + EXTRN DESIG_CP_OFFSET:WORD ;; + EXTRN NUM_DESIG_CP:WORD ;; + EXTRN TB_RETURN_CODE:WORD ;; + EXTRN FILE_BUFFER_SIZE:ABS + EXTRN FILE_BUFFER:WORD ;; +;****************CNS**************************** + EXTRN ID_PTR_SIZE:WORD ;; +;****************CNS**************************** + EXTRN LANG_PTR_SIZE:WORD ;; + EXTRN CP_PTR_SIZE:WORD ;; +;****************CNS**************************** + EXTRN NUM_ID:WORD ;; +;****************CNS**************************** + EXTRN NUM_LANG:WORD ;; + EXTRN NUM_CP:WORD ;; + EXTRN SHARED_AREA_PTR:DWORD ;; + EXTRN SD_SOURCE_PTR:BYTE ;; + EXTRN TEMP_SHARED_DATA:BYTE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST + + \ No newline at end of file diff --git a/v4.0/src/CMD/KEYB/KEYBCPSD.ASM b/v4.0/src/CMD/KEYB/KEYBCPSD.ASM new file mode 100644 index 0000000..2cae9fe --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBCPSD.ASM @@ -0,0 +1,128 @@ + PAGE ,132 + TITLE DOS - KEYB Command - Copy Shared_Data_Area + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBCPSD.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Copies the SHARED_DATA_AREA into a part of memory that +;; can be left resident. All relative pointers must already +;; be recalculated to this new position. +;; THIS FILE MUST BE THE LAST OF THE RESIDENT FILES WHEN KEYB IS LINKED. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; +;; Include Files Required: +;; ----------------------- +;; INCLUDE KEYBSHAR.INC +;; INCLUDE KEYBCMD.INC +;; INCLUDE KEYBTBBL.INC +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE ????????.ASM: +;; procedure - description???????????????????????????????? +;; +;; Linkage Information: Refer to file KEYB.ASM +;; -------------------- +;; +;; Change History: +;; --------------- +;; PTMP3955 ;AN004;KEYB component to free environment and close handles 0 - 4 +;; 3/24/88 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + PUBLIC SD_DEST_PTR ;; + PUBLIC COPY_SD_AREA ;; + PUBLIC SHARED_DATA ;; + ;; + INCLUDE STRUC.INC + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBCMD.INC ;; + INCLUDE KEYBTBBL.INC ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: COPY_SD_AREA +;; +;; Description: +;; +;; Input Registers: +;; +;; Output Registers: +;; N/A +;; +;; Logic: +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +SD EQU SHARED_DATA ;; +TSD EQU TEMP_SHARED_DATA ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +COPY_SD_AREA PROC NEAR ;; + ;; + REP MOVS ES:BYTE PTR [DI],DS:[SI] ;; Copy SHARED_DATA_AREA to + + push ax ;AN004;save existing values + push es ;AN004;; + xor ax,ax ;AN004;clear out ax + mov ax,cs:[2ch] ;AN004;check offset for address containin environ. + cmp ax,0 ;AN004; + je NO_FREEDOM ;AN004; + mov es,ax ;AN004; + mov ax,4900H ;AN004;make the free allocate mem func + int 21h ;AN004;; + + +NO_FREEDOM: + pop es ;AN004;restore existing values + pop ax ;AN004;; + + push ax ;AN004; + push bx ;AN004; + + ;AN004; ;Terminate and stay resident + mov bx,4 ;AN004; ;1st close file handles + .REPEAT ;AN004; ;STDIN,STDOUT,STDERR + mov ah,3eh ;AN004; ; + int 21h ;AN004; ; + dec bx ;AN004; ; + .UNTIL ;AN004; ; + + pop bx ;AN004; + pop ax ;AN004; + ;AN004; new part of memory + MOV BYTE PTR ES:SD.TABLE_OK,1 ;; Activate processing flag + INT 21H ;; Exit + ;; + ;; +COPY_SD_AREA ENDP ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + db 'SHARED DATA' ;; +SD_DEST_PTR LABEL BYTE ;; + ;; +SHARED_DATA SHARED_DATA_STR <> ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CODE ENDS + END diff --git a/v4.0/src/CMD/KEYB/KEYBCPSD.INC b/v4.0/src/CMD/KEYB/KEYBCPSD.INC new file mode 100644 index 0000000..bb4f036 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBCPSD.INC @@ -0,0 +1,29 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBCPSD.INC +;; ---------- +;; +;; Description: +;; ------------ +;; External declarations and equates for procedures in file +;; KEYBCPSD.ASM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN COPY_SD_AREA:NEAR ;; + ;; + EXTRN SD_DEST_PTR :BYTE ;; + EXTRN SHARED_DATA :BYTE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBDCL.INC b/v4.0/src/CMD/KEYB/KEYBDCL.INC new file mode 100644 index 0000000..43b40a4 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBDCL.INC @@ -0,0 +1,50 @@ + +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBDCL.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; Common declarations for structures in procedures for KEYB.COM +;; +;; Change History: +;; --------------- +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +PARM_LIST STRUC ;; +;*******************CNS****************** +;*******************CNS****************** + RET_CODE_1 DB 0 ;; \ + RET_CODE_2 DB 0 ;; | + RET_CODE_3 DB 0 ;; | +;*******************CNS****************** + RET_CODE_4 DB 0 ;; |;AN000; +;*******************CNS****************** + LANGUAGE_PARM DW ? ;; } PARAMETER + CODE_PAGE_PARM DW ? ;; | LIST + PATH_OFFSET DW ? ;; | + PATH_LENGTH DW 0 ;; / +;*******************CNS****************** + ID_PARM DW ? ;AN000; +;*******************CNS****************** +PARM_LIST ENDS ;; + ;; +DESIG_CP_STRUC STRUC ;; + NUM_DESIGNATES DW ? ;; + NUM_FONTS DW ? ;; + NUM_HW_CPS DW ? ;; + DESIG_CP_ENTRY DW ? ;; +DESIG_CP_STRUC ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBEQU.INC b/v4.0/src/CMD/KEYB/KEYBEQU.INC new file mode 100644 index 0000000..f12f7f3 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBEQU.INC @@ -0,0 +1,31 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBEQU.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; Include file containing equates used by all KEYB modules. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +YES EQU 1 ;; +NO EQU 0 ;; + ;; +INT_2F_SUB_FUNC EQU 0ADH ;; our subfunction code for int 2f +SD EQU SHARED_DATA ;; +TSD EQU TEMP_SHARED_DATA ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST diff --git a/v4.0/src/CMD/KEYB/KEYBI2F.ASM b/v4.0/src/CMD/KEYB/KEYBI2F.ASM new file mode 100644 index 0000000..30dce7e --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI2F.ASM @@ -0,0 +1,225 @@ + + PAGE ,132 + TITLE DOS - KEYB Command - Interrupt 2F Handler + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI2F.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Contains Interrupt 2F handler. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; KEYB_INT_2F - Interupt 2F handler +;; +;; Include Files Required: +;; ----------------------- +;; INCLUDE KEYBEQU.INC +;; INCLUDE KEYBSHAR.INC +;; INCLUDE KEYBMAC.INC +;; INCLUDE KEYBCMD.INC +;; INCLUDE KEYBCPSD.INC +;; INCLUDE KEYBI9C.INC +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE ????????.ASM: +;; procedure - description???????????????????????????????? +;; +;; Linkage Information: Refer to file KEYB.ASM +;; -------------------- +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBMAC.INC ;; + INCLUDE KEYBCMD.INC ;; + INCLUDE KEYBCPSD.INC ;; + INCLUDE KEYBI9C.INC ;; + ;; + PUBLIC KEYB_INT_2F ;; + ;; + EXTRN ERROR_BEEP:NEAR ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: KEYB_INT_2F +;; +;; Description: +;; +;; Input Registers: +;; AH = 0ADH +;; AL = 80,81,82 +;; +;; Output Registers: +;; N/A +;; +;; Logic: +;; IF AH = 0ADh THEN (this call is for us) +;; Set carry flag to 0 +;; IF AL = 80 THEN +;; Get major and minor +;; Get SEG:OFFSET of SHARED_DATA_AREA +;; +;; IF AL = 81 THEN +;; Get FIRST_XLAT_PTR +;; FOR each table +;; IF code page requested = code page value at pointer THEN +;; Set INVOKED_CODE_PAGE +;; Set ACTIVE_XLAT_PTR +;; EXIT +;; ELSE +;; Get NEXT_SECT_PTR +;; NEXT table +;; IF no corresponding code page found THEN +;; Set carry flag +;; +;; IF AL = 82 THEN +;; IF BL = 00 THEN +;; Set COUNTRY_FLAG = 00 +;; ELSE IF BL = 0FFH THEN +;; Set COUNTRY_FLAG = 0FFH +;; ELSE +;; Set carry flag +;; IRET or JMP to another INT 2FH handler (if installed) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +CP_QUERY EQU 80H ;; +CP_INVOKE EQU 81H ;; +CP_LANGUAGE EQU 82H ;; + ;; +VERSION_MAJOR EQU 01H ;; +VERSION_MINOR EQU 00H ;; + ;; +CARRY_FLAG EQU 01H ;; +RESTORE_BP DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYB_INT_2F PROC ;; + ;; + PUSH DS ;; + PUSH BX ;; + PUSH CX ;; + PUSH SI ;; + ;; + PUSH CS ;; + POP DS ;; Set DATA SEGMENT register + ;; + CMP AH,INT_2F_SUB_FUNC ;; Q..is this call for us? + JE CHECK_REQUEST_CODE ;; Y..check request code + JMP INT_2F_DONE ;; N..get out + ;; +CHECK_REQUEST_CODE: ;; Y..check request code + MOV RESTORE_BP,BP ;;;;;;;;;;; + MOV BP,SP ;; Clear CARRY flag + AND WORD PTR [BP]+12,NOT CARRY_FLAG ;; + MOV BP,RESTORE_BP ;; + ;;;;;;;;;;; + ;; +INT_2F_CP_QUERY: ;; + CMP AL,CP_QUERY ;; Q..query CP? + JNE INT_2F_CP_INVOKE ;; N..next + MOV AX,-1 ;; Y..process query + MOV BH,VERSION_MAJOR ;; + MOV BL,VERSION_MINOR ;; + MOV DI,OFFSET SD ;; + PUSH CS ;; + POP ES ;; + JMP INT_2F_DONE ;; + ;; +INT_2F_CP_INVOKE: ;; + CMP AL,CP_INVOKE ;; Q..invoke CP? + JNE INT_2F_CP_LANGUAGE ;; N..next + ;; + MOV SI,SD.FIRST_XLAT_PTR ;; Get FIRST_XLAT_PTR + ;; +INT_2F_NEXT_SECTION: ;; + CMP SI,-1 ;; + JE INT_2F_ERROR_FLAG ;; + MOV CX,[SI].XS_CP_ID ;; Read in the code page value + CMP CX,BX ;; Is this the table to make active? + JNE INT_2F_CP_INVOKE_CONT1 ;; + MOV SD.ACTIVE_XLAT_PTR,SI ;; IF Yes, Set the ACTIVE_XLAT_PTR + MOV SD.INVOKED_CP_TABLE,BX ;; record new code page + JMP INT_2F_DONE ;; + ;; +INT_2F_CP_INVOKE_CONT1: ;; Else + MOV DI,[SI].XS_NEXT_SECT_PTR ;; IF No, + MOV SI,DI ;; Get NEXT_SECT_PTR + JMP INT_2F_NEXT_SECTION ;; NEXT_SECTION + ;; +INT_2F_ERROR_FLAG: ;; + MOV AX,1 ;; + MOV RESTORE_BP,BP ;;;;;; + MOV BP,SP ;; + OR WORD PTR [BP]+12,CARRY_FLAG ;; Set carry flag + MOV BP,RESTORE_BP ;; + ;;;;;; + JMP INT_2F_DONE ;; + ;; +INT_2F_CP_LANGUAGE: ;; + CMP AL,CP_LANGUAGE ;; Q..Set default language?? + JNE INT_2F_DONE ;; N..next + ;; + CMP BL,0 ;; Y..Check if Language is to be US437 + JNE INT_2F_CONTINUE1 ;; IF yes THEN, + MOV COUNTRY_FLAG,BL ;; Set COUNTRY_FLAG to 0 + JMP INT_2F_DONE ;; + ;; +INT_2F_CONTINUE1: ;; ELSE + CMP BL,-1 ;; Check if language is to be national + JNE INT_2F_LANG_ERROR_FLAG ;; IF yes THEN, + MOV COUNTRY_FLAG,BL ;; Set COUNTRY_FLAG to -1 (0FFH) + JMP INT_2F_DONE ;; + ;; +INT_2F_LANG_ERROR_FLAG: ;; ELSE + MOV RESTORE_BP,BP ;;;;;; Set CARRY flag + MOV BP,SP ;; + OR WORD PTR [BP]+12,CARRY_FLAG ;; + MOV BP,RESTORE_BP ;; + ;;;;;; + JMP INT_2F_DONE ;; + ;; +INT_2F_DONE: ;; + POP SI ;; + POP CX ;; + POP BX ;;;;;;; + POP DS ;; + CMP WORD PTR CS:SD.OLD_INT_2F,0 ;; Q..are we the last in the chain? + JNE INT_2F_JMP ;; N..call next in chain + CMP WORD PTR CS:SD.OLD_INT_2F+2,0 ;; Q..are we the last in the chain? + JNE INT_2F_JMP ;; N..call next in chain + ;;;;;;; + IRET ;; Y..return to caller + ;; +INT_2F_JMP: ;; + ;; + JMP CS:SD.OLD_INT_2F ;; + ;; +KEYB_INT_2F ENDP ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +CODE ENDS + END diff --git a/v4.0/src/CMD/KEYB/KEYBI2F.INC b/v4.0/src/CMD/KEYB/KEYBI2F.INC new file mode 100644 index 0000000..57067f4 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI2F.INC @@ -0,0 +1,26 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI2F.INC +;; ---------- +;; +;; Description: +;; ------------ +;; External declarations and equates for procedures in file +;; KEYBI2F.ASM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN KEYB_INT_2F:NEAR ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBI48.ASM b/v4.0/src/CMD/KEYB/KEYBI48.ASM new file mode 100644 index 0000000..05ed786 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI48.ASM @@ -0,0 +1,174 @@ + + + PAGE ,132 + TITLE DOS - KEYB Command - Interrupt 48H Handler + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI48.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Contains Interrupt 48H handler. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May ?? 1986 +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; +;; Include Files Required: +;; ----------------------- +;; INCLUDE KEYBEQU.INC +;; INCLUDE KEYBSHAR.INC +;; INCLUDE KEYBMAC.INC +;; INCLUDE KEYBCMD.INC +;; INCLUDE KEYBCPSD.INC +;; INCLUDE POSTEQU.inc +;; INCLUDE DSEG.inc +;; +;; External Procedure References: +;; ------------------------------ +;; FROM FILE ????????.ASM: +;; procedure - description???????????????????????????????? +;; +;; Linkage Information: Refer to file KEYB.ASM +;; -------------------- +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBMAC.INC ;; + INCLUDE KEYBCMD.INC ;; + INCLUDE KEYBCPSD.INC ;; + INCLUDE POSTEQU.inc ;; + INCLUDE DSEG.inc ;; + ;; + PUBLIC KEYB_INT_48 ;; + ;; + EXTRN ERROR_BEEP:NEAR ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + ASSUME CS:CODE,DS:CODE,ES:DATA;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: KEYB_INT_48 +;; +;; Description: +;; +;; Input Registers: +;; AL := Scan Code +;; +;; Output Registers: +;; N/A +;; +;; Logic: +;; IF scan code is not a break code THEN +;; IF CNTL was not entered THEN +;; IF ALT+SHIFT was pressed THEN +;; Set JB_KB_FLAG in SHARED_DATA_AREA +;; Clear ALT and SHIFT states in KB_FLAG +;; IRET or JMP to a chained INT48 routine +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYB_INT_48 PROC ;; + ;; + STI ;; allow NON-KB interrupts + PUSH BX ;; + PUSH BP ;; + PUSH CX ;; + PUSH DX ;; + PUSH DI ;; + PUSH SI ;; + PUSH DS ;; + PUSH ES ;; + PUSH AX ;; + ;; + MOV SD.JR_KB_FLAG,0 ;; Clear the flag + ;; + CMP AL,80H ;; Test for break code + JA INT48_EXIT ;; IF not a break code THEN + ;; + PUSH DS ;; Save segment registers + PUSH ES ;; + ;; + PUSH CS ;; Set up addressing + POP DS ;; for DATA SEGMENT (=CODE SEGMENT) + MOV BX,DATA ;; Set up addressing + MOV ES,BX ;; for EXTRA SEGMENT (=BIOS RAM AREA) + ;; + MOV AH,KB_FLAG ;; Get the flag status + AND AH,0FH ;; Clear all shift states + ;; + TEST AH,CTL_SHIFT ;; Test if CNTL was entered? + JNE INT48_PASS ;;;;;;;;;;;;;;;; IF yes THEN + ;; pass to ROM INT48 + AND AH,ALT_SHIFT+RIGHT_SHIFT+LEFT_SHIFT ;; Test if both ALT and + CMP AH,ALT_SHIFT ;; SHIFT were pressed + JBE INT48_PASS ;; IF no THEN + ;; pass to ROM INT48 + MOV BH,KB_FLAG ;;;;;;;;;;;; IF yes then + MOV SD.JR_KB_FLAG,BH ;; Setup JR flag + AND SD.JR_KB_FLAG,ALT_SHIFT+RIGHT_SHIFT+LEFT_SHIFT ;; Pass flags + ;; (ALT and + ;;;;;;;;;;;;;;;;;;;;;;;;;; EITHER/BOTH SHIFT) + XOR KB_FLAG,AH ;; Clear the ALT state and SHIFT state + ;; Reset the KB_FLAG to permit + ;; third shifts to go through +INT48_PASS: ;; + POP ES ;; + POP DS ;; + ;;;;;;; +INT48_EXIT: ;; + CMP WORD PTR CS:SD.OLD_INT_48,0 ;; Q..are we the last in the chain? + JNE INT_48_JMP ;; N..call next in chain + CMP WORD PTR CS:SD.OLD_INT_48+2,0 ;; Q..are we the last in the chain? + JNE INT_48_JMP ;; N..call next in chain + ;;;;;;; + POP AX ;; restore regs + POP ES ;; + POP DS ;; + POP SI ;; + POP DI ;; + POP DX ;; + POP CX ;; + POP BP ;; + POP BX ;; + ;; + IRET ;; Y..return to caller + ;; +INT_48_JMP: ;; + ;; + POP AX ;; restore regs + POP ES ;; + POP DS ;; + POP SI ;; + POP DI ;; + POP DX ;; + POP CX ;; + POP BP ;; + POP BX ;; + ;; + JMP CS:SD.OLD_INT_48 ;; + ;; +KEYB_INT_48 ENDP ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +CODE ENDS + END diff --git a/v4.0/src/CMD/KEYB/KEYBI48.INC b/v4.0/src/CMD/KEYB/KEYBI48.INC new file mode 100644 index 0000000..592223c --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI48.INC @@ -0,0 +1,27 @@ + +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI48.INC +;; ---------- +;; +;; Description: +;; ------------ +;; External declarations and equates for procedures in file +;; KEYBI48.ASM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN KEYB_INT_48:NEAR ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBI9.ASM b/v4.0/src/CMD/KEYB/KEYBI9.ASM new file mode 100644 index 0000000..d32b096 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI9.ASM @@ -0,0 +1,672 @@ + + PAGE ,132 + TITLE DOS KEYB Command - Interrupt 9 Non-US Support + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI9.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Converts scan codes to ASCII for non-US keyboards. +;; This orutine uses the tables loaded into the SHARED_DATA_AREA +;; from KEYBOARD.SYS by the KEYB_COMMAND module. +;; +;; Documentation Reference: +;; ------------------------ +;; PC DOS 3.3 Detailed Design Document - May 1986 +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; KEYB_STATE_PROCESSOR - Scan to ASCII translator. +;; +;; External Procedure References: +;; ------------------------------ +;; None. +;; +;; Linkage Information: Refer to file KEYB.ASM +;; -------------------- +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;**** + INCLUDE KEYBEQU.INC ;; + INCLUDE DSEG.inc ;; System data segments + INCLUDE POSTEQU.inc ;; System equates + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBI2F.INC ;; + INCLUDE KEYBI9C.INC ;; + INCLUDE KEYBCPSD.INC ;; + INCLUDE KEYBCMD.INC ;; + ;; + PUBLIC KEYB_STATE_PROCESSOR ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Procedure: KEYB_STATE_PROCESSOR +;; +;; Description: +;; Convert scan to ASCII using the tables loaded into the +;; SHARED_DATA_AREA. Conversion is directed by the STATE LOGIC +;; commands contained in the SHARED_DATA_AREA. This routine +;; interprets those commands. +;; +;; Input Registers: +;; N/A +;; +;; Output Registers: +;; N/A +;; +;; Logic: +;; Enable interrupts +;; Save registers +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +BREAK_CODE EQU 80H ;; + ;; +HOT_KEY_ACTIVE DB 0 ;; 1 if hot key is active + ;; + ;; + ;; These are copies of the BIOS FLAGS +FLAGS_TO_TEST LABEL BYTE ;; KB_FLAG, KB_FLAG_1,2,3 +KB_SHADOW_FLAGS DB NUM_BIOS_FLAGS DUP(0) ;; +EXT_KB_FLAG DB 0 ;; Extended KB Flag for shift states +NLS_FLAG_1 DB 0 ;; NLS Flags for dead key etc +NLS_FLAG_2 DB 0 ;; . + ;; +SAVED_NLS_FLAGS DB 0,0 ;; Saved copy of the NLS flags + ;; +OPTION_BYTE DB 0 ;; Set by OPTION command + ;; +KB_FLAG_PTRS DW OFFSET KB_FLAG ;; These are pointers to the BIOS flags + DW OFFSET KB_FLAG_1 ;; we must test + DW OFFSET KB_FLAG_2 ;; + DW OFFSET KB_FLAG_3 ;; + ;; +XLAT_TAB_PTR DW 0 ;; pointer to xlat tables for cur state + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +NEST_LEVEL DB 0 ;; +PROCESS_LEVEL DB 0 ;; +TAKE_ELSE DB 0 ;; +BUSY_FLAG DB 0 ;; Flag to prevent re-entry + ;; +CMD_JUMP_TABLE LABEL WORD ;; + DW OFFSET IFF_PROC ;; CODE 0 + DW OFFSET ANDF_PROC ;; 1 + DW OFFSET ELSEF_PROC ;; 2 + DW OFFSET ENDIFF_PROC ;; 3 + DW OFFSET XLATT_PROC ;; 4 + DW OFFSET OPTION_PROC ;; 5 + DW OFFSET SET_FLAG_PROC ;; 6 + DW OFFSET PUT_ERROR_PROC ;; 7 + DW OFFSET IFKBD_PROC ;; 8 + DW OFFSET GOTO_PROC ;; 9 + DW OFFSET BEEP_PROC ;; A + DW OFFSET RESET_NLS_PROC ;; B + DW OFFSET UNKNOWN_COMMAND ;; C + DW OFFSET UNKNOWN_COMMAND ;; D + DW OFFSET UNKNOWN_COMMAND ;; E + DW OFFSET UNKNOWN_COMMAND ;; F + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYB_STATE_PROCESSOR PROC NEAR ;; + ;; + TEST CS:SD.TABLE_OK,1 ;; + JNZ WE_HAVE_A_TABLE ;; + CLC ;; BACK TO US INT 9 + RET ;; + + EVEN + +WE_HAVE_A_TABLE: ;; + + PUSH DS ;; save DS + PUSH ES ;; save ES + PUSH AX ;; save scan code for caller + PUSH BX ;; save shift states for caller + + PUSH CS ;; + POP DS ;; DS = our seg + MOV BX,DATA ;; + MOV ES,BX ;; addressability to BIOS data + ;; + ;; + CMP COUNTRY_FLAG,0FFH ;; Q..country mode? + JE INIT_STATE_PROCESSING ;; Y..continue + JMP GOTO_BIOS ;; N..exit + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; -------STATE SECTION PROCESSING------- +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +INIT_STATE_PROCESSING: ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Set NLS shift flags EITHER_SHIFT, EITHER_ALT, EITHER_CTRL +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + ;; Q..in shift state? + TEST ES:KB_FLAG,RIGHT_SHIFT+LEFT_SHIFT + JNZ IN_SHIFT_STATE ;; Y..go set bit + AND EXT_KB_FLAG,NOT EITHER_SHIFT ;; N..clear bit + JMP SHORT TEST_CTL ;; +IN_SHIFT_STATE: ;; + OR EXT_KB_FLAG,EITHER_SHIFT ;; +TEST_CTL: ;; + TEST ES:KB_FLAG,CTL_SHIFT ;; Q..in control state? + JNZ IN_CTL_STATE ;; Y..go set bit + TEST ES:KB_FLAG_3,R_CTL_SHIFT ;; Q..how bout the right ctl? + JNZ IN_CTL_STATE ;; Y..go set the bit + AND EXT_KB_FLAG,NOT EITHER_CTL ;; N..clear the bit + JMP SHORT TEST_ALT ;; +IN_CTL_STATE: ;; + OR EXT_KB_FLAG,EITHER_CTL ;; +TEST_ALT: ;; + TEST ES:KB_FLAG,ALT_SHIFT ;; Q..in alt state? + JNZ IN_ALT_STATE ;; Y..go set bit + TEST ES:KB_FLAG_3,R_ALT_SHIFT ;; Q..how bout the right alt? + JNZ IN_ALT_STATE ;; Y..go set the bit + AND EXT_KB_FLAG,NOT EITHER_ALT ;; N..clear the bit + JMP SHORT COPY_FLAGS ;; +IN_ALT_STATE: ;; + OR EXT_KB_FLAG,EITHER_ALT ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Copy BIOS KB flags from BIOS data seg into the +;; FLAGS_TO_TEST structure. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +COPY_FLAGS: ;; + MOV CX,NUM_BIOS_FLAGS ;; + MOV SI,0 ;; pointers to the BIOS flags + MOV DI,0 ;; create shadow copies +MOVE_NEXT_FLAG: ;; + MOV BX,KB_FLAG_PTRS[SI] ;; pointer to next flag + MOV AL,ES:[BX] ;; flag in AL + MOV KB_SHADOW_FLAGS[DI],AL ;; save it in the shadow table + INC DI ;; + INC SI ;; + INC SI ;; + LOOP MOVE_NEXT_FLAG ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Interpret State Logic Commands +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +PROCESS_STATES: ;; + MOV OPTION_BYTE,0 ;; clear options + MOV SI,SD.LOGIC_PTR ;; + LEA SI,[SI].SL_LOGIC_CMDS ;; +NEXT_COMMAND: ;; + MOV BL,[SI] ;; command byte in BL + SHR BL,1 ;; + SHR BL,1 ;; + SHR BL,1 ;; + SHR BL,1 ;; ISOLATE COMMAND CODE + SHL BL,1 ;; command code * 2 + JMP CMD_JUMP_TABLE[BX] ;; go process command +UNKNOWN_COMMAND: ;; + JMP FATAL_ERROR ;; bad news + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IFKBD_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE IFKBD_DONE ;; N..don't process + + MOV AX,[SI+1] ;; Keyboard Type Flag + ;; + TEST SD.KEYB_TYPE,AX ;; Q..are we the right system? + JNZ IFKBD_TEST_OK ;; Y.. +IFKBD_TEST_FAILED: ;; + MOV TAKE_ELSE,YES ;; test failed - take ELSE + JMP SHORT IFKBD_DONE ;; +IFKBD_TEST_OK: ;; + INC PROCESS_LEVEL ;; process commands within IF + MOV TAKE_ELSE,NO ;; +IFKBD_DONE: ;; + INC NEST_LEVEL ;; IFKBD increments nest level + INC SI ;; bump past IFKBD + INC SI ;; + INC SI ;; + JMP NEXT_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +PUT_ERROR_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE PUT_ERROR_DONE ;; N..don't process + MOV DI,SD.ACTIVE_XLAT_PTR ;; pointer to active Xlat Section + MOV AL,[SI+1] ;; state id in AL + CALL PUT_ERROR ;; check active section + JC PUT_ERROR_DONE ;; carry set if translation found + MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section + MOV AL,[SI+1] ;; state id for XLATT in AL + CALL PUT_ERROR ;; + ;; +PUT_ERROR_DONE: ;; + INC SI ;; + INC SI ;; + JMP NEXT_COMMAND ;; + ;; +PUT_ERROR PROC ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Search for a state whose ID matches the ID +;; on the PUT_ERROR command +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + CLC ;; + LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section +PE_NEXT_STATE: ;; + CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? + JE PE_EXIT ;; Y..exit + CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? + JE PE_STATE_MATCH ;; + ADD DI,[DI].XS_STATE_LEN ;; N..check next state + JMP SHORT PE_NEXT_STATE ;; + ;; +PE_STATE_MATCH: ;; + MOV AX,[DI].XS_ERROR_CHAR ;; get error char in AX + CALL BUFFER_FILL ;; + STC ;; indicate that we found the state +PE_EXIT: ;; + RET ;; + ;; +PUT_ERROR ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +GOTO_BIOS: ;; + CLC ;; clear carry flag indicating + POP BX ;; we should continue INT 9 + POP AX ;; processing + POP ES ;; + POP DS ;; + RET ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +IFF_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE IFF_DONE ;; N..don't process IFF + MOV BL,[SI] ;; command byte + AND BL,FLAG_ID_BITS ;; isolate flag id + XOR BH,BH ;; + MOV AL,FLAGS_TO_TEST[BX] ;; flag in AL + TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT test? + JNZ ITS_A_NOT ;; + TEST AL,[SI]+1 ;; Y..check for bit set + JNZ IFF_MATCH ;; + JZ IFF_NO_MATCH ;; +ITS_A_NOT: ;; + TEST AL,[SI]+1 ;; Y..check for bit clear + JZ IFF_MATCH ;; +IFF_NO_MATCH: ;; + MOV TAKE_ELSE,YES ;; flag test failed - take ELSE + JMP SHORT IFF_DONE ;; +IFF_MATCH: ;; + INC PROCESS_LEVEL ;; process commands within IF + MOV TAKE_ELSE,NO ;; + ;; +IFF_DONE: ;; + INC NEST_LEVEL ;; IFF increments nest level + INC SI ;; bump past IFF + INC SI ;; + JMP NEXT_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +ELSEF_PROC: ;; + MOV AL,PROCESS_LEVEL ;; + CMP AL,NEST_LEVEL ;; Q..nest level = process level? + JNE CHECK_TAKE_ELSEF ;; N..check for take_else + DEC PROCESS_LEVEL ;; Y..we just finished the "IF" block + JMP ELSEF_DONE ;; so we are finished with IFF/ELSEF +CHECK_TAKE_ELSEF: ;; + CMP TAKE_ELSE,YES ;; Q..are we scanning for ELSE? + JNE ELSEF_DONE ;; N..done + DEC NEST_LEVEL ;; ELSEF itself is back a level + CMP AL,NEST_LEVEL ;; Q..nest level = process level? + JNE NOT_THIS_ELSEF ;; N..this else is not the one + INC PROCESS_LEVEL ;; Y..process ELSEF block + MOV TAKE_ELSE,NO ;; reset +NOT_THIS_ELSEF: ;; + INC NEST_LEVEL ;; stuff within the ELSEF is up a level + ;; +ELSEF_DONE: ;; + INC SI ;; bump past ELSEF + JMP NEXT_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ENDIFF_PROC: ;; + MOV AL,PROCESS_LEVEL ;; + CMP AL,NEST_LEVEL ;; Q..nest level = process level? + JNE ENDIFF_DONE ;; N..don't adjust process level + DEC PROCESS_LEVEL ;; Y..we just finished the IF/ELSE +ENDIFF_DONE: ;; + DEC NEST_LEVEL ;; ENDIF decrements nest level + INC SI ;; bump past ENDIF + JMP NEXT_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Translations may be in the Common or Specific +;; Sections. Search the Specific section first +;; then the common section. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +XLATT_PROC: ;; + MOV AL,PROCESS_LEVEL ;; + CMP AL,NEST_LEVEL ;; Q..nest level = process level? + JNE XLATT_DONE ;; N..next command + MOV DI,SD.ACTIVE_XLAT_PTR ;; pointer to active Xlat Section + MOV AL,[SI+1] ;; state id for XLATT in AL + CALL TRANSLATE ;; check active section + JC XLATT_FOUND ;; carry set if translation found + MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section + MOV AL,[SI+1] ;; state id for XLATT in AL + CALL TRANSLATE ;; + JNC XLATT_DONE ;; +XLATT_FOUND: ;; + OR EXT_KB_FLAG,SCAN_MATCH ;; set flag indicating scan matched + TEST OPTION_BYTE,EXIT_IF_FOUND ;; Q..exit + JZ XLATT_DONE ;; + JMP EXIT ;; Y..BYE + ;; +XLATT_DONE: ;; + INC SI ;; + INC SI ;; + JMP NEXT_COMMAND ;; + ;; +TRANSLATE PROC ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Search for a state whose ID matches the ID +;; on the XLATT command +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + CLC ;; + LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section +TP_NEXT_STATE: ;; + CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? + JE TP_EXIT ;; Y..exit + CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? + JE TP_STATE_MATCH ;; + ADD DI,[DI].XS_STATE_LEN ;; N..check next state + JMP SHORT TP_NEXT_STATE ;; + ;; +TP_STATE_MATCH: ;; + AND EXT_KB_FLAG,NOT SCAN_MATCH ;; reset flag before search + PUSH SI ;; save pointer to next command + LEA SI,[DI].XS_FIRST_TAB ;; point to first xlat table + MOV XLAT_TAB_PTR,SI ;; start of XLAT tables + MOV AL,SCAN_CODE ;; restore incoming scan code + JMP SHORT NEXT_XLAT_TAB ;; +TP_DONE: ;; return here from XLAT + POP SI ;; +TP_EXIT: ;; + RET ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check xlate tables for matching scan code +;; The xlate table can be in one of two forms: +;; Type 1 = Table contains buffer entries only. +;; Scan code is used as an index into xlat table +;; Type 2 = Table contains pairs of SCAN/BUFFER_ENTRY. +;; Table must be searched for matching scan. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +NEXT_XLAT_TAB: ;; + MOV SI,XLAT_TAB_PTR ;; pointer to xlat tables + CMP [SI].XLAT_TAB_SIZE,0 ;; Q..any more xlat tables? + JNE PROCESS_XLAT_TAB ;; Y..check um + JMP TP_DONE ;; N..done +PROCESS_XLAT_TAB: ;; + MOV DL,[SI].XLAT_OPTIONS ;; save translate options IN DL + MOV BX,[SI].XLAT_TAB_SIZE ;; Y..calc pointer to next xlat tab + ADD BX,SI ;; + MOV XLAT_TAB_PTR,BX ;; pointer to next xlat tab + TEST DL,TYPE_2_TAB ;; Q..is this a type 2 table? + JZ TYPE_1_LOOKUP ;; N..go do table lookup +TYPE_2_SEARCH: ;; Y..search table + XOR CH,CH ;; + MOV CL,[SI].XLAT_NUM ;; number of xlat entries + MOV BX,DEFAULT_TAB_2_ENT_SZ ;; default entry size + TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..are buffer entries ASCII only? + JZ NEXT_TAB_2_ENTRY ;; N..continue + MOV BX,ASC_ONLY_TAB_2_ENT_SZ ;; Y..set size in BX +NEXT_TAB_2_ENTRY: ;; entry size is in BX + CMP CX,0 ;; Q..last entry? + JE NEXT_XLAT_TAB ;; y..go to next table + CMP AL,[SI].XLAT_SCAN ;; Q..scan match? + JE FOUND_TAB_2_ENTRY ;; Y..go create buffer entry + ADD SI,BX ;; point to next entry + LOOP NEXT_TAB_2_ENTRY ;; + JMP SHORT NEXT_XLAT_TAB ;; +FOUND_TAB_2_ENTRY: ;; Q..set scan code to 0? + MOV AH,AL ;; default scan code in AH + MOV AL,[SI].XLAT_2_BUF_ENTRY ;; ASCII code from table in AL + TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..are buffer entries ASCII only? + JNZ BUFFER_ENTRY_READY ;; Y..buffer entry is ready + MOV AH,[SI].XLAT_2_BUF_ENTRY+1 ;; N..scan code from table as well + JMP SHORT BUFFER_ENTRY_READY ;; go put entry in buffer + ;; +TYPE_1_LOOKUP: ;; + CMP AL,[SI].XLAT_SCAN_LO ;; Q..is scan in range of this table? + JB NEXT_XLAT_TAB ;; N..next table + CMP AL,[SI].XLAT_SCAN_HI ;; Q..is scan in range of this table? + JA NEXT_XLAT_TAB ;; N..next table + SUB AL,[SI].XLAT_SCAN_LO ;; convert scan code to xlat index + TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..ASCII only in xlat ? + JZ TWO_BYTE_LOOKUP ;; N..go do 2-byte lookup + LEA BX,[SI].XLAT_1_BUF_ENTRY ;; Y..do 1-byte lookup + XLAT [SI].XLAT_1_BUF_ENTRY ;; ASCII code in AL + MOV AH,SCAN_CODE ;; SCAN in AH + JMP SHORT BUFFER_ENTRY_READY ;; go put entry in buffer +TWO_BYTE_LOOKUP: ;; + MOV BL,2 ;; multiply scan index + MUL BL ;; by two + MOV BX,AX ;; real index in BX + MOV AX,WORD PTR [SI].XLAT_1_BUF_ENTRY[BX] ;; get 2-byte buffer entry + ;; AL=ASCII AH=SCAN +BUFFER_ENTRY_READY: ;; + TEST DL,ZERO_SCAN ;; Q..set scan part to zero? + JZ NO_ZERO_SCAN ;; N.. + XOR AH,AH ;; scan = 0 +NO_ZERO_SCAN: ;; + CALL BUFFER_FILL ;; go put entry in buffer + STC ;; indicate translation found + JMP TP_DONE ;; + ;; +TRANSLATE ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +OPTION_PROC: ;; + MOV AL,PROCESS_LEVEL ;; + CMP AL,NEST_LEVEL ;; Q..nest level = process level? + JNE DONE_OPTION ;; N..done + MOV AL,[SI]+1 ;; mask in AL + TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT? + JNZ AND_MASK ;; + OR OPTION_BYTE,AL ;; N..OR in the mask bits + JMP DONE_OPTION ;; +AND_MASK: ;; + NOT AL ;; + AND OPTION_BYTE,AL ;; Y..AND out the mask bits +DONE_OPTION: ;; + INC SI ;; + INC SI ;; + JMP NEXT_COMMAND ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +RESET_NLS_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE RN_DONE ;; N..don't process + MOV NLS_FLAG_1,0 ;; + MOV NLS_FLAG_2,0 ;; +RN_DONE: ;; + INC SI ;; + JMP NEXT_COMMAND ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +BEEP_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE BP_DONE ;; N..don't process + MOV BEEP_PENDING,YES ;; set beep pending flag. the beep + ;; will be done just before iret +BP_DONE: ;; + INC SI ;; + JMP NEXT_COMMAND ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GOTO_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE GOTO_DONE ;; N..don't process + MOV BL,[SI] ;; command byte in BL + AND BL,NOT COMMAND_BITS ;; remove command code + OR BL,BL ;; Q..goto label? + JZ GOTO_LABEL ;; Y..go jump + CMP BL,EXIT_INT_9_FLAG ;; Q..SPECIAL - Exit Int 9? + JNE NOT_EXIT_INT_9 ;; N.. + JMP EXIT ;; Y..bye bye +NOT_EXIT_INT_9: ;; + CMP BL,EXIT_STATE_LOGIC_FLAG ;; Q..SPECIAL - Exit State Logic? + JNE NOT_EXIT_S_L ;; N.. + JMP GOTO_BIOS ;; Y..goto bios +NOT_EXIT_S_L: ;; + JMP FATAL_ERROR ;; garbage in that command +GOTO_LABEL: ;; + ADD SI,[SI]+1 ;; bump by relative offset + MOV PROCESS_LEVEL,0 ;; reset process and nest level + MOV NEST_LEVEL,0 ;; +GOTO_DONE: ;; + ADD SI,3 ;; bump to next command + JMP NEXT_COMMAND ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +ANDF_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE ANDF_DONE ;; N..don't process ANDF + MOV BL,[SI] ;; command byte + AND BL,FLAG_ID_BITS ;; isolate flag id + XOR BH,BH ;; + MOV AL,FLAGS_TO_TEST[BX] ;; flag in AL + TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT test? + JNZ ANDF_NOT ;; + TEST AL,[SI]+1 ;; Y..check for bit set + JNZ ANDF_DONE ;; if set then remain in IFF + JZ ANDF_NO_MATCH ;; +ANDF_NOT: ;; + TEST AL,[SI]+1 ;; Y..check for bit clear + JZ ANDF_DONE ;; if clear then remain in IFF +ANDF_NO_MATCH: ;; + MOV TAKE_ELSE,YES ;; flag test failed - take ELSE + DEC PROCESS_LEVEL ;; IFF would have inc'd - so dec +ANDF_DONE: ;; + INC SI ;; bump past ANDF + INC SI ;; + JMP NEXT_COMMAND ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; SET_FLAG Command. +;; Flag Table must be in the Common Section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +SET_FLAG_PROC: ;; + MOV AL,NEST_LEVEL ;; + CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? + JNE SF_DONE ;; N..don't process + ;; + MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section + MOV AL,[SI+1] ;; state id in AL + LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section +SF_NEXT_STATE: ;; + CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? + JE SF_DONE ;; Y..exit + CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? + JE SF_STATE_MATCH ;; + ADD DI,[DI].XS_STATE_LEN ;; N..check next state + JMP SHORT SF_NEXT_STATE ;; + ;; +SF_STATE_MATCH: ;; + AND EXT_KB_FLAG,NOT SCAN_MATCH ;; reset flag before search + PUSH SI ;; save pointer to next command + LEA SI,[DI].XS_FIRST_TAB ;; point to table + MOV AL,SCAN_CODE ;; restore incoming scan code + MOV CX,[SI] ;; number of entries + CMP CX,0 ;; Q..any entries? + JE SF_RESTORE ;; N..done + INC SI ;; Y..Bump to first entry + INC SI ;; +NEXT_SF_ENTRY: ;; + CMP AL,[SI] ;; Q..scan match? + JE FOUND_SF_ENTRY ;; Y..go set flag + ADD SI,3 ;; point to next entry + LOOP NEXT_SF_ENTRY ;; + JMP SHORT SF_RESTORE ;; no match found +FOUND_SF_ENTRY: ;; + MOV NLS_FLAG_1,0 ;; clear all NLS bits + MOV NLS_FLAG_2,0 ;; + MOV BL,[SI]+1 ;; flag id in BX + XOR BH,BH ;; + MOV AL,[SI]+2 ;; mask in AL + OR FLAGS_TO_TEST[BX],AL ;; set the bit + OR EXT_KB_FLAG,SCAN_MATCH ;; set flag indicating scan matched + TEST OPTION_BYTE,EXIT_IF_FOUND ;; Q..exit + JZ SF_RESTORE ;; + POP SI ;; + JMP EXIT ;; +SF_RESTORE: ;; + POP SI ;; +SF_DONE: ;; + INC SI ;; bump past command + INC SI ;; + JMP NEXT_COMMAND ;; + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Fatal Error routine. Come here when +;; we have a critical error such as an +;; invalid State Logic Command. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FATAL_ERROR: ;; + JMP SHORT EXIT ;; end the int 9 processing + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Exit point. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +EXIT: ;; + MOV BUSY_FLAG,NO ;; + STC ;; indicate we should end INT 9 + POP BX ;; processing + POP AX ;; + POP ES ;; + POP DS ;; + RET ;; + ;; +KEYB_STATE_PROCESSOR ENDP ;; + ;; + ;; + +CODE ENDS + END diff --git a/v4.0/src/CMD/KEYB/KEYBI9.INC b/v4.0/src/CMD/KEYB/KEYBI9.INC new file mode 100644 index 0000000..0541cb9 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI9.INC @@ -0,0 +1,29 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Micrsoft +;; +;; File Name: KEYBI9.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; External declarations and equates for procedures in file +;; KEYBI9.ASM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN KEYB_STATE_PROCESSOR:NEAR + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBI9C.ASM b/v4.0/src/CMD/KEYB/KEYBI9C.ASM new file mode 100644 index 0000000..9cf8f5d --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI9C.ASM @@ -0,0 +1,1894 @@ + + 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 diff --git a/v4.0/src/CMD/KEYB/KEYBI9C.INC b/v4.0/src/CMD/KEYB/KEYBI9C.INC new file mode 100644 index 0000000..7848a1b --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBI9C.INC @@ -0,0 +1,41 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBI9C.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; External declarations and equates for procedures in file +;; KEYBI9C.ASM +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN KEYB_INT_9:NEAR ;; + EXTRN BUFFER_FILL:NEAR ;; + EXTRN ERROR_BEEP :NEAR ;; + EXTRN COUNTRY_FLAG:BYTE ;; + EXTRN BEEP_PENDING:BYTE ;; + EXTRN SCAN_CODE:BYTE ;; + EXTRN K8:BYTE ;; + EXTRN TEMP_HEAD:WORD ;; + EXTRN TEMP_TAIL:WORD ;; + EXTRN BUSY_TFLAG:BYTE ;; + EXTRN MYBUFF:BYTE ;; + EXTRN ENABLE_FL:BYTE ;; + EXTRN NEW_BUFF_CTR :BYTE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBMAC.INC b/v4.0/src/CMD/KEYB/KEYBMAC.INC new file mode 100644 index 0000000..5666666 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBMAC.INC @@ -0,0 +1,319 @@ +.XLIST +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - Keyboard Definition File +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBMAC.INC +;; ---------- +;; +;; Description: +;; ------------ +;; Include file containing macros for the Keyboard Definition File. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dead key flags +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +ACUTE EQU 80H ;; NLS_FLAG_1 +GRAVE EQU 40H ;; +DIARESIS EQU 20H ;; +CIRCUMFLEX EQU 10H ;; +CEDILLA EQU 08H ;; +TILDE EQU 04H ;; + ;; NLS_FLAG_2 : nothing defined yet + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; State IDs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +DEAD_LOWER EQU 1 ;; dead keys on lower shift +DEAD_UPPER EQU 2 ;; +ALPHA_LOWER EQU 3 ;; +ALPHA_UPPER EQU 4 ;; +NON_ALPHA_LOWER EQU 5 ;; +NON_ALPHA_UPPER EQU 6 ;; +THIRD_SHIFT EQU 7 ;; +ACUTE_LOWER EQU 8 ;; +ACUTE_UPPER EQU 9 ;; +ACUTE_SPACE EQU 10 ;; +GRAVE_LOWER EQU 11 ;; +GRAVE_UPPER EQU 12 ;; +GRAVE_SPACE EQU 13 ;; +DIARESIS_LOWER EQU 14 ;; +DIARESIS_UPPER EQU 15 ;; +DIARESIS_SPACE EQU 16 ;; +CIRCUMFLEX_LOWER EQU 17 ;; +CIRCUMFLEX_UPPER EQU 18 ;; +CIRCUMFLEX_SPACE EQU 19 ;; +CEDILLA_LOWER EQU 20 ;; +CEDILLA_UPPER EQU 21 ;; +CEDILLA_SPACE EQU 22 ;; +CEDILLA_CEDILLA EQU 23 ;; +DEAD_THIRD EQU 24 ;; +ACUTE_ACUTE EQU 25 ;; +GRAVE_GRAVE EQU 26 ;; +DIARESIS_DIARESIS EQU 27 ;; +CIRCUMFLEX_CIRCUMFLEX EQU 28 ;; +FOURTH_SHIFT EQU 29 ;; +DEAD_FOURTH EQU 30 ;; +TILDE_LOWER EQU 31 ;; +TILDE_UPPER EQU 32 ;; +TILDE_SPACE EQU 33 ;; +ALT_CASE EQU 34 ;; +CTRL_CASE EQU 35 ;; +NUMERIC_PAD EQU 36 ;; +DIVIDE_SIGN EQU 37 ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Logic Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + +UNKNOWN = 255 + +FIND_FLAG MACRO FLAG_MASK + IFIDN , + FLAG_ID = EXT_KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = EXT_KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = EXT_KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = EXT_KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_3_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_3_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = NLS_FLAG_1_ID + ELSE + IFIDN , + FLAG_ID = KB_FLAG_3_ID + ELSE + FLAG_ID = UNKNOWN + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDIF + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +FLAG MACRO FLAG_MASK + FIND_FLAG FLAG_MASK + IF (FLAG_ID EQ UNKNOWN) + IF2 + %OUT Unknown parameter FLAG_MASK on FLAG MACRO + ENDIF + ELSE + DB FLAG_ID + DB FLAG_MASK + ENDIF + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IFF MACRO FLAG_MASK,MASK_TYPE + MAC_OK = 1 + IFB + NOT_BIT = 00000000B + ELSE + IFIDN , + NOT_BIT = 00001000B + ELSE + MAC_OK = 0 + IF2 + %OUT Unknown parameter MASK_TYPE on IFF MACRO + ENDIF + ENDIF + ENDIF + IF MAC_OK + FIND_FLAG FLAG_MASK + IF (FLAG_ID EQ UNKNOWN) + IF2 + %OUT Unknown parameter FLAG_MASK on IFF MACRO + ENDIF + ELSE + DB IFF_COMMAND+NOT_BIT+FLAG_ID + DB FLAG_MASK + ENDIF + ENDIF + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IFKBD MACRO SYS + DB IFKBD_COMMAND + DW SYS + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ANDF MACRO FLAG_MASK,MASK_TYPE + MAC_OK = 1 + IFB + NOT_BIT = 00000000B + ELSE + IFIDN , + NOT_BIT = 00001000B + ELSE + MAC_OK = 0 + IF2 + %OUT Unknown parameter MASK_TYPE on ANDF MACRO + ENDIF + ENDIF + ENDIF + IF MAC_OK + FIND_FLAG FLAG_MASK + IF (FLAG_ID EQ UNKNOWN) + IF2 + %OUT Unknown parameter FLAG_MASK on ANDF MACRO + ENDIF + ELSE + DB ANDF_COMMAND+NOT_BIT+FLAG_ID + DB FLAG_MASK + ENDIF + ENDIF + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ELSEF MACRO + DB ELSEF_COMMAND + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ENDIFF MACRO + DB ENDIFF_COMMAND + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +XLATT MACRO STATE + DB XLATT_COMMAND + DB STATE + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +PUT_ERROR_CHAR MACRO STATE + DB PUT_ERROR_COMMAND + DB STATE + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +OPTION MACRO MASK,MASK_TYPE + MAC_OK = 1 + IFB + NOT_BIT = 00000000B + ELSE + IFIDN , + NOT_BIT = 00001000B + ELSE + MAC_OK = 0 + IF2 + %OUT Unknown parameter MASK_TYPE on OPTION MACRO + ENDIF + ENDIF + ENDIF + IF MAC_OK + DB OPTION_COMMAND+NOT_BIT + DB MASK + ENDIF + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +SET_FLAG MACRO STATE + DB SET_FLAG_COMMAND + DB STATE + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +RESET_NLS MACRO + DB RESET_NLS_COMMAND + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +BEEP MACRO + DB BEEP_COMMAND + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +GOTO MACRO GOTO_OFFSET + DB GOTO_COMMAND + DW GOTO_OFFSET-$-2 + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EXIT_INT_9 MACRO + DB GOTO_COMMAND+EXIT_INT_9_FLAG + DW 0 + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +EXIT_STATE_LOGIC MACRO + DB GOTO_COMMAND+EXIT_STATE_LOGIC_FLAG + DW 0 + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CHECK_FOR_CORE_KEY MACRO + DB CHECK_CORE_COMMAND + ENDM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST diff --git a/v4.0/src/CMD/KEYB/KEYBMSG.INC b/v4.0/src/CMD/KEYB/KEYBMSG.INC new file mode 100644 index 0000000..3bcb061 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBMSG.INC @@ -0,0 +1,44 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBMSG.INC +;; ---------- +;; +;; Root File Name: KEYBCMD.ASM (KEYB.ASM) +;; --------------- +;; +;; Description: +;; ------------ +;; External declarations for procedures in file KEYBCMD.ASM. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN ACT_KEYB_CP :BYTE ;; + EXTRN ACT_CON_CP :BYTE ;; + EXTRN ACT_KEYB :BYTE ;; + EXTRN INV_L :BYTE ;; + EXTRN INV_I :BYTE ;; + EXTRN INV_CP :BYTE ;; + EXTRN INV_S :BYTE ;; + EXTRN INV_FN :BYTE ;; + EXTRN INV_KEYB_Q :BYTE ;; + EXTRN INV_CON_Q :BYTE ;; + EXTRN NOT_DESIG :BYTE ;; + EXTRN NOT_SUPP :BYTE ;; + EXTRN NOT_VALID1 :BYTE ;; + EXTRN NOT_VALID2 :BYTE ;; + EXTRN WARNING_1 :BYTE ;; + EXTRN INV_COMBO :BYTE ;; + EXTRN CR_LF :BYTE ;; + EXTRN MEMORY_OVERF :BYTE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.LIST diff --git a/v4.0/src/CMD/KEYB/KEYBSHAR.INC b/v4.0/src/CMD/KEYB/KEYBSHAR.INC new file mode 100644 index 0000000..75bbc13 --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBSHAR.INC @@ -0,0 +1,307 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBSHAR.INC +;; ---------- +;; +;; Description: +;; ------------ +;; Include file containing structure definitions Shared Data Area +;; for the Shared Data Area. +;; The Shared Data Area contains data which is required by +;; both the resident and transient KEYB code. The Shared +;; Data Area is allocated in the KEYBI2F file and will be +;; resident following initial installation. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; SHARED_DATA_STR defines the initial fixed length portion of the +;; Shared Data Area. +;; Tables are loaded beginning at TABLE_AREA in the following order: +;; State Logic +;; Common Translate Section +;; Specific Translate Sections for +;; each code page +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; SPECIAL_FEATURES equates: +TYPEWRITER_CAPS_LK EQU 8000H ;; typewriter style caps lock +JR_HOT_KEY_1_2 EQU 4000H ;; on PCjr use 1/2 as the hot keys + ;; instead of F1/F2 + ;; + ;; Some useful scan codes: +F1_SCAN EQU 59 ;; F1 +F2_SCAN EQU 60 ;; F2 +ONE_SCAN EQU 2 ;; "1" +TWO_SCAN EQU 3 ;; "2" + ;; + ;; SYSTEM_FLAG equates: +EXT_16 EQU 8000H ;; extended int16 support is there +PC_AT EQU 4000H ;; code for pcat +PC_LAP EQU 2000H ;; code for pc lap computer (p-12) +PC_XT EQU 1000H ;; code for PC, PC/XT, PORTABLE +PC_JR EQU 0800H ;; code for PCjr +PC_PAL EQU 0400H ;; code for PALACE +PC_386 EQU 0200H ;; code for WRANGLER +PC_NET EQU 0100H ;; PC Net is installed + ;; + ;; HOT_KEY_FLAG EQUATES: +US_MODE EQU 0 ;; hot key is active => US +LANG_MODE EQU 0FFH ;; hot key is inactive + ;; + ;; ----------------------------------- +SHARED_DATA_STR STRUC ;; SHARED DATA AREA + ;; +OLD_INT_9 DD 0 ;; saved int 9 vector +OLD_INT_2F DD 0 ;; saved int 2F vector +OLD_INT_48 DD 0 ;; saved int 48 vector (if PCjr) +KEYB_TYPE DW 0 ;; type of keyboard +SYSTEM_FLAG DW 0 ;; system configuration flags +TABLE_OK DB 0 ;; flag to INT 9 that table is built +JR_KB_FLAG DB 0 ;; flag for special PCjr processing +TIMING_FACTOR DW 1 ;; Scale factor for INT 9 timing loops + ;; PC_AT = 1 + DB 2 DUP(0) ;; reserved + ;; + ;; Table copy begins here: +ACTIVE_LANGUAGE DB 'US' ;; language code +INVOKED_CP_TABLE DW 437 ;; ptr to table for invoked code page +INVOKED_KBD_ID DW 0 ;; WGR invoked keyboard id. ;AN000 +ACTIVE_XLAT_PTR DW -1 ;; ptr to active Specific Translate Sect +FIRST_XLAT_PTR DW -1 ;; ptr to first Specific Translate Sect +RESIDENT_END DW 0ffffh ;; offset of last byte in resident mem +LOGIC_PTR DW -1 ;; ptr to State Logic +COMMON_XLAT_PTR DW -1 ;; ptr to Common Translate Section +SPECIAL_FEATURES DW ? ;; special Features +TABLE_OVERFLOW DB 0 ;; overflow flag for table rebuild +HOT_KEY_ON_SCAN DB ? ;; scan codes to use with ALT+CTRL +HOT_KEY_OFF_SCAN DB ? ;; to turn hot key on and off + DB 4 DUP(0) ;; reserved +TABLE_AREA DB ? ;; tables loaded here: + ;; State Logic + ;; Common Translate Section + ;; Specific Translate Sections for + ;; each code page +SHARED_DATA_STR ENDS ;; + ;; + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; State Logic equates. +;; Contains equates for our NLS Flags and for the State Logic +;; commands. +;; State Logic command macros are defined in KEYBMAC.INC +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +STATE_LOGIC_STR STRUC ;; + ;; +SL_LOGIC_LEN DW ? ;; length of state logic +SL_SPECIAL_FEATURES DW ? ;; +SL_LOGIC_CMDS DB 0 ;; state logic commands begin here + ;; +STATE_LOGIC_STR ENDS ;; + ;; + ;; +NUM_BIOS_FLAGS EQU 4 ;; +NUM_NLS_FLAGS EQU 2 ;; '+1' below is the EXT_KB_FLAG +NUM_FLAGS EQU NUM_BIOS_FLAGS+NUM_NLS_FLAGS+1 + ;; + ;; +EITHER_SHIFT EQU 80H ;; EXT_KB_FLAG : our own shift state +EITHER_CTL EQU 40H ;; flags +EITHER_ALT EQU 20H ;; +SCAN_MATCH EQU 08H ;; set if scan code found in XLATT + ;; or SET_FLAG searches + ;; + ;; +KB_FLAG_ID EQU 0 ;; Flag ID's as coded in IFF and ANDF +KB_FLAG_1_ID EQU 1 ;; commands +KB_FLAG_2_ID EQU 2 ;; +KB_FLAG_3_ID EQU 3 ;; +EXT_KB_FLAG_ID EQU 4 ;; +NLS_FLAG_1_ID EQU 5 ;; +NLS_FLAG_2_ID EQU 6 ;; + ;; +COMMAND_BITS EQU 0F0H ;; Mask to isolate command code +SUB_CMD_BITS EQU 0FH ;; mask to isolate sub command code +NOT_TEST EQU 08H ;; NOT bit in IFF, ANDF +COMMAND_SHIFT EQU 4 ;; shift amount for command code +FLAG_ID_BITS EQU 07H ;; mask to isolate flag id in IFF, ANDF +NUM_COMMANDS EQU 0CH ;; number of commands + ;; +IFF_COMMAND EQU 00H ;; +ANDF_COMMAND EQU 10H ;; +ELSEF_COMMAND EQU 20H ;; +ENDIFF_COMMAND EQU 30H ;; +XLATT_COMMAND EQU 40H ;; +OPTION_COMMAND EQU 50H ;; +SET_FLAG_COMMAND EQU 60H ;; +PUT_ERROR_COMMAND EQU 70H ;; +IFKBD_COMMAND EQU 80H ;; +GOTO_COMMAND EQU 90H ;; +BEEP_COMMAND EQU 0A0H ;; +RESET_NLS_COMMAND EQU 0B0H ;; +CHECK_CORE_COMMAND EQU 0C0H ;; + ;; + ;; +EXIT_INT_9_FLAG EQU 01H ;; Special forms of GOTO. These +EXIT_STATE_LOGIC_FLAG EQU 02H ;; values are in the right nibble + ;; of the GOTO command. + ;; + ;; PROCESSING OPTIONS: +EXIT_IF_FOUND EQU 80H ;; exit INT 9 if a translation + ;; match is found + ;; +ANY_KB EQU 0FFFFH ;; +JR_KB EQU 8000H ;; Keyboard types +XT_KB EQU 4000H ;; +AT_KB EQU 2000H ;; +G_KB EQU 1000H ;; +P_KB EQU 0800H ;; +P12_KB EQU 0400H ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Translate Table Sections. Both the Specific and Common +;; Translate Sections are formatted as follows. +;; +;; The Specific Translate Sections are chained together using the +;; XS_NEXT_SECT_PTR field (-1 if last section). +;; Translate Sections contains multiple States. +;; A State contains the translate tables for a single +;; shift state (IE lower case, upper case ....) +;; Each State may contain multiple translate tables. +;; +;; The Translate Section layout is defined using several STRUCs. +;; These STRUCs are allocated in the Shared Data Area as follows: +;; +;; XLAT_SECT_STR ; header info for the section +;; STATE_STR ; header for state #1 +;; XLAT_STR ; first translate tab for state #1 +;; XLAT_TYPE_1_STR or XLAT_TYPE_2_STR +;; XLAT_STR ; second translate tab +;; XLAT_TYPE_1_STR or XLAT_TYPE_2_STR +;; ... +;; STATE_STR ; header for state #2 +;; XLAT_STR +;; XLAT_TYPE_1_STR or XLAT_TYPE_2_STR +;; ... +;; ... +;; +;; A State may contain a "Set_Flag" table instead of translate tables. +;; These tables are used to set the NLS flags instead of generating +;; ASCII codes (for example: to remember dead key states). +;; There can be only on Set_Flag table per state. +;; The Set_Flag table layout is defined in the SET_FLAG_STR STRUC. +;; +;; So some states will contain translate tables (to generate ASCII codes) +;; and some states will contain a Set_Flag table (to record dead key +;; status). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +XLAT_SECT_STR STRUC ;; + ;; +XS_NEXT_SECT_PTR DW ? ;; Pointer to next Specific Translate + ;; Section +XS_CP_ID DW ? ;; code page id +XS_FIRST_STATE DB ? ;; + ;; +XLAT_SECT_STR ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; State structure. +;; The last State is a null State containing only the +;; XS_STATE_LEN field with a value of 0. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +STATE_STR STRUC ;; + ;; +XS_STATE_LEN DW ? ;; length of state section +XS_STATE_ID DB ? ;; State ID +XS_KBD_TYPE DW ? ;; Keyboard Type +XS_ERROR_CHAR DW ? ;; Buffer entry for error character +XS_FIRST_TAB DB ? ;; + ;; +STATE_STR ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Translate Table structures. +;; There may be many translate tables in a State. The last +;; table is a null table containing only the XLAT_TAB_SIZE field with +;; a value of 0. +;; The xlate table can be in one of two forms: +;; Type 1 = Table contains buffer entries only. +;; Scan code is used as an index into xlat table +;; Type 2 = Table contains pairs of SCAN/BUFFER_ENTRY. +;; Table must be searched for matching scan. +;; Type 1 is the default. Type 2 tables should be identified by setting +;; the TYPE_2_TAB bit in XLAT_OPTIONS. +;; Buffer entries default to 2-bytes per entry. +;; Optionally the table may contain ASCII codes only +;; (1-byte entries). This is specified by setting the ASCII_ONLY bit +;; in XLAT_OPTIONS. 2-byte buffer entries are coded ASCII,SCAN. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + ;; Translate options: +ASCII_ONLY EQU 80H ;; Only ASCII codes listed - use + ;; incoming scan for buffer entry +TYPE_2_TAB EQU 40H ;; search xlat table for matching scan +ZERO_SCAN EQU 20H ;; set the scan half of the buffer + ;; entry to 0 + ;; +NULL_ASCII_CODE EQU -1 ;; + ;; +DEFAULT_TAB_2_ENT_SZ EQU 3 ;; +ASC_ONLY_TAB_2_ENT_SZ EQU 2 ;; + ;; + ;; +XLAT_STR STRUC ;; + ;; +XLAT_TAB_SIZE DW ? ;; Size in bytes of this table - + ;; includes this field, options etc. +XLAT_OPTIONS DB ? ;; xlat options + ;; XLAT TABLE IS HERE +XLAT_STR ENDS ;; + ;; +XLAT_TYPE_1_STR STRUC ;; use scan code as index into table + DB TYPE XLAT_STR DUP(?) ;; filler +XLAT_SCAN_LO DB ? ;; Scan code +XLAT_SCAN_HI DB ? ;; range +XLAT_1_BUF_ENTRY DB ? ;; The table itself +XLAT_TYPE_1_STR ENDS ;; + ;; +XLAT_TYPE_2_STR STRUC ;; search table for scan + DB TYPE XLAT_STR DUP(?) ;; filler +XLAT_NUM DB ? ;; number of scans +XLAT_SCAN DB ? ;; Scan code +XLAT_2_BUF_ENTRY DB ? ;; The table itself +XLAT_TYPE_2_STR ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Set_Flag Tables. +;; State Sections immediately following the LAST_ENTRYs. +;; Dead key definitions. If the scan matches then +;; set the bit in NLS_FLAGs indicated in DK_MASK +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +SF_ENT_SZ EQU 3 ;; size of entry + ;; +SET_FLAG_STR STRUC ;; + ;; +SF_NUM DB 0 ;; Number of entries +SF_SCAN_CODE DB 0 ;; scan code +SF_FLAG_ID DB 0 ;; flag id +SF_FLAG_MASK DB 0 ;; flag mask + ;; +SET_FLAG_STR ENDS ;; + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST diff --git a/v4.0/src/CMD/KEYB/KEYBSYS.INC b/v4.0/src/CMD/KEYB/KEYBSYS.INC new file mode 100644 index 0000000..4b42fbe --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBSYS.INC @@ -0,0 +1,137 @@ +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBSYS.INC +;; ---------- +;; +;; Root File Name: KEYB.ASM +;; --------------- +;; +;; Description: +;; ------------ +;; Include file containing structure definitions and equates +;; for the KEYBOARD.SYS file. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; File header - contains pointers to keyboard tables for each language +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBSYS_HEADER STRUC ;; + ;; +KH_SIGNATURE DB 0FFh,'KEYB ' ;; signature +KH_RESV_1 DB 8 DUP(0) ;; reserved +KH_MAX_COM_SZ DW 0 ;AN000;**chg ;; maximum size of Common Xlat Sect +KH_MAX_SPEC_SZ DW 0 ;AN000;;**chg ;; max size of Specific Xlat Sect +KH_MAX_LOGIC_SZ DW 0 ;AN000;;**chg ;; max size of State Logic +KH_RESV_2 Dw 0 ;AN000;;**chg ;; reserved CNS +KH_NUM_ID Dw 0 ;AN000;;; ************* CNS +KH_NUM_LANG DW 0 ;; number of languages +KH_LANG_PTRS DB 0 ;; language pointers start here +;********************* CNS ********************** +;KH_NUM_ID DW 0 ;; number of languages +;KH_ID_PTRS DB 0 ;; id pointers start here +;********************* CNS ********************** +KEYBSYS_HEADER ENDS ;; +;******************CNS******************* +KEYBSYS_ID_PTRS STRUC + +KP_ID_CODE DW 0 ;AN000; +KP_LANG_PTR DD 0 ;AN000; + +KEYBSYS_ID_PTRS ENDS + ;; +;*****************CNS******************** +KEYBSYS_LANG_PTRS STRUC ;; + ;; Next two entries repeat: +KP_LANG_CODE DW 0 ;; language code +KP_ENTRY_PTR DD 0 ;; language entry pointer + ;; +KEYBSYS_LANG_PTRS ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Language Entry - pointed to by KH_ENTRY_PTR in KEYBSYS_HEADER +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBSYS_LANG_ENTRY STRUC ;; + ;; +KL_LANG_CODE DW 'XX' ;; language code +KL_ID_CODE DW 0 ;; reserved (ID CODE) +KL_LOGIC_PTR DD 0 ;AC000;;**chg ;; State Logic pointer +KL_NUM_ID DB 0 ;AN000;;CNS ;; number of valid IDs for this lang +KL_NUM_CP DB 0 ;; number of valid CPs for this lang +KL_CP_PTRS DB 0 ;; CP table pointers start here + ;; +KEYBSYS_LANG_ENTRY ENDS ;; + ;; +KEYBSYS_CP_PTRS STRUC ;; + ;; Next two entries repeat: +KC_CODE_PAGE DW 0 ;; code page +KC_ENTRY_PTR DD 0 ;; ptr to Specific Translate Section + ;; +KEYBSYS_CP_PTRS ENDS ;; + ;; + ;; +;; Everything from here down is new +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; State Logic - pointed to by KL_LOGIC_PTR in KEYBSYS_LANG_ENTRY +;; Common Translate Section follows immediately after the State Logic. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBSYS_STATE_LOGIC STRUC ;; + ;; +KT_LOGIC_LEN DW ? ;; length of state logic +KT_SPECIAL_FEATURES DW ? ;; Special Features (see KEYBSHAR.INC) +KT_LOGIC_CMDS DB 0 ;; state logic commands begin here + ;; +KEYBSYS_STATE_LOGIC ENDS ;; + ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Translate Section - Common and Specific Translate Sections +;; are both in this form. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBSYS_XLAT_SECT STRUC ;; + ;; +KX_SECTION_LEN DW ? ;; Length of this section +KX_CP_ID DW ? ;; code page id +KX_FIRST_STATE DB ? ;; + ;; +KEYBSYS_XLAT_SECT ENDS ;; + ;; + ;; +KEYBSYS_STATE STRUC ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Translate Sections contains multiple States. + ;; A State contains the translate tables for a single + ;; shift state (IE lower case, upper case ....) + ;; The last State is a null State containing only the + ;; KX_STATE_LEN field with a value of 0. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; +KX_STATE_LEN DW ? ;; length of state section +KX_STATE_ID DB ? ;; State ID +KX_KBD_TYPE DW ? ;; Keyboard Type +KX_ERROR_CHAR DW ? ;; Buffer entry for error character +KX_FIRST_XLAT DB ? ;; XLAT tables begin here + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Each State consists of multiple translate tables. + ;; The last translate table within a state is a null + ;; table containing only the + ;; KX_XLAT_LEN field with a value of 0. + ;; Refer to KEYBSHAR.INC for translate table format. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +KEYBSYS_STATE ENDS ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST + diff --git a/v4.0/src/CMD/KEYB/KEYBTBBL.ASM b/v4.0/src/CMD/KEYB/KEYBTBBL.ASM new file mode 100644 index 0000000..b28f08c --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBTBBL.ASM @@ -0,0 +1,855 @@ + + PAGE ,132 + TITLE DOS KEYB Command - Transient Command Processing + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBTBBL.ASM +;; ---------- +;; +;; Description: +;; ------------ +;; Build SHARED_DATA_AREA with parameters specified +;; in KEYBCMD.ASM +;; +;; Documentation Reference: +;; ------------------------ +;; None +;; +;; Procedures Contained in This File: +;; ---------------------------------- +;; TABLE_BUILD: Build the header sections of the SHARED_DATA_AREA +;; STATE_BUILD: Build the state sections in the table area +;; FIND_CP_TABLE: Given the language and code page parm, determine the +;; offset of the code page table in KEYBOARD.SYS +;; +;; Include Files Required: +;; ----------------------- +;; KEYBSHAR.INC +;; KEYBSYS.INC +;; KEYBDCL.INC +;; KEYBI2F.INC +;; +;; External Procedure References: +;; ------------------------------ +;; None +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + PUBLIC TABLE_BUILD ;; + PUBLIC FIND_CP_TABLE ;; + PUBLIC CPN_INVALID ;; + PUBLIC SD_LENGTH ;; + ;; +CODE SEGMENT PUBLIC 'CODE' ;; + ;; + INCLUDE KEYBEQU.INC ;; + INCLUDE KEYBSHAR.INC ;; + INCLUDE KEYBSYS.INC ;; + INCLUDE KEYBCMD.INC ;; + INCLUDE KEYBDCL.INC ;; + INCLUDE COMMSUBS.INC ;; + INCLUDE KEYBCPSD.INC ;; + ;; + ASSUME CS:CODE,DS:CODE ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: TABLE_BUILD +;; +;; Description: +;; Create the table area within the shared data structure. Each +;; table is made up of a descriptor plus the state sections. +;; Translate tables are found in the Keyboard definition file and are +;; copied into the shared data area by means of the STATE_BUILD +;; routine. +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to our data segment +;; BP - points at beginning of CMD_PARM_LIST +;; +;; SHARED_DATA_STR must be allocated in memory +;; +;; The following variables must also be passed from KEYB_COMMAND +;; KEYBSYS_FILE_HANDLE is set to file handle after opening file +;; CP_TAB_OFFSET is the offset of the CP table in the SHARED_DATA_AREA +;; STATE_LOGIC_OFFSET is the offset of the state section in the SHARED_DATA_AREA +;; SYS_CODE_PAGE is the binary representation of the system CP +;; KEYBCMD_LANG_ENTRY_PTR is a pointer to the lang entry in KEY DEF file +;; DESIG_CP_BUFFER is the buffer which holds a list of designated CPs +;; DESIG_CP_OFFSET:WORD is the offset of that list +;; NUM_DESIG_CP is the number of CPs designated +;; FILE_BUFFER is the buffer to read in the KEY DEF file +;**********CNS *************************************** +;; ID_PTR_SIZE is the size of the ID ptr structure +;**********CNS *************************************** +;; LANG_PTR_SIZE is the size of the lang ptr structure +;; CP_PTR_SIZE is the size of the CP ptr structure +;; NUM_CP is the number of CPs in the KEYB DEF file for that lang +;; SHARED_AREA_PTR segment and offset of the SHARED_DATA_AREA +;; +;; +;; Output Registers: +;; CX - RETURN_CODE := 0 - Table build successful +;; 1 - Table build unsuccessful - ERROR 1 +;; (Invalid language parm) +;; 2 - Table build unsuccessful - ERROR 2 +;; (Invalid Code Page parm) +;; 3 - Table build unsuccessful - ERROR 3 +;; (Machine type unavaliable) +;; 4 - Table build unsuccessful - ERROR 4 +;; (Bad or missing keyboard def file) +;; 5 - Table build unsuccessful - ERROR 5 +;; (Memory overflow occurred) +;; Logic: +;; Calculate Offset difference between TEMP and SHARED_DATA_AREAs +;; Get LANGUAGE_PARM and CODE_PAGE_PARM from parm list +;; Call FIND_CP_TABLE := Determine whether CP is valid for given language +;; IF CP is valid THEN +;; Store them in the SHARED_DATA_AREA +;; Prepare to read Keyboard definition file by LSEEKing to the top +;; READ the header +;; Store maximum table values for calculation of RES_END +;; Set DI to point at TABLE_AREA within SHARED_DATA_AREA +;; FOR the state logic section of the specified language: +;; IF STATE_LOGIC_PTR is not -1 THEN +;; LSEEK to state logic section in keyboard definition file +;; READ the state logic section into the TABLE_AREA +;; Set the hot keyb scan codes +;; Set the LOGIC_PTR in the header +;; FOR the common translate section: +;; IF Length parameter is not 0 THEN +;; Build state +;; Set the COMMON_XLAT_PTR in the header +;; FOR the specific translate sections: +;; Establish addressibility to list of designated code pages +;; FOR each code page +;; IF CP_ENTRY_PTR is not -1 THEN +;; Determine offset of CP table in Keyb Def file +;; IF CP table not avaliable THEN +;; Set CPN_INVALID flag +;; ELSE +;; LSEEK to CPn state section in keyboard definition file +;; IF this is the invoked code page THEN +;; Set ACTIVE_XLAT_PTR in SHARED_DATA_AREA +;; Update RESIDENT_END ptr +;; Build state +;; Update RESIDENT_END ptr +;; End +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FB EQU FILE_BUFFER ;; +KB_MASK EQU 02H ;; + ;; +FIRST_XLAT_TAB DW 0 ;; +NEXT_SECT_PTR DW -1 ;; + ;; +MAX_COM_SIZE DW ? ;; +MAX_SPEC_SIZE DW ? ;; +MAX_LOGIC_SIZE DW ? ;; + ;; +RESIDENT_END_ACC DW 0 ;; +SA_HEADER_SIZE DW SIZE SHARED_DATA_STR;; +PARM_LIST_OFFSET DW ? ;; +;********************CNS************************* +TB_ID_PARM DW 0 +;********************CNS************************* +TB_LANGUAGE_PARM DW 0 ;; +TB_CODE_PAGE_PARM DW 0 ;; + ;; +CPN_INVALID DW 0 ;; + ;; +KEYB_INSTALLED DW 0 ;; +SD_AREA_DIFFERENCE DW 0 ;; +SD_LENGTH DW 2000 ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +TABLE_BUILD PROC NEAR ;; + ;; + MOV AX,OFFSET SD_SOURCE_PTR ;; Setup the difference + SUB AX,OFFSET SD_DEST_PTR ;; value used to calculate + MOV SD_AREA_DIFFERENCE,AX ;; new ptr values for + ;; SHARED_DATA_AREA + MOV AX,[BP].ID_PARM ;; WGR Get id parameter ;AN000 + MOV TB_ID_PARM,AX ;; WGR ;AN000 + MOV AX,[BP].LANGUAGE_PARM ;; Get language parameter + MOV TB_LANGUAGE_PARM,AX ;; + MOV BX,[BP].CODE_PAGE_PARM ;; Get code page parameter + MOV TB_CODE_PAGE_PARM,BX ;; + ;; Make sure code page is + CALL FIND_CP_TABLE ;; valid for the language + CMP CX,0 ;; Test return codes + JE TB_CHECK_CONTINUE1 ;; IF code page is found + JMP TB_ERROR6 ;; for language THEN + ;; +TB_CHECK_CONTINUE1: ;;;;;;;; + MOV BP,OFFSET SD_SOURCE_PTR ;; Put language parm and ;AN000 + MOV AX,TB_ID_PARM ;; WGR id parm and.. ;AN000 + MOV ES:[BP].INVOKED_KBD_ID,AX ;; WGR + MOV BX,TB_CODE_PAGE_PARM ;; + MOV ES:[BP].INVOKED_CP_TABLE,BX ;;;;;; code page parm into the + MOV AX,TB_LANGUAGE_PARM ;; SHARED_DATA_AREA + MOV WORD PTR ES:[BP].ACTIVE_LANGUAGE,AX ;; + ;; + MOV BX,KEYBSYS_FILE_HANDLE ;;;;;;;;;;;;;;; Get handle + XOR DX,DX ;; LSEEK file pointer + XOR CX,CX ;; back to top of file + MOV AH,42H ;; + MOV AL,0 ;; If no problem with + INT 21H ;; Keyboard Def file THEN + JNC TB_START ;; + JMP TB_ERROR4 ;; + ;; +TB_START: ;; Else + XOR DI,DI ;; Set number + LEA CX,[DI].KH_MAX_LOGIC_SZ+2;; bytes to read header + MOV DX,OFFSET FILE_BUFFER ;; Move contents into file buffer + MOV AH,3FH ;; READ + PUSH CS ;; + POP DS ;; + INT 21H ;; File + JNC TB_CONTINUE1 ;; + JMP TB_ERROR4 ;; + ;; +TB_CONTINUE1: ;; + CMP CX,AX ;; + JE TB_ERROR_CHECK1 ;; + MOV CX,4 ;; + JMP TB_CPN_INVALID ;; + ;; +TB_ERROR_CHECK1: ;; + MOV CX,FB.KH_MAX_COM_SZ ;; Save values for RESIDENT_END + MOV MAX_COM_SIZE,CX ;; calculation + MOV CX,FB.KH_MAX_SPEC_SZ ;; + MOV MAX_SPEC_SIZE,CX ;; + MOV CX,FB.KH_MAX_LOGIC_SZ ;; + MOV MAX_LOGIC_SIZE,CX ;; + ;; + LEA DI,[BP].TABLE_AREA ;; Point at beginning of table area + ;; DI ---> TABLE_AREA +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ** FOR STATE LOGIC SECTION FOR LANG ** +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +TB_STATE_BEGIN: ;; + MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle + MOV CX,WORD PTR STATE_LOGIC_OFFSET+2 ;; + MOV DX,WORD PTR STATE_LOGIC_OFFSET ;; Get LSEEK file pointer + ;; + CMP DX,-1 ;;;;;;;;;; If no language table then + JNE TB_STATE_CONTINUE1 ;; jump to code page begin + JMP TB_CP_BEGIN ;; + ;; +TB_STATE_CONTINUE1: ;; Else + MOV AH,42H ;; LSEEK to beginning of state logic sect + MOV AL,0 ;; If no problem with + INT 21H ;; Keyboard Def file THEN + JNC TB_STATE_CONTINUE2 ;; + JMP TB_ERROR4 ;; + ;;;;;;;;;; +TB_STATE_CONTINUE2: ;; + MOV DX,AX ;; + MOV WORD PTR SB_STATE_OFFSET+2,CX ;; Save the offset of the + MOV WORD PTR SB_STATE_OFFSET,DX ;; states in Keyb Def file + ;; + SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + MOV ES:[BP].LOGIC_PTR,DI ;;;;;;;;;; Set because this is state + ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;; + MOV CX,4 ;; Set number bytes to read length and + ;; special features + MOV DX,OFFSET FILE_BUFFER ;; Set the buffer address + MOV AH,3FH ;; Read from the Keyb Def file + INT 21H ;; + JNC TB_STATE_CONTINUE3 ;; + JMP TB_ERROR4 ;; + ;; +TB_STATE_CONTINUE3: ;; + CMP CX,AX ;; + JE TB_ERROR_CHECK2 ;; + MOV CX,4 ;; + JMP TB_CPN_INVALID ;; + ;;;;; +TB_ERROR_CHECK2: ;; + MOV AX,FB.KT_SPECIAL_FEATURES ;; Save the special features in the + MOV ES:[BP].SPECIAL_FEATURES,AX ;; SHARED_DATA_AREA + ;; + CMP HW_TYPE,JR_KB ;;;;;;;; + JNE USE_F1_F2 ;; + TEST AX,JR_HOT_KEY_1_2 ;; + JZ USE_F1_F2 ;; + MOV ES:[BP].HOT_KEY_ON_SCAN,ONE_SCAN ;; + MOV ES:[BP].HOT_KEY_OFF_SCAN,TWO_SCAN ;; + JMP HOT_KEY_SET ;; + ;; +USE_F1_F2: ;; + MOV ES:[BP].HOT_KEY_ON_SCAN,F1_SCAN ;; + MOV ES:[BP].HOT_KEY_OFF_SCAN,F2_SCAN ;; + ;; +HOT_KEY_SET: ;;;;;;;; + MOV CX,FB.KT_LOGIC_LEN ;; Set length of section to read + CMP CX,0 ;; + JNE TB_STATE_CONTINUE4 ;; + MOV CX,-1 ;;;;; + MOV ES:[BP].LOGIC_PTR,CX ;; + JMP SB_COMM_BEGIN ;; + ;; +TB_STATE_CONTINUE4: ;; + MOV ES:[DI],CX ;; Store length parameter in + ADD DI,2 ;; SHARED_DATA_AREA + MOV CX,FB.KT_SPECIAL_FEATURES;; Save the special features + MOV ES:[DI],CX ;; + ADD DI,2 ;; + MOV CX,FB.KT_LOGIC_LEN ;; Set length of section to read + SUB CX,4 ;; Adjust for what we have already read + MOV DX,DI ;; Set the address of SHARED_DATA_AREA + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; Read logic section from the + INT 21H ;; Keyb Def file + PUSH CS ;; + POP DS ;; + JNC TB_STATE_CONTINUE5 ;; + JMP TB_ERROR4 ;; + ;; +TB_STATE_CONTINUE5: ;; + CMP CX,AX ;; + JE TB_ERROR_CHECK3 ;; + MOV CX,4 ;; + JMP TB_CPN_INVALID ;; + ;; +TB_ERROR_CHECK3: ;; + ADD DI,CX ;; Set DI at new beginning of area + ;; TABLE_AREA + ;; STATE_LOGIC + MOV CX,RESIDENT_END_ACC ;; DI ---> + ADD CX,SA_HEADER_SIZE ;; + ADD CX,MAX_LOGIC_SIZE ;; + MOV RESIDENT_END_ACC,CX ;; Refresh resident end size + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ** FOR COMMON TRANSLATE SECTION FOR LANG ** +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +SB_COMM_BEGIN: ;; + MOV CX,SIZE KEYBSYS_XLAT_SECT-1 ;; Set number bytes to read header + MOV DX,DI ;; Set the SHARED_DATA_AREA address + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; Read from the Keyb Def file + INT 21H ;; + PUSH CS ;; + POP DS ;; + JNC TB_STATE_CONTINUE6 ;; + JMP TB_ERROR4 ;; + ;; +TB_STATE_CONTINUE6: ;; + MOV CX,ES:[DI].KX_SECTION_LEN;; Set length of section to read + CMP CX,0 ;; + JNE TB_STATE_CONTINUE7 ;; + JMP TB_CP_BEGIN ;; + ;;;;;;; +TB_STATE_CONTINUE7: ;; + MOV CX,WORD PTR SB_STATE_OFFSET ;; Save the offset of the + ADD CX,FB.KT_LOGIC_LEN ;; + MOV WORD PTR SB_STATE_OFFSET,CX ;; Save the offset of the + SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + MOV ES:[BP].COMMON_XLAT_PTR,DI ;; + ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;;;;;;; + CALL STATE_BUILD ;; + ;; DI set at new beginning of area + ;; TABLE_AREA + ;; STATE_LOGIC + ;; COMMON_XLAT_SECTION + MOV CX,RESIDENT_END_ACC ;; + ADD CX,MAX_COM_SIZE ;; + MOV RESIDENT_END_ACC,CX ;; Refresh resident end size + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; FOR ALL DESIGNATED OR INVOKED CODE PAGES +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +TB_CP_BEGIN: ;; Get the offset to + MOV CX,OFFSET DESIG_CP_BUFFER.DESIG_CP_ENTRY ;; the beginning of the + MOV DESIG_CP_OFFSET,CX ;; table of designated + ;;;;;; code pages +TB_CPN_BEGIN: ;; + MOV AX,WORD PTR ES:[BP].ACTIVE_LANGUAGE ;; Get the active language + MOV CX,NUM_DESIG_CP ;;;;;;;;;;;;;; Get the number of CPs + CMP CX,0 ;; IF we have done all requested CPs + JNE TB_CPN_VALID1 ;; + JMP TB_DONE ;; Then done + ;; +TB_CPN_VALID1: ;; + MOV SI,[DESIG_CP_OFFSET] ;; + MOV BX,[SI] ;; Get the CP + CMP BX,-1 ;; + JNE TB_CPN_CONTINUE1 ;; + JMP TB_CPN_REPEAT ;; + ;; +TB_CPN_CONTINUE1: ;; ELSE + PUSH DI ;; + CALL FIND_CP_TABLE ;; Find offset of code page table + POP DI ;; + ;; + CMP CX,0 ;; Test return codes + JE TB_CPN_VALID ;; IF code page is not found for language + MOV CPN_INVALID,CX ;; Set flag and go to next CP + JMP TB_CPN_REPEAT ;; Else + ;; +TB_CPN_VALID: ;;;;;; + MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle + MOV CX,WORD PTR CP_TAB_OFFSET+2 ;; Get offset of the code page + MOV DX,WORD PTR CP_TAB_OFFSET ;; in the Keyb Def file + ;; + CMP DX,-1 ;;;;;; Test if code page is blank + JNE TB_CPN_CONTINUE2 ;; + JMP TB_CPN_REPEAT ;; If it is then go get next CP + ;; +TB_CPN_CONTINUE2: ;; + MOV AH,42H ;; LSEEK to table in Keyb Def file + MOV AL,0 ;; If no problem with + INT 21H ;; Keyb Def file Then + JNC TB_CPN_CONTINUE3 ;; + JMP TB_ERROR4 ;; + ;;;;;;;;;; +TB_CPN_CONTINUE3: ;; + MOV DX,AX ;; + MOV WORD PTR SB_STATE_OFFSET+2,CX ;; Save the offset of the + MOV WORD PTR SB_STATE_OFFSET,DX ;; states in Keyb Def file + ;; + MOV CX,TB_CODE_PAGE_PARM ;;;;; If this code page is the + MOV SI,[DESIG_CP_OFFSET] ;; invoked code page + CMP CX,[SI] ;; + JNE TB_CPN_CONTINUE4 ;; Then + ;; + SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + MOV ES:[BP].ACTIVE_XLAT_PTR,DI ;; Set active xlat section + ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;;;;;;; +TB_CPN_CONTINUE4: ;; + SUB DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + MOV ES:[BP].FIRST_XLAT_PTR,DI;; Set flag + ADD DI,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;; +TB_CPN_CONTINUE5: ;; + CALL STATE_BUILD ;; Build state + ;; TABLE_AREA + CMP CX,0 ;; COMMON_XLAT_SECTION + JE TB_CPN_REPEAT ;; SPECIFIC_XLAT_SECTION(S) + JMP TB_ERROR4 ;; DI ---> + ;; +TB_CPN_REPEAT: ;; + MOV CX,RESIDENT_END_ACC ;; + ADD CX,MAX_SPEC_SIZE ;; Refresh resident end size + MOV RESIDENT_END_ACC,CX ;; + ;; + MOV CX,DESIG_CP_OFFSET ;; + ADD CX,2 ;; Adjust offset to find next code page + MOV DESIG_CP_OFFSET,CX ;; + ;; + MOV CX,NUM_DESIG_CP ;; Adjust the number of code pages left + DEC CX ;; + MOV NUM_DESIG_CP,CX ;; + ;; + JMP TB_CPN_BEGIN ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +TB_DONE: ;; + MOV CX,RESIDENT_END_ACC ;; Set final calculated value + ADD CX,BP ;;;;;;;;;;; + SUB CX,SD_AREA_DIFFERENCE ;; Adjust for relocation + MOV ES,WORD PTR SHARED_AREA_PTR ;; Set segment + MOV BP,WORD PTR SHARED_AREA_PTR+2 ;; + CMP CX,ES:[BP].RESIDENT_END ;; + JNA TB_DONE_CONTINUE1 ;;;;;;;;;;; + JMP TB_ERROR5 ;; + ;; +TB_DONE_CONTINUE1: ;; + CMP ES:[BP].RESIDENT_END,-1 ;; + JNE DONT_REPLACE ;; + PUSH CS ;; + POP ES ;; + MOV BP,OFFSET SD_SOURCE_PTR ;; + MOV ES:[BP].RESIDENT_END,CX ;; Save resident end + JMP CONTINUE_2_END ;; + ;; +DONT_REPLACE: ;; + PUSH CS ;; + POP ES ;; + MOV BP,OFFSET SD_SOURCE_PTR ;; + ;; +CONTINUE_2_END: ;; + SUB CX,OFFSET SD_DEST_PTR ;; Calculate # of bytes to copy + MOV SD_LENGTH,CX ;; + ;; + XOR CX,CX ;; Set valid completion return code + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_CPN_INVALID: ;; + CMP CX,1 ;; Set error 1 return code + JNE TB_ERROR2 ;; + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_ERROR2: ;; + CMP CX,2 ;; Set error 2 return code + JNE TB_ERROR3 ;; + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_ERROR3: ;; + CMP CX,3 ;; Set error 3 return code + JNE TB_ERROR4 ;; + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_ERROR4: ;; + CMP CX,4 ;; Set error 4 return code + JNE TB_ERROR5 ;; + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_ERROR5: ;; + MOV CX,5 ;; Set error 5 return code + MOV TB_RETURN_CODE,CX ;; + RET ;; + ;; +TB_ERROR6: ;; + MOV BX,TB_CODE_PAGE_PARM ;; + MOV CX,6 ;; + MOV TB_RETURN_CODE,CX ;; Set error 6 return code + RET ;; + ;; +TABLE_BUILD ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: STATE_BUILD +;; +;; Description: +;; Create the state/xlat section within the specific translate section. +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to our data segment +;; SB_STATE_OFFSET - offset to the beginning of the info in Keyb Def SYS +;; DI - offset of the beginning of the area used to build states +;; +;; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file +;; +;; Output Registers: +;; DI - offset of the end of the area used by STATE_BUILD +;; +;; CX - Return Code := 0 - State build successful +;; 4 - State build unsuccessful +;; (Bad or missing Keyboard Def file) +;; +;; Logic: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +END_OF_AREA_PTR DW 0 ;; +SB_FIRST_STATE DW 0 ;; +SB_STATE_LENGTH DW 0 ;; +SB_STATE_OFFSET DD 0 ;; +STATE_LENGTH DW 0 ;; +RESTORE_BP DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +STATE_BUILD PROC NEAR ;; + ;; + MOV SI,DI ;; Get the tally pointer + MOV END_OF_AREA_PTR,DI ;; Save pointer + ;; + MOV RESTORE_BP,BP ;; Save the base pointer + ;;;;;;;;; + MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle + MOV DX,WORD PTR SB_STATE_OFFSET ;; LSEEK file pointer + MOV CX,WORD PTR SB_STATE_OFFSET+2 ;; back to top of XLAT table + MOV AH,42H ;; + MOV AL,0 ;;;;;;;;; If no problem with + INT 21H ;; Keyboard Def file THEN + JNC SB_FIRST_HEADER ;; + JMP SB_ERROR4 ;; + ;; +SB_FIRST_HEADER: ;; + XOR BP,BP ;; + LEA CX,[BP].KX_FIRST_STATE ;; Set number of bytes to read header + MOV DX,DI ;; + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; read in the header + INT 21H ;; + PUSH CS ;; + POP DS ;; + JNC SB_HEAD_CONTINUE1 ;; + JMP SB_ERROR4 ;; + ;; +SB_HEAD_CONTINUE1: ;; + MOV DX,NEXT_SECT_PTR ;; + CMP DX,-1 ;; + JE SB_HEAD_CONTINUE2 ;; + SUB DX,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;;;;; +SB_HEAD_CONTINUE2: ;; + MOV ES:[DI].XS_NEXT_SECT_PTR,DX ;; + CMP DX,-1 ;; + JE SB_HEAD_CONTINUE3 ;;;;; + ADD DX,SD_AREA_DIFFERENCE ;; Adjust for relocation + ;; +SB_HEAD_CONTINUE3: ;; + ADD DI,CX ;; Update the DI pointer + ;; +SB_NEXT_STATE: ;; + XOR BP,BP ;; Set number + LEA CX,[BP].KX_STATE_ID ;; bytes to read state length + MOV DX,DI ;; Read the header into the + MOV BX,KEYBSYS_FILE_HANDLE ;; SHARED_DATA_AREA + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; + INT 21H ;; + ;; +SB_CONTINUE1: ;; + PUSH CS ;; Reset the data segment + POP DS ;; + MOV CX,ES:[DI].KX_STATE_LEN ;; If the length of the state section + MOV STATE_LENGTH,CX ;; + ADD DI,2 ;; is zero then done + CMP CX,0 ;; + JE SB_DONE ;; + XOR BP,BP ;; Set number + LEA CX,[BP].KX_FIRST_XLAT-2 ;; bytes to read state length + MOV DX,DI ;; Read the header into the + MOV BX,KEYBSYS_FILE_HANDLE ;; SHARED_DATA_AREA + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; + INT 21H ;; + ;; +SB_CONTINUE1A: ;; + PUSH CS ;; Reset the data segment + POP DS ;; + SUB DI,2 ;; + MOV AX,ES:[DI].XS_KBD_TYPE ;; Get the keyboard type def + TEST AX,HW_TYPE ;; Does it match our hardware? + JNZ SB_CONTINUE2 ;; + MOV DX,ES:[DI].XS_STATE_LEN ;; No, then + LEA CX,[BP].KX_FIRST_XLAT ;; + SUB DX,CX ;; + XOR CX,CX ;; + MOV AH,42H ;; LSEEK past this state + MOV AL,01H ;; + INT 21H ;; + JMP SB_NEXT_STATE ;; + ;; +SB_CONTINUE2: ;; Yes, then + MOV AX,SIZE STATE_STR-1 ;; + ADD DI,AX ;; Set PTR and end of header + ;; +SB_XLAT_TAB_BEGIN: ;; Begin getting xlat tables + MOV BX,KEYBSYS_FILE_HANDLE ;; + LEA DX,[BP].KX_FIRST_XLAT ;; Adjust for what we have already read + MOV CX,STATE_LENGTH ;; + SUB CX,DX ;; + MOV DX,DI ;; + PUSH ES ;; + POP DS ;; + MOV AH,3FH ;; Read in the xlat tables + INT 21H ;; + PUSH CS ;; + POP DS ;; + JNC SB_CONTINUE4 ;; + JMP SB_ERROR4 ;; + ;; +SB_CONTINUE4: ;; + CMP CX,AX ;; + JE SB_ERROR_CHECK1 ;; + JMP SB_ERROR4 ;; + ;; +SB_ERROR_CHECK1: ;; + ADD DI,CX ;; Update the end of area ptr + ;; + MOV SI,DI ;; + JMP SB_NEXT_STATE ;; + ;; +SB_DONE: ;; + MOV AX,-1 ;; + MOV SI,END_OF_AREA_PTR ;; + MOV NEXT_SECT_PTR,SI ;; + ;; + MOV BP,RESTORE_BP ;; + RET ;; + ;; +SB_ERROR1: ;; + MOV CX,1 ;; + RET ;; + ;; +SB_ERROR2: ;; + MOV CX,2 ;; + RET ;; + ;; +SB_ERROR3: ;; + MOV CX,3 ;; + RET ;; + ;; +SB_ERROR4: ;; + MOV CX,4 ;; + RET ;; + ;; + ;; +STATE_BUILD ENDP ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Module: FIND_CP_TABLE +;; +;; Description: +;; Determine the offset of the specified code page table in KEYBOARD.SYS +;; +;; Input Registers: +;; DS - points to our data segment +;; ES - points to our data segment +;; AX - ASCII representation of the language parm +;; BX - binary representation of the code page +;; +;; KEYBSYS_FILE_HANDLE - handle of the KEYBOARD.SYS file +;; +;; Output Registers: +;; CP_TAB_OFFSET - offset of the CP table in KEYBOARD.SYS +;; +;; CX - Return Code := 0 - State build successful +;; 2 - Invalid Code page for language +;; 4 - Bad or missing Keyboard Def file +;; Logic: +;; +;; READ language table +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Use table to verify language parm +;; Set pointer values +;; IF code page was specified +;; READ language entry +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; READ Code page table +;; IF error in reading file THEN +;; Display ERROR message and EXIT +;; ELSE +;; Use table to get the offset of the code page parm +;; RET +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FIND_CP_PARM DW ? ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Program Code +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; +FIND_CP_TABLE PROC NEAR ;; + ;; + ;; + MOV FIND_CP_PARM,BX ;; Save Code page + ;;;;;;;;;;;;;; + MOV BX,KEYBSYS_FILE_HANDLE ;; Get handle + MOV DX,WORD PTR KEYBCMD_LANG_ENTRY_PTR ;; LSEEK file pointer + MOV CX,WORD PTR KEYBCMD_LANG_ENTRY_PTR+2 ;; to top of language entry + MOV AH,42H ;; + MOV AL,0 ;;;;;;;;;;;;;; If no problem with + INT 21H ;; Keyb Def file Then + JNC FIND_BEGIN ;; + JMP FIND_CP_ERROR4 ;; + ;;;;;;;;; +FIND_BEGIN: ;; + MOV DI,AX ;; + MOV CX,SIZE KEYBSYS_LANG_ENTRY-1 ;; Set number + ;; bytes to read header + MOV DX,OFFSET FILE_BUFFER ;;;;;;;;; + MOV AH,3FH ;; Read language entry in + INT 21H ;; KEYBOARD.SYS file + JNC FIND_VALID4 ;; If no error in opening file then + JMP FIND_CP_ERROR4 ;; + ;; +FIND_VALID4: ;; +;****************************** CNS ******************************************* + xor ah,ah + mov al,FB.KL_NUM_CP +;****************************** CNS ******************************************* + MOV NUM_CP,AX ;; Save the number of code pages + MUL CP_PTR_SIZE ;; Determine # of bytes to read + MOV DX,OFFSET FILE_BUFFER ;; Establish beginning of buffer + MOV CX,AX ;; + CMP CX,FILE_BUFFER_SIZE ;; Make sure buffer is not to small + JBE FIND_VALID5 ;; + JMP FIND_CP_ERROR4 ;; + ;; +FIND_VALID5: ;; + MOV AH,3FH ;; Read code page table from + INT 21H ;; KEYBOARD.SYS file + JNC FIND_VALID6 ;; If no error in opening file then + JMP FIND_CP_ERROR4 ;; + ;; +FIND_VALID6: ;; + MOV CX,NUM_CP ;; Number of valid codes + MOV DI,OFFSET FILE_BUFFER ;; Point to correct word in table + ;; +F_SCAN_CP_TABLE: ;; FOR code page parm + MOV AX,FIND_CP_PARM ;; Get parameter + CMP [DI].KC_CODE_PAGE,AX ;; Valid Code ?? + JE F_CODE_PAGE_FOUND ;; If not found AND more entries THEN + ADD DI,LANG_PTR_SIZE ;; Check next entry + DEC CX ;; Decrement count of entries + JNE F_SCAN_CP_TABLE ;; Else + JMP FIND_CP_ERROR2 ;; Display error message + ;;;;;;;;;; +F_CODE_PAGE_FOUND: ;; + MOV AX,WORD PTR [DI].KC_ENTRY_PTR ;; + MOV WORD PTR CP_TAB_OFFSET,AX ;; + MOV AX,WORD PTR [DI].KC_ENTRY_PTR+2 ;; + MOV WORD PTR CP_TAB_OFFSET+2,AX ;; + ;; + XOR CX,CX ;;;;;;;;;; + RET ;; + ;; +FIND_CP_ERROR1: ;; + MOV CX,1 ;; + RET ;; + ;; +FIND_CP_ERROR2: ;; + MOV CX,2 ;; + RET ;; + ;; +FIND_CP_ERROR3: ;; + MOV CX,3 ;; + RET ;; + ;; +FIND_CP_ERROR4: ;; + MOV CX,4 ;; + RET ;; + ;; +FIND_CP_TABLE ENDP ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +CODE ENDS + END TABLE_BUILD + \ No newline at end of file diff --git a/v4.0/src/CMD/KEYB/KEYBTBBL.INC b/v4.0/src/CMD/KEYB/KEYBTBBL.INC new file mode 100644 index 0000000..c5ea73a --- /dev/null +++ b/v4.0/src/CMD/KEYB/KEYBTBBL.INC @@ -0,0 +1,33 @@ + +.XLIST + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; DOS - NLS Support - KEYB Command +;; (C) Copyright 1988 Microsoft +;; +;; File Name: KEYBTBBL.INC +;; ---------- +;; +;; Description: +;; ------------ +;; Include file containing structure definitions Shared Data Area +;; for the Shared Data Area. +;; The Shared Data Area contains data which is required by +;; both the resident and transient KEYB code. The Shared +;; Data Area is allocated in the KEYBI2F file and will be +;; resident following initial installation. +;; +;; Change History: +;; --------------- +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; + EXTRN TABLE_BUILD :NEAR ;; + EXTRN FIND_CP_TABLE :NEAR ;; + ;; + EXTRN CPN_INVALID :WORD ;; + EXTRN SD_LENGTH :WORD ;; + ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.LIST diff --git a/v4.0/src/CMD/KEYB/MAKEFILE b/v4.0/src/CMD/KEYB/MAKEFILE new file mode 100644 index 0000000..509b679 --- /dev/null +++ b/v4.0/src/CMD/KEYB/MAKEFILE @@ -0,0 +1,72 @@ +#************************* Makefile for KEYB ************************* + +inc =..\..\inc +msg =..\..\messages +dos =..\..\dos +hinc =..\..\h + +# +###################### Dependencies begin here. ###################### +# + +all: keyb.com + +keyb.ctl: keyb.skl $(msg)\$(COUNTRY).msg + +keybcmd.obj: keybcmd.asm \ + $(inc)\struc.inc \ + $(inc)\sysmsg.inc \ + $(inc)\versiona.inc \ + keybequ.inc \ + keybsys.inc \ + keybi9.inc \ + keybi9c.inc \ + keybi2f.inc \ + keybi48.inc \ + keybshar.inc \ + keyb.ctl \ + keyb.cl1 \ + keyb.cl2 \ + keyb.cla \ + keybdcl.inc \ + keybtbbl.inc \ + commsubs.inc \ + keybcpsd.inc \ + $(inc)\postequ.inc \ + $(inc)\dseg.inc + +keybtbbl.obj: keybtbbl.asm + +commsubs.obj: commsubs.asm + +keybi2f.obj: keybi2f.asm + +keybi48.obj: keybi48.asm + +keyb.obj: keyb.asm + +keybcpsd.obj: keybcpsd.asm + +keybi9.obj: keybi9.asm + +keybi9c.obj: keybi9c.asm + +parser.obj: parser.asm \ + $(inc)\parse.asm \ + $(inc)\struc.inc \ + keybdcl.inc \ + makefile + +keyb.com: keyb.obj \ + parser.obj \ + keybcmd.obj \ + keybtbbl.obj \ + commsubs.obj \ + keybi2f.obj \ + keybi48.obj \ + keybcpsd.obj \ + keybi9.obj \ + keybi9c.obj + link @keyb.lnk + exe2bin keyb.exe keyb.com + del keyb.exe diff --git a/v4.0/src/CMD/KEYB/PARSER.ASM b/v4.0/src/CMD/KEYB/PARSER.ASM new file mode 100644 index 0000000..808f37a --- /dev/null +++ b/v4.0/src/CMD/KEYB/PARSER.ASM @@ -0,0 +1,517 @@ +PAGE ,132 +TITLE PARSE CODE AND CONTROL BLOCKS FOR KEYB.COM + +;****************** START OF SPECIFICATIONS ************************** +; +; MODULE NAME: PARSER.ASM +; +; DESCRIPTIVE NAME: PARSES THE COMMAND LINE PARAMETERS FOR KEYB.COM +; +; FUNCTION: THE COMMAND LINE IN THE PSP IS PARSED FOR PARAMETERS. +; +; ENTRY POINT: PARSE_PARAMETERS +; +; INPUT: BP POINTS TO PARAMETER LIST +; DS & ES POINT TO PSP +; +; AT EXIT: +; PARAMETER LIST FILLED IN AS REQUIRED. +; +; INTERNAL REFERENCES: +; +; ROUTINES: SYSPARSE - PARSING CODE +; +; DATA AREAS: PARMS - PARSE CONTROL BLOCK FOR SYSPARSE +; +; EXTERNAL REFERENCES: +; +; ROUTINES: N/A +; +; DATA AREAS: PARAMETER LIST BLOCK TO BE FILLED. +; +; NOTES: +; +; REVISION HISTORY: +; A000 - DOS Version 4.00 +; 3/24/88 AN003 - P3906 PARSER changes to return "bogus" parameter on the +; "Parameter value not allowed " message - CNS +; 5/12/88 AN004 - P4867 /ID:NON-Numeric hangs the sytem as a 1st positional +; +; COPYRIGHT: "The KEYB.COM Keyboard Driver" +; "Version 4.00 (C) Copyright 1988 Microsoft" +; "Licensed Material - Program Property of Microsoft" +; +; PROGRAM AUTHOR: WGR +; +;****************** END OF SPECIFICATIONS **************************** + +INCLUDE KEYBDCL.INC ;AN000 + +ID_VALID EQU 0 ;AN000; ;AN000 +ID_INVALID EQU 1 ;AN000; ;AN000 +NO_ID EQU 2 ;AN000; ;AN000 + +LANGUAGE_VALID EQU 0 ;AN000; ;AN000 +LANGUAGE_INVALID EQU 1 ;AN000; ;AN000 +NO_LANGUAGE EQU 2 ;AN000; ;AN000 + +NO_IDLANG EQU 3 ;AN000; ;AN000 + +CODE_PAGE_VALID EQU 0 ;AN000; ;AN000 +CODE_PAGE_INVALID EQU 1 ;AN000; ;AN000 +NO_CODE_PAGE EQU 2 ;AN000; ;AN000 +VALID_SYNTAX EQU 0 ;AN000; ;AN000 +INVALID_SYNTAX EQU 1 ;AN000; ;AN000 + +COMMAND_LINE_START EQU 81H ;AN000; ;AN000 +RC_EOL EQU -1 ;AN000; ;AN000 +RC_NO_ERROR EQU 0 ;AN000; ;AN000 +RC_OP_MISSING EQU 2 ;AN000; ;AN000 +RC_NOT_IN_SW EQU 3 ;AN000; ;AN000 +;***CNS P4867 1st CHECK for /ID:ALPHA +RC_SW_FIRST EQU 9 ;AN004; ;AN000 +;***CNS P4867 1st CHECK for /ID:ALPHA +ERROR_COND EQU -1 ;AN000; ;AN000 +NUMBER EQU 1 ;AN000; ;AN000 +STRING EQU 3 ;AN000; ;AN000 +FILE_SPEC EQU 5 ;AN000; ;AN000 +MAX_ID EQU 999 ;AN000; ;AN000 +LANG_LENGTH EQU 2 ;AN000; ;AN000 + +INVALID_SWITCH EQU 3 +TOO_MANY EQU 1 +INVALID_PARAM EQU 10 +VALUE_DISALLOW EQU 8 + +.XLIST +INCLUDE STRUC.INC ; Structured macros ;AN000 +.LIST + +PUBLIC PARSE_PARAMETERS ;AN003;; near procedure for parsing command line ;AN000 +PUBLIC CUR_PTR ;AN003;; near procedure for parsing command line ;AN000 +PUBLIC OLD_PTR ;AN003;; near procedure for parsing command line ;AN000 +PUBLIC ERR_PART;AN003;; near procedure for parsing command line ;AN000 +EXTRN BAD_ID:BYTE ;; WGR to match old code ;AN000; ;AN000 +EXTRN FOURTH_PARM:BYTE ;; WGR to match old code ;AN000; ;AN000 +EXTRN ONE_PARMID:BYTE ;; WGR to match old code ;AN000; ;AN000 +EXTRN FTH_PARMID:BYTE ;; WGR to match old code ;AN000; ;AN000 +EXTRN ALPHA:BYTE ;; WGR to match old code ;AN000; ;AN000 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Set assemble switches for parse code that is not required!! +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +DateSW EQU 0 ;AN000; ;AN000 +TimeSW EQU 0 ;AN000; ;AN000 +CmpxSW EQU 0 ;AN000; ;AN000 +DrvSW EQU 0 ;AN000; ;AN000 +QusSW EQU 0 ;AN000; ;AN000 +KeySW EQU 0 ;AN000; ;AN000 +Val1SW EQU 0 ;AN000; ;AN000 +Val2SW EQU 0 ;AN000; ;AN000 +Val3SW EQU 0 ;AN000; ;AN000 + + +CODE SEGMENT PUBLIC 'CODE' BYTE ;AN000; ;AN000 + ASSUME CS:CODE,DS:CODE ;AN000; ;AN000 + +.XLIST +INCLUDE PARSE.ASM ; Parsing code ;AN000 +.LIST + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PARM control blocks for KEYB +; Parsing command line as follows: +; +; KEYB [lang],[cp],[[d:][path]KEYBOARD.SYS][/ID:id] +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +PARMS LABEL WORD ;AN000; ;AN000 + DW PARMSX ;AN000; ;AN000 + DB 0 ;AN000;; no extra delimeters or EOLs. ;AN000 + +PARMSX LABEL BYTE ;AN000; ;AN000 + DB 0,3 ;AN000;; min,max positional operands ;AN000 + DW LANG ;AN000;; pointer to control block ;AN000 + DW CP ;AN000;; pointer to control block ;AN000 + DW FILE_NAME ;AN000;; pointer to control block ;AN000 + DB 1 ;AN000;; 1 switch ;AN000 + DW ID_VALUE ;AN000;; pointer to control block ;AN000 + DB 0 ;AN000;; no keywords ;AN000 + +LANG LABEL WORD ;AN000; ;AN000 + DW 0A001H ;AN000;; sstring or numeric value (optional) ;AN000 + DW 0002H ;AN000;; cap result by char table (sstring) ;AN000 + DW RESULT_BUF ;AN000;; result ;AN000 + DW NOVALS ;AN000;; no value checking done ;AN000 + DB 0 ;AN000;; no keyword/switch synonyms ;AN000 + +CP LABEL WORD ;AN000; ;AN000 + DW 8001H ;AN000;; numeric ;AN000 + DW 0 ;AN000;; no functions ;AN000 + DW RESULT_BUF ;AN000;; result ;AN000 + DW NOVALS ;AN000;; no value checking done ;AN000 + DB 0 ;AN000;; no keyword/switch synonyms ;AN000 + +FILE_NAME LABEL WORD ;AN000; ;AN000 + DW 0201H ;AN000;; file spec ;AN000 + DW 0001H ;AN000;; cap by file table ;AN000 + DW RESULT_BUF ;AN000;; result ;AN000 + DW NOVALS ;AN000;; no value checking done ;AN000 + DB 0 ;AN000;; no keyword/switch synonyms ;AN000 + +ID_VALUE LABEL WORD ;AN000; ;AN000 + DW 8010H ;AN000;; numeric ;AN000 + DW 0 ;AN000;; no functions ;AN000 + DW RESULT_BUF ;AN000;; result ;AN000 + DW NOVALS ;AN000;; no value checking done ;AN000 + DB 1 ;AN000;; 1 switch synonym ;AN000 + DB "/ID",0 ;AN000;; ID switch ;AN000 + +NOVALS LABEL BYTE ;AN000; ;AN000 + DB 0 ;AN000;; no value checking done ;AN000 + +RESULT_BUF LABEL BYTE ;AN000; ;AN000 +RESULT_TYPE DB 0 ;AN000;; type returned (number, string, etc.) ;AN000 + DB ? ;AN000;; matched item tag (if applicable) ;AN000 +RESULT_SYN_PTR DW ? ;AN000;; synonym ptr (if applicable) ;AN000 +RESULT_VAL DD ? ;AN000;; value ;AN000 + +LOOP_COUNT DB 0 ;AN000;; keeps track of parameter position ;AN000 +;***CNS +CUR_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000 +OLD_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000 +ERR_PART DW 0 ;AN003;; keeps track of parameter position ;AN000 +;***CNS + ;AN000;; ..and reports an error condition ;AN000 +TEMP_FILE_NAME DB 128 DUP(0) ;AN000;; place for file name ;AN000 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: PARSE_PARAMETERS +; +; FUNCTION: +; THIS PROCEDURE PARSES THE COMMAND LINE PARAMETERS IN THE PSP FOR +; KEYB.COM. THE PARAMETER LIST BLOCK IS FILLED IN ACCORDINGLY. +; +; AT ENTRY: AS ABOVE. +; +; AT EXIT: +; AS ABOVE. +; +; AUTHOR: WGR +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +PARSE_PARAMETERS PROC NEAR ;AN000 + XOR AX,AX ;AN000;; setup default parameters. ;AN000 + MOV [BP].RET_CODE_1,NO_IDLANG ;AN000;; ;AN000 + MOV [BP].RET_CODE_2,NO_CODE_PAGE ;AN000;; ;AN000 + MOV [BP].RET_CODE_3,VALID_SYNTAX ;AN000;; ;AN000 + MOV [BP].RET_CODE_4,NO_ID ;AN000;; ;AN000 + MOV [BP].PATH_LENGTH,AX ;AN000;; ;AN000 + LEA DI,PARMS ;AN000;; setup parse blocks ;AN000 + MOV SI,COMMAND_LINE_START ;AN000;; ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment + +;***CNS + XOR CX,CX ;AN000;; ;AN000 + XOR DX,DX ;AN000;; ;AN000 + CALL SYSPARSE ;AN000;; ;AN000 + .WHILE near AND ;AN000;; while not end of line and.. ;AN000 + .WHILE near ;AN000;; parameters valid do. ;AN000 + .IF near OR ;AN000;; invalid switch? ;AN000 + .IF near ;AN000;; invalid switch? ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; set invalid syntax flag. ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set error flag to exit parse. ;AN000 +;***CNS + MOV ERR_PART,INVALID_SWITCH + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment + +;***CNS + .ELSE ;AN000;; ;AN000 + .IF ;AN000;; was the switch found? ;AN000 + MOV AX,WORD PTR RESULT_VAL+2 ;AN000;; is it valid? ;AN000 + OR AX,AX ;AN000;; ;AN000 + .IF NZ OR ;AN000;; ;AN000 + MOV AX,WORD PTR RESULT_VAL ;AN000;; ;AN000 + .IF ;AN000;; ;AN000 + MOV [BP].RET_CODE_1,ID_INVALID ;AN000;; no...invalid id. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error. ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse ;AN000 + mov bad_id,1 ;AN000;; ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment + +;***CNS + .ELSE ;AN000;; ;AN000 + MOV [BP].RET_CODE_4,ID_VALID ;AN000;; yes...set return code 4. ;AN000 + MOV [BP].ID_PARM,AX ;AN000;; ;AN000 + mov fourth_parm,1 ;AN000;; ;AN000 + mov fth_parmid,1 ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + .ELSE ;AN000;; ;AN000 + INC LOOP_COUNT ;AN000;; positional encountered... ;AN000 + .SELECT ;AN000;; ;AN000 + .WHEN ;AN000;; check for language ;AN000 + CALL PROCESS_1ST_PARM ;AN000;; ;AN000 + +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment +;***CNS + + + .WHEN ;AN000;; check for code page ;AN000 + CALL PROCESS_2ND_PARM ;AN000;; ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment +;***CNS + .WHEN ;AN000;; check for file name ;AN000 + CALL PROCESS_3RD_PARM ;AN000;; ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment +;***CNS + .OTHERWISE ;AN000;; ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; too many parms ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment +;***CNS + MOV ERR_PART,TOO_MANY + MOV LOOP_COUNT,ERROR_COND ;AN000;; set error flag to exit parse. ;AN000 + .ENDSELECT ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + MOV RESULT_TYPE,0 ;AN000;; reset result block. ;AN000 + CALL SYSPARSE ;AN000;; parse next parameter. ;AN000 + .ENDIF ;AN000;; ;AN000 + .ENDWHILE ;AN000;; ;AN000 + .IF <[BP].RET_CODE_4 EQ ID_VALID> AND ;AN000;; ensure that if the switch ;AN000 + .IF <[BP].RET_CODE_1 NE LANGUAGE_VALID> ;AN000;; was used..that a valid keyboard ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; code was used.. ;AN000 +;***CNS + + PUSH AX ;AN003;Save environment + MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument + MOV OLD_PTR,AX ;AN003;after saving the beginning the string + MOV CUR_PTR,SI ;AN003; + POP AX ;AN003;Restore the environment + MOV ERR_PART,VALUE_DISALLOW +;***CNS + .ENDIF ;AN000;; ;AN000 + RET ;AN000;; ;AN000 +PARSE_PARAMETERS ENDP ;AN000; ;AN000 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: PROCESS_1ST_PARM +; +; FUNCTION: +; THIS PROCEDURE PROCESSES THE FIRST POSITIONAL PARAMETER. THIS SHOULD +; BE THE LANGUAGE ID OR THE KEYBOARD ID. +; +; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR. +; +; AT EXIT: +; PARAMETER CONTROL BLOCK UPDATED FOR LANGUAGE ID. +; +; AUTHOR: WGR +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +PROCESS_1ST_PARM PROC NEAR ;AN000 + .IF ;AN000;; error on parse? ;AN000 + MOV [BP].RET_CODE_1,LANGUAGE_INVALID ;AN000;; yes...set invalid language ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; and syntax error.. ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse. ;AN000 + MOV ERR_PART,AX ;AN003;; + .ELSE near ;AN000;; ;AN000 + + .IF ;AN000;; was this a number (id)? ;AN000 + MOV AX,WORD PTR RESULT_VAL+2 ;AN000;; yes...check to see if ;AN000 + OR AX,AX ;AN000;; within range. ;AN000 + .IF NZ OR ;AN000;; ;AN000 + MOV AX,WORD PTR RESULT_VAL ;AN000;; ;AN000 + .IF ;AN000;; ;AN000 + MOV [BP].RET_CODE_1,ID_INVALID ;AN000;; no...invalid id. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error. ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse ;AN000 + mov bad_id,1 ;AN000;; ;AN000 + .ELSE ;AN000;; ;AN000 + MOV [BP].RET_CODE_1,ID_VALID ;AN000;; valid id...set ;AN000 + MOV [BP].RET_CODE_4,ID_VALID ;AN000;; valid id...set ;AN000 + MOV [BP].ID_PARM,AX ;AN000;; and value moved into block ;AN000 + MOV LOOP_COUNT,4 ;AN000;; there should be no more parms ;AN000 + mov one_parmid,1 ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + .ELSEIF ;AN000;; must be a string then.. ;AN000 + PUSH SI ;AN000;; ;AN000 + PUSH DI ;AN000;; ;AN000 + PUSH CX ;AN000;; ;AN000 + PUSH DS ;AN000;; ;AN000 + LDS SI,RESULT_VAL ;AN000;; get ptr to string ;AN000 + MOV DI,BP ;AN000;; ;AN000 + ADD DI,LANGUAGE_PARM ;AN000;; point to block for copy. ;AN000 + MOV CX,LANG_LENGTH ;AN000;; maximum length = 2 ;AN000 + LODSB ;AN000;; load AL with 1st char.. ;AN000 + .WHILE AND ;AN000;; do twice....unless ;AN000 + .WHILE ;AN000;; there is only 1 character. ;AN000 + STOSB ;AN000;; store ;AN000 + DEC CX ;AN000;; dec count ;AN000 + LODSB ;AN000;; load ;AN000 + .ENDWHILE ;AN000;; ;AN000 + .IF OR ;AN000;; if there was less than 2 or.. ;AN000 + .IF ;AN000;; greater than 2 characters then.. ;AN000 + MOV [BP].RET_CODE_1,LANGUAGE_INVALID ;AN000;; invalid. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error ;AN000 + MOV ERR_PART,INVALID_PARAM + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse. ;AN000 + .ELSE ;AN000;; ;AN000 + MOV [BP].RET_CODE_1,LANGUAGE_VALID ;AN000;; valid language has been copied ;AN000 + MOV ALPHA,1 ;AN000;; language found ;AN000 + .ENDIF ;AN000;; ;AN000 + POP DS ;AN000;; ;AN000 + POP CX ;AN000;; ;AN000 + POP DI ;AN000;; ;AN000 + POP SI ;AN000;; ;AN000 + .ELSE ;AN000;; ommited parameter... ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; invalid since further parameters.;AN000 + .ENDIF ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + RET ;AN000;; ;AN000 +PROCESS_1ST_PARM ENDP ;AN000; ;AN000 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: PROCESS_2ND_PARM +; +; FUNCTION: +; THIS PROCEDURE PROCESSES THE 2ND POSITIONAL PARAMETER. THIS SHOULD +; BE THE CODE PAGE, IF REQUESTED. +; +; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR. +; +; AT EXIT: +; PARAMETER CONTROL BLOCK UPDATED FOR CODE PAGE. +; +; AUTHOR: WGR +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +PROCESS_2ND_PARM PROC NEAR ;AN000 + .IF ;AN000;; if parse error.. ;AN000 + MOV [BP].RET_CODE_2,CODE_PAGE_INVALID ;AN000;; mark invalid.. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse ;AN000 + MOV ERR_PART,AX ;AN003;; + .ELSE ;AN000;; ;AN000 + .IF ;AN000;; was parameter specified? ;AN000 + MOV AX,WORD PTR RESULT_VAL+2 ;AN000;; yes..if code page not.. ;AN000 + OR AX,AX ;AN000;; ;AN000 + .IF NZ OR ;AN000;; ;AN000 + MOV AX,WORD PTR RESULT_VAL ;AN000;; valid..then ;AN000 + .IF ;AN000;; ;AN000 + MOV [BP].RET_CODE_2,CODE_PAGE_INVALID ;AN000;; mark invalid.. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse ;AN000 + .ELSE ;AN000;; ;AN000 + MOV [BP].RET_CODE_2,CODE_PAGE_VALID;AN000;; else...valid code page ;AN000 + MOV [BP].CODE_PAGE_PARM,AX ;AN000;; move into parm ;AN000 + .ENDIF ;AN000;; ;AN000 + .ELSE ;AN000;; ;AN000 + MOV [BP].RET_CODE_2,NO_CODE_PAGE ;AN000;; mark as not specified. ;AN000 + .ENDIF ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + RET ;AN000;; ;AN000 +PROCESS_2ND_PARM ENDP ;AN000; ;AN000 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: PROCESS_3RD_PARM +; +; FUNCTION: +; THIS PROCEDURE PROCESSES THE 3RD POSITIONAL PARAMETER. THIS SHOULD +; BE THE KEYBOARD DEFINITION FILE PATH, IF SPECIFIED. +; +; AT ENTRY: PARSE RESULT BLOCK CONTAINS VALUES IF AX HAS NO ERROR. +; +; AT EXIT: +; PARAMETER CONTROL BLOCK UPDATED FOR FILE NAME. +; +; AUTHOR: WGR +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +PROCESS_3RD_PARM PROC NEAR ;AN000; ;AN000 + .IF ;AN000;; if parse error then.. ;AN000 + MOV [BP].RET_CODE_3,INVALID_SYNTAX ;AN000;; syntax error. ;AN000 + MOV LOOP_COUNT,ERROR_COND ;AN000;; set flag to exit parse ;AN000 + MOV ERR_PART,AX ;AN003;; + .ELSE ;AN000;; ;AN000 + .IF ;AN000;; ;AN000 + PUSH DS ;AN000;; ;AN000 + PUSH SI ;AN000;; ;AN000 + PUSH DI ;AN000;; ;AN000 + PUSH CX ;AN000;; ;AN000 + LDS SI,RESULT_VAL ;AN000;; load offset of file name ;AN000 + LEA DI,TEMP_FILE_NAME ;AN000;; ;AN000 + MOV [BP].PATH_OFFSET,DI ;AN000;; copy to parameter block ;AN000 + XOR CX,CX ;AN000;; ;AN000 + LODSB ;AN000;; count the length of the path. ;AN000 + .WHILE ;AN000;; ;AN000 + STOSB ;AN000;; ;AN000 + LODSB ;AN000;; ;AN000 + INC CX ;AN000;; ;AN000 + .ENDWHILE ;AN000;; ;AN000 + MOV [BP].PATH_LENGTH,CX ;AN000;; copy to parameter block ;AN000 + POP CX ;AN000;; ;AN000 + POP DI ;AN000;; ;AN000 + POP SI ;AN000;; ;AN000 + POP DS ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + .ENDIF ;AN000;; ;AN000 + RET ;AN000;; ;AN000 +PROCESS_3RD_PARM ENDP ;AN000; ;AN000 + ;AN000; +CODE ENDS ;AN000; + END ;AN000; -- cgit v1.2.3