mirror of https://github.com/PCSX2/pcsx2.git
Minor vif/vu changes...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2654 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
f8e9b0a5bd
commit
0c8c01494f
|
@ -40,14 +40,17 @@ void vu1ResetRegs()
|
|||
vif1Regs->stat.VEW = false;
|
||||
}
|
||||
|
||||
static int count;
|
||||
|
||||
void __fastcall vu1ExecMicro(u32 addr)
|
||||
{
|
||||
while(VU0.VI[REG_VPU_STAT].UL & 0x100) {
|
||||
void vu1Finish() {
|
||||
while (VU0.VI[REG_VPU_STAT].UL & 0x100) {
|
||||
VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes");
|
||||
CpuVU1->Execute(vu1RunCycles);
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall vu1ExecMicro(u32 addr)
|
||||
{
|
||||
static int count = 0;
|
||||
vu1Finish();
|
||||
|
||||
VUM_LOG("vu1ExecMicro %x", addr);
|
||||
VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++);
|
||||
|
|
|
@ -294,6 +294,7 @@ extern void vu0Finish();
|
|||
extern void recResetVU0( void );
|
||||
|
||||
// VU1
|
||||
extern void vu1Finish();
|
||||
extern void vu1ResetRegs();
|
||||
extern void __fastcall vu1ExecMicro(u32 addr);
|
||||
extern void vu1Exec(VURegs* VU);
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
#include "VUmicro.h"
|
||||
#include "newVif.h"
|
||||
|
||||
__forceinline void vif0FLUSH()
|
||||
// Run VU0 until finish, don't add cycles to EE
|
||||
// because its vif stalling not the EE core...
|
||||
__forceinline void vif0FLUSH()
|
||||
{
|
||||
if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return;
|
||||
int _cycles = VU0.cycle;
|
||||
// Run VU0 until finish, don't add cycles to EE
|
||||
// because its vif stalling not the EE core...
|
||||
vu0Finish();
|
||||
g_vifCycles += (VU0.cycle - _cycles) * BIAS;
|
||||
}
|
||||
|
|
|
@ -21,17 +21,12 @@
|
|||
#include "VUmicro.h"
|
||||
#include "newVif.h"
|
||||
|
||||
__forceinline void vif1FLUSH()
|
||||
__forceinline void vif1FLUSH()
|
||||
{
|
||||
if (VU0.VI[REG_VPU_STAT].UL & 0x100)
|
||||
{
|
||||
int _cycles = VU1.cycle;
|
||||
|
||||
do { CpuVU1->Execute(vu1RunCycles); }
|
||||
while (VU0.VI[REG_VPU_STAT].UL & 0x100);
|
||||
|
||||
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
|
||||
}
|
||||
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100)) return;
|
||||
int _cycles = VU1.cycle;
|
||||
vu1Finish();
|
||||
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
|
||||
}
|
||||
|
||||
void vif1TransferFromMemory()
|
||||
|
|
|
@ -184,8 +184,7 @@ _mVUt _f void mVUclearProg(int progIndex) {
|
|||
microProgram& program = mVU->prog.prog[progIndex];
|
||||
|
||||
program.used = 0;
|
||||
program.isDead = 1;
|
||||
program.isOld = 1;
|
||||
program.age = isDead;
|
||||
program.frame = mVU->prog.curFrame;
|
||||
for (int j = 0; j <= program.ranges.max; j++) {
|
||||
program.ranges.range[j][0] = -1; // Set range to
|
||||
|
@ -209,7 +208,7 @@ _mVUt _f void mVUcacheProg(int progIndex) {
|
|||
_f void mVUsortProg(mV, int progIndex) {
|
||||
int* temp = new int[mVU->prog.max+1];
|
||||
int offset = 0;
|
||||
for (int i = 0; i <= (mVU->prog.max-1); i++) {
|
||||
for (int i = 0; i <=(mVU->prog.max-1); i++) {
|
||||
if (progIndex == mVU->prog.progList[i]) offset = 1;
|
||||
temp[i+1] = mVU->prog.progList[i+offset];
|
||||
}
|
||||
|
@ -223,14 +222,13 @@ _mVUt _f int mVUfindLeastUsedProg() {
|
|||
microVU* mVU = mVUx;
|
||||
|
||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||
if (mVU->prog.prog[i].isDead) {
|
||||
if (mVU->prog.prog[i].age == isDead) {
|
||||
mVU->prog.total++;
|
||||
mVUcacheProg<vuIndex>(i); // Cache Micro Program
|
||||
mVU->prog.prog[i].isDead = 0;
|
||||
mVU->prog.prog[i].isOld = 0;
|
||||
mVU->prog.prog[i].used = 1;
|
||||
mVU->prog.prog[i].age = isYoung;
|
||||
mVU->prog.prog[i].used = 1;
|
||||
mVUsortProg(mVU, i);
|
||||
Console.WriteLn( Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, i+1, mVU->prog.total+1);
|
||||
Console.WriteLn(Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, i+1, mVU->prog.total+1);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -243,31 +241,32 @@ _mVUt _f int mVUfindLeastUsedProg() {
|
|||
}
|
||||
mVU->prog.total -= ((mVU->prog.max+1)/4)-1;
|
||||
mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program
|
||||
mVU->prog.prog[pIdx].isDead = 0;
|
||||
mVU->prog.prog[pIdx].isOld = 0;
|
||||
mVU->prog.prog[pIdx].used = 1;
|
||||
mVU->prog.prog[pIdx].age = isYoung;
|
||||
mVU->prog.prog[pIdx].used = 1;
|
||||
mVUsortProg(mVU, pIdx);
|
||||
Console.WriteLn( Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, pIdx+1, mVU->prog.total+1);
|
||||
Console.WriteLn(Color_Orange, "microVU%d: Cached MicroPrograms = [%03d] [%03d]", vuIndex, pIdx+1, mVU->prog.total+1);
|
||||
return pIdx;
|
||||
}
|
||||
|
||||
// Finds and Ages/Kills Programs if they haven't been used in a while.
|
||||
_f void mVUvsyncUpdate(mV) {
|
||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||
if (mVU->prog.prog[i].isDead) continue;
|
||||
if (mVU->prog.prog[i].age == isDead) continue;
|
||||
if (mVU->prog.prog[i].used) {
|
||||
mVU->prog.prog[i].used = 0;
|
||||
mVU->prog.prog[i].frame = mVU->prog.curFrame;
|
||||
}
|
||||
else if (((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (360 * 10)) && (i != mVU->prog.cur)) {
|
||||
mVU->prog.total--;
|
||||
if (!mVU->index) mVUclearProg<0>(i);
|
||||
else mVUclearProg<1>(i);
|
||||
DevCon.WriteLn("microVU%d: Killing Dead Program [%03d]", mVU->index, i+1);
|
||||
}
|
||||
else if (((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (30 * 1)) && !mVU->prog.prog[i].isOld) {
|
||||
mVU->prog.prog[i].isOld = 1;
|
||||
//DevCon.Status("microVU%d: Aging Old Program [%03d]", mVU->index, i+1);
|
||||
else { // Age Micro Program that wasn't used
|
||||
s32 diff = mVU->prog.curFrame - mVU->prog.prog[i].frame;
|
||||
if (diff >= (360 * 10)) {
|
||||
if (i == mVU->prog.cur) continue; // Don't Age/Kill last used program
|
||||
mVU->prog.total--;
|
||||
if (!mVU->index) mVUclearProg<0>(i);
|
||||
else mVUclearProg<1>(i);
|
||||
DevCon.WriteLn("microVU%d: Killing Dead Program [%03d]", mVU->index, i+1);
|
||||
}
|
||||
elif(diff >= (60 * 1)) { mVU->prog.prog[i].age = isOld; }
|
||||
elif(diff >= (20 * 1)) { mVU->prog.prog[i].age = isAged; }
|
||||
}
|
||||
}
|
||||
mVU->prog.curFrame++;
|
||||
|
@ -286,16 +285,16 @@ _mVUt _f bool mVUcmpPartial(int progIndex) {
|
|||
}
|
||||
|
||||
// Compare Cached microProgram to mVU->regs->Micro
|
||||
_mVUt _f bool mVUcmpProg(int progIndex, const bool checkOld, const bool cmpWholeProg) {
|
||||
microVU* mVU = mVUx;
|
||||
if (!mVUprogI.isDead && (checkOld == mVUprogI.isOld)) {
|
||||
_mVUt _f bool mVUcmpProg(int progIndex, const int checkAge, const bool cmpWholeProg) {
|
||||
microVU* mVU = mVUx;
|
||||
if (checkAge == mVUprogI.age) {
|
||||
if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize))
|
||||
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) {
|
||||
mVU->prog.cur = progIndex;
|
||||
mVU->prog.cleared = 0;
|
||||
mVU->prog.isSame = cmpWholeProg ? 1 : -1;
|
||||
mVU->prog.prog[progIndex].used = 1;
|
||||
mVU->prog.prog[progIndex].isOld = 0;
|
||||
mVU->prog.prog[progIndex].used = 1;
|
||||
mVU->prog.prog[progIndex].age = isYoung;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +310,11 @@ _mVUt _f int mVUsearchProg() {
|
|||
return 1; // Check Young Programs
|
||||
}
|
||||
for (int i = mVU->prog.max; i >= 0; i--) {
|
||||
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 1, 0))
|
||||
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 1, 0))
|
||||
return 1; // Check Aged Programs
|
||||
}
|
||||
for (int i = mVU->prog.max; i >= 0; i--) {
|
||||
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 2, 0))
|
||||
return 1; // Check Old Programs
|
||||
}
|
||||
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
|
||||
|
@ -319,8 +322,8 @@ _mVUt _f int mVUsearchProg() {
|
|||
mVU->prog.isSame = 1;
|
||||
return 0;
|
||||
}
|
||||
mVU->prog.prog[mVU->prog.cur].used = 1;
|
||||
mVU->prog.prog[mVU->prog.cur].isOld = 0;
|
||||
mVU->prog.prog[mVU->prog.cur].used = 1;
|
||||
mVU->prog.prog[mVU->prog.cur].age = isYoung;
|
||||
return 1; // If !cleared, then we're still on the same program as last-time ;)
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,13 @@ struct microRange {
|
|||
s32 range[mMaxRanges][2];
|
||||
};
|
||||
|
||||
enum microProgramAge {
|
||||
isYoung = 0,
|
||||
isAged = 1,
|
||||
isOld = 2,
|
||||
isDead = 3
|
||||
};
|
||||
|
||||
#define mProgSize (0x4000/4)
|
||||
struct microProgram {
|
||||
u32 data [mProgSize]; // Holds a copy of the VU microProgram
|
||||
|
@ -118,8 +125,7 @@ struct microProgram {
|
|||
microRange ranges; // The ranges of the microProgram that have already been recompiled
|
||||
u32 frame; // Frame # the program was last used on
|
||||
u32 used; // Program was used this frame?
|
||||
bool isDead; // Program is Dead?
|
||||
bool isOld; // Program is Old? (Program hasn't been used in a while)
|
||||
int age; // Program age... Young, Aged, Old, or Dead...
|
||||
};
|
||||
|
||||
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember'
|
||||
|
|
|
@ -31,9 +31,36 @@
|
|||
// Helper Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Used by checkIfSibling below...
|
||||
bool cmpSibling(mV, int progIndex) {
|
||||
if (mVUprogI.age == isDead) return 0;
|
||||
for (int i = 0; i <= mVUprogI.ranges.total; i++) {
|
||||
if ((mVUprogI.ranges.range[i][0] < 0)
|
||||
|| (mVUprogI.ranges.range[i][1] < 0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, i, mVUprogI.ranges.total); }
|
||||
if (memcmp_mmx(cmpOffset(mVUprogI.data), cmpOffset(mVU->regs->Micro), ((mVUprogI.ranges.range[i][1] + 8) - mVUprogI.ranges.range[i][0]))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Since we use partial-program comparisons to search cached microPrograms,
|
||||
// it is possible that another cached microProgram we have also would've
|
||||
// passed the comparison check. This function checks how often this happens...
|
||||
_f void checkIfSibling(mV) {
|
||||
if (mVU->prog.isSame != -1) return;
|
||||
for (int i = mVU->prog.max; i >= 0; i--) {
|
||||
if (i != mVU->prog.cur && cmpSibling(mVU, i)) {
|
||||
if (mVU->prog.prog[i].block[iPC/2] != NULL) {
|
||||
DevCon.WriteLn("mVU: microProgram Sibling Detected! [%d][%d]", mVU->prog.cur, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by mVUsetupRange
|
||||
_f void mVUcheckIsSame(mV) {
|
||||
|
||||
if (0) checkIfSibling(mVU);
|
||||
if (mVU->prog.isSame == -1) {
|
||||
mVU->prog.isSame = !memcmp_mmx((u8*)mVUcurProg.data, mVU->regs->Micro, mVU->microMemSize);
|
||||
}
|
||||
|
@ -65,7 +92,7 @@ _f void mVUsetupRange(mV, s32 pc, bool isStartPC) {
|
|||
mVUcurProg.ranges.total = 0;
|
||||
mVUrange[0] = 0;
|
||||
mVUrange[1] = mVU->microMemSize - 8;
|
||||
DevCon.WriteLn( Color_StrongBlack, "microVU%d: Prog Range List Full", mVU->index);
|
||||
DevCon.Warning("microVU%d: Prog Range List Full", mVU->index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -100,7 +127,7 @@ _f void mVUsetupRange(mV, s32 pc, bool isStartPC) {
|
|||
mVUcurProg.ranges.total = 0;
|
||||
mVUrange[0] = 0;
|
||||
mVUrange[1] = mVU->microMemSize - 8;
|
||||
DevCon.WriteLn( Color_StrongBlack, "microVU%d: Prog Range List Full", mVU->index);
|
||||
DevCon.Warning("microVU%d: Prog Range List Full", mVU->index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,6 +196,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
|
|||
#define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4))))
|
||||
#define _1mb (0x100000)
|
||||
#define clampE CHECK_VU_EXTRA_OVERFLOW
|
||||
#define elif else if
|
||||
|
||||
// Flag Info
|
||||
#define __Status (mVUregs.needExactMatch & 1)
|
||||
|
|
Loading…
Reference in New Issue