8086程序集

时间:2017-12-13 05:36:08

标签: assembly x86-16

是否可以更快地检测和收集键盘制动器和制动器,而不仅仅是从硬件端口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

1 个答案:

答案 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