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,
|
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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue