From 7e27914b45737117e9ce204330e12f10f79f4e21 Mon Sep 17 00:00:00 2001 From: ayuanx Date: Sun, 13 Jun 2010 23:26:22 +0000 Subject: [PATCH] Revert r5681 git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5685 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/VideoCommon/Src/CommandProcessor.cpp | 23 ++++---- Source/Core/VideoCommon/Src/Fifo.cpp | 54 +++++++++++++------ 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 5fbf6494d9..28712c271d 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -165,7 +165,7 @@ void Init() memset(&fifo,0,sizeof(fifo)); fifo.CPCmdIdle = 1 ; fifo.CPReadIdle = 1; - fifo.bFF_Breakpoint = 0; + fifo.bFF_Breakpoint = 1; s_fifoIdleEvent.Init(); @@ -201,6 +201,8 @@ void Read16(u16& _rReturnValue, const u32 _Address) ); _rReturnValue = m_CPStatusReg.Hex; + // Clear on read + UpdateInterrupts(false); return; case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return; @@ -383,10 +385,8 @@ void Write16(const u16 _Value, const u32 _Address) DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************"); // (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC) // Touching that game is a no-go so I don't want to take the risk :p - while (fifo.CPReadWriteDistance) + while (fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))) { - if (!fifo.bFF_GPReadEnable) - Common::AtomicStore(fifo.bFF_GPReadEnable, 1); s_fifoIdleEvent.Wait(); } } @@ -411,11 +411,16 @@ void Write16(const u16 _Value, const u32 _Address) Common::AtomicStore(fifo.bFF_GPReadEnable, tmpCtrl.GPReadEnable); Common::AtomicStore(fifo.bFF_BPEnable, tmpCtrl.BPEnable); - if (tmpCtrl.BPInit) + if (tmpCtrl.BPInit && tmpCtrl.BPEnable && tmpCtrl.GPReadEnable) { - // Clear BP - UpdateInterrupts(false); + // Clear old BP and initiate new BP Common::AtomicStore(fifo.bFF_Breakpoint, 0); + + // The following is a hack of Synchronized Breakpoint for dual core mode + // Some games only waits a finite N cycles for FIFO interrupts, then hangs up on time out + // e.g. Metriod Prime 2 + if (g_VideoInitialize.bOnThread && g_ActiveConfig.bFIFOBPhack) + UpdateInterrupts(true); } INFO_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); @@ -617,10 +622,8 @@ void STACKALIGN GatherPipeBursted() INFO_LOG(COMMANDPROCESSOR, "(GatherPipeBursted): CPHiWatermark (Hi: 0x%04x, Lo: 0x%04x) reached (RWDistance: 0x%04x)", fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance); // Wait for GPU to catch up - while (fifo.CPReadWriteDistance > fifo.CPLoWatermark) + while (fifo.CPReadWriteDistance > fifo.CPLoWatermark && fifo.bFF_GPReadEnable && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))) { - if (!fifo.bFF_GPReadEnable) - Common::AtomicStore(fifo.bFF_GPReadEnable, 1); s_fifoIdleEvent.Wait(); } } diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 10319a7557..099084fae5 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -148,7 +148,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) VideoFifo_CheckSwapRequest(); // check if we are able to run this buffer - while (_fifo.bFF_GPReadEnable && _fifo.CPReadWriteDistance) + while (_fifo.bFF_GPReadEnable && ((!_fifo.bFF_BPEnable && _fifo.CPReadWriteDistance) || (_fifo.bFF_BPEnable && !_fifo.bFF_Breakpoint))) { if (!fifoStateRun) break; @@ -160,17 +160,46 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) u8 *uData = video_initialize.pGetMemoryPointer(readPtr); // NOTICE_LOG(BOOT, "readPtr: %08x uData %08x", readPtr, uData); - distToSend = _fifo.CPReadWriteDistance; - // send 1024B chunk max length to have better control over PeekMessages' period - distToSend = distToSend > 1024 ? 1024 : distToSend; - // add 32 bytes because the cp end points to the start of the last 32 byte chunk - if ((distToSend + readPtr) >= (_fifo.CPEnd + 32)) // TODO: better? + // If we are in BP mode we only send 32B chunks to Video plugin for BP checking + if (_fifo.bFF_BPEnable) { - distToSend =(_fifo.CPEnd + 32) - readPtr; - readPtr = _fifo.CPBase; + // Sometimes we have already exceeded the BP even before it is set + // so careful check is required + if ( + (readPtr == _fifo.CPBreakpoint) || + //(readPtr <= _fifo.CPBreakpoint && readPtr + 32 > _fifo.CPBreakpoint) || + (readPtr <= _fifo.CPWritePointer && _fifo.CPWritePointer < _fifo.CPBreakpoint) || + (readPtr <= _fifo.CPWritePointer && readPtr > _fifo.CPBreakpoint) || + (readPtr > _fifo.CPBreakpoint && _fifo.CPBreakpoint > _fifo.CPWritePointer) + ) + { + Common::AtomicStore(_fifo.bFF_Breakpoint, 1); + CommandProcessor::UpdateInterruptsFromVideoPlugin(true); + CommandProcessor::FifoCriticalLeave(); + break; + } + distToSend = 32; + + if ( readPtr >= _fifo.CPEnd) + readPtr = _fifo.CPBase; + else + readPtr += 32; } + // If we are not in BP mode we send all the chunk we have to speed up else - readPtr += distToSend; + { + distToSend = _fifo.CPReadWriteDistance; + // send 1024B chunk max length to have better control over PeekMessages' period + distToSend = distToSend > 1024 ? 1024 : distToSend; + // add 32 bytes because the cp end points to the start of the last 32 byte chunk + if ((distToSend + readPtr) >= (_fifo.CPEnd + 32)) // TODO: better? + { + distToSend =(_fifo.CPEnd + 32) - readPtr; + readPtr = _fifo.CPBase; + } + else + readPtr += distToSend; + } // Execute new instructions found in uData Fifo_SendFifoData(uData, distToSend); @@ -186,13 +215,6 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) VideoFifo_CheckEFBAccess(); VideoFifo_CheckSwapRequest(); } - - if (_fifo.bFF_BPEnable && !_fifo.bFF_Breakpoint) - { - Common::AtomicStore(_fifo.bFF_Breakpoint, 1); - CommandProcessor::UpdateInterruptsFromVideoPlugin(true); - } - CommandProcessor::SetFifoIdleFromVideoPlugin(); if (EmuRunning) Common::YieldCPU();