mirror of https://github.com/PCSX2/pcsx2.git
Minor VU changes... (get interpreter and sVU0 to be able to break execution after X cycles, instead of by hardcoded cycles...)
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2639 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ea766db4ce
commit
3308fa513f
|
@ -206,24 +206,14 @@ void InterpVU0::Step()
|
|||
|
||||
void InterpVU0::Execute(u32 cycles)
|
||||
{
|
||||
for (int i = 128; i--;)
|
||||
{
|
||||
if ((VU0.VI[REG_VPU_STAT].UL & 0x1) == 0)
|
||||
{
|
||||
// Okey.... It apparenly runs an extra instruction on branches or ebits, but
|
||||
// *only* if the microprogram is longer than 128 instructions. This has got
|
||||
// to be some kind of random gamefix hack. --air
|
||||
|
||||
if( (i < 0) && (VU0.branch || VU0.ebit) )
|
||||
{
|
||||
// execute one more
|
||||
vu0Exec(&VU0);
|
||||
for (int i = (int)cycles; i > 0 ; i--) {
|
||||
if (!(VU0.VI[REG_VPU_STAT].UL & 0x1)) {
|
||||
if (VU0.branch || VU0.ebit) {
|
||||
vu0Exec(&VU0); // run branch delay slot?
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vu0Exec(&VU0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -187,24 +187,15 @@ void InterpVU1::Step()
|
|||
vu1Exec( &VU1 );
|
||||
}
|
||||
|
||||
void InterpVU1::Execute(u32 cycles)
|
||||
void InterpVU1::Execute(u32 cycles)
|
||||
{
|
||||
for (int i = 128; i--;)
|
||||
{
|
||||
if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0)
|
||||
{
|
||||
// See VU0Interp's version for details. Or just read the comment below
|
||||
// that simply reads "execute one more" and wonder: Why? Really... WHY?
|
||||
// --air
|
||||
|
||||
if( (i < 0) && (VU1.branch || VU1.ebit) )
|
||||
{
|
||||
// execute one more
|
||||
vu1Exec(&VU1);
|
||||
for (int i = (int)cycles; i > 0 ; i--) {
|
||||
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) {
|
||||
if (VU1.branch || VU1.ebit) {
|
||||
vu1Exec(&VU1); // run branch delay slot?
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vu1Exec(&VU1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ public:
|
|||
Execute(vu0RunCycles); // Kick start VU
|
||||
// If the VU0 program didn't finish then we'll want to finish it up
|
||||
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
|
||||
if(VU0.VI[REG_VPU_STAT].UL & 0x1)
|
||||
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
||||
cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
|
||||
}
|
||||
else {
|
||||
|
@ -133,7 +133,7 @@ public:
|
|||
DevCon.Warning("VU0 running when in BranchTest");
|
||||
// This helps keep the EE and VU0 in sync.
|
||||
// Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
|
||||
if(VU0.VI[REG_VPU_STAT].UL & 0x1)
|
||||
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
||||
cpuSetNextBranchDelta( 768 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ struct microRange {
|
|||
s32 range[mMaxRanges][2];
|
||||
};
|
||||
|
||||
#define mProgSize 0x4000/4
|
||||
#define mProgSize (0x4000/4)
|
||||
struct microProgram {
|
||||
u32 data [mProgSize]; // Holds a copy of the VU microProgram
|
||||
microBlockManager* block[mProgSize/2]; // Array of Block Managers
|
||||
|
@ -122,7 +122,7 @@ struct microProgram {
|
|||
bool isOld; // Program is Old? (Program hasn't been used in a while)
|
||||
};
|
||||
|
||||
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)
|
||||
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember'
|
||||
struct microProgManager {
|
||||
microIR<mProgSize> IRinfo; // IR information
|
||||
microProgram* prog; // Store MicroPrograms in memory
|
||||
|
|
|
@ -50,8 +50,8 @@ extern void iDumpVU1Registers();
|
|||
|
||||
// SuperVURec optimization options, uncomment only for debugging purposes
|
||||
#define SUPERVU_CACHING // vu programs are saved and queried via memcompare (should be no reason to disable this)
|
||||
#define SUPERVU_WRITEBACKS // don't flush the writebacks after every block
|
||||
#define SUPERVU_VIBRANCHDELAY // when integers are modified right before a branch that uses the integer,
|
||||
#define SUPERVU_WRITEBACKS // don't flush the writebacks after every block
|
||||
#define SUPERVU_VIBRANCHDELAY // when integers are modified right before a branch that uses the integer,
|
||||
// the old integer value is used in the branch, fixes kh2
|
||||
|
||||
#define SUPERVU_PROPAGATEFLAGS // the correct behavior of VUs, for some reason superman breaks gfx with it on...
|
||||
|
@ -62,7 +62,7 @@ extern void iDumpVU1Registers();
|
|||
//#define SUPERVU_X86CACHING
|
||||
|
||||
|
||||
// registers won't be flushed at block boundaries (faster) (nothing noticable speed-wise, causes SPS in Ratchet and clank (Nneeve) )
|
||||
// registers won't be flushed at block boundaries (faster) (nothing noticeable speed-wise, causes SPS in Ratchet and clank (Nneeve) )
|
||||
#ifndef PCSX2_DEBUG
|
||||
//#define SUPERVU_INTERCACHING
|
||||
#endif
|
||||
|
@ -104,7 +104,7 @@ extern void (*recVU_LOWER_OPCODE[128])(VURegs* VU, s32 info);
|
|||
|
||||
// Let's tempt fate by defining two different constants with almost identical names
|
||||
#define INST_DUMMY_ 0x8000
|
||||
#define INST_DUMMY 0x83c0
|
||||
#define INST_DUMMY 0x83c0
|
||||
|
||||
#define VFFREE_INVALID0 0x80000000 // (vffree[i]&0xf) is invalid
|
||||
|
||||
|
@ -2869,19 +2869,23 @@ void SuperVUFreeXMMregs(u32* livevars)
|
|||
//_freeXMMregs();
|
||||
}
|
||||
|
||||
static u32 runCycles = 0; // Cycles to Compare to for early exit
|
||||
static u32 backupEAX = 0; // Backup EAX (not sure if this is needed)
|
||||
void SuperVUTestVU0Condition(u32 incstack)
|
||||
{
|
||||
if (s_vu && !SUPERVU_CHECKCONDITION) return; // vu0 only
|
||||
|
||||
// sometimes games spin on vu0, so be careful with this value
|
||||
// woody hangs if too high
|
||||
// sometimes games spin on vu0, so be careful with
|
||||
// runCycles value... woody hangs if too high
|
||||
// Edit: Need to test this again, if anyone ever has a "Woody" game :p
|
||||
CMP32ItoM((uptr)&s_TotalVUCycles, 512*12);
|
||||
|
||||
MOV32RtoM((uptr)&backupEAX, EAX);
|
||||
MOV32MtoR(EAX, (uptr)&s_TotalVUCycles);
|
||||
CMP32MtoR(EAX, (uptr)&runCycles);
|
||||
MOV32MtoR(EAX, (uptr)&backupEAX);
|
||||
|
||||
if (incstack)
|
||||
{
|
||||
u8* ptr = JB8(0);
|
||||
|
||||
ADD32ItoR(ESP, incstack);
|
||||
//CALLFunc((u32)timeout);
|
||||
JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5));
|
||||
|
@ -4634,6 +4638,7 @@ void recSuperVU0::Execute(u32 cycles)
|
|||
if ((VU0.VI[REG_VPU_STAT].UL & 1) == 0) return;
|
||||
|
||||
XMMRegisters::Freeze();
|
||||
runCycles = cycles;
|
||||
SuperVUExecuteProgram(VU0.VI[REG_TPC].UL & 0xfff, 0);
|
||||
XMMRegisters::Thaw();
|
||||
}
|
||||
|
@ -4676,7 +4681,7 @@ void recSuperVU1::Execute(u32 cycles)
|
|||
// [TODO] Debugging pre- and post- hooks?
|
||||
|
||||
XMMRegisters::Freeze();
|
||||
|
||||
|
||||
if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) {
|
||||
Console.Error("VU1 memory overflow!!: %x", VU1.VI[REG_TPC].UL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue