From 8c574fc47e9097fb892b467c4fe0f1a0eebd3bc0 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Sat, 22 Apr 2023 21:39:46 +1000 Subject: [PATCH] double speed!!!! maybe there are edge cases but ive mostly got it --- lib/src/processor/memory.rs | 18 ++++++++++--- lib/src/processor/memory/mmio/timer.rs | 35 +++++++++++++------------- lib/src/processor/opcodes.rs | 6 ++--- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index 2af22d0..336d60f 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -522,14 +522,26 @@ where C: PocketCamera + Send + 'static, { pub fn increment_timers(&mut self, machine_cycles: usize) { + self.increment_timers_div_optional(machine_cycles, true); + } + + pub fn increment_timers_div_optional(&mut self, machine_cycles: usize, div: bool) { let steps = machine_cycles * 4; + let logical_steps = if self.memory.is_double_speed() { + steps / 2 + } else { + steps + }; self.cycle_count += steps; self.memory.oam_dma_tick(steps); self.memory.camera.lock().unwrap().tick(steps); - let timer_return = self.memory.timers.tick(steps); + let timer_return = self + .memory + .timers + .tick(steps, div, self.memory.is_double_speed()); for _ in 0..timer_return.num_apu_ticks { self.memory.apu.div_apu_tick(); @@ -539,14 +551,14 @@ where self.memory.interrupts.set_interrupt(Interrupt::Timer, true); } - self.memory.apu.tick(steps); + self.memory.apu.tick(logical_steps); let serial_interrupt = self.memory.serial.tick(steps, self.memory.ime); self.memory .interrupts .set_interrupt(Interrupt::Serial, serial_interrupt); - let gpu_interrupts = self.memory.gpu.tick(steps); + let gpu_interrupts = self.memory.gpu.tick(logical_steps); self.memory .interrupts diff --git a/lib/src/processor/memory/mmio/timer.rs b/lib/src/processor/memory/mmio/timer.rs index 94409bf..0a91595 100644 --- a/lib/src/processor/memory/mmio/timer.rs +++ b/lib/src/processor/memory/mmio/timer.rs @@ -74,10 +74,6 @@ pub struct Timer { tima_counter: usize, } -// this will need to change when cgb mode is implemented -// as it uses bit 5 in double speed mode -const AUDIO_BIT: u8 = 4; - impl Timer { pub fn init() -> Self { Self { @@ -90,24 +86,27 @@ impl Timer { } } - pub fn tick(&mut self, steps: usize) -> TimerReturn { - self.div_counter += steps; - let mut div_diff = (self.div_counter / 256) as u8; - let mut last_div = self.div; + pub fn tick(&mut self, steps: usize, with_div: bool, double_speed: bool) -> TimerReturn { let mut returning = TimerReturn::default(); - while div_diff > 0 { - let div = last_div.wrapping_add(1); + if with_div { + let audio_bit = if double_speed { 5 } else { 4 }; + self.div_counter += steps; + let mut div_diff = (self.div_counter / 256) as u8; + let mut last_div = self.div; + while div_diff > 0 { + let div = last_div.wrapping_add(1); - if (div & (1 << AUDIO_BIT)) < (last_div & (1 << AUDIO_BIT)) { - // trigger DIV-APU - returning.num_apu_ticks += 1; + if (div & (1 << audio_bit)) < (last_div & (1 << audio_bit)) { + // trigger DIV-APU + returning.num_apu_ticks += 1; + } + + self.div = div; + last_div = div; + div_diff -= 1; } - - self.div = div; - last_div = div; - div_diff -= 1; + self.div_counter %= 256; } - self.div_counter %= 256; if self.control.enable { self.tima_counter += steps; diff --git a/lib/src/processor/opcodes.rs b/lib/src/processor/opcodes.rs index 05011d3..140d469 100644 --- a/lib/src/processor/opcodes.rs +++ b/lib/src/processor/opcodes.rs @@ -94,11 +94,11 @@ where // stop // 1 cycle long if self.memory.try_switch_speed() { - 2050 - } else { + self.increment_timers_div_optional(2050, false); 0 + } else { + 1 } - // panic!("stop instruction"); } 0x11 => { self.reg.de = self.ld_immediate_word();