diff options
Diffstat (limited to 'src/interrupt.c')
-rw-r--r-- | src/interrupt.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/src/interrupt.c b/src/interrupt.c index c417117..98ac2fb 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -1,43 +1,33 @@ #include "interrupt.h" #include "string.h" -#include "vga.h" -#include "bees.h" -#include "printf.h" -#include "keyboard.h" struct port pic_master_command = {0x20, port8bit_slow}; struct port pic_master_data = {0x21, port8bit_slow}; struct port pic_slave_command = {0xA0, port8bit_slow}; struct port pic_slave_data = {0xA1, port8bit_slow}; -struct port ps2_port = {0x60, port8bit}; - struct gate_desc idt[256] = {0}; -#define PIC_EOI 0x20 - void irq_end(uint8_t int_number) { if (int_number >= 0x28) port_write(pic_slave_command, PIC_EOI); port_write(pic_master_command, PIC_EOI); } -uint8_t ps2_read() { - return port_read(ps2_port); -} -uint32_t handle_int(uint8_t int_number, uint32_t idk, uint32_t esp) { - switch (int_number) { - case 0x0D: - // bye - bees("general protection fault"); - break; - case 0x21: - keyboard_event(&ps2_read); - irq_end(int_number); - break; - } +uint32_t handle_int(irqh_t *int_handler, uint8_t int_number, uint32_t esp) { + + port_write(pic_master_data, 0xFF); // mask all IRQs + start_interrupts(); // reenable interrupts + + if (int_handler != NULL) (*int_handler)(); + irq_end(int_number); + + // call event loop here + + clear_interrupts(); + port_write(pic_master_data, INT_MASK); // restore normal interrupt mask return esp; } @@ -61,16 +51,30 @@ void interrupt_init() { for (uint16_t i = 0; i < 256; i++) set_int_desc_entry(i, code_seg, &int_ignore, 0, IDT_INTERRUPT_GATE); - // Put the interrupt handlers in the IDT - set_int_desc_entry(0x20, code_seg, &handle_irq0x00, 0, IDT_INTERRUPT_GATE); - set_int_desc_entry(0x21, code_seg, &handle_irq0x01, 0, IDT_INTERRUPT_GATE); - set_int_desc_entry(0x0D, code_seg, &handle_irq0x0D, 0, IDT_INTERRUPT_GATE); +#define IRQH(IRQ) \ + set_int_desc_entry( \ + IRQ + 0x20, code_seg, &handle_irq ## IRQ, 0, IDT_INTERRUPT_GATE) + +#define EXCH(IRQ) \ + set_int_desc_entry( \ + IRQ, code_seg, &handle_exception ## IRQ, 0, IDT_INTERRUPT_GATE) + + IRQH(0x00); + IRQH(0x01); + + EXCH(0x00); + EXCH(0x01); + EXCH(0x02); + EXCH(0x03); + EXCH(0x06); + EXCH(0x07); + EXCH(0x08); + EXCH(0x0D); port_write(pic_master_command, 0x11); port_write(pic_slave_command, 0x11); - // (I actually don't understand how this works) - // Remap the PIC + // remap the PIC port_write(pic_master_data, 0x20); // Interrupt vector offsets port_write(pic_slave_data, 0x28); @@ -80,7 +84,7 @@ void interrupt_init() { port_write(pic_master_data, 0x01); port_write(pic_slave_data, 0x01); - port_write(pic_master_data, 0xFD); + port_write(pic_master_data, INT_MASK); port_write(pic_slave_data, 0xFF); // Load the IDT @@ -92,5 +96,9 @@ void interrupt_init() { } void start_interrupts() { - asm("sti"); + asm volatile("sti"); +} + +void clear_interrupts() { + asm volatile("cli"); } |