📄 usbkbd.asm
字号:
lsht equ 12h ; left shift code (scan code set-2)
rsht equ 59h ; right shift code (scan code set-2)
;-------------------------------;
; BaseCase only ;
;-------------------------------;
ralt equ 11h+80h ; 91 local code id. (used in scan-2 table also)
rctl equ 14h+80h ; 94 local code id. (used in scan-2 table also)
lmsft equ 1fh+80h ; 9F microsoft left key
rmsft equ 27h+80h ; A7 microsoft right key
amsft equ 2fh+80h ; AF microsoft application key
renter equ 5ah+80h ; DA local code id. (used in scan-2 table also)
;-------------------------------;
; BaseCase, Ctrl/Shift, AltCase ;
;-------------------------------;
prtsc equ 7ch+80h ; FC local code id. (used in scan-2 table also)
;-------------------------------;
; BaseCase, CtrlCase ;
;-------------------------------;
pause equ 7eh+80h ; FE local code id. (used in scan-2 table also)
;-------------------------------;
; BaseCase, ShiftCase only ;
;-------------------------------;
slash equ 4ah+80h ; CA local code id. (used in scan-2 table also)
;-------------------------------;
; BaseCase, ShiftCase, NumLock ;
;-------------------------------;
endx equ 69h+80h ; E9 local code id. (used in scan-2 table also)
left equ 6bh+80h ; EB local code id. (used in scan-2 table also)
home equ 6ch+80h ; EC local code id. (used in scan-2 table also)
insr equ 70h+80h ; F0 local code id. (used in scan-2 table also)
del equ 71h+80h ; F1 local code id. (used in scan-2 table also)
down equ 72h+80h ; F2 local code id. (used in scan-2 table also)
rght equ 74h+80h ; F4 local code id. (used in scan-2 table also)
up equ 75h+80h ; F5 local code id. (used in scan-2 table also)
pgdn equ 7ah+80h ; FA local code id. (used in scan-2 table also)
pgup equ 7dh+80h ; FD local code id. (used in scan-2 table also)
;-------------------------------;
; KEYBOARD SCANNER ;
;-------------------------------;
; input: ;
; (ah) = device id. ;
; (binary count 1...8) ;
; (bx) = 0..7FF (milisec) ;
; (ds,es) = data segment ;
; (ds:si) = pointer to 8 ;
; bytes data ;
;-------------------------------;
scanner:
pusha
mov al,80h ; 1/2/3/4/5/6/7/8 ==>> 1/2/4/8/10/20/40/80
next_id:
rol al,1
dec ah
jnz next_id
mov device_id,al ; save current device id
;-------------------------------;
; convert bits to 8 KeyCode bytes
;-------------------------------;
mov di,offset ip_buff_start
mov bx,offset cgroup:modifier_key_table+orgbase
mov cx,8 ; 8 bits to 8 byte
lodsb ; modifier byte
alog_2:
mov ah,cs:[bx] ; USBKeyCode
inc bx
shr al,1
jnc alog_1 ; key not pressed
mov [di],ah
inc di
alog_1:
loop alog_2
lodsb ; reserved byte (discard)
mov cx,6
alog_4:
lodsb
or al,al
jz alog_3 ; discard 00
cmp al,01h ; KeyboardErrorRollOver (overrun)
jnz alog_5
mov al,00h ; 1 byte to check overrun
call check_cbfull
jz sc_6 ; full, exit
mov al,scanner_flag
and al,03h
cmp al,01h
mov al,00h ; 00 = scan code set 1 overrun code
jz alog_6
mov al,0ffh ; FF = scan code set 2/3 overrun code
alog_6:
call put_char_buffer
mov last_scan_index,00h
jmp sc_6
alog_5:
stosb
alog_3:
loop alog_4
mov al,00h
stosb ; null terminated
;-------------------------------;
; set breakcode generation flag ;
;-------------------------------;
mov cx,di
mov di,offset ip_buff_start
sub cx,di
mov al,00h
repz scasb
jnz alog_3x ; found
mov al,device_id
or bk_device_id,al ; set breakcode generation flag
alog_3x:
;-------------------------------;
mov si,offset ip_buff_start
sc_3:
lodsb
or al,al
jz sc_2 ; list over, check break code
mov di,offset sc_buff_start
mov cx,sc_buff_ptr
sub cx,di
jcxz sc_5 ; scanner buffer empty
repnz scasb
jz sc_1 ; found
cmp di,offset sc_buff_end
jae sc_2 ; scanner buffer full, check break code
sc_5:
call generate_make_code
jz sc_6 ; character buffer full, exit
mov last_scan_index,al
mov [di],al ; put in scanner buffer
sub di,offset sc_buff_start
add di,offset dv_flag_start
mov al,device_id
mov [di],al ; set device info
sub di,offset dv_flag_start
add di,offset sc_flag_start
mov al,flag_byte
mov [di],al ; set flag_byte info
inc sc_buff_ptr
mov al,typematic_rate
and ax,60h ; bit 6,5 = typematic rate delay
shr ax,4
mov bx,ax
mov ax,[bx+cgroup:trd_table+orgbase]
mov repeat_rate,ax
mov repeat_counter,0000h
jmp sc_3 ; continue
sc_1:
dec di
sub di,offset sc_buff_start
add di,offset dv_flag_start
mov al,device_id
or [di],al ; set device info
jmp sc_3 ; continue
;-------------------------------;
; CHECK BREAK CODE GENERATION ;
;-------------------------------;
sc_2:
dec si
sub si,offset ip_buff_start
mov cx,si
mov si,offset sc_buff_start
sc_7:
cmp si,sc_buff_ptr
jae sc_66 ; breakcode generation over
lodsb
mov di,offset ip_buff_start
jcxz sc_4
push cx
repnz scasb
pop cx
jz sc_7 ; found, continue
sc_4:
mov di,si
dec di
sub di,offset sc_buff_start
add di,offset dv_flag_start
mov al,device_id
not al
and [di],al ; clear device info
jnz sc_7 ; continue
sub di,offset dv_flag_start
add di,offset sc_flag_start
mov al,[di]
xchg al,flag_byte ; modify flag_byte for break code generation
mov [di],al
dec si
mov al,[si]
call generate_break_code
mov al,[di]
xchg al,flag_byte ; restore flag_byte
mov [di],al
jz sc_6 ; char buffer full, exit
mov al,[si]
call discard_character
dec sc_buff_ptr
xor last_scan_index,al
jz sc_8 ; stop auto repeat
xor last_scan_index,al
sc_8:
jmp sc_7 ; continue
sc_66:
mov al,device_id
not al
and bk_device_id,al ; clear breakcode generation flag
sc_6:
popa
ret
;-------------------------------;
; DISCARD CHARACTER ;
;-------------------------------;
; input: (di) = points to scanner
; flag list ;
;-------------------------------;
discard_character:
pusha
push di ; save (di)
mov si,di
inc si
mov cx,offset sc_flag_end
sub cx,si
push cx
rep movsb ; scanner flag list sorted
pop cx
pop di ; restore (di)
sub di,offset sc_flag_start
push di ; save (di)
add di,offset dv_flag_start
mov si,di
inc si
push cx
rep movsb ; device id list sorted
pop cx
pop di ; restore (di)
add di,offset sc_buff_start
mov si,di
inc si
rep movsb ; scanner buffer list sorted
popa
ret
;-------------------------------;
; GENERATE_MAKE_CODE ;
;-------------------------------;
generate_make_code:
mov make_break_flag,'m'
jmp gc_0
;-------------------------------;
; GENERATE_BREAK_CODE ;
;-------------------------------;
generate_break_code:
mov make_break_flag,'b'
gc_0:
pusha
mov current_scan_index,al
call get_scan_code_2
mov tl0,al ; save
;------ alt,ctrl,shift check ---;
call check_alt_ctrl_shift
jz acs_7 ; not found
cmp make_break_flag,'m'
jz acs_8 ; make code
;------ left/right alt,ctl -----;
test ch,left_shift_bitx+right_shift_bitx
jnz acs_9
mov bx,sc_buff_ptr
jmp acs_10
acs_11:
dec bx ; dec scanner buffer pointer
mov al,[bx]
call get_scan_code_2
cmp al,cl ; other alt/control present ?
jz acs_7 ; yes, do not clear bit
acs_10:
cmp bx,offset sc_buff_start
jnz acs_11
acs_9:
not ch
and flag_byte,ch ; clear proper bit (alt/ctl/shift)
and [di],ch ; clear proper bit (alt/ctl/shift)
jmp acs_7
acs_8:
or flag_byte,ch ; set proper bit (alt/ctl/shift)
;-------------------------------;
; SCAN CODE 1/2/3 ;
;-------------------------------;
acs_7:
mov al,scanner_flag
and al,03h ; bit 1,0 = scan code set-1/2/3
cmp al,03h
jnz gc_1 ; check for scan code set-1/2
;------ SCAN CODE SET-3 --------;
mov al,tl0 ; scan code set 2
cmp al,pause
jnz gc_2
mov al,62h ; scan code set-3 for PAUSE key
jmp gc_3 ; goto common path
gc_2:
cmp al,prtsc
jnz gc_4
mov al,57h ; scan code set-3 for PRTSC key
jmp gc_3 ; goto common path
gc_4:
cmp al,slash
jnz gc_5
mov al,77h ; scan code set-3 for '/' key
jmp gc_3 ; goto common path
gc_5:
call check_get_num_key_pad
jnc gc_3 ; found (al) = scan code set 3
call check_get_extd_key
jnc gc_3 ; found (al) = scan code set 3
;------ SCAN CODE-3 TABLE ------;
mov al,tl0 ; scan code set-2
call get_scan_code_3 ; SCAN CODE-2 -> SCAN CODE-3
gc_3:
mov th0,al ; save scan code-3
test al,80h
jz gc_3x
call check_get_extd_scan_3_new
gc_3x:
call read_code_3_value ; read scan code-3 type value
and al,03h ; bit-1,0 = 0/1/2/3
;-------------------------------------------------------;
; (A) | MAKE CODE | AUTO REPEAT | BREAK CODE ;
;-------------------------------------------------------;
; 00 | 1 | 0 | 0 ;
;-------------------------------------------------------;
; 01 | 1 | 0 | 1 ;
;-------------------------------------------------------;
; 10 | 1 | 1 | 0 ;
;-------------------------------------------------------;
; 11 | 1 | 1 | 1 ;
;-------------------------------------------------------;
jz gc_11_0 ; make code, no auto repeat, no break code
dec al
jz gc_11_1 ; make code, no auto repeat, break code
dec al
jz gc_11_2 ; make code, auto repeat, no break code
;------ MAKE, AUTO, BREAK ------;
cmp make_break_flag,'m'
jnz gc_11_4 ; break code
jmp gc_11_0x ; make code
gc_11_2:
;------ MAKE, AUTO, NO BREAK ---;
cmp make_break_flag,'m'
jnz gc_11_6 ; no break code, ret
jmp gc_11_0x ; make code
gc_11_1:
;------ MAKE, NO AUTO, BREAK ---;
cmp make_break_flag,'m'
jz gc_11_0y ; make code
gc_11_4:
;------ BREAK CODE GENERATION --;
mov al,02h ; 2 bytes required
test ccb,40h
jz gc_11_3 ; no conversion
mov al,01h ; 1 byte required
gc_11_3:
call check_cbfull ; check if character buffer full ?
jz gc_11_6 ; character buffer full, error
test ccb,40h
jnz gc_11_7
mov al,0f0h
call put_char_buffer ; put character in character buffer
jmp gc_11_5
gc_11_7:
mov al,th0 ; restore scan code-3
call get_scan_code_1
or al,80h ; break code, bit-7 = 1
call put_char_buffer ; put data to character buffer
jmp gc_over
gc_11_0:
;------ MAKE, NO AUTO, NO BREAK-;
cmp make_break_flag,'m'
jnz gc_11_6 ; no break code, ret
gc_11_0y:
mov al,last_scan_index
cmp al,current_scan_index
jnz gc_11_0x ; no auto repeat
call get_scan_code_2
cmp al,tl0
jnz gc_11_0x ; if current code = last scan code then
or sp,sp
jmp gc_11_6 ; auto repeat, no make code
gc_11_0x:
;------ MAKE CODE GENERATION ---;
mov al,01h
call check_cbfull ; check if character buffer full ?
jz gc_11_6 ; character buffer full, error
gc_11_5:
mov al,th0 ; restore scan code-3
test ccb,40h
jz gc_11_8 ; no conversion
call get_scan_code_1
gc_11_8:
call put_char_buffer ; put character in character buffer
gc_11_6:
jmp gc_over
;-------------------------------;
; CHECK FOR SCAN CODE SET-1/2 ;
;-------------------------------;
gc_1:
mov al,tl0 ; scan code set 2
cmp al,pause
jnz gc_20
;------ PAUSE KEY PROCESSING ---;
cmp make_break_flag,'m'
jnz gc_over ; no BREAK CODE for pause_key
mov al,last_scan_index
cmp al,current_scan_index
jnz gc_19
call get_scan_code_2
cmp al,tl0
jnz gc_19 ; if current code = last scan code then exit
or sp,sp
jmp gc_over ; no AUTO REPEAT for pause_key
gc_19:
mov bx,offset cgroup:t4500+orgbase ; CtrlCase PAUSE
test flag_byte,ctl_key_bitx
jnz gc_23
mov bx,offset cgroup:t6800+orgbase ; BaseCase PAUSE
jmp gc_23
gc_20:
cmp al,prtsc
jnz gc_24
;------ PRTSC KEY PROCESSING ---;
mov bx,offset cgroup:t1112+orgbase ; AltCase PRTSC
test flag_byte,alt_key_bitx
jnz gc_23
mov bx,offset cgroup:t2223+orgbase ; CtrlShift PRTSC
test flag_byte,ctl_key_bitx+left_shift_bitx+right_shift_bitx
jnz gc_23
mov bx,offset cgroup:t4446+orgbase ; BaseCase PRTSC
jmp gc_23
gc_24:
call check_get_num_key_pad
jc gc_25 ; not inside num key pad
;------ NUMERIC KEY PROCESSING -;
mov bx,offset cgroup:t2223+orgbase ; BaseCase num key pad
test flag_byte,num_lock_bitx+left_shift_bitx+right_shift_bitx
jz gc_23
mov bx,offset cgroup:t4446+orgbase ; NumLock num key pad
test flag_byte,num_lock_bitx
jnz gc_23
mov bx,offset cgroup:t4545+orgbase ; ShiftCase num key pad
jmp gc_23
gc_25:
call check_get_extd_key
mov bx,offset cgroup:t2223+orgbase ; BaseCase extended key
jnc gc_23
;------ EXTENDED KEY PROCESSING ;
cmp tl0,slash
jnz gc_21
test flag_byte,left_shift_bitx+right_shift_bitx
jz gc_23
mov bx,offset cgroup:t4545+orgbase ; ShiftCase '/'
jmp gc_23
gc_21:
mov bx,offset cgroup:t1112+orgbase ; BaseCase regular key
;-------------------------------;
gc_23:
mov al,00h ; offset in xlat table
cmp make_break_flag,'b'
jnz gc_23x
mov al,02h ; offset in xlat table
gc_23x:
test ccb,40h ; conversion required ?
jnz gc_32 ; yes
inc al
gc_32:
db 2eh ; CS:
xlat
call check_cbfull
jz gc_over ; buffer full, error exit
;-------------------------------;
; CODE GENERATION ;
;-------------------------------;
mov al,tl0 ; scan code set-2
cmp al,pause
jnz gc_40
test flag_byte,ctl_key_bitx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -