GTE: Fix buggy MVMVA instruction

This commit is contained in:
Connor McLaughlin 2020-05-09 13:48:13 +10:00
parent 9959440a3a
commit f679f8d063
2 changed files with 26 additions and 7 deletions

View file

@ -405,6 +405,26 @@ void Core::MulMatVec(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16
#undef dot3 #undef dot3
} }
void Core::MulMatVecBuggy(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift,
bool lm)
{
#define dot3(i) \
do \
{ \
TruncateAndSetIR<i + 1>( \
SignExtendMACResult<i + 1>(SignExtendMACResult<i + 1>((s64(T[i]) << 12) + (s64(M[i][0]) * s64(Vx)))) >> shift, \
false); \
TruncateAndSetMACAndIR<i + 1>(SignExtendMACResult<i + 1>((s64(M[i][1]) * s64(Vy))) + (s64(M[i][2]) * s64(Vz)), \
shift, lm); \
} while (0)
dot3(0);
dot3(1);
dot3(2);
#undef dot3
}
void Core::Execute_MVMVA(Instruction inst) void Core::Execute_MVMVA(Instruction inst)
{ {
m_regs.FLAG.Clear(); m_regs.FLAG.Clear();
@ -463,25 +483,23 @@ void Core::Execute_MVMVA(Instruction inst)
break; break;
} }
s32 T[3]; static const s32 zero_T[3] = {};
switch (inst.mvmva_translation_vector) switch (inst.mvmva_translation_vector)
{ {
case 0: case 0:
std::memcpy(T, m_regs.TR, sizeof(T)); MulMatVec(M, m_regs.TR, Vx, Vy, Vz, inst.GetShift(), inst.lm);
break; break;
case 1: case 1:
std::memcpy(T, m_regs.BK, sizeof(T)); MulMatVec(M, m_regs.BK, Vx, Vy, Vz, inst.GetShift(), inst.lm);
break; break;
case 2: case 2:
std::memcpy(T, m_regs.FC, sizeof(T)); MulMatVecBuggy(M, m_regs.FC, Vx, Vy, Vz, inst.GetShift(), inst.lm);
break; break;
default: default:
std::fill_n(T, countof(T), s32(0)); MulMatVec(M, zero_T, Vx, Vy, Vz, inst.GetShift(), inst.lm);
break; break;
} }
MulMatVec(M, T, Vx, Vy, Vz, inst.GetShift(), inst.lm);
m_regs.FLAG.UpdateError(); m_regs.FLAG.UpdateError();
} }

View file

@ -74,6 +74,7 @@ private:
// 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 s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift, bool lm); void MulMatVec(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift, bool lm);
void MulMatVecBuggy(const s16 M[3][3], const s32 T[3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift, bool lm);
// Interpolate colour, or as in nocash "MAC+(FC-MAC)*IR0". // Interpolate colour, or as in nocash "MAC+(FC-MAC)*IR0".
void InterpolateColor(s64 in_MAC1, s64 in_MAC2, s64 in_MAC3, u8 shift, bool lm); void InterpolateColor(s64 in_MAC1, s64 in_MAC2, s64 in_MAC3, u8 shift, bool lm);