Refactor interrupt implementation

This commit is contained in:
Franco Colmenarez 2021-10-29 17:03:02 -05:00
parent c77bc9db70
commit 66731e1c8e
3 changed files with 25 additions and 25 deletions

View File

@ -91,11 +91,11 @@ impl Bus {
pub fn write(&mut self, address: u16, data: u8) { pub fn write(&mut self, address: u16, data: u8) {
if address == 0xFF01 { if address == 0xFF01 {
print!("{}", data as char); // print!("{}", data as char);
} }
if BANK_ZERO.in_range(address) || BANK_SWITCHABLE.in_range(address) { if BANK_ZERO.in_range(address) || BANK_SWITCHABLE.in_range(address) {
println!("WRITING TO ROM"); // println!("WRITING TO ROM");
} else if WORK_RAM_1.in_range(address) || WORK_RAM_2.in_range(address) { } else if WORK_RAM_1.in_range(address) || WORK_RAM_2.in_range(address) {
self.data[address as usize] = data; self.data[address as usize] = data;
// Copy to the ECHO RAM // Copy to the ECHO RAM

View File

@ -873,39 +873,37 @@ impl CPU {
bus.set_interrupt(interrupt, false); bus.set_interrupt(interrupt, false);
let vector = Bus::get_interrupt_vector(interrupt); let vector = Bus::get_interrupt_vector(interrupt);
self.exec(Opcode::CALL(OpcodeParameter::U16(vector)), bus); self.exec(Opcode::CALL(OpcodeParameter::U16(vector)), bus);
self.decrement_cycles(Cycles(1)); self.increment_cycles(Cycles(5));
println!("Interrupt: {:?}", interrupt);
} }
pub fn check_interrupt(&mut self, bus: &mut Bus) -> bool { pub fn check_interrupts(&mut self, bus: &mut Bus) -> Option<Interrupt> {
if bus.get_interrupt(Interrupt::VBlank) { if bus.get_interrupt(Interrupt::VBlank) {
self.handle_interrupt(bus, Interrupt::VBlank); return Some(Interrupt::VBlank);
return true;
} else if bus.get_interrupt(Interrupt::LCDSTAT) { } else if bus.get_interrupt(Interrupt::LCDSTAT) {
self.handle_interrupt(bus, Interrupt::LCDSTAT); return Some(Interrupt::LCDSTAT);
return true;
} else if bus.get_interrupt(Interrupt::Timer) { } else if bus.get_interrupt(Interrupt::Timer) {
self.handle_interrupt(bus, Interrupt::Timer); return Some(Interrupt::Timer);
return true;
} else if bus.get_interrupt(Interrupt::Serial) { } else if bus.get_interrupt(Interrupt::Serial) {
self.handle_interrupt(bus, Interrupt::Serial); return Some(Interrupt::Serial);
return true;
} else if bus.get_interrupt(Interrupt::Joypad) { } else if bus.get_interrupt(Interrupt::Joypad) {
self.handle_interrupt(bus, Interrupt::Joypad); return Some(Interrupt::Joypad);
return true;
} }
return false; None
} }
pub fn run(&mut self, bus: &mut Bus) { pub fn run(&mut self, bus: &mut Bus) {
let cycles_start = self.get_cycles(); let cycles_start = self.get_cycles();
let program_counter = self.registers.get(Register::PC); if let Some(interrupt) = self.check_interrupts(bus) {
let parameter_bytes = OpcodeParameterBytes::from_address(program_counter, bus); self.handle_interrupt(bus, interrupt);
let (opcode, cycles) = parameter_bytes.parse_opcode(); } else {
if !env::var("CPU_LOG").is_err() { let program_counter = self.registers.get(Register::PC);
self.log(parameter_bytes); let parameter_bytes = OpcodeParameterBytes::from_address(program_counter, bus);
} let (opcode, cycles) = parameter_bytes.parse_opcode();
self.increment_cycles(cycles); if !env::var("CPU_LOG").is_err() {
if !self.check_interrupt(bus) { self.log(parameter_bytes);
}
self.increment_cycles(cycles);
self.exec(opcode, bus); self.exec(opcode, bus);
} }
let cycles_end = self.get_cycles(); let cycles_end = self.get_cycles();

View File

@ -98,8 +98,10 @@ impl PPU {
pub fn cycle(&mut self, bus: &mut Bus) { pub fn cycle(&mut self, bus: &mut Bus) {
// Mode 1 Vertical blank // Mode 1 Vertical blank
if PPU::get_lcd_y(bus) >= 144 { if PPU::get_lcd_y(bus) >= 144 {
bus.set_interrupt(Interrupt::VBlank, true); if PPU::get_lcd_y(bus) == 144 {
PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::VBlank), true); bus.set_interrupt(Interrupt::VBlank, true);
PPU::set_lcd_status(bus, LCDStatus::ModeFlag(LCDStatusModeFlag::VBlank), true);
}
} else { } else {
if self.cycles.0 == 0 { if self.cycles.0 == 0 {
// Mode 2 OAM scan // Mode 2 OAM scan