From be193088cac02d969b5ea2124fde76148b0480e9 Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Sun, 13 Feb 2011 15:08:37 +0000 Subject: [PATCH] - FIX RE0 GFX fifo errors :D - This game read the CPRead pointer when the GP is processing data and after detach the fifo and attach again an use this pointer for continue, so implement fifo.SafeCPReadPointer pointer. - fifo.SafeCPReadPointer is updated when (FAKE_GetFifoEndPtr() - g_pVideoData) == 0) to have a pointer without GFX Commands Cut in the beginning of 32 block. - Reset video buffer when the CPReadWriteDistance is written by the software. - This commit is experimental please test a lot your games. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7165 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/VideoBackendBase.h | 2 +- .../Core/VideoCommon/Src/CommandProcessor.cpp | 17 +++++++++++++---- Source/Core/VideoCommon/Src/Fifo.cpp | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/Common/Src/VideoBackendBase.h index 798750ca73..3e9c71bfb9 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/Common/Src/VideoBackendBase.h @@ -49,7 +49,7 @@ struct SCPFifoStruct volatile u32 CPWritePointer; volatile u32 CPReadPointer; volatile u32 CPBreakpoint; - + volatile u32 SafeCPReadPointer; // Super Monkey Ball Adventure require this. // Because the read&check-PEToken-loop stays in its JITed block I suppose. // So no possiblity to ack the Token irq by the scheduler until some sort of PPC watchdog do its mess. diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index a8ee3c8df6..05ebd1ede2 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -284,13 +284,19 @@ void Read16(u16& _rReturnValue, const u32 _Address) return; case FIFO_READ_POINTER_LO: - _rReturnValue = ReadLow (fifo.CPReadPointer); + if (IsOnThread()) + _rReturnValue = ReadLow (fifo.SafeCPReadPointer); + else + _rReturnValue = ReadLow (fifo.CPReadPointer); // hack: CPU will always believe fifo is empty and on idle //_rReturnValue = ReadLow (fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_LO : %04x", _rReturnValue); return; case FIFO_READ_POINTER_HI: - _rReturnValue = ReadHigh(fifo.CPReadPointer); + if (IsOnThread()) + _rReturnValue = ReadHigh (fifo.SafeCPReadPointer); + else + _rReturnValue = ReadHigh (fifo.CPReadPointer); // hack: CPU will always believe fifo is empty and on idle //_rReturnValue = ReadHigh(fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_HI : %04x", _rReturnValue); @@ -614,8 +620,11 @@ void Write16(const u16 _Value, const u32 _Address) { GPFifo::ResetGatherPipe(); ResetVideoBuffer(); - IncrementCheckContextId(); - } + }else + { + ResetVideoBuffer(); + } + IncrementCheckContextId(); DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_LO : %04x", _Value); break; diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 18daeec5b7..f459fd4ef6 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -169,7 +169,8 @@ void Fifo_EnterLoop() Common::AtomicStore(_fifo.CPReadPointer, readPtr); Common::AtomicAdd(_fifo.CPReadWriteDistance, -distToSend); - + if((FAKE_GetFifoEndPtr() - g_pVideoData) == 0) + Common::AtomicStore(_fifo.SafeCPReadPointer, _fifo.CPReadPointer); CommandProcessor::SetStatus(); // This call is pretty important in DualCore mode and must be called in the FIFO Loop.