0

I have this code:

bits 16

org 0x7C00
start: jmp main

key: dw 0x1e, 'a', 0x30, 'b'

print:
    mov ah, 0x0E
    int 0x10

keyboard:
    cli
    in al, 0x64
    test al, 1
    jz return
    test al, 0x20
    jnz return

    in al, 0x60

    call convert

    call print
    sti

convert:
    mov bx, 0
    .LOOP:
        cmp al, [key+bx]
        je .conv
        add bx, 2
        jmp .LOOP
    .conv:
        mov al, [key+bx+1]
        ret

return:
    ret

main:
    call keyboard
    jmp main

times 510 - ($-$$) db 0
dw 0xAA55

It checks for keypressess and everytime I press a key, I save it to register al and then wanna print it out.

But it is only the scancode that gets saved and i need to replace it with ASCII character, I do that with the array 'key', but it doesn't work and only prints out only 1 key and then the program just lags.

Jiří Velek
  • 153
  • 2
  • 12
  • Of course, if you press keys it doesn't recognize. You only have one exit condition: when it finds a match for the keycode. If it doesn't it will go on and on through the memory until it finds one. And if there isn't one in that segment of memory it will loop forever. – Sami Kuhmonen Sep 28 '16 at 09:40
  • I only press a and b.. – Jiří Velek Sep 28 '16 at 09:40
  • 3
    Maybe you want an array of bytes (`db`)? – Margaret Bloom Sep 28 '16 at 09:49
  • Also 0x9c for key b sounds a bit strange – Sami Kuhmonen Sep 28 '16 at 09:55
  • True, @Sami is right: you need both make and break scancodes. Or just change the exit condition on the loop. – Margaret Bloom Sep 28 '16 at 09:56
  • 1
    Maybe you should consider 256 bytes long table: `scancode_to_ascii: db ascii_char_for_scancode_0, ascii_char_for_scancode_1, ...` Then convert will be: `xor bx,bx mov bl,al mov al,[scancode_to_ascii+bx]` ... BTW, the `in` instruction doesn't "wait" for some keydown, so you are trying to print even "no scancode" values. – Ped7g Sep 28 '16 at 10:24

1 Answers1

0

I fixed it by separating keydowns and keyups The code:

bits 16

org 0x7C00
mov cl, 0
start: jmp main

keydown: db 0x1e, 'a', 0x30, 'b'

keyup: db 0x9e, 'a', 0xb0, 'b'

print:
    mov ah, 0x0E
    int 0x10

keyboard:
    cli
    in al, 0x64
    test al, 1
    jz return
    test al, 0x20
    jnz return

    in al, 0x60

    cmp cl, 0
    je keypress
    jmp keyrelease

keyrelease:
    mov cl, 0
    sti
    ret

keypress:
    mov cl, 1
    call convert
    call print
    sti
    ret

convert:
    mov bx, 0
    .LOOP:
        cmp al, [keydown+bx]
        je .conv
        add bx, 2
        jmp .LOOP
    .conv:
        mov al, [keydown+bx+1]
        ret

return:
   ret

main:
    call keyboard
    jmp main

    times 510 - ($-$$) db 0
    dw 0xAA55
Jiří Velek
  • 153
  • 2
  • 12
  • 2
    Glad you solved your problem, but for future readers I'm compelled to mention that this is a very **poor** method for telling break from make scancodes. Testing bit7 of the scancode (set on "ketrelease") is the only way to go. Some key sends multiple scancodes! Also in general the code in this answer is clumsy at best. – Margaret Bloom Sep 28 '16 at 11:22
  • I know it's bad code, I'm new to assembly language, but thank you for your help! – Jiří Velek Sep 28 '16 at 12:29