diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 5cf73b2fdb0a90f08d73f0fc03eaf29465502d46..ab884e78741e0e6a3c5a9428c25a681baf1316f7 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -3,8 +3,8 @@ use boytacean::{
     ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH},
 };
 use sdl2::{
-    pixels::PixelFormatEnum, video::Window, AudioSubsystem, EventPump, TimerSubsystem,
-    VideoSubsystem,
+    event::Event, pixels::PixelFormatEnum, video::Window, AudioSubsystem, EventPump,
+    TimerSubsystem, VideoSubsystem,
 };
 
 /// The base title to be used in the window.
@@ -76,6 +76,7 @@ fn main() {
     let mut game_boy = GameBoy::new();
     game_boy.load_boot_default();
     game_boy.load_rom("../../res/roms/ld_r_r.gb");
+    //game_boy.load_rom("../../res/roms/opus5.gb");
 
     let mut counter = 0;
 
@@ -84,7 +85,12 @@ fn main() {
             break;
         }
 
-        while let Some(event) = graphics.event_pump.poll_event() {}
+        while let Some(event) = graphics.event_pump.poll_event() {
+            match event {
+                Event::Quit { .. } => break 'main,
+                _ => (),
+            }
+        }
 
         let mut counter_ticks = 0u32;
 
diff --git a/src/cpu.rs b/src/cpu.rs
index dc9ef41a77b19a1327712f6aba838e23a0f3400f..38a3d7d2ec55b5dd1079fdfe6d45e0f94fb2d569 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -41,8 +41,16 @@ impl Cpu {
             }
         }
 
-        println!("Implemented {}/{} instructions", implemented, INSTRUCTIONS.len());
-        println!("Implemented {}/{} extended instructions", implemented_ext, EXTENDED.len());
+        println!(
+            "Implemented {}/{} instructions",
+            implemented,
+            INSTRUCTIONS.len()
+        );
+        println!(
+            "Implemented {}/{} extended instructions",
+            implemented_ext,
+            EXTENDED.len()
+        );
 
         Cpu {
             pc: 0x0,
diff --git a/src/inst.rs b/src/inst.rs
index 17e43c9b5532088fe74096be0d36c918228e327c..93ff6fddab12d297d235db789f3ea852b68a0d62 100644
--- a/src/inst.rs
+++ b/src/inst.rs
@@ -65,7 +65,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (inc_a, 4, "INC A"),
     (dec_a, 4, "DEC A"),
     (ld_a_u8, 8, "LD A, u8"),
     (noimpl, 4, "! UNIMP !"),
@@ -73,7 +73,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (ld_b_b, 4, "LD B, B"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (ld_b_e, 4, "LD B, E"),
     (ld_b_h, 4, "LD B, H"),
     (noimpl, 4, "! UNIMP !"),
     (ld_b_mhl, 8, "LD B, [HL]"),
@@ -139,9 +139,9 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     // 0x8 opcodes
     (noimpl, 4, "! UNIMP !"),
+    (add_a_c, 4, "ADD A, C"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (add_a_e, 4, "ADD A, E"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (add_a_mhl, 8, "ADD A, [HL]"),
@@ -162,7 +162,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (sub_a_a, 4, "SUB A, A"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
@@ -208,7 +208,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     // 0xc opcodes
     (ret_nz, 8, "RET NZ"),
     (pop_bc, 12, "POP BC"),
-    (noimpl, 4, "! UNIMP !"),
+    (jp_nz_u16, 12, "JP NZ, u16"),
     (jp_u16, 16, "JP u16"),
     (call_nz_u16, 12, "CALL NZ, u16"),
     (push_bc, 16, "PUSH BC"),
@@ -216,9 +216,9 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (ret, 16, "RET"),
+    (jp_z_u16, 12, "JP Z, u16"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (call_z_u16, 12, "CALL Z, u16"),
     (call_u16, 24, "CALL u16"),
     (noimpl, 4, "! UNIMP !"),
     (rst_08h, 16, "RST 08h"),
@@ -233,9 +233,9 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
+    (jp_c_u16, 12, "JP C, u16"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (call_c_u16, 12, "CALL C, u16"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
@@ -275,7 +275,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (rst_38h, 16, "RST 38h"),
 ];
 
-pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 176] = [
+pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 256] = [
     // 0x0 opcodes
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
@@ -463,6 +463,91 @@ pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 176] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
+    // 0xb opcodes
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    // 0xc opcodes
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    // 0xd opcodes
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    // 0xe opcodes
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (set_4_a, 8, "SET 4, A"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    // 0xf opcodes
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
+    (noimpl, 4, "! UNIMP !"),
 ];
 
 fn nop(_cpu: &mut Cpu) {}
@@ -804,6 +889,16 @@ fn jr_c_i8(cpu: &mut Cpu) {
     cpu.ticks = cpu.ticks.wrapping_add(4);
 }
 
+fn inc_a(cpu: &mut Cpu) {
+    let value = cpu.a.wrapping_add(1);
+
+    cpu.set_sub(false);
+    cpu.set_zero(value == 0);
+    cpu.set_half_carry((value & 0xf) == 0xf);
+
+    cpu.a = value;
+}
+
 fn dec_a(cpu: &mut Cpu) {
     let a = cpu.a;
     let value = a.wrapping_sub(1);
@@ -824,6 +919,10 @@ fn ld_b_b(cpu: &mut Cpu) {
     cpu.b = cpu.b;
 }
 
+fn ld_b_e(cpu: &mut Cpu) {
+    cpu.b = cpu.e;
+}
+
 fn ld_b_h(cpu: &mut Cpu) {
     cpu.b = cpu.h;
 }
@@ -903,6 +1002,14 @@ fn ld_a_l(cpu: &mut Cpu) {
     cpu.a = cpu.l;
 }
 
+fn add_a_c(cpu: &mut Cpu) {
+    cpu.a = add_set_flags(cpu, cpu.a, cpu.c);
+}
+
+fn add_a_e(cpu: &mut Cpu) {
+    cpu.a = add_set_flags(cpu, cpu.a, cpu.e);
+}
+
 fn add_a_mhl(cpu: &mut Cpu) {
     let byte = cpu.mmu.read(cpu.hl());
     cpu.a = add_set_flags(cpu, cpu.a, byte);
@@ -912,6 +1019,10 @@ fn sub_a_b(cpu: &mut Cpu) {
     cpu.a = sub_set_flags(cpu, cpu.a, cpu.b);
 }
 
+fn sub_a_a(cpu: &mut Cpu) {
+    cpu.a = sub_set_flags(cpu, cpu.a, cpu.a);
+}
+
 fn and_a_c(cpu: &mut Cpu) {
     cpu.a &= cpu.c;
 
@@ -995,6 +1106,17 @@ fn pop_bc(cpu: &mut Cpu) {
     cpu.set_bc(word);
 }
 
+fn jp_nz_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+
+    if cpu.get_zero() {
+        return;
+    }
+
+    cpu.pc = word;
+    cpu.ticks = cpu.ticks.wrapping_add(4);
+}
+
 fn jp_u16(cpu: &mut Cpu) {
     let word = cpu.read_u16();
     cpu.pc = word;
@@ -1025,6 +1147,29 @@ fn ret(cpu: &mut Cpu) {
     cpu.pc = cpu.pop_word();
 }
 
+fn jp_z_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+
+    if !cpu.get_zero() {
+        return;
+    }
+
+    cpu.pc = word;
+    cpu.ticks = cpu.ticks.wrapping_add(4);
+}
+
+fn call_z_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+
+    if !cpu.get_zero() {
+        return;
+    }
+
+    cpu.push_word(cpu.pc);
+    cpu.pc = word;
+    cpu.ticks = cpu.ticks.wrapping_add(12);
+}
+
 fn call_u16(cpu: &mut Cpu) {
     let word = cpu.read_u16();
     cpu.push_word(cpu.pc);
@@ -1049,6 +1194,29 @@ fn sub_a_u8(cpu: &mut Cpu) {
     cpu.a = sub_set_flags(cpu, cpu.a, byte);
 }
 
+fn jp_c_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+
+    if !cpu.get_carry() {
+        return;
+    }
+
+    cpu.pc = word;
+    cpu.ticks = cpu.ticks.wrapping_add(4);
+}
+
+fn call_c_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+
+    if !cpu.get_carry() {
+        return;
+    }
+
+    cpu.push_word(cpu.pc);
+    cpu.pc = word;
+    cpu.ticks = cpu.ticks.wrapping_add(12);
+}
+
 fn ld_mff00u8_a(cpu: &mut Cpu) {
     let byte = cpu.read_u8();
     cpu.mmu.write(0xff00 + byte as u16, cpu.a);
@@ -1158,6 +1326,15 @@ fn bit_7_h(cpu: &mut Cpu) {
     bit_h(cpu, 7);
 }
 
+fn set_4_a(cpu: &mut Cpu) {
+    cpu.a = set(cpu.a, 4);
+}
+
+/// Helper function to set one bit in a u8.
+fn set(value: u8, bit: u8) -> u8 {
+    value | (1u8 << (bit as usize))
+}
+
 /// Helper function that rotates (shifts) left the given
 /// byte (probably from a register) and updates the
 /// proper flag registers.