Implement proper shutdown
This commit is contained in:
parent
74234dd405
commit
92855bf6b9
23
src/cpu.rs
23
src/cpu.rs
@ -21,6 +21,12 @@ const FLAG_N: u8 = 1 << 6;
|
||||
const FLAG_H: u8 = 1 << 5;
|
||||
const FLAG_C: u8 = 1 << 4;
|
||||
|
||||
use interconnect::TickResult;
|
||||
enum CpuTickResult {
|
||||
Continue { cycles_executed: usize },
|
||||
Shutdown { cycles_executed: usize },
|
||||
}
|
||||
|
||||
pub struct CPU {
|
||||
// Registers: B, C, D, E, H, L, A
|
||||
regs: [u8; 7],
|
||||
@ -904,9 +910,13 @@ impl CPU {
|
||||
// The gameboy has a freq of 4.194304MHz
|
||||
// This means it takes it 238.418569ns to execute a single
|
||||
// cycle.
|
||||
let expected_cycles = start.elapsed().as_nanos() / 238;
|
||||
let expected_cycles = start.elapsed().as_nanos() / (238 / 2);
|
||||
while cycles_executed < expected_cycles {
|
||||
cycles_executed += self.run_instruction() as u128;
|
||||
if let CpuTickResult::Continue { cycles_executed: x, .. } = self.run_instruction() {
|
||||
cycles_executed += x as u128;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sleep(Duration::new(0, 10 * 238));
|
||||
}
|
||||
@ -951,7 +961,7 @@ impl CPU {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn run_instruction(&mut self) -> u8 {
|
||||
pub fn run_instruction(&mut self) -> CpuTickResult {
|
||||
// self.debug = !self.interconnect.is_boot_rom();
|
||||
if !self.trigger_once && !self.interconnect.is_boot_rom() {
|
||||
self.trigger_once = true;
|
||||
@ -1745,7 +1755,10 @@ impl CPU {
|
||||
_ => panic!("Unknown instruction: {:02x}", instruction),
|
||||
};
|
||||
}
|
||||
self.interconnect.tick(cycles);
|
||||
cycles
|
||||
|
||||
if self.interconnect.tick(cycles) == TickResult::Shutdown {
|
||||
return CpuTickResult::Shutdown { cycles_executed: cycles as usize }
|
||||
}
|
||||
CpuTickResult::Continue { cycles_executed: cycles as usize }
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,12 @@ extern crate sdl2;
|
||||
use self::sdl2::event::Event;
|
||||
use self::sdl2::keyboard::Keycode;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum TickResult {
|
||||
Continue,
|
||||
Shutdown,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Key {
|
||||
UP,
|
||||
@ -137,7 +143,7 @@ impl Interconnect {
|
||||
}
|
||||
|
||||
// Somehow we need different timers for this.
|
||||
pub fn tick(&mut self, cycles: u8) {
|
||||
pub fn tick(&mut self, cycles: u8) -> TickResult {
|
||||
self.display.tick(cycles as u16);
|
||||
self.timer.tick(cycles as u16);
|
||||
|
||||
@ -168,7 +174,7 @@ impl Interconnect {
|
||||
..
|
||||
} => {
|
||||
self.cartridge.save();
|
||||
panic!("TODO: Proper shutdown");
|
||||
return TickResult::Shutdown;
|
||||
}
|
||||
Event::KeyDown {
|
||||
keycode: Some(Keycode::Left),
|
||||
@ -245,6 +251,7 @@ impl Interconnect {
|
||||
} else {
|
||||
self.cycles += cycles as u16;
|
||||
}
|
||||
TickResult::Continue
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@ -36,9 +36,7 @@ fn main() {
|
||||
let interconnect = interconnect::Interconnect::new(bios, rom, save_file);
|
||||
let mut cpu = cpu::CPU::new(interconnect);
|
||||
|
||||
loop {
|
||||
cpu.run();
|
||||
}
|
||||
cpu.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user