diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index fd5604b..625db34 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -521,7 +521,7 @@ where R: Renderer, C: PocketCamera + Send + 'static, { - pub fn increment_timers(&mut self, machine_cycles: u8) { + pub fn increment_timers(&mut self, machine_cycles: usize) { let steps = (machine_cycles as usize) * 4; self.cycle_count += steps; diff --git a/lib/src/processor/memory/mmio/cgb/double_speed.rs b/lib/src/processor/memory/mmio/cgb/double_speed.rs index 951ac55..79d103c 100644 --- a/lib/src/processor/memory/mmio/cgb/double_speed.rs +++ b/lib/src/processor/memory/mmio/cgb/double_speed.rs @@ -32,14 +32,16 @@ where .map_or(false, |v| v.double_speed.current) } - pub(crate) fn should_switch_speed(&mut self) -> bool { + pub(crate) fn try_switch_speed(&mut self) -> bool { if let Some(cgb_peripherals) = &mut self.cgb_peripherals { if cgb_peripherals.double_speed.prepared && !cgb_peripherals.double_speed.current { + println!("switching to double speed"); cgb_peripherals.double_speed.current = true; cgb_peripherals.double_speed.prepared = false; return true; } else if cgb_peripherals.double_speed.prepared && cgb_peripherals.double_speed.current { + println!("switching to normal speed"); cgb_peripherals.double_speed.current = false; cgb_peripherals.double_speed.prepared = false; return true; diff --git a/lib/src/processor/mod.rs b/lib/src/processor/mod.rs index e5d0321..2a0e6d0 100644 --- a/lib/src/processor/mod.rs +++ b/lib/src/processor/mod.rs @@ -98,15 +98,9 @@ where } // double this if in double speed mode - let mut vram_dma_cycles = self.memory.vram_dma_tick(); - while vram_dma_cycles > 0 { - let cycles = if vram_dma_cycles > 0xFF { - 0xFF - } else { - vram_dma_cycles as u8 - }; - vram_dma_cycles -= cycles as usize; - self.increment_timers(cycles); + let vram_dma_cycles = self.memory.vram_dma_tick(); + if vram_dma_cycles > 0 { + self.increment_timers(vram_dma_cycles); let interrupt_cycles = self.handle_interrupts(); self.increment_timers(interrupt_cycles); } @@ -152,7 +146,7 @@ where } } - fn handle_interrupts(&mut self) -> u8 { + fn handle_interrupts(&mut self) -> usize { if self.memory.ime { if let Some(interrupt) = self.memory.interrupts.get_next_interrupt() { // if interrupt != Interrupt::Vblank { diff --git a/lib/src/processor/opcodes.rs b/lib/src/processor/opcodes.rs index 8574a9f..05011d3 100644 --- a/lib/src/processor/opcodes.rs +++ b/lib/src/processor/opcodes.rs @@ -15,7 +15,7 @@ where R: Renderer, C: PocketCamera + Send + 'static, { - pub fn run_opcode(&mut self, opcode: u8) -> u8 { + pub fn run_opcode(&mut self, opcode: u8) -> usize { match opcode { 0x00 => { // noop @@ -93,7 +93,12 @@ where 0x10 => { // stop // 1 cycle long - panic!("stop instruction"); + if self.memory.try_switch_speed() { + 2050 + } else { + 0 + } + // panic!("stop instruction"); } 0x11 => { self.reg.de = self.ld_immediate_word(); @@ -1231,7 +1236,7 @@ where } } - fn cb_subop(&mut self, subop: u8) -> u8 { + fn cb_subop(&mut self, subop: u8) -> usize { match subop { 0x00 => { let val = self.rlc(self.reg.get_8(Reg8::B)); @@ -2453,6 +2458,6 @@ where } } -fn undefined(opcode: u8) -> u8 { +fn undefined(opcode: u8) -> usize { panic!("Undefined behaviour: opcode {opcode:#X}"); }