diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs index f30039a08723b429334fd7bc19cccdb987d424c2..6f9ff95eaa7eaf4d918c1283ab805388faa3ed70 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 5108379403f085295ea7111376d363b88742449e..ddbc0c32d81181921d7ad920449a6dc509c5aa8c 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 ace18d143b9b46a568b929c838c8c82033191d10..07acdf7c93fb132f6448a788f7da5acbc8189259 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 e1fb4a1a397180b52fde04e14336b6be66cc60fc..537c14c6714406aa2045ab6a578a8f121f59a119 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 {