From d7f88d05b281df03ac8f0699675b393d8c2bb984 Mon Sep 17 00:00:00 2001 From: refraction Date: Thu, 1 Jul 2010 00:32:06 +0000 Subject: [PATCH] Fixed up VU1 looping so it works how it did, Rock Band should hopefully work again now. (And Guitar Hero 3, Tony Hawks Project etc) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3355 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/ps2/GIFpath.cpp | 68 ++++++++++++++++++++++++++++++++---- pcsx2/x86/microVU_Lower.inl | 2 +- pcsx2/x86/newVif_Dynarec.cpp | 2 +- pcsx2/x86/sVU_Lower.cpp | 2 +- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 6b6470f858..67190b6a11 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -370,7 +370,7 @@ static __forceinline void gsHandler(const u8* pMem) #define incTag(x, y) do { \ pMem += (x); \ size -= (y); \ - if (pMem>=vuMemEnd) pMem -= 0x4000; \ + /*if (pMem>=vuMemEnd) pMem -= 0x4000;*/ \ } while(false) #define aMin(x, y) std::min(x, y) @@ -398,9 +398,28 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s { GIF_LOG("Packed Mode"); numregs = ((tag.NREG-1)&0xf) + 1; - u32 len = aMin(size, nloop * numregs); - if(len < (nloop * numregs)) nloop -= len / numregs; - else nloop = 0; + u32 len = aMin(size, (nloop * numregs) - curreg); + if(len < ((nloop * numregs) - curreg)) + { + int curregtemp = 0; + int oldnloop = (nloop * numregs) - curreg; + curregtemp = len / numregs; //Divide the size by numregs, this should get rid of any remainder + nloop -= curregtemp; + curregtemp *= numregs; //multiply it again so we have a total size value + curregtemp = len - curregtemp; //take the temp figure from the size, which should leave the remainder + //AKA current reg :) + if(curregtemp > 0) + { + DevCon.Warning("Currtemp = %x size %x nloop * nregs %x", curregtemp, size, oldnloop); + curreg = curregtemp; + } + + } + else + { + curreg = 0; + nloop = 0; + } incTag(16 * len, len); } break; @@ -429,6 +448,23 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s break; } } + if(pathidx == GIF_PATH_1) + { + if(size == 0 && (!tag.EOP || nloop > 0)) //Need to check all of this, some cases VU will send info (like the BIOS) but be incomplete + { + if(startSize < 0x400) + { + size = 0x400 - startSize; + startSize = 0x400; + pMem -= 0x4000; + } + else + { + size = 0; + Console.Warning("GIFTAG error, size exceeded VU memory size %x", startSize); + } + } + } if (tag.EOP && !nloop) break; } @@ -440,7 +476,7 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) { - const u8* vuMemEnd = pMem + (size<<4); // End of VU1 Mem + //const u8* vuMemEnd = pMem + (size<<4); // End of VU1 Mem u32 startSize = size; // Start Size while (size > 0) { @@ -561,7 +597,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) //AKA current reg :) if(curregtemp > 0) { - DevCon.Warning("Currtemp = %x size %x nloop * nregs %x", curregtemp, size, oldnloop); + //DevCon.Warning("Currtemp = %x size %x nloop * nregs %x", curregtemp, size, oldnloop); curreg = curregtemp; } @@ -599,6 +635,26 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size) } break; } + + + } + + if(pathidx == GIF_PATH_1) + { + if(size == 0 && (!tag.EOP || nloop > 0)) //Need to check all of this, some cases VU will send info (like the BIOS) but be incomplete + { + if(startSize < 0x3ff) + { + size = 0x3ff - startSize; + startSize = 0x3ff; + pMem -= 0x4000; + } + else + { + size = 0; + Console.Warning("GIFTAG error, size exceeded VU memory size %x", startSize); + } + } } if (tag.EOP && !nloop) diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index f711ea8f6d..2c66144c4d 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -1105,7 +1105,7 @@ extern void gsPath1Interrupt(); void __fastcall mVU_XGKICK_(u32 addr) { addr &= 0x3ff; u8* data = microVU1.regs->Mem + (addr*16); - u32 diff = 0x400; + u32 diff = 0x400 - addr; u32 size; u8* pDest; diff --git a/pcsx2/x86/newVif_Dynarec.cpp b/pcsx2/x86/newVif_Dynarec.cpp index cfcbb0c9e4..252e13cd26 100644 --- a/pcsx2/x86/newVif_Dynarec.cpp +++ b/pcsx2/x86/newVif_Dynarec.cpp @@ -209,7 +209,7 @@ static _f u8* dVifsetVUptr(const nVifStruct& v, int cl, int wl, bool isFill) { } else endPtr = ptr + (_vBlock.num * 16); if ( endPtr > v.vuMemEnd ) { - DevCon.WriteLn("nVif%x - VU Mem Ptr Overflow; falling back to interpreter. Start = %x End = %x num = %x, wl = %x, cl = %x", v.idx, v.vif->tag.addr, v.vif->tag.addr + (_vBlock.num * 16), _vBlock.num, wl, cl); + //DevCon.WriteLn("nVif%x - VU Mem Ptr Overflow; falling back to interpreter. Start = %x End = %x num = %x, wl = %x, cl = %x", v.idx, v.vif->tag.addr, v.vif->tag.addr + (_vBlock.num * 16), _vBlock.num, wl, cl); ptr = NULL; // Fall Back to Interpreters which have wrap-around logic } return ptr; diff --git a/pcsx2/x86/sVU_Lower.cpp b/pcsx2/x86/sVU_Lower.cpp index 0ec91d4a07..ca9c0acf0d 100644 --- a/pcsx2/x86/sVU_Lower.cpp +++ b/pcsx2/x86/sVU_Lower.cpp @@ -1974,7 +1974,7 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) { addr &= 0x3fff; u8* data = VU1.Mem + (addr); - u32 diff = 0x400; + u32 diff = 0x400 - (addr >> 4); u32 size; u8* pDest;