double speed!!!! maybe there are edge cases but ive mostly got it
This commit is contained in:
parent
a5c45b48b9
commit
8c574fc47e
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue