summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-07-25 19:30:30 -0700
committerPokechu22 <Pokechu022@gmail.com>2022-07-25 20:35:43 -0700
commit1dcccb1f75bf6d1d97167da1b136dfb3df4918ee (patch)
tree542e028678aff7e1d3b34b84171e794a48221285
parente44b596f50a87863abe2aa3cda92cf7151bea5c2 (diff)
DSPHLE: Add warning to use of MAIL_TERMINATE
-rw-r--r--Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp
index 902d940bde..122044dda6 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/AESnd.cpp
@@ -161,7 +161,30 @@ void AESndUCode::HandleMail(u32 mail)
break;
case MAIL_TERMINATE:
INFO_LOG_FMT(DSPHLE, "AESndUCode - MAIL_TERMINATE: {:08x}", mail);
- // This doesn't actually change the state of the system.
+ if (true) // currently no mainline libogc uCode has this issue fixed
+ {
+ // The relevant code looks like this:
+ //
+ // lrs $acc1.m,@CMBL
+ // ...
+ // cmpi $acc1.m,#0xdead
+ // jeq task_terminate
+ //
+ // The cmpi instruction always sign-extends, so it will compare $acc1 with 0xff'dead'0000.
+ // However, recv_cmd runs in set16 mode, so the load to $acc1 will produce 0x00'dead'0000.
+ // This means that the comparison never succeeds, and no mail is sent in response to
+ // MAIL_TERMINATE. This means that __dsp_donecallback is never called (since that's
+ // normally called in response to DSP_DONE), so __aesnddspinit is never cleared, so
+ // AESND_Reset never returns, resulting in a hang. We always send the mail to avoid this
+ // hang. (It's possible to exit without calling AESND_Reset, so most homebrew probably
+ // isn't affected by this bug in the first place.)
+ //
+ // A fix exists, but has not yet been added to mainline libogc:
+ // https://github.com/extremscorner/libogc2/commit/38edc9db93232faa612f680c91be1eb4d95dd1c6
+ WARN_LOG_FMT(DSPHLE, "AESndUCode - MAIL_TERMINATE is broken in this version of the "
+ "uCode; this will hang on real hardware or with DSP LLE");
+ }
+ // This doesn't actually change the state of the DSP code.
m_mail_handler.PushMail(DSP_DONE, true);
break;
default: