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
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
|