diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index 3b7b79a8..0a6ac612 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -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; diff --git a/src/n64/core/RSP.cpp b/src/n64/core/RSP.cpp index 6613b6eb..3f36884c 100644 --- a/src/n64/core/RSP.cpp +++ b/src/n64/core/RSP.cpp @@ -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; } diff --git a/src/n64/core/RSP.hpp b/src/n64/core/RSP.hpp index 470f0f94..bd7733d2 100644 --- a/src/n64/core/RSP.hpp +++ b/src/n64/core/RSP.hpp @@ -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); diff --git a/src/n64/core/rsp/decode.cpp b/src/n64/core/rsp/decode.cpp index b8573d4d..c94b9200 100644 --- a/src/n64/core/rsp/decode.cpp +++ b/src/n64/core/rsp/decode.cpp @@ -94,17 +94,16 @@ 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) { - 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); + 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; + default: util::panic("Unhandled RSP COP2 sub ({:05b})\n", mask_sub); + } } break; case 0x04: rsp.vmudl(instr); break; diff --git a/src/n64/core/rsp/instructions.cpp b/src/n64/core/rsp/instructions.cpp index 975e8a44..ed64632a 100644 --- a/src/n64/core/rsp/instructions.cpp +++ b/src/n64/core/rsp/instructions.cpp @@ -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)];