it's a start...

This commit is contained in:
2026-05-28 17:53:52 +02:00
parent 4f42a673a3
commit 430ccdab40
4 changed files with 402 additions and 333 deletions
+3
View File
@@ -88,6 +88,9 @@ void Core::StepRSP(const u32 cpuCycles) {
return;
}
if (cpuType == CachedInterpreter)
return mmio.rsp.ExecuteCached();
static constexpr u32 cpuRatio = 3, rspRatio = 2;
regs.steps += cpuCycles;
-2
View File
@@ -152,8 +152,6 @@ u32 Interpreter::ExecuteCached() {
// 0, making so the emulator halts cause the outer loop won't advance
const auto blockCycles = line->cycles;
for (u32 i = 0; i < line->len; i++) {
addr += 4;
if (!MaybeAdvance())
return i + 1;
+67
View File
@@ -1,5 +1,6 @@
#include <Core.hpp>
#include <log.hpp>
#include <jit/helpers.hpp>
namespace n64 {
RSP::RSP() { Reset(); }
@@ -230,4 +231,70 @@ void RSP::Write(const u32 addr, const u32 val) {
panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
}
}
void RSP::CacheBlock(u16 addr) {
auto blockAddr = addr;
CachedLine line;
u32 i;
bool fetchDelaySlot = false;
for (i = 0; i < MAX_INSTR_PER_BLOCK; i++) {
Instruction instr = ircolib::ReadAccess<u32>(imem, addr & IMEM_DSIZE);
addr += 4;
line.code[i] = instr;
if (fetchDelaySlot) {
i++;
break;
}
if (InstrEndsBlock(instr)) {
if (InstrHasDelaySlot(instr) && !fetchDelaySlot) {
fetchDelaySlot = true;
continue;
}
if (i == 0)
i = 1;
break;
}
}
line.cycles = i;
line.len = i;
cachedState.blocks[CACHE_GET_BLOCK(blockAddr)]->lines[CACHE_GET_LINE(blockAddr)] = new CachedLine(line);
return ExecuteCached();
}
void RSP::ExecuteCached() {
u16 addr = pc;
auto &blocks = cachedState.blocks;
if (!blocks[CACHE_GET_BLOCK(addr)]) {
blocks[CACHE_GET_BLOCK(addr)] = new CachedBlock<cachedState.MAX_LINES / 4>();
return CacheBlock(addr);
}
const auto line = blocks[CACHE_GET_BLOCK(addr)]->lines[CACHE_GET_LINE(addr)];
if (line) {
for (u32 i = 0; i < line->len; i++) {
prevDelaySlot = delaySlot;
delaySlot = false;
oldPC = pc & 0xFFC;
pc = nextPC & 0xFFC;
nextPC += 4;
Instruction instr = line->code[i];
Exec(instr);
}
return;
}
return CacheBlock(addr);
}
} // namespace n64
+10 -9
View File
@@ -5,6 +5,7 @@
#include <core/RDP.hpp>
#include <core/mmio/MI.hpp>
#include <Instruction.hpp>
#include <JITUtils.hpp>
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
@@ -145,10 +146,18 @@ struct RSP {
VPR l{}, h{};
} vcc, vco;
CachedState<4, 0xFFF> cachedState;
bool delaySlot = false, prevDelaySlot = false;
RSP();
void Reset();
void ExecuteCached();
void CacheBlock(u16 addr);
FORCE_INLINE void Step() {
prevDelaySlot = delaySlot;
delaySlot = false;
gpr[0] = 0;
const u32 instr = ircolib::ReadAccess<u32>(imem, pc & IMEM_DSIZE);
oldPC = pc & 0xFFC;
@@ -380,15 +389,7 @@ private:
FORCE_INLINE void branch(const u16 address, const bool cond) {
if (cond) {
nextPC = address & 0xFFC;
}
}
FORCE_INLINE void branch_likely(const u16 address, const bool cond) {
if (cond) {
nextPC = address & 0xFFC;
} else {
pc = nextPC & 0xFFC;
nextPC = pc + 4;
delaySlot = true;
}
}
};