Resolved Issue 165 so the scratchpad syncs with the MFIFO drain (this was the cause of the Tekken issue). and some other misc tweaks for unpack errors n such

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1008 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
refraction 2009-04-18 23:36:01 +00:00
parent a4abcf1206
commit 07c22b357c
4 changed files with 60 additions and 22 deletions

View File

@ -31,13 +31,14 @@ using std::min;
#define gifsplit 128 #define gifsplit 128
enum gifstate_t enum gifstate_t
{ {
GIF_STATE_EMPTY = 0, GIF_STATE_READY = 0,
GIF_STATE_STALL, GIF_STATE_STALL = 1,
GIF_STATE_DONE GIF_STATE_DONE = 2,
GIF_STATE_EMPTY = 0x10
}; };
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY; static int gifstate = GIF_STATE_READY;
static u64 s_gstag = 0; // used for querying the last tag static u64 s_gstag = 0; // used for querying the last tag
@ -347,7 +348,7 @@ void dmaGIF() {
//It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
Console::WriteLn("GIF MFIFO"); //Console::WriteLn("GIF MFIFO");
gifMFIFOInterrupt(); gifMFIFOInterrupt();
return; return;
} }
@ -415,7 +416,7 @@ static __forceinline int mfifoGIFrbTransfer() {
gifqwc -= mfifoqwc; gifqwc -= mfifoqwc;
gif->qwc -= mfifoqwc; gif->qwc -= mfifoqwc;
gif->madr += mfifoqwc*16; gif->madr += mfifoqwc*16;
mfifocycles += (mfifoqwc) * 2; /* guessing */ //mfifocycles += (mfifoqwc) * 2; /* guessing */
return 0; return 0;
} }
@ -456,8 +457,8 @@ void mfifoGIFtransfer(int qwc) {
if(qwc > 0 ) { if(qwc > 0 ) {
gifqwc += qwc; gifqwc += qwc;
if (!(gif->chcr & 0x100)) return; if (gifstate != GIF_STATE_EMPTY) return;
if (gifstate == GIF_STATE_STALL) return; gifstate &= ~GIF_STATE_EMPTY;
} }
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
@ -491,20 +492,20 @@ void mfifoGIFtransfer(int qwc) {
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
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
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
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
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
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
break; break;
case 7: // End - Transfer QWC following the tag case 7: // End - Transfer QWC following the tag
@ -544,10 +545,16 @@ void gifMFIFOInterrupt()
cpuRegs.interrupt &= ~(1 << 11); cpuRegs.interrupt &= ~(1 << 11);
return ; return ;
} }
if(spr0->chcr & 0x100)
{
spr0->chcr &= ~0x100;
hwDmacIrq(8);
}
if(gifstate != GIF_STATE_STALL) { if(gifstate != GIF_STATE_STALL) {
if(gifqwc <= 0) { if(gifqwc <= 0) {
//Console::WriteLn("Empty"); //Console::WriteLn("Empty");
gifstate |= GIF_STATE_EMPTY;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
hwDmacIrq(14); hwDmacIrq(14);
return; return;
@ -556,14 +563,14 @@ void gifMFIFOInterrupt()
return; return;
} }
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if(gifstate == GIF_STATE_EMPTY || gif->qwc > 0) { if(gifstate == GIF_STATE_READY || gif->qwc > 0) {
Console::Error("gifMFIFO Panic > Shouldn't go here!"); Console::Error("gifMFIFO Panic > Shouldn't go here!");
return; return;
} }
#endif #endif
//if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc); //if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc);
if (!gifmfifoirq) gifqwc = 0; if (!gifmfifoirq) gifqwc = 0;
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff

View File

@ -227,6 +227,7 @@ void SPRFROMinterrupt()
//Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr); //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr);
mfifoGIFtransfer(mfifotransferred); mfifoGIFtransfer(mfifotransferred);
mfifotransferred = 0; mfifotransferred = 0;
return;
} }
else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
{ {
@ -235,6 +236,7 @@ void SPRFROMinterrupt()
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr); //Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
mfifoVIF1transfer(mfifotransferred); mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0; mfifotransferred = 0;
return;
} }
} }
if (spr0finished == 0) return; if (spr0finished == 0) return;

View File

@ -434,17 +434,18 @@ void mfifoVIF1transfer(int qwc)
if (qwc > 0) if (qwc > 0)
{ {
vifqwc += qwc; vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10) if (vif1.inprogress & 0x10)
{ {
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
CPU_INT(10, min((int)vifqwc, (int)vif1ch->qwc) * BIAS); CPU_INT(10, 0);
else else
CPU_INT(10, vif1ch->qwc * BIAS); CPU_INT(10, vif1ch->qwc * BIAS);
vif1Regs->stat |= 0x10000000; // FQC=16 vif1Regs->stat |= 0x10000000; // FQC=16
} }
vif1.inprogress &= ~0x10; vif1.inprogress &= ~0x10;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr, vif1.vifstalled, vif1.done);
return; return;
} }
@ -531,7 +532,11 @@ void mfifoVIF1transfer(int qwc)
void vifMFIFOInterrupt() void vifMFIFOInterrupt()
{ {
g_vifCycles = 0; g_vifCycles = 0;
if(spr0->chcr & 0x100)
{
spr0->chcr &= ~0x100;
hwDmacIrq(8);
}
if (vif1.inprogress == 1) mfifo_VIF1chain(); if (vif1.inprogress == 1) mfifo_VIF1chain();
if (vif1.irq && vif1.tag.size == 0) if (vif1.irq && vif1.tag.size == 0)
@ -560,7 +565,7 @@ void vifMFIFOInterrupt()
if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0); if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0);
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
CPU_INT(10, min((int)vifqwc, (int)vif1ch->qwc) * BIAS); CPU_INT(10, 0);
else else
CPU_INT(10, vif1ch->qwc * BIAS); CPU_INT(10, vif1ch->qwc * BIAS);

View File

@ -645,7 +645,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
//VIF_LOG("warning, end with size = %d", size); //VIF_LOG("warning, end with size = %d", size);
/* unpack one qword */ /* unpack one qword */
vif->tag.addr += (size / ft->dsize) * 4; //vif->tag.addr += (size / ft->dsize) * 4;
func(dest, (u32*)cdata, size / ft->dsize); func(dest, (u32*)cdata, size / ft->dsize);
size = 0; size = 0;
@ -714,7 +714,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
//VIF_LOG("warning, end with size = %d", size); //VIF_LOG("warning, end with size = %d", size);
/* unpack one qword */ /* unpack one qword */
vif->tag.addr += (size / ft->dsize) * 4; //vif->tag.addr += (size / ft->dsize) * 4;
func(dest, (u32*)cdata, size / ft->dsize); func(dest, (u32*)cdata, size / ft->dsize);
size = 0; size = 0;
@ -1008,6 +1008,18 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK
FreezeXMMRegs(1); FreezeXMMRegs(1);
if (vif0.vifpacketsize < vif0.tag.size) if (vif0.vifpacketsize < vif0.tag.size)
{ {
if(vif0Regs->offset != 0 || vif0.cl != 0)
{
ret = vif0.tag.size;
vif0.tag.size = VIFalign(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum);
ret = ret - vif0.tag.size;
data += ret;
if(vif0.vifpacketsize > 0) VIFunpack(data, &vif0.tag, vif0.vifpacketsize - ret, VIF0dmanum);
ProcessMemSkip((vif0.vifpacketsize - ret) << 2, (vif0.cmd & 0xf), VIF0dmanum);
vif0.tag.size -= (vif0.vifpacketsize - ret);
FreezeXMMRegs(0);
return vif0.vifpacketsize;
}
/* size is less that the total size, transfer is 'in pieces' */ /* size is less that the total size, transfer is 'in pieces' */
VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum);
@ -1835,8 +1847,20 @@ static int __fastcall Vif1TransUnpack(u32 *data)
if (vif1.vifpacketsize < vif1.tag.size) if (vif1.vifpacketsize < vif1.tag.size)
{ {
int ret = vif1.tag.size;
/* size is less that the total size, transfer is /* size is less that the total size, transfer is
'in pieces' */ 'in pieces' */
if(vif1Regs->offset != 0 || vif1.cl != 0)
{
vif1.tag.size = VIFalign(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum);
ret = ret - vif1.tag.size;
data += ret;
if((vif1.vifpacketsize - ret) > 0) VIFunpack(data, &vif1.tag, vif1.vifpacketsize - ret, VIF1dmanum);
ProcessMemSkip((vif1.vifpacketsize - ret) << 2, (vif1.cmd & 0xf), VIF1dmanum);
vif1.tag.size -= (vif1.vifpacketsize - ret);
FreezeXMMRegs(0);
return vif1.vifpacketsize;
}
VIFunpack(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum); VIFunpack(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum);
ProcessMemSkip(vif1.vifpacketsize << 2, (vif1.cmd & 0xf), VIF1dmanum); ProcessMemSkip(vif1.vifpacketsize << 2, (vif1.cmd & 0xf), VIF1dmanum);
@ -2390,7 +2414,7 @@ __forceinline void vif1Interrupt()
if (vif1.inprogress) _VIF1chain(); if (vif1.inprogress) _VIF1chain();
if ((!vif1.done) || (vif1.inprogress)) if ((!vif1.done) || (vif1.inprogress & 0x1))
{ {
if (!(psHu32(DMAC_CTRL) & 0x1)) if (!(psHu32(DMAC_CTRL) & 0x1))
@ -2399,7 +2423,7 @@ __forceinline void vif1Interrupt()
return; return;
} }
if (vif1.inprogress == 0) vif1SetupTransfer(); if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
CPU_INT(1, vif1ch->qwc * BIAS); CPU_INT(1, vif1ch->qwc * BIAS);
return; return;
@ -2436,7 +2460,7 @@ void dmaVIF1()
if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO
{ {
// Console::WriteLn("VIFMFIFO\n"); //Console::WriteLn("VIFMFIFO\n");
if (!(vif1ch->chcr & 0x4)) Console::WriteLn("MFIFO mode != Chain! %x", params vif1ch->chcr); if (!(vif1ch->chcr & 0x4)) Console::WriteLn("MFIFO mode != Chain! %x", params vif1ch->chcr);
vifMFIFOInterrupt(); vifMFIFOInterrupt();
return; return;