Couple RDP fixes and some other stuff i forgor 💀
This commit is contained in:
@@ -138,6 +138,7 @@ void Window::InitImgui(const n64::Core& core) {
|
|||||||
|
|
||||||
memoryEditor.ReadFn = readHandler;
|
memoryEditor.ReadFn = readHandler;
|
||||||
memoryEditor.WriteFn = writeHandler;
|
memoryEditor.WriteFn = writeHandler;
|
||||||
|
memoryEditor.Cols = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
@@ -194,8 +195,13 @@ void Window::Render(n64::Core& core) {
|
|||||||
windowTitle = shadowWindowTitle;
|
windowTitle = shadowWindowTitle;
|
||||||
}
|
}
|
||||||
static bool showSettings = false;
|
static bool showSettings = false;
|
||||||
|
static bool showMemEditor = false;
|
||||||
bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus());
|
bool showMainMenuBar = windowID == SDL_GetWindowID(SDL_GetMouseFocus());
|
||||||
|
if(showMemEditor) {
|
||||||
|
ImGui::PushFont(codeFont);
|
||||||
memoryEditor.DrawWindow("Memory viewer", &core, 0x80000000);
|
memoryEditor.DrawWindow("Memory viewer", &core, 0x80000000);
|
||||||
|
ImGui::PopFont();
|
||||||
|
}
|
||||||
if(showMainMenuBar) {
|
if(showMainMenuBar) {
|
||||||
ImGui::BeginMainMenuBar();
|
ImGui::BeginMainMenuBar();
|
||||||
if (ImGui::BeginMenu("File")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
@@ -214,6 +220,9 @@ void Window::Render(n64::Core& core) {
|
|||||||
if (ImGui::MenuItem("Dump IMEM")) {
|
if (ImGui::MenuItem("Dump IMEM")) {
|
||||||
core.mem.DumpIMEM();
|
core.mem.DumpIMEM();
|
||||||
}
|
}
|
||||||
|
if (ImGui::MenuItem("Dump DMEM")) {
|
||||||
|
core.mem.DumpDMEM();
|
||||||
|
}
|
||||||
if (ImGui::MenuItem("Exit")) {
|
if (ImGui::MenuItem("Exit")) {
|
||||||
core.done = true;
|
core.done = true;
|
||||||
}
|
}
|
||||||
@@ -241,6 +250,7 @@ void Window::Render(n64::Core& core) {
|
|||||||
if (ImGui::MenuItem("Settings")) {
|
if (ImGui::MenuItem("Settings")) {
|
||||||
showSettings = true;
|
showSettings = true;
|
||||||
}
|
}
|
||||||
|
ImGui::Checkbox("Show memory editor", &showMemEditor);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
|
|||||||
@@ -28,9 +28,7 @@ inline void CheckCompareInterrupt(MI& mi, Registers& regs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void HandleInterrupt(Registers& regs) {
|
inline void HandleInterrupt(Registers& regs) {
|
||||||
if(ShouldServiceInterrupt(regs)) {
|
|
||||||
FireException(regs, ExceptionCode::Interrupt, 0, regs.pc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Cpu::disassembly(u32 instr) {
|
inline void Cpu::disassembly(u32 instr) {
|
||||||
@@ -57,19 +55,21 @@ void Cpu::Step(Mem& mem) {
|
|||||||
regs.gpr[0] = 0;
|
regs.gpr[0] = 0;
|
||||||
|
|
||||||
CheckCompareInterrupt(mem.mmio.mi, regs);
|
CheckCompareInterrupt(mem.mmio.mi, regs);
|
||||||
HandleInterrupt(regs);
|
|
||||||
|
regs.prevDelaySlot = regs.delaySlot;
|
||||||
|
regs.delaySlot = false;
|
||||||
|
|
||||||
u32 instruction = mem.Read32(regs, regs.pc, regs.pc);
|
u32 instruction = mem.Read32(regs, regs.pc, regs.pc);
|
||||||
|
|
||||||
//disassembly(instruction);
|
if(ShouldServiceInterrupt(regs)) {
|
||||||
|
FireException(regs, ExceptionCode::Interrupt, 0, regs.pc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
regs.oldPC = regs.pc;
|
regs.oldPC = regs.pc;
|
||||||
regs.pc = regs.nextPC;
|
regs.pc = regs.nextPC;
|
||||||
regs.nextPC += 4;
|
regs.nextPC += 4;
|
||||||
|
|
||||||
Exec(mem, instruction);
|
Exec(mem, instruction);
|
||||||
|
|
||||||
regs.prevDelaySlot = regs.delaySlot;
|
|
||||||
regs.delaySlot = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return mmio.rdp.dram[BYTE_ADDRESS(paddr) & RDRAM_DSIZE];
|
return mmio.rdp.dram[BYTE_ADDRESS(paddr)];
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
||||||
@@ -116,7 +116,7 @@ u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr) & RDRAM_DSIZE);
|
return util::ReadAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr));
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
|
return util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
|
||||||
@@ -148,7 +148,7 @@ u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u32>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
|
return util::ReadAccess<u32>(mmio.rdp.dram.data(), paddr);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
@@ -180,7 +180,7 @@ u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u64>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
|
return util::ReadAccess<u64>(mmio.rdp.dram.data(), paddr);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
@@ -222,7 +222,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
mmio.rdp.dram[BYTE_ADDRESS(paddr) & RDRAM_DSIZE] = val;
|
mmio.rdp.dram[BYTE_ADDRESS(paddr)] = val;
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (8 * (3 - (paddr & 3)));
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
@@ -261,7 +261,7 @@ void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr) & RDRAM_DSIZE, val);
|
util::WriteAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr), val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (16 * !(paddr & 2));
|
val = val << (16 * !(paddr & 2));
|
||||||
@@ -297,7 +297,7 @@ void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u32>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rdp.dram.data(), paddr, val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
@@ -340,7 +340,7 @@ void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) {
|
|||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u64>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
|
util::WriteAccess<u64>(mmio.rdp.dram.data(), paddr, val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val >>= 32;
|
val >>= 32;
|
||||||
|
|||||||
@@ -62,6 +62,16 @@ struct Mem {
|
|||||||
free(temp);
|
free(temp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void DumpDMEM() const {
|
||||||
|
FILE *fp = fopen("dmem.dump", "wb");
|
||||||
|
u8 *temp = (u8*)calloc(DMEM_SIZE, 1);
|
||||||
|
memcpy(temp, mmio.rsp.dmem, DMEM_SIZE);
|
||||||
|
util::SwapBuffer32(DMEM_SIZE, temp);
|
||||||
|
fwrite(temp, 1, DMEM_SIZE, fp);
|
||||||
|
free(temp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
friend struct SI;
|
friend struct SI;
|
||||||
friend struct PI;
|
friend struct PI;
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ auto RDP::Read(u32 addr) const -> u32{
|
|||||||
case 0x04100000: return dpc.start;
|
case 0x04100000: return dpc.start;
|
||||||
case 0x04100004: return dpc.end;
|
case 0x04100004: return dpc.end;
|
||||||
case 0x04100008: return dpc.current;
|
case 0x04100008: return dpc.current;
|
||||||
case 0x0410000C: return dpc.status.raw;
|
case 0x0410000C:
|
||||||
|
return dpc.status.raw;
|
||||||
case 0x04100010: return dpc.clock;
|
case 0x04100010: return dpc.clock;
|
||||||
case 0x04100014: return dpc.status.cmdBusy;
|
case 0x04100014: return dpc.status.cmdBusy;
|
||||||
case 0x04100018: return dpc.status.pipeBusy;
|
case 0x04100018: return dpc.status.pipeBusy;
|
||||||
@@ -62,15 +63,12 @@ template void RDP::Write<true>(MI&, Registers&, RSP&, u32, u32);
|
|||||||
template void RDP::Write<false>(MI&, Registers&, RSP&, u32, u32);
|
template void RDP::Write<false>(MI&, Registers&, RSP&, u32, u32);
|
||||||
|
|
||||||
void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
|
void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
|
||||||
bool rdpUnfrozen = false;
|
|
||||||
|
|
||||||
DPCStatusWrite temp{};
|
DPCStatusWrite temp{};
|
||||||
temp.raw = val;
|
temp.raw = val;
|
||||||
|
|
||||||
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;
|
||||||
rdpUnfrozen = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(temp.setFreeze) {
|
if(temp.setFreeze) {
|
||||||
@@ -82,7 +80,7 @@ void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) {
|
|||||||
CLEAR_SET(dpc.status.pipeBusy, temp.clearPipe, false);
|
CLEAR_SET(dpc.status.pipeBusy, temp.clearPipe, false);
|
||||||
CLEAR_SET(dpc.status.tmemBusy, temp.clearTmem, false);
|
CLEAR_SET(dpc.status.tmemBusy, temp.clearTmem, false);
|
||||||
|
|
||||||
if(rdpUnfrozen) {
|
if(!dpc.status.freeze) {
|
||||||
RunCommand(mi, regs, rsp);
|
RunCommand(mi, regs, rsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,11 +126,12 @@ inline void logCommand(u8 cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
||||||
//if (dpc.status.freeze) {
|
if (dpc.status.freeze) {
|
||||||
// return;
|
return;
|
||||||
//}
|
}
|
||||||
dpc.status.pipeBusy = true;
|
dpc.status.pipeBusy = true;
|
||||||
dpc.status.startGclk = true;
|
dpc.status.startGclk = true;
|
||||||
|
if(dpc.end > dpc.current) {
|
||||||
dpc.status.freeze = true;
|
dpc.status.freeze = true;
|
||||||
|
|
||||||
static int remaining_cmds = 0;
|
static int remaining_cmds = 0;
|
||||||
@@ -144,6 +143,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
if (len <= 0) return;
|
if (len <= 0) return;
|
||||||
|
|
||||||
if (len + (remaining_cmds * 4) > 0xFFFFF) {
|
if (len + (remaining_cmds * 4) > 0xFFFFF) {
|
||||||
|
util::panic("Too many RDP commands\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +153,8 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(end > RDRAM_DSIZE || current > RDRAM_DSIZE) {
|
if (end > 0x7FFFFFF || current > 0x7FFFFFF) {
|
||||||
|
util::panic("Not running RDP commands past end of RDRAM\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < len; i += 4) {
|
for (int i = 0; i < len; i += 4) {
|
||||||
@@ -169,7 +170,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
|
|
||||||
while (buf_index < word_len) {
|
while (buf_index < word_len) {
|
||||||
u8 cmd = (cmd_buf[buf_index] >> 24) & 0x3F;
|
u8 cmd = (cmd_buf[buf_index] >> 24) & 0x3F;
|
||||||
// logCommand(cmd);
|
logCommand(cmd);
|
||||||
|
|
||||||
int cmd_len = cmd_lens[cmd];
|
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)) {
|
||||||
@@ -181,7 +182,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < remaining_cmds; i++) {
|
for (int i = 0; i < remaining_cmds; i++) {
|
||||||
cmd_buf[buf_index + i] = tmp[i];
|
cmd_buf[i] = tmp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_all = false;
|
processed_all = false;
|
||||||
@@ -205,9 +206,10 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
|
|
||||||
dpc.current = end;
|
dpc.current = end;
|
||||||
dpc.end = end;
|
dpc.end = end;
|
||||||
dpc.status.cbufReady = true;
|
|
||||||
dpc.status.freeze = false;
|
dpc.status.freeze = false;
|
||||||
}
|
}
|
||||||
|
dpc.status.cbufReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
void RDP::OnFullSync(MI& mi, Registers& regs) {
|
void RDP::OnFullSync(MI& mi, Registers& regs) {
|
||||||
ParallelRdpOnFullSync();
|
ParallelRdpOnFullSync();
|
||||||
|
|||||||
@@ -56,11 +56,9 @@ inline void logRSP(const RSP& rsp, const u32 instr) {
|
|||||||
for (int e = 0; e < 8; e++) {
|
for (int e = 0; e < 8; e++) {
|
||||||
util::print("{:04X}", rsp.acc.l.element[e]);
|
util::print("{:04X}", rsp.acc.l.element[e]);
|
||||||
}
|
}
|
||||||
util::print(" ");
|
|
||||||
|
|
||||||
util::print("{:04X} {:04X} {:02X}", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE());
|
util::print(" {:04X} {:04X} {:02X}\n", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE());
|
||||||
|
util::print("DMEM: {:02X}{:02X}\n", rsp.dmem[0x3c4], rsp.dmem[0x3c5]);
|
||||||
util::print("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::Step(Registers& regs, Mem& mem) {
|
void RSP::Step(Registers& regs, Mem& mem) {
|
||||||
@@ -69,9 +67,7 @@ void RSP::Step(Registers& regs, Mem& mem) {
|
|||||||
oldPC = pc & 0xFFC;
|
oldPC = pc & 0xFFC;
|
||||||
pc = nextPC & 0xFFC;
|
pc = nextPC & 0xFFC;
|
||||||
nextPC += 4;
|
nextPC += 4;
|
||||||
if(oldPC == 0x00E4 && gpr[1] == 0x18) {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
Exec(regs, mem, instr);
|
Exec(regs, mem, instr);
|
||||||
|
|
||||||
//logRSP(*this, instr);
|
//logRSP(*this, instr);
|
||||||
@@ -87,7 +83,11 @@ auto RSP::Read(u32 addr) -> u32{
|
|||||||
case 0x04040010: return spStatus.raw;
|
case 0x04040010: return spStatus.raw;
|
||||||
case 0x04040014: return spStatus.dmaFull;
|
case 0x04040014: return spStatus.dmaFull;
|
||||||
case 0x04040018: return 0;
|
case 0x04040018: return 0;
|
||||||
case 0x0404001C: return AcquireSemaphore();
|
case 0x0404001C:
|
||||||
|
if constexpr (crashOnUnimplemented) {
|
||||||
|
return semaphore;
|
||||||
|
}
|
||||||
|
return AcquireSemaphore();
|
||||||
case 0x04080000: return pc & 0xFFC;
|
case 0x04080000: return pc & 0xFFC;
|
||||||
default:
|
default:
|
||||||
if constexpr (crashOnUnimplemented) {
|
if constexpr (crashOnUnimplemented) {
|
||||||
|
|||||||
@@ -390,13 +390,15 @@ struct RSP {
|
|||||||
|
|
||||||
int skip = i == len.count ? 0 : len.skip;
|
int skip = i == len.count ? 0 : len.skip;
|
||||||
|
|
||||||
dram_address += (length + skip) & 0xFFFFF8;
|
dram_address += (length + skip);
|
||||||
|
dram_address &= 0xFFFFF8;
|
||||||
mem_address += length;
|
mem_address += length;
|
||||||
|
mem_address &= 0xFF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsp.lastSuccessfulSPAddr.address = mem_address & 0xFF8;
|
rsp.lastSuccessfulSPAddr.address = mem_address;
|
||||||
rsp.lastSuccessfulSPAddr.bank = bank;
|
rsp.lastSuccessfulSPAddr.bank = bank;
|
||||||
rsp.lastSuccessfulDRAMAddr.address = dram_address & 0xFFFFF8;
|
rsp.lastSuccessfulDRAMAddr.address = dram_address;
|
||||||
rsp.spDMALen.raw = 0xFF8 | (rsp.spDMALen.skip << 20);
|
rsp.spDMALen.raw = 0xFF8 | (rsp.spDMALen.skip << 20);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ void Registers::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Registers::SetPC(s64 val) {
|
void Registers::SetPC(s64 val) {
|
||||||
|
oldPC = pc;
|
||||||
pc = val;
|
pc = val;
|
||||||
nextPC = pc + 4;
|
nextPC = pc + 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ u64 getVPN(u64 addr, u64 pageMask) {
|
|||||||
TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match) {
|
TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match) {
|
||||||
for(int i = 0; i < 32; i++) {
|
for(int i = 0; i < 32; i++) {
|
||||||
TLBEntry *entry = ®s.cop0.tlb[i];
|
TLBEntry *entry = ®s.cop0.tlb[i];
|
||||||
|
if(entry->initialized) {
|
||||||
u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw);
|
u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw);
|
||||||
u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw);
|
u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw);
|
||||||
|
|
||||||
@@ -186,6 +187,7 @@ TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match) {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ union PageMask {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TLBEntry {
|
struct TLBEntry {
|
||||||
|
bool initialized;
|
||||||
union {
|
union {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ void Cop0::tlbwi(Registers& regs) {
|
|||||||
tlb[Index].pageMask.raw = page_mask.raw;
|
tlb[Index].pageMask.raw = page_mask.raw;
|
||||||
|
|
||||||
tlb[Index].global = entryLo0.g && entryLo1.g;
|
tlb[Index].global = entryLo0.g && entryLo1.g;
|
||||||
|
tlb[Index].initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cop0::tlbp(Registers& regs) {
|
void Cop0::tlbp(Registers& regs) {
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ inline auto ReadFileBinary(const std::string& path, u32** buf) {
|
|||||||
std::ifstream file(path, std::ios::binary);
|
std::ifstream file(path, std::ios::binary);
|
||||||
file.unsetf(std::ios::skipws);
|
file.unsetf(std::ios::skipws);
|
||||||
if(!file.is_open()) {
|
if(!file.is_open()) {
|
||||||
panic("Could not load file!\n");
|
panic("Could not load file '{}'!\n", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
file.seekg(0, std::ios::end);
|
file.seekg(0, std::ios::end);
|
||||||
|
|||||||
Reference in New Issue
Block a user