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
|
#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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue