Merge pull request #10753 from Pokechu22/dsp-hle-cdd1-constants

DSPHLE: Move CDD1 constants to UCodes.h
This commit is contained in:
Admiral H. Curtiss 2022-06-23 13:43:57 +02:00 committed by GitHub
commit 0a2aabe6ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 31 deletions

View File

@ -74,17 +74,9 @@ public:
void DoState(PointerWrap& p) override; void DoState(PointerWrap& p) override;
protected: protected:
enum MailType // CPU sends 0xBABE0000 | cmdlist_size to the DSP
{ static constexpr u32 MAIL_CMDLIST = 0xBABE0000;
MAIL_RESUME = 0xCDD10000, static constexpr u32 MAIL_CMDLIST_MASK = 0xFFFF0000;
MAIL_NEW_UCODE = 0xCDD10001,
MAIL_RESET = 0xCDD10002,
MAIL_CONTINUE = 0xCDD10003,
// CPU sends 0xBABE0000 | cmdlist_size to the DSP
MAIL_CMDLIST = 0xBABE0000,
MAIL_CMDLIST_MASK = 0xFFFF0000
};
// 32 * 5 because 32 samples per millisecond, for max 5 milliseconds. // 32 * 5 because 32 samples per millisecond, for max 5 milliseconds.
int m_samples_main_left[32 * 5]{}; int m_samples_main_left[32 * 5]{};

View File

@ -114,14 +114,14 @@ void GBAUCode::HandleMail(u32 mail)
calc_done = true; calc_done = true;
m_mail_handler.PushMail(DSP_DONE); m_mail_handler.PushMail(DSP_DONE);
} }
else if ((mail >> 16 == 0xcdd1) && calc_done) else if (((mail & TASK_MAIL_MASK) == TASK_MAIL_TO_DSP) && calc_done)
{ {
switch (mail & 0xffff) switch (mail)
{ {
case 1: case MAIL_NEW_UCODE:
m_upload_setup_in_progress = true; m_upload_setup_in_progress = true;
break; break;
case 2: case MAIL_RESET:
m_dsphle->SetUCode(UCODE_ROM); m_dsphle->SetUCode(UCODE_ROM);
break; break;
default: default:

View File

@ -61,15 +61,50 @@ protected:
CMailHandler& m_mail_handler; CMailHandler& m_mail_handler;
enum EDSP_Codes : u32 static constexpr u32 TASK_MAIL_MASK = 0xFFFF'0000;
{ // Task-management mails, used for uCode switching. The DSP sends mail with 0xDCD1 in the high
DSP_INIT = 0xDCD10000, // word to the CPU to report its status. The CPU reacts in different ways for different mails.
DSP_RESUME = 0xDCD10001, // Also, Zelda uCode titles use a slightly different handler compared to AX uCode titles. Libogc's
DSP_YIELD = 0xDCD10002, // mail handler is based on the AX one.
DSP_DONE = 0xDCD10003, static constexpr u32 TASK_MAIL_TO_CPU = 0xDCD1'0000;
DSP_SYNC = 0xDCD10004, // Triggers a callback. No response is sent.
DSP_FRAME_END = 0xDCD10005, static constexpr u32 DSP_INIT = TASK_MAIL_TO_CPU | 0x0000;
}; // Triggers a callback. No response is sent.
static constexpr u32 DSP_RESUME = TASK_MAIL_TO_CPU | 0x0001;
// If the current task is canceled by the CPU, the CPU processes this mail as if it were DSP_DONE
// instead. Otherwise, it is handled differently for Zelda uCode games and AX games.
// On Zelda uCode, the CPU will always respond with MAIL_NEW_UCODE.
// On AX uCode, the CPU will respond with MAIL_NEW_UCODE if it has a new task, and otherwise
// will use MAIL_CONTINUE.
static constexpr u32 DSP_YIELD = TASK_MAIL_TO_CPU | 0x0002;
// Triggers a callback. The response is handled differently for Zelda uCode games and AX games.
// On Zelda uCode, the CPU will always respond with MAIL_NEW_UCODE.
// On AX uCode, the CPU will respond with MAIL_NEW_UCODE if there is a new task, and otherwise
// will use MAIL_RESET if the finished task was the only task.
static constexpr u32 DSP_DONE = TASK_MAIL_TO_CPU | 0x0003;
// Triggers a callback. No response is sent.
static constexpr u32 DSP_SYNC = TASK_MAIL_TO_CPU | 0x0004;
// Used by Zelda uCode only. Zelda uCode titles (or at least Super Mario Sunshine and Super Mario
// Galaxy) will log "Audio Yield Start", send MAIL_NEW_UCODE, and then log "Audio Yield Finish" if
// they have a task to execute (e.g. the card uCode), and otherwise will send MAIL_CONTINUE.
static constexpr u32 DSP_FRAME_END = TASK_MAIL_TO_CPU | 0x0005;
// The CPU will send a mail prefixed with 0xCDD1 in the high word in response.
static constexpr u32 TASK_MAIL_TO_DSP = 0xCDD1'0000;
// On AX, this sends DSP_RESUME and then returns to normal execution. On Zelda, this immediately
// HALTs. Other uCodes (e.g. Card, GBA) do not implement (and instead ignore) this mail.
// This mail does not seem to be sent in practice.
static constexpr u32 MAIL_RESUME = TASK_MAIL_TO_DSP | 0x0000;
// Starts populating info for a new uCode (see PrepareBootUCode and m_upload_setup_in_progress).
// The current uCode's state can optionally be saved, although the Card and GBA uCode do not
// support this (as there is no reason to reload their old state).
static constexpr u32 MAIL_NEW_UCODE = TASK_MAIL_TO_DSP | 0x0001;
// Immediately switches to ROM uCode. Implemented by the Zelda uCode, but the Zelda uCode task
// handler doesn't seem to send it.
static constexpr u32 MAIL_RESET = TASK_MAIL_TO_DSP | 0x0002;
// Jumps back to the main loop. Not implemented by all uCode (in particular Card and GBA which do
// not have a main loop).
static constexpr u32 MAIL_CONTINUE = TASK_MAIL_TO_DSP | 0x0003;
// UCode is forwarding mails to PrepareBootUCode // UCode is forwarding mails to PrepareBootUCode
// UCode only needs to set this to true, UCodeInterface will set to false when done! // UCode only needs to set this to true, UCodeInterface will set to false when done!

View File

@ -201,14 +201,16 @@ void ZeldaUCode::HandleMailDefault(u32 mail)
case MailState::WAITING: case MailState::WAITING:
if (mail & 0x80000000) if (mail & 0x80000000)
{ {
if ((mail >> 16) != 0xCDD1) if ((mail & TASK_MAIL_MASK) != TASK_MAIL_TO_DSP)
{ {
PanicAlertFmt("Rendering end mail without prefix CDD1: {:08x}", mail); WARN_LOG_FMT(DSPHLE, "Received rendering end mail 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 & 0xFFFF) switch (mail)
{ {
case 1: case MAIL_NEW_UCODE:
m_cmd_can_execute = true; m_cmd_can_execute = true;
RunPendingCommands(); RunPendingCommands();
NOTICE_LOG_FMT(DSPHLE, "UCode being replaced."); NOTICE_LOG_FMT(DSPHLE, "UCode being replaced.");
@ -216,13 +218,13 @@ void ZeldaUCode::HandleMailDefault(u32 mail)
SetMailState(MailState::WAITING); SetMailState(MailState::WAITING);
break; break;
case 2: case MAIL_RESET:
NOTICE_LOG_FMT(DSPHLE, "UCode being rebooted to ROM."); NOTICE_LOG_FMT(DSPHLE, "UCode being rebooted to ROM.");
SetMailState(MailState::HALTED); SetMailState(MailState::HALTED);
m_dsphle->SetUCode(UCODE_ROM); m_dsphle->SetUCode(UCODE_ROM);
break; break;
case 3: case MAIL_CONTINUE:
m_cmd_can_execute = true; m_cmd_can_execute = true;
RunPendingCommands(); RunPendingCommands();
break; break;
@ -230,7 +232,7 @@ void ZeldaUCode::HandleMailDefault(u32 mail)
default: default:
NOTICE_LOG_FMT(DSPHLE, "Unknown end rendering action. Halting."); NOTICE_LOG_FMT(DSPHLE, "Unknown end rendering action. Halting.");
[[fallthrough]]; [[fallthrough]];
case 0: case MAIL_RESUME:
NOTICE_LOG_FMT(DSPHLE, "UCode asked to halt. Stopping any processing."); NOTICE_LOG_FMT(DSPHLE, "UCode asked to halt. Stopping any processing.");
SetMailState(MailState::HALTED); SetMailState(MailState::HALTED);
break; break;