diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp index 3334626ac0..18ab8ee4c2 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "Common/ChunkFile.h" +#include "Core/HW/DSP.h" #include "Core/HW/DSPHLE/MailHandler.h" CMailHandler::CMailHandler() @@ -14,9 +15,20 @@ CMailHandler::~CMailHandler() Clear(); } -void CMailHandler::PushMail(u32 _Mail) +void CMailHandler::PushMail(u32 _Mail, bool interrupt) { - m_Mails.push(_Mail); + if (interrupt) + { + if (m_Mails.empty()) + { + DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); + } + else + { + m_Mails.front().second = true; + } + } + m_Mails.emplace(_Mail, false); DEBUG_LOG(DSP_MAIL, "DSP writes 0x%08x", _Mail); } @@ -25,7 +37,7 @@ u16 CMailHandler::ReadDSPMailboxHigh() // check if we have a mail for the core if (!m_Mails.empty()) { - u16 result = (m_Mails.front() >> 16) & 0xFFFF; + u16 result = (m_Mails.front().first >> 16) & 0xFFFF; return result; } return 0x00; @@ -36,8 +48,15 @@ u16 CMailHandler::ReadDSPMailboxLow() // check if we have a mail for the core if (!m_Mails.empty()) { - u16 result = m_Mails.front() & 0xFFFF; + u16 result = m_Mails.front().first & 0xFFFF; + bool generate_interrupt = m_Mails.front().second; m_Mails.pop(); + + if (generate_interrupt) + { + DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); + } + return result; } return 0x00; @@ -59,7 +78,7 @@ void CMailHandler::Halt(bool _Halt) if (_Halt) { Clear(); - m_Mails.push(0x80544348); + PushMail(0x80544348); } } @@ -73,21 +92,25 @@ void CMailHandler::DoState(PointerWrap &p) for (int i = 0; i < sz; i++) { u32 mail = 0; + bool interrupt = false; p.Do(mail); - m_Mails.push(mail); + p.Do(interrupt); + m_Mails.emplace(mail, interrupt); } } else // WRITE and MEASURE { - std::queue temp; + std::queue> temp; int sz = (int)m_Mails.size(); p.Do(sz); for (int i = 0; i < sz; i++) { - u32 value = m_Mails.front(); + u32 value = m_Mails.front().first; + bool interrupt = m_Mails.front().second; m_Mails.pop(); p.Do(value); - temp.push(value); + p.Do(interrupt); + temp.emplace(value, interrupt); } if (!m_Mails.empty()) PanicAlert("CMailHandler::DoState - WTF?"); @@ -95,9 +118,10 @@ void CMailHandler::DoState(PointerWrap &p) // Restore queue. for (int i = 0; i < sz; i++) { - u32 value = temp.front(); + u32 value = temp.front().first; + bool interrupt = temp.front().second; temp.pop(); - m_Mails.push(value); + m_Mails.emplace(value, interrupt); } } } diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.h b/Source/Core/Core/HW/DSPHLE/MailHandler.h index 40ecaec953..41d5f77c89 100644 --- a/Source/Core/Core/HW/DSPHLE/MailHandler.h +++ b/Source/Core/Core/HW/DSPHLE/MailHandler.h @@ -5,6 +5,8 @@ #pragma once #include +#include + #include "Common/CommonTypes.h" class PointerWrap; @@ -15,7 +17,7 @@ public: CMailHandler(); ~CMailHandler(); - void PushMail(u32 _Mail); + void PushMail(u32 _Mail, bool interrupt = false); void Clear(); void Halt(bool _Halt); void DoState(PointerWrap &p); @@ -24,20 +26,7 @@ public: u16 ReadDSPMailboxHigh(); u16 ReadDSPMailboxLow(); - u32 GetNextMail() const - { - if (!m_Mails.empty()) - { - return m_Mails.front(); - } - else - { - // WARN_LOG(DSPHLE, "GetNextMail: No mails"); - return 0; - } - } - private: // mail handler - std::queue m_Mails; + std::queue> m_Mails; };