void AXUCode::HandleMail(u32 mail) { // Indicates if the next message is a command list address. static bool next_is_cmdlist = false; static u16 cmdlist_size = 0; bool set_next_is_cmdlist = false; if (next_is_cmdlist) { CopyCmdList(mail, cmdlist_size); HandleCommandList(); m_cmdlist_size = 0; SignalWorkEnd(); } else if (m_upload_setup_in_progress) { PrepareBootUCode(mail); } else if (mail == MAIL_RESUME) { // Acknowledge the resume request m_mail_handler.PushMail(DSP_RESUME); DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); } else if (mail == MAIL_NEW_UCODE) { m_upload_setup_in_progress = true; } else if (mail == MAIL_RESET) { m_dsphle->SetUCode(UCODE_ROM); } else if (mail == MAIL_CONTINUE) { // We don't have to do anything here - the CPU does not wait for a ACK // and sends a cmdlist mail just after. } else if ((mail & MAIL_CMDLIST_MASK) == MAIL_CMDLIST) { // A command list address is going to be sent next. set_next_is_cmdlist = true; cmdlist_size = (u16)(mail & ~MAIL_CMDLIST_MASK); } else { ERROR_LOG(DSPHLE, "Unknown mail sent to AX::HandleMail: %08x", mail); } next_is_cmdlist = set_next_is_cmdlist; }
void CUCode_AX::Update(int cycles) { // Used for UCode switching. if (NeedsResumeMail()) { m_rMailHandler.PushMail(DSP_RESUME); DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); } else if (m_work_available) { HandleCommandList(); m_cmdlist_size = 0; SignalWorkEnd(); } }
void CUCode_AX::AXThread() { while (true) { { std::unique_lock<std::mutex> lk(m_cmdlist_mutex); while (m_cmdlist_size == 0) m_cmdlist_cv.wait(lk); } if (m_cmdlist_size == (u16)-1) // End of thread signal break; m_processing.lock(); HandleCommandList(); m_cmdlist_size = 0; SignalWorkEnd(); m_processing.unlock(); } }