summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-06-22 13:20:00 -0700
committerPokechu22 <Pokechu022@gmail.com>2022-08-03 17:32:12 -0700
commitf2e833b5c474c8f5e42d413c8994174bc6fccd16 (patch)
tree01ec3b98969e5d4cf92ad5961083be3dbea476c4 /Source
parent8d66c29f3303f564d039015ec7ea0f95a570b564 (diff)
DSPHLE: Eliminate global state in AX uCode
This also increases accuracy as to when specific mail is allowed, and correctly handles masking of the 0xCDD1 mails.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp103
-rw-r--r--Source/Core/Core/HW/DSPHLE/UCodes/AX.h9
2 files changed, 70 insertions, 42 deletions
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp
index c53d7a8e8e..7a7d9e5d39 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp
@@ -653,53 +653,72 @@ void AXUCode::SendAUXAndMix(u32 main_auxa_up, u32 auxb_s_up, u32 main_l_dl, u32
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 (m_upload_setup_in_progress)
+ {
+ PrepareBootUCode(mail);
+ return;
+ }
- if (next_is_cmdlist)
+ switch (m_mail_state)
{
- CopyCmdList(mail, cmdlist_size);
+ case MailState::WaitingForCmdListSize:
+ if ((mail & MAIL_CMDLIST_MASK) == MAIL_CMDLIST)
+ {
+ // A command list address is going to be sent next.
+ m_cmdlist_size = static_cast<u16>(mail & ~MAIL_CMDLIST_MASK);
+ m_mail_state = MailState::WaitingForCmdListAddress;
+ }
+ else
+ {
+ ERROR_LOG_FMT(DSPHLE, "Unknown mail sent to AX::HandleMail; expected command list: {:08x}",
+ mail);
+ }
+ break;
+
+ case MailState::WaitingForCmdListAddress:
+ CopyCmdList(mail, m_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, true);
- }
- 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_FMT(DSPHLE, "Unknown mail sent to AX::HandleMail: {:08x}", mail);
- }
+ m_mail_state = MailState::WaitingForNextTask;
+ break;
+
+ case MailState::WaitingForNextTask:
+ if ((mail & TASK_MAIL_MASK) != TASK_MAIL_TO_DSP)
+ {
+ WARN_LOG_FMT(DSPHLE, "Rendering task without prefix CDD1: {:08x}", mail);
+ mail = TASK_MAIL_TO_DSP | (mail & ~TASK_MAIL_MASK);
+ // The actual uCode does not check for the CDD1 prefix.
+ }
+
+ switch (mail)
+ {
+ case MAIL_RESUME:
+ // Acknowledge the resume request
+ m_mail_handler.PushMail(DSP_RESUME, true);
+ m_mail_state = MailState::WaitingForCmdListSize;
+ break;
+
+ case MAIL_NEW_UCODE:
+ m_upload_setup_in_progress = true;
+ break;
+
+ case MAIL_RESET:
+ m_dsphle->SetUCode(UCODE_ROM);
+ break;
+
+ case 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.
+ m_mail_state = MailState::WaitingForCmdListSize;
+ break;
- next_is_cmdlist = set_next_is_cmdlist;
+ default:
+ WARN_LOG_FMT(DSPHLE, "Unknown task mail: {:08x}", mail);
+ break;
+ }
+ break;
+ }
}
void AXUCode::CopyCmdList(u32 addr, u16 size)
@@ -712,7 +731,6 @@ void AXUCode::CopyCmdList(u32 addr, u16 size)
for (u32 i = 0; i < size; ++i, addr += 2)
m_cmdlist[i] = HLEMemory_Read_U16(addr);
- m_cmdlist_size = size;
}
void AXUCode::Update()
@@ -728,6 +746,7 @@ void AXUCode::DoAXState(PointerWrap& p)
{
p.Do(m_cmdlist);
p.Do(m_cmdlist_size);
+ p.Do(m_mail_state);
p.Do(m_samples_main_left);
p.Do(m_samples_main_right);
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h
index c51cdb34b9..d63659a995 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h
@@ -200,5 +200,14 @@ private:
CMD_COMPRESSOR = 0x12,
CMD_SEND_AUX_AND_MIX = 0x13,
};
+
+ enum class MailState
+ {
+ WaitingForCmdListSize,
+ WaitingForCmdListAddress,
+ WaitingForNextTask,
+ };
+
+ MailState m_mail_state = MailState::WaitingForCmdListSize;
};
} // namespace DSP::HLE