double speed!!!! maybe there are edge cases but ive mostly got it

This commit is contained in:
Alex Janka 2023-04-22 21:39:46 +10:00
parent a5c45b48b9
commit 8c574fc47e
3 changed files with 35 additions and 24 deletions

View file

@ -522,14 +522,26 @@ where
C: PocketCamera + Send + 'static, C: PocketCamera + Send + 'static,
{ {
pub fn increment_timers(&mut self, machine_cycles: usize) { 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 steps = machine_cycles * 4;
let logical_steps = if self.memory.is_double_speed() {
steps / 2
} else {
steps
};
self.cycle_count += steps; self.cycle_count += steps;
self.memory.oam_dma_tick(steps); self.memory.oam_dma_tick(steps);
self.memory.camera.lock().unwrap().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 { for _ in 0..timer_return.num_apu_ticks {
self.memory.apu.div_apu_tick(); self.memory.apu.div_apu_tick();
@ -539,14 +551,14 @@ where
self.memory.interrupts.set_interrupt(Interrupt::Timer, true); 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); let serial_interrupt = self.memory.serial.tick(steps, self.memory.ime);
self.memory self.memory
.interrupts .interrupts
.set_interrupt(Interrupt::Serial, serial_interrupt); .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 self.memory
.interrupts .interrupts

View file

@ -74,10 +74,6 @@ pub struct Timer {
tima_counter: usize, 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 { impl Timer {
pub fn init() -> Self { pub fn init() -> Self {
Self { Self {
@ -90,15 +86,17 @@ impl Timer {
} }
} }
pub fn tick(&mut self, steps: usize) -> TimerReturn { pub fn tick(&mut self, steps: usize, with_div: bool, double_speed: bool) -> TimerReturn {
let mut returning = TimerReturn::default();
if with_div {
let audio_bit = if double_speed { 5 } else { 4 };
self.div_counter += steps; self.div_counter += steps;
let mut div_diff = (self.div_counter / 256) as u8; let mut div_diff = (self.div_counter / 256) as u8;
let mut last_div = self.div; let mut last_div = self.div;
let mut returning = TimerReturn::default();
while div_diff > 0 { while div_diff > 0 {
let div = last_div.wrapping_add(1); let div = last_div.wrapping_add(1);
if (div & (1 << AUDIO_BIT)) < (last_div & (1 << AUDIO_BIT)) { if (div & (1 << audio_bit)) < (last_div & (1 << audio_bit)) {
// trigger DIV-APU // trigger DIV-APU
returning.num_apu_ticks += 1; returning.num_apu_ticks += 1;
} }
@ -108,6 +106,7 @@ impl Timer {
div_diff -= 1; div_diff -= 1;
} }
self.div_counter %= 256; self.div_counter %= 256;
}
if self.control.enable { if self.control.enable {
self.tima_counter += steps; self.tima_counter += steps;

View file

@ -94,11 +94,11 @@ where
// stop // stop
// 1 cycle long // 1 cycle long
if self.memory.try_switch_speed() { if self.memory.try_switch_speed() {
2050 self.increment_timers_div_optional(2050, false);
} else {
0 0
} else {
1
} }
// panic!("stop instruction");
} }
0x11 => { 0x11 => {
self.reg.de = self.ld_immediate_word(); self.reg.de = self.ld_immediate_word();