keyboard questions

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
beyondsociety

keyboard questions

Post by beyondsociety »

I been trying to get the keyboard to display a message when I press a key and it doesn't seem to work. I've been looking at chris greeses keyboard code and a few things confuse me.

Whats the difference between a buffer and a queue?
Also at the end of his keyboard_handler code, he does this:

Code: Select all

outportb(0x20, 0x20);
Shouldn't it be:

Code: Select all

outportb(0x21, 0x21);
considering the remapped interrupt for the keyboard is 0x21 and not 0x20 which is the timer interrupt?

If I leave it at outportb(0x20, 0x20); nothing happens but after a while in bochs it will show a internal buffer full error and give me the scancode. But if I change the outportb function to 0x21, tripple faults after I press a key.



[attachment deleted by admin]
tommie

Re:keyboard questions

Post by tommie »

Hi, checked your attachment, Big difference between port 0x20 and interrupt 0x21. only outportb 0x20 to port 0x20 will suffice - to acknowledge the PIC that we've taken care of the interrupt.
The 8259 PIC master controller is at port 0x20, take out the C code to reset it ie. outportb(0x21, 0x21) which causes the code to dive off into the woods and boom and is incorrect anyway!
And leave the assembler kbd handler to take care of it which you have coded - is correct!
Remember the kbd's IRQ is 1, and is <u>remapped</u> to
<b>interrupt 0x21</b>. Don't confuse the two between int 0x21 and port 0x20!

Keyboard queue is located in memory at 0x41A (in realmode) which is the tail of the queue,
the head is located at 0x41E, and to empty the queue (essentially a kbd buffer) one could code it in this
fashion in realmode, dunno if this applies to pmode though, mind you, the memory location - am a bit rusty if that's where it resides ....ie.
void clear_kbd_buf(void)
{
int far *head_q = (int far *) MK_FP(0x40, 0x1A);
int far *tail_q = (int far *) MK_FP(0x40, 0x1E);
*head_q = *tail_q;
}

and call this immediately after processing the keystroke, that's how DOS work so that typeahead is achieved.....enter too many keys and DOS beeps at you... :)

Regards,
Tommie/newbie_os_dsgnr
udarkman

Re:keyboard questions

Post by udarkman »

Code:outportb(0x20, 0x20);
Shouldn't it be:
Code:outportb(0x21, 0x21);
Nope..outportb(0x20,0x20) is right. This is EOI.This is sent to the PIC at the end of the Interrupt Service Routine so that the PIC can reset the In Service Register. Before we can return from the interrupt, we must tell the Programmable Interrupt Controller,
that we are ending the interrupt by sending an EOI (End of Interrupt 0x20) to it. As there are two
PIC's you must first establish which one to send it to. Use outportb(0x20,0x20); for PIC 1 (IRQ 0 -7)
or outportb(0xA0,0x20); for PIC 2 (IRQ 8 - 15).

And so in your keyboard_handler function outportb(0x21,0x21) must be outportb(0x20,0x20). And also you send EOI twice, once in keyboard_handler function and the other in IRQ0 handler. Not so sure but this also may couse errors.
beyondsociety

Re:keyboard questions

Post by beyondsociety »

You guys are right. I need to do a refresh course on ports and the PIC. My problem might very be that I have used the EOI twice in my code. I'll change the outportb to port 20 and get rid of the outport stuff in my interrupt handler.

I'll post my results later.
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 questions

Post by Pype.Clicker »

out(0x21,0x21) is a command to the masking feature of the master PIC. It means that only IRQ0 and IRQ5 can be transmitted to the CPU :-)

note that in the case of a slave IRQ (IRQ8 -- IRQ15), it is not enough to send 0x20 on port 0xA0 (which tells the slave PIC that it can send another interrupt request), but also 0x20 on 0x20, as the master cascaded IRQ8..15 through IRQ2 (and therefore is also waiting for the interrupt to complete).
beyondsociety

Re:keyboard questions

Post by beyondsociety »

I had some problems with enabling interrupts and now Im back working on my keyboard driver. I having sort of a problem and wondered if anybody knows whats wrong.

When I run my keyboard code in bochs and press a key on the keyboard it tripple faults. If I open up the bochs debugger and set the breakpoint to the EIP address thats crashing, run it and press a key, it doesn't tripple fault but displays this:

Code: Select all

(0) [0x00100b54] 0008:00100b54 (unk. ctxt): jmp 00100c54
<bochs:3> 00000650961e[WGUI ] enq_scancode: buffer full
00000650961e[WGUI ] enq_scancode: buffer full
What could be my problem?
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 questions

Post by Pype.Clicker »

do you know if the interrupt has been taken at that address ?

if the tripple fault come from the IRQ handling, the eip address you'll receive is the address of the instruction *being interrupted* -- which is of course not the reason of the fault ...

did you checked your IDT with some INT xx call first ?
beyondsociety

Re:keyboard questions

Post by beyondsociety »

do you know if the interrupt has been taken at that address ?
What do you mean by this?
did you checked your IDT with some INT xx call first ?
I tried this and it worked. When I remap the pics, what interrupt does the keyboard irq get remapped to? Example when I try interrupt 0x20 in my code, I get a int 14 which is an exception. Is this supposed to happen because I wonder if I havent remapped the pics right?
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 questions

Post by Pype.Clicker »

hmmm ... as 0x14==20, i would first check whether there miss a "0x" before your remapping call or not ;)

for the "has the interrupt be taken" thing, you just showed a line of code that seems correct (a jump 100 bytes further is unlikely to cause trouble :) ), but do you know if the CPU is executing code for the interrupt handler or if that instruction is from the "normal" flow.

I mean, when you got the eip value for the tripple fault, here's what could've happened:

you were gently executing code (and reached 0008:00100b54) when suddenly an IRQ arise. The cpu will then first lookup the IDT table and try to find out how to handle it. If an exception occur while performing that task, and then again another exception while trying to execute the exception, you'll find yourself in a "tripple fault" condition. The problem is that, as there's no "code address" for the exception generation internal logic, you'll just have the last value of eip that was valid before the IRQ arise as the address of the "tripple fault" ... which makes no sense.

imho, there must be something wrong with your IDT. Have you tried basic exception handling tests like generating a division by zero or loading a data segment with an 0xf001 selector and see if it raises a GPF correctly ? until this works, don't try any INT xx, and until INT xx works, do not enable IRQs.
beyondsociety

Re:keyboard questions

Post by beyondsociety »

Have you tried basic exception handling tests like generating a division by zero or loading a data segment with an 0xf001 selector and see if it raises a GPF correctly ?
How would I go about doing this?
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 questions

Post by Pype.Clicker »

Code: Select all

mov ax,0xf001   ;; try to fool the CPU
mov ds,ax
mov ax,[ds:0x12345678] ;; this should generate a GPF exception.
The GPF handler should be called with 0x****f001 on the top of the stack. display a string and halt : this prooves your GPF handler works.
beyondsociety

Re:keyboard questions

Post by beyondsociety »

hmmm ... as 0x14==20, i would first check whether there miss a "0x" before your remapping call or not
The code for my remapping of the pics was wrong but now it works. I tested the interrupt and got what I was testing.

As for my tripple fault when I press a key on the keyboard, my problem has to do something with my irq handler code or my keyboard code. Are the idt descriptors for irqs different from exceptions? If so, how different are they?
Post Reply