Raw File
; _____________________________________________
; | |
; | Project: APPLER |
; | File: KEYBOARD.ASM |
; | Compiler: 16-bit TASM (2.5) |
; | |
; | Subject: Keyboard Manager |
; | |
; | Author: Emil Dotchevski |
; |_____________________________________________|
include GLOBALS.INC
include INTERFAC.INC
Keyboards group Keyboard,SimKbd
Keyboard segment public
assume cs:Keyboard, ds:Keyboard, es:Emulate, ss:Data
DATA_PORT = 60h
COMMAND_PORT = 64h
OUTPUT_FULL = 01h ; Output buffer full flag bit
INPUT_EMPTY = 02h ; Input buffer empty flag bit
DISABLE_KEYBOARD= 0ADh ; Disable keyboard command code
ENABLE_KEYBOARD = 0AEh ; Enable keyboard command code
LED_SET = 0EDh ; Set keyboard LEDs command code
ACKNOWLEDGE = 0FAh ; Keyboard ACK
TIME_OUT = 0FFFFh ; 8042 time out counter value
K_KeyboardRet1 label byte
SetLEDs proc far ; AL - LED data
push ax
mov al,DISABLE_KEYBOARD
call K_SendCommand
jc SetLEDs_Exit
mov al,LED_SET
call K_SendData
jc SetLEDs_Exit
pop ax
push ax
call K_SendData
SetLEDs_Exit: mov al,ENABLE_KEYBOARD
out COMMAND_PORT,al
pop ax
ret
SetLEDs endp
LightsData db 0
K_KeyboardRet2 label byte
K_SendCommand proc far
push ax
call WaitInputEmpty
jc K_SC_Ret
out COMMAND_PORT,al
call WaitOutputFull
jc K_SC_Ret
in al,DATA_PORT
call WaitInputEmpty
K_SC_Ret: pop ax
ret
K_SendCommand endp
K_KeyboardRet3 label byte
K_SendData proc far
push ax
call WaitInputEmpty
jc K_SD_Ret
out DATA_PORT,al
call WaitOutputFull
jc K_SD_Ret
in al,DATA_PORT
call WaitInputEmpty
K_SD_Ret: pop ax
ret
K_SendData endp
K_KeyboardRet4 label byte
K_GetData proc far
in al,DATA_PORT
call WaitInputEmpty
ret
K_GetData endp
WaitInputEmpty proc near
push ax cx
mov cx,TIME_OUT
WIE_Loop: in al,COMMAND_PORT
test al,INPUT_EMPTY
jz WIE_Exit
loop WIE_Loop
stc
WIE_Exit: pop cx ax
ret
WaitInputEmpty endp
WaitOutputFull proc near
push ax cx
mov cx,TIME_OUT
WOF_Loop: in al,COMMAND_PORT
test al,OUTPUT_FULL
jz WOF_Exit
loop WOF_Loop
stc
WOF_Exit: pop cx ax
ret
WaitOutputFull endp
k_BufferFlag db 0
k_BuffPtr1 db 0
k_BuffPtr2 db 0
k_Buffer db 64 dup (?)
ClearBuffer proc far
mov cs:k_BuffPtr1,0
mov cs:k_BuffPtr2,0
ret
ClearBuffer endp
PutBuffer proc near
test C000,10000000b
jz k_NoBuff
test k_BufferFlag,1
jz k_NoBuff
xor bx,bx
mov bl,k_BuffPtr2
mov k_Buffer[bx],al
inc bl
cmp bl,size k_Buffer
jb PB_1
xor bx,bx
PB_1: cmp bl,k_BuffPtr1
je PB_Ret
mov k_BuffPtr2,bl
jmp PB_Ret
k_NoBuff: mov C000,al
PB_Ret: ret
PutBuffer endp
GetBuffer proc far
pushf
push ax bx ds es
push cs
pop ds
cmp k_BufferFlag,0
jz GB_Ret
mov ax,Emulate
mov es,ax
xor bx,bx
mov bl,k_BuffPtr1
mov al,k_Buffer[bx]
cmp bl,k_BuffPtr2
je GB_Ret
inc bl
cmp bl,size k_Buffer
jb GB_1
xor bx,bx
GB_1: mov k_BuffPtr1,bl
mov [C000],al
GB_Ret: pop es ds bx ax
popf
ret
GetBuffer endp
get_table_ofs proc far
push ax
mov al,bl
xor bx,bx
test al,M_ALT
mov bl,2 shl 1
jnz gto_ModeOK
test al,M_CTRL
mov bl,1 shl 1
jnz gto_ModeOK
test al,M_CAPS_LOCK
jz gto_not_caps
test al,M_LEFT_SHIFT or M_RIGHT_SHIFT
mov bl,4 shl 1
jnz gto_ModeOK
mov bl,3 shl 1
jmp gto_ModeOK
gto_not_caps: test al,M_LEFT_SHIFT or M_RIGHT_SHIFT
mov bl,5 shl 1
jnz gto_ModeOK
test al,M_NUM_LOCK
mov bl,6 shl 1
jnz gto_ModeOK
xor bx,bx
gto_ModeOK: pop ax
ret
get_table_ofs endp
k_Fire1 = 80h
k_Fire2 = 81h
k_LeftArrow = 82h
k_RightArrow = 83h
k_UpArrow = 84h
k_DownArrow = 85h
None = 86h
Ctrl = 87h
Lshift = 88h
Rshift = 89h
Caps = 8Ah
ALT = 8Bh
k_Reset = 8Ch
k_Pause = 8Dh
k_F1 = 8Eh
k_F2 = 8Fh
k_F3 = 90h
k_F4 = 91h
k_F5 = 92h
k_F6 = 93h
k_F7 = 94h
k_F8 = 95h
k_F9 = 96h
k_F10 = 97h
k_DosShell = 98h
k_QuitAppler = 99h
k_F11 = 9Ah
k_F12 = 9Bh
k_NumLock = 9Ch
k_KeyPressed db 1
k_Flags dw 0
k_KeyCode db 0
k_ScanCode db 0
k_Shifts dw 0
k_Table dw k_AppleTable
k_AppleTable dw a_NormalTable ; Normal table
dw a_CtrlTable ; Ctrl pressed
dw a_AltTable ; Ctrl and Alt pressed
dw a_CapsTable ; Caps Lock mode
dw a_CpsShfTable ; Shift in Caps Lock mode
dw a_ShiftTable ; Shift mode
dw a_NumTable ; Num Lock mode
k_DebugTable dw d_NormalTable
dw d_NormalTable
dw d_AltTable
dw d_CapsTable
dw d_CpsShfTable
dw d_ShiftTable
dw d_NormalTable
k_KbdSetupTable dw k_NormalTable
dw k_NormalTable
dw k_AltTable
dw k_NormalTable
dw k_NormalTable
dw k_NormalTable
dw k_NormalTable
k_int09: push ax
in al,DATA_PORT
push ax
in al,61h
or al,11000000b
jmp $+2
out 61h,al
and al,01111111b
jmp $+2
out 61h,al
mov al,20h
out 20h,al
pop ax
call far ptr KeyStopPlay
xchg sp,bp
or [bp+6],ax
xchg sp,bp
k_int09_iret: pop ax
iret
KeyStopPlay: or al,al
js Key
call SimKbdClr
Key: push bx si ds es
push cs
pop ds
mov k_Flags,0
test k_PauseFlag,1
jnz k_KeyPause
mov bx,Emulate
mov es,bx
mov ah,al
xor bx,bx
mov bl,ah
and bl,01111111b
cmp bl,58h
ja k_ret
mov al,bl
mov bx,k_Shifts
call get_table_ofs
mov si,k_Table
mov bx,[si][bx]
xlat
mov k_KeyCode,al
or al,al
js k_SpecialKey
or ah,ah
js k_ret
or al,10000000b
call PutBuffer
k_record_ret: mov al,ah
call RecordKey
k_ret: and ah,01111111b
mov k_ScanCode,ah
mov ax,k_Flags
pop es ds si bx
retf
k_KeyPause: or al,al
js k_ret
mov k_PauseFlag,0
jmp k_ret
k_SpecialKey: cmp ah,k_OldSpcKey
je k_ret
push ax
and al,01111111b
or ah,ah
mov si,offset k_KeyOnSub
jns k_SK_on
mov si,offset k_KeyOffSub
xor ah,ah
k_SK_on: mov k_OldSpcKey,ah
xor bh,bh
mov bl,al
shl bx,1
mov ax,k_Shifts
call [si][bx]
mov k_Shifts,ax
mov k_KeyPressed,1
pop ax
jmp k_record_ret
k_OldSpcKey db 0
k_KeyOnSub dw k_Fire1_ON,k_Fire2_ON,k_LA_ON,k_RA_ON,k_UA_ON,k_DA_ON
dw k_None
dw k_Ctrl_ON,k_Lshift_ON,k_Rshift_ON,k_Caps_ON,k_ALT_ON
dw k_Reset_ON,k_Pause_ON
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
dw k_F_ON,k_F_ON
dw k_None,k_F12_ON,k_Num_ON
k_KeyOffSub dw k_Fire1_OFF,k_Fire2_OFF,k_LA_OFF,k_RA_OFF,k_UA_OFF,k_DA_OFF
dw k_None
dw k_Ctrl_OFF,k_Lshift_OFF,k_Rshift_OFF,k_Caps_OFF,k_ALT_OFF
dw k_Reset_OFF,k_None
dw k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None,k_None
dw k_None,k_None
dw k_None,k_None,k_Num_OFF
k_Ctrl_OFF: and al,not M_CTRL
k_None: ret
k_Lshift_OFF: and al,not M_LEFT_SHIFT
ret
k_Rshift_OFF: and al,not M_RIGHT_SHIFT
k_Caps_OFF: ret
k_ALT_OFF: and al,not M_ALT
ret
k_Reset_OFF: and ResetFlag,11111110b
mov C000,0
ret
k_Fire1_OFF: mov es:JoyButton1,7Fh
ret
k_Fire2_OFF: mov es:JoyButton2,7Fh
ret
k_LA_OFF: and es:JoyStick,not 00000001b
ret
k_RA_OFF: and es:JoyStick,not 00000010b
ret
k_UA_OFF: and es:JoyStick,not 00000100b
ret
k_DA_OFF: and es:JoyStick,not 00001000b
ret
k_Ctrl_ON: or al,M_CTRL
ret
k_Lshift_ON: cmp k_ScanCode,060h
je k_Lshift_ON_ret
or al,M_LEFT_SHIFT
k_Lshift_ON_ret:ret
k_Rshift_ON: cmp k_ScanCode,060h
je k_Rshift_ON_ret
or al,M_RIGHT_SHIFT
k_Rshift_ON_ret:ret
k_Caps_ON: xor al,M_CAPS_LOCK
push ax
xor LightsData,00000100b
mov al,LightsData
call SetLEDs
pop ax
ret
k_ALT_ON: or al,M_ALT
ret
k_Num_ON: xor al,M_NUM_LOCK
push ax
xor LightsData,00000010b
mov al,LightsData
call SetLEDs
test al,00000010b
mov ss:C0xxRead[2*61h], offset C0612r
mov ss:C0xxRead[2*62h], offset C0612r
mov ss:C0xxRead[2*64h], offset C0645r
mov ss:C0xxRead[2*65h], offset C0645r
jz k_Num_ON1
mov ss:C0xxRead[2*61h], offset C061r
mov ss:C0xxRead[2*62h], offset C062r
mov ss:C0xxRead[2*64h], offset C064r
mov ss:C0xxRead[2*65h], offset C065r
mov es:JoyStick,0
k_Num_ON1: pop ax
k_Num_OFF: ret
k_Fire1_ON: mov es:JoyButton1,0FFh
ret
k_Fire2_ON: mov es:JoyButton2,0FFh
ret
k_LA_ON: or es:JoyStick,00000001b
ret
k_RA_ON: or es:JoyStick,00000010b
ret
k_UA_ON: or es:JoyStick,00000100b
ret
k_DA_ON: or es:JoyStick,00001000b
ret
k_Reset_ON: test al,M_CTRL
jz k_Reset_ON_J
test ResetFlag,00000001b
jnz k_Reset_ON_J
or ResetFlag,00000001b
jmp RESET
k_Reset_ON_J: ret
k_PauseFlag db 0
k_OldIRQ db ?
k_Pause_ON: push ax
in al,21h
mov k_OldIRQ,al
mov al,11111101b
out 21h,al
mov k_PauseFlag,1
mov al,00000111b
call SetLEDs
sti
k_PauseLoop: test k_PauseFlag,1
jnz k_PauseLoop
cli
mov al,k_OldIRQ
out 21h,al
mov al,LightsData
call SetLEDs
pop ax
and al,not M_CTRL
ret
k_ProcessIDs db PID_DEBUGGER
db PID_FILE_MANAGER
db PID_FLOPPY_DISK_MANAGER
db PID_KEYBOARD_SETUP
db PID_DONT_SWITCH
db PID_DONT_SWITCH
db PID_DONT_SWITCH
db PID_DONT_SWITCH
db PID_ABOUT_SCREEN
db PID_HELP_SCREEN
db PID_DOS_SHELL
db PID_QUIT_APPLER
k_F_ON: push es
mov ax,seg RetWhere?
mov es,ax
assume es:seg RetWhere?
shr bx,1
sub bl,k_F1 and 01111111b
mov al,k_ProcessIDs[bx]
mov k_OldSpcKey,0
mov es:RetWhere?,al
or word ptr k_Flags,0000000100000000b
pop es
mov ax,k_Shifts
and al,not(M_CTRL or M_LEFT_SHIFT or M_RIGHT_SHIFT or M_ALT)
ret
assume es:Emulate
k_F12_ON: xor es:synchro_push_ax,0FAh xor 0C3h
ret
a_NormalTable db None,1Bh,'1234567890-=',8 ; Normal Table
db 9,'QWERTYUIOP[]',0Dh
db Ctrl,'ASDFGHJKL;',27h,'`'
db LShift,'\ZXCVBNM,./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,None,0Bh,None,'-'
db 8,None,15h,'+',None,0Ah,None,9,4
db None,None,None,None,k_F12
a_CtrlTable db None,1Bh,'1234567890-=',8 ; CtrlTable
db 9,11h,17h,5,12h,14h,19h,15h,9,0Fh,10h,1Bh,1Dh,0Dh
db Ctrl,1,13h,4,6,7,8,0Ah,0Bh,0Ch,';',27h,1Eh
db LShift,0,1Ah,18h,3,16h,2,0Eh,0Dh,',./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_Pause,k_Reset,None,0Bh,None,'-'
db 8,None,15h,'+',None,0Ah,None,9,k_Reset
db None,None,None,None,k_F12
a_ShiftTable db None,1Bh,'!@#$%^&*()_+',15h ; ShiftTable
db 9,'qwertyuiop{}',0Dh
db Ctrl,'asdfghjkl:"~'
db LShift,'|zxcvbnm<>?',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,'789-456+1230.'
db None,None,None,None,k_F12
a_CapsTable db None,1Bh,'1234567890-=',8 ; CapsTable
db 9,'qwertyuiop[]',0Dh
db Ctrl,'asdfghjkl;',27h,'`'
db LShift,'\zxcvbnm,./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,None,0Bh,None,'-'
db 8,None,15h,'+',None,0Ah,None,9,4
db None,None,None,None,k_F12
a_CpsShfTable db None,1Bh,'!@#$%^&*()_+',15h ; CpsShfTable
db 9,'QWERTYUIOP[]',0Dh
db Ctrl,'ASDFGHJKL:"~'
db LShift,'|ZXCVBNM,./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,'789-456+1230.'
db None,None,None,None,k_F12
a_AltTable db None,k_DosShell,'1234567890-=',8 ; AltTable
db 9,11h,17h,5,12h,14h,19h,15h,9,0Fh,10h,1Bh,1Dh,0Dh
db Ctrl,1,13h,4,6,7,8,0Ah,0Bh,0Ch,';',27h,1Eh
db LShift,0,1Ah,k_QuitAppler,3,16h,2,0Eh,0Dh,',./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,None,0Bh,None,'-'
db 8,None,15h,'+',None,0Ah,None,9,None
db None,None,None,None,k_F12
a_NumTable db None,1Bh,'1234567890-=',8 ; Num Table
db 9,'QWERTYUIOP[]',0Dh
db Ctrl,'ASDFGHJKL;',27h,'`'
db LShift,'\ZXCVBNM,./',RShift,'*'
db ALT,' ',Caps
db k_F1,k_F2,k_F3,k_F4,k_F5,k_F6,k_F7,k_F8,k_F9,k_F10
db k_NumLock,k_Reset,None,k_UpArrow,None,'-'
db k_LeftArrow,None,k_RightArrow,'+',None,k_DownArrow,None,k_Fire1,k_Fire2
db None,None,None,None,k_F12
; 1 Home
; 2 End
; 3 PgUp
; 4 PgDn
; 5 Left
; 6 Right
; 7 Up
; 8 Down
; 9 Ins
; A Del
; B BS
; C Esc
; D Tab
; E F1
; F F2
; 10 F3
; 11 F4
; 12 F5
; 13 F6
; 14 F7
; 15 F8
; 16 F9
; 17 F10
; 18 Enter
; 19 Cntr
; 1A Dos Shell
; 1B Quit
d_NormalTable db None,0Ch,'1234567890-=',0Bh
db 0Dh,'qwertyuiop[]',18h
db Ctrl,'asdfghjkl;',27h,'`'
db LShift,'\zxcvbnm,./',RShift,'*'
db ALT,' ',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,1,7,3,'-'
db 5,19h,6,'+',2,8,4,9,0Ah
db None,None,None,None,None
d_ShiftTable db None,0Ch,'!@#$%^&*()_+',0Bh
db 0Dh,'QWERTYUIOP{}',18h
db Ctrl,'ASDFGHJKL:"~'
db LShift,'|ZXCVBNM<>?',RShift,'*'
db ALT,' ',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,1,7,3,'-'
db 5,19h,6,'+',2,8,4,9,0Ah
db None,None,None,None,None
d_CapsTable db None,0Ch,'1234567890-=',0Bh
db 0Dh,'QWERTYUIOP[]',18h
db Ctrl,'ASDFGHJKL;',27h,'`'
db LShift,'\ZXCVBNM,./',RShift,'*'
db ALT,' ',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,1,7,3,'-'
db 5,19h,6,'+',2,8,4,9,0Ah
db None,None,None,None,None
d_CpsShfTable db None,0Ch,'!@#$%^&*()_+',0Bh
db 0Dh,'qwertyuiop{}',18h
db Ctrl,'asdfghjkl:"~'
db LShift,'|zxcvbnm<>?',RShift,'*'
db ALT,' ',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,1,7,3,'-'
db 5,19h,6,'+',2,8,4,9,0Ah
db None,None,None,None,None
d_AltTable db None,1Ah,'1234567890-=',0Bh
db 0Dh,'qwertyuiop[]',18h
db Ctrl,'asdfghjkl;',27h,'`'
db LShift,'\z',1Bh,'cvbnm,./',RShift,'*'
db ALT,' ',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,1,7,3,'-'
db 5,19h,6,'+',2,8,4,9,0Ah
db None,None,None,None,None
k_NormalTable db None,'..............'
db '..............'
db Ctrl,'............'
db LShift,'...........',RShift,'.'
db ALT,'.',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,'....'
db '.........'
db None,None,None,None,None
k_AltTable db None,1Ah,'.............'
db '..............'
db Ctrl,'............'
db LShift,'..',1Bh,'........',RShift,'.'
db ALT,'.',Caps
db 0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h
db k_NumLock,None,'....'
db '........',1Bh
db None,None,None,None,None
Keyboard ends
SimKbd segment public
assume cs:SimKbd,ds:SimKbd,es:Emulate
; Entry:
; DS:SI -> keys
; CF -- keys format type: 1 - single, 0 - double
SimKbdRq proc far
push ax cx dx
mov al,0
jnc SKR_1
inc al
SKR_1: mov cs:SK_SpeedType,al
mov word ptr cs:SK_Address,si
mov word ptr cs:SK_Address[2],ds
xor ax,ax
mov al,cs:SK_Speed
mov cx,cs
mov dx,offset SimKbdTimer
call TimerReq
pop dx cx ax
ret
SimKbdRq endp
SimKbdClrKeys db 0
SimKbdClr proc far
push si ds
push cs
pop ds
mov si,offset SimKbdClrKeys
stc
call SimKbdRq
pop ds si
ret
SimKbdClr endp
key_taken proc far
mov cs:SK_WaitFlag,0
ret
key_taken endp
SK_SpeedType db 1
SK_Address dd ?
SK_Speed db 1
SK_WaitFlag db 0
SimKbdTimer proc far
mov ax,seg C000
mov es,ax
lds si,cs:SK_Address
cmp cs:SK_WaitFlag,0
jz SK_ok
mov ax,1
mov cx,cs
mov dx,offset SimKbdTimer
call TimerReq
ret
SK_ok: cld
lodsb
or al,al
jz SK_Ret
cmp al,0FFh
jne SK_DoIt
lodsb
mov cs:SK_Speed,al
jmp SK_CallRq
SK_DoIt: mov es:C000,0
call far ptr Key
mov bl,es:C000
mov cs:SK_WaitFlag,bl
mov bx,seg TimerFlags
mov es,bx
assume es:seg TimerFlags
or es:TimerFlags,ax
cmp cs:SK_SpeedType,1
je SK_CallRq
lodsb
mov cs:SK_Speed,al
SK_CallRq: cmc
call SimKbdRq
SK_Ret: ret
SimKbdTimer endp
;------------------------------------------------------ Recording & Playback ---
; Entry:
; ES:DI -> buffer
; CX -- buffer length
StartRecord proc far
push ax ds
push cs
pop ds
mov RK_RecordAddrLo,di
mov RK_RecordAddrHi,es
mov RK_MaxRecord,cx
mov RK_InitialCount,cx
mov ax,40h
mov ds,ax
mov ax,word ptr ds:[6Ch]
mov cs:RK_RecordTime,ax
pop ds ax
ret
StartRecord endp
RK_InitialCount dw 0
; Exit:
; CX -- recorded keys count
StopRecord proc far
push ax di es
mov cx,cs:RK_InitialCount
sub cx,cs:RK_MaxRecord
xor ax,ax
mov cs:RK_MaxRecord,ax
les di,cs:RK_RecordAddr
inc ax
stosw
pop es di ax
ret
StopRecord endp
RK_RecordAddr label dword
RK_RecordAddrLo dw 0
RK_RecordAddrHi dw 0
RK_RecordTime dw 0
RK_MaxRecord dw 0
RK_GoToDebug db 0FFh,1,38h,3Bh,0B8h
db 1Fh,14h,18h,19h,2Ah,02h,0AAh,39h,30h,16h,21h
DB 21h,12h,13h,39h,21h,16h,26h,26h,2Ah,02h,0AAh
db 0
; Entry:
; AL -- key to be recorded
RecordKey proc far
push ax bx di ds es
push cs
pop ds
cmp RK_MaxRecord,0
jz RK_ret
mov bx,40h
mov es,bx
mov bx,word ptr es:[6Ch]
xchg bx,RK_RecordTime
sub bx,RK_RecordTime
neg bx
or bx,bx
jnz RK_1
inc bx
RK_1: or bh,bh
jz RK_2
mov bl,0FFh
RK_2: les di,RK_RecordAddr
cld
mov ah,al
mov al,bl
stosw
mov RK_RecordAddrLo,di
dec RK_MaxRecord
jnz RK_Ret
call StopRecord
mov si,offset RK_GoToDebug
stc
call SimKbdRq
RK_ret: pop es ds di bx ax
ret
RecordKey endp
SimKbd ends
end
Generated by GNU Enscript 1.6.6, and GophHub 1.3.