From 63f47c8621e85cf659ba1dc8f033448819675e2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Fri, 3 Mar 2023 19:24:06 +0000
Subject: [PATCH] feat: better reset of APU and Timer Support for set of video,
 audio and timer. Now with support for toggling audio in the SDL version.

---
 frontends/sdl/src/main.rs |  9 +++++++
 src/apu.rs                | 50 +++++++++++++++++++++++++++++++++++++++
 src/gb.rs                 | 27 ++++++++++++++++++++-
 src/timer.rs              | 12 ++++++++++
 4 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index f30039a0..6f9ff95e 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -162,6 +162,11 @@ impl Emulator {
         );
     }
 
+    pub fn toggle_audio(&mut self) {
+        let apu_enabled = self.system.get_apu_enabled();
+        self.system.set_apu_enabled(!apu_enabled);
+    }
+
     pub fn toggle_palette(&mut self) {
         self.system
             .ppu()
@@ -225,6 +230,10 @@ impl Emulator {
                         keycode: Some(Keycode::B),
                         ..
                     } => self.benchmark(Benchmark::default()),
+                    Event::KeyDown {
+                        keycode: Some(Keycode::T),
+                        ..
+                    } => self.toggle_audio(),
                     Event::KeyDown {
                         keycode: Some(Keycode::P),
                         ..
diff --git a/src/apu.rs b/src/apu.rs
index 51083794..ddbc0c32 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -128,6 +128,56 @@ impl Apu {
         }
     }
 
+    pub fn reset(&mut self) {
+        self.ch1_timer = 0;
+        self.ch1_sequence = 0;
+        self.ch1_envelope_sequence = 0;
+        self.ch1_envelope_enabled = false;
+        self.ch1_sweep_sequence = 0;
+        self.ch1_output = 0;
+        self.ch1_sweep_slope = 0x0;
+        self.ch1_sweep_increase = false;
+        self.ch1_sweep_pace = 0x0;
+        self.ch1_length_timer = 0x0;
+        self.ch1_wave_duty = 0x0;
+        self.ch1_pace = 0x0;
+        self.ch1_direction = 0x0;
+        self.ch1_volume = 0x0;
+        self.ch1_wave_length = 0x0;
+        self.ch1_length_stop = false;
+        self.ch1_enabled = false;
+
+        self.ch2_timer = 0;
+        self.ch2_sequence = 0;
+        self.ch2_envelope_sequence = 0;
+        self.ch2_envelope_enabled = false;
+        self.ch2_output = 0;
+        self.ch2_length_timer = 0x0;
+        self.ch2_wave_duty = 0x0;
+        self.ch2_pace = 0x0;
+        self.ch2_direction = 0x0;
+        self.ch2_volume = 0x0;
+        self.ch2_wave_length = 0x0;
+        self.ch2_length_stop = false;
+        self.ch2_enabled = false;
+
+        self.ch3_timer = 0;
+        self.ch3_position = 0;
+        self.ch3_output = 0;
+        self.ch3_dac = false;
+        self.ch3_length_timer = 0x0;
+        self.ch3_output_level = 0x0;
+        self.ch3_wave_length = 0x0;
+        self.ch3_length_stop = false;
+        self.ch3_enabled = false;
+
+        self.sequencer = 0;
+        self.sequencer_step = 0;
+        self.output_timer = 0;
+
+        self.clear_audio_buffer()
+    }
+
     pub fn clock(&mut self, cycles: u8) {
         // @TODO the performance here requires improvement
         for _ in 0..cycles {
diff --git a/src/gb.rs b/src/gb.rs
index ace18d14..07acdf7c 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -77,13 +77,14 @@ impl GameBoy {
         Self {
             cpu,
             ppu_enabled: true,
-            apu_enabled: false,
+            apu_enabled: true,
             timer_enabled: true,
         }
     }
 
     pub fn reset(&mut self) {
         self.ppu().reset();
+        self.apu().reset();
         self.mmu().reset();
         self.cpu.reset();
     }
@@ -254,6 +255,30 @@ impl GameBoy {
     pub fn get_compilation_time(&self) -> String {
         String::from(COMPILATION_TIME)
     }
+
+    pub fn get_ppu_enabled(&self) -> bool {
+        self.ppu_enabled
+    }
+
+    pub fn set_ppu_enabled(&mut self, value: bool) {
+        self.ppu_enabled = value;
+    }
+
+    pub fn get_apu_enabled(&self) -> bool {
+        self.apu_enabled
+    }
+
+    pub fn set_apu_enabled(&mut self, value: bool) {
+        self.apu_enabled = value;
+    }
+
+    pub fn get_timer_enabled(&self) -> bool {
+        self.apu_enabled
+    }
+
+    pub fn set_timer_enabled(&mut self, value: bool) {
+        self.timer_enabled = value;
+    }
 }
 
 /// Gameboy implementations that are meant with performance
diff --git a/src/timer.rs b/src/timer.rs
index e1fb4a1a..537c14c6 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -27,6 +27,18 @@ impl Timer {
         }
     }
 
+    pub fn reset(&mut self) {
+        self.div = 0;
+        self.tima = 0;
+        self.tma = 0;
+        self.tac = 0x0;
+        self.div_clock = 0;
+        self.tima_clock = 0;
+        self.tima_enabled = false;
+        self.tima_ratio = 1024;
+        self.int_tima = false;
+    }
+
     pub fn clock(&mut self, cycles: u8) {
         self.div_clock += cycles as u16;
         while self.div_clock >= 256 {
-- 
GitLab