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;