ZeldaHLE: Rip out more code, only keep normal version support and one CRC

This commit is contained in:
Pierre Bourdon 2014-04-27 13:03:32 +02:00
parent 22ec258194
commit 8f3302419b
3 changed files with 24 additions and 313 deletions

View file

@ -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

View file

@ -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()

View file

@ -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];