more accurate timing
This commit is contained in:
parent
645b5e365a
commit
f42f58a663
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use self::{gpu::Gpu, memory::Memory, timer::Timers};
|
use self::{gpu::Gpu, memory::Memory, timer::Timers};
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{clear_bit, get_bit},
|
util::{clear_bit, get_bit},
|
||||||
|
@ -35,6 +37,7 @@ pub struct Cpu {
|
||||||
halted: bool,
|
halted: bool,
|
||||||
timers: Timers,
|
timers: Timers,
|
||||||
gamepad_handler: Gilrs,
|
gamepad_handler: Gilrs,
|
||||||
|
cycle_start: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hz
|
// Hz
|
||||||
|
@ -62,15 +65,18 @@ impl Cpu {
|
||||||
halted: false,
|
halted: false,
|
||||||
timers: Timers::init(),
|
timers: Timers::init(),
|
||||||
gamepad_handler,
|
gamepad_handler,
|
||||||
|
cycle_start: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec_next(&mut self) {
|
pub fn exec_next(&mut self) {
|
||||||
|
self.cycle_start = Instant::now();
|
||||||
let interrupt_cycles = self.handle_interrupts();
|
let interrupt_cycles = self.handle_interrupts();
|
||||||
self.increment_timers(interrupt_cycles);
|
self.increment_timers(interrupt_cycles);
|
||||||
|
|
||||||
if self.halted {
|
if self.halted {
|
||||||
self.increment_timers(1);
|
self.increment_timers(1);
|
||||||
|
self.sleep(interrupt_cycles + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +100,7 @@ impl Cpu {
|
||||||
let cycles = self.run_opcode(opcode);
|
let cycles = self.run_opcode(opcode);
|
||||||
self.memory.user_mode = false;
|
self.memory.user_mode = false;
|
||||||
self.increment_timers(cycles);
|
self.increment_timers(cycles);
|
||||||
|
self.sleep(interrupt_cycles + cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_opcode(&mut self) -> u8 {
|
fn next_opcode(&mut self) -> u8 {
|
||||||
|
|
|
@ -44,9 +44,15 @@ impl Cpu {
|
||||||
self.memory.set(0xFF05, val);
|
self.memory.set(0xFF05, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let secs = clock_cycles as f64 / CLOCK_SPEED as f64;
|
pub(super) fn sleep(&mut self, machine_cycles: u8) {
|
||||||
spin_sleep::sleep(Duration::from_secs_f64(secs / SPEEDUP));
|
let secs = ((machine_cycles as f64) * 4.) / CLOCK_SPEED as f64;
|
||||||
|
if let Some(remaining) =
|
||||||
|
Duration::from_secs_f64(secs / SPEEDUP).checked_sub(self.cycle_start.elapsed())
|
||||||
|
{
|
||||||
|
spin_sleep::sleep(remaining);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timer_scale(&self) -> (bool, usize) {
|
fn timer_scale(&self) -> (bool, usize) {
|
||||||
|
|
Loading…
Reference in a new issue