Page 1 of 2

Problem with keyboard driver

Posted: Fri Aug 27, 2004 5:43 pm
by beyondsociety
For weeks Ive been trying to write a basic keyboard driver. On my first attempt I polled the keyboard and was successful in outputing characters to the screen when a key was pressed.

When I modified the code to work with interrupts, I was unable to get anything to print out when a certain key was pressed. Does any body know what could be wrong?

Thanks in advance.

Re:Problem with keyboard driver

Posted: Fri Aug 27, 2004 11:22 pm
by Neo
The keyboard IRQ number is at 0x21(hex) not 21(decimal). Also you might want to consider calling the C functioon from within an ASM wrapper with EOI etc.

Re:Problem with keyboard driver

Posted: Sat Aug 28, 2004 7:31 am
by Neo

Code: Select all

if(shift)    // Same as if(shift == 1)
Just thought i'd mention this, your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.

Re:Problem with keyboard driver

Posted: Sat Aug 28, 2004 9:24 am
by beyondsociety
The keyboard IRQ number is at 0x21(hex) not 21(decimal). Also you might want to consider calling the C functioon from within an ASM wrapper with EOI etc.
I changed the 21(decimal) to 0x21(hex) and it didnt make a difference. My ASM wrapper calls the C function and sends an EOI at the end.
Just thought i'd mention this, your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.
I guess, not too sure what your mean.

Re:Problem with keyboard driver

Posted: Wed Sep 01, 2004 4:34 pm
by SystemHalted
after your code in c do an outb 0x20,0x20
at the end of the wrapper code is there iret

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 12:28 am
by Dreamsmith
beyondsociety wrote:
Just thought i'd mention this, your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.
I guess, not too sure what your mean.
The comment on this line is false:

Code: Select all

if(shift)    // Same as if(shift == 1)
A true comment would say this:

Code: Select all

if(shift)    // Same as if(shift != 0)

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 7:22 am
by gaf
Hi beyondsociety,
since your code worked when you were polling the keyboard, I suppose that there's a problem with the way you set up your interrupt handler. Change the ISR so that it simply prints a message to the screen. Is the message printed when you press a key ? If not - is the message printed when the ISR is called manually (asm: int 0x21) ? Make sure that interrupts are enabled after all. If it still doesn't work, please post the code of install_handlers() and irq_mask().

regards,
gaf

btw: Why are you calling the ISR at the end of your ini-code ? Maybe this confuses the PIC...

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 8:45 am
by Candy
@dreamsmith:
a real comment would say what the code intends to do (and should do), not what it does. The comment would best be:

if (shift) { // if the combination of caps lock and shift should produce a shifted value

But this guesses as to what the shift value stands for.

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 10:45 am
by Dreamsmith
Candy wrote:a real comment would say what the code intends to do (and should do), not what it does.
Indeed. I was simply clarifying Neo's comment about how what the comment says is false, by showing what a similar but true comment would say.

Point in fact, that particular comment shouldn't be there at all. Whether something else should be there instead is debatable. As Allen Holub points out in his book Enough Rope to Shoot Yourself in the Foot (which ought to be required reading for any C/C++ programmer), unnecessary comments distract attention away from important comments. Always comment when you should, but never comment when you shouldn't. And, as you say, a comment should never explain what code does -- the code explains what it does precisely. A comment needs to explain why...

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 11:41 am
by Neo
Dreamsmith wrote:
Candy wrote:a real comment would say what the code intends to do (and should do), not what it does.
Indeed. I was simply clarifying Neo's comment about how what the comment says is false, by showing what a similar but true comment would say.
<from earlier post>...your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.</from earlier post>

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 12:15 pm
by Dreamsmith
Neo wrote:<from earlier post>...your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.</from>
Right, and I thought that was perfectly clear myself, but beyondsociety responded:
I guess, not too sure what your mean.
Thus, my attempt to clarify further by using an example.

Okay, now that we've disected that thread to death... ::)

Re:Problem with keyboard driver

Posted: Thu Sep 02, 2004 12:22 pm
by Neo
Righto! :)

Re:Problem with keyboard driver

Posted: Fri Sep 03, 2004 2:37 pm
by Neo
BTW beyond inf, why are you calling the handler from your init() function?
Your handler should only be called when an INT is generated by the keyboard controller.

Re:Problem with keyboard driver

Posted: Fri Sep 03, 2004 6:22 pm
by IRBMe
I'm new to os dev so please excuse any innacurate information, but what I would do is first make sure that the interrupt handler is infact properly installed.

With bochs you can run the debug version, control+c to halt execution, then type "info idt 33" which will write out entry 0x21 in the interrupt table. Check that the values make sense. Just to double check, I would then "disas" (disassemble) the first couple of bytes at the address written in the interrupt table and make sure that your asm code for your interrupt handler is indeed there.

Assuming that's ok, I would then place some code in the interrupt handler which does something very simple that you can recognise such as print some text to the screen (make sure that does actually work!) and try to using a software itnerrupt like so:

Code: Select all

__asm__ __volatile ("int $33");
If that doesn't work, then make sure interrupts are enabled. heh. If they are, something in your idt must be wrong. Double check every detail of it.

If that does work however, but the interrupt doesn't fire when you press a key on the keyboard, then I would suspect your PIC code. The interrupt itself works fine as shown by the software interrupt, but the hardware doesn't fire it - dead give away that it's the PIC. I wouldn't really know how to debug that other than to go over the PIC code very closely and make double sure that everything is correct. Another thing to watch out for is to make sure that the keyboard IRQ line is unmasked (IRQ number 1, the second one, if i recall correctly).

I see you mentioned it above, but for completenes, remember to send the EOI command word to the PIC (for the keyboard line - just the master). Even if that's wrong though, it should still work once at least.

That's about all I can suggest. I have a few minor hitches when setting up my keyboard driver, but I got it all working perfectly in the end using those simple debugging techniques.

Good luck.

Re:Problem with keyboard driver

Posted: Sat Sep 04, 2004 10:31 am
by beyondsociety
since your code worked when you were polling the keyboard, I suppose that there's a problem with the way you set up your interrupt handler. Change the ISR so that it simply prints a message to the screen. Is the message printed when you press a key ? If not - is the message printed when the ISR is called manually (asm: int 0x21) ? Make sure that interrupts are enabled after all. If it still doesn't work, please post the code of install_handlers() and irq_mask().

regards,
gaf

btw: Why are you calling the ISR at the end of your ini-code ? Maybe this confuses the PIC...
The reason it wasnt doing anything at all, was because I had previously been working on my delay function and I left it running, problem solved as interrupts are working. Tested by printing a message to the screen from my keyboard handler.

Though when my code gets to this

Code: Select all

if(ascii_key != 0)
         putc(ascii_key);
It prints out a

Code: Select all

{ 
which tells me that theres maybe something wrong with my keyboard map, is this so?

NEO
BTW beyond inf, why are you calling the handler from your init() function? Your handler should only be called when an INT is generated by the keyboard controller.
I dont know, I guess its a stupid mistake I made, happens when you code at all hours of the night. ;D

If my interrupts are working, then it should generate an interrupt which you are right.

Thanks in advance.