From 9dec9c03b42fc4e121b89fb45b058e8c3c63a536 Mon Sep 17 00:00:00 2001 From: irisz64 Date: Sat, 26 Jul 2025 00:26:40 +0200 Subject: [PATCH] Small RDP accuracy improvement --- src/backend/core/MMIO.cpp | 4 ++-- src/backend/core/RDP.cpp | 33 ++++++++++++++++++++++----------- src/backend/core/RDP.hpp | 7 +++++-- src/backend/core/RSP.cpp | 11 +++++++++++ src/backend/core/RSP.hpp | 8 -------- 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index b692da9d..0174bd0f 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -80,7 +80,7 @@ std::vector MMIO::Serialize() { index += sizeof(RSP); memcpy(res.data() + index, &rdp.dpc, sizeof(DPC)); index += sizeof(DPC); - memcpy(res.data() + index, rdp.cmd_buf, 0xFFFFF); + memcpy(res.data() + index, rdp.cmd_buf.data(), RDP::COMMAND_BUFFER_SIZE); index += 0xFFFFF; std::ranges::copy(rdp.rdram, res.begin() + index); index += RDRAM_SIZE; @@ -127,7 +127,7 @@ void MMIO::Deserialize(const std::vector &data) { index += sizeof(RSP); memcpy(&rdp.dpc, data.data() + index, sizeof(DPC)); index += sizeof(DPC); - memcpy(rdp.cmd_buf, data.data() + index, 0xFFFFF); + memcpy(rdp.cmd_buf.data(), data.data() + index, RDP::COMMAND_BUFFER_SIZE); index += 0xFFFFF; std::copy_n(data.begin() + index, RDRAM_SIZE, rdp.rdram.begin()); index += RDRAM_SIZE; diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index 16182ffd..a2bc6773 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -8,7 +8,7 @@ namespace n64 { RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) { rdram.resize(RDRAM_SIZE); std::ranges::fill(rdram, 0); - memset(cmd_buf, 0, 0x100000); + std::ranges::fill(cmd_buf, 0); dpc.status.raw = 0x80; } @@ -16,7 +16,7 @@ void RDP::Reset() { dpc = {}; dpc.status.raw = 0x80; std::ranges::fill(rdram, 0); - memset(cmd_buf, 0, 0x100000); + std::ranges::fill(cmd_buf, 0); } template <> @@ -124,26 +124,37 @@ void RDP::Write(const u32 addr, const u32 val) { } } + + void RDP::WriteStatus(const u32 val) { DPCStatusWrite temp{}; temp.raw = val; + bool unfrozen = false; +#define CLEAR_SET(val, clear, set) \ + do { \ + if ((clear)) \ + (val) = 0; \ + if ((set)) \ + (val) = 1; \ + } \ + while (0) CLEAR_SET(dpc.status.xbusDmemDma, temp.clearXbusDmemDma, temp.setXbusDmemDma); if (temp.clearFreeze) { dpc.status.freeze = false; + unfrozen = true; } if (temp.setFreeze) { dpc.status.freeze = true; } CLEAR_SET(dpc.status.flush, temp.clearFlush, temp.setFlush); - CLEAR_SET(dpc.status.cmdBusy, temp.clearCmd, false); - if (temp.clearClock) - dpc.clock = 0; - CLEAR_SET(dpc.status.pipeBusy, temp.clearPipe, false); CLEAR_SET(dpc.status.tmemBusy, temp.clearTmem, false); + CLEAR_SET(dpc.status.pipeBusy, temp.clearPipe, false); + CLEAR_SET(dpc.status.cmdBusy, temp.clearCmd, false); + CLEAR_SET(dpc.clock, temp.clearClock, false); - if (!dpc.status.freeze) { + if (!unfrozen) { RunCommand(); } } @@ -207,14 +218,14 @@ void RDP::RunCommand() { if (len <= 0) return; - if (len + remaining_cmds * 4 > 0xFFFFF) { + if (len + remaining_cmds * 4 > COMMAND_BUFFER_SIZE) { panic("Too many RDP commands"); return; } if (dpc.status.xbusDmemDma) { for (int i = 0; i < len; i += 4) { - const u32 cmd = Util::ReadAccess(mem.mmio.rsp.dmem, (current + i) & 0xFFF); + const u32 cmd = Util::ReadAccess(mem.mmio.rsp.dmem, current + i & 0xFFF); cmd_buf[remaining_cmds + (i >> 2)] = cmd; } } else { @@ -234,10 +245,10 @@ void RDP::RunCommand() { bool processed_all = true; while (buf_index < word_len) { - const u8 cmd = (cmd_buf[buf_index] >> 24) & 0x3F; + const u8 cmd = cmd_buf[buf_index] >> 24 & 0x3F; const int cmd_len = cmd_lens[cmd]; - if ((buf_index + cmd_len) * 4 > len + (remaining_cmds * 4)) { + if ((buf_index + cmd_len) * 4 > len + remaining_cmds * 4) { remaining_cmds = word_len - buf_index; u32 tmp[remaining_cmds]; diff --git a/src/backend/core/RDP.hpp b/src/backend/core/RDP.hpp index 82239c4f..95837b46 100644 --- a/src/backend/core/RDP.hpp +++ b/src/backend/core/RDP.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include #include +#include class ParallelRDP; @@ -53,8 +54,10 @@ struct DPC { }; struct RDP { + static constexpr auto COMMAND_BUFFER_SIZE = 0xFFFFF; + DPC dpc{}; - u32 cmd_buf[0xFFFFF]{}; + std::array cmd_buf{}; RDP(Mem &, ParallelRDP &); void Reset(); diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index d690eb22..3de0eadf 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -105,6 +105,16 @@ void RSP::WriteStatus(const u32 value) { mi.InterruptLower(MI::Interrupt::SP); if (write.setIntr && !write.clearIntr) mi.InterruptRaise(MI::Interrupt::SP); + +#define CLEAR_SET(val, clear, set) \ + do { \ + if ((clear) && !(set)) \ + (val) = 0; \ + if ((set) && !(clear)) \ + (val) = 1; \ + } \ + while (0) + CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep); CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak); CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0); @@ -115,6 +125,7 @@ void RSP::WriteStatus(const u32 value) { CLEAR_SET(spStatus.signal5, write.clearSignal5, write.setSignal5); CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6); CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7); +#undef CLEAR_SET } template <> diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 174f66e6..af6cc012 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -116,14 +116,6 @@ struct Mem; struct Registers; #define DE(x) (((x) >> 11) & 0x1F) -#define CLEAR_SET(val, clear, set) \ - do { \ - if ((clear) && !(set)) \ - (val) = 0; \ - if ((set) && !(clear)) \ - (val) = 1; \ - } \ - while (0) struct RSP { RSP(Mem &, Registers &);