Small RDP accuracy improvement
This commit is contained in:
@@ -80,7 +80,7 @@ std::vector<u8> MMIO::Serialize() {
|
|||||||
index += sizeof(RSP);
|
index += sizeof(RSP);
|
||||||
memcpy(res.data() + index, &rdp.dpc, sizeof(DPC));
|
memcpy(res.data() + index, &rdp.dpc, sizeof(DPC));
|
||||||
index += 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;
|
index += 0xFFFFF;
|
||||||
std::ranges::copy(rdp.rdram, res.begin() + index);
|
std::ranges::copy(rdp.rdram, res.begin() + index);
|
||||||
index += RDRAM_SIZE;
|
index += RDRAM_SIZE;
|
||||||
@@ -127,7 +127,7 @@ void MMIO::Deserialize(const std::vector<u8> &data) {
|
|||||||
index += sizeof(RSP);
|
index += sizeof(RSP);
|
||||||
memcpy(&rdp.dpc, data.data() + index, sizeof(DPC));
|
memcpy(&rdp.dpc, data.data() + index, sizeof(DPC));
|
||||||
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;
|
index += 0xFFFFF;
|
||||||
std::copy_n(data.begin() + index, RDRAM_SIZE, rdp.rdram.begin());
|
std::copy_n(data.begin() + index, RDRAM_SIZE, rdp.rdram.begin());
|
||||||
index += RDRAM_SIZE;
|
index += RDRAM_SIZE;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace n64 {
|
|||||||
RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) {
|
RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) {
|
||||||
rdram.resize(RDRAM_SIZE);
|
rdram.resize(RDRAM_SIZE);
|
||||||
std::ranges::fill(rdram, 0);
|
std::ranges::fill(rdram, 0);
|
||||||
memset(cmd_buf, 0, 0x100000);
|
std::ranges::fill(cmd_buf, 0);
|
||||||
dpc.status.raw = 0x80;
|
dpc.status.raw = 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ void RDP::Reset() {
|
|||||||
dpc = {};
|
dpc = {};
|
||||||
dpc.status.raw = 0x80;
|
dpc.status.raw = 0x80;
|
||||||
std::ranges::fill(rdram, 0);
|
std::ranges::fill(rdram, 0);
|
||||||
memset(cmd_buf, 0, 0x100000);
|
std::ranges::fill(cmd_buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -124,26 +124,37 @@ void RDP::Write(const u32 addr, const u32 val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RDP::WriteStatus(const u32 val) {
|
void RDP::WriteStatus(const u32 val) {
|
||||||
DPCStatusWrite temp{};
|
DPCStatusWrite temp{};
|
||||||
temp.raw = val;
|
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);
|
CLEAR_SET(dpc.status.xbusDmemDma, temp.clearXbusDmemDma, temp.setXbusDmemDma);
|
||||||
if (temp.clearFreeze) {
|
if (temp.clearFreeze) {
|
||||||
dpc.status.freeze = false;
|
dpc.status.freeze = false;
|
||||||
|
unfrozen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp.setFreeze) {
|
if (temp.setFreeze) {
|
||||||
dpc.status.freeze = true;
|
dpc.status.freeze = true;
|
||||||
}
|
}
|
||||||
CLEAR_SET(dpc.status.flush, temp.clearFlush, temp.setFlush);
|
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.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();
|
RunCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,14 +218,14 @@ void RDP::RunCommand() {
|
|||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (len + remaining_cmds * 4 > 0xFFFFF) {
|
if (len + remaining_cmds * 4 > COMMAND_BUFFER_SIZE) {
|
||||||
panic("Too many RDP commands");
|
panic("Too many RDP commands");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpc.status.xbusDmemDma) {
|
if (dpc.status.xbusDmemDma) {
|
||||||
for (int i = 0; i < len; i += 4) {
|
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;
|
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -234,10 +245,10 @@ void RDP::RunCommand() {
|
|||||||
bool processed_all = true;
|
bool processed_all = true;
|
||||||
|
|
||||||
while (buf_index < word_len) {
|
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];
|
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;
|
remaining_cmds = word_len - buf_index;
|
||||||
|
|
||||||
u32 tmp[remaining_cmds];
|
u32 tmp[remaining_cmds];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <common.hpp>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <common.hpp>
|
||||||
|
|
||||||
class ParallelRDP;
|
class ParallelRDP;
|
||||||
|
|
||||||
@@ -53,8 +54,10 @@ struct DPC {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RDP {
|
struct RDP {
|
||||||
|
static constexpr auto COMMAND_BUFFER_SIZE = 0xFFFFF;
|
||||||
|
|
||||||
DPC dpc{};
|
DPC dpc{};
|
||||||
u32 cmd_buf[0xFFFFF]{};
|
std::array<u32, COMMAND_BUFFER_SIZE> cmd_buf{};
|
||||||
|
|
||||||
RDP(Mem &, ParallelRDP &);
|
RDP(Mem &, ParallelRDP &);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|||||||
@@ -105,6 +105,16 @@ void RSP::WriteStatus(const u32 value) {
|
|||||||
mi.InterruptLower(MI::Interrupt::SP);
|
mi.InterruptLower(MI::Interrupt::SP);
|
||||||
if (write.setIntr && !write.clearIntr)
|
if (write.setIntr && !write.clearIntr)
|
||||||
mi.InterruptRaise(MI::Interrupt::SP);
|
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.singleStep, write.clearSstep, write.setSstep);
|
||||||
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
|
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
|
||||||
CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0);
|
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.signal5, write.clearSignal5, write.setSignal5);
|
||||||
CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6);
|
CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6);
|
||||||
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
|
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
|
||||||
|
#undef CLEAR_SET
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|||||||
@@ -116,14 +116,6 @@ struct Mem;
|
|||||||
struct Registers;
|
struct Registers;
|
||||||
|
|
||||||
#define DE(x) (((x) >> 11) & 0x1F)
|
#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 {
|
struct RSP {
|
||||||
RSP(Mem &, Registers &);
|
RSP(Mem &, Registers &);
|
||||||
|
|||||||
Reference in New Issue
Block a user