From 3fe2d11f63715e0d09a7182844dcd44d67481b09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Tue, 25 Apr 2023 09:30:22 +0100
Subject: [PATCH] chore: more debug information

---
 Cargo.toml                |  1 +
 frontends/sdl/Cargo.toml  |  2 ++
 frontends/sdl/README.md   |  8 ++++++++
 frontends/sdl/src/main.rs | 13 ++++++++++++-
 src/cpu.rs                |  3 +++
 src/gb.rs                 |  3 ++-
 src/mmu.rs                | 27 ++++++++++++++++++++++++++-
 7 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index ef4b6574..4653eaf2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,7 @@ crate-type = ["cdylib", "rlib"]
 [features]
 wasm = ["wasm-bindgen"]
 debug = []
+cpulog = []
 gen-mock = []
 
 [dependencies]
diff --git a/frontends/sdl/Cargo.toml b/frontends/sdl/Cargo.toml
index 0a07c0b6..c291cf05 100644
--- a/frontends/sdl/Cargo.toml
+++ b/frontends/sdl/Cargo.toml
@@ -8,7 +8,9 @@ keywords = ["gameboy", "emulator", "rust", "sdl"]
 edition = "2018"
 
 [features]
+slow = []
 debug = ["boytacean/debug"]
+cpulog = ["boytacean/cpulog"]
 
 [dependencies.boytacean]
 path = "../.."
diff --git a/frontends/sdl/README.md b/frontends/sdl/README.md
index 163d1b2e..b98904b6 100644
--- a/frontends/sdl/README.md
+++ b/frontends/sdl/README.md
@@ -29,3 +29,11 @@ There are some feature flags that control the verbosity of the emulator to run i
 ```bash
 cargo run --features debug
 ```
+
+## Features
+
+| Provider | Description                                                                 |
+| -------- | --------------------------------------------------------------------------- |
+| `debug`  | Activates the base `debug` feature from Boytacean.                          |
+| `slow`   | Runs the emulator at a very slow page 60x slower to allow visual debugging. |
+| `cpulog` | Prints a log of the CPU instruction executed.                               |
diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index 61d8d543..a31475eb 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -143,7 +143,10 @@ impl Emulator {
     }
 
     pub fn start(&mut self, screen_scale: f32) {
+        self.start_base();
+
         let sdl = sdl2::init().unwrap();
+
         if self.features.contains(&"video") {
             self.start_graphics(&sdl, screen_scale);
         }
@@ -152,6 +155,14 @@ impl Emulator {
         }
     }
 
+    #[cfg(not(feature = "slow"))]
+    pub fn start_base(&mut self) {}
+
+    #[cfg(feature = "slow")]
+    pub fn start_base(&mut self) {
+        self.logic_frequency = 100;
+    }
+
     pub fn start_graphics(&mut self, sdl: &Sdl, screen_scale: f32) {
         self.graphics = Some(Graphics::new(
             sdl,
@@ -446,7 +457,7 @@ impl Emulator {
 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(GameBoyMode::Dmg);
+    let mut game_boy = GameBoy::new(GameBoyMode::Cgb);
     let mut printer = Box::<PrinterDevice>::default();
     printer.set_callback(|image_buffer| {
         let file_name = format!("printer-{}.png", Utc::now().format("%Y%m%d-%H%M%S"));
diff --git a/src/cpu.rs b/src/cpu.rs
index 262704a1..63798bb0 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -279,6 +279,9 @@ impl Cpu {
             );
         }
 
+        #[cfg(feature = "cpulog")]
+        println!("[0x{:04x}] {}", self.pc - 1, inst_str);
+
         // calls the current instruction and increments the number of
         // cycles executed by the instruction time of the instruction
         // that has just been executed
diff --git a/src/gb.rs b/src/gb.rs
index b65aec3d..602468dc 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -235,7 +235,7 @@ impl GameBoy {
         let pad = Pad::default();
         let timer = Timer::default();
         let serial = Serial::default();
-        let mmu = Mmu::new(ppu, apu, pad, timer, serial, gbc.clone());
+        let mmu = Mmu::new(ppu, apu, pad, timer, serial, mode, gbc.clone());
         let cpu = Cpu::new(mmu, gbc.clone());
 
         Self {
@@ -492,6 +492,7 @@ impl GameBoy {
     pub fn set_mode(&mut self, value: GameBoyMode) {
         self.mode = value;
         (*self.gbc).borrow_mut().set_mode(value);
+        self.mmu().set_mode(value);
     }
 
     pub fn ppu_enabled(&self) -> bool {
diff --git a/src/mmu.rs b/src/mmu.rs
index bfd8047a..3584df47 100644
--- a/src/mmu.rs
+++ b/src/mmu.rs
@@ -1,7 +1,13 @@
 use std::{cell::RefCell, rc::Rc};
 
 use crate::{
-    apu::Apu, debugln, gb::GameBoyConfig, pad::Pad, ppu::Ppu, rom::Cartridge, serial::Serial,
+    apu::Apu,
+    debugln,
+    gb::{GameBoyConfig, GameBoyMode},
+    pad::Pad,
+    ppu::Ppu,
+    rom::Cartridge,
+    serial::Serial,
     timer::Timer,
 };
 
@@ -65,6 +71,8 @@ pub struct Mmu {
 
     ram_offset: u16,
 
+    mode: GameBoyMode,
+
     gbc: Rc<RefCell<GameBoyConfig>>,
 }
 
@@ -75,6 +83,7 @@ impl Mmu {
         pad: Pad,
         timer: Timer,
         serial: Serial,
+        mode: GameBoyMode,
         gbc: Rc<RefCell<GameBoyConfig>>,
     ) -> Self {
         Self {
@@ -90,6 +99,7 @@ impl Mmu {
             ram_bank: 0x1,
             ram_offset: 0x1000,
             ie: 0x0,
+            mode,
             gbc,
         }
     }
@@ -165,6 +175,13 @@ impl Mmu {
                     }
                     return self.boot[addr as usize];
                 }
+                if self.boot_active
+                    && self.mode == GameBoyMode::Cgb
+                    && addr >= 0x0200
+                    && addr <= 0x08ff
+                {
+                    return self.boot[(addr - 0x0100) as usize];
+                }
                 self.rom.read(addr)
             }
 
@@ -381,4 +398,12 @@ impl Mmu {
     pub fn set_rom(&mut self, rom: Cartridge) {
         self.rom = rom;
     }
+
+    pub fn mode(&self) -> GameBoyMode {
+        self.mode
+    }
+
+    pub fn set_mode(&mut self, value: GameBoyMode) {
+        self.mode = value;
+    }
 }
-- 
GitLab