From 0718e1bd772e641cfad180b42d800f5fb49b46d7 Mon Sep 17 00:00:00 2001
From: Marcos Vitali <marcosvitali@gmail.com>
Date: Wed, 1 Dec 2010 03:04:36 +0000
Subject: [PATCH] More fifo work and the Pokemon teaching us ;) * I've fixed
 concurrency problem with fifo.bFF_GPReadEnable when the breakpoint is
 achieved * I modified when fifo.bFF_Breakpoint is turn off to prevent that
 the  interruption happens * I reverted r6483 * I improved the commit r6495
 adding another protection when the GPRead is enabled in CTRL_REGISTER

You can test Pokemon XD in dual core mode is more estable now :P This commit could solve others hangs fifo related in DKC, Sport Resorts, etc. I dont have these games.



git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6503 8ced0084-cf51-0410-be5f-012b33b47a6e
---
 .../Core/VideoCommon/Src/CommandProcessor.cpp | 45 ++++++++-----------
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
index b505265e80..89aadc1448 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
@@ -401,31 +401,9 @@ void Write16(const u16 _Value, const u32 _Address)
 		{
 			UCPCtrlReg tmpCtrl(_Value);
 			m_CPCtrlReg.Hex = tmpCtrl.Hex;
-
-			//If there is a SetBreakPoint and the actual distance is enought to achieve the BP,
-			//we wait for the FIFO Loop in DC MODE
-			if (g_VideoInitialize.bOnThread && fifo.bFF_BPInt && tmpCtrl.BPInt && fifo.bFF_BPEnable && tmpCtrl.BPEnable)				
-			{
-				bool wait = false;
-				if (fifo.CPReadPointer + fifo.CPReadWriteDistance + 32 > fifo.CPBreakpoint)
-				{
-					wait = true;
-				} //If the distance is >= CPEnd we need to calculate the distane related to CPBase
-				else if (fifo.CPReadPointer + fifo.CPReadWriteDistance  >= fifo.CPEnd) 
-				{
-					if (fifo.CPReadWriteDistance + fifo.CPReadPointer - fifo.CPEnd + 32 > fifo.CPBreakpoint)
-						wait = true;
-				}
-
-				// We waiting for the fifo loop finish
-				while (wait && fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance ||
-					(fifo.bFF_BPEnable && ((fifo.CPReadPointer <= fifo.CPBreakpoint) &&
-					(fifo.CPReadPointer + 32 > fifo.CPBreakpoint)))))
-				{
-					Common::YieldCPU();
-				}					
-			}
-
+			u32 tmpFifoGPReadEnable = fifo.bFF_GPReadEnable;
+			
+			if(fifo.bFF_GPReadEnable && !fifo.bFF_BPInt)
 			Common::AtomicStore(fifo.bFF_Breakpoint, false);
 
 			if (tmpCtrl.FifoUnderflowIntEnable)
@@ -446,7 +424,22 @@ void Write16(const u16 _Value, const u32 _Address)
 
 			fifo.bFF_BPInt = tmpCtrl.BPInt;
 			fifo.bFF_BPEnable = tmpCtrl.BPEnable;
-			fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable;
+			if(tmpFifoGPReadEnable == fifo.bFF_GPReadEnable)
+			{
+				fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable;
+				
+				if  (fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance >= fifo.CPHiWatermark))
+				{
+					// A little trick to prevent FIFO from overflown in dual core mode
+					while (fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance >= fifo.CPHiWatermark))
+						Common::YieldCPU();
+					
+					if (!m_CPStatusReg.OverflowHiWatermark)
+						m_CPStatusReg.OverflowHiWatermark = true;				
+				}
+
+
+			}
 
 			INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value);
 			DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | BP %s | Int %s | OvF %s | UndF %s | LINK %s"