mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 07:35:41 +00:00
GTE: Implement unverified MVMVA
This commit is contained in:
parent
3df7b22c37
commit
c18597c3bf
|
@ -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
|
|
@ -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 = {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue