如何在不中断代码的情况下从键盘获得输入?即检查键盘状态

时间:2019-07-16 19:17:35

标签: assembly x86 keyboard dos bios

当前我正在使用int 16,1。由于我的代码中的某些原因,第二次我使用int 16,1(在游戏循环中),它保持在我第一次按下的相同值,无论是否仍然按下。我已经放弃了,我在问是否还有另一种方法可以在不停止代码的情况下获得键盘状态。

我尝试调试了多个小时,运行了turbo调试器,并通过多位老师进行了测试,没有找到问题的根源。

这是完整代码的要点,如果需要的话 https://gist.github.com/yuvyuv2005/09ab20fd321c70ce598d6bb4151990cf#file-nole-asm

    Proc Get_Input

    xor ax, ax
    mov ah, 1h
    int 16h
    jz noInp


    push ax
    call Check_Input
    noInp:

    ret
    endp Get_Input



    Key_Pressed EQU [bp+4]
    Proc Check_Input
    push bp
    mov bp, sp
    mov [RightMole], 0




    mov ax, Key_Pressed
    mov [Num_Pressed], al



    Num7:
    mov al, [Num_Pressed]
    sub al, "0"

    cmp al, 7
    JNE Num4



    cmp [MoleHole], 0
    JNE Num4

    push [word ptr MoleHole]
    call Remove_Mole
    inc [Scorearr+6] 
    mov [RightMole], 1

    Num4:
    mov al, [Num_Pressed]
    sub al, "0"
    cmp al, 4
    JNE Num1


cmp [MoleHole], 1
JNE Num1
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num1:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 1
JNE Num8

cmp [MoleHole], 2
JNE Num8
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num8:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 8
JNE Num5

cmp [MoleHole], 3
JNE Num5
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num5:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 5
JNE Num2

cmp [MoleHole], 4
JNE Num2
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num2:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 2
JNE Num9

cmp [MoleHole], 5
JNE Num9
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num9:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 9
JNE Num6

cmp [MoleHole], 6
JNE Num6
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num6:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 6
JNE Num3

cmp [MoleHole], 7
JNE Num3
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6] 
mov [RightMole], 1


Num3:
mov al, [Num_Pressed]
sub al, "0"
cmp al, 3
JNE finish

cmp [MoleHole], 8
JNE finish
push [word ptr MoleHole]
call Remove_Mole
inc [Scorearr+6]
mov [RightMole], 1

实际游戏循环

Game_Loop:



    call DrawMole

    ; push offset Scorearr
    ; push 0
    ; push 2
    ; call Print_str
    ; add [Scorearr+6], "0"

    ;cx is how many times i want to wait 0.55 seconds before the player loses. the number here is very high for debugging reasons, ususally its a lot lower.
    mov cx, 640

    KeyPressLoop:
        push cx



        call Get_Input
        cmp [RightMole], 1
        JE Game_Loop
        pop cx
        push 1
        call Delay


    Loop KeyPressLoop
    jmp GameOver

这是延迟功能,尽管据我所知它完全可以,但它可能也有问题。

    proc delay
    push bp
    mov bp, sp
    push ax
    push cx
    push es

    ticks equ [bp + 4]
    clock equ es:6Ch

    mov ax, 40h
    mov es, ax
    mov ax, [clock]

    mov cx, ticks
    delayLoop:
        mov ax, [clock]
    tick:
            cmp ax, [clock]
            je tick
        loop delayLoop


    pop es
    pop cx
    pop ax
    pop bp
    ret 2
    endp delay

这是一个关于mole鼠游戏的代码,因此是所有与related鼠有关的整数。

此代码是使用numpad检查用户输入的代码。从ive读取int 16,将1放入AL中按数字的ASCII值。 (使用numpad玩游戏),如果您正在运行代码,则仅在打开模拟器后才打开numlock。在dosbox上,数字锁定仅在打开dosbox之后才适用。第一次要mole鼠时,该程序有效。当第二个痣出现时,代码在“检查输入”命令中按下的最后一个按钮进入无限循环。我发现使用debug_rect proc。游戏的实际工作方式是,如果玩家在数字小键盘上按下正确的数字,游戏将移除该痣并随机绘制一个新的痣。 它适用于第一个痣,但在绘制第二个痣后陷入无限循环。

0 个答案:

没有答案