Page 1 of 1

Key press/release

Posted: Tue Aug 03, 2004 3:44 pm
by ManOfSteel
Hello,
I would like to know how to check, in my keyboard driver, if a key was pressed or released.
I tried to input a byte from the port 60h and tested if the MSB was set (or not) but it didn't work (the release key is also printed to screen); I tried the same with the port 64h but it didn't work neither.
Thanks for any help.

Re:Key press/release

Posted: Tue Aug 03, 2004 6:04 pm
by Gnome
The scancode you get from the keyboard controller through port 0x60 has bit 7 set if the key is released.

Re:Key press/release

Posted: Tue Aug 03, 2004 6:44 pm
by Brandon
This works great for me

Code: Select all

volatile unsigned char ScanCode;
...
void irq_01() {
        out(0x20, 0x20);   // Send EOI
        ScanCode = in(0x60);     
        if((ScanCode & 128) == 128)
                 // Released
        else
                // Pressed
}

Re:Key press/release

Posted: Tue Aug 03, 2004 10:35 pm
by Dreamsmith
Is there some reason you need to know this inside the IRQ handler? I just buffer the scancodes as they come in, and let the reading function interpret their meaning. But then I'm allergic to ISRs with more than a dozen or so instructions... ;D

Re:Key press/release

Posted: Wed Aug 04, 2004 1:52 pm
by ManOfSteel
Hello,
It is working better now (I did a silly mistake). Anyway, thanks for your replies.
I do have another question: are the keyboard break codes important in any way? Do I have to save them for later use?
Thanks for any help.

Re:Key press/release

Posted: Thu Aug 05, 2004 12:32 am
by Brendan
Hi,
ManOfSteel wrote: I do have another question: are the keyboard break codes important in any way? Do I have to save them for later use?
Thanks for any help.
Have you ever played a computer game, where you' start turning left when you put your finger on the left arrow key and continue turning until you take your finger off the left cursor key?

Normally the keyboard driver has a flag for each key, where the flag is set when it's pressed and cleared when it's released. This way software can use these flags to determine which keys are currently pressed. Also it's used to determine if one of the control, alt or shift keys are pressed - "a", "shift+a", "ctrl+a" and "alt+a" usually mean completely different things.


Cheers,

Brendan

Re:Key press/release

Posted: Fri Aug 06, 2004 3:08 am
by ManOfSteel
Hello,
Have you ever played a computer game, where you' start turning left when you put your finger on the left arrow key and continue turning until you take your finger off the left cursor key?
1- So the makecode will be the same as long as you press the same key, once you release the key, the keyboard driver will read the breakcode key and will stop doing what it was doing (turning in the example). Isn't it?
Normally the keyboard driver has a flag for each key, where the flag is set when it's pressed and cleared when it's released. This way software can use these flags to determine which keys are currently pressed. Also it's used to determine if one of the control, alt or shift keys are pressed - "a", "shift+a", "ctrl+a" and "alt+a" usually mean completely different things.
2- So these flags are for shift, ctrl, alt, num-lock, caps-lock and scroll-lock, right? What port(s) should I use to determine what flag is set or cleared?

3- In a file about the keyboard Scan Codes Set 1, I saw "left GUI" (makecode: E05B, breakcode: E0DB) and "right GUI" (makecode: E05C, breakcode: E0DC). What are these keys?

4- In my keyboard driver, I do the following:
* check if the keyboard is ready
* read a key
* check if it's a makecode or breakcode
* in case it's a makecode, I check for shift (left, right),
left ctrl, left alt, extended keys (E0 and E1) or normal keys
* in case it's a normal key, I pass it through the normal
scancode table and end (eoi)
* in case it's a shift key, I check if the keyboard is ready
(if the makecode was sent), I pass it through the shift
scancode table and end (eoi)
* in case it's a ctrl or alt, I treat it as a normal key
(for now).
I didn't implement yet the support for extended keys and breakcode

Till now, is that a decent way to do it? I would be pleased to hear your comments.

Thanks for any help.

Re:Key press/release

Posted: Fri Aug 06, 2004 7:13 am
by Brendan
Hi,
ManOfSteel wrote: 2- So these flags are for shift, ctrl, alt, num-lock, caps-lock and scroll-lock, right? What port(s) should I use to determine what flag is set or cleared?
These "key state flags" are maintained by the keyboard driver in memory, not by any hardware.
ManOfSteel wrote: 3- In a file about the keyboard Scan Codes Set 1, I saw "left GUI" (makecode: E05B, breakcode: E0DB) and "right GUI" (makecode: E05C, breakcode: E0DC). What are these keys?
These keys would be the left GUI and right GUI keys - have a look at a (US) windows keyboard next to the alt keys.
ManOfSteel wrote: 4- In my keyboard driver, I do the following:
* check if the keyboard is ready
* read a key
* check if it's a makecode or breakcode
* in case it's a makecode, I check for shift (left, right),
left ctrl, left alt, extended keys (E0 and E1) or normal keys
* in case it's a normal key, I pass it through the normal
scancode table and end (eoi)
* in case it's a shift key, I check if the keyboard is ready
(if the makecode was sent), I pass it through the shift
scancode table and end (eoi)
* in case it's a ctrl or alt, I treat it as a normal key
(for now).
If this is your IRQ handler then you don't need to check if the keyboard is ready (it wouldn't generate an IRQ unless it was ready).

ManOfSteel wrote: I didn't implement yet the support for extended keys and breakcode

Till now, is that a decent way to do it? I would be pleased to hear your comments.
This depends on your OS and what you want the keyboard driver to do. The keyboard driver for my OS builds a 64 bit "keypress packet" each time a key is pressed or release (and each time a key is repeated when it's held down):

; Bit/s      Description
; 0 to 7    ASCII value of keypress
; 8 to 15    Key code
; 16       Scroll lock is on if set
; 17       Number lock is on if set
; 18       Capitals lock is on if set
; 19 to 23    Unused/reserved
; 24       Left shift key is also pressed if set
; 25       Right shift key is also pressed if set
; 26       Left alt key is also pressed if set
; 27       Right alt key is also pressed if set
; 28       Left control key is also pressed if set
; 29       Right control key is also pressed if set
; 30       Key is repeat key if set
; 31       Key was released if set
; 32 to 63    UNICODE character

The steps my keyboard driver's IRQ handler take are:
- read the byte from the keyboard
- if it's an "ACK", clear the "last sent" data and EOI.
- if it's a "retry", resend the "last sent" data (unless the same data has been sent to the keyboard more than 3 times) and EOI.
- if it's a "BAT", reset the typematic rate and keyboard LEDs and EOI
- convert the received byte into a "key code" (I define a unique 8 bit key code for each key)
- if the key code is "caps lock", "scroll lock" or "numb lock", set the keyboard LEDs
- set (if make) or clear (if break) a flag in the key state table corresponding to the key code
- set the key code and pressed/released flag in the keypress packet
- set the other flags in the keypress packet
- use the keypress packet to determine the ASCII character (if any) and set it in the keypress packet
- use the keypress packet to determine the UNICODE character (if any) and set it in the keypress packet
- send a message containing the keypress packet to the user interface code


Cheers,

Brendan