summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-06-16 15:40:41 -0700
committerPokechu22 <Pokechu022@gmail.com>2022-06-22 09:57:33 -0700
commita72fa4b9ccabf5113a903f880e7df64e9dffc467 (patch)
treed913ae8dc024b450cbc75675cae7de00304cb6b4 /Source/Core
parent3aeafcc70b4358d0a9736d5c654fd8b9e30e4ead (diff)
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.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/DSPHLE/DSPHLE.cpp1
-rw-r--r--Source/Core/Core/HW/DSPHLE/MailHandler.cpp12
-rw-r--r--Source/Core/Core/HW/DSPHLE/MailHandler.h4
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