asdjkfhaskdjdf
This commit is contained in:
+2
-13
@@ -65,11 +65,8 @@ void Core::LoadROM(const std::string &rom_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 Core::StepCPU() {
|
u32 Core::StepCPU() {
|
||||||
if (cpuType == Interpreted) {
|
if (cpuType == Interpreted)
|
||||||
auto taken = interpreter.Step() + regs.PopStalledCycles();
|
return interpreter.Step() + regs.PopStalledCycles();
|
||||||
StepRSP(taken);
|
|
||||||
return taken;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpuType == CachedInterpreter)
|
if (cpuType == CachedInterpreter)
|
||||||
return interpreter.ExecuteCached() + regs.PopStalledCycles();
|
return interpreter.ExecuteCached() + regs.PopStalledCycles();
|
||||||
@@ -85,12 +82,6 @@ u32 Core::StepCPU() {
|
|||||||
void Core::StepRSP(const u32 cpuCycles) {
|
void Core::StepRSP(const u32 cpuCycles) {
|
||||||
MMIO &mmio = mem->mmio;
|
MMIO &mmio = mem->mmio;
|
||||||
|
|
||||||
if (mmio.rsp.spStatus.halt) {
|
|
||||||
regs.steps = 0;
|
|
||||||
mmio.rsp.steps = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr u32 cpuRatio = 3, rspRatio = 2;
|
static constexpr u32 cpuRatio = 3, rspRatio = 2;
|
||||||
|
|
||||||
regs.steps += cpuCycles;
|
regs.steps += cpuCycles;
|
||||||
@@ -119,8 +110,6 @@ void Core::Run(const float volumeL, const float volumeR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int cycles = 0; cycles < mem->mmio.vi.cyclesPerHalfline;) {
|
for (int cycles = 0; cycles < mem->mmio.vi.cyclesPerHalfline;) {
|
||||||
Scheduler::GetInstance().HandleEvents();
|
|
||||||
|
|
||||||
const u32 taken = StepCPU();
|
const u32 taken = StepCPU();
|
||||||
cycles += taken;
|
cycles += taken;
|
||||||
frameCycles += taken;
|
frameCycles += taken;
|
||||||
|
|||||||
@@ -27,13 +27,9 @@ u64 Scheduler::Remove(const EventType eventType) const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::SkipToNext() {
|
void Scheduler::SkipToNext() { ticks = events.top().time; }
|
||||||
ticks = events.top().time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scheduler::Tick(const u64 t) {
|
void Scheduler::Tick(const u64 t) { ticks += t; }
|
||||||
ticks += t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scheduler::HandleEvents() {
|
void Scheduler::HandleEvents() {
|
||||||
n64::Mem &mem = n64::Core::GetMem();
|
n64::Mem &mem = n64::Core::GetMem();
|
||||||
@@ -43,6 +39,9 @@ void Scheduler::HandleEvents() {
|
|||||||
|
|
||||||
while (ticks >= events.top().time) {
|
while (ticks >= events.top().time) {
|
||||||
switch (const auto type = events.top().type) {
|
switch (const auto type = events.top().type) {
|
||||||
|
case RSP_STEP:
|
||||||
|
n64::Core::GetInstance().StepRSP(1);
|
||||||
|
break;
|
||||||
case SI_DMA:
|
case SI_DMA:
|
||||||
si.DMA();
|
si.DMA();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE };
|
enum EventType { NONE, RSP_STEP, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE };
|
||||||
|
|
||||||
struct Event {
|
struct Event {
|
||||||
u64 time;
|
u64 time;
|
||||||
|
|||||||
@@ -52,18 +52,6 @@ bool Interpreter::MaybeAdvance() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.push_to_stack_trace(regs.pc);
|
|
||||||
if ((u32)regs.pc == 0x4) {
|
|
||||||
auto ®s = Core::GetRegs();
|
|
||||||
std::sort(regs.stack_trace.begin(), regs.stack_trace.end());
|
|
||||||
|
|
||||||
std::println("Stack trace:");
|
|
||||||
for (int i = 0; i < regs.stack_trace.size(); i++) {
|
|
||||||
std::println(" [{:016X}]", regs.stack_trace[i]);
|
|
||||||
}
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
regs.oldPC = regs.pc;
|
regs.oldPC = regs.pc;
|
||||||
regs.pc = regs.nextPC;
|
regs.pc = regs.nextPC;
|
||||||
regs.nextPC += 4;
|
regs.nextPC += 4;
|
||||||
@@ -105,6 +93,14 @@ u32 Interpreter::Step() {
|
|||||||
|
|
||||||
DecodeExecute(instr);
|
DecodeExecute(instr);
|
||||||
|
|
||||||
|
if (!mem.mmio.rsp.spStatus.halt) {
|
||||||
|
rspSyncCount++;
|
||||||
|
if (rspSyncCount >= 3)
|
||||||
|
Scheduler::GetInstance().EnqueueRelative(0, RSP_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheduler::GetInstance().HandleEvents();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +138,7 @@ void CachedState::EvictLine(u64 addr) {
|
|||||||
|
|
||||||
u32 Interpreter::ExecuteCached() {
|
u32 Interpreter::ExecuteCached() {
|
||||||
auto addr = regs.pc;
|
auto addr = regs.pc;
|
||||||
auto block_addr = addr;
|
auto blockAddr = addr;
|
||||||
auto line = cachedState.GetLine(addr);
|
auto line = cachedState.GetLine(addr);
|
||||||
|
|
||||||
if (line) {
|
if (line) {
|
||||||
@@ -153,8 +149,7 @@ u32 Interpreter::ExecuteCached() {
|
|||||||
Instruction instr = line->code[i];
|
Instruction instr = line->code[i];
|
||||||
DecodeExecute(instr);
|
DecodeExecute(instr);
|
||||||
|
|
||||||
Core::GetInstance().StepRSP(1);
|
Scheduler::GetInstance().HandleEvents();
|
||||||
|
|
||||||
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
|
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
|
||||||
if (IsBranchLikely(instr) && !regs.delaySlot)
|
if (IsBranchLikely(instr) && !regs.delaySlot)
|
||||||
break;
|
break;
|
||||||
@@ -192,7 +187,16 @@ u32 Interpreter::ExecuteCached() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedState.InsertLine(block_addr, std::make_shared<CachedLine>(code, i, i));
|
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();
|
return ExecuteCached();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ struct Interpreter final {
|
|||||||
Registers ®s;
|
Registers ®s;
|
||||||
Mem &mem;
|
Mem &mem;
|
||||||
u64 cop2Latch{};
|
u64 cop2Latch{};
|
||||||
|
u32 rspSyncCount = 0;
|
||||||
|
|
||||||
bool Fetch(Instruction &, u64);
|
bool Fetch(Instruction &, u64);
|
||||||
void CacheTypeData(u8, u64, u32, u32);
|
void CacheTypeData(u8, u64, u32, u32);
|
||||||
|
|||||||
@@ -85,10 +85,7 @@ auto RSP::Read(const u32 addr) -> u32 {
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
auto ®s = Core::GetRegs();
|
auto ®s = Core::GetRegs();
|
||||||
std::println("Stack trace:");
|
|
||||||
for (int i = 0; i < regs.stack_trace.size(); i++) {
|
|
||||||
std::println(" [{:016X}]", regs.stack_trace[i]);
|
|
||||||
}
|
|
||||||
panic("Unimplemented SP register read {:08X} (cpu pc: 0x{:016X}, rsp pc: 0x{:04X}, ra: 0x{:016X})", addr,
|
panic("Unimplemented SP register read {:08X} (cpu pc: 0x{:016X}, rsp pc: 0x{:04X}, ra: 0x{:016X})", addr,
|
||||||
(u64)regs.oldPC, pc & 0xffc, (u64)regs.gpr[31]);
|
(u64)regs.oldPC, pc & 0xffc, (u64)regs.gpr[31]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ namespace n64 {
|
|||||||
#ifdef KAIZEN_JIT_ENABLED
|
#ifdef KAIZEN_JIT_ENABLED
|
||||||
Registers::Registers(JIT &jit) : jit(jit) { Reset(); }
|
Registers::Registers(JIT &jit) : jit(jit) { Reset(); }
|
||||||
#else
|
#else
|
||||||
Registers::Registers() {
|
Registers::Registers() { Reset(); }
|
||||||
stack_trace.resize(0x10000000);
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Registers::Reset() {
|
void Registers::Reset() {
|
||||||
@@ -17,7 +14,6 @@ void Registers::Reset() {
|
|||||||
lo = 0;
|
lo = 0;
|
||||||
delaySlot = false;
|
delaySlot = false;
|
||||||
prevDelaySlot = false;
|
prevDelaySlot = false;
|
||||||
std::fill(stack_trace.begin(), stack_trace.end(), 0);
|
|
||||||
gpr.fill(0);
|
gpr.fill(0);
|
||||||
regIsConstant = 1; // first bit is true indicating $zero is constant which yes it is always
|
regIsConstant = 1; // first bit is true indicating $zero is constant which yes it is always
|
||||||
|
|
||||||
|
|||||||
@@ -48,14 +48,6 @@ struct Registers {
|
|||||||
Cop0 cop0;
|
Cop0 cop0;
|
||||||
Cop1 cop1;
|
Cop1 cop1;
|
||||||
|
|
||||||
std::vector<u64> stack_trace;
|
|
||||||
int stack_count = 0;
|
|
||||||
|
|
||||||
void push_to_stack_trace(s64 val) {
|
|
||||||
stack_trace[stack_count++] = val;
|
|
||||||
stack_count %= stack_trace.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CpuStall(u32 cycles) { extraCycles += cycles; }
|
void CpuStall(u32 cycles) { extraCycles += cycles; }
|
||||||
|
|
||||||
u32 PopStalledCycles() {
|
u32 PopStalledCycles() {
|
||||||
|
|||||||
Reference in New Issue
Block a user