是否可以更快地检测和收集键盘制动器和制动器,而不仅仅是从硬件端口60h读取?
每当我按下一个键,让我们说“W”键,然后很快按下另一个键,“W”键的中断代码仍然由端口60h返回。
在我正在编写的游戏中,当用户试图快速改变方向时,这具有锁定玩家精灵的效果。
我尝试使用int 16h函数01h以及int 16h函数00,但与端口60h相比,它非常不稳定和缓慢。
这是我使用端口60h的输入代码。我只是将扫描码传递给bp。我需要用户输入的所有程序都检查bp中的扫描码。
HANDLE_INPUT PROC
;CLEARS THE KEYBOARD TYPEHEAD BUFFER AND COLLECTS A SCANCODE
;ALTERS BP
push ax
push es
mov ax, 40h
mov es, ax ;access keyboard data area via segment 40h
mov WORD PTR es:[1ah], 1eh ;set the kbd buff head to start of buff
mov WORD PTR es:[1ch], 1eh ;set the kbd buff tail to same as buff head
;the keyboard typehead buffer is now cleared
xor ah, ah
in al, 60h ;al -> scancode
mov bp, ax ;bp -> scancode, accessible globally
pop es
pop ax
ret
HANDLE_INPUT ENDP
这是使用int 16h的备用版本,与使用端口60h的上述版本几乎没有效果。
HANDLE_INPUT PROC
;COLLECTS A SCANCODE
;ALTERS BP
push ax
xor bp, bp ;clear out bp
mov ah, 1 ;Function 1, check key status.
int 16h ;Is a key ready?
jz NO_KEY ;If zf cleared, then no.
xor ah, ah ;Otherwise, a key is waiting.
int 16h ;ah -> scancode
xor al, al
xchg al, ah ;ax -> scancode
mov bp, ax ;bp -> scancode, accessible globally
NO_KEY:
pop ax
ret
HANDLE_INPUT ENDP
答案 0 :(得分:1)
要回答我自己的问题,通过端口60h提供的扫描码实际上并不太慢,它们太快了。
在我的问题中给出的以下示例中:"每当我按下一个键时,让我们说'W' W'键,然后很快按下另一个键,' W'密钥仍然由端口60h返回。"
我认为端口60h仍然返回了W' W'是因为键盘控制器没有足够的时间来记录我敲了一把新钥匙的事实。
实际上,我先按下另一个键,然后确实返回了密钥的make代码。然后,一瞬间,我的手指从W' W'密钥重写端口60h返回的字节与' W'打破代码。
解决方案:如果它们与已存储在bp中的生成代码相对应,则仅兑现中断代码。
新的HANDLE_INPUT程序,现在工作得更好:
HANDLE_INPUT PROC
;CLEARS THE KEYBOARD TYPEHEAD BUFFER AND COLLECTS A SCANCODE
;ALTERS BP
push ax
push bx
push es
mov ax, 40h
mov es, ax ;access keyboard data area via segment 40h
mov WORD PTR es:[1ah], 1eh ;set the kbd buff head to start of buff
mov WORD PTR es:[1ch], 1eh ;set the kbd buff tail to same as buff head
;the keyboard typehead buffer is now cleared
xor ah, ah
in al, 60h ;al -> scancode
test al, 80h ;Is a break code in al?
jz ACCEPT_KEY ;If not, accept it.
;If so, check to see if it's the break code
;that corresponds with the make code in bp.
mov bx, bp ;bx -> make code
or bl, 80h ;change make code into it's break code
cmp bl, al ;Do the new and old break codes match?
je ACCEPT_KEY ;If so, accept the break code.
pop es ;If not, bp retains old make code.
pop bx
pop ax
ret
ACCEPT_KEY:
mov bp, ax ;bp -> scancode, accessible globally
pop es
pop bx
pop ax
ret
HANDLE_INPUT ENDP