This commit fix games hanging because of my prior Revision c2e6fdf09f
The external exceptions in dolphin are checking frequently but is different to real HW, so sometime the game is in a loop checking GPU STATUS, the exceptions doesn't checked, and the game hang.\
For solve this I need a trick: still waiting for the exception handler be linked but if CommandProcecsor is reading the GPStatus, resume this.
This fixed "TimeSplitters: Future Perfect" broken in the Revision c2e6fdf09f
and surely others games.
This commit is contained in:
parent
41652d6b1f
commit
104603467b
|
@ -574,7 +574,7 @@ void ProcessFifoAllDistance()
|
||||||
if (IsOnThread())
|
if (IsOnThread())
|
||||||
{
|
{
|
||||||
while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable &&
|
while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable &&
|
||||||
fifo.CPReadWriteDistance && !AtBreakpoint())
|
fifo.CPReadWriteDistance && !AtBreakpoint() && !PixelEngine::WaitingForPEInterrupt())
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
}
|
}
|
||||||
bProcessFifoAllDistance = false;
|
bProcessFifoAllDistance = false;
|
||||||
|
@ -597,10 +597,12 @@ void SetCpStatusRegister()
|
||||||
|
|
||||||
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
||||||
m_CPStatusReg.ReadIdle = (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
|
m_CPStatusReg.ReadIdle = (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
|
||||||
m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance || (IsOnThread() && PixelEngine::WaitingForPEInterrupt());
|
m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance;
|
||||||
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
|
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
|
||||||
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
|
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
|
||||||
|
|
||||||
|
PixelEngine::ResumeWaitingForPEInterrupt();
|
||||||
|
|
||||||
INFO_LOG(COMMANDPROCESSOR,"\t Read from STATUS_REGISTER : %04x", m_CPStatusReg.Hex);
|
INFO_LOG(COMMANDPROCESSOR,"\t Read from STATUS_REGISTER : %04x", m_CPStatusReg.Hex);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "(r) status: iBP %s | fReadIdle %s | fCmdIdle %s | iOvF %s | iUndF %s"
|
DEBUG_LOG(COMMANDPROCESSOR, "(r) status: iBP %s | fReadIdle %s | fCmdIdle %s | iOvF %s | iUndF %s"
|
||||||
, m_CPStatusReg.Breakpoint ? "ON" : "OFF"
|
, m_CPStatusReg.Breakpoint ? "ON" : "OFF"
|
||||||
|
@ -609,6 +611,8 @@ void SetCpStatusRegister()
|
||||||
, m_CPStatusReg.OverflowHiWatermark ? "ON" : "OFF"
|
, m_CPStatusReg.OverflowHiWatermark ? "ON" : "OFF"
|
||||||
, m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF"
|
, m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCpControlRegister()
|
void SetCpControlRegister()
|
||||||
|
|
|
@ -356,22 +356,16 @@ void UpdateInterrupts()
|
||||||
|
|
||||||
void UpdateTokenInterrupt(bool active)
|
void UpdateTokenInterrupt(bool active)
|
||||||
{
|
{
|
||||||
if(interruptSetToken != active)
|
|
||||||
{
|
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN, active);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN, active);
|
||||||
interruptSetToken = active;
|
interruptSetToken = active;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateFinishInterrupt(bool active)
|
void UpdateFinishInterrupt(bool active)
|
||||||
{
|
{
|
||||||
if(interruptSetFinish != active)
|
|
||||||
{
|
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH, active);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH, active);
|
||||||
interruptSetFinish = active;
|
interruptSetFinish = active;
|
||||||
if (active)
|
if (active)
|
||||||
State::ProcessRequestedStates(0);
|
State::ProcessRequestedStates(0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mb2): Refactor SetTokenINT_OnMainThread(u64 userdata, int cyclesLate).
|
// TODO(mb2): Refactor SetTokenINT_OnMainThread(u64 userdata, int cyclesLate).
|
||||||
|
@ -473,4 +467,12 @@ bool WaitingForPEInterrupt()
|
||||||
{
|
{
|
||||||
return CommandProcessor::interruptFinishWaiting || CommandProcessor::interruptTokenWaiting || interruptSetFinish || interruptSetToken;
|
return CommandProcessor::interruptFinishWaiting || CommandProcessor::interruptTokenWaiting || interruptSetFinish || interruptSetToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResumeWaitingForPEInterrupt()
|
||||||
|
{
|
||||||
|
interruptSetFinish = false;
|
||||||
|
interruptSetToken = false;
|
||||||
|
CommandProcessor::interruptFinishWaiting = false;
|
||||||
|
CommandProcessor::interruptTokenWaiting = false;
|
||||||
|
}
|
||||||
} // end of namespace PixelEngine
|
} // end of namespace PixelEngine
|
||||||
|
|
|
@ -81,6 +81,7 @@ void SetFinish(void);
|
||||||
void ResetSetFinish(void);
|
void ResetSetFinish(void);
|
||||||
void ResetSetToken(void);
|
void ResetSetToken(void);
|
||||||
bool WaitingForPEInterrupt();
|
bool WaitingForPEInterrupt();
|
||||||
|
void ResumeWaitingForPEInterrupt();
|
||||||
|
|
||||||
// Bounding box functionality. Paper Mario (both) are a couple of the few games that use it.
|
// Bounding box functionality. Paper Mario (both) are a couple of the few games that use it.
|
||||||
extern u16 bbox[4];
|
extern u16 bbox[4];
|
||||||
|
|
Loading…
Reference in New Issue