drc: starting arm64 support
[pcsx_rearmed.git] / libpcsxcore / gte.c
index 31213ef..97a4ccd 100644 (file)
 #define gteBFC (((s32 *)regs->CP2C.r)[23])
 #define gteOFX (((s32 *)regs->CP2C.r)[24])
 #define gteOFY (((s32 *)regs->CP2C.r)[25])
-#define gteH   (regs->CP2C.p[26].sw.l)
+// senquack - gteH register is u16, not s16, and used in GTE that way.
+//  HOWEVER when read back by CPU using CFC2, it will be incorrectly
+//  sign-extended by bug in original hardware, according to Nocash docs
+//  GTE section 'Screen Offset and Distance'. The emulator does this
+//  sign extension when it is loaded to GTE by CTC2.
+//#define gteH   (psxRegs.CP2C.p[26].sw.l)
+#define gteH   (psxRegs.CP2C.p[26].w.l)
 #define gteDQA (regs->CP2C.p[27].sw.l)
 #define gteDQB (((s32 *)regs->CP2C.r)[28])
 #define gteZSF3 (regs->CP2C.p[29].sw.l)
@@ -254,7 +260,18 @@ static inline u32 limE_(psxCP2Regs *regs, u32 result) {
 #define A3U(x) (x)
 #endif
 
+
+//senquack - n param should be unsigned (will be 'gteH' reg which is u16)
+#ifdef GTE_USE_NATIVE_DIVIDE
+INLINE u32 DIVIDE(u16 n, u16 d) {
+       if (n < d * 2) {
+               return ((u32)n << 16) / d;
+       }
+       return 0xffffffff;
+}
+#else
 #include "gte_divider.h"
+#endif // GTE_USE_NATIVE_DIVIDE
 
 #ifndef FLAGLESS
 
@@ -404,6 +421,7 @@ static u32 DIVIDE_(s16 n, u16 d) {
 
 void gteRTPS(psxCP2Regs *regs) {
        int quotient;
+       s64 tmp;
 
 #ifdef GTE_LOG
        GTE_LOG("GTE RTPS\n");
@@ -426,14 +444,16 @@ void gteRTPS(psxCP2Regs *regs) {
        gteSX2 = limG1(F((s64)gteOFX + ((s64)gteIR1 * quotient)) >> 16);
        gteSY2 = limG2(F((s64)gteOFY + ((s64)gteIR2 * quotient)) >> 16);
 
-       gteMAC0 = F((s64)gteDQB + ((s64)gteDQA * quotient));
-       gteIR0 = limH(gteMAC0 >> 12);
+       tmp = (s64)gteDQB + ((s64)gteDQA * quotient);
+       gteMAC0 = F(tmp);
+       gteIR0 = limH(tmp >> 12);
 }
 
 void gteRTPT(psxCP2Regs *regs) {
        int quotient;
        int v;
        s32 vx, vy, vz;
+       s64 tmp;
 
 #ifdef GTE_LOG
        GTE_LOG("GTE RTPT\n");
@@ -456,8 +476,10 @@ void gteRTPT(psxCP2Regs *regs) {
                fSX(v) = limG1(F((s64)gteOFX + ((s64)gteIR1 * quotient)) >> 16);
                fSY(v) = limG2(F((s64)gteOFY + ((s64)gteIR2 * quotient)) >> 16);
        }
-       gteMAC0 = F((s64)gteDQB + ((s64)gteDQA * quotient));
-       gteIR0 = limH(gteMAC0 >> 12);
+
+       tmp = (s64)gteDQB + ((s64)gteDQA * quotient);
+       gteMAC0 = F(tmp);
+       gteIR0 = limH(tmp >> 12);
 }
 
 void gteMVMVA(psxCP2Regs *regs) {