Only honor T and D bits if E bit has not been encountered.

Fixes Silent Hill 2 hanging at movies.
This commit is contained in:
Jean-Philip Desjardins 2024-09-12 13:14:56 -04:00
parent f5bcb8bb1d
commit 3fd5b7a56c
4 changed files with 24 additions and 8 deletions

View file

@ -261,7 +261,7 @@ void CBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
jitter->BeginIf(Jitter::CONDITION_LE);
{
jitter->PushRel(offsetof(CMIPS, m_State.nHasException));
jitter->PushCst(MIPS_EXECUTION_STATUS_QUOTADONE);
jitter->PushCst(MIPS_EXCEPTION_STATUS_QUOTADONE);
jitter->Or();
jitter->PullRel(offsetof(CMIPS, m_State.nHasException));
}

View file

@ -69,7 +69,7 @@ public:
auto block = m_blockLookup.FindBlockAt(address);
block->Execute();
}
m_context.m_State.nHasException &= ~MIPS_EXECUTION_STATUS_QUOTADONE;
m_context.m_State.nHasException &= ~MIPS_EXCEPTION_STATUS_QUOTADONE;
#ifdef DEBUGGER_INCLUDED
if(m_context.m_State.nHasException == MIPS_EXCEPTION_BREAKPOINT)
{

View file

@ -45,7 +45,11 @@ enum
MIPS_EXCEPTION_VU_DBIT,
MIPS_EXCEPTION_VU_TBIT,
MIPS_EXCEPTION_VU_EBIT,
MIPS_EXCEPTION_MAX, //Used to make sure we don't conflict with the QUOTADONE status
};
static_assert(MIPS_EXCEPTION_MAX <= 0x80);
static constexpr uint32 MIPS_EXCEPTION_STATUS_QUOTADONE = 0x80;
struct TLBENTRY
{
@ -55,8 +59,6 @@ struct TLBENTRY
uint32 pageMask;
};
#define MIPS_EXECUTION_STATUS_QUOTADONE 0x80
struct MIPSSTATE
{
uint32 nPC;

View file

@ -30,16 +30,30 @@ void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, C
((this)->*(m_pOpVector[m_nOpcode & 0x3F]))();
auto setTDBitException = [&](uint32 exceptionValue) {
//Only set TD bit exception if there's no other outstanding
//exceptions (ie.: E bit). We could set a bit for every stop bit
//we encounter, but we assume that no game relies on multiple bits
//being set.
//This assumes that QUOTADONE is only set at the end
m_codeGen->PushRel(offsetof(CMIPS, m_State.nHasException));
m_codeGen->PushCst(0);
m_codeGen->BeginIf(Jitter::CONDITION_EQ);
{
m_codeGen->PushCst(exceptionValue);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}
m_codeGen->EndIf();
};
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_D)
{
m_codeGen->PushCst(MIPS_EXCEPTION_VU_DBIT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
setTDBitException(MIPS_EXCEPTION_VU_DBIT);
}
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_T)
{
m_codeGen->PushCst(MIPS_EXCEPTION_VU_TBIT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
setTDBitException(MIPS_EXCEPTION_VU_TBIT);
}
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_I)