summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2013-01-25 20:04:31 +1100
committerskidau <skidau@gmail.com>2013-01-25 20:04:31 +1100
commit1b6240f7f972caef7c53a7a51ff71b4653b3f00a (patch)
tree78aa4d8dd22b628068d41c41c7b4b826fa16d856 /Source/Core/VideoCommon
parent2cc1a97a66c2d96357e777cd507acaaac888116f (diff)
Changed cmdidle to be idle on breakpoint.
Added low watermark interrupts generated by the gather pipe. Fixes Gladius from not booting. Fixes issue 5518.
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.cpp22
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.h1
-rw-r--r--Source/Core/VideoCommon/Src/Fifo.cpp4
3 files changed, 21 insertions, 6 deletions
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
index a4dddf537f..1c0b43a835 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
@@ -57,6 +57,7 @@ static bool bProcessFifoAllDistance = false;
volatile bool isPossibleWaitingSetDrawDone = false;
volatile bool isHiWatermarkActive = false;
+volatile bool isLoWatermarkActive = false;
volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
volatile bool interruptTokenWaiting = false;
@@ -88,6 +89,7 @@ void DoState(PointerWrap &p)
p.Do(bProcessFifoToLoWatermark);
p.Do(bProcessFifoAllDistance);
p.Do(isHiWatermarkActive);
+ p.Do(isLoWatermarkActive);
p.Do(isPossibleWaitingSetDrawDone);
p.Do(interruptSet);
p.Do(interruptWaiting);
@@ -119,7 +121,7 @@ void Init()
m_tokenReg = 0;
memset(&fifo,0,sizeof(fifo));
- fifo.CPCmdIdle = 1 ;
+ fifo.CPCmdIdle = 1;
fifo.CPReadIdle = 1;
fifo.bFF_Breakpoint = 0;
fifo.bFF_HiWatermark = 0;
@@ -136,6 +138,7 @@ void Init()
bProcessFifoAllDistance = false;
isPossibleWaitingSetDrawDone = false;
isHiWatermarkActive = false;
+ isLoWatermarkActive = false;
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
}
@@ -294,7 +297,6 @@ void Read16(u16& _rReturnValue, const u32 _Address)
void Write16(const u16 _Value, const u32 _Address)
{
-
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
switch (_Address & 0xFFF)
@@ -405,7 +407,8 @@ void Write16(const u16 _Value, const u32 _Address)
{
GPFifo::ResetGatherPipe();
ResetVideoBuffer();
- }else
+ }
+ else
{
ResetVideoBuffer();
}
@@ -514,7 +517,9 @@ void AbortFrame()
void SetOverflowStatusFromGatherPipe()
{
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
+ fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
isHiWatermarkActive = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt && m_CPCtrlReg.GPReadEnable;
+ isLoWatermarkActive = fifo.bFF_LoWatermark && fifo.bFF_LoWatermarkInt && m_CPCtrlReg.GPReadEnable;
if (isHiWatermarkActive)
{
@@ -522,6 +527,12 @@ void SetOverflowStatusFromGatherPipe()
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
}
+ else if (isLoWatermarkActive)
+ {
+ interruptSet = true;
+ INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
+ ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
+ }
}
void SetCpStatus()
@@ -562,7 +573,8 @@ void SetCpStatus()
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
- isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
+ isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
+ isLoWatermarkActive = undfInt && m_CPCtrlReg.GPReadEnable;
if (interrupt != interruptSet && !interruptWaiting)
{
@@ -618,7 +630,7 @@ void SetCpStatusRegister()
// Here always there is one fifo attached to the GPU
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
- m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance;
+ m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance || AtBreakpoint();
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h
index 5d31453537..d70bcf475c 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.h
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.h
@@ -31,6 +31,7 @@ namespace CommandProcessor
extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread.
extern volatile bool isPossibleWaitingSetDrawDone; //This one is used for sync gfx thread and emulator thread.
extern volatile bool isHiWatermarkActive;
+extern volatile bool isLoWatermarkActive;
extern volatile bool interruptSet;
extern volatile bool interruptWaiting;
extern volatile bool interruptTokenWaiting;
diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp
index 50aa21ebbf..e21cc94da2 100644
--- a/Source/Core/VideoCommon/Src/Fifo.cpp
+++ b/Source/Core/VideoCommon/Src/Fifo.cpp
@@ -155,6 +155,7 @@ void RunGpuLoop()
VideoFifo_CheckAsyncRequest();
CommandProcessor::SetCpStatus();
+
// check if we are able to run this buffer
while (GpuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() && !PixelEngine::WaitingForPEInterrupt())
{
@@ -172,7 +173,7 @@ void RunGpuLoop()
_assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 ,
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", fifo.CPReadWriteDistance - 32);
- ReadDataFromFifo(uData, 32);
+ ReadDataFromFifo(uData, 32);
OpcodeDecoder_Run(g_bSkipCurrentFrame);
@@ -180,6 +181,7 @@ void RunGpuLoop()
Common::AtomicAdd(fifo.CPReadWriteDistance, -32);
if((GetVideoBufferEndPtr() - g_pVideoData) == 0)
Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
+
CommandProcessor::SetCpStatus();
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.