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
enum gifstate_t
{
GIF_STATE_EMPTY = 0,
GIF_STATE_STALL,
GIF_STATE_DONE
GIF_STATE_READY = 0,
GIF_STATE_STALL = 1,
GIF_STATE_DONE = 2,
GIF_STATE_EMPTY = 0x10
};
// 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
@ -347,7 +348,7 @@ void dmaGIF() {
//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);
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
Console::WriteLn("GIF MFIFO");
//Console::WriteLn("GIF MFIFO");
gifMFIFOInterrupt();
return;
}
@ -415,7 +416,7 @@ static __forceinline int mfifoGIFrbTransfer() {
gifqwc -= mfifoqwc;
gif->qwc -= mfifoqwc;
gif->madr += mfifoqwc*16;
mfifocycles += (mfifoqwc) * 2; /* guessing */
//mfifocycles += (mfifoqwc) * 2; /* guessing */
return 0;
}
@ -456,8 +457,8 @@ void mfifoGIFtransfer(int qwc) {
if(qwc > 0 ) {
gifqwc += qwc;
if (!(gif->chcr & 0x100)) return;
if (gifstate == GIF_STATE_STALL) return;
if (gifstate != GIF_STATE_EMPTY) return;
gifstate &= ~GIF_STATE_EMPTY;
}
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.
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
gifstate = GIF_STATE_EMPTY;
gifstate = GIF_STATE_READY;
break;
case 2: // Next - Transfer QWC following tag. TADR = 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->tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_EMPTY;
gifstate = GIF_STATE_READY;
break;
case 3: // Ref - Transfer QWC from ADDR field
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
gifstate = GIF_STATE_EMPTY;
gifstate = GIF_STATE_READY;
break;
case 7: // End - Transfer QWC following the tag
@ -544,10 +545,16 @@ void gifMFIFOInterrupt()
cpuRegs.interrupt &= ~(1 << 11);
return ;
}
if(spr0->chcr & 0x100)
{
spr0->chcr &= ~0x100;
hwDmacIrq(8);
}
if(gifstate != GIF_STATE_STALL) {
if(gifqwc <= 0) {
//Console::WriteLn("Empty");
gifstate |= GIF_STATE_EMPTY;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
hwDmacIrq(14);
return;
@ -556,14 +563,14 @@ void gifMFIFOInterrupt()
return;
}
#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!");
return;
}
#endif
//if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc);
if (!gifmfifoirq) gifqwc = 0;
gifstate = GIF_STATE_EMPTY;
gifstate = GIF_STATE_READY;
gif->chcr &= ~0x100;
hwDmacIrq(DMAC_GIF);
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);
mfifoGIFtransfer(mfifotransferred);
mfifotransferred = 0;
return;
}
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);
mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0;
return;
}
}
if (spr0finished == 0) return;

View File

@ -434,17 +434,18 @@ void mfifoVIF1transfer(int qwc)
if (qwc > 0)
{
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 (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
CPU_INT(10, vif1ch->qwc * BIAS);
vif1Regs->stat |= 0x10000000; // FQC=16
}
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;
}
@ -531,7 +532,11 @@ void mfifoVIF1transfer(int qwc)
void vifMFIFOInterrupt()
{
g_vifCycles = 0;
if(spr0->chcr & 0x100)
{
spr0->chcr &= ~0x100;
hwDmacIrq(8);
}
if (vif1.inprogress == 1) mfifo_VIF1chain();
if (vif1.irq && vif1.tag.size == 0)
@ -560,7 +565,7 @@ void vifMFIFOInterrupt()
if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0);
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
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);
/* unpack one qword */
vif->tag.addr += (size / ft->dsize) * 4;
//vif->tag.addr += (size / ft->dsize) * 4;
func(dest, (u32*)cdata, size / ft->dsize);
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);
/* unpack one qword */
vif->tag.addr += (size / ft->dsize) * 4;
//vif->tag.addr += (size / ft->dsize) * 4;
func(dest, (u32*)cdata, size / ft->dsize);
size = 0;
@ -1008,6 +1008,18 @@ static int __fastcall Vif0TransUnpack(u32 *data) // UNPACK
FreezeXMMRegs(1);
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' */
VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum);
@ -1835,8 +1847,20 @@ static int __fastcall Vif1TransUnpack(u32 *data)
if (vif1.vifpacketsize < vif1.tag.size)
{
int ret = vif1.tag.size;
/* size is less that the total size, transfer is
'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);
ProcessMemSkip(vif1.vifpacketsize << 2, (vif1.cmd & 0xf), VIF1dmanum);
@ -2390,7 +2414,7 @@ __forceinline void vif1Interrupt()
if (vif1.inprogress) _VIF1chain();
if ((!vif1.done) || (vif1.inprogress))
if ((!vif1.done) || (vif1.inprogress & 0x1))
{
if (!(psHu32(DMAC_CTRL) & 0x1))
@ -2399,7 +2423,7 @@ __forceinline void vif1Interrupt()
return;
}
if (vif1.inprogress == 0) vif1SetupTransfer();
if ((vif1.inprogress & 0x1) == 0) vif1SetupTransfer();
CPU_INT(1, vif1ch->qwc * BIAS);
return;
@ -2436,7 +2460,7 @@ void dmaVIF1()
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);
vifMFIFOInterrupt();
return;