diff --git a/src/core/gte.cpp b/src/core/gte.cpp index 3bedb3610..c4183b961 100644 --- a/src/core/gte.cpp +++ b/src/core/gte.cpp @@ -294,6 +294,14 @@ void Core::ExecuteInstruction(Instruction inst) Execute_NCCS(inst); break; + case 0x1E: + Execute_NCS(inst); + break; + + case 0x20: + Execute_NCT(inst); + break; + case 0x28: Execute_SQR(inst); break; @@ -599,6 +607,41 @@ void Core::InterpolateColor(s64 in_MAC1, s64 in_MAC2, s64 in_MAC3, u8 shift, boo TruncateAndSetMACAndIR<3>(s64(s32(m_regs.IR3) * s32(m_regs.IR0)) + in_MAC3, shift, lm); } +void Core::NCS(const s16 V[3], u8 shift, bool lm) +{ + // [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] = (LLM*V0) SAR (sf*12) + MulMatVec(m_regs.LLM, V[0], V[1], V[2], shift, lm); + + // [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); + + // Color FIFO = [MAC1/16,MAC2/16,MAC3/16,CODE], [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] + PushRGBFromMAC(); +} + +void Core::Execute_NCS(Instruction inst) +{ + m_regs.FLAG.Clear(); + + NCS(m_regs.V0, inst.GetShift(), inst.lm); + + m_regs.FLAG.UpdateError(); +} + +void Core::Execute_NCT(Instruction inst) +{ + m_regs.FLAG.Clear(); + + const u8 shift = inst.GetShift(); + const bool lm = inst.lm; + + NCS(m_regs.V0, shift, lm); + NCS(m_regs.V1, shift, lm); + NCS(m_regs.V2, shift, lm); + + m_regs.FLAG.UpdateError(); +} + void Core::NCCS(const s16 V[3], u8 shift, bool lm) { // [IR1,IR2,IR3] = [MAC1,MAC2,MAC3] = (LLM*V0) SAR (sf*12) diff --git a/src/core/gte.h b/src/core/gte.h index 0baaebcc0..10a1e653e 100644 --- a/src/core/gte.h +++ b/src/core/gte.h @@ -71,6 +71,7 @@ private: void InterpolateColor(s64 in_MAC1, s64 in_MAC2, s64 in_MAC3, u8 shift, bool lm); void RTPS(const s16 V[3], bool sf, bool lm, bool last); + void NCS(const s16 V[3], u8 shift, bool lm); void NCCS(const s16 V[3], u8 shift, bool lm); void NCDS(const s16 V[3], u8 shift, bool lm); void DPCS(const u8 color[3], u8 shift, bool lm); @@ -81,6 +82,8 @@ private: void Execute_SQR(Instruction inst); void Execute_AVSZ3(Instruction inst); void Execute_AVSZ4(Instruction inst); + void Execute_NCS(Instruction inst); + void Execute_NCT(Instruction inst); void Execute_NCCS(Instruction inst); void Execute_NCCT(Instruction inst); void Execute_NCDS(Instruction inst);