Page 1 of 1
Keyboard Interrupt
Posted: Wed Sep 25, 2002 7:40 am
by Whatever5k
I have built my own IDT with all interrupts having the same ISR (common_isr). common_isr does nothing then print a message "Key pressed"
on the screen...
Ok, I first disable interrupts, unmask IRQ1(keyboard) and enable interrupts...
When I call bochs, there is just one "Key pressed" on the screen. And when I press on the keyboard, no more messages appear. I suppose, that the one message comes even not from the keyboard, but from another interrupt (since every IDT descriptor has the same interrupt
handler).
Why do I not get the "Key pressed" messages?
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 7:43 am
by Curufir
Are you clearing the interrupt off the PIC.
Ie.
MOV AL, 0x20
OUT 0x20, AL
Or something similar. Think it won't process another IRQ until that is done.
Curufir
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 9:17 am
by Whatever5k
Ouch!
I forgot that! Ok, but then, there were endless messages printed out. I figured out, that it was the system clock and disabled that. So now I have the system clock disabled and the keyboard enabled, but when I press a key, no message is printed. Actually, no message of "key pressed" is printed out...
Why?
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 9:49 am
by PlayOS
Need to see some code for this one I think.
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 9:54 am
by Whatever5k
Ok, this is the common_isr:
Code: Select all
common_isr:
extern testfunc
call testfunc
iret
This is the function testfunc():
Code: Select all
void testfunc(void)
{
asm("cli");
printk("key pressed/released\n");
send_eoi(1);
asm("sti");
}
And this here enables everything:
Code: Select all
/* first, remap the PICs to avoid conflicts with exceptions */
remap_pics(0x20, 0x28);
printk("PICs remapped: IRQs starting at interrupt 0x20\n");
asm("cli");
disable_irq(0);
enable_irq(1);
printk("Enabled IRQ1\n");
printk("Enabling interrupts\n");
asm("sti");
Any ideas?
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:04 am
by PlayOS
I cant really see a problem, sorry.
However I dont know why you disable/enable interrupts inside of your ISR. Try removing them. I am pretty sure that only exceptions (int0-31) can happen here.
Also what is the state of your second PIC are those IRQ's masked out?
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:09 am
by Whatever5k
Removing "sti" and "cli" does not help...
I do nothing with the second PIC. So they are all unmasked (enabled)
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:14 am
by PlayOS
Well if one of them goes off then you need to send an End Of Interrupt to PIC2 as well as PIC1.
mov al, 0x20
out 0xa0, al
None of the second lot of IRQs should be going off, but it is worth the try, just disable bit 2 'disable_irq(2)' to disable them and see what happens then.
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:21 am
by Whatever5k
Well, maybe it's helpful to look at the enable/disable_irq() code:
Code: Select all
unsigned short int ocw1 = 0xFFFF; /* short int = 16 bits */
void remap_pics(int pic1, int pic2)
{
/* send ICW1 */
outb(PIC1, ICW1);
outb(PIC2, ICW1);
/* send ICW2 */
outb(PIC1 + 1, pic1); /* remap
outb(PIC2 + 2, pic2); pics */
/* send ICW3 */
outb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
outb(PIC2 + 2, 2);
/* send ICW4 */
outb(PIC1 + 1, ICW4);
outb(PIC2 + 1, ICW4);
/* disable all IRQs */
outb(PIC1 + 1, 0xFF);
}
/* enable_irq()
* sends command to PIC to enable an IRQ
*/
void enable_irq(int irq)
{
ocw1 &= ~(1 << irq); /* enable propriate bit with shifting to left
invert the thing to enable the interrupt
use AND operation to leave the other bits
as they are
*/
if (irq < 8)
outb(PIC1 + 1, ocw1&0xFF); /* AND with 0xFF to clear the high 8
bits because we send to PIC1
*/
else
outb(PIC2 + 1, ocw1 >> 8); /* move high 8 bits to low 8 bits
since we send to PIC2
*/
}
/* disable_irq()
* sends a command to PIC to disable an IRQ
*/
void disable_irq(int irq)
{
ocw1 |= (1 << irq); /* shift left to disable the propriate bit
OR to not change the mask
*/
if (irq < 8)
outb(PIC1 + 1, ocw1&0xFF); /* AND with 0xFF to clear the
high 8 bits since we send to PIC1
*/
else
outb(PIC2 + 1, ocw1 >> 8); /* move high 8 bits to low 8 bits since
we send to PIC2
*/
}
/* send_eoi()
* sends a EOI to the PICs involved in the IRQ operation
*/
void send_eoi(int irq)
{
if (irq > 7)
outb(PIC2, 0x20);
outb(PIC1, 0x20);
}
What do you think, this should work, shouldn't it?
When I compile it with that code and disable irq 2, there's ONE message printed out, but no more...
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:28 am
by PlayOS
Whatever5k wrote:
void remap_pics(int pic1, int pic2)
{
......
???/* send ICW2 */
???outb(PIC1 + 1, pic1);???/* remap
???outb(PIC2 + 2, pic2);??? pics */
???/* send ICW3 */
???outb(PIC1 + 1, 4);???/* IRQ2 -> connection to slave */
???outb(PIC2 + 2, 2);
.......
}
shouldn't outb(PIC2 + 2, 2); be outb(PIC2 + 1, 2);
Thats just a first observation (typo's just hate em'), still looking at the rest.
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:34 am
by Whatever5k
Ah right...
And...I got it!
Do you know what was wrong? Actually nothing! But: I need to tell the keyboard that I have succesfully received the code...
I did it like that (copy&paste from s.o.'s code):
Code: Select all
int scan;
register int i;
printk("key pressed/released\n");
scan = inb(0x60);
i = inb(0x61);
outb(0x61, i|0x80);
outb(0x61, i);
send_eoi(1);
That's it, now I get a message for every press&release!
Thanks for your help!
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:36 am
by PlayOS
Your very welcome, now I can go to bed, its like 2:38am in the morning over here in australia.
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:38 am
by Whatever5k
Hehe, sorry for have having kept you so long awaken.
But I'll keep that in mind, I won't forget...
Re:Keyboard Interrupt
Posted: Wed Sep 25, 2002 10:41 am
by PlayOS
Thats ok, I'm just glad that I could help you. ;D