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