|
|
PAGE ,132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; (C) Copyright Microsoft Corp. 1987-1990 ; MS-DOS 5.00 - NLS Support - KEYB Command ; ; 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. ; ; ; 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
PUBLIC FLAGS_TO_TEST ;; (YST) PUBLIC NLS_FLAG_1 ;; (YST)
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 RESET_NLS1_PROC ; C DW OFFSET UNKNOWN_COMMAND ; D DW OFFSET UNKNOWN_COMMAND ; E DW OFFSET UNKNOWN_COMMAND ; F
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KEYB_STATE_PROCESSOR PROC NEAR
TEST byte ptr CS:SD.TABLE_OK,1 JNZ WE_HAVE_A_TABLE CLC ; BACK TO US INT 9 RET 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 xor si,si ; pointers to the BIOS flags xor di,di ; 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: XOR BH,BH ; ???? 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 short 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 jcxz next_xlat_tab ; brif last entry 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 short 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
MOV COPY_NLS1_FLAG,0 ;; (YST)
RN_DONE: INC SI JMP NEXT_COMMAND ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; This PROC only for Yugoslavian (Cyrillic) ;; keyboard from CRAZY IBM (YST) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RESET_NLS1_PROC: ;; MOV AL,NEST_LEVEL ;; CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? JNE RN1_DONE ;; N..don't process MOV NLS_FLAG_1, 1 ;; MOV NLS_FLAG_2,0 ;; MOV COPY_NLS1_FLAG, 1 ;; (YST) RN1_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 jcxz sf_restore ; done if no entries 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
MOV AL,NLS_FLAG_1 ;; copy NLS_FLAG_1 to the (YST) MOV COPY_NLS1_FLAG,AL ;; public place (YST)
TEST OPTION_BYTE,EXIT_IF_FOUND ; Q..exit JZ SF_RESTORE POP SI JMP short 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
|