[Solved] Polling keyboard - last scancode not resetting?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
probablypaul
Posts: 2
Joined: Thu Dec 31, 2020 10:44 pm
Libera.chat IRC: probablypaul

[Solved] Polling keyboard - last scancode not resetting?

Post 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.
Last edited by probablypaul on Sat Jan 09, 2021 12:11 am, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Polling keyboard - last scancode not resetting?

Post 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++.
probablypaul
Posts: 2
Joined: Thu Dec 31, 2020 10:44 pm
Libera.chat IRC: probablypaul

Re: Polling keyboard - last scancode not resetting?

Post 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!
Post Reply