fix(cpu): use enums only of maintaining IME register state

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-04-05 01:10:03 -05:00
parent 77c7c610d0
commit 748c32c446
2 changed files with 14 additions and 18 deletions

View File

@ -4,7 +4,6 @@ use super::interrupt::{InterruptEnable, InterruptFlag};
use super::ppu::Ppu; use super::ppu::Ppu;
use bitfield::bitfield; use bitfield::bitfield;
use std::fmt::{Display, Formatter, Result as FmtResult}; use std::fmt::{Display, Formatter, Result as FmtResult};
use std::ops::Add;
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct Cpu { pub struct Cpu {
@ -155,13 +154,18 @@ impl Cpu {
} }
fn check_ime(&mut self) { fn check_ime(&mut self) {
if let ImeState::EnablePending(count) = self.ime { match self.ime {
self.ime = if count < 2 { ImeState::Pending => {
self.ime.wait() // This is within the context of the EI instruction, we need to not update EI until the end of the
} else { // next executed Instruction
ImeState::Enabled self.ime = ImeState::PendingEnd;
} }
}; ImeState::PendingEnd => {
// The Instruction after EI has now been executed, so we want to enable the IME flag here
self.ime = ImeState::Enabled;
}
ImeState::Disabled | ImeState::Enabled => {} // Do Nothing
}
} }
fn handle_interrupts(&mut self) { fn handle_interrupts(&mut self) {
@ -478,8 +482,9 @@ pub enum HaltState {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum ImeState { pub enum ImeState {
Disabled, Disabled,
Pending,
PendingEnd,
Enabled, Enabled,
EnablePending(u8),
} }
impl Default for ImeState { impl Default for ImeState {
@ -487,12 +492,3 @@ impl Default for ImeState {
Self::Disabled Self::Disabled
} }
} }
impl ImeState {
pub fn wait(self) -> Self {
match self {
Self::EnablePending(count) => Self::EnablePending(count + 1),
_ => panic!("IME is {:?}, however wait() was called", self),
}
}
}

View File

@ -1022,7 +1022,7 @@ impl Instruction {
Instruction::EI => { Instruction::EI => {
// Enable IME (After the next instruction) // Enable IME (After the next instruction)
// FIXME: IME is set after the next instruction, this currently is not represented in this emulator. // FIXME: IME is set after the next instruction, this currently is not represented in this emulator.
cpu.set_ime(ImeState::EnablePending(0)); cpu.set_ime(ImeState::Pending);
Cycle::new(4) Cycle::new(4)
} }
Instruction::CALL(cond, nn) => { Instruction::CALL(cond, nn) => {