EDIT: I completely recoded my interrupt code and it works now.
I am currently developing a 32 bit C++ and assembly OS booted by grub 2. I have got as far as implementing the IDT, remapping the PIC and implementing test keyboard code. However, when I press a key I get IRQ 4(interrupt 36) instead of IRQ 1 and the cpu resets. I have debugged it in bochs and it seems to do a far jump to 246:000a during the iret instruction then resets. This is very strange because my code segment is 8 and my data segment is 16. Including the null segment, they are the only gdt selectors in the kernel.
My Keyboard code is here:
Code:
void kbd_isr()
{
unsigned char scancode = inb(0x60);
char tmp[5];
itoa(scancode,tmp,10);
puts(tmp);
}
and my irq/isr handler is here:
Code:
#include <screen.h>
#include <string.h>
#include <system.h>
#include <keyboard.h>
//extern "C" void pit_isr();
struct registers
{
unsigned int ds; // Data segment selector
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
unsigned int int_no, err_code; // Interrupt number and error code (if applicable)
unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
}__attribute__((__packed__));
extern "C"
{
void isr_handler(struct registers regs)
{
switch(regs.int_no)
{
case 33:
kbd_isr();
break;
default:
char tmp[3];
itoa(regs.int_no,tmp,16);
error((char *) "interrupt: 0x");
error(tmp);
}
if(regs.int_no > 31)
{
/* if(regs.int_no == 39 || regs.int_no == 47)
{
puts("spurious7\n");
outb(0x20,0x0B);
if(inb(0x20) & 0x80)
{
if(regs.int_no == 47)
{
puts("spurious15\n");
outb(0x20,0x20);
}
return;
}
}
*/
if(regs.int_no >= 40)
outb(0xA0,0x20);
outb(0x20,0x20);
}
}
}
My code is partly based on JamesM's tutorials, but modified a large amount.