mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 00:39:23 +01:00
DSPHLE: Return last mail with top bit cleared if there is no new mail
This is an accuracy improvement, though I don't think it matters for anything in practice.
This commit is contained in:
parent
bdbb23fa1a
commit
3aeafcc70b
@ -41,10 +41,9 @@ 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_pending_mails.empty())
|
||||||
{
|
{
|
||||||
u16 result = (m_pending_mails.front().first >> 16) & 0xFFFF;
|
m_last_mail = m_pending_mails.front().first;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return 0x00;
|
return u16(m_last_mail >> 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 CMailHandler::ReadDSPMailboxLow()
|
u16 CMailHandler::ReadDSPMailboxLow()
|
||||||
@ -52,18 +51,22 @@ 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_pending_mails.empty())
|
||||||
{
|
{
|
||||||
u16 result = m_pending_mails.front().first & 0xFFFF;
|
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;
|
||||||
|
|
||||||
m_pending_mails.pop_front();
|
m_pending_mails.pop_front();
|
||||||
|
|
||||||
if (generate_interrupt)
|
if (generate_interrupt)
|
||||||
{
|
{
|
||||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return 0x00;
|
// Clear the top bit of the high mail word after the mail has been read.
|
||||||
|
// The remaining bits read back the same as the previous mail, until new mail sent.
|
||||||
|
// (The CPU reads the high word first, and then the low word; since this function returns the low
|
||||||
|
// word, this means that the next read of the high word will have the top bit cleared.)
|
||||||
|
m_last_mail &= ~0x8000'0000;
|
||||||
|
return u16(m_last_mail & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMailHandler::ClearPending()
|
void CMailHandler::ClearPending()
|
||||||
|
@ -27,6 +27,8 @@ public:
|
|||||||
// Clear any pending mail from the current uCode. This is called by DSPHLE::SetUCode and
|
// Clear any pending mail from the current uCode. This is called by DSPHLE::SetUCode and
|
||||||
// DSPHLE::SwapUCode. Since pending mail is an abstraction for DSPHLE and not something that
|
// DSPHLE::SwapUCode. Since pending mail is an abstraction for DSPHLE and not something that
|
||||||
// actually exists on real hardware, HLE implementations do not need to call this directly.
|
// actually exists on real hardware, HLE implementations do not need to call this directly.
|
||||||
|
// Note that this function does not reset m_last_mail, which will continue to read the same value
|
||||||
|
// until the new uCode sends mail.
|
||||||
void ClearPending();
|
void ClearPending();
|
||||||
|
|
||||||
u16 ReadDSPMailboxHigh();
|
u16 ReadDSPMailboxHigh();
|
||||||
@ -37,5 +39,8 @@ private:
|
|||||||
// mails. But for HLE, it's a lot easier to write all the mails that will be read ahead of time,
|
// mails. But for HLE, it's a lot easier to write all the mails that will be read ahead of time,
|
||||||
// and then give them to the CPU in the requested order.
|
// and then give them to the CPU in the requested order.
|
||||||
std::deque<std::pair<u32, bool>> m_pending_mails;
|
std::deque<std::pair<u32, bool>> m_pending_mails;
|
||||||
|
// 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;
|
||||||
};
|
};
|
||||||
} // namespace DSP::HLE
|
} // namespace DSP::HLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user