Implement proper shutdown

This commit is contained in:
Kevin Hamacher 2020-02-17 19:23:16 +01:00
parent 74234dd405
commit 92855bf6b9
3 changed files with 28 additions and 10 deletions

View File

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

View File

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

View File

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