DSPHLE: Don't generate new mail if the DSP is halted

This fixes booting Datel titles with DSPHLE (see https://bugs.dolphin-emu.org/issues/12943). Datel messed up their DSP initialization code, so it only works by receiving a mail later on, but if halting isn't implemented then it receives the mail too early and hangs.
This commit is contained in:
Pokechu22 2022-06-16 15:40:41 -07:00
parent 3aeafcc70b
commit a72fa4b9cc
3 changed files with 8 additions and 9 deletions

View File

@ -196,6 +196,7 @@ u16 DSPHLE::DSP_WriteControlRegister(u16 value)
{
INFO_LOG_FMT(DSPHLE, "DSP_CONTROL halt bit changed: {:04x} -> {:04x}", m_dsp_control.Hex,
value);
m_mail_handler.SetHalted(temp.DSPHalt);
}
if (temp.DSPReset)

View File

@ -39,7 +39,7 @@ void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future)
u16 CMailHandler::ReadDSPMailboxHigh()
{
// check if we have a mail for the CPU core
if (!m_pending_mails.empty())
if (!m_halted && !m_pending_mails.empty())
{
m_last_mail = m_pending_mails.front().first;
}
@ -49,7 +49,7 @@ u16 CMailHandler::ReadDSPMailboxHigh()
u16 CMailHandler::ReadDSPMailboxLow()
{
// check if we have a mail for the CPU core
if (!m_pending_mails.empty())
if (!m_halted && !m_pending_mails.empty())
{
m_last_mail = m_pending_mails.front().first;
const bool generate_interrupt = m_pending_mails.front().second;
@ -79,13 +79,9 @@ bool CMailHandler::HasPending() const
return !m_pending_mails.empty();
}
void CMailHandler::Halt(bool _Halt)
void CMailHandler::SetHalted(bool halt)
{
if (_Halt)
{
ClearPending();
PushMail(0x80544348);
}
m_halted = halt;
}
void CMailHandler::DoState(PointerWrap& p)

View File

@ -20,7 +20,7 @@ public:
// TODO: figure out correct timing for interrupts rather than defaulting to "immediately."
void PushMail(u32 mail, bool interrupt = false, int cycles_into_future = 0);
void Halt(bool _Halt);
void SetHalted(bool halt);
void DoState(PointerWrap& p);
bool HasPending() const;
@ -42,5 +42,7 @@ private:
// If no pending mail exists, the last mail that was read is returned,
// but with the top bit (0x80000000) cleared.
u32 m_last_mail = 0;
// When halted, the DSP itself is not running, but the last mail can be read.
bool m_halted = false;
};
} // namespace DSP::HLE