mirror of https://github.com/PCSX2/pcsx2.git
VIF/VU: Fixes for Everblue and Hitman 2 from r5404, details below. Savestate bump needed, sorry. Also fixed a copy/paste bug i noticed along the way in vif0FBRST.
Everblue: Slightly messy fix, not as nice as id hope, but it seems to work, we need to remember VU programs written to the VU so we can check if an unpack is modifying it. This retains the behaviour of the Snowblind engines whilst fixing everblue. Hitman 2: Our vif0/1VUFinish() routing which works in conjunction with the delays wasn't paying attention to if the VIF was stalled or not and reran it before the game wanted it to, now fixed. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5544 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
580f7a2e3d
commit
c30f67b767
|
@ -24,7 +24,7 @@
|
|||
// the lower 16 bit value. IF the change is breaking of all compatibility with old
|
||||
// states, increment the upper 16 bit value, and clear the lower 16 bits to 0.
|
||||
|
||||
static const u32 g_SaveVersion = (0x9A0A << 16) | 0x0000;
|
||||
static const u32 g_SaveVersion = (0x9A0B << 16) | 0x0000;
|
||||
|
||||
// this function is meant to be used in the place of GSfreeze, and provides a safe layer
|
||||
// between the GS saving function and the MTGS's needs. :)
|
||||
|
|
|
@ -98,11 +98,12 @@ __fi void vif0FBRST(u32 value) {
|
|||
psHu64(VIF0_FIFO) = 0;
|
||||
psHu64(VIF0_FIFO + 8) = 0;
|
||||
vif0.vifstalled.enabled = false;
|
||||
vif1.irqoffset.enabled = false;
|
||||
vif0.irqoffset.enabled = false;
|
||||
vif0.inprogress = 0;
|
||||
vif0.cmd = 0;
|
||||
vif0.done = true;
|
||||
vif0ch.chcr.STR = false;
|
||||
vif0.LoadedMicroProgs = 0;
|
||||
vif0Regs.err.reset();
|
||||
vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
|
||||
}
|
||||
|
@ -177,6 +178,7 @@ __fi void vif1FBRST(u32 value) {
|
|||
psHu64(VIF1_FIFO) = 0;
|
||||
psHu64(VIF1_FIFO + 8) = 0;
|
||||
vif1.done = true;
|
||||
vif1.LoadedMicroProgs = 0;
|
||||
vif1ch.chcr.STR = false;
|
||||
|
||||
#if USE_OLD_GIF == 1 // ...
|
||||
|
|
|
@ -162,7 +162,7 @@ __fi void vif0VUFinish()
|
|||
vif0.waitforvu = false;
|
||||
ExecuteVU(0);
|
||||
//Make sure VIF0 isnt already scheduled to spin.
|
||||
if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR == true)
|
||||
if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR == true && !vif0Regs.stat.INT)
|
||||
vif0Interrupt();
|
||||
}
|
||||
//DevCon.Warning("VU0 state cleared");
|
||||
|
|
|
@ -235,7 +235,7 @@ __fi void vif1VUFinish()
|
|||
vif1.waitforvu = false;
|
||||
ExecuteVU(1);
|
||||
//Check if VIF is already scheduled to interrupt, if it's waiting, kick it :P
|
||||
if((cpuRegs.interrupt & (1<<DMAC_VIF1 | 1 << DMAC_MFIFO_VIF)) == 0 && vif1ch.chcr.STR == true)
|
||||
if((cpuRegs.interrupt & (1<<DMAC_VIF1 | 1 << DMAC_MFIFO_VIF)) == 0 && vif1ch.chcr.STR == true && !vif1Regs.stat.INT)
|
||||
{
|
||||
if(dmacRegs.ctrl.MFD == MFD_VIF1)
|
||||
vifMFIFOInterrupt();
|
||||
|
|
|
@ -306,10 +306,30 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) {
|
|||
vifOp(vifCode_MPG) {
|
||||
vifStruct& vifX = GetVifX;
|
||||
pass1 {
|
||||
bool bProgramExists = false;
|
||||
int vifNum = (u8)(vifXRegs.code >> 16);
|
||||
vifX.tag.addr = (u16)(vifXRegs.code << 3) & (idx ? 0x3fff : 0xfff);
|
||||
vifX.tag.size = vifNum ? (vifNum*2) : 512;
|
||||
vifFlush(idx);
|
||||
|
||||
//Make a note of the VU programs we're loading, checked in VIF Unpacks
|
||||
for( u32 i = 0; i < vifX.LoadedMicroProgs; i++ )
|
||||
{
|
||||
if(vifX.MicroProgAddrS[i] == vifX.tag.addr)
|
||||
{
|
||||
bProgramExists = true;
|
||||
vifX.MicroProgAddrS[i] = vifX.tag.addr;
|
||||
vifX.MicroProgAddrE[i] = vifX.tag.addr + (vifX.tag.size * 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(bProgramExists == false)
|
||||
{
|
||||
vifX.MicroProgAddrS[vifX.LoadedMicroProgs] = vifX.tag.addr;
|
||||
vifX.MicroProgAddrE[vifX.LoadedMicroProgs] = vifX.tag.addr + (vifX.tag.size * 4);
|
||||
vifX.LoadedMicroProgs++;
|
||||
}
|
||||
|
||||
if(vifX.vifstalled.enabled == true) return 0;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -93,6 +93,9 @@ struct vifStruct {
|
|||
|
||||
bool queued_program;
|
||||
u32 queued_pc;
|
||||
u32 LoadedMicroProgs; //Note how many microprograms we have on the VU.
|
||||
u32 MicroProgAddrS[100]; //Start Addresses
|
||||
u32 MicroProgAddrE[100]; //End Addresses
|
||||
};
|
||||
|
||||
extern __aligned16 vifStruct vif0, vif1;
|
||||
|
|
|
@ -185,7 +185,7 @@ __aligned16 const UNPACKFUNCTYPE VIFfuncTable[2][3][4 * 4 * 2 * 2] =
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
_vifT void vifUnpackSetup(const u32 *data) {
|
||||
|
||||
bool bModifyingVUProg = false;
|
||||
vifStruct& vifX = GetVifX;
|
||||
|
||||
if ((vifXRegs.cycle.wl == 0) && (vifXRegs.cycle.wl < vifXRegs.cycle.cl)) {
|
||||
|
@ -226,6 +226,25 @@ _vifT void vifUnpackSetup(const u32 *data) {
|
|||
if (idx && ((addr>>15)&1)) addr += vif1Regs.tops;
|
||||
vifX.tag.addr = (addr<<4) & (idx ? 0x3ff0 : 0xff0);
|
||||
|
||||
//The Snowblind Engine modifies VU programs with unpacks (seemingly),
|
||||
//however some games (like everblue) don't like the vu waiting until the
|
||||
//last minute, so as long as the unpack isn't editing a microprogram, we're safe.
|
||||
if(vifX.queued_program == true && vifX.LoadedMicroProgs > 0)
|
||||
{
|
||||
for(u32 i = 0; i < vifX.LoadedMicroProgs; i++)
|
||||
{
|
||||
if(vifX.MicroProgAddrS[i] <= vifX.tag.addr && vifX.MicroProgAddrE[i] > vifX.tag.addr)
|
||||
{
|
||||
bModifyingVUProg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(bModifyingVUProg == false)
|
||||
vifExecQueue(idx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VIF_LOG("Unpack VIF%x, QWC %x tagsize %x", idx, vifNum, vif0.tag.size);
|
||||
|
||||
vifX.cl = 0;
|
||||
|
|
Loading…
Reference in New Issue