GTE: Implement CC
This commit is contained in:
parent
13389caa60
commit
b133f96c24
214
src/core/gte.cpp
214
src/core/gte.cpp
|
@ -294,6 +294,10 @@ void Core::ExecuteInstruction(Instruction inst)
|
|||
Execute_NCCS(inst);
|
||||
break;
|
||||
|
||||
case 0x1C:
|
||||
Execute_CC(inst);
|
||||
break;
|
||||
|
||||
case 0x1E:
|
||||
Execute_NCS(inst);
|
||||
break;
|
||||
|
@ -424,6 +428,110 @@ void Core::PushRGBFromMAC()
|
|||
m_regs.RGBC[3]);
|
||||
}
|
||||
|
||||
void Core::MulMatVec(const s16 M[3][3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift, bool lm)
|
||||
{
|
||||
#define dot3(i) \
|
||||
TruncateAndSetMACAndIR<i + 1>(SignExtendMACResult<i + 1>((s64(M[i][0]) * s64(Vx)) + (s64(M[i][1]) * s64(Vy))) + \
|
||||
(s64(M[i][2]) * s64(Vz)), \
|
||||
shift, lm)
|
||||
|
||||
dot3(0);
|
||||
dot3(1);
|
||||
dot3(2);
|
||||
|
||||
#undef dot3
|
||||
}
|
||||
|
||||
void Core::MulMatVec(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) \
|
||||
TruncateAndSetMACAndIR<i + 1>( \
|
||||
SignExtendMACResult<i + 1>(SignExtendMACResult<i + 1>((s64(T[i]) << 12) + (s64(M[i][0]) * s64(Vx))) + \
|
||||
(s64(M[i][1]) * s64(Vy))) + \
|
||||
(s64(M[i][2]) * s64(Vz)), \
|
||||
shift, lm)
|
||||
|
||||
dot3(0);
|
||||
dot3(1);
|
||||
dot3(2);
|
||||
|
||||
#undef dot3
|
||||
}
|
||||
|
||||
void Core::Execute_MVMVA(Instruction inst)
|
||||
{
|
||||
m_regs.FLAG.Clear();
|
||||
|
||||
// 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.IR1;
|
||||
Vy = m_regs.IR2;
|
||||
Vz = m_regs.IR3;
|
||||
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.GetShift(), inst.lm);
|
||||
|
||||
m_regs.FLAG.UpdateError();
|
||||
}
|
||||
|
||||
void Core::RTPS(const s16 V[3], bool sf, bool lm, bool last)
|
||||
{
|
||||
const u8 shift = sf ? 12 : 0;
|
||||
|
@ -562,36 +670,6 @@ void Core::Execute_AVSZ4(Instruction inst)
|
|||
m_regs.FLAG.UpdateError();
|
||||
}
|
||||
|
||||
void Core::MulMatVec(const s16 M[3][3], const s16 Vx, const s16 Vy, const s16 Vz, u8 shift, bool lm)
|
||||
{
|
||||
#define dot3(i) \
|
||||
TruncateAndSetMACAndIR<i + 1>(SignExtendMACResult<i + 1>((s64(M[i][0]) * s64(Vx)) + (s64(M[i][1]) * s64(Vy))) + \
|
||||
(s64(M[i][2]) * s64(Vz)), \
|
||||
shift, lm)
|
||||
|
||||
dot3(0);
|
||||
dot3(1);
|
||||
dot3(2);
|
||||
|
||||
#undef dot3
|
||||
}
|
||||
|
||||
void Core::MulMatVec(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) \
|
||||
TruncateAndSetMACAndIR<i + 1>( \
|
||||
SignExtendMACResult<i + 1>(SignExtendMACResult<i + 1>((s64(T[i]) << 12) + (s64(M[i][0]) * s64(Vx))) + \
|
||||
(s64(M[i][1]) * s64(Vy))) + \
|
||||
(s64(M[i][2]) * s64(Vz)), \
|
||||
shift, lm)
|
||||
|
||||
dot3(0);
|
||||
dot3(1);
|
||||
dot3(2);
|
||||
|
||||
#undef dot3
|
||||
}
|
||||
|
||||
void Core::InterpolateColor(s64 in_MAC1, s64 in_MAC2, s64 in_MAC3, u8 shift, bool lm)
|
||||
{
|
||||
// [MAC1,MAC2,MAC3] = MAC+(FC-MAC)*IR0
|
||||
|
@ -727,76 +805,24 @@ void Core::Execute_NCDT(Instruction inst)
|
|||
m_regs.FLAG.UpdateError();
|
||||
}
|
||||
|
||||
void Core::Execute_MVMVA(Instruction inst)
|
||||
void Core::Execute_CC(Instruction inst)
|
||||
{
|
||||
m_regs.FLAG.Clear();
|
||||
|
||||
// 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;
|
||||
}
|
||||
const u8 shift = inst.GetShift();
|
||||
const bool lm = inst.lm;
|
||||
|
||||
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.IR1;
|
||||
Vy = m_regs.IR2;
|
||||
Vz = m_regs.IR3;
|
||||
break;
|
||||
}
|
||||
// [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] = (BK*1000h + LCM*IR) SAR (sf*12)
|
||||
MulMatVec(m_regs.LCM, m_regs.BK, m_regs.IR1, m_regs.IR2, m_regs.IR3, shift, lm);
|
||||
|
||||
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;
|
||||
}
|
||||
// [MAC1,MAC2,MAC3] = [R*IR1,G*IR2,B*IR3] SHL 4
|
||||
// [MAC1,MAC2,MAC3] = [MAC1,MAC2,MAC3] SAR (sf*12)
|
||||
TruncateAndSetMACAndIR<1>(s64(s32(ZeroExtend32(m_regs.RGBC[0])) * s32(m_regs.IR1)) << 4, shift, lm);
|
||||
TruncateAndSetMACAndIR<2>(s64(s32(ZeroExtend32(m_regs.RGBC[1])) * s32(m_regs.IR2)) << 4, shift, lm);
|
||||
TruncateAndSetMACAndIR<3>(s64(s32(ZeroExtend32(m_regs.RGBC[2])) * s32(m_regs.IR3)) << 4, shift, lm);
|
||||
|
||||
MulMatVec(M, T, Vx, Vy, Vz, inst.GetShift(), inst.lm);
|
||||
// Color FIFO = [MAC1/16,MAC2/16,MAC3/16,CODE], [IR1,IR2,IR3] = [MAC1,MAC2,MAC3]
|
||||
PushRGBFromMAC();
|
||||
|
||||
m_regs.FLAG.UpdateError();
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ private:
|
|||
void NCDS(const s16 V[3], u8 shift, bool lm);
|
||||
void DPCS(const u8 color[3], u8 shift, bool lm);
|
||||
|
||||
void Execute_MVMVA(Instruction inst);
|
||||
void Execute_RTPS(Instruction inst);
|
||||
void Execute_RTPT(Instruction inst);
|
||||
void Execute_NCLIP(Instruction inst);
|
||||
|
@ -88,7 +89,7 @@ private:
|
|||
void Execute_NCCT(Instruction inst);
|
||||
void Execute_NCDS(Instruction inst);
|
||||
void Execute_NCDT(Instruction inst);
|
||||
void Execute_MVMVA(Instruction inst);
|
||||
void Execute_CC(Instruction inst);
|
||||
void Execute_DPCS(Instruction inst);
|
||||
void Execute_DPCT(Instruction inst);
|
||||
void Execute_DCPL(Instruction inst);
|
||||
|
|
Loading…
Reference in New Issue