8086 汇编中更快的键盘扫描码检测 [英] Faster keyboard scan code detection in 8086 assembly
问题描述
是否可以比仅从硬件端口 60h 读取更快地检测和收集键盘品牌和刹车?
Is it possible to detect and collect keyboard makes and brakes faster than just reading from hardware port 60h?
每当我按下一个键时,比如说'W'键,然后很快地按下另一个键,'W'键的中断代码仍然由端口60h返回.
Whenever I press a key, let's say the 'W' key, then very quickly press another key, the break code for the 'W' key is still returned by port 60h.
在我正在编写的游戏中,当用户试图快速改变方向时,这具有将玩家精灵锁定到位的效果.
In the game i am writing, this has the effect of locking the player sprite in place when a user tries to quickly change direction.
我曾尝试将 int 16h 函数 01h 和 int 16h 函数 00 一起使用,但与端口 60h 相比,它非常不稳定且缓慢.
I have tried using int 16h function 01h along with int 16h function 00, but it's very choppy and slow compared to port 60h.
这是我使用端口 60h 的输入代码.我只是将扫描码传递给 bp.我所有需要用户输入的程序检查 bp 中的扫描码.
Here's my input code using port 60h. I just pass a scancode into bp. All my procedures that require user input check the scancode in 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 的版本.
And here's the alternate version using int 16h, doesn't work nearly as well as the above version that uses port 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
推荐答案
回答我自己的问题,通过端口 60h 提供的扫描码实际上并不是太慢,而是太快了.
To answer my own question, scancodes provided via port 60h were not actually too slow, they were too fast.
在我的问题中给出的以下示例中:每当我按下一个键时,假设是 'W' 键,然后很快按下另一个键,'W' 键的中断代码仍由端口 60h 返回."
In the following example given in my question: "Whenever I press a key, let's say the 'W' key, then very quickly press another key, the break code for the 'W' key is still returned by port 60h."
我认为端口 60h 仍然返回W"的中断代码的原因是键盘控制器没有足够的时间来记录我敲击了一个新键的事实.
I thought the reason port 60h still returned the break code for the 'W' was due to the keyboard controller not having enough time to register the fact that I had struck a new key.
实际上,我是先按下另一个键,然后确实返回了该键的 make 代码.然后,一秒钟后,我的手指从W"键上抬起,用W"中断码覆盖了端口 60h 返回的字节.
Actually, I was pressing the other key first, and the make code for the key was indeed being returned. Then, a split second later, my finger lifted from the 'W' key overwriting the byte returned by port 60h with the 'W' break code.
解决方案:只有当断码与已存储在 bp 中的通码对应时才接受断码.
The solution: Only honor break codes if they correspond with the make code already stored in bp.
新的 HANDLE_INPUT 程序,现在工作得更好:
New HANDLE_INPUT procedure, now working much better:
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
这篇关于8086 汇编中更快的键盘扫描码检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!