X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fgte.c;h=97a4ccd0db0ddf54afb130d2f11c6ec42bc5fb46;hb=981752f84063a77f456e494dc298808ec14611a9;hp=62fc7f384dcbd797a532775a54a6c9efdc3e97e0;hpb=eac3852265815a2e57ea9987a2bea2fcadd3f022;p=pcsx_rearmed.git diff --git a/libpcsxcore/gte.c b/libpcsxcore/gte.c index 62fc7f38..97a4ccd0 100644 --- a/libpcsxcore/gte.c +++ b/libpcsxcore/gte.c @@ -149,7 +149,13 @@ #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) @@ -170,7 +176,7 @@ #ifndef FLAGLESS -static inline s32 BOUNDS_(psxCP2Regs *regs, s64 n_value, s64 n_max, int n_maxflag, s64 n_min, int n_minflag) { +static inline s64 BOUNDS_(psxCP2Regs *regs, s64 n_value, s64 n_max, int n_maxflag, s64 n_min, int n_minflag) { if (n_value > n_max) { gteFLAG |= n_maxflag; } else if (n_value < n_min) { @@ -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) {