Merge pull request #1507 from FlatOutPS2/master

PCSX2: IPU end of video freeze fixes
    Fixes end of video freeze in Enthusia - Professional Racing.
    Fixes end of video freeze with IPU Normal error in games like Enter The Matrix(#1494), Rygar, Freestyle Metal X, etc. Also fixes The Incredible Hulk and Bolt (thanks to @prafullpcsx2 for testing).
This commit is contained in:
ramapcsx2 2016-08-23 12:56:21 +02:00 committed by GitHub
commit c1f45dafa5
2 changed files with 21 additions and 14 deletions

View File

@ -64,6 +64,13 @@ __fi void IPUProcessInterrupt()
{ {
if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1ch.chcr.STR && ipu1ch.qwc > 0))) if (ipuRegs.ctrl.BUSY) // && (g_BP.FP || g_BP.IFC || (ipu1ch.chcr.STR && ipu1ch.qwc > 0)))
IPUWorker(); IPUWorker();
if (ipuRegs.ctrl.BUSY && ipuRegs.cmd.BUSY && ipuRegs.cmd.DATA == 0x000001B7) {
// 0x000001B7 is the MPEG2 sequence end code, signalling the end of a video.
// At the end of a video BUSY values should be automatically set to 0.
// This does not happen for Enthusia - Professional Racing, causing it to get stuck in an endless loop.
ipuRegs.cmd.BUSY = 0;
ipuRegs.ctrl.BUSY = 0;
}
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
@ -274,6 +281,7 @@ void ipuSoftReset()
ipuRegs.top = 0; ipuRegs.top = 0;
ipu_cmd.clear(); ipu_cmd.clear();
ipuRegs.cmd.BUSY = 0; ipuRegs.cmd.BUSY = 0;
ipuRegs.cmd.DATA = NULL; // required for Enthusia - Professional Racing after fix, or will freeze at start of next video.
memzero(g_BP); memzero(g_BP);
} }

View File

@ -293,6 +293,19 @@ __fi void dmaIPU1() // toIPU
hwDmacIrq(DMAC_TO_IPU); hwDmacIrq(DMAC_TO_IPU);
} }
if (ipu1ch.chcr.MOD == NORMAL_MODE && ipu1ch.qwc == 0) //avoids freeze when IPU1 Normal error is triggered
{
/*ipu1ch.chcr.STR = false;
// Hack to force stop IPU
ipuRegs.cmd.BUSY = 0;
ipuRegs.ctrl.BUSY = 0;
ipuRegs.topbusy = 0;
//
hwDmacIrq(DMAC_TO_IPU);*/
IPU_LOG("IPU1 Normal error fix");
ipu1ch.qwc = 1;
}
if (ipu1ch.chcr.MOD == CHAIN_MODE) //Chain Mode if (ipu1ch.chcr.MOD == CHAIN_MODE) //Chain Mode
{ {
IPU_LOG("Setting up IPU1 Chain mode"); IPU_LOG("Setting up IPU1 Chain mode");
@ -321,19 +334,6 @@ __fi void dmaIPU1() // toIPU
IPU1dma(); IPU1dma();
} }
else //Normal Mode else //Normal Mode
{
if(ipu1ch.qwc == 0)
{
ipu1ch.chcr.STR = false;
// Hack to force stop IPU
ipuRegs.cmd.BUSY = 0;
ipuRegs.ctrl.BUSY = 0;
ipuRegs.topbusy = 0;
//
hwDmacIrq(DMAC_TO_IPU);
Console.Warning("IPU1 Normal error!");
}
else
{ {
IPU_LOG("Setting up IPU1 Normal mode"); IPU_LOG("Setting up IPU1 Normal mode");
IPU1Status.InProgress = true; IPU1Status.InProgress = true;
@ -342,7 +342,6 @@ __fi void dmaIPU1() // toIPU
IPU1dma(); IPU1dma();
} }
} }
}
extern void GIFdma(); extern void GIFdma();