- Implemented m-bit functionality. Fixes Crash Twinsanity and most-likely other games...

Note: If anyone has any games that have broken graphics when mVU prints "microVU0: M-bit set!" to console, then please notify me about it.


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1318 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-06-04 05:52:57 +00:00
parent 5831b47c4e
commit 4490d237dc
4 changed files with 23 additions and 12 deletions

View File

@ -157,7 +157,7 @@ microVUt(void) mVUsetCycles(mV) {
tCycles(mVUregs.xgkick, mVUregsTemp.xgkick);
}
microVUt(void) mVUendProgram(mV, int qInst, int pInst, int fStatus, int fMac, int fClip) {
microVUt(void) mVUendProgram(mV, bool clearIsBusy, int qInst, int pInst, int fStatus, int fMac, int fClip) {
// Save P/Q Regs
if (qInst) { SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, 0xe5); }
@ -175,9 +175,12 @@ microVUt(void) mVUendProgram(mV, int qInst, int pInst, int fStatus, int fMac, in
MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1);
MOV32RtoM((uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL, gprT2);
// Clear 'is busy' Flags, Save PC, and Jump to Exit Point
AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif
if (clearIsBusy) { // Clear 'is busy' Flags
AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif
}
//Save PC, and Jump to Exit Point
MOV32ItoM((uptr)&mVU->regs->VI[REG_TPC].UL, xPC);
JMP32((uptr)mVU->exitFunct - ((uptr)x86Ptr + 5));
}
@ -196,10 +199,10 @@ microVUt(void) mVUtestCycles(mV) {
SUB32ItoM((uptr)&mVU->cycles, mVUcycles);
u32* jmp32 = JG32(0);
MOV32ItoR(gprT2, xPC);
if (!isVU1) CALLFunc((uptr)mVUwarning0);
else CALLFunc((uptr)mVUwarning1);
if (isVU1) CALLFunc((uptr)mVUwarning1);
//else CALLFunc((uptr)mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
MOV32ItoR(gprR, Roffset); // Restore gprR
mVUendProgram(mVU, 0, 0, sI, 0, cI);
mVUendProgram(mVU, (isVU1)?1:0, 0, 0, sI, 0, cI);
x86SetJ32(jmp32);
}
@ -249,7 +252,9 @@ microVUf(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
incCycles(1);
mVUopU(mVU, 0);
if (curI & _Ebit_) { branch = 1; mVUup.eBit = 1; }
if (curI & _MDTbit_) { branch = 4; }
if (curI & _DTbit_) { branch = 4; }
if (curI & _Mbit_) { mVUup.mBit = 1; }
if (curI & _Ibit_) { mVUlow.isNOP = 1; mVUup.iBit = 1; }
else { incPC(-1); mVUopL(mVU, 0); incPC(1); }
mVUsetCycles(mVU);
@ -276,6 +281,7 @@ microVUf(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
int x;
for (x = 0; x < (vuIndex ? (0x3fff/8) : (0xfff/8)); x++) {
if (mVUinfo.isEOB) { x = 0xffff; }
if (mVUup.mBit) { OR32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); }
if (mVUlow.isNOP) { incPC(1); doUpperOp(); doIbit(); }
else if (!mVUinfo.swapOps) { incPC(1); doUpperOp(); doLowerOp(); }
else { mVUopL(mVU, 1); incPC(1); doUpperOp(); }
@ -383,7 +389,7 @@ eBitTemination:
// Do E-bit end stuff here
mVUsetupRange(mVU, xPC - 8);
mVUendProgram(mVU, mVU->q, mVU->p, lStatus, lMac, lClip);
mVUendProgram(mVU, 1, mVU->q, mVU->p, lStatus, lMac, lClip);
return thisPtr;
}

View File

@ -207,7 +207,7 @@ void mVUflagPass(mV, u32 startPC, u32 xCount) {
for (int branch = 0; mVUcount < xCount; mVUcount++) {
incPC(1);
if ( curI & _Ebit_ ) { branch = 1; }
if ( curI & _MDTbit_ ) { branch = 4; }
if ( curI & _DTbit_ ) { branch = 4; }
if (!(curI & _Ibit_) ) { incPC(-1); mVUopL(mVU, 3); incPC(1); }
if (branch >= 2) { shortBranch(); break; }
else if (branch == 1) { branch = 2; }

View File

@ -81,6 +81,7 @@ struct microVIreg {
struct microUpperOp {
bool eBit; // Has E-bit set
bool iBit; // Has I-bit set
bool mBit; // Has M-bit set
microVFreg VF_write; // VF Vectors written to by this instruction
microVFreg VF_read[2]; // VF Vectors read by this instruction
};

View File

@ -103,7 +103,7 @@ declareAllVariables
#define _Mbit_ (1<<29)
#define _Dbit_ (1<<28)
#define _Tbit_ (1<<27)
#define _MDTbit_ 0 //( _Mbit_ | _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff...
#define _DTbit_ 0 //( _Dbit_ | _Tbit_ ) // ToDo: Implement this stuff...
#define divI 0x1040000
#define divD 0x2080000
@ -231,7 +231,11 @@ declareAllVariables
}
#else
#define mVUprint 0&&
#define mVUdebug1() {}
#define mVUdebug1() { \
if (curI & _Mbit_) { Console::Status("microVU%d: M-bit set!", params getIndex); } \
if (curI & _Dbit_) { DevCon::Status ("microVU%d: D-bit set!", params getIndex); } \
if (curI & _Tbit_) { DevCon::Status ("microVU%d: T-bit set!", params getIndex); } \
}
#endif
// Program Logging...