Game fixes:

- Batman Returns Issue 709 . 
- Fixed flashing in Sega Superstars Tennis. 
- Clawed back some of the speed loss from the XGKick delays.

Detailed changes:
- CALL Tag DMAs that contain invalid next tag addresses ignore the call (Batman started sending corrupt information from invalid addresses)
- VU1 now flushes any pending transfers if it's trying to send another and doesnt process any packed/list regs
- Batman was checking for OPH to be high, this was a timing thing, something id completely got rid of accidently (same for APATH)
- XGKick will no longer queue if PATH3 is interrupted

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3285 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
refraction 2010-06-24 14:55:57 +00:00
parent 85e061d4fb
commit b911ce1443
11 changed files with 83 additions and 43 deletions

View File

@ -670,6 +670,7 @@ static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write)
if (addr < Ps2MemSize::Base)
{
if(addr == 0) return NULL;
return (tDMA_TAG*)&psM[addr];
}

View File

@ -162,6 +162,11 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
if(vif1.irqoffset != 0 && vif1.vifstalled == true) DevCon.Warning("Offset on VIF1 FIFO start!");
bool ret = VIF1transfer((u32*)value, 4);
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
{
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
if (vif1.cmd)
{
if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING;
@ -190,17 +195,15 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
nloop0_packet[2] = psHu32(GIF_FIFO + 8);
nloop0_packet[3] = psHu32(GIF_FIFO + 12);
Registers::Freeze();
gifRegs->stat.APATH = GIF_APATH3;
GetMTGS().PrepDataPacket(GIF_PATH_3, nloop0_packet, 1);
u64* data = (u64*)GetMTGS().GetDataPacketPtr();
data[0] = value[0];
data[1] = value[1];
GetMTGS().SendDataPacket();
if(GSTransferStatus.PTH3 == PENDINGSTOP_MODE)
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 )
{
GSTransferStatus.PTH3 = STOPPED_MODE;
gifRegs->stat.APATH = GIF_APATH_IDLE;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
Registers::Thaw();
}

View File

@ -56,7 +56,7 @@ void gsPath1Interrupt()
if((gifRegs->stat.APATH == GIF_APATH_IDLE || gifRegs->stat.APATH == GIF_APATH1) && Path1WritePos > 0 && !gifRegs->stat.PSE)
if((gifRegs->stat.APATH == GIF_APATH_IDLE || gifRegs->stat.APATH == GIF_APATH1 || gifRegs->stat.IP3) && Path1WritePos > 0 && !gifRegs->stat.PSE)
{
Registers::Freeze();
u32 size = GetMTGS().PrepDataPacket(GIF_PATH_1, Path1Buffer + (Path1ReadPos*16), (Path1WritePos - Path1ReadPos));
@ -69,11 +69,17 @@ void gsPath1Interrupt()
Registers::Thaw();
Path1ReadPos += size;
if(GSTransferStatus.PTH1 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH1 )
{
gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
if(Path1ReadPos == Path1WritePos)
{
Path1WritePos = Path1ReadPos = 0;
}
CPU_INT(28, 16); //Should be size * BIAS (probably) but Tony Hawk doesnt like this, probably to do with vif flush stalling
if(!(cpuRegs.interrupt & (1<<28))) CPU_INT(28, 16); //Should be size * BIAS (probably) but Tony Hawk doesnt like this, probably to do with vif flush stalling
}
else
{
@ -85,7 +91,7 @@ void gsPath1Interrupt()
else
{
if(gifRegs->stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
CPU_INT(28, 16);
if(!(cpuRegs.interrupt & (1<<28)))CPU_INT(28, 16);
}
}
@ -94,7 +100,11 @@ __forceinline void gsInterrupt()
{
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 )
{
gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
if (!(gif->chcr.STR))
{
@ -120,8 +130,13 @@ __forceinline void gsInterrupt()
gspath3done = false;
gscycles = 0;
gif->chcr.STR = false;
//gifRegs->stat.OPH = false;
gifRegs->stat.clear_flags(GIF_STAT_FQC);
////
/*gifRegs->stat.OPH = false;
GSTransferStatus.PTH3 = STOPPED_MODE;
gifRegs->stat.APATH = GIF_APATH_IDLE;
////
gifRegs->stat.clear_flags(GIF_STAT_FQC);*/
clearFIFOstuff(false);
hwDmacIrq(DMAC_GIF);
//DevCon.Warning("GIF DMA end");
@ -223,10 +238,6 @@ bool CheckPaths(int Channel)
{
if((vif1.cmd & 0x7f) != 0x51 || gifRegs->stat.P1Q == true)
{
if(gifRegs->stat.APATH == GIF_APATH3)
{
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
gifRegs->stat.IP3 = true;
CPU_INT(DMAC_GIF, 16);
return false;
@ -238,10 +249,6 @@ bool CheckPaths(int Channel)
//This should cover both scenarios, as DIRECTHL doesn't gain priority when image mode is running (PENDINGIMAGE_MODE == fininshed).
if((gifRegs->stat.P1Q == true || gifRegs->stat.P2Q == true) || (gifRegs->stat.APATH > GIF_APATH_IDLE && gifRegs->stat.APATH < GIF_APATH3))
{
if(gifRegs->stat.APATH == GIF_APATH3)
{
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
gifRegs->stat.IP3 = true;
CPU_INT(DMAC_GIF, 16);
return false;
@ -619,9 +626,10 @@ void gifMFIFOInterrupt()
//Console.WriteLn("gifMFIFOInterrupt");
mfifocycles = 0;
if (GSTransferStatus.PTH3 == STOPPED_MODE)
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH3 )
{
gifRegs->stat.APATH = GIF_APATH_IDLE;
gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
if(CheckPaths(11) == false) return;

View File

@ -191,6 +191,12 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
u32 temp = dma->madr;
dma->madr = dma->tadr + 16;
if(temp == 0)
{
DevCon.Warning("DMA Chain CALL next tag error. Tag Addr = 0");
dma->tadr = dma->madr + (dma->qwc << 4);
return false;
}
// Stash an address on the address stack pointer.
switch(dma->chcr.ASP)
{

View File

@ -336,6 +336,13 @@ __forceinline void vif1Interrupt()
g_vifCycles = 0;
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
{
gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
if (schedulepath3msk & 0x10)
{
Vif1MskPath3();
@ -358,12 +365,7 @@ __forceinline void vif1Interrupt()
if (vif1ch->chcr.DIR)vif1Regs->stat.FQC = min(vif1ch->qwc, (u16)16);
//Simulated GS transfer time done, clear the flags
if(GSTransferStatus.PTH2 == PENDINGSTOP_MODE)
{
GSTransferStatus.PTH2 = STOPPED_MODE;
/*gifRegs->stat.APATH = GIF_APATH_IDLE;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/
}

View File

@ -236,6 +236,15 @@ void vifMFIFOInterrupt()
g_vifCycles = 0;
VIF_LOG("vif mfifo interrupt");
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH2)
{
GSTransferStatus.PTH2 = STOPPED_MODE;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
/*gifRegs->stat.APATH = GIF_APATH_IDLE;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/
}
if (schedulepath3msk & 0x10) Vif1MskPath3();
if(vif1ch->chcr.DIR && CheckPath2GIF(10) == false) return;
@ -243,13 +252,6 @@ void vifMFIFOInterrupt()
//Simulated GS transfer time done, clear the flags
if(GSTransferStatus.PTH2 == PENDINGSTOP_MODE)
{
GSTransferStatus.PTH2 = STOPPED_MODE;
/*gifRegs->stat.APATH = GIF_APATH_IDLE;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;*/
}
if (vif1.cmd)
{
if(vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING;

View File

@ -166,7 +166,7 @@ template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
const int ret = aMin(vif1.vifpacketsize, vif1.tag.size);
u32 size = ret << 2;
gifRegs->stat.APATH = GIF_APATH2; //Flag is cleared in vif1interrupt to simulate it being in progress.
//gifRegs->stat.APATH = GIF_APATH2; //Flag is cleared in vif1interrupt to simulate it being in progress.
//In the original code we were saving this data, it seems if it does happen, its just blank, so we ignore it.

View File

@ -384,8 +384,8 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size,
if(TestOnly == false)
{
gifRegs->stat.APATH = pathidx + 1;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = true;
gifRegs->stat.APATH = pathidx + 1;
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = true;
}
switch(tag.FLG) {
case GIF_FLG_PACKED:
@ -393,7 +393,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size,
PrepPackedRegs();
do {
if (GetReg() == 0xe) {
gsHandler(pMem);
if(TestOnly == false)gsHandler(pMem);
}
incTag(16, 1);
} while(StepReg() && size > 0);
@ -463,15 +463,15 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size,
}
else if(nloop == 0)
{
if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
/*if(gifRegs->stat.DIR == 0)gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;*/
switch(pathidx)
{
case GIF_PATH_1:
GSTransferStatus.PTH1 = STOPPED_MODE;
break;
case GIF_PATH_2:
GSTransferStatus.PTH2 = PENDINGSTOP_MODE;
GSTransferStatus.PTH2 = STOPPED_MODE;
break;
case GIF_PATH_3:
if(GSTransferStatus.PTH3 != IDLE_MODE) GSTransferStatus.PTH3 = STOPPED_MODE;

View File

@ -20,6 +20,7 @@
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="D:\Files\ps2\Pcsx2\$(PcsxSubsection)"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;..\..\..\common\vsprops\pthreads.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\..\common\vsprops\IncrementalLinking.vsprops;..\..\..\common\vsprops\wxWidgetsGui.vsprops"
UseOfMFC="0"

View File

@ -1102,7 +1102,7 @@ mVUop(mVU_XITOP) {
//------------------------------------------------------------------
// XGkick
//------------------------------------------------------------------
extern void gsPath1Interrupt();
void __fastcall mVU_XGKICK_(u32 addr) {
addr &= 0x3ff;
u8* data = microVU1.regs->Mem + (addr*16);
@ -1110,8 +1110,14 @@ void __fastcall mVU_XGKICK_(u32 addr) {
u32 size;
u8* pDest;
if(gifRegs->stat.APATH == GIF_APATH_IDLE)
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true))
{
if(Path1WritePos != 0)
{
//Flush any pending transfers so things dont go up in the wrong order
while(gifRegs->stat.P1Q == true) gsPath1Interrupt();
}
size = GetMTGS().PrepDataPacket(GIF_PATH_1, data, diff);
pDest = GetMTGS().GetDataPacketPtr();
if (size > diff) {
@ -1127,6 +1133,11 @@ void __fastcall mVU_XGKICK_(u32 addr) {
memcpy_aligned(pDest, microVU1.regs->Mem + (addr*16), size*16);
}
GetMTGS().SendDataPacket();
if(GSTransferStatus.PTH1 == STOPPED_MODE && gifRegs->stat.APATH == GIF_APATH1 )
{
gifRegs->stat.OPH = false;
gifRegs->stat.APATH = GIF_APATH_IDLE;
}
}
else
{

View File

@ -1978,8 +1978,14 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
u32 size;
u8* pDest;
if(gifRegs->stat.APATH == GIF_APATH_IDLE)
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true))
{
if(Path1WritePos != 0)
{
//Flush any pending transfers so things dont go up in the wrong order
while(gifRegs->stat.P1Q == true) gsPath1Interrupt();
}
size = GetMTGS().PrepDataPacket(GIF_PATH_1, data, diff);
pDest = GetMTGS().GetDataPacketPtr();
if (size > diff) {