From fd93c068ada2ff3bf57a794f4eabd24558ea83f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 26 Jun 2022 01:12:38 +0100
Subject: [PATCH] feat: initial MMU support Added more instructions

---
 examples/sdl/src/main.rs |  2 ++
 src/cpu.rs               | 61 ++++++++++++++++++++++++++++++++++++----
 src/mmu.rs               | 30 +++++++++++++++++++-
 src/ppu.rs               |  2 +-
 4 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index a8c90f31..51903a1c 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -7,4 +7,6 @@ fn main() {
     game_boy.clock();
     game_boy.clock();
     game_boy.clock();
+    game_boy.clock();
+    game_boy.clock();
 }
diff --git a/src/cpu.rs b/src/cpu.rs
index 20d5207e..7351f6be 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -1,6 +1,6 @@
 use crate::mmu::Mmu;
 
-pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
+pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 208] = [
     // 0x0 opcodes
     (nop, 4, "NOP"),
     (ld_bc_u16, 12, "LD BC, NN"),
@@ -37,7 +37,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
     (nop, 4, "NOP"),
     // 0x2 opcodes
     (nop, 4, "NOP"),
-    (nop, 4, "NOP"),
+    (ld_hl_u16, 12, "LD HL, u16"),
     (nop, 4, "NOP"),
     (nop, 4, "NOP"),
     (nop, 4, "NOP"),
@@ -55,7 +55,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
     // 0x3 opcodes
     (nop, 4, "NOP"),
     (ld_sp_u16, 12, "LD SP, NN"),
-    (nop, 4, "NOP"),
+    (ld_mhld_a, 8, "LD [HL]-, A"),
     (nop, 4, "NOP"),
     (nop, 4, "NOP"),
     (nop, 4, "NOP"),
@@ -188,6 +188,40 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
     (nop, 4, "NOP"),
     (nop, 4, "NOP"),
     (xor_a_a, 4, "XOR A, A"),
+    // 0xb opcodes
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    // 0xc opcodes
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
+    (nop, 4, "NOP"),
 ];
 
 pub struct Cpu {
@@ -238,10 +272,10 @@ impl Cpu {
         let instruction = INSTRUCTIONS[opcode as usize];
         let (instruction_fn, instruction_size, instruction_str) = instruction;
 
+        println!("{} ({:#x})", instruction_str, opcode);
+
         instruction_fn(self);
         self.clocks = self.clocks.wrapping_add(instruction_size as u32);
-
-        println!("{} ({:#x})", instruction_str, opcode)
     }
 
     #[inline(always)]
@@ -423,12 +457,27 @@ fn add_hl_bc(cpu: &mut Cpu) {
     cpu.set_hl(value);
 }
 
+fn ld_hl_u16(cpu: &mut Cpu) {
+    let word = cpu.read_u16();
+    cpu.set_hl(word);
+}
+
 fn ld_sp_u16(cpu: &mut Cpu) {
     cpu.sp = cpu.read_u16();
 }
 
+fn ld_mhld_a(cpu: &mut Cpu) {
+    cpu.mmu.write(cpu.hl(), cpu.a);
+    cpu.set_hl(cpu.hl().wrapping_sub(1));
+}
+
 fn xor_a_a(cpu: &mut Cpu) {
-    cpu.a ^= cpu.a
+    cpu.a ^= cpu.a;
+
+    cpu.set_sub(false);
+    cpu.set_zero(cpu.a == 0);
+    cpu.set_half_carry(false);
+    cpu.set_carry(false);
 }
 
 fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
diff --git a/src/mmu.rs b/src/mmu.rs
index 6666aeae..a8e95ff0 100644
--- a/src/mmu.rs
+++ b/src/mmu.rs
@@ -20,7 +20,35 @@ impl Mmu {
     }
 
     pub fn write(&mut self, addr: u16, value: u8) {
-        self.ram[addr as usize] = value;
+        match addr & 0xf000 {
+            // BIOS
+            0x0000 => {
+                println!("WRITING to BIOS")
+            }
+            // ROM0
+            0x1000 | 0x2000 | 0x3000 => {
+                println!("WRITING TO ROM 0");
+            }
+            // ROM1 (unbanked) (16k)
+            0x4000 | 0x5000 | 0x6000 | 0x7000 => {
+                println!("WRITING TO ROM 1");
+            }
+            // Graphics: VRAM (8k)
+            0x8000 | 0x9000 => {
+                println!("WRITING TO VRAM");
+                self.ppu.vram[(addr & 0x1fff) as usize] = value;
+            }
+            // External RAM (8k)
+            0xa000 | 0xb000 => {
+                println!("WRITING TO ERAM");
+            }
+            // Working RAM (8k)
+            0xc000 | 0xd000 => {
+                println!("WRITING TO RAM");
+                self.ram[(addr & 0x1fff) as usize] = value;
+            }
+            _ => panic!("asdad"),
+        }
     }
 
     pub fn write_buffer(&mut self, addr: u16, buffer: &[u8]) {
diff --git a/src/ppu.rs b/src/ppu.rs
index 226a07a7..ba7680ed 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -1,7 +1,7 @@
 pub const VRAM_SIZE: usize = 8192;
 
 pub struct Ppu {
-    vram: [u8; VRAM_SIZE],
+    pub vram: [u8; VRAM_SIZE],
 }
 
 impl Ppu {
-- 
GitLab