From 4184b31adaee7e27030599c40eeb2e7c066a51f9 Mon Sep 17 00:00:00 2001 From: refraction Date: Thu, 18 Jun 2009 17:19:01 +0000 Subject: [PATCH] MFIFO fixes for Project Altered Beast - Issue 155, Tekken Tag should be better now too (second time lucky!) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1394 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Gif.cpp | 4 ++-- pcsx2/SPR.cpp | 4 ++-- pcsx2/Vif.cpp | 52 ++++++++++++++++++++++++++++++++++-------------- pcsx2/VifDma.cpp | 4 ++-- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index c11762d302..8b078d89b9 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -464,8 +464,8 @@ void mfifoGIFtransfer(int qwc) { if (gif->qwc == 0) { if (gif->tadr == spr0->madr) { //if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc); - //hwDmacIrq(14); - + hwDmacIrq(14); + gifstate |= GIF_STATE_EMPTY; return; } gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR)); diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 702cdb3306..6b8a1973b9 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -227,7 +227,7 @@ void SPRFROMinterrupt() //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr); mfifoGIFtransfer(mfifotransferred); mfifotransferred = 0; - return; + if(gif->chcr & 0x100)return; } else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO { @@ -236,7 +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(vif1ch->chcr & 0x100)return; } } if (spr0finished == 0) return; diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index a3c7cfc4fa..76f466303c 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -397,7 +397,7 @@ static __forceinline int mfifo_VIF1chain() /* Is QWC = 0? if so there is nothing to transfer */ if ((vif1ch->qwc == 0) && (!vif1.vifstalled)) { - vif1.inprogress = 0; + vif1.inprogress &= ~1; return 0; } @@ -451,7 +451,7 @@ void mfifoVIF1transfer(int qwc) mfifodmairq = false; //Clear any previous TIE interrupt - if (vif1ch->qwc == 0) + if (vif1ch->qwc == 0 && vifqwc > 0) { ptag = (u32*)dmaGetAddr(vif1ch->tadr); @@ -550,7 +550,9 @@ void vifMFIFOInterrupt() hwDmacIrq(DMAC_FROM_SPR); } - if (vif1.inprogress == 1) mfifo_VIF1chain(); + + + if (vif1.irq && vif1.tag.size == 0) { @@ -565,16 +567,36 @@ void vifMFIFOInterrupt() } } - if (!vif1.done || vif1.inprogress & 1) + if (vif1.done == false || vif1ch->qwc) { - if (vifqwc <= 0) + + + switch(vif1.inprogress & 1) { - //Console::WriteLn("Empty 1"); - vif1.inprogress |= 0x10; - vif1Regs->stat &= ~0x1F000000; // FQC=0 - hwDmacIrq(14); - return; + case 0: //Set up transfer + if (vif1ch->tadr == spr0->madr) + { + // Console::WriteLn("Empty 1"); + vifqwc = 0; + vif1.inprogress |= 0x10; + vif1Regs->stat &= ~0x1F000000; // FQC=0 + hwDmacIrq(14); + return; + } + + mfifoVIF1transfer(0); + if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) + CPU_INT(10, 0); + else + CPU_INT(10, vif1ch->qwc * BIAS); + + return; + case 1: //Transfer data + mfifo_VIF1chain(); + CPU_INT(10, 0); + return; } + if (!(vif1.inprogress & 0x1)) mfifoVIF1transfer(0); if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) @@ -582,16 +604,16 @@ void vifMFIFOInterrupt() else CPU_INT(10, vif1ch->qwc * BIAS); - return; - } - else if (vifqwc <= 0) + } + + /*if (vifqwc <= 0) { //Console::WriteLn("Empty 2"); - vif1.inprogress |= 0x10; + //vif1.inprogress |= 0x10; vif1Regs->stat &= ~0x1F000000; // FQC=0 hwDmacIrq(14); - } + }*/ //On a TIE break we do not clear the MFIFO (Art of Fighting) //If we dont clear it on MFIFO end, Tekken Tag breaks, understandably (Refraction) diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 8bf107fae2..aecf054914 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -2307,7 +2307,7 @@ int VIF1transfer(u32 *data, int size, int istag) if (((vif1Regs->code >> 24) & 0x7f) != 0x7) vif1Regs->stat |= VIF1_STAT_VIS; // Note: commenting this out fixes WALL-E if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) - vif1.inprogress = 0; + vif1.inprogress &= ~0x1; // spiderman doesn't break on qw boundaries if (istag) return -2; @@ -2338,7 +2338,7 @@ int VIF1transfer(u32 *data, int size, int istag) if (vif1ch->qwc == 0 && (vif1.irqoffset == 0 || istag == 1)) - vif1.inprogress = 0; + vif1.inprogress &= ~0x1; return vif1.vifstalled ? -2 : 0; }