mirror of https://github.com/PCSX2/pcsx2.git
microVU:
- 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:
parent
c3ae30f250
commit
12ca3898d6
|
@ -117,6 +117,7 @@ struct microVU {
|
||||||
u32 code; // Contains the current Instruction
|
u32 code; // Contains the current Instruction
|
||||||
u32 divFlag; // 1 instance of I/D flags
|
u32 divFlag; // 1 instance of I/D flags
|
||||||
u32 VIbackup[2]; // Holds a backup of a VI reg if modified before a branch
|
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 branch; // Holds branch compare result (IBxx) OR Holds address to Jump to (JALR/JR)
|
||||||
u32 p; // Holds current P instance index
|
u32 p; // Holds current P instance index
|
||||||
u32 q; // Holds current Q instance index
|
u32 q; // Holds current Q instance index
|
||||||
|
|
|
@ -354,6 +354,12 @@ microVUt(void) mVUanalyzeXGkick(int Fs, int xCycles) {
|
||||||
analyzeVIreg1(Fs);
|
analyzeVIreg1(Fs);
|
||||||
analyzeXGkick1();
|
analyzeXGkick1();
|
||||||
analyzeXGkick2(xCycles);
|
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.
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -125,8 +125,11 @@ microVUt(void) mVUincCycles(int x) {
|
||||||
calcCycles(mVUregs.p, x);
|
calcCycles(mVUregs.p, x);
|
||||||
if (!mVUregs.p || (mVUregs.p && mVUregsTemp.p)) { incP(); }
|
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.r, x);
|
||||||
calcCycles(mVUregs.xgkick, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
microVUt(void) mVUsetCycles() {
|
microVUt(void) mVUsetCycles() {
|
||||||
|
@ -277,6 +280,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
|
||||||
if (isNOP) { incPC(1); doUpperOp(); doIbit(); }
|
if (isNOP) { incPC(1); doUpperOp(); doIbit(); }
|
||||||
else if (!swapOps) { incPC(1); doUpperOp(); doLowerOp(); }
|
else if (!swapOps) { incPC(1); doUpperOp(); doLowerOp(); }
|
||||||
else { mVUopL<vuIndex, 1>(); incPC(1); doUpperOp(); }
|
else { mVUopL<vuIndex, 1>(); incPC(1); doUpperOp(); }
|
||||||
|
if (doXGKICK) { mVU_XGKICK_DELAY<vuIndex>(); }
|
||||||
|
|
||||||
if (!isBdelay) { incPC(1); }
|
if (!isBdelay) { incPC(1); }
|
||||||
else {
|
else {
|
||||||
|
@ -376,6 +380,7 @@ eBitTemination:
|
||||||
AND32ItoR (flagReg, 0x0fcf);
|
AND32ItoR (flagReg, 0x0fcf);
|
||||||
OR32MtoR (flagReg, (uptr)&mVU->divFlag);
|
OR32MtoR (flagReg, (uptr)&mVU->divFlag);
|
||||||
}
|
}
|
||||||
|
if (doXGKICK) { mVU_XGKICK_DELAY<vuIndex>(); }
|
||||||
|
|
||||||
// Do E-bit end stuff here
|
// Do E-bit end stuff here
|
||||||
mVUsetupRange<vuIndex>(xPC - 8);
|
mVUsetupRange<vuIndex>(xPC - 8);
|
||||||
|
|
|
@ -1113,18 +1113,24 @@ void __fastcall mVU_XGKICK__(u32 addr) {
|
||||||
|
|
||||||
microVUf(void) mVU_XGKICK() {
|
microVUf(void) mVU_XGKICK() {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
pass1 { mVUanalyzeXGkick<vuIndex>(_Is_, 4); }
|
pass1 { mVUanalyzeXGkick<vuIndex>(_Is_, mVU_XGKICK_CYCLES); }
|
||||||
pass2 {
|
pass2 {
|
||||||
mVUprint("XGkick");
|
mVUprint("XGkick");
|
||||||
mVUallocVIa<vuIndex>(gprT2, _Is_); // gprT2 = ECX for __fastcall
|
mVUallocVIa<vuIndex>(gprT1, _Is_);
|
||||||
mVUbackupRegs<vuIndex>();
|
MOV32RtoM((uptr)&mVU->VIxgkick, gprT1);
|
||||||
if (mtgsThread != NULL) CALLFunc((uptr)mVU_XGKICK_);
|
|
||||||
else CALLFunc((uptr)mVU_XGKICK__);
|
|
||||||
mVUrestoreRegs<vuIndex>();
|
|
||||||
}
|
}
|
||||||
pass3 { mVUlog("XGKICK vi%02d", _Fs_); }
|
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
|
// Branches/Jumps
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -191,6 +191,7 @@ declareAllVariables
|
||||||
#define _isEOB (1<<2) // End of Block
|
#define _isEOB (1<<2) // End of Block
|
||||||
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
|
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
|
||||||
#define _isSflag (1<<4) // Cur Instruction uses status flag
|
#define _isSflag (1<<4) // Cur Instruction uses status flag
|
||||||
|
#define _doXGKICK (1<<5) // Do XGKICK transfer on this instruction
|
||||||
#define _writeQ (1<<6)
|
#define _writeQ (1<<6)
|
||||||
#define _readQ (1<<6) // same as writeQ
|
#define _readQ (1<<6) // same as writeQ
|
||||||
#define _writeP (1<<7)
|
#define _writeP (1<<7)
|
||||||
|
@ -222,6 +223,7 @@ declareAllVariables
|
||||||
#define isEOB (mVUinfo & (1<<2))
|
#define isEOB (mVUinfo & (1<<2))
|
||||||
#define isBdelay (mVUinfo & (1<<3))
|
#define isBdelay (mVUinfo & (1<<3))
|
||||||
#define isSflag (mVUinfo & (1<<4))
|
#define isSflag (mVUinfo & (1<<4))
|
||||||
|
#define doXGKICK (mVUinfo & (1<<5))
|
||||||
#define readQ ((mVUinfo >> 6) & 1) // same as writeQ
|
#define readQ ((mVUinfo >> 6) & 1) // same as writeQ
|
||||||
#define readP ((mVUinfo >> 7) & 1) // same as writeP
|
#define readP ((mVUinfo >> 7) & 1) // same as writeP
|
||||||
#define writeQ (((mVUinfo >> 6) + 1) & 1)
|
#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_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...)
|
#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
|
// Cache Limit Check
|
||||||
#define mVUcacheCheck(ptr, start, limit) { \
|
#define mVUcacheCheck(ptr, start, limit) { \
|
||||||
uptr diff = ptr - start; \
|
uptr diff = ptr - start; \
|
||||||
|
|
Loading…
Reference in New Issue