diff --git a/src/pse/gte.cpp b/src/pse/gte.cpp index b7b853bae..ab6a80f54 100644 --- a/src/pse/gte.cpp +++ b/src/pse/gte.cpp @@ -294,6 +294,10 @@ void Core::ExecuteInstruction(Instruction inst) Execute_SQR(inst); break; + case 0x2A: + Execute_DPCT(inst); + break; + case 0x2D: Execute_AVSZ3(inst); break; @@ -383,9 +387,10 @@ void Core::PushSZ(s32 value) void Core::PushRGB(u8 r, u8 g, u8 b, u8 c) { - m_regs.RGB0 = m_regs.RGB1; - m_regs.RGB1 = m_regs.RGB2; - m_regs.RGB2 = ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(c) << 24); + m_regs.dr32[20] = m_regs.dr32[21]; // RGB0 <- RGB1 + m_regs.dr32[21] = m_regs.dr32[22]; // RGB1 <- RGB2 + m_regs.dr32[22] = + ZeroExtend32(r) | (ZeroExtend32(g) << 8) | (ZeroExtend32(b) << 16) | (ZeroExtend32(c) << 24); // RGB2 <- Value } void Core::RTPS(const s16 V[3], bool sf, bool lm, bool last) @@ -737,18 +742,15 @@ void Core::Execute_MVMVA(Instruction inst) m_regs.FLAG.UpdateError(); } -void Core::Execute_DPCS(Instruction inst) +void Core::DPCS(const u8 color[3], bool sf, bool lm) { - m_regs.FLAG.Clear(); - - const u8 shift = inst.GetShift(); - const bool lm = inst.lm; + const u8 shift = sf ? 12 : 0; // In: [IR1,IR2,IR3]=Vector, FC=Far Color, IR0=Interpolation value, CODE=MSB of RGBC // [MAC1,MAC2,MAC3] = [R,G,B] SHL 16 ;<--- for DPCS/DPCT - TruncateAndSetMAC<1>((s64(ZeroExtend64(m_regs.RGBC[0])) << 16), 0); - TruncateAndSetMAC<2>((s64(ZeroExtend64(m_regs.RGBC[1])) << 16), 0); - TruncateAndSetMAC<3>((s64(ZeroExtend64(m_regs.RGBC[2])) << 16), 0); + TruncateAndSetMAC<1>((s64(ZeroExtend64(color[0])) << 16), 0); + TruncateAndSetMAC<2>((s64(ZeroExtend64(color[1])) << 16), 0); + TruncateAndSetMAC<3>((s64(ZeroExtend64(color[2])) << 16), 0); // [MAC1,MAC2,MAC3] = MAC+(FC-MAC)*IR0 // [IR1,IR2,IR3] = (([RFC,GFC,BFC] SHL 12) - [MAC1,MAC2,MAC3]) SAR (sf*12) @@ -772,4 +774,27 @@ void Core::Execute_DPCS(Instruction inst) m_regs.FLAG.UpdateError(); } +void Core::Execute_DPCS(Instruction inst) +{ + m_regs.FLAG.Clear(); + + DPCS(m_regs.RGBC, inst.sf, inst.lm); + + m_regs.FLAG.UpdateError(); +} + +void Core::Execute_DPCT(Instruction inst) +{ + m_regs.FLAG.Clear(); + + const bool sf = inst.sf; + const bool lm = inst.lm; + + DPCS(m_regs.RGB0, sf, lm); + DPCS(m_regs.RGB0, sf, lm); + DPCS(m_regs.RGB0, sf, lm); + + m_regs.FLAG.UpdateError(); +} + } // namespace GTE \ No newline at end of file diff --git a/src/pse/gte.h b/src/pse/gte.h index 9c9ac9657..911d6bd97 100644 --- a/src/pse/gte.h +++ b/src/pse/gte.h @@ -62,6 +62,7 @@ private: void RTPS(const s16 V[3], bool sf, bool lm, bool last); void NCCS(const s16 V[3], bool sf, bool lm); void NCDS(const s16 V[3], bool sf, bool lm); + void DPCS(const u8 color[3], bool sf, bool lm); void Execute_RTPS(Instruction inst); void Execute_RTPT(Instruction inst); @@ -75,6 +76,7 @@ private: void Execute_NCDT(Instruction inst); void Execute_MVMVA(Instruction inst); void Execute_DPCS(Instruction inst); + void Execute_DPCT(Instruction inst); Regs m_regs = {}; }; diff --git a/src/pse/gte_types.h b/src/pse/gte_types.h index a563bc7ac..0bcc87a37 100644 --- a/src/pse/gte_types.h +++ b/src/pse/gte_types.h @@ -86,9 +86,9 @@ union Regs u16 pad15; // 18 u16 SZ3; // 19 u16 pad16; // 19 - u32 RGB0; // 20 - u32 RGB1; // 21 - u32 RGB2; // 22 + u8 RGB0[4]; // 20 + u8 RGB1[4]; // 21 + u8 RGB2[4]; // 22 u32 RES1; // 23 s32 MAC0; // 24 s32 MAC1; // 25