Skip to content

Commit

Permalink
DSPHLE: Eliminate global state in GBA uCode + accuracy improvements
Browse files Browse the repository at this point in the history
The accuracy improvements are:

* The request mail must be 0xabba0000 exactly; both the low and high parts are checked
* The address is masked with 0x0fffffff
* Before, the global state meant that after the GBA uCode had been used once, it would accept 0xcdd1 commands immediately. Now, it only accepts them after execution has finished.
  • Loading branch information
Pokechu22 committed Aug 4, 2022
1 parent 8b65e84 commit 8d66c29
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
39 changes: 26 additions & 13 deletions Source/Core/Core/HW/DSPHLE/UCodes/GBA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,44 @@ void GBAUCode::Update()

void GBAUCode::HandleMail(u32 mail)
{
static bool nextmail_is_mramaddr = false;
static bool calc_done = false;

if (m_upload_setup_in_progress)
{
PrepareBootUCode(mail);
// The GBA ucode ignores the first 3 mails (mram_dest_addr, mram_size, mram_dram_addr)
// but we currently don't handle that (they're read when they shoudln't be, but DSP HLE doesn't
// implement them so it's fine).
return;
}
else if ((mail >> 16 == 0xabba) && !nextmail_is_mramaddr)

switch (m_mail_state)
{
nextmail_is_mramaddr = true;
case MailState::WaitingForRequest:
{
if (mail == REQUEST_MAIL)
{
INFO_LOG_FMT(DSPHLE, "GBAUCode - Recieved request mail");
m_mail_state = MailState::WaitingForAddress;
}
else
{
WARN_LOG_FMT(DSPHLE, "GBAUCode - Expected request mail but got {:08x}", mail);
}
break;
}
else if (nextmail_is_mramaddr)
case MailState::WaitingForAddress:
{
nextmail_is_mramaddr = false;
const u32 address = mail & 0x0fff'ffff;

ProcessGBACrypto(mail);
ProcessGBACrypto(address);

calc_done = true;
m_mail_handler.PushMail(DSP_DONE);
m_mail_state = MailState::WaitingForNextTask;
break;
}
else if (((mail & TASK_MAIL_MASK) == TASK_MAIL_TO_DSP) && calc_done)
case MailState::WaitingForNextTask:
{
// The GBA uCode checks that the high word is cdd1, so we compare the full mail with
// MAIL_NEW_UCODE/MAIL_RESET without doing masking
switch (mail)
{
case MAIL_NEW_UCODE:
Expand All @@ -124,9 +140,6 @@ void GBAUCode::HandleMail(u32 mail)
break;
}
}
else
{
WARN_LOG_FMT(DSPHLE, "GBAUCode - unknown command: {:08x}", mail);
}
}
} // namespace DSP::HLE
12 changes: 12 additions & 0 deletions Source/Core/Core/HW/DSPHLE/UCodes/GBA.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,17 @@ class GBAUCode final : public UCodeInterface
void Initialize() override;
void HandleMail(u32 mail) override;
void Update() override;

private:
static constexpr u32 REQUEST_MAIL = 0xabba0000;

enum class MailState
{
WaitingForRequest,
WaitingForAddress,
WaitingForNextTask,
};

MailState m_mail_state = MailState::WaitingForRequest;
};
} // namespace DSP::HLE

0 comments on commit 8d66c29

Please sign in to comment.