mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-01 23:54:21 +00:00
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:
parent
3aeafcc70b
commit
a72fa4b9cc
@ -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,
|
INFO_LOG_FMT(DSPHLE, "DSP_CONTROL halt bit changed: {:04x} -> {:04x}", m_dsp_control.Hex,
|
||||||
value);
|
value);
|
||||||
|
m_mail_handler.SetHalted(temp.DSPHalt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp.DSPReset)
|
if (temp.DSPReset)
|
||||||
|
@ -39,7 +39,7 @@ void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future)
|
|||||||
u16 CMailHandler::ReadDSPMailboxHigh()
|
u16 CMailHandler::ReadDSPMailboxHigh()
|
||||||
{
|
{
|
||||||
// check if we have a mail for the CPU core
|
// 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;
|
m_last_mail = m_pending_mails.front().first;
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ u16 CMailHandler::ReadDSPMailboxHigh()
|
|||||||
u16 CMailHandler::ReadDSPMailboxLow()
|
u16 CMailHandler::ReadDSPMailboxLow()
|
||||||
{
|
{
|
||||||
// check if we have a mail for the CPU core
|
// 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;
|
m_last_mail = m_pending_mails.front().first;
|
||||||
const bool generate_interrupt = m_pending_mails.front().second;
|
const bool generate_interrupt = m_pending_mails.front().second;
|
||||||
@ -79,13 +79,9 @@ bool CMailHandler::HasPending() const
|
|||||||
return !m_pending_mails.empty();
|
return !m_pending_mails.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMailHandler::Halt(bool _Halt)
|
void CMailHandler::SetHalted(bool halt)
|
||||||
{
|
{
|
||||||
if (_Halt)
|
m_halted = halt;
|
||||||
{
|
|
||||||
ClearPending();
|
|
||||||
PushMail(0x80544348);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMailHandler::DoState(PointerWrap& p)
|
void CMailHandler::DoState(PointerWrap& p)
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
// TODO: figure out correct timing for interrupts rather than defaulting to "immediately."
|
// 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 PushMail(u32 mail, bool interrupt = false, int cycles_into_future = 0);
|
||||||
void Halt(bool _Halt);
|
void SetHalted(bool halt);
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
bool HasPending() const;
|
bool HasPending() const;
|
||||||
|
|
||||||
@ -42,5 +42,7 @@ private:
|
|||||||
// If no pending mail exists, the last mail that was read is returned,
|
// If no pending mail exists, the last mail that was read is returned,
|
||||||
// but with the top bit (0x80000000) cleared.
|
// but with the top bit (0x80000000) cleared.
|
||||||
u32 m_last_mail = 0;
|
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
|
} // namespace DSP::HLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user