diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 6fbfedee55..5d7c26bfae 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -360,7 +360,7 @@ static __fi bool mfifoGIFchain() if (gifch.qwc == 0) return true; if (gifch.madr >= dmacRegs.rbor.ADDR && - gifch.madr < (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) + gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) { bool ret = true; // if(gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge GIF"); @@ -390,6 +390,32 @@ static u32 qwctag(u32 mask) { return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK)); } +void mfifoGifMaskMem(int id) +{ + switch (id) { + //These five transfer data following the tag, need to check its within the buffer (Front Mission 4) + case TAG_CNT: + case TAG_NEXT: + case TAG_CALL: + case TAG_RET: + case TAG_END: + if(gifch.madr < dmacRegs.rbor.ADDR) //probably not needed but we will check anyway. + { + //DevCon.Warning("GIF MFIFO MADR below bottom of ring buffer, wrapping GIF MADR = %x Ring Bottom %x", gifch.madr, dmacRegs.rbor.ADDR); + gifch.madr = qwctag(gifch.madr); + } + if(gifch.madr > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)) //Usual scenario is the tag is near the end (Front Mission 4) + { + //DevCon.Warning("GIF MFIFO MADR outside top of ring buffer, wrapping GIF MADR = %x Ring Top %x", gifch.madr, (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)+16); + gifch.madr = qwctag(gifch.madr); + } + break; + default: + //Do nothing as the MADR could be outside + break; + } +} + void mfifoGIFtransfer(int qwc) { tDMA_TAG *ptag; @@ -426,6 +452,8 @@ void mfifoGIFtransfer(int qwc) gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID); + mfifoGifMaskMem(ptag->ID); + if(gspath3done == true) gifstate = GIF_STATE_DONE; else gifstate = GIF_STATE_READY; diff --git a/pcsx2/Vif1_MFIFO.cpp b/pcsx2/Vif1_MFIFO.cpp index 8f93d17c3e..65eb9d5f12 100644 --- a/pcsx2/Vif1_MFIFO.cpp +++ b/pcsx2/Vif1_MFIFO.cpp @@ -145,6 +145,32 @@ static __fi void mfifo_VIF1chain() } } +void mfifoVifMaskMem(int id) +{ + switch (id) { + //These five transfer data following the tag, need to check its within the buffer (Front Mission 4) + case TAG_CNT: + case TAG_NEXT: + case TAG_CALL: + case TAG_RET: + case TAG_END: + if(vif1ch.madr < dmacRegs.rbor.ADDR) //probably not needed but we will check anyway. + { + //DevCon.Warning("VIF MFIFO MADR below bottom of ring buffer, wrapping VIF MADR = %x Ring Bottom %x", vif1ch.madr, dmacRegs.rbor.ADDR); + vif1ch.madr = qwctag(vif1ch.madr); + } + if(vif1ch.madr > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)) //Usual scenario is the tag is near the end (Front Mission 4) + { + //DevCon.Warning("VIF MFIFO MADR outside top of ring buffer, wrapping VIF MADR = %x Ring Top %x", vif1ch.madr, (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)+16); + vif1ch.madr = qwctag(vif1ch.madr); + } + break; + default: + //Do nothing as the MADR could be outside + break; + } +} + void mfifoVIF1transfer(int qwc) { tDMA_TAG *ptag; @@ -223,6 +249,8 @@ void mfifoVIF1transfer(int qwc) vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID); + mfifoVifMaskMem(ptag->ID); + if (vif1ch.chcr.TIE && ptag->IRQ) { VIF_LOG("dmaIrq Set");