SSV and SLV switched, fix shift in SBV, implement "Dump RDRAM" and "Dump IMEM" buttons in GUI
This commit is contained in:
@@ -13,14 +13,9 @@ void App::Run() {
|
|||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case SDL_QUIT: {
|
case SDL_QUIT:
|
||||||
core.done = true;
|
core.done = true;
|
||||||
FILE *fp = fopen("rdram.dump", "wb");
|
break;
|
||||||
u8 *temp = core.mem.GetRDRAM();
|
|
||||||
util::SwapBuffer32(RDRAM_SIZE, temp);
|
|
||||||
fwrite(temp, 1, RDRAM_SIZE, fp);
|
|
||||||
fclose(fp);
|
|
||||||
} break;
|
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
core.done = window.gotClosed(event);
|
core.done = window.gotClosed(event);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -182,6 +182,20 @@ void Window::Render(n64::Core& core) {
|
|||||||
NFD_FreePath(outpath);
|
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")) {
|
if (ImGui::MenuItem("Exit")) {
|
||||||
core.done = true;
|
core.done = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return mmio.rdp.dram[BYTE_ADDRESS(paddr) & RDRAM_DSIZE];
|
return mmio.rdp.dram[BYTE_ADDRESS(paddr) & RDRAM_DSIZE];
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
||||||
else
|
else
|
||||||
return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE];
|
return mmio.rsp.dmem[BYTE_ADDRESS(paddr) & DMEM_DSIZE];
|
||||||
@@ -113,7 +113,7 @@ u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
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) & RDRAM_DSIZE);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
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);
|
||||||
else
|
else
|
||||||
return util::ReadAccess<u16>(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE);
|
return util::ReadAccess<u16>(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE);
|
||||||
@@ -146,7 +146,7 @@ u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
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 & RDRAM_DSIZE);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
else
|
else
|
||||||
return util::ReadAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
|
return util::ReadAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
|
||||||
@@ -178,7 +178,7 @@ u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
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 & RDRAM_DSIZE);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
else
|
else
|
||||||
return util::ReadAccess<u64>(mmio.rsp.dmem, paddr & DMEM_DSIZE);
|
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:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (8 * (3 - (paddr & 3)));
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
paddr = (paddr & DMEM_DSIZE) & ~3;
|
paddr = (paddr & DMEM_DSIZE) & ~3;
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
||||||
else
|
else
|
||||||
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
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:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (16 * !(paddr & 2));
|
val = val << (16 * !(paddr & 2));
|
||||||
paddr &= ~3;
|
paddr &= ~3;
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
||||||
else
|
else
|
||||||
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
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);
|
util::WriteAccess<u32>(mmio.rdp.dram.data(), paddr & RDRAM_DSIZE, val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
||||||
else
|
else
|
||||||
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
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;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val >>= 32;
|
val >>= 32;
|
||||||
if(paddr & 0x1000)
|
if((paddr >> 12) & 1)
|
||||||
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE, val);
|
||||||
else
|
else
|
||||||
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
util::WriteAccess<u32>(mmio.rsp.dmem, paddr & DMEM_DSIZE, val);
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline u64 ReadDword(u32 addr, bool i) {
|
inline u64 ReadDword(u32 addr, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
return GET_RSP_DWORD(addr, imem);
|
return GET_RSP_DWORD(addr, imem);
|
||||||
} else {
|
} else {
|
||||||
@@ -226,6 +227,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteDword(u32 addr, u64 val, bool i) {
|
inline void WriteDword(u32 addr, u64 val, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
SET_RSP_DWORD(addr, imem, val);
|
SET_RSP_DWORD(addr, imem, val);
|
||||||
} else {
|
} else {
|
||||||
@@ -234,6 +236,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline u32 ReadWord(u32 addr, bool i) {
|
inline u32 ReadWord(u32 addr, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
return GET_RSP_WORD(addr, imem);
|
return GET_RSP_WORD(addr, imem);
|
||||||
} else {
|
} else {
|
||||||
@@ -242,6 +245,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteWord(u32 addr, u32 val, bool i) {
|
inline void WriteWord(u32 addr, u32 val, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
SET_RSP_WORD(addr, imem, val);
|
SET_RSP_WORD(addr, imem, val);
|
||||||
} else {
|
} else {
|
||||||
@@ -250,6 +254,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline u16 ReadHalf(u32 addr, bool i) {
|
inline u16 ReadHalf(u32 addr, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
return GET_RSP_HALF(addr, imem);
|
return GET_RSP_HALF(addr, imem);
|
||||||
} else {
|
} else {
|
||||||
@@ -258,6 +263,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteHalf(u32 addr, u16 val, bool i) {
|
inline void WriteHalf(u32 addr, u16 val, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
SET_RSP_HALF(addr, imem, val);
|
SET_RSP_HALF(addr, imem, val);
|
||||||
} else {
|
} else {
|
||||||
@@ -266,6 +272,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline u8 ReadByte(u32 addr, bool i) {
|
inline u8 ReadByte(u32 addr, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
return RSP_BYTE(addr, imem);
|
return RSP_BYTE(addr, imem);
|
||||||
} else {
|
} else {
|
||||||
@@ -274,6 +281,7 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteByte(u32 addr, u8 val, bool i) {
|
inline void WriteByte(u32 addr, u8 val, bool i) {
|
||||||
|
addr &= 0xfff;
|
||||||
if (i) {
|
if (i) {
|
||||||
RSP_BYTE(addr, imem) = val;
|
RSP_BYTE(addr, imem) = val;
|
||||||
} else {
|
} else {
|
||||||
@@ -282,34 +290,42 @@ struct RSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline u64 ReadDword(u32 addr) {
|
inline u64 ReadDword(u32 addr) {
|
||||||
|
addr &= 0xfff;
|
||||||
return GET_RSP_DWORD(addr, dmem);
|
return GET_RSP_DWORD(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteDword(u32 addr, u64 val) {
|
inline void WriteDword(u32 addr, u64 val) {
|
||||||
|
addr &= 0xfff;
|
||||||
SET_RSP_DWORD(addr, dmem, val);
|
SET_RSP_DWORD(addr, dmem, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 ReadWord(u32 addr) {
|
inline u32 ReadWord(u32 addr) {
|
||||||
|
addr &= 0xfff;
|
||||||
return GET_RSP_WORD(addr, dmem);
|
return GET_RSP_WORD(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteWord(u32 addr, u32 val) {
|
inline void WriteWord(u32 addr, u32 val) {
|
||||||
|
addr &= 0xfff;
|
||||||
SET_RSP_WORD(addr, dmem, val);
|
SET_RSP_WORD(addr, dmem, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u16 ReadHalf(u32 addr) {
|
inline u16 ReadHalf(u32 addr) {
|
||||||
|
addr &= 0xfff;
|
||||||
return GET_RSP_HALF(addr, dmem);
|
return GET_RSP_HALF(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteHalf(u32 addr, u16 val) {
|
inline void WriteHalf(u32 addr, u16 val) {
|
||||||
|
addr &= 0xfff;
|
||||||
SET_RSP_HALF(addr, dmem, val);
|
SET_RSP_HALF(addr, dmem, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u8 ReadByte(u32 addr) {
|
inline u8 ReadByte(u32 addr) {
|
||||||
|
addr &= 0xfff;
|
||||||
return RSP_BYTE(addr, dmem);
|
return RSP_BYTE(addr, dmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteByte(u32 addr, u8 val) {
|
inline void WriteByte(u32 addr, u8 val) {
|
||||||
|
addr &= 0xfff;
|
||||||
RSP_BYTE(addr, dmem) = val;
|
RSP_BYTE(addr, dmem) = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +427,8 @@ struct RSP {
|
|||||||
void vsub(u32 instr);
|
void vsub(u32 instr);
|
||||||
void vsubc(u32 instr);
|
void vsubc(u32 instr);
|
||||||
void vxor(u32 instr);
|
void vxor(u32 instr);
|
||||||
void vxnor(u32 instr);
|
void vnxor(u32 instr);
|
||||||
|
void vor(u32 instr);
|
||||||
void vnor(u32 instr);
|
void vnor(u32 instr);
|
||||||
void vzero(u32 instr);
|
void vzero(u32 instr);
|
||||||
void mfc0(RDP& rdp, u32 instr);
|
void mfc0(RDP& rdp, u32 instr);
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ inline void swc2(RSP& rsp, u32 instr) {
|
|||||||
//util::print("swc2 {:02X}\n", mask);
|
//util::print("swc2 {:02X}\n", mask);
|
||||||
switch(mask) {
|
switch(mask) {
|
||||||
case 0x00: rsp.sbv(instr); break;
|
case 0x00: rsp.sbv(instr); break;
|
||||||
case 0x01: rsp.slv(instr); break;
|
case 0x01: rsp.ssv(instr); break;
|
||||||
case 0x02: rsp.ssv(instr); break;
|
case 0x02: rsp.slv(instr); break;
|
||||||
case 0x03: rsp.sdv(instr); break;
|
case 0x03: rsp.sdv(instr); break;
|
||||||
case 0x04: rsp.sqv(instr); break;
|
case 0x04: rsp.sqv(instr); break;
|
||||||
case 0x06: rsp.spv(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 0x02: rsp.cfc2(instr); break;
|
||||||
case 0x04: rsp.mtc2(instr); break;
|
case 0x04: rsp.mtc2(instr); break;
|
||||||
case 0x06: rsp.ctc2(instr); break;
|
case 0x06: rsp.ctc2(instr); break;
|
||||||
case 0x10: case 0x1C: case 0x1E:
|
case 0x10: case 0x14:
|
||||||
case 0x1F: case 0x14: break; //rsp.vzero(instr); break;
|
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);
|
default: util::panic("Unhandled RSP COP2 sub ({:05b})\n", mask_sub);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -130,9 +132,10 @@ inline void cop2(RSP& rsp, u32 instr) {
|
|||||||
case 0x27: rsp.vmrg(instr); break;
|
case 0x27: rsp.vmrg(instr); break;
|
||||||
case 0x28: rsp.vand(instr); break;
|
case 0x28: rsp.vand(instr); break;
|
||||||
case 0x29: rsp.vnand(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 0x2C: rsp.vxor(instr); break;
|
||||||
case 0x2D: rsp.vxnor(instr); break;
|
case 0x2D: rsp.vnxor(instr); break;
|
||||||
case 0x31: rsp.vrcpl(instr); break;
|
case 0x31: rsp.vrcpl(instr); break;
|
||||||
case 0x35: rsp.vrsql(instr); break;
|
case 0x35: rsp.vrsql(instr); break;
|
||||||
case 0x32: case 0x36:
|
case 0x32: case 0x36:
|
||||||
@@ -141,6 +144,8 @@ inline void cop2(RSP& rsp, u32 instr) {
|
|||||||
case 0x30: rsp.vrcp(instr); break;
|
case 0x30: rsp.vrcp(instr); break;
|
||||||
case 0x33: rsp.vmov(instr); break;
|
case 0x33: rsp.vmov(instr); break;
|
||||||
case 0x34: rsp.vrsq(instr); break;
|
case 0x34: rsp.vrsq(instr); break;
|
||||||
|
case 0x37: break;
|
||||||
|
case 0x3F: break;
|
||||||
default: util::panic("Unhandled RSP COP2 ({:06b})\n", mask);
|
default: util::panic("Unhandled RSP COP2 ({:06b})\n", mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,11 +97,23 @@ inline VPR GetVTE(VPR vt, u8 e) {
|
|||||||
VPR vte{};
|
VPR vte{};
|
||||||
switch(e & 0xf) {
|
switch(e & 0xf) {
|
||||||
case 0 ... 1: return vt;
|
case 0 ... 1: return vt;
|
||||||
case 2 ... 3:
|
case 2:
|
||||||
vte = Broadcast(vt, e - 2, e - 2, e, e, e + 2, e + 2, e + 4, e + 4);
|
vte = Broadcast(vt, 0, 0, 2, 2, 4, 4, 6, 6);
|
||||||
break;
|
break;
|
||||||
case 4 ... 7:
|
case 3:
|
||||||
vte = Broadcast(vt, e - 4, e - 4, e - 4, e - 4, e, e, e, e);
|
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;
|
break;
|
||||||
case 8 ... 15: {
|
case 8 ... 15: {
|
||||||
int index = ELEMENT_INDEX(e - 8);
|
int index = ELEMENT_INDEX(e - 8);
|
||||||
@@ -289,7 +301,7 @@ void RSP::ldv(u32 instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RSP::lsv(u32 instr) {
|
void RSP::lsv(u32 instr) {
|
||||||
int e = E1(instr);
|
u8 e = E1(instr);
|
||||||
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1);
|
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1);
|
||||||
u16 val = ReadHalf(addr);
|
u16 val = ReadHalf(addr);
|
||||||
vpr[VT(instr)].byte[BYTE_INDEX(e)] = val >> 8;
|
vpr[VT(instr)].byte[BYTE_INDEX(e)] = val >> 8;
|
||||||
@@ -404,7 +416,7 @@ void RSP::spv(u32 instr) {
|
|||||||
|
|
||||||
void RSP::sbv(u32 instr) {
|
void RSP::sbv(u32 instr) {
|
||||||
int e = E1(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)]);
|
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));
|
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
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;
|
acc.l.element[i] = result;
|
||||||
vd.element[i] = result;
|
vd.element[i] = result;
|
||||||
vco.l.element[i] = (result >> 16) & 1 ? 0xffff : 0;
|
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);
|
VPR vte = GetVTE(vpr[VT(instr)], e);
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
s16 vsElem = vs.selement[i];
|
u16 vsElem = vs.element[i];
|
||||||
s16 vteElem = vte.selement[i];
|
u16 vteElem = vte.element[i];
|
||||||
|
|
||||||
if(vco.l.element[i]) {
|
|
||||||
if(vco.h.element[i]) {
|
|
||||||
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
|
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
|
||||||
} else {
|
if(vco.l.element[i]) {
|
||||||
|
if(!vco.h.element[i]) {
|
||||||
u16 clampSum = vsElem + vteElem;
|
u16 clampSum = vsElem + vteElem;
|
||||||
bool overflow = (vsElem + vteElem) != clampSum;
|
bool overflow = (vsElem + vteElem) != clampSum;
|
||||||
|
|
||||||
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
|
|
||||||
if(vce.element[i]) {
|
if(vce.element[i]) {
|
||||||
vcc.l.element[i] = !clampSum || !overflow ? 0xffff : 0;
|
vcc.l.element[i] = !clampSum || !overflow ? 0xffff : 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -681,9 +691,8 @@ void RSP::vcl(u32 instr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
acc.l.element[i] = vcc.l.element[i] ? -vteElem : vsElem;
|
|
||||||
if(!vco.h.element[i]) {
|
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& vd = vpr[VD(instr)];
|
||||||
VPR vte = GetVTE(vpr[VT(instr)], e);
|
VPR vte = GetVTE(vpr[VT(instr)], e);
|
||||||
|
|
||||||
u32 se;
|
/*u8 se;
|
||||||
|
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case 0 ... 1:
|
case 0 ... 1:
|
||||||
@@ -716,11 +725,11 @@ void RSP::vmov(u32 instr) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
util::panic("VMOV: This should be unreachable!\n");
|
util::panic("VMOV: This should be unreachable!\n");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
u8 de = VS(instr) & 7;
|
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++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
acc.l.element[i] = vte.element[i];
|
acc.l.element[i] = vte.element[i];
|
||||||
}
|
}
|
||||||
@@ -950,7 +959,7 @@ void RSP::vge(u32 instr) {
|
|||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
bool eql = vs.element[i] == vte.element[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;
|
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];
|
acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i];
|
||||||
vd.element[i] = acc.l.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++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
bool eql = vs.element[i] == vte.element[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;
|
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];
|
acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i];
|
||||||
vd.element[i] = acc.l.element[i];
|
vd.element[i] = acc.l.element[i];
|
||||||
vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0;
|
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) {
|
void RSP::vrcph(u32 instr) {
|
||||||
int e = E2(instr);
|
int e = E2(instr) & 7;
|
||||||
int de = DE(instr);
|
int de = DE(instr) & 7;
|
||||||
VPR& vd = vpr[VD(instr)];
|
VPR& vd = vpr[VD(instr)];
|
||||||
VPR& vt = vpr[VT(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++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
acc.l.element[i] = vte.element[i];
|
acc.l.element[i] = vte.element[i];
|
||||||
@@ -1169,9 +1178,9 @@ void RSP::vsub(u32 instr) {
|
|||||||
VPR vte = GetVTE(vpr[VT(instr)], e);
|
VPR vte = GetVTE(vpr[VT(instr)], e);
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
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;
|
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.l.element[i] = 0;
|
||||||
vco.h.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);
|
int e = E2(instr);
|
||||||
VPR& vs = vpr[VS(instr)];
|
VPR& vs = vpr[VS(instr)];
|
||||||
VPR& vd = vpr[VD(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) {
|
void RSP::vzero(u32 instr) {
|
||||||
VPR& vs = vpr[VS(instr)];
|
VPR& vs = vpr[VS(instr)];
|
||||||
VPR& vd = vpr[VD(instr)];
|
VPR& vd = vpr[VD(instr)];
|
||||||
|
|||||||
Reference in New Issue
Block a user