keyboard...

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
frank

keyboard...

Post by frank »

Hi,

I made a keyboard module for my kernel (kernel module :))
(i defined all the keys in an array)
it works fine, but I have some keys which I can not use now.
(the 2 windows keys and another one...)

they have 2 scancodes or 1 long scancode...
0xe0 0x5c is what "showkey -s" shows me.

I tried to check if it works like this:

Code: Select all

char c=0x00;

c = inportb(0x60);       // I wrote a function for reading from ports ;)

if (c==0xe0){
 c = inportb(0x60);
 if (c==0x5c){ printf('W'); }
}
It does work if I only read one scancode... so 0xe0 or 0x5c...
so is it a long scancode or not?
also, has anybody got some info about keyboards?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:keyboard...

Post by Pype.Clicker »

there are several keys that have such longs scancodes with some 0xe0 pre-pending, such as print-screen (e0 + same code as numerical '*')
Tim

Re:keyboard...

Post by Tim »

The keyboard controller will give you one interrupt per byte from the keyboard, not one interrupt per key. This means you can get as many as 6 interrupts for keys such as Pause. It won't work just doing several reads of port 0x60 and expecting to get several different bytes out; the processor in the keyboard is far slower than the CPU.

What you should do is:
On IRQ 1:
code = in(0x60)
is_break = (code & 0x80) == 0x80;
code &= ~0x80;
If NumLock key flag set then
// Some keys have different codes with NumLock on
ascii = num_lock[ code ];
Clear NumLock key flag
Return
If extended key flag set then
// Extended keys
Clear extended key flag
If code == 0x2A then
Set NumLock key flag
Return
Else
ascii = extended_keys[ code ];
Return
End if
Else if code == 0xE0 then
Set extended key flag
Return
Else
ascii = normal_keys[ code ];
Return
End if

Note that this code doesn't account for everything (e.g. shift, Caps Lock, translation of arrow keys to number with NumLock on) but it demonstrates the general approach you need.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:keyboard...

Post by Pype.Clicker »

[attachment deleted by admin]
Tim

Re:keyboard...

Post by Tim »

Ah... the NumLock stuff is a bit of a red herring. Apparently (according to HelpPC), the keyboard gives an alternate set of scan codes for some keys when NumLock is turned on. For example, for the Del key:

[table]
[tr][td][/td][td]Normal[/td][td]NumLock On[/td][/tr]
[tr][td]Make:[/td][td]E0 53[/td][td]E0 2A E0 53[/td][/tr]
[tr][td]Break:[/td][td]E0 D3[/td][td]E0 D3 E0 AA[/td][/tr]
[/table]

Your state diagram explains what I coded better than my words did, but you'll only see the E0 2A codes when NumLock is physically turned on. This NumLock behaviour is independent of turning arrow keys into numbers when NumLock is turned on; you have to do that in software.

I've just put some debugging code into my keyboard driver, and I can confirm that the scan codes for certain keys (e.g. the small cursor keys) change depending on whether the Num Lock LED is on. For example, the left arrow key: (results from an *actual* AT keyboard :) )

[table]
[tr][td][/td][td]Normal[/td][td]NumLock On[/td][/tr]
[tr][td]Make:[/td][td]E0 4B[/td][td]E0 2A E0 2B[/td][/tr]
[tr][td]Break:[/td][td]E0 CB[/td][td]E0 CB E0 AA[/td][/tr]
[/table]

I also checked the behaviour of Del and it conforms to what HelpPC says (the table at the top of my post).

I'd like to emphasise that this behaviour isn't related to arrows turning to numbers when NumLock is on: note that the codes emitted don't refer to numbers. You have to keep track of the NumLock state the same way as for Caps Lock and do the translations yourself.
frank

Re:keyboard...

Post by frank »

ok, got it working now...

the bytes of the (long) scancode are all sended seprate....
so after you received the first byte you must wait for the second one...
and if the scancode is 3 bytes, wait for the third one.

my kernel module now supports 1,2 and 3 byte long scancodes.

it returns the character. (or number if it is a special key, then it'll return a number higher then 255)
it's kinda like getch...

the scancode list and the keyboard module is 2048 bytes long , (compiled) is that big for a kernel module ?

Tnx :)

Best,
Frank
Tim

Re:keyboard...

Post by Tim »

frank wrote:the scancode list and the keyboard module is 2048 bytes long , (compiled) is that big for a kernel module ?
That's tiny! :) All my kernel drivers are at least the size of a page, i.e. 4096 bytes, and that's not including the PE headers.
Post Reply