DSPHLE: Eliminate global state in GBA uCode + accuracy improvements

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.
This commit is contained in:
Pokechu22 2022-06-19 12:09:32 -07:00
parent 8b65e84121
commit 8d66c29f33
2 changed files with 38 additions and 13 deletions

View File

@ -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 if (nextmail_is_mramaddr)
else
{
nextmail_is_mramaddr = false;
WARN_LOG_FMT(DSPHLE, "GBAUCode - Expected request mail but got {:08x}", mail);
}
break;
}
case MailState::WaitingForAddress:
{
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:
@ -124,9 +140,6 @@ void GBAUCode::HandleMail(u32 mail)
break;
}
}
else
{
WARN_LOG_FMT(DSPHLE, "GBAUCode - unknown command: {:08x}", mail);
}
}
} // namespace DSP::HLE

View File

@ -23,5 +23,17 @@ public:
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