From 687badc14208b2240c2acbfd68b9e4295bd4efc2 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:49:29 +0100 Subject: [PATCH] Modify RSP sync points (#198) * modify RSP sync points * more * more * more * more * more * more * more --- src/device.rs | 1 + src/device/rdp.rs | 11 ++++++++++- src/device/rsp_interface.rs | 28 +++++++++++++++++++++++----- src/device/rsp_su_instructions.rs | 3 --- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/device.rs b/src/device.rs index 621faaa..b2970df 100644 --- a/src/device.rs +++ b/src/device.rs @@ -367,6 +367,7 @@ impl Device { regs: [0; rsp_interface::SP_REGS_COUNT as usize], regs2: [0; rsp_interface::SP_REGS2_COUNT as usize], mem: [0; 0x2000], + last_status_value: 0, fifo: [rsp_interface::RspDma { dir: rsp_interface::DmaDir::None, length: 0, diff --git a/src/device/rdp.rs b/src/device/rdp.rs index 971425c..c61f4db 100644 --- a/src/device/rdp.rs +++ b/src/device/rdp.rs @@ -52,7 +52,16 @@ pub fn read_regs_dpc( address: u64, _access_size: device::memory::AccessSize, ) -> u32 { - device.rdp.regs_dpc[((address & 0xFFFF) >> 2) as usize] + let reg = (address & 0xFFFF) >> 2; + match reg as u32 { + DPC_CURRENT_REG => { + if device.rdp.wait_frozen { + device.rsp.cpu.sync_point = true; + } + device.rdp.regs_dpc[reg as usize] + } + _ => device.rdp.regs_dpc[reg as usize], + } } pub fn write_regs_dpc(device: &mut device::Device, address: u64, value: u32, mask: u32) { diff --git a/src/device/rsp_interface.rs b/src/device/rsp_interface.rs index 2fbb404..cec05b5 100644 --- a/src/device/rsp_interface.rs +++ b/src/device/rsp_interface.rs @@ -81,6 +81,7 @@ pub struct Rsp { pub regs2: [u32; SP_REGS2_COUNT as usize], pub mem: [u8; 0x2000], pub fifo: [RspDma; 2], + pub last_status_value: u32, } pub fn read_mem_fast( @@ -260,8 +261,27 @@ pub fn read_regs( ) -> u32 { let reg = (address & 0xFFFF) >> 2; match reg as u32 { + SP_DMA_BUSY_REG | SP_DMA_FULL_REG => { + if device.rsp.regs[reg as usize] != 0 { + device.rsp.cpu.sync_point = true; + } + device.rsp.regs[reg as usize] + } + SP_STATUS_REG => { + let value = device.rsp.regs[reg as usize] + & !(SP_STATUS_HALT | SP_STATUS_BROKE | SP_STATUS_INTR_BREAK); + if value == device.rsp.last_status_value && value != 0 { + device.rsp.cpu.sync_point = true; + } + device.rsp.last_status_value = value; + device.rsp.regs[reg as usize] + } SP_SEMAPHORE_REG => { let value = device.rsp.regs[reg as usize]; + if value == 1 { + device.rsp.cpu.sync_point = true; + device.rsp.cpu.cycle_counter += 4; // needed for DK64 + } device.rsp.regs[reg as usize] = 1; value } @@ -284,9 +304,7 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u SP_SEMAPHORE_REG => { device::memory::masked_write_32(&mut device.rsp.regs[reg as usize], 0, mask) } - _ => { - device::memory::masked_write_32(&mut device.rsp.regs[reg as usize], value, mask); - } + _ => device::memory::masked_write_32(&mut device.rsp.regs[reg as usize], value, mask), } } @@ -421,12 +439,13 @@ fn update_sp_status(device: &mut device::Device, w: u32) { if device.rsp.regs[SP_STATUS_REG as usize] & SP_STATUS_HALT == 0 && was_halted { device.rsp.cpu.broken = false; device.rsp.cpu.halted = false; - device.rsp.cpu.sync_point = false; do_task(device); } } fn do_task(device: &mut device::Device) { + device.rsp.cpu.sync_point = false; + device.rsp.last_status_value = 0; let timer = device::rsp_cpu::run(device); device::events::create_event( @@ -450,7 +469,6 @@ fn rsp_event(device: &mut device::Device) { device.rsp.regs[SP_STATUS_REG as usize] |= SP_STATUS_HALT; return; } - device.rsp.cpu.sync_point = false; do_task(device) } diff --git a/src/device/rsp_su_instructions.rs b/src/device/rsp_su_instructions.rs index b454e73..07d0e9f 100644 --- a/src/device/rsp_su_instructions.rs +++ b/src/device/rsp_su_instructions.rs @@ -565,8 +565,6 @@ pub fn mfc0(device: &mut device::Device, opcode: u32) { device::memory::AccessSize::Word, ) } - device.rsp.cpu.cycle_counter += 4; // needed for DK64 - device.rsp.cpu.sync_point = true; } pub fn mtc0(device: &mut device::Device, opcode: u32) { @@ -592,7 +590,6 @@ pub fn mtc0(device: &mut device::Device, opcode: u32) { !device::rsp_interface::SP_STATUS_HALT; // set halt when event happens device.rsp.cpu.halted = true // the RSP can halt itself by setting SP_SET_HALT } - device.rsp.cpu.sync_point = true; } pub fn mfc2(device: &mut device::Device, opcode: u32) {