Added some more relevant persistent state vars from the GIF to the savestates. There's still a known bug in the IPU's savestate however, so saving/loading while FMVs are playing could result in bad states (not sure when the bug started, and it could be very old, only noticed it today)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@541 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-02-20 00:39:58 +00:00
parent 32c6b06127
commit 35d2328dd1
3 changed files with 38 additions and 17 deletions

View File

@ -31,7 +31,7 @@ using std::min;
#define gif ((DMACh*)&psH[0xA000]) #define gif ((DMACh*)&psH[0xA000])
static u64 s_gstag=0; // used for querying the last tag static u64 s_gstag = 0; // used for querying the last tag
static int gspath3done=0; static int gspath3done=0;
static int gscycles = 0; static int gscycles = 0;
@ -149,7 +149,6 @@ int _GIFchain() {
int gscount = 0; int gscount = 0;
static int prevcycles = 0; static int prevcycles = 0;
static u32* prevtag = NULL;
void GIFdma() void GIFdma()
{ {
@ -312,7 +311,6 @@ void GIFdma()
} }
} }
} }
prevtag = NULL;
prevcycles = 0; prevcycles = 0;
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) { if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
CPU_INT(2, gscycles); CPU_INT(2, gscycles);
@ -341,9 +339,18 @@ void dmaGIF() {
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) #define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
enum gifstate_t
{
GIF_STATE_EMPTY = 0,
GIF_STATE_STALL,
GIF_STATE_DONE
};
static unsigned int mfifocycles; static unsigned int mfifocycles;
static unsigned int gifqwc = 0; static unsigned int gifqwc = 0;
unsigned int gifdone = 0;
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY;
// called from only one location, so forceinline it: // called from only one location, so forceinline it:
static __forceinline int mfifoGIFrbTransfer() { static __forceinline int mfifoGIFrbTransfer() {
@ -421,7 +428,7 @@ void mfifoGIFtransfer(int qwc) {
if(qwc > 0 ) { if(qwc > 0 ) {
gifqwc += qwc; gifqwc += qwc;
if(!(gif->chcr & 0x100))return; if(!(gif->chcr & 0x100))return;
if(gifdone == 1) return; if(gifstate == GIF_STATE_STALL) return;
} }
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
@ -451,37 +458,37 @@ void mfifoGIFtransfer(int qwc) {
switch (id) { switch (id) {
case 0: // Refe - Transfer Packet According to ADDR field case 0: // Refe - Transfer Packet According to ADDR field
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR));
gifdone = 2; //End Transfer gifstate = GIF_STATE_DONE; //End Transfer
break; break;
case 1: // CNT - Transfer QWC following the tag. case 1: // CNT - Transfer QWC following the tag.
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifdone = 0; gifstate = GIF_STATE_EMPTY;
break; break;
case 2: // Next - Transfer QWC following tag. TADR = ADDR case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = gif->madr; //Temporarily Store ADDR temp = gif->madr; //Temporarily Store ADDR
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag
gif->tadr = temp; //Copy temporarily stored ADDR to Tag gif->tadr = temp; //Copy temporarily stored ADDR to Tag
gifdone = 0; gifstate = GIF_STATE_EMPTY;
break; break;
case 3: // Ref - Transfer QWC from ADDR field case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control) case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
gifdone = 0; gifstate = GIF_STATE_EMPTY;
break; break;
case 7: // End - Transfer QWC following the tag case 7: // End - Transfer QWC following the tag
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifdone = 2; //End Transfer gifstate = GIF_STATE_DONE; //End Transfer
break; break;
} }
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
SPR_LOG("dmaIrq Set\n"); SPR_LOG("dmaIrq Set\n");
gifdone = 2; gifstate = GIF_STATE_DONE;
} }
} }
FreezeXMMRegs(1); FreezeXMMRegs(1);
@ -489,12 +496,12 @@ void mfifoGIFtransfer(int qwc) {
if (mfifoGIFchain() == -1) { if (mfifoGIFchain() == -1) {
SysPrintf("GIF dmaChain error size=%d, madr=%lx, tadr=%lx\n", SysPrintf("GIF dmaChain error size=%d, madr=%lx, tadr=%lx\n",
gif->qwc, gif->madr, gif->tadr); gif->qwc, gif->madr, gif->tadr);
gifdone = 1; gifstate = GIF_STATE_STALL;
} }
FreezeXMMRegs(0); FreezeXMMRegs(0);
FreezeMMXRegs(0); FreezeMMXRegs(0);
if(gif->qwc == 0 && gifdone == 2) gifdone = 1; if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
CPU_INT(11,mfifocycles); CPU_INT(11,mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
@ -504,7 +511,7 @@ void gifMFIFOInterrupt()
{ {
if(!(gif->chcr & 0x100)) { SysPrintf("WTF GIFMFIFO\n");cpuRegs.interrupt &= ~(1 << 11); return ; } if(!(gif->chcr & 0x100)) { SysPrintf("WTF GIFMFIFO\n");cpuRegs.interrupt &= ~(1 << 11); return ; }
if(gifdone != 1) { if(gifstate != GIF_STATE_STALL) {
if(gifqwc <= 0) { if(gifqwc <= 0) {
//SysPrintf("Empty\n"); //SysPrintf("Empty\n");
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
@ -515,14 +522,14 @@ void gifMFIFOInterrupt()
return; return;
} }
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if(gifdone == 0 || gif->qwc > 0) { if(gifstate == GIF_STATE_EMPTY || gif->qwc > 0) {
Console::Error("gifMFIFO Panic > Shouldnt go here!"); Console::Error("gifMFIFO Panic > Shouldn't go here!");
return; return;
} }
#endif #endif
//if(gifqwc > 0)SysPrintf("GIF MFIFO ending with stuff in it %x\n", gifqwc); //if(gifqwc > 0)SysPrintf("GIF MFIFO ending with stuff in it %x\n", gifqwc);
gifqwc = 0; gifqwc = 0;
gifdone = 0; gifstate = GIF_STATE_EMPTY;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
@ -532,3 +539,15 @@ void gifMFIFOInterrupt()
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
} }
void SaveState::gifFreeze()
{
if( GetVersion() >= 0x14 )
{
Freeze( gifstate );
Freeze( gifqwc );
Freeze( gspath3done );
Freeze( gscycles );
// Note: mfifocycles is not a persistent var, so no need to save it here.
}
}

View File

@ -126,6 +126,7 @@ void SaveState::FreezeAll()
vif1Freeze(); vif1Freeze();
sifFreeze(); sifFreeze();
ipuFreeze(); ipuFreeze();
gifFreeze();
// iop now // iop now
FreezeMem(psxM, Ps2MemSize::IopRam); // 2 MB main memory FreezeMem(psxM, Ps2MemSize::IopRam); // 2 MB main memory

View File

@ -112,6 +112,7 @@ protected:
void vif1Freeze(); void vif1Freeze();
void sifFreeze(); void sifFreeze();
void ipuFreeze(); void ipuFreeze();
void gifFreeze();
void sioFreeze(); void sioFreeze();
void cdrFreeze(); void cdrFreeze();