diff options
Diffstat (limited to 'v4.0/src/CMD/KEYB/KEYBI9.ASM')
| -rw-r--r-- | v4.0/src/CMD/KEYB/KEYBI9.ASM | 672 |
1 files changed, 672 insertions, 0 deletions
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 @@ | |||
| 1 | |||
| 2 | PAGE ,132 | ||
| 3 | TITLE DOS KEYB Command - Interrupt 9 Non-US Support | ||
| 4 | |||
| 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 6 | ;; DOS - NLS Support - KEYB Command | ||
| 7 | ;; (C) Copyright 1988 Microsoft | ||
| 8 | ;; | ||
| 9 | ;; File Name: KEYBI9.ASM | ||
| 10 | ;; ---------- | ||
| 11 | ;; | ||
| 12 | ;; Description: | ||
| 13 | ;; ------------ | ||
| 14 | ;; Converts scan codes to ASCII for non-US keyboards. | ||
| 15 | ;; This orutine uses the tables loaded into the SHARED_DATA_AREA | ||
| 16 | ;; from KEYBOARD.SYS by the KEYB_COMMAND module. | ||
| 17 | ;; | ||
| 18 | ;; Documentation Reference: | ||
| 19 | ;; ------------------------ | ||
| 20 | ;; PC DOS 3.3 Detailed Design Document - May 1986 | ||
| 21 | ;; | ||
| 22 | ;; Procedures Contained in This File: | ||
| 23 | ;; ---------------------------------- | ||
| 24 | ;; KEYB_STATE_PROCESSOR - Scan to ASCII translator. | ||
| 25 | ;; | ||
| 26 | ;; External Procedure References: | ||
| 27 | ;; ------------------------------ | ||
| 28 | ;; None. | ||
| 29 | ;; | ||
| 30 | ;; Linkage Information: Refer to file KEYB.ASM | ||
| 31 | ;; -------------------- | ||
| 32 | ;; | ||
| 33 | ;; Change History: | ||
| 34 | ;; --------------- | ||
| 35 | ;; | ||
| 36 | ;; | ||
| 37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 38 | ;; | ||
| 39 | ;**** | ||
| 40 | INCLUDE KEYBEQU.INC ;; | ||
| 41 | INCLUDE DSEG.inc ;; System data segments | ||
| 42 | INCLUDE POSTEQU.inc ;; System equates | ||
| 43 | INCLUDE KEYBSHAR.INC ;; | ||
| 44 | INCLUDE KEYBI2F.INC ;; | ||
| 45 | INCLUDE KEYBI9C.INC ;; | ||
| 46 | INCLUDE KEYBCPSD.INC ;; | ||
| 47 | INCLUDE KEYBCMD.INC ;; | ||
| 48 | ;; | ||
| 49 | PUBLIC KEYB_STATE_PROCESSOR ;; | ||
| 50 | ;; | ||
| 51 | CODE SEGMENT PUBLIC 'CODE' ;; | ||
| 52 | ;; | ||
| 53 | ASSUME CS:CODE,DS:CODE ;; | ||
| 54 | ;; | ||
| 55 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 56 | ;; | ||
| 57 | ;; Procedure: KEYB_STATE_PROCESSOR | ||
| 58 | ;; | ||
| 59 | ;; Description: | ||
| 60 | ;; Convert scan to ASCII using the tables loaded into the | ||
| 61 | ;; SHARED_DATA_AREA. Conversion is directed by the STATE LOGIC | ||
| 62 | ;; commands contained in the SHARED_DATA_AREA. This routine | ||
| 63 | ;; interprets those commands. | ||
| 64 | ;; | ||
| 65 | ;; Input Registers: | ||
| 66 | ;; N/A | ||
| 67 | ;; | ||
| 68 | ;; Output Registers: | ||
| 69 | ;; N/A | ||
| 70 | ;; | ||
| 71 | ;; Logic: | ||
| 72 | ;; Enable interrupts | ||
| 73 | ;; Save registers | ||
| 74 | ;; | ||
| 75 | ;; | ||
| 76 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 77 | ;; | ||
| 78 | BREAK_CODE EQU 80H ;; | ||
| 79 | ;; | ||
| 80 | HOT_KEY_ACTIVE DB 0 ;; 1 if hot key is active | ||
| 81 | ;; | ||
| 82 | ;; | ||
| 83 | ;; These are copies of the BIOS FLAGS | ||
| 84 | FLAGS_TO_TEST LABEL BYTE ;; KB_FLAG, KB_FLAG_1,2,3 | ||
| 85 | KB_SHADOW_FLAGS DB NUM_BIOS_FLAGS DUP(0) ;; | ||
| 86 | EXT_KB_FLAG DB 0 ;; Extended KB Flag for shift states | ||
| 87 | NLS_FLAG_1 DB 0 ;; NLS Flags for dead key etc | ||
| 88 | NLS_FLAG_2 DB 0 ;; . | ||
| 89 | ;; | ||
| 90 | SAVED_NLS_FLAGS DB 0,0 ;; Saved copy of the NLS flags | ||
| 91 | ;; | ||
| 92 | OPTION_BYTE DB 0 ;; Set by OPTION command | ||
| 93 | ;; | ||
| 94 | KB_FLAG_PTRS DW OFFSET KB_FLAG ;; These are pointers to the BIOS flags | ||
| 95 | DW OFFSET KB_FLAG_1 ;; we must test | ||
| 96 | DW OFFSET KB_FLAG_2 ;; | ||
| 97 | DW OFFSET KB_FLAG_3 ;; | ||
| 98 | ;; | ||
| 99 | XLAT_TAB_PTR DW 0 ;; pointer to xlat tables for cur state | ||
| 100 | ;; | ||
| 101 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 102 | |||
| 103 | |||
| 104 | NEST_LEVEL DB 0 ;; | ||
| 105 | PROCESS_LEVEL DB 0 ;; | ||
| 106 | TAKE_ELSE DB 0 ;; | ||
| 107 | BUSY_FLAG DB 0 ;; Flag to prevent re-entry | ||
| 108 | ;; | ||
| 109 | CMD_JUMP_TABLE LABEL WORD ;; | ||
| 110 | DW OFFSET IFF_PROC ;; CODE 0 | ||
| 111 | DW OFFSET ANDF_PROC ;; 1 | ||
| 112 | DW OFFSET ELSEF_PROC ;; 2 | ||
| 113 | DW OFFSET ENDIFF_PROC ;; 3 | ||
| 114 | DW OFFSET XLATT_PROC ;; 4 | ||
| 115 | DW OFFSET OPTION_PROC ;; 5 | ||
| 116 | DW OFFSET SET_FLAG_PROC ;; 6 | ||
| 117 | DW OFFSET PUT_ERROR_PROC ;; 7 | ||
| 118 | DW OFFSET IFKBD_PROC ;; 8 | ||
| 119 | DW OFFSET GOTO_PROC ;; 9 | ||
| 120 | DW OFFSET BEEP_PROC ;; A | ||
| 121 | DW OFFSET RESET_NLS_PROC ;; B | ||
| 122 | DW OFFSET UNKNOWN_COMMAND ;; C | ||
| 123 | DW OFFSET UNKNOWN_COMMAND ;; D | ||
| 124 | DW OFFSET UNKNOWN_COMMAND ;; E | ||
| 125 | DW OFFSET UNKNOWN_COMMAND ;; F | ||
| 126 | ;; | ||
| 127 | ;; | ||
| 128 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 129 | ;; | ||
| 130 | KEYB_STATE_PROCESSOR PROC NEAR ;; | ||
| 131 | ;; | ||
| 132 | TEST CS:SD.TABLE_OK,1 ;; | ||
| 133 | JNZ WE_HAVE_A_TABLE ;; | ||
| 134 | CLC ;; BACK TO US INT 9 | ||
| 135 | RET ;; | ||
| 136 | |||
| 137 | EVEN | ||
| 138 | |||
| 139 | WE_HAVE_A_TABLE: ;; | ||
| 140 | |||
| 141 | PUSH DS ;; save DS | ||
| 142 | PUSH ES ;; save ES | ||
| 143 | PUSH AX ;; save scan code for caller | ||
| 144 | PUSH BX ;; save shift states for caller | ||
| 145 | |||
| 146 | PUSH CS ;; | ||
| 147 | POP DS ;; DS = our seg | ||
| 148 | MOV BX,DATA ;; | ||
| 149 | MOV ES,BX ;; addressability to BIOS data | ||
| 150 | ;; | ||
| 151 | ;; | ||
| 152 | CMP COUNTRY_FLAG,0FFH ;; Q..country mode? | ||
| 153 | JE INIT_STATE_PROCESSING ;; Y..continue | ||
| 154 | JMP GOTO_BIOS ;; N..exit | ||
| 155 | ;; | ||
| 156 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 157 | ;; -------STATE SECTION PROCESSING------- | ||
| 158 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 159 | ;; | ||
| 160 | INIT_STATE_PROCESSING: ;; | ||
| 161 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 162 | ;; Set NLS shift flags EITHER_SHIFT, EITHER_ALT, EITHER_CTRL | ||
| 163 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 164 | ;; | ||
| 165 | ;; Q..in shift state? | ||
| 166 | TEST ES:KB_FLAG,RIGHT_SHIFT+LEFT_SHIFT | ||
| 167 | JNZ IN_SHIFT_STATE ;; Y..go set bit | ||
| 168 | AND EXT_KB_FLAG,NOT EITHER_SHIFT ;; N..clear bit | ||
| 169 | JMP SHORT TEST_CTL ;; | ||
| 170 | IN_SHIFT_STATE: ;; | ||
| 171 | OR EXT_KB_FLAG,EITHER_SHIFT ;; | ||
| 172 | TEST_CTL: ;; | ||
| 173 | TEST ES:KB_FLAG,CTL_SHIFT ;; Q..in control state? | ||
| 174 | JNZ IN_CTL_STATE ;; Y..go set bit | ||
| 175 | TEST ES:KB_FLAG_3,R_CTL_SHIFT ;; Q..how bout the right ctl? | ||
| 176 | JNZ IN_CTL_STATE ;; Y..go set the bit | ||
| 177 | AND EXT_KB_FLAG,NOT EITHER_CTL ;; N..clear the bit | ||
| 178 | JMP SHORT TEST_ALT ;; | ||
| 179 | IN_CTL_STATE: ;; | ||
| 180 | OR EXT_KB_FLAG,EITHER_CTL ;; | ||
| 181 | TEST_ALT: ;; | ||
| 182 | TEST ES:KB_FLAG,ALT_SHIFT ;; Q..in alt state? | ||
| 183 | JNZ IN_ALT_STATE ;; Y..go set bit | ||
| 184 | TEST ES:KB_FLAG_3,R_ALT_SHIFT ;; Q..how bout the right alt? | ||
| 185 | JNZ IN_ALT_STATE ;; Y..go set the bit | ||
| 186 | AND EXT_KB_FLAG,NOT EITHER_ALT ;; N..clear the bit | ||
| 187 | JMP SHORT COPY_FLAGS ;; | ||
| 188 | IN_ALT_STATE: ;; | ||
| 189 | OR EXT_KB_FLAG,EITHER_ALT ;; | ||
| 190 | ;; | ||
| 191 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 192 | ;; Copy BIOS KB flags from BIOS data seg into the | ||
| 193 | ;; FLAGS_TO_TEST structure. | ||
| 194 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 195 | ;; | ||
| 196 | COPY_FLAGS: ;; | ||
| 197 | MOV CX,NUM_BIOS_FLAGS ;; | ||
| 198 | MOV SI,0 ;; pointers to the BIOS flags | ||
| 199 | MOV DI,0 ;; create shadow copies | ||
| 200 | MOVE_NEXT_FLAG: ;; | ||
| 201 | MOV BX,KB_FLAG_PTRS[SI] ;; pointer to next flag | ||
| 202 | MOV AL,ES:[BX] ;; flag in AL | ||
| 203 | MOV KB_SHADOW_FLAGS[DI],AL ;; save it in the shadow table | ||
| 204 | INC DI ;; | ||
| 205 | INC SI ;; | ||
| 206 | INC SI ;; | ||
| 207 | LOOP MOVE_NEXT_FLAG ;; | ||
| 208 | ;; | ||
| 209 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 210 | ;; Interpret State Logic Commands | ||
| 211 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 212 | ;; | ||
| 213 | PROCESS_STATES: ;; | ||
| 214 | MOV OPTION_BYTE,0 ;; clear options | ||
| 215 | MOV SI,SD.LOGIC_PTR ;; | ||
| 216 | LEA SI,[SI].SL_LOGIC_CMDS ;; | ||
| 217 | NEXT_COMMAND: ;; | ||
| 218 | MOV BL,[SI] ;; command byte in BL | ||
| 219 | SHR BL,1 ;; | ||
| 220 | SHR BL,1 ;; | ||
| 221 | SHR BL,1 ;; | ||
| 222 | SHR BL,1 ;; ISOLATE COMMAND CODE | ||
| 223 | SHL BL,1 ;; command code * 2 | ||
| 224 | JMP CMD_JUMP_TABLE[BX] ;; go process command | ||
| 225 | UNKNOWN_COMMAND: ;; | ||
| 226 | JMP FATAL_ERROR ;; bad news | ||
| 227 | ;; | ||
| 228 | ;; | ||
| 229 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 230 | IFKBD_PROC: ;; | ||
| 231 | MOV AL,NEST_LEVEL ;; | ||
| 232 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 233 | JNE IFKBD_DONE ;; N..don't process | ||
| 234 | |||
| 235 | MOV AX,[SI+1] ;; Keyboard Type Flag | ||
| 236 | ;; | ||
| 237 | TEST SD.KEYB_TYPE,AX ;; Q..are we the right system? | ||
| 238 | JNZ IFKBD_TEST_OK ;; Y.. | ||
| 239 | IFKBD_TEST_FAILED: ;; | ||
| 240 | MOV TAKE_ELSE,YES ;; test failed - take ELSE | ||
| 241 | JMP SHORT IFKBD_DONE ;; | ||
| 242 | IFKBD_TEST_OK: ;; | ||
| 243 | INC PROCESS_LEVEL ;; process commands within IF | ||
| 244 | MOV TAKE_ELSE,NO ;; | ||
| 245 | IFKBD_DONE: ;; | ||
| 246 | INC NEST_LEVEL ;; IFKBD increments nest level | ||
| 247 | INC SI ;; bump past IFKBD | ||
| 248 | INC SI ;; | ||
| 249 | INC SI ;; | ||
| 250 | JMP NEXT_COMMAND ;; | ||
| 251 | ;; | ||
| 252 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 253 | ;; | ||
| 254 | PUT_ERROR_PROC: ;; | ||
| 255 | MOV AL,NEST_LEVEL ;; | ||
| 256 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 257 | JNE PUT_ERROR_DONE ;; N..don't process | ||
| 258 | MOV DI,SD.ACTIVE_XLAT_PTR ;; pointer to active Xlat Section | ||
| 259 | MOV AL,[SI+1] ;; state id in AL | ||
| 260 | CALL PUT_ERROR ;; check active section | ||
| 261 | JC PUT_ERROR_DONE ;; carry set if translation found | ||
| 262 | MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section | ||
| 263 | MOV AL,[SI+1] ;; state id for XLATT in AL | ||
| 264 | CALL PUT_ERROR ;; | ||
| 265 | ;; | ||
| 266 | PUT_ERROR_DONE: ;; | ||
| 267 | INC SI ;; | ||
| 268 | INC SI ;; | ||
| 269 | JMP NEXT_COMMAND ;; | ||
| 270 | ;; | ||
| 271 | PUT_ERROR PROC ;; | ||
| 272 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 273 | ;; Search for a state whose ID matches the ID | ||
| 274 | ;; on the PUT_ERROR command | ||
| 275 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 276 | ;; | ||
| 277 | CLC ;; | ||
| 278 | LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section | ||
| 279 | PE_NEXT_STATE: ;; | ||
| 280 | CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? | ||
| 281 | JE PE_EXIT ;; Y..exit | ||
| 282 | CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? | ||
| 283 | JE PE_STATE_MATCH ;; | ||
| 284 | ADD DI,[DI].XS_STATE_LEN ;; N..check next state | ||
| 285 | JMP SHORT PE_NEXT_STATE ;; | ||
| 286 | ;; | ||
| 287 | PE_STATE_MATCH: ;; | ||
| 288 | MOV AX,[DI].XS_ERROR_CHAR ;; get error char in AX | ||
| 289 | CALL BUFFER_FILL ;; | ||
| 290 | STC ;; indicate that we found the state | ||
| 291 | PE_EXIT: ;; | ||
| 292 | RET ;; | ||
| 293 | ;; | ||
| 294 | PUT_ERROR ENDP ;; | ||
| 295 | ;; | ||
| 296 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 297 | ;; | ||
| 298 | GOTO_BIOS: ;; | ||
| 299 | CLC ;; clear carry flag indicating | ||
| 300 | POP BX ;; we should continue INT 9 | ||
| 301 | POP AX ;; processing | ||
| 302 | POP ES ;; | ||
| 303 | POP DS ;; | ||
| 304 | RET ;; | ||
| 305 | ;; | ||
| 306 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 307 | ;; | ||
| 308 | IFF_PROC: ;; | ||
| 309 | MOV AL,NEST_LEVEL ;; | ||
| 310 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 311 | JNE IFF_DONE ;; N..don't process IFF | ||
| 312 | MOV BL,[SI] ;; command byte | ||
| 313 | AND BL,FLAG_ID_BITS ;; isolate flag id | ||
| 314 | XOR BH,BH ;; | ||
| 315 | MOV AL,FLAGS_TO_TEST[BX] ;; flag in AL | ||
| 316 | TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT test? | ||
| 317 | JNZ ITS_A_NOT ;; | ||
| 318 | TEST AL,[SI]+1 ;; Y..check for bit set | ||
| 319 | JNZ IFF_MATCH ;; | ||
| 320 | JZ IFF_NO_MATCH ;; | ||
| 321 | ITS_A_NOT: ;; | ||
| 322 | TEST AL,[SI]+1 ;; Y..check for bit clear | ||
| 323 | JZ IFF_MATCH ;; | ||
| 324 | IFF_NO_MATCH: ;; | ||
| 325 | MOV TAKE_ELSE,YES ;; flag test failed - take ELSE | ||
| 326 | JMP SHORT IFF_DONE ;; | ||
| 327 | IFF_MATCH: ;; | ||
| 328 | INC PROCESS_LEVEL ;; process commands within IF | ||
| 329 | MOV TAKE_ELSE,NO ;; | ||
| 330 | ;; | ||
| 331 | IFF_DONE: ;; | ||
| 332 | INC NEST_LEVEL ;; IFF increments nest level | ||
| 333 | INC SI ;; bump past IFF | ||
| 334 | INC SI ;; | ||
| 335 | JMP NEXT_COMMAND ;; | ||
| 336 | ;; | ||
| 337 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 338 | ;; | ||
| 339 | ELSEF_PROC: ;; | ||
| 340 | MOV AL,PROCESS_LEVEL ;; | ||
| 341 | CMP AL,NEST_LEVEL ;; Q..nest level = process level? | ||
| 342 | JNE CHECK_TAKE_ELSEF ;; N..check for take_else | ||
| 343 | DEC PROCESS_LEVEL ;; Y..we just finished the "IF" block | ||
| 344 | JMP ELSEF_DONE ;; so we are finished with IFF/ELSEF | ||
| 345 | CHECK_TAKE_ELSEF: ;; | ||
| 346 | CMP TAKE_ELSE,YES ;; Q..are we scanning for ELSE? | ||
| 347 | JNE ELSEF_DONE ;; N..done | ||
| 348 | DEC NEST_LEVEL ;; ELSEF itself is back a level | ||
| 349 | CMP AL,NEST_LEVEL ;; Q..nest level = process level? | ||
| 350 | JNE NOT_THIS_ELSEF ;; N..this else is not the one | ||
| 351 | INC PROCESS_LEVEL ;; Y..process ELSEF block | ||
| 352 | MOV TAKE_ELSE,NO ;; reset | ||
| 353 | NOT_THIS_ELSEF: ;; | ||
| 354 | INC NEST_LEVEL ;; stuff within the ELSEF is up a level | ||
| 355 | ;; | ||
| 356 | ELSEF_DONE: ;; | ||
| 357 | INC SI ;; bump past ELSEF | ||
| 358 | JMP NEXT_COMMAND ;; | ||
| 359 | ;; | ||
| 360 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 361 | ENDIFF_PROC: ;; | ||
| 362 | MOV AL,PROCESS_LEVEL ;; | ||
| 363 | CMP AL,NEST_LEVEL ;; Q..nest level = process level? | ||
| 364 | JNE ENDIFF_DONE ;; N..don't adjust process level | ||
| 365 | DEC PROCESS_LEVEL ;; Y..we just finished the IF/ELSE | ||
| 366 | ENDIFF_DONE: ;; | ||
| 367 | DEC NEST_LEVEL ;; ENDIF decrements nest level | ||
| 368 | INC SI ;; bump past ENDIF | ||
| 369 | JMP NEXT_COMMAND ;; | ||
| 370 | ;; | ||
| 371 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 372 | ;; Translations may be in the Common or Specific | ||
| 373 | ;; Sections. Search the Specific section first | ||
| 374 | ;; then the common section. | ||
| 375 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 376 | XLATT_PROC: ;; | ||
| 377 | MOV AL,PROCESS_LEVEL ;; | ||
| 378 | CMP AL,NEST_LEVEL ;; Q..nest level = process level? | ||
| 379 | JNE XLATT_DONE ;; N..next command | ||
| 380 | MOV DI,SD.ACTIVE_XLAT_PTR ;; pointer to active Xlat Section | ||
| 381 | MOV AL,[SI+1] ;; state id for XLATT in AL | ||
| 382 | CALL TRANSLATE ;; check active section | ||
| 383 | JC XLATT_FOUND ;; carry set if translation found | ||
| 384 | MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section | ||
| 385 | MOV AL,[SI+1] ;; state id for XLATT in AL | ||
| 386 | CALL TRANSLATE ;; | ||
| 387 | JNC XLATT_DONE ;; | ||
| 388 | XLATT_FOUND: ;; | ||
| 389 | OR EXT_KB_FLAG,SCAN_MATCH ;; set flag indicating scan matched | ||
| 390 | TEST OPTION_BYTE,EXIT_IF_FOUND ;; Q..exit | ||
| 391 | JZ XLATT_DONE ;; | ||
| 392 | JMP EXIT ;; Y..BYE | ||
| 393 | ;; | ||
| 394 | XLATT_DONE: ;; | ||
| 395 | INC SI ;; | ||
| 396 | INC SI ;; | ||
| 397 | JMP NEXT_COMMAND ;; | ||
| 398 | ;; | ||
| 399 | TRANSLATE PROC ;; | ||
| 400 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 401 | ;; Search for a state whose ID matches the ID | ||
| 402 | ;; on the XLATT command | ||
| 403 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 404 | ;; | ||
| 405 | CLC ;; | ||
| 406 | LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section | ||
| 407 | TP_NEXT_STATE: ;; | ||
| 408 | CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? | ||
| 409 | JE TP_EXIT ;; Y..exit | ||
| 410 | CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? | ||
| 411 | JE TP_STATE_MATCH ;; | ||
| 412 | ADD DI,[DI].XS_STATE_LEN ;; N..check next state | ||
| 413 | JMP SHORT TP_NEXT_STATE ;; | ||
| 414 | ;; | ||
| 415 | TP_STATE_MATCH: ;; | ||
| 416 | AND EXT_KB_FLAG,NOT SCAN_MATCH ;; reset flag before search | ||
| 417 | PUSH SI ;; save pointer to next command | ||
| 418 | LEA SI,[DI].XS_FIRST_TAB ;; point to first xlat table | ||
| 419 | MOV XLAT_TAB_PTR,SI ;; start of XLAT tables | ||
| 420 | MOV AL,SCAN_CODE ;; restore incoming scan code | ||
| 421 | JMP SHORT NEXT_XLAT_TAB ;; | ||
| 422 | TP_DONE: ;; return here from XLAT | ||
| 423 | POP SI ;; | ||
| 424 | TP_EXIT: ;; | ||
| 425 | RET ;; | ||
| 426 | ;; | ||
| 427 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 428 | ;; Check xlate tables for matching scan code | ||
| 429 | ;; The xlate table can be in one of two forms: | ||
| 430 | ;; Type 1 = Table contains buffer entries only. | ||
| 431 | ;; Scan code is used as an index into xlat table | ||
| 432 | ;; Type 2 = Table contains pairs of SCAN/BUFFER_ENTRY. | ||
| 433 | ;; Table must be searched for matching scan. | ||
| 434 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 435 | ;; | ||
| 436 | NEXT_XLAT_TAB: ;; | ||
| 437 | MOV SI,XLAT_TAB_PTR ;; pointer to xlat tables | ||
| 438 | CMP [SI].XLAT_TAB_SIZE,0 ;; Q..any more xlat tables? | ||
| 439 | JNE PROCESS_XLAT_TAB ;; Y..check um | ||
| 440 | JMP TP_DONE ;; N..done | ||
| 441 | PROCESS_XLAT_TAB: ;; | ||
| 442 | MOV DL,[SI].XLAT_OPTIONS ;; save translate options IN DL | ||
| 443 | MOV BX,[SI].XLAT_TAB_SIZE ;; Y..calc pointer to next xlat tab | ||
| 444 | ADD BX,SI ;; | ||
| 445 | MOV XLAT_TAB_PTR,BX ;; pointer to next xlat tab | ||
| 446 | TEST DL,TYPE_2_TAB ;; Q..is this a type 2 table? | ||
| 447 | JZ TYPE_1_LOOKUP ;; N..go do table lookup | ||
| 448 | TYPE_2_SEARCH: ;; Y..search table | ||
| 449 | XOR CH,CH ;; | ||
| 450 | MOV CL,[SI].XLAT_NUM ;; number of xlat entries | ||
| 451 | MOV BX,DEFAULT_TAB_2_ENT_SZ ;; default entry size | ||
| 452 | TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..are buffer entries ASCII only? | ||
| 453 | JZ NEXT_TAB_2_ENTRY ;; N..continue | ||
| 454 | MOV BX,ASC_ONLY_TAB_2_ENT_SZ ;; Y..set size in BX | ||
| 455 | NEXT_TAB_2_ENTRY: ;; entry size is in BX | ||
| 456 | CMP CX,0 ;; Q..last entry? | ||
| 457 | JE NEXT_XLAT_TAB ;; y..go to next table | ||
| 458 | CMP AL,[SI].XLAT_SCAN ;; Q..scan match? | ||
| 459 | JE FOUND_TAB_2_ENTRY ;; Y..go create buffer entry | ||
| 460 | ADD SI,BX ;; point to next entry | ||
| 461 | LOOP NEXT_TAB_2_ENTRY ;; | ||
| 462 | JMP SHORT NEXT_XLAT_TAB ;; | ||
| 463 | FOUND_TAB_2_ENTRY: ;; Q..set scan code to 0? | ||
| 464 | MOV AH,AL ;; default scan code in AH | ||
| 465 | MOV AL,[SI].XLAT_2_BUF_ENTRY ;; ASCII code from table in AL | ||
| 466 | TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..are buffer entries ASCII only? | ||
| 467 | JNZ BUFFER_ENTRY_READY ;; Y..buffer entry is ready | ||
| 468 | MOV AH,[SI].XLAT_2_BUF_ENTRY+1 ;; N..scan code from table as well | ||
| 469 | JMP SHORT BUFFER_ENTRY_READY ;; go put entry in buffer | ||
| 470 | ;; | ||
| 471 | TYPE_1_LOOKUP: ;; | ||
| 472 | CMP AL,[SI].XLAT_SCAN_LO ;; Q..is scan in range of this table? | ||
| 473 | JB NEXT_XLAT_TAB ;; N..next table | ||
| 474 | CMP AL,[SI].XLAT_SCAN_HI ;; Q..is scan in range of this table? | ||
| 475 | JA NEXT_XLAT_TAB ;; N..next table | ||
| 476 | SUB AL,[SI].XLAT_SCAN_LO ;; convert scan code to xlat index | ||
| 477 | TEST DL,ASCII_ONLY+ZERO_SCAN ;; Q..ASCII only in xlat ? | ||
| 478 | JZ TWO_BYTE_LOOKUP ;; N..go do 2-byte lookup | ||
| 479 | LEA BX,[SI].XLAT_1_BUF_ENTRY ;; Y..do 1-byte lookup | ||
| 480 | XLAT [SI].XLAT_1_BUF_ENTRY ;; ASCII code in AL | ||
| 481 | MOV AH,SCAN_CODE ;; SCAN in AH | ||
| 482 | JMP SHORT BUFFER_ENTRY_READY ;; go put entry in buffer | ||
| 483 | TWO_BYTE_LOOKUP: ;; | ||
| 484 | MOV BL,2 ;; multiply scan index | ||
| 485 | MUL BL ;; by two | ||
| 486 | MOV BX,AX ;; real index in BX | ||
| 487 | MOV AX,WORD PTR [SI].XLAT_1_BUF_ENTRY[BX] ;; get 2-byte buffer entry | ||
| 488 | ;; AL=ASCII AH=SCAN | ||
| 489 | BUFFER_ENTRY_READY: ;; | ||
| 490 | TEST DL,ZERO_SCAN ;; Q..set scan part to zero? | ||
| 491 | JZ NO_ZERO_SCAN ;; N.. | ||
| 492 | XOR AH,AH ;; scan = 0 | ||
| 493 | NO_ZERO_SCAN: ;; | ||
| 494 | CALL BUFFER_FILL ;; go put entry in buffer | ||
| 495 | STC ;; indicate translation found | ||
| 496 | JMP TP_DONE ;; | ||
| 497 | ;; | ||
| 498 | TRANSLATE ENDP ;; | ||
| 499 | ;; | ||
| 500 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 501 | OPTION_PROC: ;; | ||
| 502 | MOV AL,PROCESS_LEVEL ;; | ||
| 503 | CMP AL,NEST_LEVEL ;; Q..nest level = process level? | ||
| 504 | JNE DONE_OPTION ;; N..done | ||
| 505 | MOV AL,[SI]+1 ;; mask in AL | ||
| 506 | TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT? | ||
| 507 | JNZ AND_MASK ;; | ||
| 508 | OR OPTION_BYTE,AL ;; N..OR in the mask bits | ||
| 509 | JMP DONE_OPTION ;; | ||
| 510 | AND_MASK: ;; | ||
| 511 | NOT AL ;; | ||
| 512 | AND OPTION_BYTE,AL ;; Y..AND out the mask bits | ||
| 513 | DONE_OPTION: ;; | ||
| 514 | INC SI ;; | ||
| 515 | INC SI ;; | ||
| 516 | JMP NEXT_COMMAND ;; | ||
| 517 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 518 | RESET_NLS_PROC: ;; | ||
| 519 | MOV AL,NEST_LEVEL ;; | ||
| 520 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 521 | JNE RN_DONE ;; N..don't process | ||
| 522 | MOV NLS_FLAG_1,0 ;; | ||
| 523 | MOV NLS_FLAG_2,0 ;; | ||
| 524 | RN_DONE: ;; | ||
| 525 | INC SI ;; | ||
| 526 | JMP NEXT_COMMAND ;; | ||
| 527 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 528 | BEEP_PROC: ;; | ||
| 529 | MOV AL,NEST_LEVEL ;; | ||
| 530 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 531 | JNE BP_DONE ;; N..don't process | ||
| 532 | MOV BEEP_PENDING,YES ;; set beep pending flag. the beep | ||
| 533 | ;; will be done just before iret | ||
| 534 | BP_DONE: ;; | ||
| 535 | INC SI ;; | ||
| 536 | JMP NEXT_COMMAND ;; | ||
| 537 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 538 | GOTO_PROC: ;; | ||
| 539 | MOV AL,NEST_LEVEL ;; | ||
| 540 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 541 | JNE GOTO_DONE ;; N..don't process | ||
| 542 | MOV BL,[SI] ;; command byte in BL | ||
| 543 | AND BL,NOT COMMAND_BITS ;; remove command code | ||
| 544 | OR BL,BL ;; Q..goto label? | ||
| 545 | JZ GOTO_LABEL ;; Y..go jump | ||
| 546 | CMP BL,EXIT_INT_9_FLAG ;; Q..SPECIAL - Exit Int 9? | ||
| 547 | JNE NOT_EXIT_INT_9 ;; N.. | ||
| 548 | JMP EXIT ;; Y..bye bye | ||
| 549 | NOT_EXIT_INT_9: ;; | ||
| 550 | CMP BL,EXIT_STATE_LOGIC_FLAG ;; Q..SPECIAL - Exit State Logic? | ||
| 551 | JNE NOT_EXIT_S_L ;; N.. | ||
| 552 | JMP GOTO_BIOS ;; Y..goto bios | ||
| 553 | NOT_EXIT_S_L: ;; | ||
| 554 | JMP FATAL_ERROR ;; garbage in that command | ||
| 555 | GOTO_LABEL: ;; | ||
| 556 | ADD SI,[SI]+1 ;; bump by relative offset | ||
| 557 | MOV PROCESS_LEVEL,0 ;; reset process and nest level | ||
| 558 | MOV NEST_LEVEL,0 ;; | ||
| 559 | GOTO_DONE: ;; | ||
| 560 | ADD SI,3 ;; bump to next command | ||
| 561 | JMP NEXT_COMMAND ;; | ||
| 562 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 563 | ;; | ||
| 564 | ANDF_PROC: ;; | ||
| 565 | MOV AL,NEST_LEVEL ;; | ||
| 566 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 567 | JNE ANDF_DONE ;; N..don't process ANDF | ||
| 568 | MOV BL,[SI] ;; command byte | ||
| 569 | AND BL,FLAG_ID_BITS ;; isolate flag id | ||
| 570 | XOR BH,BH ;; | ||
| 571 | MOV AL,FLAGS_TO_TEST[BX] ;; flag in AL | ||
| 572 | TEST BYTE PTR[SI],NOT_TEST ;; Q..is this a NOT test? | ||
| 573 | JNZ ANDF_NOT ;; | ||
| 574 | TEST AL,[SI]+1 ;; Y..check for bit set | ||
| 575 | JNZ ANDF_DONE ;; if set then remain in IFF | ||
| 576 | JZ ANDF_NO_MATCH ;; | ||
| 577 | ANDF_NOT: ;; | ||
| 578 | TEST AL,[SI]+1 ;; Y..check for bit clear | ||
| 579 | JZ ANDF_DONE ;; if clear then remain in IFF | ||
| 580 | ANDF_NO_MATCH: ;; | ||
| 581 | MOV TAKE_ELSE,YES ;; flag test failed - take ELSE | ||
| 582 | DEC PROCESS_LEVEL ;; IFF would have inc'd - so dec | ||
| 583 | ANDF_DONE: ;; | ||
| 584 | INC SI ;; bump past ANDF | ||
| 585 | INC SI ;; | ||
| 586 | JMP NEXT_COMMAND ;; | ||
| 587 | ;; | ||
| 588 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 589 | ;; SET_FLAG Command. | ||
| 590 | ;; Flag Table must be in the Common Section | ||
| 591 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 592 | ;; | ||
| 593 | SET_FLAG_PROC: ;; | ||
| 594 | MOV AL,NEST_LEVEL ;; | ||
| 595 | CMP AL,PROCESS_LEVEL ;; Q..nest level = process level? | ||
| 596 | JNE SF_DONE ;; N..don't process | ||
| 597 | ;; | ||
| 598 | MOV DI,SD.COMMON_XLAT_PTR ;; check common Xlat Section | ||
| 599 | MOV AL,[SI+1] ;; state id in AL | ||
| 600 | LEA DI,[DI].XS_FIRST_STATE ;; point to first state in section | ||
| 601 | SF_NEXT_STATE: ;; | ||
| 602 | CMP [DI].XS_STATE_LEN,0 ;; Q..out of states? | ||
| 603 | JE SF_DONE ;; Y..exit | ||
| 604 | CMP AL,[DI].XS_STATE_ID ;; Q..is this the requested state? | ||
| 605 | JE SF_STATE_MATCH ;; | ||
| 606 | ADD DI,[DI].XS_STATE_LEN ;; N..check next state | ||
| 607 | JMP SHORT SF_NEXT_STATE ;; | ||
| 608 | ;; | ||
| 609 | SF_STATE_MATCH: ;; | ||
| 610 | AND EXT_KB_FLAG,NOT SCAN_MATCH ;; reset flag before search | ||
| 611 | PUSH SI ;; save pointer to next command | ||
| 612 | LEA SI,[DI].XS_FIRST_TAB ;; point to table | ||
| 613 | MOV AL,SCAN_CODE ;; restore incoming scan code | ||
| 614 | MOV CX,[SI] ;; number of entries | ||
| 615 | CMP CX,0 ;; Q..any entries? | ||
| 616 | JE SF_RESTORE ;; N..done | ||
| 617 | INC SI ;; Y..Bump to first entry | ||
| 618 | INC SI ;; | ||
| 619 | NEXT_SF_ENTRY: ;; | ||
| 620 | CMP AL,[SI] ;; Q..scan match? | ||
| 621 | JE FOUND_SF_ENTRY ;; Y..go set flag | ||
| 622 | ADD SI,3 ;; point to next entry | ||
| 623 | LOOP NEXT_SF_ENTRY ;; | ||
| 624 | JMP SHORT SF_RESTORE ;; no match found | ||
| 625 | FOUND_SF_ENTRY: ;; | ||
| 626 | MOV NLS_FLAG_1,0 ;; clear all NLS bits | ||
| 627 | MOV NLS_FLAG_2,0 ;; | ||
| 628 | MOV BL,[SI]+1 ;; flag id in BX | ||
| 629 | XOR BH,BH ;; | ||
| 630 | MOV AL,[SI]+2 ;; mask in AL | ||
| 631 | OR FLAGS_TO_TEST[BX],AL ;; set the bit | ||
| 632 | OR EXT_KB_FLAG,SCAN_MATCH ;; set flag indicating scan matched | ||
| 633 | TEST OPTION_BYTE,EXIT_IF_FOUND ;; Q..exit | ||
| 634 | JZ SF_RESTORE ;; | ||
| 635 | POP SI ;; | ||
| 636 | JMP EXIT ;; | ||
| 637 | SF_RESTORE: ;; | ||
| 638 | POP SI ;; | ||
| 639 | SF_DONE: ;; | ||
| 640 | INC SI ;; bump past command | ||
| 641 | INC SI ;; | ||
| 642 | JMP NEXT_COMMAND ;; | ||
| 643 | ;; | ||
| 644 | ;; | ||
| 645 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 646 | ;; Fatal Error routine. Come here when | ||
| 647 | ;; we have a critical error such as an | ||
| 648 | ;; invalid State Logic Command. | ||
| 649 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 650 | ;; | ||
| 651 | FATAL_ERROR: ;; | ||
| 652 | JMP SHORT EXIT ;; end the int 9 processing | ||
| 653 | ;; | ||
| 654 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 655 | ;; Exit point. | ||
| 656 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 657 | ;; | ||
| 658 | EXIT: ;; | ||
| 659 | MOV BUSY_FLAG,NO ;; | ||
| 660 | STC ;; indicate we should end INT 9 | ||
| 661 | POP BX ;; processing | ||
| 662 | POP AX ;; | ||
| 663 | POP ES ;; | ||
| 664 | POP DS ;; | ||
| 665 | RET ;; | ||
| 666 | ;; | ||
| 667 | KEYB_STATE_PROCESSOR ENDP ;; | ||
| 668 | ;; | ||
| 669 | ;; | ||
| 670 | |||
| 671 | CODE ENDS | ||
| 672 | END | ||