diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 8482d30966..c1b5be46fe 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -282,7 +282,7 @@ void Init() et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback); et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback); // Always register this. Increases chances of DC/SC save state compatibility. - et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback); +// et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback); et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback); CoreTiming::ScheduleEvent(AI_PERIOD, et_AI); @@ -292,8 +292,8 @@ void Init() CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA); // For DC watchdog hack - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_FakeGPWD); +// if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) +// CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_FakeGPWD); CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_PatchEngine); diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 6f9872dd90..5fbf6494d9 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -98,6 +98,9 @@ UCPStatusReg m_CPStatusReg; UCPCtrlReg m_CPCtrlReg; UCPClearReg m_CPClearReg; +int m_tempHWM, m_tempLWM; +int m_tempBP; + int m_bboxleft; int m_bboxtop; int m_bboxright; @@ -120,6 +123,9 @@ void FifoCriticalLeave() void DoState(PointerWrap &p) { + p.Do(m_tempHWM); + p.Do(m_tempLWM); + p.Do(m_tempBP); p.Do(m_CPStatusReg); p.Do(m_CPCtrlReg); //p.Do(m_CPClearReg); @@ -159,7 +165,7 @@ void Init() memset(&fifo,0,sizeof(fifo)); fifo.CPCmdIdle = 1 ; fifo.CPReadIdle = 1; - fifo.bFF_Breakpoint = 1; + fifo.bFF_Breakpoint = 0; s_fifoIdleEvent.Init(); @@ -195,8 +201,6 @@ 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; @@ -379,8 +383,10 @@ 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.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))) + while (fifo.CPReadWriteDistance) { + if (!fifo.bFF_GPReadEnable) + Common::AtomicStore(fifo.bFF_GPReadEnable, 1); s_fifoIdleEvent.Wait(); } } @@ -405,16 +411,11 @@ 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 && tmpCtrl.BPEnable && tmpCtrl.GPReadEnable) + if (tmpCtrl.BPInit) { - // Clear old BP and initiate new BP + // Clear BP + UpdateInterrupts(false); 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); @@ -494,29 +495,29 @@ void Write16(const u16 _Value, const u32 _Address) break; case FIFO_HI_WATERMARK_LO: - WriteLow ((u32 &)fifo.CPHiWatermark, _Value); + m_tempHWM = (u32)_Value; DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_LO : %04x", _Value); break; case FIFO_HI_WATERMARK_HI: - WriteHigh((u32 &)fifo.CPHiWatermark, _Value); + Common::AtomicStore(fifo.CPHiWatermark, (u32)_Value << 16 | m_tempHWM); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI : %04x", _Value); break; case FIFO_LO_WATERMARK_LO: - WriteLow ((u32 &)fifo.CPLoWatermark, _Value); + m_tempLWM = (u32)_Value; DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_LO : %04x", _Value); break; case FIFO_LO_WATERMARK_HI: - WriteHigh((u32 &)fifo.CPLoWatermark, _Value); + Common::AtomicStore(fifo.CPLoWatermark, (u32)_Value << 16 | m_tempLWM); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_HI : %04x", _Value); break; case FIFO_BP_LO: - WriteLow ((u32 &)fifo.CPBreakpoint, _Value); + m_tempBP = (u32)_Value; DEBUG_LOG(COMMANDPROCESSOR,"write to FIFO_BP_LO : %04x", _Value); break; case FIFO_BP_HI: - WriteHigh((u32 &)fifo.CPBreakpoint, _Value); + Common::AtomicStore(fifo.CPBreakpoint, (u32)_Value << 16 | m_tempBP); DEBUG_LOG(COMMANDPROCESSOR,"write to FIFO_BP_HI : %04x", _Value); break; @@ -616,8 +617,10 @@ 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 && fifo.bFF_GPReadEnable && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))) + while (fifo.CPReadWriteDistance > fifo.CPLoWatermark) { + 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 099084fae5..10319a7557 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.bFF_BPEnable && _fifo.CPReadWriteDistance) || (_fifo.bFF_BPEnable && !_fifo.bFF_Breakpoint))) + while (_fifo.bFF_GPReadEnable && _fifo.CPReadWriteDistance) { if (!fifoStateRun) break; @@ -160,46 +160,17 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) u8 *uData = video_initialize.pGetMemoryPointer(readPtr); // NOTICE_LOG(BOOT, "readPtr: %08x uData %08x", readPtr, uData); - // If we are in BP mode we only send 32B chunks to Video plugin for BP checking - if (_fifo.bFF_BPEnable) + 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? { - // 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; + distToSend =(_fifo.CPEnd + 32) - readPtr; + readPtr = _fifo.CPBase; } - // If we are not in BP mode we send all the chunk we have to speed up else - { - 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; - } + readPtr += distToSend; // Execute new instructions found in uData Fifo_SendFifoData(uData, distToSend); @@ -215,6 +186,13 @@ 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();