mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
a4abcf1206
commit
07c22b357c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue