Initial commit
diff --git a/src/descriptor_tables.c b/src/descriptor_tables.c
new file mode 100644
index 0000000..3b121b1
--- /dev/null
+++ b/src/descriptor_tables.c
@@ -0,0 +1,124 @@
+#include "descriptor_tables.h"
+#include "vga.h"
+#include "mem.h"
+
+extern void gdt_flush(uint gdt);
+extern void idt_flush(uint idt);
+
+static void gdt_set_gate(uint i, uint base, uint limit, uchar access, uchar gran);
+static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags);
+
+struct gdt_entry gdt_entries[5];
+struct gdt_pointer gdt_pointer;
+
+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
+};
+
+void init_gdt()
+{
+ gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
+ gdt_pointer.base = (uint)&gdt_entries;
+
+ gdt_set_gate(0, 0, 0, 0, 0); // Null segment
+ gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment
+ gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment
+ gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment
+ gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment
+
+ gdt_flush((uint) &gdt_pointer);
+
+ vga_write("GDT Initialized\n");
+}
+
+static void gdt_set_gate(uint i, uint base, uint limit, uchar access, uchar gran)
+{
+ struct gdt_entry *e = &gdt_entries[i];
+
+ e->base_low = base & 0xffff;
+ e->base_middle = (base >> 16) & 0xff;
+ e->base_high = (base >> 24) & 0xff;
+
+ e->limit_low = limit & 0xffff;
+ e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
+
+ e->access = access;
+}
+
+void init_idt()
+{
+ idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
+ idt_pointer.base = (uint)&idt_entries;
+
+ memset(&idt_entries, 0, sizeof(idt_entries));
+
+ vga_write("sizeof(idt_entries) = ");
+ vga_putx(sizeof(idt_entries));
+ vga_put('\n');
+
+ vga_write("isr0 = ");
+ vga_putx((uint)isrs[0]);
+ vga_put('\n');
+
+ for (int i = 0; i < 32; i++)
+ {
+ idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
+ }
+
+ idt_flush((uint)&idt_pointer);
+
+ vga_write("IDT Initialized!\n");
+}
+
+static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
+{
+ struct idt_entry *e = &idt_entries[num];
+
+ e->base_low = base & 0xffff;
+ e->base_high = (base >> 16) & 0xffff;
+
+ e->selector = selector;
+ e->zero = 0;
+ e->flags = flags /* | 0x60 */;
+}
+
+void init_descriptor_tables()
+{
+ init_gdt();
+ init_idt();
+}