Page 1 of 1

[Solved] Polling keyboard - last scancode not resetting?

Posted: Fri Jan 08, 2021 6:28 am
by probablypaul
Hi

I am polling the PS/2 keyboard for scancodes and everything is working apart from the last scancode appears to be read every time I poll the device. I can't see how I can reset it from the wiki, or if I should be doing that at all.

Here's the function where I get the scancode:

Code: Select all

    static __attribute__ ((noinline)) 
    auto pollKeyboardForScancode()
      -> uint8_t
    {
        auto scancode = char{ 0 };
        auto ps2_status = uint8_t{ 0x64 };
        auto ps2_data = uint8_t{ 0x60 };

        asm(R"(
            poll:
              in al, %b[_ps2_status]
              test al, 1            
              jz poll 
              .have_key:
                in al, %b[_ps2_data]
                mov %[_char], al   
          )"
          : [_char] "=r" (scancode)
          : [_ps2_data] "g" (ps2_data), 
              [_ps2_status] "g" (ps2_status)
          : "eax"
        );

        return scancode;
    }
I would appreciate any pointers or tips that could get me going here.

Re: Polling keyboard - last scancode not resetting?

Posted: Fri Jan 08, 2021 3:09 pm
by Octocontrabass
probablypaul wrote:I am polling the PS/2 keyboard for scancodes
Why? You really should be using interrupts instead of polling.
probablypaul wrote:and everything is working apart from the last scancode appears to be read every time I poll the device.
Your inline assembly is wrong. Assuming you can even get it to compile, the compiler assumes it will always read the same value. You should use a function like this:

Code: Select all

static inline uint8_t inb( uint16_t port )
{
    uint8_t ret;
    asm volatile( "in %0, %1" : "=a"(ret) : "Nd"(port) );
    return ret;
}
This is the only part that needs to be inline assembly; the rest you can write in ordinary C++.

Re: Polling keyboard - last scancode not resetting?

Posted: Fri Jan 08, 2021 6:10 pm
by probablypaul
Thanks for the reply!
Why? You really should be using interrupts instead of polling.
Yes, this isn't the way, but I am going from baby steps so am planning on getting to interrupts. I've just ventured out of playing in 16 bit real mode asm and will probably periodically seek refuge back there.
Your inline assembly is wrong. Assuming you can even get it to compile, the compiler assumes it will always read the same value. You should use a function like this:
I have inb/outb functions, I really should just use those - good point. Thanks for the hint about the compiler assuming the same value, I have added the volatile keyword to my inline asm and it works as expected now - no more endlessly repeating characters!

Cheers!