fix decoding rsp

This commit is contained in:
CocoSimone
2022-10-06 18:30:04 +02:00
parent 73d65c2246
commit 6d9516933d
5 changed files with 40 additions and 20 deletions

View File

@@ -15,7 +15,7 @@ struct Window {
[[nodiscard]] bool gotClosed(SDL_Event event);
ImFont *uiFont, *codeFont;
u32 windowID;
float volumeL = 0.001, volumeR = 0.001;
float volumeL = 0.05, volumeR = 0.05;
void LoadROM(n64::Core& core, const std::string& path);
private:
bool lockVolume = true;

View File

@@ -20,11 +20,11 @@ void RSP::Reset() {
memset(dmem, 0, DMEM_SIZE);
memset(imem, 0, IMEM_SIZE);
memset(vpr, 0, 32 * sizeof(VPR));
memset(gpr, 0, 32);
memset(gpr, 0, 32 * sizeof(u32));
memset(&vce, 0, sizeof(VPR));
acc = {.h={}, .m={}, .l={}};
vcc = {.l = {}, .h = {}};
vco = {.l = {}, .h = {}};
memset(&acc, 0, 3 * sizeof(VPR));
memset(&vcc, 0, 2 * sizeof(VPR));
memset(&vco, 0, 2 * sizeof(VPR));
semaphore = false;
}

View File

@@ -409,6 +409,7 @@ struct RSP {
void vmadm(u32 instr);
void vmadn(u32 instr);
void vmov(u32 instr);
void vmulf(u32 instr);
void vmudl(u32 instr);
void vmudh(u32 instr);
void vmudm(u32 instr);

View File

@@ -94,18 +94,17 @@ inline void cop2(RSP& rsp, u32 instr) {
//util::print("Cop2 {:02X}\n", mask);
switch(mask) {
case 0x00:
//util::print("Cop2 sub {:02X}\n", mask_sub);
switch(mask_sub) {
if((instr >> 25) & 1) {
rsp.vmulf(instr);
} else {
switch (mask_sub) {
case 0x00: rsp.mfc2(instr); break;
case 0x02: rsp.cfc2(instr); break;
case 0x04: rsp.mtc2(instr); break;
case 0x06: rsp.ctc2(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;
case 0x04: rsp.vmudl(instr); break;
case 0x05: rsp.vmudm(instr); break;

View File

@@ -402,14 +402,14 @@ void RSP::spv(u32 instr) {
int e = E1(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3);
int start = E1(instr);
int start = e;
int end = start + 8;
for(int offset = start; offset < end; offset++) {
if((offset & 15) < 8) {
WriteByte(addr++, vpr[VT(instr)].byte[BYTE_INDEX((offset & 7) << 1)]);
} else {
WriteByte(addr++, vpr[VT(instr)].byte[ELEMENT_INDEX(offset & 7)] >> 7);
WriteByte(addr++, vpr[VT(instr)].element[ELEMENT_INDEX(offset & 7)] >> 7);
}
}
}
@@ -581,7 +581,10 @@ void RSP::vadd(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] + (vco.l.element[i] != 0);
s16 vsE = vs.selement[i];
s16 vteE = vte.selement[i];
s32 result = vsE + vteE + (vco.l.element[i] != 0);
acc.l.element[i] = result;
vd.element[i] = clamp_signed(result);
vco.l.element[i] = 0;
@@ -595,7 +598,7 @@ void RSP::vaddc(u32 instr) {
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
for(int i = 0; i < 8; i++) {
u32 result = vs.element[i] + vte.element[i];
s32 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;
@@ -744,6 +747,23 @@ inline bool IsSignExtension(s16 hi, s16 lo) {
return false;
}
void RSP::vmulf(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++) {
s32 prod = vs.selement[i] * vte.selement[i];
s64 accum = (prod * 2) + 0x8000;
SetACC(i, accum);
s16 result = clamp_signed(accum >> 16);
vd.element[i] = result;
}
}
void RSP::vmudl(u32 instr) {
int e = E2(instr);
VPR& vs = vpr[VS(instr)];