diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 44e078fa7995f28ccce0ad956da721347e265ec1..879ac9f4d116b6e8ae4618358e432f6be4d4df84 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -81,24 +81,24 @@ fn main() {
     // creates a new Game Boy instance and loads both the boot ROM
     // and the initial game ROM to "start the engine"
     let mut game_boy = GameBoy::new();
-    game_boy.load_boot_mgb_bootix();
+    game_boy.load_boot_dmg_bootix();
 
     //game_boy.load_rom_file("../../res/roms.prop/tetris.gb");
     //game_boy.load_rom_file("../../res/roms.prop/alleyway.gb");
 
     //game_boy.load_rom_file("../../res/roms/firstwhite.gb");
-    game_boy.load_rom_file("../../res/roms/opus5.gb");
+    //game_boy.load_rom_file("../../res/roms/opus5.gb");
     //game_boy.load_rom_file("../../res/roms/special.gb");
 
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/01-special.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/02-interrupts.gb"); // NO FINISH
-    //game_boy.load_rom_file("../../res/roms/paradius/cpu/03-op sp,hl.gb"); // NO FINISH
+    //game_boy.load_rom_file("../../res/roms/paradius/cpu/03-op sp,hl.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/04-op r,imm.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/05-op rp.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/06-ld r,r.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/07-jr,jp,call,ret,rst.gb"); // PASSED
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/08-misc instrs.gb");  // PASSED
-    //game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // NO FINISH
+    game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // NO FINISH
     //game_boy.load_rom_file("../../res/roms/paradius/cpu/11-op a,(hl).gb"); // NO FINISH
 
     'main: loop {
diff --git a/src/inst.rs b/src/inst.rs
index cdcceb6f8c07604952451d8bb745d9a37fcb6de1..04a8bd7e053d815afa4dd0f00b10b6de56f07324 100644
--- a/src/inst.rs
+++ b/src/inst.rs
@@ -220,7 +220,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (ret_z, 8, "RET Z"),
     (ret, 16, "RET"),
     (jp_z_u16, 12, "JP Z, u16"),
-    (noimpl, 4, "! UNIMP !"),
+    (illegal, 4, "ILLEGAL"),
     (call_z_u16, 12, "CALL Z, u16"),
     (call_u16, 24, "CALL u16"),
     (adc_a_u8, 8, "ADC A, u8 "),
@@ -268,7 +268,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (push_af, 16, "PUSH AF"),
     (or_a_u8, 8, "OR A, u8"),
     (rst_30h, 16, "RST 30h"),
-    (noimpl, 4, "! UNIMP !"),
+    (ld_hl_spi8, 12, "LD HL, SP+i8"),
     (ld_sp_hl, 8, "LD SP, HL"),
     (ld_a_mu16, 16, "LD A [u16]"),
     (ei, 4, "EI"),
@@ -2005,6 +2005,21 @@ fn rst_30h(cpu: &mut Cpu) {
     rst(cpu, 0x0030);
 }
 
+fn ld_hl_spi8(cpu: &mut Cpu) {
+    let sp = cpu.sp as i32;
+    let byte = cpu.read_u8() as i8;
+    let byte_i32 = byte as i32;
+
+    let result = sp.wrapping_add(byte_i32);
+
+    cpu.set_sub(false);
+    cpu.set_zero(false);
+    cpu.set_half_carry((sp ^ byte_i32 ^ result) & 0x10 == 0x10);
+    cpu.set_carry((sp ^ byte_i32 ^ result) & 0x100 == 0x100);
+
+    cpu.set_hl(result as u16);
+}
+
 fn ld_sp_hl(cpu: &mut Cpu) {
     cpu.sp = cpu.hl();
 }