diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 28555dd9fd..e7c5769bb8 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -46,7 +46,6 @@ #define incQ() { mVU->q = (mVU->q+1) & 1; } #define doUpperOp() { mVUopU(mVU, 1); mVUdivSet(mVU); } #define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); } -#define doIbit() { if (mVUup.iBit) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } } #define blockCreate(addr) { if (!mVUblocks[addr]) mVUblocks[addr] = new microBlockManager(); } //------------------------------------------------------------------ @@ -76,6 +75,19 @@ microVUt(void) doSwapOp(mV) { else { mVUopL(mVU, 1); incPC(1); doUpperOp(); } } +microVUt(void) doIbit(mV) { + if (mVUup.iBit) { + incPC(-1); + if (CHECK_VU_OVERFLOW && ((curI & 0x7fffffff) >= 0x7f800000)) { + Console::Status("microVU%d: Clamping I Reg", params mVU->index); + int tempI = (0x80000000 & curI) | 0x7f7fffff; // Clamp I Reg + MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, tempI); + } + else MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); + incPC(1); + } +} + // Used by mVUsetupRange microVUt(void) mVUcheckIsSame(mV) { @@ -434,7 +446,7 @@ microVUr(void*) mVUcompile(microVU* mVU, u32 startPC, uptr pState) { for (x = 0; x < endCount; x++) { if (mVUinfo.isEOB) { x = 0xffff; } if (mVUup.mBit) { OR32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); } - if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(); } + if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(mVU); } else if (!mVUinfo.swapOps) { incPC(1); doUpperOp(); doLowerOp(); } else { doSwapOp(mVU); } if (mVUinfo.doXGKICK) { mVU_XGKICK_DELAY(mVU, 1); } diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 195c22a415..44c17a32fe 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -80,9 +80,10 @@ declareAllVariables #define _Z ((mVU->code>>22) & 0x1) #define _W ((mVU->code>>21) & 0x1) -#define _X_Y_Z_W (((mVU->code >> 21 ) & 0xF )) +#define _X_Y_Z_W (((mVU->code >> 21 ) & 0xF)) #define _XYZW_SS (_X+_Y+_Z+_W==1) #define _XYZW_SS2 (_XYZW_SS && (_X_Y_Z_W != 8)) +#define _XYZW_PS (_X_Y_Z_W == 0xf) #define _bc_ (mVU->code & 0x3) #define _bc_x ((mVU->code & 0x3) == 0) diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index 920ad96da2..d7c7f69acc 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -152,8 +152,10 @@ void mVU_FMACa(microVU* mVU, int recPass, int opCase, int opType, bool isACC, co } else { Fs = mVU->regAlloc->allocReg(_Fs_, _Fd_, _X_Y_Z_W); } - opCase2 { if (opType == 2) { mVUclamp1(Fs, -1, _X_Y_Z_W); } } // Clamp Needed for alot of games (TOTA, DoM, etc...) - + opCase1 { if((opType == 2) && _XYZW_PS) { mVUclamp1(Ft, -1, _X_Y_Z_W); } } // Clamp Needed for Ice Age 3 (VU0) + opCase1 { if((opType == 2) && _XYZW_PS) { mVUclamp1(Fs, -1, _X_Y_Z_W); } } // Clamp Needed for Ice Age 3 (VU0) + opCase2 { if (opType == 2) { mVUclamp1(Fs, -1, _X_Y_Z_W); } } // Clamp Needed for alot of games (TOTA, DoM, etc...) + if (_XYZW_SS) SSE_SS[opType](mVU, Fs, Ft, -1, -1); else SSE_PS[opType](mVU, Fs, Ft, -1, -1);