From e6420f5a75d4e6e1ff57b7ed27f366b6188dad49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sat, 2 Jul 2022 23:22:31 +0100
Subject: [PATCH] feat: more instructions added

---
 examples/sdl/src/main.rs |  2 +-
 src/cpu.rs               | 14 +++++++++++
 src/inst.rs              | 50 +++++++++++++++++++++++++++++++++++-----
 src/mmu.rs               | 12 ++++------
 4 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 0b39bd95..5cf73b2f 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -75,7 +75,7 @@ fn main() {
 
     let mut game_boy = GameBoy::new();
     game_boy.load_boot_default();
-    game_boy.load_rom("../../res/roms/firstwhite.gb");
+    game_boy.load_rom("../../res/roms/ld_r_r.gb");
 
     let mut counter = 0;
 
diff --git a/src/cpu.rs b/src/cpu.rs
index 04cd30ec..d16da5f4 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -137,6 +137,20 @@ impl Cpu {
         f
     }
 
+    #[inline(always)]
+    pub fn set_f(&mut self, value: u8) {
+        self.zero = value & 0x80 == 0x80;
+        self.sub = value & 0x40 == 0x40;
+        self.half_carry = value & 0x20 == 0x20;
+        self.carry = value & 0x10 == 0x10;
+    }
+
+    #[inline(always)]
+    pub fn set_af(&mut self, value: u16) {
+        self.a = (value >> 8) as u8;
+        self.set_f(value as u8);
+    }
+
     #[inline(always)]
     pub fn set_bc(&mut self, value: u16) {
         self.b = (value >> 8) as u8;
diff --git a/src/inst.rs b/src/inst.rs
index db94b51c..c1b64f12 100644
--- a/src/inst.rs
+++ b/src/inst.rs
@@ -21,9 +21,9 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     // 0x1 opcodes
     (noimpl, 4, "! UNIMP !"),
     (ld_de_u16, 12, "LD DE, u16"),
-    (noimpl, 4, "! UNIMP !"),
+    (ld_mde_a, 8, "LD [DE], A"),
     (inc_de, 8, "INC DE"),
-    (noimpl, 4, "! UNIMP !"),
+    (inc_d, 4, "INC D"),
     (dec_d, 4, "DEC D"),
     (ld_d_u8, 8, "LD D, u8"),
     (rla, 4, "RLA"),
@@ -31,7 +31,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (ld_a_mde, 8, "LD A, [DE]"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (inc_e, 4, "INC E"),
     (dec_e, 4, "DEC E"),
     (ld_e_u8, 8, "LD E, u8"),
     (noimpl, 4, "! UNIMP !"),
@@ -241,11 +241,11 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     // 0xe opcodes
     (ld_mff00u8_a, 12, "LD [FF00+u8], A"),
-    (noimpl, 4, "! UNIMP !"),
+    (pop_hl, 12, "POP HL"),
     (ld_mff00c_a, 8, "LD [FF00+C], A"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (push_hl, 16, "PUSH HL"),
     (and_a_u8, 8, "AND A, u8"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
@@ -258,7 +258,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (rst_18h, 16, "RST 18h"),
     // 0xf opcodes
     (ld_a_mff00u8, 12, "LD A, [FF00+u8]"),
-    (noimpl, 4, "! UNIMP !"),
+    (pop_af, 12, "POP AF"),
     (noimpl, 4, "! UNIMP !"),
     (di, 4, "DI"),
     (noimpl, 4, "! UNIMP !"),
@@ -567,10 +567,24 @@ fn ld_de_u16(cpu: &mut Cpu) {
     cpu.set_de(word);
 }
 
+fn ld_mde_a(cpu: &mut Cpu) {
+    cpu.mmu.write(cpu.de(), cpu.a);
+}
+
 fn inc_de(cpu: &mut Cpu) {
     cpu.set_de(cpu.de().wrapping_add(1));
 }
 
+fn inc_d(cpu: &mut Cpu) {
+    let value = cpu.d.wrapping_add(1);
+
+    cpu.set_sub(false);
+    cpu.set_zero(value == 0);
+    cpu.set_half_carry((value & 0xf) == 0xf);
+
+    cpu.d = value;
+}
+
 fn dec_d(cpu: &mut Cpu) {
     let d = cpu.d;
     let value = d.wrapping_sub(1);
@@ -609,6 +623,16 @@ fn ld_a_mde(cpu: &mut Cpu) {
     cpu.a = byte;
 }
 
+fn inc_e(cpu: &mut Cpu) {
+    let value = cpu.e.wrapping_add(1);
+
+    cpu.set_sub(false);
+    cpu.set_zero(value == 0);
+    cpu.set_half_carry((value & 0xf) == 0xf);
+
+    cpu.e = value;
+}
+
 fn dec_e(cpu: &mut Cpu) {
     let e = cpu.e;
     let value = e.wrapping_sub(1);
@@ -893,10 +917,19 @@ fn ld_mff00u8_a(cpu: &mut Cpu) {
     cpu.mmu.write(0xff00 + byte as u16, cpu.a);
 }
 
+fn pop_hl(cpu: &mut Cpu) {
+    let word = cpu.pop_word();
+    cpu.set_hl(word);
+}
+
 fn ld_mff00c_a(cpu: &mut Cpu) {
     cpu.mmu.write(0xff00 + cpu.c as u16, cpu.a);
 }
 
+fn push_hl(cpu: &mut Cpu) {
+    cpu.push_word(cpu.hl());
+}
+
 fn and_a_u8(cpu: &mut Cpu) {
     let byte = cpu.read_u8();
 
@@ -922,6 +955,11 @@ fn ld_a_mff00u8(cpu: &mut Cpu) {
     cpu.a = cpu.mmu.read(0xff00 + byte as u16);
 }
 
+fn pop_af(cpu: &mut Cpu) {
+    let word = cpu.pop_word();
+    cpu.set_af(word);
+}
+
 fn di(cpu: &mut Cpu) {
     cpu.disable_int();
 }
diff --git a/src/mmu.rs b/src/mmu.rs
index 97bbcca4..4eab0ec2 100644
--- a/src/mmu.rs
+++ b/src/mmu.rs
@@ -140,14 +140,12 @@ impl Mmu {
                             0x40 | 0x60 | 0x70 => {
                                 self.ppu.write(addr, value);
                             }
-                            0x50 => {
-                                match addr & 0x00ff {
-                                    0x50 => self.boot_active = false,
-                                    _ => {
-                                        println!("Writing to unknown IO control 0x{:04x}", addr);
-                                    }
+                            0x50 => match addr & 0x00ff {
+                                0x50 => self.boot_active = false,
+                                _ => {
+                                    println!("Writing to unknown IO control 0x{:04x}", addr);
                                 }
-                            }
+                            },
                             _ => {
                                 println!("Writing to unknown IO control 0x{:04x}", addr);
                             }
-- 
GitLab