aaaaaaaaa
This commit is contained in:
@@ -82,6 +82,12 @@ u32 Core::StepCPU() {
|
||||
void Core::StepRSP(const u32 cpuCycles) {
|
||||
MMIO &mmio = mem->mmio;
|
||||
|
||||
if (mmio.rsp.spStatus.halt) {
|
||||
regs.steps = 0;
|
||||
mmio.rsp.steps = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr u32 cpuRatio = 3, rspRatio = 2;
|
||||
|
||||
regs.steps += cpuCycles;
|
||||
@@ -113,6 +119,7 @@ void Core::Run(const float volumeL, const float volumeR) {
|
||||
const u32 taken = StepCPU();
|
||||
cycles += taken;
|
||||
frameCycles += taken;
|
||||
StepRSP(taken);
|
||||
Scheduler::GetInstance().Tick(taken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ void Scheduler::HandleEvents() {
|
||||
|
||||
while (ticks >= events.top().time) {
|
||||
switch (const auto type = events.top().type) {
|
||||
case RSP_STEP:
|
||||
n64::Core::GetInstance().StepRSP(1);
|
||||
break;
|
||||
case SI_DMA:
|
||||
si.DMA();
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <log.hpp>
|
||||
#include <queue>
|
||||
|
||||
enum EventType { NONE, RSP_STEP, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE };
|
||||
enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE };
|
||||
|
||||
struct Event {
|
||||
u64 time;
|
||||
|
||||
@@ -93,14 +93,6 @@ u32 Interpreter::Step() {
|
||||
|
||||
DecodeExecute(instr);
|
||||
|
||||
if (!mem.mmio.rsp.spStatus.halt) {
|
||||
rspSyncCount++;
|
||||
if (rspSyncCount >= 3)
|
||||
Scheduler::GetInstance().EnqueueRelative(0, RSP_STEP);
|
||||
}
|
||||
|
||||
Scheduler::GetInstance().HandleEvents();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -132,8 +124,10 @@ void CachedState::EvictLine(u64 addr) {
|
||||
u32 offset;
|
||||
u32 page = DivideAddr(addr, offset);
|
||||
|
||||
if (blocks[page])
|
||||
blocks[page] = nullptr;
|
||||
if (blocks[page]) {
|
||||
blocks[page]->lines[offset].reset();
|
||||
blocks[page].reset();
|
||||
}
|
||||
}
|
||||
|
||||
u32 Interpreter::ExecuteCached() {
|
||||
@@ -149,7 +143,6 @@ u32 Interpreter::ExecuteCached() {
|
||||
Instruction instr = line->code[i];
|
||||
DecodeExecute(instr);
|
||||
|
||||
Scheduler::GetInstance().HandleEvents();
|
||||
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
|
||||
if (IsBranchLikely(instr) && !regs.delaySlot)
|
||||
break;
|
||||
@@ -187,15 +180,6 @@ u32 Interpreter::ExecuteCached() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!mem.mmio.rsp.spStatus.halt) {
|
||||
for (int j = 1; j <= (int)std::floor((double)i / 3); j++) {
|
||||
Scheduler::GetInstance().EnqueueRelative(j * 3, RSP_STEP);
|
||||
}
|
||||
} else {
|
||||
regs.steps = 0;
|
||||
mem.mmio.rsp.steps = 0;
|
||||
}
|
||||
|
||||
cachedState.InsertLine(blockAddr, std::make_shared<CachedLine>(code, i, i));
|
||||
|
||||
return ExecuteCached();
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
namespace n64 {
|
||||
struct Core;
|
||||
|
||||
static constexpr u32 MAX_INSTRUCTION_PER_LINE = 128;
|
||||
static constexpr u32 MAX_LINES_PER_BLOCK = 1 << 12;
|
||||
static constexpr u32 MAX_INSTRUCTION_PER_LINE = MAX_LINES_PER_BLOCK >> 2;
|
||||
|
||||
struct CachedLine {
|
||||
std::array<Instruction, MAX_INSTRUCTION_PER_LINE> code = {};
|
||||
@@ -51,14 +51,15 @@ struct Interpreter final {
|
||||
cachedState.Reset();
|
||||
}
|
||||
|
||||
|
||||
CachedState cachedState;
|
||||
|
||||
private:
|
||||
friend struct Cop1;
|
||||
friend struct Mem;
|
||||
|
||||
void MaybeIdleSkip();
|
||||
|
||||
CachedState cachedState;
|
||||
|
||||
InstructionCache icache;
|
||||
DataCache dcache;
|
||||
Registers ®s;
|
||||
|
||||
@@ -19,6 +19,7 @@ template <>
|
||||
void RDP::WriteRDRAM<u8>(const size_t idx, const u8 v) {
|
||||
if (const size_t real = BYTE_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] {
|
||||
rdram[real] = v;
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +27,7 @@ template <>
|
||||
void RDP::WriteRDRAM<u16>(const size_t idx, const u16 v) {
|
||||
if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] {
|
||||
ircolib::WriteAccess<u16>(rdram, real, v);
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +35,7 @@ template <>
|
||||
void RDP::WriteRDRAM<u32>(const size_t idx, const u32 v) {
|
||||
if (idx < RDRAM_SIZE) [[likely]] {
|
||||
ircolib::WriteAccess<u32>(rdram, idx, v);
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +43,7 @@ template <>
|
||||
void RDP::WriteRDRAM<u64>(const size_t idx, const u64 v) {
|
||||
if (idx < RDRAM_SIZE) [[likely]] {
|
||||
ircolib::WriteAccess<u64>(rdram, idx, v);
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +125,6 @@ void RDP::Write(const u32 addr, const u32 val) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RDP::WriteStatus(const u32 val) {
|
||||
DPCStatusWrite temp{};
|
||||
temp.raw = val;
|
||||
@@ -197,8 +200,8 @@ FORCE_INLINE void logCommand(u8 cmd) {
|
||||
*/
|
||||
|
||||
void RDP::RunCommand() {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
ParallelRDP& parallel = n64::Core::GetInstance().parallel;
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
ParallelRDP ¶llel = n64::Core::GetInstance().parallel;
|
||||
if (dpc.status.freeze) {
|
||||
return;
|
||||
}
|
||||
@@ -285,8 +288,8 @@ void RDP::RunCommand() {
|
||||
}
|
||||
|
||||
void RDP::OnFullSync() {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
ParallelRDP& parallel = n64::Core::GetInstance().parallel;
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
ParallelRDP ¶llel = n64::Core::GetInstance().parallel;
|
||||
|
||||
parallel.OnFullSync();
|
||||
|
||||
|
||||
@@ -1311,6 +1311,7 @@ void Cop1::swc1(const Instruction instr) {
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
mem.Write<u32>(physical, FGR_T<u32>(regs.cop0.status, instr.ft()));
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1338,6 +1339,7 @@ void Cop1::sdc1(const Instruction instr) {
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
mem.Write(physical, FGR_T<u64>(regs.cop0.status, instr.ft()));
|
||||
Core::GetInstance().interpreter.cachedState.EvictLine(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,18 @@ static bool InstrEndsBlock(const Instruction instr) {
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case Instruction::COP0:
|
||||
switch (instr.cop_rs()) {
|
||||
case 0x10 ... 0x1F:
|
||||
switch (instr.cop_funct()) {
|
||||
case 0x18: // eret
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user