Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

694 lines
26 KiB

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