1 ; _____________________________________________ 2 ; | | 3 ; | Project: APPLER | 4 ; | File: KEYBOARD.ASM | 5 ; | Compiler: 16-bit TASM (2.5) | 6 ; | | 7 ; | Subject: Keyboard Manager | 8 ; | | 9 ; | Author: Emil Dotchevski | 10 ; |_____________________________________________| 11 12 include GLOBALS.INC 13 include INTERFAC.INC 14 15 Keyboards group Keyboard,SimKbd 16 Keyboard segment public 17 assume cs:Keyboard, ds:Keyboard, es:Emulate, ss:Data 18 19 20 DATA_PORT = 60h 21 COMMAND_PORT = 64h 22 OUTPUT_FULL = 01h ; Output buffer full flag bit 23 INPUT_EMPTY = 02h ; Input buffer empty flag bit 24 DISABLE_KEYBOARD= 0ADh ; Disable keyboard command code 25 ENABLE_KEYBOARD = 0AEh ; Enable keyboard command code 26 LED_SET = 0EDh ; Set keyboard LEDs command code 27 ACKNOWLEDGE = 0FAh ; Keyboard ACK 28 TIME_OUT = 0FFFFh ; 8042 time out counter value 29 30 K_KeyboardRet1 label byte 31 SetLEDs proc far ; AL - LED data 32 push ax 33 mov al,DISABLE_KEYBOARD 34 call K_SendCommand 35 jc SetLEDs_Exit 36 mov al,LED_SET 37 call K_SendData 38 jc SetLEDs_Exit 39 pop ax 40 push ax 41 call K_SendData 42 SetLEDs_Exit: mov al,ENABLE_KEYBOARD 43 out COMMAND_PORT,al 44 pop ax 45 ret 46 SetLEDs endp 47 LightsData db 0 48 49 K_KeyboardRet2 label byte 50 K_SendCommand proc far 51 push ax 52 call WaitInputEmpty 53 jc K_SC_Ret 54 out COMMAND_PORT,al 55 call WaitOutputFull 56 jc K_SC_Ret 57 in al,DATA_PORT 58 call WaitInputEmpty 59 K_SC_Ret: pop ax 60 ret 61 K_SendCommand endp 62 63 K_KeyboardRet3 label byte 64 K_SendData proc far 65 push ax 66 call WaitInputEmpty 67 jc K_SD_Ret 68 out DATA_PORT,al 69 call WaitOutputFull 70 jc K_SD_Ret 71 in al,DATA_PORT 72 call WaitInputEmpty 73 K_SD_Ret: pop ax 74 ret 75 K_SendData endp 76 77 K_KeyboardRet4 label byte 78 K_GetData proc far 79 in al,DATA_PORT 80 call WaitInputEmpty 81 ret 82 K_GetData endp 83 84 WaitInputEmpty proc near 85 push ax cx 86 mov cx,TIME_OUT 87 WIE_Loop: in al,COMMAND_PORT 88 test al,INPUT_EMPTY 89 jz WIE_Exit 90 loop WIE_Loop 91 stc 92 WIE_Exit: pop cx ax 93 ret 94 WaitInputEmpty endp 95 96 WaitOutputFull proc near 97 push ax cx 98 mov cx,TIME_OUT 99 WOF_Loop: in al,COMMAND_PORT 100 test al,OUTPUT_FULL 101 jz WOF_Exit 102 loop WOF_Loop 103 stc 104 WOF_Exit: pop cx ax 105 ret 106 WaitOutputFull endp 107 108 109 k_BufferFlag db 0 110 k_BuffPtr1 db 0 111 k_BuffPtr2 db 0 112 k_Buffer db 64 dup (?) 113 114 ClearBuffer proc far 115 mov cs:k_BuffPtr1,0 116 mov cs:k_BuffPtr2,0 117 ret 118 ClearBuffer endp 119 120 PutBuffer proc near 121 test C000,10000000b 122 jz k_NoBuff 123 test k_BufferFlag,1 124 jz k_NoBuff 125 xor bx,bx 126 mov bl,k_BuffPtr2 127 mov k_Buffer[bx],al 128 inc bl 129 cmp bl,size k_Buffer 130 jb PB_1 131 xor bx,bx 132 PB_1: cmp bl,k_BuffPtr1 133 je PB_Ret 134 mov k_BuffPtr2,bl 135 jmp PB_Ret 136 k_NoBuff: mov C000,al 137 PB_Ret: ret 138 PutBuffer endp 139 140 GetBuffer proc far 141 pushf 142 push ax bx ds es 143 push cs 144 pop ds 145 cmp k_BufferFlag,0 146 jz GB_Ret 147 mov ax,Emulate 148 mov es,ax 149 xor bx,bx 150 mov bl,k_BuffPtr1 151 mov al,k_Buffer[bx] 152 cmp bl,k_BuffPtr2 153 je GB_Ret 154 inc bl 155 cmp bl,size k_Buffer 156 jb GB_1 157 xor bx,bx 158 GB_1: mov k_BuffPtr1,bl 159 mov [C000],al 160 GB_Ret: pop es ds bx ax 161 popf 162 ret 163 GetBuffer endp 164 165 get_table_ofs proc far 166 push ax 167 mov al,bl 168 xor bx,bx 169 test al,M_ALT 170 mov bl,2 shl 1 171 jnz gto_ModeOK 172 test al,M_CTRL 173 mov bl,1 shl 1 174 jnz gto_ModeOK 175 test al,M_CAPS_LOCK 176 jz gto_not_caps 177 test al,M_LEFT_SHIFT or M_RIGHT_SHIFT 178 mov bl,4 shl 1 179 jnz gto_ModeOK 180 mov bl,3 shl 1 181 jmp gto_ModeOK 182 gto_not_caps: test al,M_LEFT_SHIFT or M_RIGHT_SHIFT 183 mov bl,5 shl 1 184 jnz gto_ModeOK 185 test al,M_NUM_LOCK 186 mov bl,6 shl 1 187 jnz gto_ModeOK 188 xor bx,bx 189 gto_ModeOK: pop ax 190 ret 191 get_table_ofs endp 192 193 k_Fire1 = 80h 194 k_Fire2 = 81h 195 k_LeftArrow = 82h 196 k_RightArrow = 83h 197 k_UpArrow = 84h 198 k_DownArrow = 85h 199 None = 86h 200 Ctrl = 87h 201 Lshift = 88h 202 Rshift = 89h 203 Caps = 8Ah 204 ALT = 8Bh 205 k_Reset = 8Ch 206 k_Pause = 8Dh 207 k_F1 = 8Eh 208 k_F2 = 8Fh 209 k_F3 = 90h 210 k_F4 = 91h 211 k_F5 = 92h 212 k_F6 = 93h 213 k_F7 = 94h 214 k_F8 = 95h 215 k_F9 = 96h 216 k_F10 = 97h 217 k_DosShell = 98h 218 k_QuitAppler = 99h 219 k_F11 = 9Ah 220 k_F12 = 9Bh 221 k_NumLock = 9Ch 222 223 k_KeyPressed db 1 224 k_Flags dw 0 225 k_KeyCode db 0 226 k_ScanCode db 0 227 k_Shifts dw 0 228 k_Table dw k_AppleTable 229 k_AppleTable dw a_NormalTable ; Normal table 230 dw a_CtrlTable ; Ctrl pressed 231 dw a_AltTable ; Ctrl and Alt pressed 232 dw a_CapsTable ; Caps Lock mode 233 dw a_CpsShfTable ; Shift in Caps Lock mode 234 dw a_ShiftTable ; Shift mode 235 dw a_NumTable ; Num Lock mode 236 k_DebugTable dw d_NormalTable 237 dw d_NormalTable 238 dw d_AltTable 239 dw d_CapsTable 240 dw d_CpsShfTable 241 dw d_ShiftTable 242 dw d_NormalTable 243 k_KbdSetupTable dw k_NormalTable 244 dw k_NormalTable 245 dw k_AltTable 246 dw k_NormalTable 247 dw k_NormalTable 248 dw k_NormalTable 249 dw k_NormalTable 250 251 252 k_int09: push ax 253 in al,DATA_PORT 254 push ax 255 in al,61h 256 or al,11000000b 257 jmp $+2 258 out 61h,al 259 and al,01111111b 260 jmp $+2 261 out 61h,al 262 mov al,20h 263 out 20h,al 264 pop ax 265 call far ptr KeyStopPlay 266 xchg sp,bp 267 or [bp+6],ax 268 xchg sp,bp 269 k_int09_iret: pop ax 270 iret 271 272 KeyStopPlay: or al,al 273 js Key 274 call SimKbdClr 275 Key: push bx si ds es 276 push cs 277 pop ds 278 mov k_Flags,0 279 test k_PauseFlag,1 280 jnz k_KeyPause 281 mov bx,Emulate 282 mov es,bx 283 mov ah,al 284 xor bx,bx 285 mov bl,ah 286 and bl,01111111b 287 cmp bl,58h 288 ja k_ret 289 mov al,bl 290 mov bx,k_Shifts 291 call get_table_ofs 292 mov si,k_Table 293 mov bx,[si][bx] 294 xlat 295 mov k_KeyCode,al 296 or al,al 297 js k_SpecialKey 298 or ah,ah 299 js k_ret 300 or al,10000000b 301 call PutBuffer 302 k_record_ret: mov al,ah 303 call RecordKey 304 k_ret: and ah,01111111b 305 mov k_ScanCode,ah 306 mov ax,k_Flags 307 pop es ds si bx 308 retf 309 310 k_KeyPause: or al,al 311 js k_ret 312 mov k_PauseFlag,0 313 jmp k_ret 314 315 k_SpecialKey: cmp ah,k_OldSpcKey 316 je k_ret 317 push ax 318 and al,01111111b 319 or ah,ah 320 mov si,offset k_KeyOnSub 321 jns k_SK_on 322 mov si,offset k_KeyOffSub 323 xor ah,ah 324 k_SK_on: mov k_OldSpcKey,ah 325 xor bh,bh 326 mov bl,al 327 shl bx,1 328 mov ax,k_Shifts 329 call [si][bx] 330 mov k_Shifts,ax 331 mov k_KeyPressed,1 332 pop ax 333 jmp k_record_ret 334 k_OldSpcKey db 0 335 k_KeyOnSub dw k_Fire1_ON,k_Fire2_ON,k_LA_ON,k_RA_ON,k_UA_ON,k_DA_ON 336 dw k_None 337 dw k_Ctrl_ON,k_Lshift_ON,k_Rshift_ON,k_Caps_ON,k_ALT_ON 338 dw k_Reset_ON,k_Pause_ON 339 dw k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON,k_F_ON 340 dw k_F_ON,k_F_ON 341 dw k_None,k_F12_ON,k_Num_ON 342 k_KeyOffSub dw k_Fire1_OFF,k_Fire2_OFF,k_LA_OFF,k_RA_OFF,k_UA_OFF,k_DA_OFF 343 dw k_None 344 dw k_Ctrl_OFF,k_Lshift_OFF,k_Rshift_OFF,k_Caps_OFF,k_ALT_OFF 345 dw k_Reset_OFF,k_None 346 dw k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None 347 dw k_None,k_None 348 dw k_None,k_None,k_Num_OFF 349 350 k_Ctrl_OFF: and al,not M_CTRL 351 k_None: ret 352 k_Lshift_OFF: and al,not M_LEFT_SHIFT 353 ret 354 k_Rshift_OFF: and al,not M_RIGHT_SHIFT 355 k_Caps_OFF: ret 356 k_ALT_OFF: and al,not M_ALT 357 ret 358 k_Reset_OFF: and ResetFlag,11111110b 359 mov C000,0 360 ret 361 k_Fire1_OFF: mov es:JoyButton1,7Fh 362 ret 363 k_Fire2_OFF: mov es:JoyButton2,7Fh 364 ret 365 k_LA_OFF: and es:JoyStick,not 00000001b 366 ret 367 k_RA_OFF: and es:JoyStick,not 00000010b 368 ret 369 k_UA_OFF: and es:JoyStick,not 00000100b 370 ret 371 k_DA_OFF: and es:JoyStick,not 00001000b 372 ret 373 374 k_Ctrl_ON: or al,M_CTRL 375 ret 376 k_Lshift_ON: cmp k_ScanCode,060h 377 je k_Lshift_ON_ret 378 or al,M_LEFT_SHIFT 379 k_Lshift_ON_ret:ret 380 k_Rshift_ON: cmp k_ScanCode,060h 381 je k_Rshift_ON_ret 382 or al,M_RIGHT_SHIFT 383 k_Rshift_ON_ret:ret 384 k_Caps_ON: xor al,M_CAPS_LOCK 385 push ax 386 xor LightsData,00000100b 387 mov al,LightsData 388 call SetLEDs 389 pop ax 390 ret 391 k_ALT_ON: or al,M_ALT 392 ret 393 k_Num_ON: xor al,M_NUM_LOCK 394 push ax 395 xor LightsData,00000010b 396 mov al,LightsData 397 call SetLEDs 398 test al,00000010b 399 mov ss:C0xxRead[2*61h], offset C0612r 400 mov ss:C0xxRead[2*62h], offset C0612r 401 mov ss:C0xxRead[2*64h], offset C0645r 402 mov ss:C0xxRead[2*65h], offset C0645r 403 jz k_Num_ON1 404 mov ss:C0xxRead[2*61h], offset C061r 405 mov ss:C0xxRead[2*62h], offset C062r 406 mov ss:C0xxRead[2*64h], offset C064r 407 mov ss:C0xxRead[2*65h], offset C065r 408 mov es:JoyStick,0 409 k_Num_ON1: pop ax 410 k_Num_OFF: ret 411 k_Fire1_ON: mov es:JoyButton1,0FFh 412 ret 413 k_Fire2_ON: mov es:JoyButton2,0FFh 414 ret 415 k_LA_ON: or es:JoyStick,00000001b 416 ret 417 k_RA_ON: or es:JoyStick,00000010b 418 ret 419 k_UA_ON: or es:JoyStick,00000100b 420 ret 421 k_DA_ON: or es:JoyStick,00001000b 422 ret 423 k_Reset_ON: test al,M_CTRL 424 jz k_Reset_ON_J 425 test ResetFlag,00000001b 426 jnz k_Reset_ON_J 427 or ResetFlag,00000001b 428 jmp RESET 429 k_Reset_ON_J: ret 430 431 k_PauseFlag db 0 432 k_OldIRQ db ? 433 k_Pause_ON: push ax 434 in al,21h 435 mov k_OldIRQ,al 436 mov al,11111101b 437 out 21h,al 438 mov k_PauseFlag,1 439 mov al,00000111b 440 call SetLEDs 441 sti 442 k_PauseLoop: test k_PauseFlag,1 443 jnz k_PauseLoop 444 cli 445 mov al,k_OldIRQ 446 out 21h,al 447 mov al,LightsData 448 call SetLEDs 449 pop ax 450 and al,not M_CTRL 451 ret 452 453 k_ProcessIDs db PID_DEBUGGER 454 db PID_FILE_MANAGER 455 db PID_FLOPPY_DISK_MANAGER 456 db PID_KEYBOARD_SETUP 457 db PID_DONT_SWITCH 458 db PID_DONT_SWITCH 459 db PID_DONT_SWITCH 460 db PID_DONT_SWITCH 461 db PID_ABOUT_SCREEN 462 db PID_HELP_SCREEN 463 db PID_DOS_SHELL 464 db PID_QUIT_APPLER 465 466 k_F_ON: push es 467 mov ax,seg RetWhere? 468 mov es,ax 469 assume es:seg RetWhere? 470 shr bx,1 471 sub bl,k_F1 and 01111111b 472 mov al,k_ProcessIDs[bx] 473 mov k_OldSpcKey,0 474 mov es:RetWhere?,al 475 or word ptr k_Flags,0000000100000000b 476 pop es 477 mov ax,k_Shifts 478 and al,not(M_CTRL or M_LEFT_SHIFT or M_RIGHT_SHIFT or M_ALT) 479 ret 480 assume es:Emulate 481 482 k_F12_ON: xor es:synchro_push_ax,0FAh xor 0C3h 483 ret 484 485 486 a_NormalTable db None,1Bh,'1234567890-=',8 ; Normal Table 487 db 9,'QWERTYUIOP[]',0Dh 488 db Ctrl,'ASDFGHJKL;',27h,'`' 489 db LShift,'\ZXCVBNM,./',RShift,'*' 490 db ALT,' ',Caps 491 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 492 db k_NumLock,k_Reset,None,0Bh,None,'-' 493 db 8,None,15h,'+',None,0Ah,None,9,4 494 db None,None,None,None,k_F12 495 496 a_CtrlTable db None,1Bh,'1234567890-=',8 ; CtrlTable 497 db 9,11h,17h,5,12h,14h,19h,15h,9,0Fh,10h,1Bh,1Dh,0Dh 498 db Ctrl,1,13h,4,6,7,8,0Ah,0Bh,0Ch,';',27h,1Eh 499 db LShift,0,1Ah,18h,3,16h,2,0Eh,0Dh,',./',RShift,'*' 500 db ALT,' ',Caps 501 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 502 db k_Pause,k_Reset,None,0Bh,None,'-' 503 db 8,None,15h,'+',None,0Ah,None,9,k_Reset 504 db None,None,None,None,k_F12 505 506 a_ShiftTable db None,1Bh,'!@#$%^&*()_+',15h ; ShiftTable 507 db 9,'qwertyuiop{}',0Dh 508 db Ctrl,'asdfghjkl:"~' 509 db LShift,'|zxcvbnm<>?',RShift,'*' 510 db ALT,' ',Caps 511 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 512 db k_NumLock,k_Reset,'789-456+1230.' 513 db None,None,None,None,k_F12 514 515 a_CapsTable db None,1Bh,'1234567890-=',8 ; CapsTable 516 db 9,'qwertyuiop[]',0Dh 517 db Ctrl,'asdfghjkl;',27h,'`' 518 db LShift,'\zxcvbnm,./',RShift,'*' 519 db ALT,' ',Caps 520 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 521 db k_NumLock,k_Reset,None,0Bh,None,'-' 522 db 8,None,15h,'+',None,0Ah,None,9,4 523 db None,None,None,None,k_F12 524 525 a_CpsShfTable db None,1Bh,'!@#$%^&*()_+',15h ; CpsShfTable 526 db 9,'QWERTYUIOP[]',0Dh 527 db Ctrl,'ASDFGHJKL:"~' 528 db LShift,'|ZXCVBNM,./',RShift,'*' 529 db ALT,' ',Caps 530 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 531 db k_NumLock,k_Reset,'789-456+1230.' 532 db None,None,None,None,k_F12 533 534 a_AltTable db None,k_DosShell,'1234567890-=',8 ; AltTable 535 db 9,11h,17h,5,12h,14h,19h,15h,9,0Fh,10h,1Bh,1Dh,0Dh 536 db Ctrl,1,13h,4,6,7,8,0Ah,0Bh,0Ch,';',27h,1Eh 537 db LShift,0,1Ah,k_QuitAppler,3,16h,2,0Eh,0Dh,',./',RShift,'*' 538 db ALT,' ',Caps 539 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 540 db k_NumLock,k_Reset,None,0Bh,None,'-' 541 db 8,None,15h,'+',None,0Ah,None,9,None 542 db None,None,None,None,k_F12 543 544 a_NumTable db None,1Bh,'1234567890-=',8 ; Num Table 545 db 9,'QWERTYUIOP[]',0Dh 546 db Ctrl,'ASDFGHJKL;',27h,'`' 547 db LShift,'\ZXCVBNM,./',RShift,'*' 548 db ALT,' ',Caps 549 db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10 550 db k_NumLock,k_Reset,None,k_UpArrow,None,'-' 551 db k_LeftArrow,None,k_RightArrow,'+',None,k_DownArrow,None,k_Fire1,k_Fire2 552 db None,None,None,None,k_F12 553 554 555 556 ; 1 Home 557 ; 2 End 558 ; 3 PgUp 559 ; 4 PgDn 560 ; 5 Left 561 ; 6 Right 562 ; 7 Up 563 ; 8 Down 564 ; 9 Ins 565 ; A Del 566 ; B BS 567 ; C Esc 568 ; D Tab 569 ; E F1 570 ; F F2 571 ; 10 F3 572 ; 11 F4 573 ; 12 F5 574 ; 13 F6 575 ; 14 F7 576 ; 15 F8 577 ; 16 F9 578 ; 17 F10 579 ; 18 Enter 580 ; 19 Cntr 581 ; 1A Dos Shell 582 ; 1B Quit 583 584 d_NormalTable db None,0Ch,'1234567890-=',0Bh 585 db 0Dh,'qwertyuiop[]',18h 586 db Ctrl,'asdfghjkl;',27h,'`' 587 db LShift,'\zxcvbnm,./',RShift,'*' 588 db ALT,' ',Caps 589 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 590 db k_NumLock,None,1,7,3,'-' 591 db 5,19h,6,'+',2,8,4,9,0Ah 592 db None,None,None,None,None 593 594 d_ShiftTable db None,0Ch,'!@#$%^&*()_+',0Bh 595 db 0Dh,'QWERTYUIOP{}',18h 596 db Ctrl,'ASDFGHJKL:"~' 597 db LShift,'|ZXCVBNM<>?',RShift,'*' 598 db ALT,' ',Caps 599 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 600 db k_NumLock,None,1,7,3,'-' 601 db 5,19h,6,'+',2,8,4,9,0Ah 602 db None,None,None,None,None 603 604 d_CapsTable db None,0Ch,'1234567890-=',0Bh 605 db 0Dh,'QWERTYUIOP[]',18h 606 db Ctrl,'ASDFGHJKL;',27h,'`' 607 db LShift,'\ZXCVBNM,./',RShift,'*' 608 db ALT,' ',Caps 609 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 610 db k_NumLock,None,1,7,3,'-' 611 db 5,19h,6,'+',2,8,4,9,0Ah 612 db None,None,None,None,None 613 614 d_CpsShfTable db None,0Ch,'!@#$%^&*()_+',0Bh 615 db 0Dh,'qwertyuiop{}',18h 616 db Ctrl,'asdfghjkl:"~' 617 db LShift,'|zxcvbnm<>?',RShift,'*' 618 db ALT,' ',Caps 619 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 620 db k_NumLock,None,1,7,3,'-' 621 db 5,19h,6,'+',2,8,4,9,0Ah 622 db None,None,None,None,None 623 624 d_AltTable db None,1Ah,'1234567890-=',0Bh 625 db 0Dh,'qwertyuiop[]',18h 626 db Ctrl,'asdfghjkl;',27h,'`' 627 db LShift,'\z',1Bh,'cvbnm,./',RShift,'*' 628 db ALT,' ',Caps 629 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 630 db k_NumLock,None,1,7,3,'-' 631 db 5,19h,6,'+',2,8,4,9,0Ah 632 db None,None,None,None,None 633 634 k_NormalTable db None,'..............' 635 db '..............' 636 db Ctrl,'............' 637 db LShift,'...........',RShift,'.' 638 db ALT,'.',Caps 639 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 640 db k_NumLock,None,'....' 641 db '.........' 642 db None,None,None,None,None 643 644 k_AltTable db None,1Ah,'.............' 645 db '..............' 646 db Ctrl,'............' 647 db LShift,'..',1Bh,'........',RShift,'.' 648 db ALT,'.',Caps 649 db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h 650 db k_NumLock,None,'....' 651 db '........',1Bh 652 db None,None,None,None,None 653 Keyboard ends 654 655 656 657 SimKbd segment public 658 assume cs:SimKbd,ds:SimKbd,es:Emulate 659 660 ; Entry: 661 ; DS:SI -> keys 662 ; CF -- keys format type: 1 - single, 0 - double 663 SimKbdRq proc far 664 push ax cx dx 665 mov al,0 666 jnc SKR_1 667 inc al 668 SKR_1: mov cs:SK_SpeedType,al 669 mov word ptr cs:SK_Address,si 670 mov word ptr cs:SK_Address[2],ds 671 xor ax,ax 672 mov al,cs:SK_Speed 673 mov cx,cs 674 mov dx,offset SimKbdTimer 675 call TimerReq 676 pop dx cx ax 677 ret 678 SimKbdRq endp 679 680 SimKbdClrKeys db 0 681 SimKbdClr proc far 682 push si ds 683 push cs 684 pop ds 685 mov si,offset SimKbdClrKeys 686 stc 687 call SimKbdRq 688 pop ds si 689 ret 690 SimKbdClr endp 691 692 key_taken proc far 693 mov cs:SK_WaitFlag,0 694 ret 695 key_taken endp 696 697 SK_SpeedType db 1 698 SK_Address dd ? 699 SK_Speed db 1 700 SK_WaitFlag db 0 701 SimKbdTimer proc far 702 mov ax,seg C000 703 mov es,ax 704 lds si,cs:SK_Address 705 cmp cs:SK_WaitFlag,0 706 jz SK_ok 707 mov ax,1 708 mov cx,cs 709 mov dx,offset SimKbdTimer 710 call TimerReq 711 ret 712 SK_ok: cld 713 lodsb 714 or al,al 715 jz SK_Ret 716 cmp al,0FFh 717 jne SK_DoIt 718 lodsb 719 mov cs:SK_Speed,al 720 jmp SK_CallRq 721 SK_DoIt: mov es:C000,0 722 call far ptr Key 723 mov bl,es:C000 724 mov cs:SK_WaitFlag,bl 725 mov bx,seg TimerFlags 726 mov es,bx 727 assume es:seg TimerFlags 728 or es:TimerFlags,ax 729 cmp cs:SK_SpeedType,1 730 je SK_CallRq 731 lodsb 732 mov cs:SK_Speed,al 733 SK_CallRq: cmc 734 call SimKbdRq 735 SK_Ret: ret 736 SimKbdTimer endp 737 738 ;------------------------------------------------------ Recording & Playback --- 739 740 ; Entry: 741 ; ES:DI -> buffer 742 ; CX -- buffer length 743 StartRecord proc far 744 push ax ds 745 push cs 746 pop ds 747 mov RK_RecordAddrLo,di 748 mov RK_RecordAddrHi,es 749 mov RK_MaxRecord,cx 750 mov RK_InitialCount,cx 751 mov ax,40h 752 mov ds,ax 753 mov ax,word ptr ds:[6Ch] 754 mov cs:RK_RecordTime,ax 755 pop ds ax 756 ret 757 StartRecord endp 758 759 760 RK_InitialCount dw 0 761 762 ; Exit: 763 ; CX -- recorded keys count 764 StopRecord proc far 765 push ax di es 766 mov cx,cs:RK_InitialCount 767 sub cx,cs:RK_MaxRecord 768 xor ax,ax 769 mov cs:RK_MaxRecord,ax 770 les di,cs:RK_RecordAddr 771 inc ax 772 stosw 773 pop es di ax 774 ret 775 StopRecord endp 776 777 778 RK_RecordAddr label dword 779 RK_RecordAddrLo dw 0 780 RK_RecordAddrHi dw 0 781 RK_RecordTime dw 0 782 RK_MaxRecord dw 0 783 RK_GoToDebug db 0FFh,1,38h,3Bh,0B8h 784 db 1Fh,14h,18h,19h,2Ah,02h,0AAh,39h,30h,16h,21h 785 DB 21h,12h,13h,39h,21h,16h,26h,26h,2Ah,02h,0AAh 786 db 0 787 788 ; Entry: 789 ; AL -- key to be recorded 790 RecordKey proc far 791 push ax bx di ds es 792 push cs 793 pop ds 794 cmp RK_MaxRecord,0 795 jz RK_ret 796 mov bx,40h 797 mov es,bx 798 mov bx,word ptr es:[6Ch] 799 xchg bx,RK_RecordTime 800 sub bx,RK_RecordTime 801 neg bx 802 or bx,bx 803 jnz RK_1 804 inc bx 805 RK_1: or bh,bh 806 jz RK_2 807 mov bl,0FFh 808 RK_2: les di,RK_RecordAddr 809 cld 810 mov ah,al 811 mov al,bl 812 stosw 813 mov RK_RecordAddrLo,di 814 dec RK_MaxRecord 815 jnz RK_Ret 816 call StopRecord 817 mov si,offset RK_GoToDebug 818 stc 819 call SimKbdRq 820 RK_ret: pop es ds di bx ax 821 ret 822 RecordKey endp 823 824 SimKbd ends 825 826 end