Initialize PIC
diff --git a/src/Makefile b/src/Makefile
index 23ef8f4..511afef 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,4 +1,14 @@
-SOURCES = boot.o main.o descriptor_tables.o mem.o vga.o gdt_flush.o idt.o interrupts.o log.o
+SOURCES = boot.o \
+ main.o \
+ descriptor_tables.o \
+ io.o \
+ vga.o \
+ gdt_flush.o \
+ idt.o \
+ interrupts.o \
+ log.o \
+ irq.o \
+ pic.o
CFLAGS = -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding -m32 -O2 -g
LDFLAGS = -Tlink.ld -melf_i386
ASMFLAGS = -felf
diff --git a/src/descriptor_tables.c b/src/descriptor_tables.c
index 36e6f8f..a9aa521 100644
--- a/src/descriptor_tables.c
+++ b/src/descriptor_tables.c
@@ -1,6 +1,7 @@
#include "descriptor_tables.h"
#include "vga.h"
-#include "mem.h"
+#include "io.h"
+#include "pic.h"
extern void gdt_flush(uint gdt);
extern void idt_flush(uint idt);
@@ -14,41 +15,14 @@
struct idt_entry idt_entries[256];
struct idt_pointer idt_pointer;
-static void (* isrs[32])() =
-{
- isr0,
- isr1,
- isr2,
- isr3,
- isr4,
- isr5,
- isr6,
- isr7,
- isr8,
- isr9,
- isr10,
- isr11,
- isr12,
- isr13,
- isr14,
- isr15,
- isr16,
- isr17,
- isr18,
- isr19,
- isr20,
- isr21,
- isr22,
- isr23,
- isr24,
- isr25,
- isr26,
- isr27,
- isr28,
- isr29,
- isr30,
- isr31
-};
+static void (*isrs[32])() = {
+ isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10,
+ isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21,
+ isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31};
+
+static void (*irqs[16])() = {irq0, irq1, irq2, irq3, irq4, irq5,
+ irq6, irq7, irq8, irq9, irq10, irq11,
+ irq12, irq13, irq14, irq15};
void init_gdt()
{
@@ -106,6 +80,25 @@
idt_flush((uint)&idt_pointer);
+ // Remap PIC
+
+ outb(PIC1_COMMAND, 0x11);
+ outb(PIC2_COMMAND, 0x11);
+
+ outb(PIC1_DATA, 0x20);
+ outb(PIC2_DATA, 0x28);
+ outb(PIC1_DATA, 0x04);
+ outb(PIC2_DATA, 0x02);
+ outb(PIC1_DATA, 0x01);
+ outb(PIC2_DATA, 0x01);
+ outb(PIC1_DATA, 0);
+ outb(PIC2_DATA, 0);
+
+ for (int i = 0; i < 16; i++)
+ {
+ idt_set_gate(i + 32, (uint)irqs[i], 0x08, 0x8e);
+ }
+
vga_write("IDT Initialized!\n");
}
diff --git a/src/descriptor_tables.h b/src/descriptor_tables.h
index 6f3fb89..d1b68bc 100644
--- a/src/descriptor_tables.h
+++ b/src/descriptor_tables.h
@@ -108,6 +108,23 @@
extern void isr30();
extern void isr31();
+extern void irq0();
+extern void irq1();
+extern void irq2();
+extern void irq3();
+extern void irq4();
+extern void irq5();
+extern void irq6();
+extern void irq7();
+extern void irq8();
+extern void irq9();
+extern void irq10();
+extern void irq11();
+extern void irq12();
+extern void irq13();
+extern void irq14();
+extern void irq15();
+
void init_descriptor_tables();
void init_idt();
diff --git a/src/interrupts.c b/src/interrupts.c
index c8ded7c..c1743d1 100644
--- a/src/interrupts.c
+++ b/src/interrupts.c
@@ -1,13 +1,6 @@
#include "kint.h"
#include "vga.h"
-
-struct registers
-{
- uint ds;
- uint edi, esi, ebp, esp, ebx, edx, ecx, eax;
- uint interrupt_number, error_code;
- uint eip, cs, eflags, useresp, ss;
-};
+#include "registers.h"
void isr_handler(struct registers regs)
{
diff --git a/src/mem.c b/src/io.c
similarity index 87%
rename from src/mem.c
rename to src/io.c
index 21afb34..1b35f71 100644
--- a/src/mem.c
+++ b/src/io.c
@@ -1,4 +1,4 @@
-#include "mem.h"
+#include "io.h"
void outb(ushort port, uchar val)
@@ -35,3 +35,8 @@
((uchar *)dest)[i] = ((uchar *)src)[i];
}
}
+
+void io_wait()
+{
+ asm volatile("outb %0, $0x80" :: "a"(0));
+}
diff --git a/src/mem.h b/src/io.h
similarity index 92%
rename from src/mem.h
rename to src/io.h
index b55eb8b..ab5ce4a 100644
--- a/src/mem.h
+++ b/src/io.h
@@ -8,3 +8,5 @@
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
+
+void io_wait();
diff --git a/src/irq.s b/src/irq.s
new file mode 100644
index 0000000..9806b1e
--- /dev/null
+++ b/src/irq.s
@@ -0,0 +1,53 @@
+ [bits 32]
+
+%macro IRQ 2
+ [global irq%1]
+irq%1:
+ cli
+ push byte 0 ; Error code
+ push byte %2 ; Interrupt number
+ jmp irq_common
+%endmacro
+
+IRQ 0, 32
+IRQ 1, 33
+IRQ 2, 34
+IRQ 3, 35
+IRQ 4, 36
+IRQ 5, 37
+IRQ 6, 38
+IRQ 7, 39
+IRQ 8, 40
+IRQ 9, 41
+IRQ 10, 42
+IRQ 11, 43
+IRQ 12, 44
+IRQ 13, 45
+IRQ 14, 46
+IRQ 15, 47
+
+ [extern irq_handler]
+irq_common:
+ pusha
+ mov ax, ds ; Save data segment
+ push eax
+
+ mov ax, 0x10 ; New segments
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ call irq_handler
+
+ pop ebx ; Old data segment
+ mov ds, bx
+ mov es, bx
+ mov fs, bx
+ mov gs, bx
+
+ popa
+ add esp, 8
+ sti
+ iret
+
diff --git a/src/pic.c b/src/pic.c
new file mode 100644
index 0000000..693c747
--- /dev/null
+++ b/src/pic.c
@@ -0,0 +1,24 @@
+#include "pic.h"
+#include "io.h"
+
+void (* interrupt_handlers[256])(struct registers);
+
+void pic_send_eoi(uchar interrupt)
+{
+ if (interrupt >= 40)
+ outb(PIC2_COMMAND, PIC_EOI);
+ outb(PIC1_COMMAND, PIC_EOI);
+}
+
+void irq_handler(struct registers regs)
+{
+ pic_send_eoi(regs.interrupt_number);
+
+ if (interrupt_handlers[regs.interrupt_number])
+ interrupt_handlers[regs.interrupt_number](regs);
+}
+
+void add_interrupt_handler(uchar interrupt, void (* handler)(struct registers))
+{
+ interrupt_handlers[interrupt] = handler;
+}
diff --git a/src/pic.h b/src/pic.h
new file mode 100644
index 0000000..ad44216
--- /dev/null
+++ b/src/pic.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "kint.h"
+#include "registers.h"
+
+#define PIC1 0x20
+#define PIC2 0xa0
+#define PIC1_COMMAND PIC1
+#define PIC1_DATA (PIC1 + 1)
+#define PIC2_COMMAND PIC2
+#define PIC2_DATA (PIC2 + 1)
+
+#define PIC_EOI 0x20 // End of input
+
+void pic_send_eoi(uchar interrupt);
+void add_interrupt_handler(uchar interrupt, void (* handler)(struct registers));
diff --git a/src/registers.h b/src/registers.h
new file mode 100644
index 0000000..687bd0e
--- /dev/null
+++ b/src/registers.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "kint.h"
+
+struct registers
+{
+ uint ds;
+ uint edi, esi, ebp, esp, ebx, edx, ecx, eax;
+ uint interrupt_number, error_code;
+ uint eip, cs, eflags, useresp, ss;
+};
diff --git a/src/vga.c b/src/vga.c
index 11fbc0c..11f3b9e 100644
--- a/src/vga.c
+++ b/src/vga.c
@@ -1,5 +1,5 @@
#include "vga.h"
-#include "mem.h"
+#include "io.h"
#include "log.h"
static uint cursor_x = 0;