Minor vif/vu changes...

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2654 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2010-03-02 04:36:09 +00:00
parent f8e9b0a5bd
commit 0c8c01494f
8 changed files with 90 additions and 53 deletions

View File

@ -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++);

View File

@ -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);

View File

@ -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;
}

View File

@ -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()

View File

@ -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 ;)
}

View File

@ -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'

View File

@ -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);
}
}
}

View File

@ -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)