From b063f15dccf030e9b4fdeac189f779181d25db9c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 8 Jun 2022 20:22:20 -0700 Subject: [PATCH 1/6] DSPHLE: Replace CMailHandler::IsEmpty with CMailHandler::HasPending --- Source/Core/Core/HW/DSPHLE/MailHandler.cpp | 4 ++-- Source/Core/Core/HW/DSPHLE/MailHandler.h | 2 +- Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp | 4 ++-- Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index ce6b8f8a1a..46019abc6f 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -75,9 +75,9 @@ void CMailHandler::Clear() m_Mails.pop(); } -bool CMailHandler::IsEmpty() const +bool CMailHandler::HasPending() const { - return m_Mails.empty(); + return !m_Mails.empty(); } void CMailHandler::Halt(bool _Halt) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index e5afbc9869..773cf042bb 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -23,7 +23,7 @@ public: void Clear(); void Halt(bool _Halt); void DoState(PointerWrap& p); - bool IsEmpty() const; + bool HasPending() const; u16 ReadDSPMailboxHigh(); u16 ReadDSPMailboxLow(); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp index bf8da5db10..23ee74bec8 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp @@ -28,8 +28,8 @@ void CARDUCode::Initialize() void CARDUCode::Update() { - // check if we have to sent something - if (!m_mail_handler.IsEmpty()) + // check if we have something to send + if (m_mail_handler.HasPending()) { DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp index 6704a489ec..49816fe6fd 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp @@ -85,8 +85,8 @@ void GBAUCode::Initialize() void GBAUCode::Update() { - // check if we have to send something - if (!m_mail_handler.IsEmpty()) + // check if we have something to send + if (m_mail_handler.HasPending()) { DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); } From 567f9bede4db4298c709c5234bfa103c2a3fd279 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 8 Jun 2022 19:59:27 -0700 Subject: [PATCH 2/6] DSPHLE: Remove unneeded calls to m_mail_handler.Clear() It's cleared whenever the uCode changes, so there's no reason to clear it in a destructor or during initialization. I've also renamed it to ClearPending. --- Source/Core/Core/HW/DSPHLE/DSPHLE.cpp | 4 ++-- Source/Core/Core/HW/DSPHLE/MailHandler.cpp | 7 +++---- Source/Core/Core/HW/DSPHLE/MailHandler.h | 6 +++++- Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp | 1 - Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp | 1 - Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp | 1 - Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp | 1 - Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp | 1 - 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp index c686930383..9e17a78ecc 100644 --- a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp @@ -67,7 +67,7 @@ void DSPHLE::SendMailToDSP(u32 mail) void DSPHLE::SetUCode(u32 crc) { - m_mail_handler.Clear(); + m_mail_handler.ClearPending(); m_ucode = UCodeFactory(crc, this, m_wii); m_ucode->Initialize(); } @@ -77,7 +77,7 @@ void DSPHLE::SetUCode(u32 crc) // Even callers are deleted. void DSPHLE::SwapUCode(u32 crc) { - m_mail_handler.Clear(); + m_mail_handler.ClearPending(); if (m_last_ucode && UCodeInterface::GetCRC(m_last_ucode.get()) == crc) { diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index 46019abc6f..b1d0377ec2 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -19,7 +19,6 @@ CMailHandler::CMailHandler() CMailHandler::~CMailHandler() { - Clear(); } void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future) @@ -69,7 +68,7 @@ u16 CMailHandler::ReadDSPMailboxLow() return 0x00; } -void CMailHandler::Clear() +void CMailHandler::ClearPending() { while (!m_Mails.empty()) m_Mails.pop(); @@ -84,7 +83,7 @@ void CMailHandler::Halt(bool _Halt) { if (_Halt) { - Clear(); + ClearPending(); PushMail(0x80544348); } } @@ -93,7 +92,7 @@ void CMailHandler::DoState(PointerWrap& p) { if (p.IsReadMode()) { - Clear(); + ClearPending(); int sz = 0; p.Do(sz); for (int i = 0; i < sz; i++) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index 773cf042bb..411d169545 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -20,11 +20,15 @@ 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 Clear(); void Halt(bool _Halt); void DoState(PointerWrap& p); bool HasPending() const; + // 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 + // actually exists on real hardware, HLE implementations do not need to call this directly. + void ClearPending(); + u16 ReadDSPMailboxHigh(); u16 ReadDSPMailboxLow(); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index ee64a96659..45d9848b8c 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -34,7 +34,6 @@ AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) AXUCode::~AXUCode() { - m_mail_handler.Clear(); } void AXUCode::Initialize() diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp index 23ee74bec8..ac14bd26be 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp @@ -18,7 +18,6 @@ CARDUCode::CARDUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) CARDUCode::~CARDUCode() { - m_mail_handler.Clear(); } void CARDUCode::Initialize() diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp index 49816fe6fd..b22e594719 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp @@ -75,7 +75,6 @@ GBAUCode::GBAUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) GBAUCode::~GBAUCode() { - m_mail_handler.Clear(); } void GBAUCode::Initialize() diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp index e41a5b19c0..00e4989afe 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp @@ -34,7 +34,6 @@ ROMUCode::~ROMUCode() void ROMUCode::Initialize() { - m_mail_handler.Clear(); m_mail_handler.PushMail(0x8071FEED); } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp index 7cfab59596..5c07a31ea4 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp @@ -130,7 +130,6 @@ ZeldaUCode::ZeldaUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) ZeldaUCode::~ZeldaUCode() { - m_mail_handler.Clear(); } void ZeldaUCode::Initialize() From 0fec8ffb3c9c71a9daaf83e5c3f8b3f7ba394583 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 19 Jun 2022 12:19:09 -0700 Subject: [PATCH 3/6] DSPHLE: Remove empty destructors Most of these were made unnecessary by the previous commit. --- Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/AX.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/CARD.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/GBA.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/INIT.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/INIT.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/ROM.h | 1 - Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp | 4 ---- Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h | 1 - 14 files changed, 35 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index 45d9848b8c..c53d7a8e8e 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -32,10 +32,6 @@ AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) INFO_LOG_FMT(DSPHLE, "Instantiating AXUCode: crc={:08x}", crc); } -AXUCode::~AXUCode() -{ -} - void AXUCode::Initialize() { m_mail_handler.PushMail(DSP_INIT, true); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h index 52adc73b63..9f69fa3195 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h @@ -66,7 +66,6 @@ class AXUCode : public UCodeInterface { public: AXUCode(DSPHLE* dsphle, u32 crc); - ~AXUCode() override; void Initialize() override; void HandleMail(u32 mail) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index e1a7530c35..1c4709af16 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -30,10 +30,6 @@ AXWiiUCode::AXWiiUCode(DSPHLE* dsphle, u32 crc) : AXUCode(dsphle, crc), m_last_m m_old_axwii = (crc == 0xfa450138) || (crc == 0x7699af32); } -AXWiiUCode::~AXWiiUCode() -{ -} - void AXWiiUCode::HandleCommandList() { // Temp variables for addresses computation diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h index 7d1baf871d..27d79ba1ae 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.h @@ -15,7 +15,6 @@ class AXWiiUCode : public AXUCode { public: AXWiiUCode(DSPHLE* dsphle, u32 crc); - ~AXWiiUCode() override; void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp index ac14bd26be..4ad47757f8 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.cpp @@ -16,10 +16,6 @@ CARDUCode::CARDUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) INFO_LOG_FMT(DSPHLE, "CARDUCode - initialized"); } -CARDUCode::~CARDUCode() -{ -} - void CARDUCode::Initialize() { m_mail_handler.PushMail(DSP_INIT); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.h b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.h index 99dcd2f231..55b1e7f95d 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/CARD.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/CARD.h @@ -14,7 +14,6 @@ class CARDUCode : public UCodeInterface { public: CARDUCode(DSPHLE* dsphle, u32 crc); - ~CARDUCode() override; void Initialize() override; void HandleMail(u32 mail) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp index b22e594719..bccd7fe6ef 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp @@ -73,10 +73,6 @@ GBAUCode::GBAUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) { } -GBAUCode::~GBAUCode() -{ -} - void GBAUCode::Initialize() { m_mail_handler.PushMail(DSP_INIT); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.h b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.h index 89c9ac4af8..22083d127d 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/GBA.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/GBA.h @@ -18,7 +18,6 @@ void ProcessGBACrypto(u32 address); struct GBAUCode : public UCodeInterface { GBAUCode(DSPHLE* dsphle, u32 crc); - ~GBAUCode() override; void Initialize() override; void HandleMail(u32 mail) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/INIT.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/INIT.cpp index 6df84313f1..7869460bc1 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/INIT.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/INIT.cpp @@ -16,10 +16,6 @@ INITUCode::INITUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) INFO_LOG_FMT(DSPHLE, "INITUCode - initialized"); } -INITUCode::~INITUCode() -{ -} - void INITUCode::Initialize() { m_mail_handler.PushMail(0x80544348); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/INIT.h b/Source/Core/Core/HW/DSPHLE/UCodes/INIT.h index 9b286065c2..53cbe01428 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/INIT.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/INIT.h @@ -14,7 +14,6 @@ class INITUCode : public UCodeInterface { public: INITUCode(DSPHLE* dsphle, u32 crc); - ~INITUCode() override; void Initialize() override; void HandleMail(u32 mail) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp index 00e4989afe..cd5e72a009 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.cpp @@ -28,10 +28,6 @@ ROMUCode::ROMUCode(DSPHLE* dsphle, u32 crc) INFO_LOG_FMT(DSPHLE, "UCode_Rom - initialized"); } -ROMUCode::~ROMUCode() -{ -} - void ROMUCode::Initialize() { m_mail_handler.PushMail(0x8071FEED); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.h b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.h index bf43d34f71..431c9ed052 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ROM.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ROM.h @@ -14,7 +14,6 @@ class ROMUCode : public UCodeInterface { public: ROMUCode(DSPHLE* dsphle, u32 crc); - ~ROMUCode() override; void Initialize() override; void HandleMail(u32 mail) override; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp index 5c07a31ea4..16c5a20cda 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp @@ -128,10 +128,6 @@ ZeldaUCode::ZeldaUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) INFO_LOG_FMT(DSPHLE, "Zelda UCode loaded, crc={:08x}, flags={:08x}", crc, m_flags); } -ZeldaUCode::~ZeldaUCode() -{ -} - void ZeldaUCode::Initialize() { if (m_flags & LIGHT_PROTOCOL) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h index 941f140dea..6051faf853 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.h @@ -191,7 +191,6 @@ class ZeldaUCode : public UCodeInterface { public: ZeldaUCode(DSPHLE* dsphle, u32 crc); - ~ZeldaUCode() override; void Initialize() override; void HandleMail(u32 mail) override; From bdbb23fa1a3052337af2106a3dc8715a8cde8bd2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 8 Jun 2022 20:08:40 -0700 Subject: [PATCH 4/6] DSPHLE: Rename CMailHandler::m_Mails to m_pending_mails --- Source/Core/Core/HW/DSPHLE/MailHandler.cpp | 70 +++++----------------- Source/Core/Core/HW/DSPHLE/MailHandler.h | 8 ++- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index b1d0377ec2..87e8d957c2 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -3,8 +3,6 @@ #include "Core/HW/DSPHLE/MailHandler.h" -#include - #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" @@ -25,25 +23,25 @@ void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future) { if (interrupt) { - if (m_Mails.empty()) + if (m_pending_mails.empty()) { DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP, cycles_into_future); } else { - m_Mails.front().second = true; + m_pending_mails.front().second = true; } } - m_Mails.emplace(mail, false); + m_pending_mails.emplace_back(mail, false); DEBUG_LOG_FMT(DSP_MAIL, "DSP writes {:#010x}", mail); } u16 CMailHandler::ReadDSPMailboxHigh() { - // check if we have a mail for the core - if (!m_Mails.empty()) + // check if we have a mail for the CPU core + if (!m_pending_mails.empty()) { - u16 result = (m_Mails.front().first >> 16) & 0xFFFF; + u16 result = (m_pending_mails.front().first >> 16) & 0xFFFF; return result; } return 0x00; @@ -51,12 +49,12 @@ u16 CMailHandler::ReadDSPMailboxHigh() u16 CMailHandler::ReadDSPMailboxLow() { - // check if we have a mail for the core - if (!m_Mails.empty()) + // check if we have a mail for the CPU core + if (!m_pending_mails.empty()) { - u16 result = m_Mails.front().first & 0xFFFF; - bool generate_interrupt = m_Mails.front().second; - m_Mails.pop(); + u16 result = m_pending_mails.front().first & 0xFFFF; + const bool generate_interrupt = m_pending_mails.front().second; + m_pending_mails.pop_front(); if (generate_interrupt) { @@ -70,13 +68,12 @@ u16 CMailHandler::ReadDSPMailboxLow() void CMailHandler::ClearPending() { - while (!m_Mails.empty()) - m_Mails.pop(); + m_pending_mails.clear(); } bool CMailHandler::HasPending() const { - return !m_Mails.empty(); + return !m_pending_mails.empty(); } void CMailHandler::Halt(bool _Halt) @@ -90,45 +87,6 @@ void CMailHandler::Halt(bool _Halt) void CMailHandler::DoState(PointerWrap& p) { - if (p.IsReadMode()) - { - ClearPending(); - int sz = 0; - p.Do(sz); - for (int i = 0; i < sz; i++) - { - u32 mail = 0; - bool interrupt = false; - p.Do(mail); - p.Do(interrupt); - m_Mails.emplace(mail, interrupt); - } - } - else // WRITE and MEASURE - { - std::queue> temp; - int sz = (int)m_Mails.size(); - p.Do(sz); - for (int i = 0; i < sz; i++) - { - u32 value = m_Mails.front().first; - bool interrupt = m_Mails.front().second; - m_Mails.pop(); - p.Do(value); - p.Do(interrupt); - temp.emplace(value, interrupt); - } - if (!m_Mails.empty()) - PanicAlertFmt("CMailHandler::DoState - WTF?"); - - // Restore queue. - for (int i = 0; i < sz; i++) - { - u32 value = temp.front().first; - bool interrupt = temp.front().second; - temp.pop(); - m_Mails.emplace(value, interrupt); - } - } + p.Do(m_pending_mails); } } // namespace DSP::HLE diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index 411d169545..0bc1227ede 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -3,7 +3,7 @@ #pragma once -#include +#include #include #include "Common/CommonTypes.h" @@ -33,7 +33,9 @@ public: u16 ReadDSPMailboxLow(); private: - // mail handler - std::queue> m_Mails; + // The actual DSP only has a single pair of mail registers, and doesn't keep track of pending + // 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. + std::deque> m_pending_mails; }; } // namespace DSP::HLE From 3aeafcc70b4358d0a9736d5c654fd8b9e30e4ead Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 16 Jun 2022 14:51:59 -0700 Subject: [PATCH 5/6] 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. --- Source/Core/Core/HW/DSPHLE/MailHandler.cpp | 17 ++++++++++------- Source/Core/Core/HW/DSPHLE/MailHandler.h | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index 87e8d957c2..fc5b22b778 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -41,10 +41,9 @@ u16 CMailHandler::ReadDSPMailboxHigh() // check if we have a mail for the CPU core if (!m_pending_mails.empty()) { - u16 result = (m_pending_mails.front().first >> 16) & 0xFFFF; - return result; + m_last_mail = m_pending_mails.front().first; } - return 0x00; + return u16(m_last_mail >> 0x10); } u16 CMailHandler::ReadDSPMailboxLow() @@ -52,18 +51,22 @@ u16 CMailHandler::ReadDSPMailboxLow() // check if we have a mail for the CPU core 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; + m_pending_mails.pop_front(); if (generate_interrupt) { 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() diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index 0bc1227ede..c036a9f72d 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -27,6 +27,8 @@ public: // 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 // 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(); 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, // and then give them to the CPU in the requested order. std::deque> 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 From a72fa4b9ccabf5113a903f880e7df64e9dffc467 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 16 Jun 2022 15:40:41 -0700 Subject: [PATCH 6/6] 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