From 9416e604770c126b015a44fc377f8dd43f1b4bb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Tue, 5 Jul 2022 10:07:11 +0100
Subject: [PATCH] feat: more instructions

---
 examples/sdl/src/main.rs |  7 +++--
 src/inst.rs              | 59 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 4b1648e2..99a3a6f1 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -86,15 +86,18 @@ fn main() {
 
     //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/ld_r_r.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/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");
+    //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
 
     let mut counter = 0;
 
diff --git a/src/inst.rs b/src/inst.rs
index 7ed12f42..2d01dfa6 100644
--- a/src/inst.rs
+++ b/src/inst.rs
@@ -46,11 +46,11 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (inc_h, 4, "INC H"),
     (dec_h, 4, "DEC H"),
     (ld_h_u8, 8, "LD H, u8"),
-    (noimpl, 4, "! UNIMP !"),
+    (daa, 4, "DAA"),
     (jr_z_i8, 8, "JR Z, i8"),
     (add_hl_hl, 8, "ADD HL, HL"),
     (ld_a_mhli, 8, "LD A, [HL+] "),
-    (noimpl, 4, "! UNIMP !"),
+    (dec_hl, 8, "DEC HL"),
     (inc_l, 4, "INC L"),
     (dec_l, 4, "DEC L"),
     (ld_l_u8, 8, "LD L, u8"),
@@ -66,7 +66,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (scf, 4, "SCF"),
     (jr_c_i8, 8, "JR C, i8"),
     (add_hl_sp, 8, "ADD HL, SP"),
-    (noimpl, 4, "! UNIMP !"),
+    (ld_a_mhld, 8, "LD A, [HL-]"),
     (dec_sp, 8, "DEC SP"),
     (inc_a, 4, "INC A"),
     (dec_a, 4, "DEC A"),
@@ -286,7 +286,7 @@ pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (rlc_e, 8, "RLC E"),
     (rlc_h, 8, "RLC H"),
     (rlc_l, 8, "RLC L"),
-    (noimpl, 4, "! UNIMP !"),
+    (rlc_mhl, 16, "RLC [HL]"),
     (rlc_a, 8, "RLC A"),
     (rrc_b, 8, "RRC B"),
     (rrc_c, 8, "RRC C"),
@@ -839,6 +839,40 @@ fn ld_h_u8(cpu: &mut Cpu) {
     cpu.h = byte;
 }
 
+fn daa(cpu: &mut Cpu) {
+    let a = cpu.a;
+    let mut adjust = 0;
+
+    if cpu.get_half_carry() {
+        adjust |= 0x06;
+    }
+
+    if cpu.get_carry() {
+        // Yes, we have to adjust it.
+        adjust |= 0x60;
+    }
+
+    let res = if cpu.get_sub() {
+        a.wrapping_sub(adjust)
+    } else {
+        if a & 0x0F > 0x09 {
+            adjust |= 0x06;
+        }
+
+        if a > 0x99 {
+            adjust |= 0x60;
+        }
+
+        a.wrapping_add(adjust)
+    };
+
+    cpu.a = res;
+
+    cpu.set_zero(res == 0);
+    cpu.set_half_carry(false);
+    cpu.set_carry(adjust & 0x60 == 0x60);
+}
+
 fn jr_z_i8(cpu: &mut Cpu) {
     let byte = cpu.read_u8() as i8;
 
@@ -861,6 +895,10 @@ fn ld_a_mhli(cpu: &mut Cpu) {
     cpu.set_hl(cpu.hl().wrapping_add(1));
 }
 
+fn dec_hl(cpu: &mut Cpu) {
+    cpu.set_hl(cpu.hl().wrapping_sub(1));
+}
+
 fn inc_l(cpu: &mut Cpu) {
     let l = cpu.l;
     let value = l.wrapping_add(1);
@@ -968,6 +1006,12 @@ fn add_hl_sp(cpu: &mut Cpu) {
     cpu.set_hl(value);
 }
 
+fn ld_a_mhld(cpu: &mut Cpu) {
+    let byte = cpu.mmu.read(cpu.hl());
+    cpu.a = byte;
+    cpu.set_hl(cpu.hl().wrapping_sub(1));
+}
+
 fn dec_sp(cpu: &mut Cpu) {
     cpu.sp = cpu.sp.wrapping_sub(1);
 }
@@ -2008,6 +2052,13 @@ fn rlc_l(cpu: &mut Cpu) {
     cpu.l = rlc(cpu, cpu.l);
 }
 
+fn rlc_mhl(cpu: &mut Cpu) {
+    let hl = cpu.hl();
+    let byte = cpu.mmu.read(hl);
+    let result = rlc(cpu, byte);
+    cpu.mmu.write(hl, result);
+}
+
 fn rlc_a(cpu: &mut Cpu) {
     cpu.a = rlc(cpu, cpu.a);
 }
-- 
GitLab