Small RDP accuracy improvement

This commit is contained in:
irisz64
2025-07-26 00:26:40 +02:00
parent ef05bcfac6
commit 9dec9c03b4
5 changed files with 40 additions and 23 deletions

View File

@@ -80,7 +80,7 @@ std::vector<u8> 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<u8> &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;

View File

@@ -8,7 +8,7 @@ namespace n64 {
RDP::RDP(Mem &mem, ParallelRDP &parallel) : 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<u32>(mem.mmio.rsp.dmem, (current + i) & 0xFFF);
const u32 cmd = Util::ReadAccess<u32>(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];

View File

@@ -1,6 +1,7 @@
#pragma once
#include <common.hpp>
#include <array>
#include <vector>
#include <common.hpp>
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<u32, COMMAND_BUFFER_SIZE> cmd_buf{};
RDP(Mem &, ParallelRDP &);
void Reset();

View File

@@ -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 <>

View File

@@ -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 &);