8086 汇编中更快的键盘扫描码检测 [英] Faster keyboard scan code detection in 8086 assembly

查看:76
本文介绍了8086 汇编中更快的键盘扫描码检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以比仅从硬件端口 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆