GTE: Implement unverified MVMVA

This commit is contained in:
Connor McLaughlin 2019-09-25 15:58:33 +10:00
parent 3df7b22c37
commit c18597c3bf
3 changed files with 83 additions and 8 deletions

View file

@ -290,6 +290,10 @@ void Core::ExecuteInstruction(Instruction inst)
Execute_RTPT(inst); Execute_RTPT(inst);
break; break;
case 0x12:
Execute_MVMVA(inst);
break;
default: default:
Panic("Missing handler"); Panic("Missing handler");
break; break;
@ -607,10 +611,10 @@ void Core::MulMatVec(const s16 M[3][3], const s16 Vx, const s16 Vy, const s16 Vz
TruncateAndSetIR<3>(m_regs.MAC3, lm); TruncateAndSetIR<3>(m_regs.MAC3, lm);
} }
void Core::MulMatVec(const s16 M[3][3], const u32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm) void Core::MulMatVec(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm)
{ {
#define dot3(i) \ #define dot3(i) \
TruncateAndSetMAC<i + 1>(static_cast<s64>(ZeroExtend64(T[i]) << 12) + \ TruncateAndSetMAC<i + 1>(s64(T[i] << 12) + \
TruncateMAC<i + 1>(TruncateMAC<i + 1>(TruncateMAC<i + 1>(s64(s32(M[i][0]) * s32(Vx))) + \ TruncateMAC<i + 1>(TruncateMAC<i + 1>(TruncateMAC<i + 1>(s64(s32(M[i][0]) * s32(Vx))) + \
s64(s32(M[i][1]) * s32(Vy))) + \ s64(s32(M[i][1]) * s32(Vy))) + \
s64(s32(M[i][2]) * s32(Vz))), \ s64(s32(M[i][2]) * s32(Vz))), \
@ -644,9 +648,9 @@ void Core::NCDS(const s16 V[3], bool sf, bool lm)
// [MAC1,MAC2,MAC3] = MAC+(FC-MAC)*IR0 ;<--- for NCDx only // [MAC1,MAC2,MAC3] = MAC+(FC-MAC)*IR0 ;<--- for NCDx only
// [IR1,IR2,IR3] = (([RFC,GFC,BFC] SHL 12) - [MAC1,MAC2,MAC3]) SAR (sf*12) // [IR1,IR2,IR3] = (([RFC,GFC,BFC] SHL 12) - [MAC1,MAC2,MAC3]) SAR (sf*12)
TruncateAndSetIR<1>(s32(s64(ZeroExtend64(m_regs.FC[0]) << 12) - s64(m_regs.MAC1)) >> (sf ? 12 : 0), false); TruncateAndSetIR<1>(s32((s64(m_regs.FC[0]) << 12) - s64(m_regs.MAC1)) >> (sf ? 12 : 0), false);
TruncateAndSetIR<2>(s32(s64(ZeroExtend64(m_regs.FC[1]) << 12) - s64(m_regs.MAC2)) >> (sf ? 12 : 0), false); TruncateAndSetIR<2>(s32((s64(m_regs.FC[1]) << 12) - s64(m_regs.MAC2)) >> (sf ? 12 : 0), false);
TruncateAndSetIR<3>(s32(s64(ZeroExtend64(m_regs.FC[2]) << 12) - s64(m_regs.MAC3)) >> (sf ? 12 : 0), false); TruncateAndSetIR<3>(s32((s64(m_regs.FC[2]) << 12) - s64(m_regs.MAC3)) >> (sf ? 12 : 0), false);
// [MAC1,MAC2,MAC3] = (([IR1,IR2,IR3] * IR0) + [MAC1,MAC2,MAC3]) // [MAC1,MAC2,MAC3] = (([IR1,IR2,IR3] * IR0) + [MAC1,MAC2,MAC3])
// [MAC1,MAC2,MAC3] = [MAC1,MAC2,MAC3] SAR (sf*12) ;<--- for NCDx/NCCx // [MAC1,MAC2,MAC3] = [MAC1,MAC2,MAC3] SAR (sf*12) ;<--- for NCDx/NCCx
@ -671,4 +675,74 @@ void Core::Execute_NCDS(Instruction inst)
m_regs.FLAG.UpdateError(); m_regs.FLAG.UpdateError();
} }
void Core::Execute_MVMVA(Instruction inst)
{
// TODO: Remove memcpy..
s16 M[3][3];
switch (inst.mvmva_multiply_matrix)
{
case 0:
std::memcpy(M, m_regs.RT, sizeof(s16) * 3 * 3);
break;
case 1:
std::memcpy(M, m_regs.LLM, sizeof(s16) * 3 * 3);
break;
case 2:
std::memcpy(M, m_regs.LCM, sizeof(s16) * 3 * 3);
break;
default:
// buggy
Panic("Missing implementation");
return;
}
s16 Vx, Vy, Vz;
switch (inst.mvmva_multiply_vector)
{
case 0:
Vx = m_regs.V0[0];
Vy = m_regs.V0[1];
Vz = m_regs.V0[2];
break;
case 1:
Vx = m_regs.V1[0];
Vy = m_regs.V1[1];
Vz = m_regs.V1[2];
break;
case 2:
Vx = m_regs.V2[0];
Vy = m_regs.V2[1];
Vz = m_regs.V2[2];
break;
default:
Vx = m_regs.IR0;
Vy = m_regs.IR1;
Vz = m_regs.IR2;
break;
}
s32 T[3];
switch (inst.mvmva_translation_vector)
{
case 0:
std::memcpy(T, m_regs.TR, sizeof(T));
break;
case 1:
std::memcpy(T, m_regs.BK, sizeof(T));
break;
case 2:
// buggy
std::memcpy(T, m_regs.FC, sizeof(T));
break;
case 3:
std::fill_n(T, countof(T), s32(0));
break;
default:
Panic("Missing implementation");
return;
}
MulMatVec(M, T, Vx, Vy, Vz, inst.sf, inst.lm);
}
} // namespace GTE } // namespace GTE

View file

@ -64,7 +64,7 @@ private:
void MulMatVec(const s16 M[3][3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm); void MulMatVec(const s16 M[3][3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm);
// 3x3 matrix * 3x1 vector with translation, updates MAC[1-3] and IR[1-3] // 3x3 matrix * 3x1 vector with translation, updates MAC[1-3] and IR[1-3]
void MulMatVec(const s16 M[3][3], const u32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm); void MulMatVec(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, bool sf, bool lm);
void RTPS(const s16 V[3], bool sf); void RTPS(const s16 V[3], bool sf);
void NCDS(const s16 V[3], bool sf, bool lm); void NCDS(const s16 V[3], bool sf, bool lm);
@ -76,6 +76,7 @@ private:
void Execute_AVSZ3(Instruction inst); void Execute_AVSZ3(Instruction inst);
void Execute_AVSZ4(Instruction inst); void Execute_AVSZ4(Instruction inst);
void Execute_NCDS(Instruction inst); void Execute_NCDS(Instruction inst);
void Execute_MVMVA(Instruction inst);
Regs m_regs = {}; Regs m_regs = {};
}; };

View file

@ -103,10 +103,10 @@ union Regs
s32 TR[3]; // 37-39 s32 TR[3]; // 37-39
s16 LLM[3][3]; // 40-44 s16 LLM[3][3]; // 40-44
u16 pad18; // 44 u16 pad18; // 44
u32 BK[3]; // 45-47 s32 BK[3]; // 45-47
s16 LCM[3][3]; // 48-52 s16 LCM[3][3]; // 48-52
u16 pad19; // 52 u16 pad19; // 52
u32 FC[3]; // 53-55 s32 FC[3]; // 53-55
s32 OFX; // 56 s32 OFX; // 56
s32 OFY; // 57 s32 OFY; // 57
u16 H; // 58 u16 H; // 58