From e0a16db08c1f9f715ed2a061be61b54d617256fd Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 24 Feb 2024 15:54:20 +0100 Subject: [PATCH] SuperFX: implement interrupt --- src/cpu_gsu/cpu.rs | 15 +++++++++++++++ src/cpu_gsu/regs.rs | 2 +- src/snes/bus/mainbus.rs | 4 ++++ src/snes/cartridge.rs | 8 ++++++++ src/snes/coprocessor/superfx.rs | 13 +++++++++++-- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/cpu_gsu/cpu.rs b/src/cpu_gsu/cpu.rs index ef12ec4..981d9e2 100644 --- a/src/cpu_gsu/cpu.rs +++ b/src/cpu_gsu/cpu.rs @@ -35,6 +35,7 @@ pub struct CpuGsu { dreg: usize, last_instr: u8, branch_pc: Option, + irq_pending: bool, pub cache_valid: [bool; CACHE_LINES], } @@ -52,6 +53,7 @@ impl CpuGsu { last_instr: 0, branch_pc: None, cache_valid: [false; CACHE_LINES], + irq_pending: false, }; c.rom[0..rom.len()].copy_from_slice(rom); @@ -208,6 +210,13 @@ impl CpuGsu { (0x00, _, _) => { // STOP self.regs.write_flags(&[(Flag::G, false)]); + println!("{}", self.regs); + + if !self.regs.test_cfgr(CFGRFlag::IRQ) { + self.regs.write_flags(&[(Flag::IRQ, true)]); + self.irq_pending = true; + } + self.cycles(1)?; } (0x01, _, _) => { @@ -929,6 +938,12 @@ impl CpuGsu { } // TODO cycles } + + pub fn get_clr_int(&mut self) -> bool { + let v = self.irq_pending; + self.irq_pending = false; + v + } } impl Tickable for CpuGsu { diff --git a/src/cpu_gsu/regs.rs b/src/cpu_gsu/regs.rs index 228509b..5a2f5bf 100644 --- a/src/cpu_gsu/regs.rs +++ b/src/cpu_gsu/regs.rs @@ -288,7 +288,7 @@ impl RegisterFile { Register::SCBR => self.scbr.into(), Register::CLSR => self.clsr.into(), Register::SCMR => self.scmr.into(), - Register::VCR => 0, + Register::VCR => 1, Register::RAMBR => self.rambr.into(), Register::BRAMBR => self.brambr.into(), Register::COLR => self.colr.into(), diff --git a/src/snes/bus/mainbus.rs b/src/snes/bus/mainbus.rs index 26773b6..ea19db6 100644 --- a/src/snes/bus/mainbus.rs +++ b/src/snes/bus/mainbus.rs @@ -858,6 +858,10 @@ where self.timeup.set(true); } + if self.cartridge.get_clr_int() { + self.intreq_int = true; + } + Ok(()) } } diff --git a/src/snes/cartridge.rs b/src/snes/cartridge.rs index 70d4e35..be21cef 100644 --- a/src/snes/cartridge.rs +++ b/src/snes/cartridge.rs @@ -521,6 +521,14 @@ impl Cartridge { _ => None, } } + + pub fn get_clr_int(&mut self) -> bool { + if let Some(sfx) = self.co_superfx.as_mut() { + return sfx.get_clr_int(); + } + + false + } } impl fmt::Display for Cartridge { diff --git a/src/snes/coprocessor/superfx.rs b/src/snes/coprocessor/superfx.rs index 86807e8..7b0913d 100644 --- a/src/snes/coprocessor/superfx.rs +++ b/src/snes/coprocessor/superfx.rs @@ -21,6 +21,11 @@ impl SuperFX { cpu: RefCell::new(CpuGsu::new(rom)), } } + + pub fn get_clr_int(&mut self) -> bool { + let mut cpu = self.cpu.borrow_mut(); + cpu.get_clr_int() + } } impl Tickable for SuperFX { @@ -34,7 +39,7 @@ impl Tickable for SuperFX { impl BusMember
for SuperFX { fn read(&self, fulladdr: Address) -> Option { let (_bank, addr) = ((fulladdr >> 16) as usize, (fulladdr & 0xFFFF) as usize); - let cpu = self.cpu.borrow(); + let mut cpu = self.cpu.borrow_mut(); //println!("SuperFX read: {:04X}", addr); match addr { @@ -49,7 +54,11 @@ impl BusMember
for SuperFX { Some((cpu.regs.read_r(r) >> 8) as u8) } } - 0x3030 => Some(cpu.regs.read(Register::SFR) as u8), + 0x3030 => { + let v = cpu.regs.read(Register::SFR) as u8; + cpu.regs.write_flags(&[(Flag::IRQ, false)]); + Some(v) + } 0x3031 => Some((cpu.regs.read(Register::SFR) >> 8) as u8), // 0x3032 unused 0x3033 => Some(cpu.regs.read8(Register::BRAMBR)),