Keyboard Interrupt
Keyboard Interrupt
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?
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
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
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
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?
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
Ok, this is the common_isr:
This is the function testfunc():
And this here enables everything:
Any ideas?
Code: Select all
common_isr:
extern testfunc
call testfunc
iret
Code: Select all
void testfunc(void)
{
asm("cli");
printk("key pressed/released\n");
send_eoi(1);
asm("sti");
}
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");
Re:Keyboard Interrupt
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?
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
Removing "sti" and "cli" does not help...
I do nothing with the second PIC. So they are all unmasked (enabled)
I do nothing with the second PIC. So they are all unmasked (enabled)
Re:Keyboard Interrupt
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.
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
Well, maybe it's helpful to look at the enable/disable_irq() code:
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...
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);
}
When I compile it with that code and disable irq 2, there's ONE message printed out, but no more...
Re:Keyboard Interrupt
shouldn't outb(PIC2 + 2, 2); be outb(PIC2 + 1, 2);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);
.......
}
Thats just a first observation (typo's just hate em'), still looking at the rest.
Re:Keyboard Interrupt
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):
That's it, now I get a message for every press&release!
Thanks for your help!
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);
Thanks for your help!
Re:Keyboard Interrupt
Your very welcome, now I can go to bed, its like 2:38am in the morning over here in australia.
Re:Keyboard Interrupt
Hehe, sorry for have having kept you so long awaken.
But I'll keep that in mind, I won't forget...
But I'll keep that in mind, I won't forget...