mirror of https://github.com/PCSX2/pcsx2.git
- Working on getting some old code working again which allows comparison between mVU and sVU program results.
- Have the compiler explicitly pack the VU reg structs since we rely on this. - Various minor changes. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3407 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
b53a92e019
commit
3649a9e226
|
@ -383,6 +383,15 @@ void SysCoreAllocations::SelectCpuProviders() const
|
|||
CpuVU1 = EmuConfig.Cpu.Recompiler.UseMicroVU1 ? (BaseVUmicroCPU*)CpuProviders->microVU1 : (BaseVUmicroCPU*)CpuProviders->superVU1;
|
||||
}
|
||||
|
||||
// This is a semi-hacky function for convenience
|
||||
BaseVUmicroCPU* SysCoreAllocations::getVUprovider(int whichProvider, int vuIndex) const {
|
||||
switch (whichProvider) {
|
||||
case 0: return vuIndex ? (BaseVUmicroCPU*)CpuProviders->interpVU1 : (BaseVUmicroCPU*)CpuProviders->interpVU0;
|
||||
case 1: return vuIndex ? (BaseVUmicroCPU*)CpuProviders->superVU1 : (BaseVUmicroCPU*)CpuProviders->superVU0;
|
||||
case 2: return vuIndex ? (BaseVUmicroCPU*)CpuProviders->microVU1 : (BaseVUmicroCPU*)CpuProviders->microVU0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Resets all PS2 cpu execution caches, which does not affect that actual PS2 state/condition.
|
||||
// This can be called at any time outside the context of a Cpu->Execute() block without
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "CDVD/CDVDaccess.h"
|
||||
|
||||
typedef SafeArray<u8> VmStateBuffer;
|
||||
class BaseVUmicroCPU;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SysCoreAllocations class
|
||||
|
@ -39,6 +40,7 @@ public:
|
|||
virtual ~SysCoreAllocations() throw();
|
||||
|
||||
void SelectCpuProviders() const;
|
||||
BaseVUmicroCPU* getVUprovider(int whichProvider, int vuIndex) const;
|
||||
|
||||
bool HadSomeFailures( const Pcsx2Config::RecompilerOptions& recOpts ) const;
|
||||
|
||||
|
|
15
pcsx2/VU.h
15
pcsx2/VU.h
|
@ -16,6 +16,10 @@
|
|||
#pragma once
|
||||
#include "Vif.h"
|
||||
|
||||
#ifdef _MSC_VER // Most of the structs here should be packed
|
||||
# pragma pack(1)
|
||||
#endif
|
||||
|
||||
enum VURegFlags
|
||||
{
|
||||
REG_STATUS_FLAG = 16,
|
||||
|
@ -62,7 +66,7 @@ union VECTOR {
|
|||
s16 SS[8];
|
||||
u8 UC[16];
|
||||
s8 SC[16];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct REG_VI {
|
||||
union {
|
||||
|
@ -76,7 +80,7 @@ struct REG_VI {
|
|||
};
|
||||
u32 padding[3]; // needs padding to make them 128bit; VU0 maps VU1's VI regs as 128bits to addr 0x4xx0 in
|
||||
// VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes)
|
||||
};
|
||||
} __packed;
|
||||
|
||||
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
||||
#define VUFLAG_MFLAGSET 0x00000002
|
||||
|
@ -152,7 +156,8 @@ struct VURegs {
|
|||
, Micro( NULL )
|
||||
{
|
||||
}
|
||||
};
|
||||
} __packed;
|
||||
|
||||
enum VUPipeState
|
||||
{
|
||||
VUPIPE_NONE = 0,
|
||||
|
@ -177,6 +182,10 @@ struct _VURegsNum {
|
|||
int cycles;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER // Restore to default pack alignment
|
||||
# pragma pack()
|
||||
#endif
|
||||
|
||||
extern VURegs* g_pVU1;
|
||||
extern __aligned16 VURegs VU0;
|
||||
|
||||
|
|
|
@ -671,6 +671,10 @@
|
|||
<Filter
|
||||
Name="Super VU"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\x86\sVU_Compare.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\x86\sVU_Debug.h"
|
||||
>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#if 0
|
||||
#include "Common.h"
|
||||
#include "iR5900.h"
|
||||
#include "VUmicro.h"
|
||||
|
@ -24,8 +24,6 @@
|
|||
|
||||
#define useMVU1 CHECK_MICROVU1
|
||||
|
||||
int mVUdebugNow = 0;
|
||||
|
||||
//#define DEBUG_COMPARE // Run sVU or mVU and print results
|
||||
//#define DEBUG_COMPARE2 // Runs both VU recs and breaks when results differ
|
||||
|
||||
|
@ -285,3 +283,5 @@ namespace VU1micro
|
|||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -114,6 +114,10 @@ _f void mVUreset(mV) {
|
|||
// Clear All Program Data
|
||||
//memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
||||
|
||||
if (IsDevBuild) { // Release builds shouldn't need this
|
||||
memset(mVU->cache, 0xcc, mVU->cacheSize);
|
||||
}
|
||||
|
||||
// Program Variables
|
||||
mVU->prog.cleared = 1;
|
||||
|
@ -163,12 +167,9 @@ void mVUresizeCache(mV, u32 size) {
|
|||
|
||||
if (size >= (u32)mVUcacheMaxSize) {
|
||||
if (mVU->cacheSize==mVUcacheMaxSize) {
|
||||
|
||||
// Crap! We can't grow the rec any larger, so just reset it and start over.
|
||||
// (if we don't reset, the rec will eventually crash)
|
||||
|
||||
// We can't grow the rec any larger, so just reset it and start over.
|
||||
//(if we don't reset, the rec will eventually crash)
|
||||
Console.WriteLn(Color_Magenta, "microVU%d: Cannot grow cache, size limit reached! [%dmb]. Resetting rec.", mVU->index, mVU->cacheSize/_1mb);
|
||||
memset(mVU->cache, 0xcc, mVU->cacheSize);
|
||||
mVUreset(mVU);
|
||||
return;
|
||||
}
|
||||
|
@ -179,7 +180,7 @@ void mVUresizeCache(mV, u32 size) {
|
|||
|
||||
u8* cache = SysMmapEx(NULL, size, 0, (mVU->index ? "Micro VU1 RecCache" : "Micro VU0 RecCache"));
|
||||
if(!cache && !mVU->cache) throw Exception::OutOfMemory( wxsFormat( L"Micro VU%d recompiled code cache", mVU->index) );
|
||||
if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); return; }
|
||||
if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVUreset(mVU); return; }
|
||||
if (mVU->cache) {
|
||||
HostSys::Munmap(mVU->cache, mVU->cacheSize);
|
||||
ProfilerTerminateSource(isVU1?"mVU1 Rec":"mVU0 Rec");
|
||||
|
@ -187,7 +188,6 @@ void mVUresizeCache(mV, u32 size) {
|
|||
|
||||
mVU->cache = cache;
|
||||
mVU->cacheSize = size;
|
||||
memset(mVU->cache, 0xcc, mVU->cacheSize);
|
||||
ProfilerRegisterSource(isVU1?"mVU1 Rec":"mVU0 Rec", mVU->cache, mVU->cacheSize);
|
||||
mVUreset(mVU);
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ extern __aligned16 microVU microVU0;
|
|||
extern __aligned16 microVU microVU1;
|
||||
|
||||
// Debug Helper
|
||||
extern int mVUdebugNow;
|
||||
int mVUdebugNow = 0;
|
||||
|
||||
// Main Functions
|
||||
_f void mVUinit(VURegs*, int);
|
||||
|
|
|
@ -73,7 +73,7 @@ _f void mVUallocSFLAGc(x32 reg, x32 regT, int fInstance)
|
|||
setBitSFLAG(reg, regT, 0x00f0, 0x0080); // SS Bit
|
||||
xAND(regT, 0xffff0000); // DS/DI/OS/US/D/I/O/U Bits
|
||||
xSHR(regT, 14);
|
||||
xOR(reg, regT);
|
||||
xOR (reg, regT);
|
||||
}
|
||||
|
||||
// Denormalizes Status Flag
|
||||
|
@ -149,8 +149,8 @@ _f void mVUallocVIa(mV, x32 GPRreg, int _reg_, bool signext = false)
|
|||
_f void mVUallocVIb(mV, x32 GPRreg, int _reg_)
|
||||
{
|
||||
if (mVUlow.backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch)
|
||||
xMOVZX(edx, ptr16[&mVU->regs->VI[_reg_].UL]);
|
||||
xMOV(ptr32[&mVU->VIbackup], edx);
|
||||
xMOVZX(gprT3, ptr16[&mVU->regs->VI[_reg_].UL]);
|
||||
xMOV (ptr32[&mVU->VIbackup], gprT3);
|
||||
}
|
||||
if (_reg_ == 0) { return; }
|
||||
else if (_reg_ < 16) { xMOV(ptr16[&mVU->regs->VI[_reg_].UL], xRegister16(GPRreg.Id)); }
|
||||
|
|
|
@ -66,7 +66,7 @@ _f void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
|
|||
#if 1 // CHECK_MACROVU0 - Always on now
|
||||
xMOV(ptr32[&mVU->regs->VI[REG_STATUS_FLAG].UL], getFlagReg(fStatus));
|
||||
#else
|
||||
mVUallocSFLAGc(gprT1, fStatus);
|
||||
mVUallocSFLAGc(gprT1, gprT2, fStatus);
|
||||
xMOV(ptr32[&mVU->regs->VI[REG_STATUS_FLAG].UL], gprT1);
|
||||
#endif
|
||||
mVUallocMFLAGa(mVU, gprT1, fMac);
|
||||
|
|
|
@ -134,27 +134,25 @@ void doIbit(mV) {
|
|||
void doSwapOp(mV) {
|
||||
if (mVUinfo.backupVF && !mVUlow.noWriteVF) {
|
||||
DevCon.WriteLn(Color_Green, "microVU%d: Backing Up VF Reg [%04x]", getIndex, xPC);
|
||||
xmm t1 = mVU->regAlloc->allocReg(mVUlow.VF_write.reg);
|
||||
xmm t2 = mVU->regAlloc->allocReg();
|
||||
{
|
||||
xmm t1 = mVU->regAlloc->allocReg(mVUlow.VF_write.reg);
|
||||
xMOVAPS(t2, t1);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
}
|
||||
xMOVAPS(t2, t1);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
|
||||
mVUopL(mVU, 1);
|
||||
{
|
||||
xmm t1 = mVU->regAlloc->allocReg(mVUlow.VF_write.reg, mVUlow.VF_write.reg, 0xf, 0);
|
||||
xXOR.PS(t2, t1);
|
||||
xXOR.PS(t1, t2);
|
||||
xXOR.PS(t2, t1);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
}
|
||||
|
||||
t1 = mVU->regAlloc->allocReg(mVUlow.VF_write.reg, mVUlow.VF_write.reg, 0xf, 0);
|
||||
xXOR.PS(t2, t1);
|
||||
xXOR.PS(t1, t2);
|
||||
xXOR.PS(t2, t1);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
|
||||
incPC(1);
|
||||
doUpperOp();
|
||||
{
|
||||
xmm t1 = mVU->regAlloc->allocReg(-1, mVUlow.VF_write.reg, 0xf);
|
||||
xMOVAPS(t1, t2);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
}
|
||||
|
||||
t1 = mVU->regAlloc->allocReg(-1, mVUlow.VF_write.reg, 0xf);
|
||||
xMOVAPS(t1, t2);
|
||||
mVU->regAlloc->clearNeeded(t1);
|
||||
mVU->regAlloc->clearNeeded(t2);
|
||||
}
|
||||
else { mVUopL(mVU, 1); incPC(1); doUpperOp(); }
|
||||
|
@ -171,7 +169,7 @@ _f void mVUcheckBadOp(mV) {
|
|||
// Prints msg when exiting block early if 1st op was a bad opcode (Dawn of Mana Level 2)
|
||||
_f void handleBadOp(mV, int count) {
|
||||
if (mVUinfo.isBadOp && count == 0) {
|
||||
xMOV(ecx, (uptr)mVU);
|
||||
xMOV(gprT2, (uptr)mVU);
|
||||
if (!isVU1) xCALL(mVUbadOp0);
|
||||
else xCALL(mVUbadOp1);
|
||||
}
|
||||
|
@ -312,21 +310,36 @@ _f void mVUsavePipelineState(microVU* mVU) {
|
|||
}
|
||||
}
|
||||
|
||||
// Prints Start/End PC of blocks executed, for debugging...
|
||||
void mVUdebugPrintBlocks(microVU* mVU, bool isEndPC) {
|
||||
if (mVUdebugNow) {
|
||||
xMOV(gprT2, xPC);
|
||||
if (isEndPC) xCALL(mVUprintPC2);
|
||||
else xCALL(mVUprintPC1);
|
||||
}
|
||||
}
|
||||
|
||||
// Test cycles to see if we need to exit-early...
|
||||
void mVUtestCycles(microVU* mVU) {
|
||||
//u32* vu0jmp;
|
||||
iPC = mVUstartPC;
|
||||
mVUdebugNOW(0);
|
||||
if (doEarlyExit(mVU)) {
|
||||
xCMP(ptr32[&mVU->cycles], 0);
|
||||
xForwardJG32 skip;
|
||||
// FIXME: uh... actually kind of a pain with xForwardJump
|
||||
//if (!isVU1) { TEST32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); vu0jmp = JZ32(0); }
|
||||
xMOV(ecx, (uptr)mVU);
|
||||
if (isVU1) xCALL(mVUwarning1);
|
||||
//else xCALL(mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
|
||||
mVUsavePipelineState(mVU);
|
||||
mVUendProgram(mVU, NULL, 0);
|
||||
//if (!isVU1) vu0jmp.SetTarget();
|
||||
if (isVU0) {
|
||||
// TEST32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET);
|
||||
// xFowardJZ32 vu0jmp;
|
||||
// xMOV(gprT2, (uptr)mVU);
|
||||
// xCALL(mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
|
||||
mVUsavePipelineState(mVU);
|
||||
mVUendProgram(mVU, NULL, 0);
|
||||
// vu0jmp.SetTarget();
|
||||
}
|
||||
else {
|
||||
xMOV(gprT2, (uptr)mVU);
|
||||
xCALL(mVUwarning1);
|
||||
mVUsavePipelineState(mVU);
|
||||
mVUendProgram(mVU, NULL, 0);
|
||||
}
|
||||
skip.SetTarget();
|
||||
}
|
||||
xSUB(ptr32[&mVU->cycles], mVUcycles);
|
||||
|
@ -408,6 +421,7 @@ _r void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) {
|
|||
|
||||
mVUsetFlags(mVU, mFC); // Sets Up Flag instances
|
||||
mVUoptimizePipeState(mVU); // Optimize the End Pipeline State for nicer Block Linking
|
||||
mVUdebugPrintBlocks(mVU,0);// Prints Start/End PC of blocks executed, for debugging...
|
||||
mVUtestCycles(mVU); // Update VU Cycles and Exit Early if Necessary
|
||||
|
||||
// Second Pass
|
||||
|
@ -427,7 +441,7 @@ _r void* mVUcompile(microVU* mVU, u32 startPC, uptr pState) {
|
|||
else if (!mVUinfo.isBdelay) { incPC(1); }
|
||||
else {
|
||||
mVUsetupRange(mVU, xPC, 0);
|
||||
mVUdebugNOW(1);
|
||||
mVUdebugPrintBlocks(mVU,1);
|
||||
incPC(-3); // Go back to branch opcode
|
||||
switch (mVUlow.branch) {
|
||||
case 1: case 2: normBranch(mVU, mFC); return thisPtr; // B/BAL
|
||||
|
|
|
@ -53,11 +53,11 @@ void mVUdispatcherA(mV) {
|
|||
|
||||
xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_MAC_FLAG].UL]);
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU->macFlag[0]], xmmT1);
|
||||
xMOVAPS(ptr128[mVU->macFlag], xmmT1);
|
||||
|
||||
xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_CLIP_FLAG].UL]);
|
||||
xSHUF.PS(xmmT1, xmmT1, 0);
|
||||
xMOVAPS(ptr128[&mVU->clipFlag[0]], xmmT1);
|
||||
xMOVAPS(ptr128[mVU->clipFlag], xmmT1);
|
||||
|
||||
xMOVAPS(xmmT1, ptr128[&mVU->regs->VI[REG_P].UL]);
|
||||
xMOVAPS(xmmPQ, ptr128[&mVU->regs->VI[REG_Q].UL]);
|
||||
|
|
|
@ -178,17 +178,17 @@ _f void mVUsetupFlags(mV, microFlagCycles& mFC) {
|
|||
xMOV(gprF[3], getFlagReg(bStatus[3]));
|
||||
}
|
||||
else if (sortRegs == 2) {
|
||||
xMOV(gprT1, getFlagReg(bStatus[3]));
|
||||
xMOV(gprF[0], getFlagReg(bStatus[0]));
|
||||
xMOV(gprT1, getFlagReg (bStatus[3]));
|
||||
xMOV(gprF[0], getFlagReg (bStatus[0]));
|
||||
xMOV(gprF[1], getFlagReg2(bStatus[1]));
|
||||
xMOV(gprF[2], getFlagReg2(bStatus[2]));
|
||||
xMOV(gprF[3], gprT1);
|
||||
}
|
||||
else if (sortRegs == 3) {
|
||||
int gFlag = (bStatus[0] == bStatus[1]) ? bStatus[2] : bStatus[1];
|
||||
xMOV(gprT1, getFlagReg(gFlag));
|
||||
xMOV(gprT2, getFlagReg(bStatus[3]));
|
||||
xMOV(gprF[0], getFlagReg(bStatus[0]));
|
||||
xMOV(gprT1, getFlagReg (gFlag));
|
||||
xMOV(gprT2, getFlagReg (bStatus[3]));
|
||||
xMOV(gprF[0], getFlagReg (bStatus[0]));
|
||||
xMOV(gprF[1], getFlagReg3(bStatus[1]));
|
||||
xMOV(gprF[2], getFlagReg4(bStatus[2]));
|
||||
xMOV(gprF[3], gprT2);
|
||||
|
|
|
@ -255,8 +255,8 @@ void COP2_Interlock(bool mBitSync) {
|
|||
void TEST_FBRST_RESET(FnType_Void* resetFunct, int vuIndex) {
|
||||
xTEST(eax, (vuIndex) ? 0x200 : 0x002);
|
||||
xForwardJZ8 skip;
|
||||
xCALL(resetFunct);
|
||||
xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
|
||||
xCALL(resetFunct);
|
||||
xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
|
||||
skip.SetTarget();
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef xRegister32 x32;
|
|||
|
||||
#define isCOP2 (mVU->cop2 != 0)
|
||||
#define isVU1 (mVU->index != 0)
|
||||
#define isVU0 (mVU->index == 0)
|
||||
#define getIndex (isVU1 ? 1 : 0)
|
||||
#define getVUmem(x) (((isVU1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16)
|
||||
#define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12)))
|
||||
|
@ -296,14 +297,6 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
|
|||
} \
|
||||
}
|
||||
|
||||
#define mVUdebugNOW(isEndPC) { \
|
||||
if (mVUdebugNow) { \
|
||||
xMOV(gprT2, xPC); \
|
||||
if (isEndPC) { xCALL(mVUprintPC2); } \
|
||||
else { xCALL(mVUprintPC1); } \
|
||||
} \
|
||||
}
|
||||
|
||||
void mVUmergeRegs(xmm dest, xmm src, int xyzw, bool modXYZW=false);
|
||||
void mVUsaveReg(xmm reg, xAddressVoid ptr, int xyzw, bool modXYZW);
|
||||
void mVUloadReg(xmm reg, xAddressVoid ptr, int xyzw);
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
void mVUunpack_xyzw(xmm dstreg, xmm srcreg, int xyzw)
|
||||
{
|
||||
switch ( xyzw ) {
|
||||
case 0: xPSHUF.D(dstreg, srcreg, 0x00); break;
|
||||
case 1: xPSHUF.D(dstreg, srcreg, 0x55); break;
|
||||
case 2: xPSHUF.D(dstreg, srcreg, 0xaa); break;
|
||||
case 3: xPSHUF.D(dstreg, srcreg, 0xff); break;
|
||||
case 0: xPSHUF.D(dstreg, srcreg, 0x00); break; // XXXX
|
||||
case 1: xPSHUF.D(dstreg, srcreg, 0x55); break; // YYYY
|
||||
case 2: xPSHUF.D(dstreg, srcreg, 0xaa); break; // ZZZZ
|
||||
case 3: xPSHUF.D(dstreg, srcreg, 0xff); break; // WWWW
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ void mVUloadReg(xmm reg, xAddressVoid ptr, int xyzw)
|
|||
case 4: xMOVSSZX(reg, ptr32[ptr+4]); break; // Y
|
||||
case 2: xMOVSSZX(reg, ptr32[ptr+8]); break; // Z
|
||||
case 1: xMOVSSZX(reg, ptr32[ptr+12]); break; // W
|
||||
default: xMOVAPS(reg, ptr128[ptr]); break;
|
||||
default: xMOVAPS (reg, ptr128[ptr]); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,10 +135,10 @@ void mVUsaveReg(xmm reg, xAddressVoid ptr, int xyzw, bool modXYZW)
|
|||
case 1: if (!modXYZW) mVUunpack_xyzw(reg, reg, 3);
|
||||
xMOVSS(ptr32[ptr+12], reg);
|
||||
break; // W
|
||||
case 8: xMOVSS(ptr32[ptr], reg); break; // X
|
||||
case 12: xMOVL.PS(ptr64[ptr], reg); break; // XY
|
||||
case 3: xMOVH.PS(ptr64[ptr+8], reg); break; // ZW
|
||||
default: xMOVAPS(ptr128[ptr], reg); break; // XYZW
|
||||
case 8: xMOVSS(ptr32[ptr], reg); break; // X
|
||||
case 12: xMOVL.PS(ptr64[ptr], reg); break; // XY
|
||||
case 3: xMOVH.PS(ptr64[ptr+8], reg); break; // ZW
|
||||
default: xMOVAPS(ptr128[ptr], reg); break; // XYZW
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,13 +236,13 @@ _f void mVUaddrFix(mV, x32 gprReg)
|
|||
_f void mVUbackupRegs(microVU* mVU)
|
||||
{
|
||||
mVU->regAlloc->flushAll();
|
||||
xMOVAPS(ptr128[&mVU->xmmPQb[0]], xmmPQ);
|
||||
xMOVAPS(ptr128[mVU->xmmPQb], xmmPQ);
|
||||
}
|
||||
|
||||
// Restore Volatile Regs
|
||||
_f void mVUrestoreRegs(microVU* mVU)
|
||||
{
|
||||
xMOVAPS(xmmPQ, ptr128[&mVU->xmmPQb[0]]);
|
||||
xMOVAPS(xmmPQ, ptr128[mVU->xmmPQb]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -24,29 +24,31 @@
|
|||
#define SHIFT_XYZW(gprReg) { if (_XYZW_SS && modXYZW && !_W) { xSHL(gprReg, ADD_XYZW); } }
|
||||
|
||||
// Note: If modXYZW is true, then it adjusts XYZW for Single Scalar operations
|
||||
static void mVUupdateFlags(mV, xmm reg, xmm regT1in = xEmptyReg, xmm regT2 = xEmptyReg, bool modXYZW = 1) {
|
||||
x32 mReg = gprT1;
|
||||
bool regT2b = false;
|
||||
static void mVUupdateFlags(mV, xmm reg, xmm regT1 = xEmptyReg, xmm regT2 = xEmptyReg, bool modXYZW = 1) {
|
||||
x32 mReg = gprT1, sReg = getFlagReg(sFLAG.write);
|
||||
bool regT1b = false, regT2b = false;
|
||||
static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
|
||||
|
||||
//SysPrintf("Status = %d; Mac = %d\n", sFLAG.doFlag, mFLAG.doFlag);
|
||||
if (!sFLAG.doFlag && !mFLAG.doFlag) { return; }
|
||||
|
||||
xmm regT1 = regT1in.IsEmpty() ? mVU->regAlloc->allocReg() : regT1in;
|
||||
if ((mFLAG.doFlag && !(_XYZW_SS && modXYZW)))
|
||||
{
|
||||
if (regT2.IsEmpty())
|
||||
{
|
||||
regT2 = mVU->regAlloc->allocReg();
|
||||
if (regT1.IsEmpty()) {
|
||||
regT1 = mVU->regAlloc->allocReg();
|
||||
regT1b = true;
|
||||
}
|
||||
|
||||
if ((mFLAG.doFlag && !(_XYZW_SS && modXYZW))) {
|
||||
if (regT2.IsEmpty()) {
|
||||
regT2 = mVU->regAlloc->allocReg();
|
||||
regT2b = true;
|
||||
}
|
||||
xPSHUF.D(regT2, reg, 0x1B); // Flip wzyx to xyzw
|
||||
}
|
||||
else
|
||||
regT2 = reg;
|
||||
else regT2 = reg;
|
||||
|
||||
if (sFLAG.doFlag) {
|
||||
mVUallocSFLAGa(getFlagReg(sFLAG.write), sFLAG.lastWrite); // Get Prev Status Flag
|
||||
if (sFLAG.doNonSticky) xAND(getFlagReg(sFLAG.write), 0xfffc00ff); // Clear O,U,S,Z flags
|
||||
mVUallocSFLAGa(sReg, sFLAG.lastWrite); // Get Prev Status Flag
|
||||
if (sFLAG.doNonSticky) xAND(sReg, 0xfffc00ff); // Clear O,U,S,Z flags
|
||||
}
|
||||
|
||||
//-------------------------Check for Signed flags------------------------------
|
||||
|
@ -56,12 +58,12 @@ static void mVUupdateFlags(mV, xmm reg, xmm regT1in = xEmptyReg, xmm regT2 = xEm
|
|||
xCMPEQ.PS(regT1, regT2); // Set all F's if each vector is zero
|
||||
xMOVMSKPS(gprT2, regT1); // Used for Zero Flag Calculation
|
||||
|
||||
xAND(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||
xAND(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||
xSHL(mReg, 4 + ADD_XYZW);
|
||||
|
||||
//-------------------------Check for Zero flags------------------------------
|
||||
|
||||
xAND(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||
xAND(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||
if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); }
|
||||
xOR(mReg, gprT2);
|
||||
|
||||
|
@ -69,13 +71,13 @@ static void mVUupdateFlags(mV, xmm reg, xmm regT1in = xEmptyReg, xmm regT2 = xEm
|
|||
|
||||
if (mFLAG.doFlag) mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag
|
||||
if (sFLAG.doFlag) {
|
||||
xOR(getFlagReg(sFLAG.write), mReg);
|
||||
xOR(sReg, mReg);
|
||||
if (sFLAG.doNonSticky) {
|
||||
xSHL(mReg, 8);
|
||||
xOR(getFlagReg(sFLAG.write), mReg);
|
||||
xOR (sReg, mReg);
|
||||
}
|
||||
}
|
||||
if (regT1 != regT1in) mVU->regAlloc->clearNeeded(regT1);
|
||||
if (regT1b) mVU->regAlloc->clearNeeded(regT1);
|
||||
if (regT2b) mVU->regAlloc->clearNeeded(regT2);
|
||||
}
|
||||
|
||||
|
@ -350,7 +352,7 @@ mVUop(mVU_OPMSUB) {
|
|||
}
|
||||
|
||||
// FTOI0/FTIO4/FTIO12/FTIO15 Opcodes
|
||||
static void mVU_FTOIx(mP, const float (*addr)[4], const char* opName) {
|
||||
static void mVU_FTOIx(mP, const float* addr, const char* opName) {
|
||||
pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); }
|
||||
pass2 {
|
||||
if (!_Ft_) return;
|
||||
|
@ -377,7 +379,7 @@ static void mVU_FTOIx(mP, const float (*addr)[4], const char* opName) {
|
|||
}
|
||||
|
||||
// ITOF0/ITOF4/ITOF12/ITOF15 Opcodes
|
||||
static void mVU_ITOFx(mP, const float (*addr)[4], const char* opName) {
|
||||
static void mVU_ITOFx(mP, const float* addr, const char* opName) {
|
||||
pass1 { mVUanalyzeFMAC2(mVU, _Fs_, _Ft_); }
|
||||
pass2 {
|
||||
if (!_Ft_) return;
|
||||
|
@ -404,9 +406,9 @@ mVUop(mVU_CLIP) {
|
|||
mVUallocCFLAGa(mVU, gprT1, cFLAG.lastWrite);
|
||||
xSHL(gprT1, 6);
|
||||
|
||||
xAND.PS(Ft, ptr128[&mVUglob.absclip[0]]);
|
||||
xAND.PS(Ft, ptr128[mVUglob.absclip]);
|
||||
xMOVAPS(t1, Ft);
|
||||
xPOR(t1, ptr128[&mVUglob.signbit[0]]);
|
||||
xPOR(t1, ptr128[mVUglob.signbit]);
|
||||
|
||||
xCMPNLE.PS(t1, Fs); // -w, -z, -y, -x
|
||||
xCMPLT.PS(Ft, Fs); // +w, +z, +y, +x
|
||||
|
@ -520,11 +522,11 @@ mVUop(mVU_MINIy) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIy", 0); }
|
|||
mVUop(mVU_MINIz) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIz", 0); }
|
||||
mVUop(mVU_MINIw) { mVU_FMACa(mVU, recPass, 2, 4, 0, "MINIw", 0); }
|
||||
mVUop(mVU_FTOI0) { mVU_FTOIx(mX, NULL, "FTOI0"); }
|
||||
mVUop(mVU_FTOI4) { mVU_FTOIx(mX, &mVUglob.FTOI_4, "FTOI4"); }
|
||||
mVUop(mVU_FTOI12) { mVU_FTOIx(mX, &mVUglob.FTOI_12, "FTOI12"); }
|
||||
mVUop(mVU_FTOI15) { mVU_FTOIx(mX, &mVUglob.FTOI_15, "FTOI15"); }
|
||||
mVUop(mVU_FTOI4) { mVU_FTOIx(mX, mVUglob.FTOI_4, "FTOI4"); }
|
||||
mVUop(mVU_FTOI12) { mVU_FTOIx(mX, mVUglob.FTOI_12, "FTOI12"); }
|
||||
mVUop(mVU_FTOI15) { mVU_FTOIx(mX, mVUglob.FTOI_15, "FTOI15"); }
|
||||
mVUop(mVU_ITOF0) { mVU_ITOFx(mX, NULL, "ITOF0"); }
|
||||
mVUop(mVU_ITOF4) { mVU_ITOFx(mX, &mVUglob.ITOF_4, "ITOF4"); }
|
||||
mVUop(mVU_ITOF12) { mVU_ITOFx(mX, &mVUglob.ITOF_12, "ITOF12"); }
|
||||
mVUop(mVU_ITOF15) { mVU_ITOFx(mX, &mVUglob.ITOF_15, "ITOF15"); }
|
||||
mVUop(mVU_ITOF4) { mVU_ITOFx(mX, mVUglob.ITOF_4, "ITOF4"); }
|
||||
mVUop(mVU_ITOF12) { mVU_ITOFx(mX, mVUglob.ITOF_12, "ITOF12"); }
|
||||
mVUop(mVU_ITOF15) { mVU_ITOFx(mX, mVUglob.ITOF_15, "ITOF15"); }
|
||||
mVUop(mVU_NOP) { pass3 { mVUlog("NOP"); } }
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
extern BaseVUmicroCPU* getVUprovider(int whichProvider, int vuIndex);
|
||||
SysCoreAllocations& GetSysCoreAlloc();
|
||||
|
||||
void runSVU1(u32 cycles) {
|
||||
do { // while loop needed since not always will return finished
|
||||
SuperVUExecuteProgram(VU1.VI[REG_TPC].UL & 0x3ff8, 1);
|
||||
} while( VU0.VI[REG_VPU_STAT].UL&0x100 );
|
||||
}
|
||||
void runMVU1(u32 cycles) {
|
||||
GetSysCoreAlloc().getVUprovider(2, 1)->Execute(cycles);
|
||||
}
|
||||
void clearSVU1(u32 Addr, u32 Size) {
|
||||
SuperVUClear(Addr, Size, 1);
|
||||
}
|
||||
void clearMVU1(u32 Addr, u32 Size) {
|
||||
GetSysCoreAlloc().getVUprovider(2, 1)->Clear(Addr, Size);
|
||||
}
|
||||
void recSuperVU1::Clear(u32 Addr, u32 Size) {
|
||||
clearSVU1(Addr, Size);
|
||||
clearMVU1(Addr, Size);
|
||||
}
|
||||
void resetSVU1() {
|
||||
GetSysCoreAlloc().getVUprovider(1, 1)->Reset();
|
||||
}
|
||||
void resetMVU1() {
|
||||
GetSysCoreAlloc().getVUprovider(2, 1)->Reset();
|
||||
}
|
||||
|
||||
|
||||
extern int mVUdebugNow;
|
||||
static u32 runCount = 0;
|
||||
__aligned16 u8 backVUregs[sizeof(VURegs)];
|
||||
__aligned16 u8 cmpVUregs [sizeof(VURegs)];
|
||||
__aligned16 u8 backVUmem [0x4000];
|
||||
__aligned16 u8 cmpVUmem [0x4000];
|
||||
|
||||
#define VU3 (*(VURegs*)cmpVUregs)
|
||||
#define fABS(aInt) (aInt & 0x7fffffff)
|
||||
//#define cmpU(uA, uB) (fABS(uA) != fABS(uB))
|
||||
#define cmpU(uA, uB) (uA != uB)
|
||||
#define cmpA Console.Error
|
||||
#define cmpB Console.WriteLn
|
||||
#define cmpPrint(cond) { \
|
||||
if (cond) { \
|
||||
cmpA("%s", str1); \
|
||||
cmpA("%s", str2); \
|
||||
/*mVUdebugNow = 1;*/\
|
||||
} \
|
||||
else { \
|
||||
cmpB("%s", str1); \
|
||||
cmpB("%s", str2); \
|
||||
} \
|
||||
}
|
||||
|
||||
//#define DEBUG_COMPARE // Run sVU or mVU and print results
|
||||
//#define DEBUG_COMPARE2 // Runs both VU recs and breaks when results differ
|
||||
|
||||
#ifdef DEBUG_COMPARE
|
||||
|
||||
static int runAmount = 0;
|
||||
|
||||
void VUtestPause() {
|
||||
|
||||
runAmount++;
|
||||
if (runAmount < 654) return;
|
||||
|
||||
if (useMVU1) SysPrintf("Micro VU - Pass %d\n", runAmount);
|
||||
else SysPrintf("Super VU - Pass %d\n", runAmount);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
SysPrintf("VF%02d = {%f, %f, %f, %f}\n", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
|
||||
}
|
||||
|
||||
SysPrintf("ACC = {%f, %f, %f, %f}\n", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
SysPrintf("VI%02d = % 8d ($%08x)\n", i, (s16)VU1.VI[i].UL, (s16)VU1.VI[i].UL);
|
||||
}
|
||||
|
||||
SysPrintf("Stat = % 8d ($%08x)\n", (s16)VU1.VI[REG_STATUS_FLAG].UL, (s16)VU1.VI[REG_STATUS_FLAG].UL);
|
||||
SysPrintf("MAC = % 8d ($%08x)\n", (s16)VU1.VI[REG_MAC_FLAG].UL, (s16)VU1.VI[REG_MAC_FLAG].UL);
|
||||
SysPrintf("CLIP = % 8d ($%08x)\n", (s16)VU1.VI[REG_CLIP_FLAG].UL, (s16)VU1.VI[REG_CLIP_FLAG].UL);
|
||||
|
||||
SysPrintf("Q-reg = %f ($%08x)\n", VU1.VI[REG_Q].F, (s32)VU1.VI[REG_Q].UL);
|
||||
SysPrintf("P-reg = %f ($%08x)\n", VU1.VI[REG_P].F, (s32)VU1.VI[REG_P].UL);
|
||||
SysPrintf("I-reg = %f ($%08x)\n", VU1.VI[REG_I].F, (s32)VU1.VI[REG_I].UL);
|
||||
|
||||
SysPrintf("_Stat = % 8d ($%08x)\n", (s16)VU1.statusflag, (s16)VU1.statusflag);
|
||||
SysPrintf("_MAC = % 8d ($%08x)\n", (s16)VU1.macflag, (s16)VU1.macflag);
|
||||
SysPrintf("_CLIP = % 8d ($%08x)\n", (s16)VU1.clipflag, (s16)VU1.clipflag);
|
||||
|
||||
u32 j = 0;
|
||||
for (int i = 0; i < (0x4000 / 4); i++) {
|
||||
j ^= ((u32*)(VU1.Mem))[i];
|
||||
}
|
||||
SysPrintf("VU Mem CRC = 0x%08x\n", j);
|
||||
SysPrintf("EndPC = 0x%04x\n", VU1.VI[REG_TPC].UL);
|
||||
|
||||
// ... wtf?? --air
|
||||
for (int i = 0; i < 10000000; i++) {
|
||||
Threading::Sleep(1000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void VUtestPause() {}
|
||||
#endif
|
||||
|
||||
void recSuperVU1::Execute(u32 cycles) {
|
||||
cycles = 0x7fffffff;
|
||||
if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return;
|
||||
if (VU1.VI[REG_TPC].UL >= VU1.maxmicro) { Console.Error("VU1 memory overflow!!: %x", VU1.VI[REG_TPC].UL); }
|
||||
|
||||
#ifdef DEBUG_COMPARE
|
||||
SysPrintf("(%08d) StartPC = 0x%04x\n", runAmount, VU1.VI[REG_TPC].UL);
|
||||
#endif
|
||||
|
||||
runCount++;
|
||||
memcpy_const((u8*)backVUregs, (u8*)&VU1, sizeof(VURegs));
|
||||
memcpy_const((u8*)backVUmem, (u8*) VU1.Mem, 0x4000);
|
||||
|
||||
runMVU1(cycles);
|
||||
|
||||
memcpy_const((u8*)cmpVUregs,(u8*)&VU1, sizeof(VURegs));
|
||||
memcpy_const((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000);
|
||||
memcpy_const((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
|
||||
memcpy_const((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
|
||||
|
||||
runSVU1(cycles);
|
||||
if ((memcmp((u8*)cmpVUregs, (u8*)&VU1, (16*32) + (16*16))) || (memcmp((u8*)cmpVUmem, (u8*)VU1.Mem, 0x4000))) {
|
||||
static char str1[1000];
|
||||
static char str2[1000];
|
||||
Console.WriteLn("\n\n");
|
||||
Console.WriteLn("-----------------------------------------------\n");
|
||||
Console.Warning("Problem Occurred!");
|
||||
Console.WriteLn("-----------------------------------------------\n");
|
||||
Console.WriteLn("runCount = %d\n", runCount);
|
||||
Console.WriteLn("StartPC [%04x]\n", ((VURegs*)backVUregs)->VI[REG_TPC].UL);
|
||||
Console.WriteLn("-----------------------------------------------\n\n");
|
||||
|
||||
Console.WriteLn("-----------------------------------------------\n");
|
||||
Console.Warning("Micro VU / Super VU");
|
||||
Console.WriteLn("-----------------------------------------------\n");
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
sprintf(str1, "VF%02d = {%f, %f, %f, %f}", i, VU3.VF[i].F[0], VU3.VF[i].F[1], VU3.VF[i].F[2], VU3.VF[i].F[3]);
|
||||
sprintf(str2, "VF%02d = {%f, %f, %f, %f}", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
|
||||
cmpPrint((cmpU(VU1.VF[i].UL[0], VU3.VF[i].UL[0]) || cmpU(VU1.VF[i].UL[1], VU3.VF[i].UL[1]) || cmpU(VU1.VF[i].UL[2], VU3.VF[i].UL[2]) || cmpU(VU1.VF[i].UL[3], VU3.VF[i].UL[3])));
|
||||
}
|
||||
|
||||
sprintf(str1, "ACC = {%f, %f, %f, %f}", VU3.ACC.F[0], VU3.ACC.F[1], VU3.ACC.F[2], VU3.ACC.F[3]);
|
||||
sprintf(str2, "ACC = {%f, %f, %f, %f}", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]);
|
||||
cmpPrint((cmpU(VU1.ACC.UL[0], VU3.ACC.UL[0]) || cmpU(VU1.ACC.UL[1], VU3.ACC.UL[1]) || cmpU(VU1.ACC.UL[2], VU3.ACC.UL[2]) || cmpU(VU1.ACC.UL[3], VU3.ACC.UL[3])));
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
sprintf(str1, "VI%02d = % 8d ($%08x)", i, (s16)VU3.VI[i].UL, VU3.VI[i].UL);
|
||||
sprintf(str2, "VI%02d = % 8d ($%08x)", i, (s16)VU1.VI[i].UL, VU1.VI[i].UL);
|
||||
cmpPrint((VU1.VI[i].UL != VU3.VI[i].UL));
|
||||
}
|
||||
|
||||
sprintf(str1, "Stat = % 8d ($%08x)", (s16)VU3.VI[REG_STATUS_FLAG].UL, VU3.VI[REG_STATUS_FLAG].UL);
|
||||
sprintf(str2, "Stat = % 8d ($%08x)", (s16)VU1.VI[REG_STATUS_FLAG].UL, VU1.VI[REG_STATUS_FLAG].UL);
|
||||
cmpPrint((VU1.VI[REG_STATUS_FLAG].UL != VU3.VI[REG_STATUS_FLAG].UL));
|
||||
|
||||
sprintf(str1, "MAC = % 8d ($%08x)", (s16)VU3.VI[REG_MAC_FLAG].UL, VU3.VI[REG_MAC_FLAG].UL);
|
||||
sprintf(str2, "MAC = % 8d ($%08x)", (s16)VU1.VI[REG_MAC_FLAG].UL, VU1.VI[REG_MAC_FLAG].UL);
|
||||
cmpPrint((VU1.VI[REG_MAC_FLAG].UL != VU3.VI[REG_MAC_FLAG].UL));
|
||||
|
||||
sprintf(str1, "CLIP = % 8d ($%08x)", (s16)VU3.VI[REG_CLIP_FLAG].UL, VU3.VI[REG_CLIP_FLAG].UL);
|
||||
sprintf(str2, "CLIP = % 8d ($%08x)", (s16)VU1.VI[REG_CLIP_FLAG].UL, VU1.VI[REG_CLIP_FLAG].UL);
|
||||
cmpPrint((VU1.VI[REG_CLIP_FLAG].UL != VU3.VI[REG_CLIP_FLAG].UL));
|
||||
|
||||
sprintf(str1, "Q-reg = %f ($%08x)", VU3.VI[REG_Q].F, VU3.VI[REG_Q].UL);
|
||||
sprintf(str2, "Q-reg = %f ($%08x)", VU1.VI[REG_Q].F, VU1.VI[REG_Q].UL);
|
||||
cmpPrint((VU1.VI[REG_Q].UL != VU3.VI[REG_Q].UL));
|
||||
|
||||
sprintf(str1, "P-reg = %f ($%08x)", VU3.VI[REG_P].F, VU3.VI[REG_P].UL);
|
||||
sprintf(str2, "P-reg = %f ($%08x)", VU1.VI[REG_P].F, VU1.VI[REG_P].UL);
|
||||
cmpPrint((VU1.VI[REG_P].UL != VU3.VI[REG_P].UL));
|
||||
|
||||
sprintf(str1, "I-reg = %f ($%08x)", VU3.VI[REG_I].F, VU3.VI[REG_I].UL);
|
||||
sprintf(str2, "I-reg = %f ($%08x)", VU1.VI[REG_I].F, VU1.VI[REG_I].UL);
|
||||
cmpPrint((VU1.VI[REG_I].UL != VU3.VI[REG_I].UL));
|
||||
|
||||
sprintf(str1, "_Stat = % 8d ($%08x)", (s16)VU3.statusflag, VU3.statusflag);
|
||||
sprintf(str2, "_Stat = % 8d ($%08x)", (s16)VU1.statusflag, VU1.statusflag);
|
||||
cmpPrint((VU1.statusflag != VU3.statusflag));
|
||||
|
||||
sprintf(str1, "_MAC = % 8d ($%08x)", (s16)VU3.macflag, VU3.macflag);
|
||||
sprintf(str2, "_MAC = % 8d ($%08x)", (s16)VU1.macflag, VU1.macflag);
|
||||
cmpPrint((VU1.macflag != VU3.macflag));
|
||||
|
||||
sprintf(str1, "_CLIP = % 8d ($%08x)", (s16)VU3.clipflag, VU3.clipflag);
|
||||
sprintf(str2, "_CLIP = % 8d ($%08x)", (s16)VU1.clipflag, VU1.clipflag);
|
||||
cmpPrint((VU1.clipflag != VU3.clipflag));
|
||||
|
||||
u32 j = 0;
|
||||
u32 z = 0;
|
||||
for (int i = 0; i < (0x4000 / 4); i++) {
|
||||
j ^= ((u32*)(cmpVUmem))[i];
|
||||
z ^= ((u32*)(VU1.Mem)) [i];
|
||||
}
|
||||
sprintf(str1, "VU Mem CRC = 0x%08x", j);
|
||||
sprintf(str2, "VU Mem CRC = 0x%08x", z);
|
||||
cmpPrint((j != z));
|
||||
|
||||
sprintf(str1, "EndPC = 0x%04x", VU3.VI[REG_TPC].UL);
|
||||
sprintf(str2, "EndPC = 0x%04x", VU1.VI[REG_TPC].UL);
|
||||
cmpPrint((VU1.VI[REG_TPC].UL != VU3.VI[REG_TPC].UL));
|
||||
|
||||
Console.WriteLn("-----------------------------------------------\n\n");
|
||||
|
||||
/*
|
||||
if (mVUdebugNow) {
|
||||
|
||||
resetMVU1();
|
||||
|
||||
memcpy_const((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
|
||||
memcpy_const((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
|
||||
|
||||
runMVU1(cycles);
|
||||
|
||||
for (int i = 0; i < 10000000; i++) {
|
||||
Sleep(1000);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
//VUtestPause();
|
||||
}
|
|
@ -4670,6 +4670,9 @@ void recSuperVU1::Reset()
|
|||
SuperVUReset( 1 );
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "sVU_Compare.h"
|
||||
#else
|
||||
void recSuperVU1::Execute(u32 cycles)
|
||||
{
|
||||
if ((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0) return;
|
||||
|
@ -4690,3 +4693,4 @@ void recSuperVU1::Clear(u32 Addr, u32 Size)
|
|||
{
|
||||
SuperVUClear(Addr, Size, 1);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue