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,
{
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

View file

@ -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;

View file

@ -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();