- Added a 1-cycle xgkick delay, fixes SO3 graphic corruption and flickering.

Theres still VU stuff the game does that isn't implemented, but the game seems to run fine w/o the implementation (only tested the beginning though).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1282 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-05-29 03:02:21 +00:00
parent c3ae30f250
commit 12ca3898d6
5 changed files with 31 additions and 7 deletions

View File

@ -117,6 +117,7 @@ struct microVU {
u32 code; // Contains the current Instruction
u32 divFlag; // 1 instance of I/D flags
u32 VIbackup[2]; // Holds a backup of a VI reg if modified before a branch
u32 VIxgkick; // Holds a backup of a VI reg used for xgkick-delays
u32 branch; // Holds branch compare result (IBxx) OR Holds address to Jump to (JALR/JR)
u32 p; // Holds current P instance index
u32 q; // Holds current Q instance index

View File

@ -354,6 +354,12 @@ microVUt(void) mVUanalyzeXGkick(int Fs, int xCycles) {
analyzeVIreg1(Fs);
analyzeXGkick1();
analyzeXGkick2(xCycles);
// Note: Technically XGKICK should stall on the next instruction,
// this code stalls on the same instruction. The only case where this
// will be a problem with, is if you have very-specifically placed
// FMxxx or FSxxx opcodes checking flags near this instruction AND
// the XGKICK instruction stalls. No-game should be effected by
// this minor difference.
}
//------------------------------------------------------------------

View File

@ -125,8 +125,11 @@ microVUt(void) mVUincCycles(int x) {
calcCycles(mVUregs.p, x);
if (!mVUregs.p || (mVUregs.p && mVUregsTemp.p)) { incP(); }
}
if (mVUregs.xgkick) {
calcCycles(mVUregs.xgkick, x);
if (!mVUregs.xgkick) { mVUinfo |= _doXGKICK; }
}
calcCycles(mVUregs.r, x);
calcCycles(mVUregs.xgkick, x);
}
microVUt(void) mVUsetCycles() {
@ -277,6 +280,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
if (isNOP) { incPC(1); doUpperOp(); doIbit(); }
else if (!swapOps) { incPC(1); doUpperOp(); doLowerOp(); }
else { mVUopL<vuIndex, 1>(); incPC(1); doUpperOp(); }
if (doXGKICK) { mVU_XGKICK_DELAY<vuIndex>(); }
if (!isBdelay) { incPC(1); }
else {
@ -376,6 +380,7 @@ eBitTemination:
AND32ItoR (flagReg, 0x0fcf);
OR32MtoR (flagReg, (uptr)&mVU->divFlag);
}
if (doXGKICK) { mVU_XGKICK_DELAY<vuIndex>(); }
// Do E-bit end stuff here
mVUsetupRange<vuIndex>(xPC - 8);

View File

@ -1113,18 +1113,24 @@ void __fastcall mVU_XGKICK__(u32 addr) {
microVUf(void) mVU_XGKICK() {
microVU* mVU = mVUx;
pass1 { mVUanalyzeXGkick<vuIndex>(_Is_, 4); }
pass1 { mVUanalyzeXGkick<vuIndex>(_Is_, mVU_XGKICK_CYCLES); }
pass2 {
mVUprint("XGkick");
mVUallocVIa<vuIndex>(gprT2, _Is_); // gprT2 = ECX for __fastcall
mVUbackupRegs<vuIndex>();
if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_);
else CALLFunc((uptr)mVU_XGKICK__);
mVUrestoreRegs<vuIndex>();
mVUallocVIa<vuIndex>(gprT1, _Is_);
MOV32RtoM((uptr)&mVU->VIxgkick, gprT1);
}
pass3 { mVUlog("XGKICK vi%02d", _Fs_); }
}
microVUt(void) mVU_XGKICK_DELAY() {
microVU* mVU = mVUx;
MOV32MtoR(gprT2, (uptr)&mVU->VIxgkick); // gprT2 = ECX for __fastcall
mVUbackupRegs<vuIndex>();
if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_);
else CALLFunc((uptr)mVU_XGKICK__);
mVUrestoreRegs<vuIndex>();
}
//------------------------------------------------------------------
// Branches/Jumps
//------------------------------------------------------------------

View File

@ -191,6 +191,7 @@ declareAllVariables
#define _isEOB (1<<2) // End of Block
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
#define _isSflag (1<<4) // Cur Instruction uses status flag
#define _doXGKICK (1<<5) // Do XGKICK transfer on this instruction
#define _writeQ (1<<6)
#define _readQ (1<<6) // same as writeQ
#define _writeP (1<<7)
@ -222,6 +223,7 @@ declareAllVariables
#define isEOB (mVUinfo & (1<<2))
#define isBdelay (mVUinfo & (1<<3))
#define isSflag (mVUinfo & (1<<4))
#define doXGKICK (mVUinfo & (1<<5))
#define readQ ((mVUinfo >> 6) & 1) // same as writeQ
#define readP ((mVUinfo >> 7) & 1) // same as writeP
#define writeQ (((mVUinfo >> 6) + 1) & 1)
@ -295,6 +297,10 @@ declareAllVariables
#define CHECK_VU_FLAGHACK2 (u32)Config.Hacks.vuFlagHack2 // (Can cause Infinite loops, SPS, etc...)
#define CHECK_VU_MINMAXHACK (u32)Config.Hacks.vuMinMax // (Can cause SPS, Black Screens, etc...)
// Unknown Data
#define mVU_XGKICK_CYCLES 1 // Its unknown at recompile time how long the xgkick transfer will take
// so give it a value that makes games happy :) (SO3 is fine at 1 cycle delay)
// Cache Limit Check
#define mVUcacheCheck(ptr, start, limit) { \
uptr diff = ptr - start; \