SSV and SLV switched, fix shift in SBV, implement "Dump RDRAM" and "Dump IMEM" buttons in GUI

This commit is contained in:
CocoSimone
2022-10-06 02:17:36 +02:00
parent 89daa969eb
commit 73d65c2246
6 changed files with 101 additions and 49 deletions

View File

@@ -13,14 +13,9 @@ void App::Run() {
while (SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
switch(event.type) {
case SDL_QUIT: {
case SDL_QUIT:
core.done = true;
FILE *fp = fopen("rdram.dump", "wb");
u8 *temp = core.mem.GetRDRAM();
util::SwapBuffer32(RDRAM_SIZE, temp);
fwrite(temp, 1, RDRAM_SIZE, fp);
fclose(fp);
} break;
break;
case SDL_WINDOWEVENT:
core.done = window.gotClosed(event);
break;

View File

@@ -182,6 +182,20 @@ void Window::Render(n64::Core& core) {
NFD_FreePath(outpath);
}
}
if (ImGui::MenuItem("Dump RDRAM")) {
FILE *fp = fopen("rdram.dump", "wb");
u8 *temp = core.mem.GetRDRAM();
util::SwapBuffer32(RDRAM_SIZE, temp);
fwrite(temp, 1, RDRAM_SIZE, fp);
fclose(fp);
}
if (ImGui::MenuItem("Dump IMEM")) {
FILE *fp = fopen("imem.dump", "wb");
u8 *temp = core.mem.mmio.rsp.imem;
util::SwapBuffer32(IMEM_SIZE, temp);
fwrite(temp, 1, IMEM_SIZE, fp);
fclose(fp);
}
if (ImGui::MenuItem("Exit")) {
core.done = true;
}

View File

@@ -80,7 +80,7 @@ u8 Mem::Read8(n64::Registers &regs, u64 vaddr, s64 pc) {
case 0x00000000 ... 0x007FFFFF:
return mmio.rdp.dram[BYTE_ADDRESS(paddr) & RDRAM_DSIZE];
case 0x04000000 ... 0x0403FFFF:
if(paddr & 0x1000)
if((paddr >> 12) & 1)
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
else
return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE];
@@ -113,7 +113,7 @@ u16 Mem::Read16(n64::Registers &regs, u64 vaddr, s64 pc) {
case 0x00000000 ... 0x007FFFFF:
return util::ReadAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr) & RDRAM_DSIZE);
case 0x04000000 ... 0x0403FFFF:
if(paddr & 0x1000)
if((paddr >> 12) & 1)
return util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
else
return util::ReadAccess<u16>(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE);
@@ -146,7 +146,7 @@ u32 Mem::Read32(n64::Registers &regs, u64 vaddr, s64 pc) {
case 0x00000000 ... 0x007FFFFF:
return util::ReadAccess<u32>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
case 0x04000000 ... 0x0403FFFF:
if(paddr & 0x1000)
if((paddr >> 12) & 1)
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
else
return util::ReadAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
@@ -178,7 +178,7 @@ u64 Mem::Read64(n64::Registers &regs, u64 vaddr, s64 pc) {
case 0x00000000 ... 0x007FFFFF:
return util::ReadAccess<u64>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE);
case 0x04000000 ... 0x0403FFFF:
if(paddr & 0x1000)
if((paddr >> 12) & 1)
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
else
return util::ReadAccess<u64>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
@@ -222,7 +222,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
case 0x04000000 ... 0x0403FFFF:
val = val << (8 * (3 - (paddr & 3)));
paddr = (paddr & DMEM_DSIZE) & ~3;
if(paddr & 0x1000)
if((paddr >> 12) & 1)
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
else
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
@@ -258,7 +258,7 @@ void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) {
case 0x04000000 ... 0x0403FFFF:
val = val << (16 * !(paddr & 2));
paddr &= ~3;
if(paddr & 0x1000)
if((paddr >> 12) & 1)
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
else
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
@@ -292,7 +292,7 @@ void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) {
util::WriteAccess<u32>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
break;
case 0x04000000 ... 0x0403FFFF:
if(paddr & 0x1000)
if((paddr >> 12) & 1)
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
else
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
@@ -336,7 +336,7 @@ void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) {
break;
case 0x04000000 ... 0x0403FFFF:
val >>= 32;
if(paddr & 0x1000)
if((paddr >> 12) & 1)
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
else
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);

View File

@@ -218,6 +218,7 @@ struct RSP {
}
inline u64 ReadDword(u32 addr, bool i) {
addr &= 0xfff;
if (i) {
return GET_RSP_DWORD(addr, imem);
} else {
@@ -226,6 +227,7 @@ struct RSP {
}
inline void WriteDword(u32 addr, u64 val, bool i) {
addr &= 0xfff;
if (i) {
SET_RSP_DWORD(addr, imem, val);
} else {
@@ -234,6 +236,7 @@ struct RSP {
}
inline u32 ReadWord(u32 addr, bool i) {
addr &= 0xfff;
if (i) {
return GET_RSP_WORD(addr, imem);
} else {
@@ -242,6 +245,7 @@ struct RSP {
}
inline void WriteWord(u32 addr, u32 val, bool i) {
addr &= 0xfff;
if (i) {
SET_RSP_WORD(addr, imem, val);
} else {
@@ -250,6 +254,7 @@ struct RSP {
}
inline u16 ReadHalf(u32 addr, bool i) {
addr &= 0xfff;
if (i) {
return GET_RSP_HALF(addr, imem);
} else {
@@ -258,6 +263,7 @@ struct RSP {
}
inline void WriteHalf(u32 addr, u16 val, bool i) {
addr &= 0xfff;
if (i) {
SET_RSP_HALF(addr, imem, val);
} else {
@@ -266,6 +272,7 @@ struct RSP {
}
inline u8 ReadByte(u32 addr, bool i) {
addr &= 0xfff;
if (i) {
return RSP_BYTE(addr, imem);
} else {
@@ -274,6 +281,7 @@ struct RSP {
}
inline void WriteByte(u32 addr, u8 val, bool i) {
addr &= 0xfff;
if (i) {
RSP_BYTE(addr, imem) = val;
} else {
@@ -282,34 +290,42 @@ struct RSP {
}
inline u64 ReadDword(u32 addr) {
addr &= 0xfff;
return GET_RSP_DWORD(addr, dmem);
}
inline void WriteDword(u32 addr, u64 val) {
addr &= 0xfff;
SET_RSP_DWORD(addr, dmem, val);
}
inline u32 ReadWord(u32 addr) {
addr &= 0xfff;
return GET_RSP_WORD(addr, dmem);
}
inline void WriteWord(u32 addr, u32 val) {
addr &= 0xfff;
SET_RSP_WORD(addr, dmem, val);
}
inline u16 ReadHalf(u32 addr) {
addr &= 0xfff;
return GET_RSP_HALF(addr, dmem);
}
inline void WriteHalf(u32 addr, u16 val) {
addr &= 0xfff;
SET_RSP_HALF(addr, dmem, val);
}
inline u8 ReadByte(u32 addr) {
addr &= 0xfff;
return RSP_BYTE(addr, dmem);
}
inline void WriteByte(u32 addr, u8 val) {
addr &= 0xfff;
RSP_BYTE(addr, dmem) = val;
}
@@ -411,7 +427,8 @@ struct RSP {
void vsub(u32 instr);
void vsubc(u32 instr);
void vxor(u32 instr);
void vxnor(u32 instr);
void vnxor(u32 instr);
void vor(u32 instr);
void vnor(u32 instr);
void vzero(u32 instr);
void mfc0(RDP& rdp, u32 instr);

View File

@@ -77,8 +77,8 @@ inline void swc2(RSP& rsp, u32 instr) {
//util::print("swc2 {:02X}\n", mask);
switch(mask) {
case 0x00: rsp.sbv(instr); break;
case 0x01: rsp.slv(instr); break;
case 0x02: rsp.ssv(instr); break;
case 0x01: rsp.ssv(instr); break;
case 0x02: rsp.slv(instr); break;
case 0x03: rsp.sdv(instr); break;
case 0x04: rsp.sqv(instr); break;
case 0x06: rsp.spv(instr); break;
@@ -100,8 +100,10 @@ inline void cop2(RSP& rsp, u32 instr) {
case 0x02: rsp.cfc2(instr); break;
case 0x04: rsp.mtc2(instr); break;
case 0x06: rsp.ctc2(instr); break;
case 0x10: case 0x1C: case 0x1E:
case 0x1F: case 0x14: break; //rsp.vzero(instr); break;
case 0x10: case 0x14:
case 0x1C: case 0x1E: case 0x1F:
util::print("Invalid COP2 SUB {:05b} at PC: {:016X}\n", mask_sub, rsp.oldPC);
break;
default: util::panic("Unhandled RSP COP2 sub ({:05b})\n", mask_sub);
}
break;
@@ -130,9 +132,10 @@ inline void cop2(RSP& rsp, u32 instr) {
case 0x27: rsp.vmrg(instr); break;
case 0x28: rsp.vand(instr); break;
case 0x29: rsp.vnand(instr); break;
case 0x2A: rsp.vnor(instr); break;
case 0x2A: rsp.vor(instr); break;
case 0x2B: rsp.vnor(instr); break;
case 0x2C: rsp.vxor(instr); break;
case 0x2D: rsp.vxnor(instr); break;
case 0x2D: rsp.vnxor(instr); break;
case 0x31: rsp.vrcpl(instr); break;
case 0x35: rsp.vrsql(instr); break;
case 0x32: case 0x36:
@@ -141,6 +144,8 @@ inline void cop2(RSP& rsp, u32 instr) {
case 0x30: rsp.vrcp(instr); break;
case 0x33: rsp.vmov(instr); break;
case 0x34: rsp.vrsq(instr); break;
case 0x37: break;
case 0x3F: break;
default: util::panic("Unhandled RSP COP2 ({:06b})\n", mask);
}
}

View File

@@ -97,11 +97,23 @@ inline VPR GetVTE(VPR vt, u8 e) {
VPR vte{};
switch(e & 0xf) {
case 0 ... 1: return vt;
case 2 ... 3:
vte = Broadcast(vt, e - 2, e - 2, e, e, e + 2, e + 2, e + 4, e + 4);
case 2:
vte = Broadcast(vt, 0, 0, 2, 2, 4, 4, 6, 6);
break;
case 4 ... 7:
vte = Broadcast(vt, e - 4, e - 4, e - 4, e - 4, e, e, e, e);
case 3:
vte = Broadcast(vt, 1, 1, 3, 3, 5, 5, 7, 7);
break;
case 4:
vte = Broadcast(vt, 0, 0, 0, 0, 4, 4, 4, 4);
break;
case 5:
vte = Broadcast(vt, 1, 1, 1, 1, 5, 5, 5, 5);
break;
case 6:
vte = Broadcast(vt, 2, 2, 2, 2, 6, 6, 6, 6);
break;
case 7:
vte = Broadcast(vt, 3, 3, 3, 3, 7, 7, 7, 7);
break;
case 8 ... 15: {
int index = ELEMENT_INDEX(e - 8);
@@ -289,7 +301,7 @@ void RSP::ldv(u32 instr) {
}
void RSP::lsv(u32 instr) {
int e = E1(instr);
u8 e = E1(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1);
u16 val = ReadHalf(addr);
vpr[VT(instr)].byte[BYTE_INDEX(e)] = val >> 8;
@@ -404,7 +416,7 @@ void RSP::spv(u32 instr) {
void RSP::sbv(u32 instr) {
int e = E1(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0);
WriteByte(addr, vpr[VT(instr)].byte[BYTE_INDEX(e & 0xF)]);
}
@@ -583,7 +595,7 @@ void RSP::vaddc(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
for(int i = 0; i < 8; i++) {
s32 result = vs.selement[i] + vte.selement[i];
u32 result = vs.element[i] + vte.element[i];
acc.l.element[i] = result;
vd.element[i] = result;
vco.l.element[i] = (result >> 16) & 1 ? 0xffff : 0;
@@ -663,17 +675,15 @@ void RSP::vcl(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], e);
for(int i = 0; i < 8; i++) {
s16 vsElem = vs.selement[i];
s16 vteElem = vte.selement[i];
u16 vsElem = vs.element[i];
u16 vteElem = vte.element[i];
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
if(vco.l.element[i]) {
if(vco.h.element[i]) {
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
} else {
if(!vco.h.element[i]) {
u16 clampSum = vsElem + vteElem;
bool overflow = (vsElem + vteElem) != clampSum;
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
if(vce.element[i]) {
vcc.l.element[i] = !clampSum || !overflow ? 0xffff : 0;
} else {
@@ -681,9 +691,8 @@ void RSP::vcl(u32 instr) {
}
}
} else {
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
if(!vco.h.element[i]) {
vcc.h.element[i] = s32(vsElem) - s32(vteElem) >= 0 ? 0xffff : 0;
vcc.h.element[i] = (s32(vsElem) - s32(vteElem) >= 0) ? 0xffff : 0;
}
}
@@ -699,7 +708,7 @@ void RSP::vmov(u32 instr) {
VPR& vd = vpr[VD(instr)];
VPR vte = GetVTE(vpr[VT(instr)], e);
u32 se;
/*u8 se;
switch (e) {
case 0 ... 1:
@@ -716,11 +725,11 @@ void RSP::vmov(u32 instr) {
break;
default:
util::panic("VMOV: This should be unreachable!\n");
}
}*/
u8 de = VS(instr) & 7;
vd.element[ELEMENT_INDEX(de)] = vte.element[ELEMENT_INDEX(se)];
vd.element[ELEMENT_INDEX(de)] = vte.element[ELEMENT_INDEX(de)];
for(int i = 0; i < 8; i++) {
acc.l.element[i] = vte.element[i];
}
@@ -950,7 +959,7 @@ void RSP::vge(u32 instr) {
for(int i = 0; i < 8; i++) {
bool eql = vs.element[i] == vte.element[i];
bool neg = !(vco.h.element[i] & vco.l.element[i]) & eql;
bool neg = !(vco.h.element[i] && vco.l.element[i]) && eql;
vcc.l.element[i] = (neg || (vs.element[i] > vte.element[i])) ? 0xffff : 0;
acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i];
vd.element[i] = acc.l.element[i];
@@ -966,8 +975,8 @@ void RSP::vlt(u32 instr) {
for(int i = 0; i < 8; i++) {
bool eql = vs.element[i] == vte.element[i];
bool neg = vco.h.element[i] & vco.l.element[i] & eql;
vcc.l.element[i] = (neg || (vs.element[i] < vte.element[i])) ? 0xffff : 0;
bool neg = vco.h.element[i] && vco.l.element[i] && eql;
vcc.l.element[i] = (neg || (vs.selement[i] < vte.selement[i])) ? 0xffff : 0;
acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i];
vd.element[i] = acc.l.element[i];
vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0;
@@ -1105,11 +1114,11 @@ void RSP::vrsql(u32 instr) {
}
void RSP::vrcph(u32 instr) {
int e = E2(instr);
int de = DE(instr);
int e = E2(instr) & 7;
int de = DE(instr) & 7;
VPR& vd = vpr[VD(instr)];
VPR& vt = vpr[VT(instr)];
VPR vte = GetVTE(vpr[VT(instr)], e);
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
for(int i = 0; i < 8; i++) {
acc.l.element[i] = vte.element[i];
@@ -1169,9 +1178,9 @@ void RSP::vsub(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], e);
for(int i = 0; i < 8; i++) {
u32 result = vs.element[i] - vte.element[i] - vco.l.element[i];
s32 result = vs.selement[i] - vte.selement[i] - (vco.l.element[i] != 0);
acc.l.element[i] = result;
vd.element[i] = clamp_signed(s32(result) & 0x1FFFF);
vd.element[i] = clamp_signed(result);
vco.l.element[i] = 0;
vco.h.element[i] = 0;
@@ -1202,7 +1211,7 @@ void RSP::vxor(u32 instr) {
}
}
void RSP::vxnor(u32 instr) {
void RSP::vnxor(u32 instr) {
int e = E2(instr);
VPR& vs = vpr[VS(instr)];
VPR& vd = vpr[VD(instr)];
@@ -1250,6 +1259,18 @@ void RSP::vnor(u32 instr) {
}
}
void RSP::vor(u32 instr) {
int e = E2(instr);
VPR& vs = vpr[VS(instr)];
VPR& vd = vpr[VD(instr)];
VPR vte = GetVTE(vpr[VT(instr)], e);
for(int i = 0; i < 8; i++) {
acc.l.element[i] = vte.element[i] | vs.element[i];
vd.element[i] = acc.l.element[i];
}
}
void RSP::vzero(u32 instr) {
VPR& vs = vpr[VS(instr)];
VPR& vd = vpr[VD(instr)];