fix bug when handling NMI interrupt and WIP for IRQ

This commit is contained in:
2024-04-14 19:00:44 -05:00
parent b329659683
commit c96bc77c4d
2 changed files with 17 additions and 9 deletions
+15 -9
View File
@@ -1,4 +1,4 @@
use super::{instructions::{phk::PHK, php::PHP, push_common, CPUInstruction}, interface::CPU, internal_registers::RDNMI}; use super::{instructions::push_common, interface::CPU, internal_registers::RDNMI};
use crate::cpu::bus::Bus; use crate::cpu::bus::Bus;
@@ -38,23 +38,26 @@ impl CPU {
self.registers.is_cpu_stopped = false; self.registers.is_cpu_stopped = false;
} }
fn push_emulation_interrupt(&mut self, bus: &mut Bus) { fn push_interrupt(&mut self, bus: &mut Bus) {
let pbr = self.registers.pbr;
if !self.registers.emulation_mode { if !self.registers.emulation_mode {
PHK{}.execute(&mut self.registers, bus); push_common::do_push(&mut self.registers, bus, &[pbr]);
} }
let values = [ let values = [
(self.registers.pc >> 8) as u8, (self.registers.pc >> 8) as u8,
self.registers.pc as u8, self.registers.pc as u8,
]; ];
push_common::do_push(&mut self.registers, bus, &values); push_common::do_push(&mut self.registers, bus, &values);
PHP{}.execute(&mut self.registers, bus); let p = self.registers.p;
push_common::do_push(&mut self.registers, bus, &[p]);
} }
fn handle_interrupt(&mut self, bus: &mut Bus, vector: Vector) { fn handle_interrupt(&mut self, bus: &mut Bus, vector: Vector) {
self.push_emulation_interrupt(bus); self.push_interrupt(bus);
let effective_vector = vector.get_base_address(); let base_address = vector.get_base_address();
self.registers.pc = effective_vector as u16; let effective_vector = CPU::get_vector(base_address, bus);
self.registers.pbr = (effective_vector >> 16) as u8; self.registers.pc = effective_vector;
self.registers.pbr = 0x00;
} }
pub fn check_interrupts(&mut self, bus: &mut Bus) { pub fn check_interrupts(&mut self, bus: &mut Bus) {
@@ -62,7 +65,10 @@ impl CPU {
if rdnmi_byte >> 7 != 0 { if rdnmi_byte >> 7 != 0 {
self.registers.is_cpu_waiting_interrupt = false; self.registers.is_cpu_waiting_interrupt = false;
self.handle_interrupt(bus, Vector::NMI); self.handle_interrupt(bus, Vector::NMI);
return; }
if !self.registers.get_irq_disable_flag() && bus.ppu.is_irq_set {
self.registers.is_cpu_waiting_interrupt = false;
self.handle_interrupt(bus, Vector::IRQ);
} }
} }
+2
View File
@@ -4,6 +4,7 @@ pub struct PPU {
framebuffer: Vec<u8>, framebuffer: Vec<u8>,
pub registers: PPURegisters, pub registers: PPURegisters,
was_vblank_nmi_set: bool, was_vblank_nmi_set: bool,
pub is_irq_set: bool,
} }
impl PPU { impl PPU {
@@ -12,6 +13,7 @@ impl PPU {
framebuffer: vec![], framebuffer: vec![],
registers: PPURegisters::new(), registers: PPURegisters::new(),
was_vblank_nmi_set: false, was_vblank_nmi_set: false,
is_irq_set: false,
} }
} }