From a72fa4b9ccabf5113a903f880e7df64e9dffc467 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 16 Jun 2022 15:40:41 -0700 Subject: [PATCH] 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. --- Source/Core/Core/HW/DSPHLE/DSPHLE.cpp | 1 + Source/Core/Core/HW/DSPHLE/MailHandler.cpp | 12 ++++-------- Source/Core/Core/HW/DSPHLE/MailHandler.h | 4 +++- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp index 9e17a78ecc..b8d3b8e5a2 100644 --- a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp @@ -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) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index fc5b22b778..f297b6f53c 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -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) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index c036a9f72d..ee38bcde53 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -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