Page 1 of 1
keyboard questions
Posted: Wed May 21, 2003 11:25 am
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:
Shouldn't it be:
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]
Re:keyboard questions
Posted: Wed May 21, 2003 12:47 pm
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
Re:keyboard questions
Posted: Wed May 21, 2003 12:50 pm
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.
Re:keyboard questions
Posted: Wed May 21, 2003 1:15 pm
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.
Re:keyboard questions
Posted: Thu May 22, 2003 4:28 am
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).
Re:keyboard questions
Posted: Sun Jun 22, 2003 5:39 pm
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?
Re:keyboard questions
Posted: Tue Jun 24, 2003 2:16 am
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 ?
Re:keyboard questions
Posted: Tue Jun 24, 2003 5:15 pm
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?
Re:keyboard questions
Posted: Wed Jun 25, 2003 12:16 am
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.
Re:keyboard questions
Posted: Wed Jun 25, 2003 12:28 am
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?
Re:keyboard questions
Posted: Wed Jun 25, 2003 12:48 am
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.
Re:keyboard questions
Posted: Wed Jun 25, 2003 1:07 am
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?