ZeldaHLE: Rip out more code, only keep normal version support and one CRC
This commit is contained in:
parent
22ec258194
commit
8f3302419b
|
@ -52,27 +52,7 @@ UCodeInterface* UCodeFactory(u32 crc, DSPHLE* dsphle, bool wii)
|
|||
INFO_LOG(DSPHLE, "CRC %08x: AX ucode chosen", crc);
|
||||
return new AXUCode(dsphle, crc);
|
||||
|
||||
case 0x6ba3b3ea: // IPL - PAL
|
||||
case 0x24b22038: // IPL - NTSC/NTSC-JAP
|
||||
case 0x42f64ac4: // Luigi's Mansion
|
||||
case 0x4be6a5cb: // AC, Pikmin
|
||||
INFO_LOG(DSPHLE, "CRC %08x: JAC (early Zelda) ucode chosen", crc);
|
||||
return new ZeldaUCode(dsphle, crc);
|
||||
|
||||
case 0x6CA33A6D: // DK Jungle Beat
|
||||
case 0x86840740: // Zelda WW - US
|
||||
case 0x56d36052: // Mario Sunshine
|
||||
case 0x2fcdf1ec: // Mario Kart, Zelda 4 Swords
|
||||
case 0x267fd05a: // Pikmin PAL
|
||||
INFO_LOG(DSPHLE, "CRC %08x: Zelda ucode chosen", crc);
|
||||
return new ZeldaUCode(dsphle, crc);
|
||||
|
||||
// Wii CRCs
|
||||
case 0xb7eb9a9c: // Wii Pikmin - PAL
|
||||
case 0xeaeb38cc: // Wii Pikmin 2 - PAL
|
||||
case 0x6c3f6f94: // Zelda TP - PAL
|
||||
case 0xd643001f: // Mario Galaxy - PAL / Wii DK Jungle Beat - PAL
|
||||
INFO_LOG(DSPHLE, "CRC %08x: Zelda Wii ucode chosen\n", crc);
|
||||
return new ZeldaUCode(dsphle, crc);
|
||||
|
||||
case 0x2ea36ce6: // Some Wii demos
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// Games that uses this UCode:
|
||||
// Zelda: The Windwaker, Mario Sunshine, Mario Kart, Twilight Princess,
|
||||
// Super Mario Galaxy
|
||||
// Games that uses this UCode (exhaustive list):
|
||||
// * Animal Crossing (type ????, CRC ????)
|
||||
// * Donkey Kong Jungle Beat (type ????, CRC ????)
|
||||
// * IPL (type ????, CRC ????)
|
||||
// * Luigi's Mansion (type ????, CRC ????)
|
||||
// * Mario Kary: Double Dash!! (type ????, CRC ????)
|
||||
// * Pikmin (type ????, CRC ????)
|
||||
// * Pikmin 2 (type ????, CRC ????)
|
||||
// * Super Mario Galaxy (type ????, CRC ????)
|
||||
// * Super Mario Galaxy 2 (type ????, CRC ????)
|
||||
// * Super Mario Sunshine (type ????, CRC ????)
|
||||
// * The Legend of Zelda: Four Swords Adventures (type ????, CRC ????)
|
||||
// * The Legend of Zelda: The Wind Waker (type Normal, CRC 86840740)
|
||||
// * The Legend of Zelda: Twilight Princess (type ????, CRC ????)
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/DSP.h"
|
||||
|
@ -12,7 +23,6 @@
|
|||
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
|
||||
#include "Core/HW/DSPHLE/UCodes/Zelda.h"
|
||||
|
||||
|
||||
ZeldaUCode::ZeldaUCode(DSPHLE *dsphle, u32 crc)
|
||||
: UCodeInterface(dsphle, crc),
|
||||
m_sync_in_progress(false),
|
||||
|
@ -28,19 +38,9 @@ ZeldaUCode::ZeldaUCode(DSPHLE *dsphle, u32 crc)
|
|||
m_step(0),
|
||||
m_read_offset(0)
|
||||
{
|
||||
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
|
||||
|
||||
if (IsLightVersion())
|
||||
{
|
||||
DEBUG_LOG(DSPHLE, "Luigi Stylee!");
|
||||
m_mail_handler.PushMail(0x88881111);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mail_handler.PushMail(DSP_INIT);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
m_mail_handler.PushMail(0xF3551111); // handshake
|
||||
}
|
||||
m_mail_handler.PushMail(DSP_INIT);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
m_mail_handler.PushMail(0xF3551111); // handshake
|
||||
}
|
||||
|
||||
ZeldaUCode::~ZeldaUCode()
|
||||
|
@ -50,12 +50,6 @@ ZeldaUCode::~ZeldaUCode()
|
|||
|
||||
void ZeldaUCode::Update()
|
||||
{
|
||||
if (!IsLightVersion())
|
||||
{
|
||||
if (m_mail_handler.GetNextMail() == DSP_FRAME_END)
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
}
|
||||
|
||||
if (NeedsResumeMail())
|
||||
{
|
||||
m_mail_handler.PushMail(DSP_RESUME);
|
||||
|
@ -65,169 +59,6 @@ void ZeldaUCode::Update()
|
|||
|
||||
void ZeldaUCode::HandleMail(u32 mail)
|
||||
{
|
||||
if (IsLightVersion())
|
||||
HandleMail_LightVersion(mail);
|
||||
else if (IsSMSVersion())
|
||||
HandleMail_SMSVersion(mail);
|
||||
else
|
||||
HandleMail_NormalVersion(mail);
|
||||
}
|
||||
|
||||
void ZeldaUCode::HandleMail_LightVersion(u32 mail)
|
||||
{
|
||||
//ERROR_LOG(DSPHLE, "Light version mail %08X, list in progress: %s, step: %i/%i",
|
||||
// mail, m_list_in_progress ? "yes":"no", m_step, m_num_steps);
|
||||
|
||||
if (m_sync_cmd_pending)
|
||||
{
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
|
||||
// TODO(delroth): Mix audio.
|
||||
|
||||
m_current_buffer++;
|
||||
|
||||
if (m_current_buffer == m_num_buffers)
|
||||
{
|
||||
m_sync_cmd_pending = false;
|
||||
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_list_in_progress)
|
||||
{
|
||||
switch ((mail >> 24) & 0x7F)
|
||||
{
|
||||
case 0x00: m_num_steps = 1; break; // dummy
|
||||
case 0x01: m_num_steps = 5; break; // DsetupTable
|
||||
case 0x02: m_num_steps = 3; break; // DsyncFrame
|
||||
|
||||
default:
|
||||
{
|
||||
m_num_steps = 0;
|
||||
PanicAlert("Zelda uCode (light version): unknown/unsupported command %02X", (mail >> 24) & 0x7F);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_list_in_progress = true;
|
||||
m_step = 0;
|
||||
}
|
||||
|
||||
if (m_step >= sizeof(m_buffer) / 4)
|
||||
PanicAlert("m_step out of range");
|
||||
|
||||
((u32*)m_buffer)[m_step] = mail;
|
||||
m_step++;
|
||||
|
||||
if (m_step >= m_num_steps)
|
||||
{
|
||||
ExecuteList();
|
||||
m_list_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ZeldaUCode::HandleMail_SMSVersion(u32 mail)
|
||||
{
|
||||
if (m_sync_in_progress)
|
||||
{
|
||||
if (m_sync_cmd_pending)
|
||||
{
|
||||
m_sync_flags[(m_num_sync_mail << 1) ] = mail >> 16;
|
||||
m_sync_flags[(m_num_sync_mail << 1) + 1] = mail & 0xFFFF;
|
||||
|
||||
m_num_sync_mail++;
|
||||
if (m_num_sync_mail == 2)
|
||||
{
|
||||
m_num_sync_mail = 0;
|
||||
m_sync_in_progress = false;
|
||||
|
||||
// TODO(delroth): Mix audio.
|
||||
|
||||
m_current_buffer++;
|
||||
|
||||
m_mail_handler.PushMail(DSP_SYNC);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
m_mail_handler.PushMail(0xF355FF00 | m_current_buffer);
|
||||
|
||||
if (m_current_buffer == m_num_buffers)
|
||||
{
|
||||
m_mail_handler.PushMail(DSP_FRAME_END);
|
||||
// DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
|
||||
m_sync_cmd_pending = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sync_in_progress = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_list_in_progress)
|
||||
{
|
||||
if (m_step >= sizeof(m_buffer) / 4)
|
||||
PanicAlert("m_step out of range");
|
||||
|
||||
((u32*)m_buffer)[m_step] = mail;
|
||||
m_step++;
|
||||
|
||||
if (m_step >= m_num_steps)
|
||||
{
|
||||
ExecuteList();
|
||||
m_list_in_progress = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Here holds: m_sync_in_progress == false && m_list_in_progress == false
|
||||
|
||||
if (mail == 0)
|
||||
{
|
||||
m_sync_in_progress = true;
|
||||
m_num_sync_mail = 0;
|
||||
}
|
||||
else if ((mail >> 16) == 0)
|
||||
{
|
||||
m_list_in_progress = true;
|
||||
m_num_steps = mail;
|
||||
m_step = 0;
|
||||
}
|
||||
else if ((mail >> 16) == 0xCDD1) // A 0xCDD1000X mail should come right after we send a DSP_SYNCEND mail
|
||||
{
|
||||
// The low part of the mail tells the operation to perform
|
||||
// Seeing as every possible operation number halts the uCode,
|
||||
// except 3, that thing seems to be intended for debugging
|
||||
switch (mail & 0xFFFF)
|
||||
{
|
||||
case 0x0003: // Do nothing
|
||||
return;
|
||||
|
||||
case 0x0000: // Halt
|
||||
case 0x0001: // Dump memory? and halt
|
||||
case 0x0002: // Do something and halt
|
||||
WARN_LOG(DSPHLE, "Zelda uCode(SMS version): received halting operation %04X", mail & 0xFFFF);
|
||||
return;
|
||||
|
||||
default: // Invalid (the real ucode would likely crash)
|
||||
WARN_LOG(DSPHLE, "Zelda uCode(SMS version): received invalid operation %04X", mail & 0xFFFF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(DSPHLE, "Zelda uCode (SMS version): unknown mail %08X", mail);
|
||||
}
|
||||
}
|
||||
|
||||
void ZeldaUCode::HandleMail_NormalVersion(u32 mail)
|
||||
{
|
||||
// WARN_LOG(DSPHLE, "Zelda uCode: Handle mail %08X", mail);
|
||||
|
||||
if (m_upload_setup_in_progress) // evaluated first!
|
||||
{
|
||||
PrepareBootUCode(mail);
|
||||
|
@ -259,10 +90,7 @@ void ZeldaUCode::HandleMail_NormalVersion(u32 mail)
|
|||
|
||||
if (m_current_buffer == m_num_buffers)
|
||||
{
|
||||
if (!IsDMAVersion()) // this is a hack... without it Pikmin 1 Wii/ Zelda TP Wii mail-s stopped
|
||||
m_mail_handler.PushMail(DSP_FRAME_END);
|
||||
//g_dspInitialize.pGenerateDSPInterrupt();
|
||||
|
||||
m_mail_handler.PushMail(DSP_FRAME_END);
|
||||
m_sync_cmd_pending = false;
|
||||
}
|
||||
}
|
||||
|
@ -343,10 +171,8 @@ void ZeldaUCode::HandleMail_NormalVersion(u32 mail)
|
|||
}
|
||||
}
|
||||
|
||||
// zelda debug ..803F6418
|
||||
void ZeldaUCode::ExecuteList()
|
||||
{
|
||||
// begin with the list
|
||||
m_read_offset = 0;
|
||||
|
||||
u32 cmd_mail = Read32();
|
||||
|
@ -354,79 +180,38 @@ void ZeldaUCode::ExecuteList()
|
|||
u32 sync;
|
||||
u32 extra_data = cmd_mail & 0xFFFF;
|
||||
|
||||
if (IsLightVersion())
|
||||
sync = 0x62 + (command << 1); // seen in DSP_UC_Luigi.txt
|
||||
else
|
||||
sync = cmd_mail >> 16;
|
||||
|
||||
DEBUG_LOG(DSPHLE, "==============================================================================");
|
||||
DEBUG_LOG(DSPHLE, "Zelda UCode - execute dlist (command: 0x%04x : sync: 0x%04x)", command, sync);
|
||||
sync = cmd_mail >> 16;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
// dummy
|
||||
case 0x00: break;
|
||||
|
||||
// DsetupTable ... zelda ww jumps to 0x0095
|
||||
case 0x01:
|
||||
Read32(); Read32(); Read32(); Read32();
|
||||
break;
|
||||
|
||||
// SyncFrame ... zelda ww jumps to 0x0243
|
||||
case 0x02:
|
||||
Read32(); Read32();
|
||||
if (IsLightVersion())
|
||||
break;
|
||||
else
|
||||
return;
|
||||
return;
|
||||
|
||||
|
||||
// Simply sends the sync messages
|
||||
case 0x03: break;
|
||||
|
||||
/* case 0x04: break; // dunno ... zelda ww jmps to 0x0580
|
||||
case 0x05: break; // dunno ... zelda ww jmps to 0x0592
|
||||
case 0x06: break; // dunno ... zelda ww jmps to 0x0469
|
||||
case 0x07: break; // dunno ... zelda ww jmps to 0x044d
|
||||
case 0x08: break; // Mixer ... zelda ww jmps to 0x0485
|
||||
case 0x09: break; // dunno ... zelda ww jmps to 0x044d
|
||||
*/
|
||||
|
||||
// DsetDolbyDelay ... zelda ww jumps to 0x00b2
|
||||
case 0x0d:
|
||||
{
|
||||
u32 tmp = Read32();
|
||||
DEBUG_LOG(DSPHLE, "DSetDolbyDelay");
|
||||
DEBUG_LOG(DSPHLE, "DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp);
|
||||
}
|
||||
Read32();
|
||||
break;
|
||||
|
||||
// This opcode, in the SMG ucode, sets the base address for audio data transfers from main memory (using DMA).
|
||||
// In the Zelda ucode, it is dummy, because this ucode uses accelerator for audio data transfers.
|
||||
case 0x0e:
|
||||
Read32();
|
||||
break;
|
||||
|
||||
// default ... zelda ww jumps to 0x0043
|
||||
default:
|
||||
PanicAlert("Zelda UCode - unknown command: %x (size %i)", command, m_num_steps);
|
||||
break;
|
||||
}
|
||||
|
||||
// sync, we are ready
|
||||
if (IsLightVersion())
|
||||
{
|
||||
if (m_sync_cmd_pending)
|
||||
m_mail_handler.PushMail(0x80000000 | m_num_buffers); // after CMD_2
|
||||
else
|
||||
m_mail_handler.PushMail(0x80000000 | sync); // after CMD_0, CMD_1
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mail_handler.PushMail(DSP_SYNC);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
m_mail_handler.PushMail(0xF3550000 | sync);
|
||||
}
|
||||
m_mail_handler.PushMail(DSP_SYNC);
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
m_mail_handler.PushMail(0xF3550000 | sync);
|
||||
}
|
||||
|
||||
u32 ZeldaUCode::GetUpdateMs()
|
||||
|
|
|
@ -15,9 +15,6 @@ public:
|
|||
u32 GetUpdateMs() override;
|
||||
|
||||
void HandleMail(u32 mail) override;
|
||||
void HandleMail_LightVersion(u32 mail);
|
||||
void HandleMail_SMSVersion(u32 mail);
|
||||
void HandleMail_NormalVersion(u32 mail);
|
||||
void Update() override;
|
||||
|
||||
void DoState(PointerWrap &p) override;
|
||||
|
@ -30,57 +27,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
// These map CRC to behavior.
|
||||
|
||||
// DMA version
|
||||
// - sound data transferred using DMA instead of accelerator
|
||||
bool IsDMAVersion() const
|
||||
{
|
||||
switch (m_crc)
|
||||
{
|
||||
case 0xb7eb9a9c: // Wii Pikmin - PAL
|
||||
case 0xeaeb38cc: // Wii Pikmin 2 - PAL
|
||||
case 0x6c3f6f94: // Wii Zelda TP - PAL
|
||||
case 0xD643001F: // Super Mario Galaxy
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Light version
|
||||
// - slightly different communication protocol (no list begin mail)
|
||||
// - exceptions and interrupts not used
|
||||
bool IsLightVersion() const
|
||||
{
|
||||
switch (m_crc)
|
||||
{
|
||||
case 0x6ba3b3ea: // IPL - PAL
|
||||
case 0x24b22038: // IPL - NTSC/NTSC-JAP
|
||||
case 0x42f64ac4: // Luigi's Mansion
|
||||
case 0x4be6a5cb: // AC, Pikmin NTSC
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// SMS version
|
||||
// - sync mails are sent every frame, not every 16 PBs
|
||||
// (named SMS because it's used by Super Mario Sunshine
|
||||
// and I couldn't find a better name)
|
||||
bool IsSMSVersion() const
|
||||
{
|
||||
switch (m_crc)
|
||||
{
|
||||
case 0x56d36052: // Super Mario Sunshine
|
||||
case 0x267fd05a: // Pikmin PAL
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_sync_in_progress;
|
||||
u32 m_max_voice;
|
||||
u32 m_sync_flags[16];
|
||||
|
|
Loading…
Reference in New Issue