Page 1 of 3
not unique keyboard scancodes
Posted: Sat Nov 17, 2012 9:23 am
by zgintasz
Hi,
I'm developing my OS, it's in very early stage. I'm creating keyboard driver, but I noticed some bugs. This is how I get scancode and use scancode:
Code: Select all
scancode = inportb(0x60);
if (scancode & 0x80)
{
}
else
{
cprintf("%i", scancode);
}
I noticed, that some keyboard keys has the same scancode, for example num pad 7 has the same scancode as home key, num pad 8 has the same as arrow up and etc... How to fix it
?
Thanks.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 9:47 am
by online
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 9:55 am
by zgintasz
Thanks, but which exactly section should I read
? Maybe can you show solution by the code?
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 10:44 am
by Brendan
Hi,
zgintasz wrote:This is how I get scancode and use scancode:
If you don't use an IRQ and don't check bit 0 of the PS/2 controller's status register; then there's no way for you to know if the value you're reading from IO port 0x60 is a new value (that you haven't read yet) or an old value (that you've already read one or more times before).
It's probably best to read the
wiki page about the PS/2 controller (especially the part about
receiving bytes from devices).
zgintasz wrote:I noticed, that some keyboard keys has the same scancode, for example num pad 7 has the same scancode as home key, num pad 8 has the same as arrow up and etc... How to fix it
?
This sounds like a different problem though. It sounds like you're using "scancode set 1" (which was designed for 84 key keyboards) and you need "scancode set 2". For this problem, you'd want to read the
part about translation in the wiki page about the PS/2 controller.
Cheers,
Brendan
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 11:20 am
by zgintasz
Thanks, I'm using IRQ, the big part is based on Bran's Kernel Development tutorial. I'll took at it, thanks.
EDIT: how can I use/enable scan code set 2? I can't find information.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 12:52 pm
by egos
Brendan wrote:This sounds like a different problem though. It sounds like you're using "scancode set 1" (which was designed for 84 key keyboards) and you need "scancode set 2". For this problem, you'd want to read the
part about translation in the wiki page about the PS/2 controller.
Prefixes 0xE0, 0xE1 work in set 1 (including translation) as well as in set 2.
zgintasz wrote:EDIT: how can I use/enable scan code set 2? I can't find information.
Use keyboard command 0xF0 to set scan code set. Use controller command 0x60 to clean translation bit (to disable translation).
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 12:58 pm
by SparrowOS
So, scan codes are usually 00-7F or they are E0 followed by 00-7F.
What I do is if it is an E0 scan code, I make the scan code 80-FF.
My applications, just have to worry about a one byte scan code, not multibyte.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 1:59 pm
by jnc100
Your problem (as alluded to by others) is that you ignore the e0 scancode. The line 'if (scancode & 0x80) { }' will ignore the e0 code as 0xe0 & 0x80 evaluates to true, thus the only code of a two byte scancode you read will be the second byte.
Regards,
John.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 2:09 pm
by SparrowOS
Code: Select all
U8 GetChar()
{
U8 b=InPort(0x60);
if (b==0xE0)
return 0x80+(InPort(0x60)&0x7F);
else
return b&0x7F;
}
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 2:18 pm
by Brendan
Hi,
That's broken.
SparrowOS wrote:Code: Select all
U8 GetChar()
{
U8 b=InPort(0x60);
if (b==0xE0)
return 0x80+(InPort(0x60)&0x7F); // Return 0x60, because the keyboard didn't have time to send the
// next byte and "(0x80 + 0xE0) & 0xFF = 0x60"
else
return b&0x7F;
}
Alternatively it could return a byte from the mouse! Yay.
Cheers,
Brendan
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 2:31 pm
by SparrowOS
Code: Select all
U16 GetChar()
{
U8 b0=InPort(0x60),b1=0x80;
if (b0==0xE0) {
b0=InPort(0x60);
b1=0x80;
}
if (b0&0x80)
return 0x100+b1+(b0&0x7f);
else
return b1+(b0&0x7F);
}
Yeah, keyboard and mouse get mixed-up if you don't use interrupts.
If you do, I think you need to read just one byte from 0x60 per interrupt for keyboard.
On one machine, my mouse interrupt doesn't fire, so I poll about 50 times a second. It doesn't get mixed-up because keyboard IRQ does fire.
When you write your debugger, you want to poll keyboard, not use interrupts.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 2:32 pm
by zgintasz
jnc100 wrote:Your problem (as alluded to by others) is that you ignore the e0 scancode. The line 'if (scancode & 0x80) { }' will ignore the e0 code as 0xe0 & 0x80 evaluates to true, thus the only code of a two byte scancode you read will be the second byte.
Regards,
John.
I don't think so, it just checks if the key was released(right?).
By the way, I cut that part of code just to test if it works and put it in the main function:
Code: Select all
int fail_safe=200000;
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
outportb (0x60, 0xf0);
fail_safe=200000;
while ((inportb(0x64)&2)!=0 && fail_safe>0) fail_safe--;
outportb (0x60, 2);
It doesn't work, I still get the same scancodes.
SparrowOS wrote:Code: Select all
U8 GetChar()
{
U8 b=InPort(0x60);
if (b==0xE0)
return 0x80+(InPort(0x60)&0x7F);
else
return b&0x7F;
}
then some keys(e.g. insert, home, page up, delete, end, page down, arrays) aren't recognised.
_______________________________________
IGNORE EVERYTHING TEMPORARY
. I've got another problem, I think I should fix it first. So, here is an example:
if I put this function in keyboard.c file:
Code: Select all
uint8 GetChar()
{
uint8 b=inportb(0x60);
if (b==0xE0)
return 0x80+(inportb(0x60)&0x7F);
else
return b&0x7F;
}
then I get error from GRUB, it says "Invalid or unsupported executable format". Compiler doesn't show anything bad.
if I put this function in
main file - I don't get error. Why(it's not because of only that function)
?
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 2:56 pm
by egos
SparrowOS wrote:So, scan codes are usually 00-7F or they are E0 followed by 00-7F.
??? Extra prefixes can follow before basic codes to change key meaning. You should use additional translation tables in this case.
What I do is if it is an E0 scan code, I make the scan code 80-FF.
??? No, you confuse 0xE0 with 0xF0 prefix. Moreover in set 1 and set 2 with enabled translation the "break" scan codes are produced by hardware.
My applications, just have to worry about a one byte scan code, not multibyte.
My applications use virtual key codes and accompanied key flags (led status, left/right "shift" status). Now are defined about 140 codes including some specific codes for european (one additional code: UK backslash) and japanese (five additional codes: Kana and so on) keyboards. Only keyboard driver works with multibyte predbuffer. Virtual key codes are 32-bit. They are transfering through console event queue as part of event packages.
zgintasz wrote:then I get error from GRUB, it says "Invalid or unsupported executable format".
Do you use Multiboot header in your executable module? If so, check for its location within the first 8 Kbytes.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 3:31 pm
by SparrowOS
egos wrote:SparrowOS wrote:So, scan codes are usually 00-7F or they are E0 followed by 00-7F.
??? Extra prefixes can follow before basic codes to change key meaning. You should use additional translation tables in this case.
What I do is if it is an E0 scan code, I make the scan code 80-FF.
??? No, you confuse 0xE0 with 0xF0 prefix. Moreover in set 1 and set 2 with enabled translation the "break" scan codes are produced by hardware.
My applications, just have to worry about a one byte scan code, not multibyte.
My applications use virtual key codes and accompanied key flags (led status, left/right "shift" status). Now are defined about 140 codes including some specific codes for european (one additional code: UK backslash) and japanese (five additional codes: Kana and so on) keyboards. Only keyboard driver works with multibyte predbuffer. Virtual key codes are 32-bit. They are transfering through console event queue as part of event packages.
zgintasz wrote:then I get error from GRUB, it says "Invalid or unsupported executable format".
Do you use Multiboot header in your executable module? If so, check for its location within the first 8 Kbytes.
Maybe in China it's F0. In America it's definitely E0.
Re: not unique keyboard scancodes
Posted: Sat Nov 17, 2012 4:08 pm
by Brendan
Hi,
SparrowOS wrote:egos wrote:SparrowOS wrote:So, scan codes are usually 00-7F or they are E0 followed by 00-7F.
??? Extra prefixes can follow before basic codes to change key meaning. You should use additional translation tables in this case.
What I do is if it is an E0 scan code, I make the scan code 80-FF.
??? No, you confuse 0xE0 with 0xF0 prefix. Moreover in set 1 and set 2 with enabled translation the "break" scan codes are produced by hardware.
Maybe in China it's F0. In America it's definitely E0.
For scancode set 1, 0xE0 is the first byte of a multi-byte scan code, and the highest bit of the last byte indicates if the key was released. E.g. "0xE0, 0x48 = cursor up key pressed" and "0xE0, 0xC8 = cursor up key released".
For scancode set 2, 0xE0 is the first byte of a multi-byte scan code; and 0xF0 means the key was released. E.g. "0xE0, 0x75 = cursor up key pressed" and "0xE0, 0xF0, 0x75 = cursor up key released".
Cheers,
Brendan