mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 18:40:45 +00:00
More correct and cleaner merge of Zelda (normal) and Luigi (light) uCodes.
Split HandleMail into two functions, one for each version. Let's hope it won't break anything... BTW: if you wonder what "DMA version" and "Light version" mean: - DMA version is, say, the uCode used by SMG - Light version is Luigi-styled uCode (named that way for obvious reasons) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3772 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
5c7844df69
commit
ddd09eda84
@ -67,16 +67,16 @@ CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler, u32 _CRC)
|
|||||||
m_PBAddress2(0)
|
m_PBAddress2(0)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
|
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
|
||||||
if (LuigiStyle())
|
|
||||||
NOTICE_LOG(DSPHLE, "Luigi Stylee!");
|
|
||||||
|
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
if (IsLightVersion())
|
||||||
if (LuigiStyle())
|
|
||||||
{
|
{
|
||||||
m_rMailHandler.PushMail(0x80000000);
|
NOTICE_LOG(DSPHLE, "Luigi Stylee!");
|
||||||
|
// Is it correct? seen in DSP_UC_Luigi.txt reset vector
|
||||||
|
m_rMailHandler.PushMail(0x80001111);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
g_dspInitialize.pGenerateDSPInterrupt();
|
||||||
m_rMailHandler.PushMail(0xF3551111); // handshake
|
m_rMailHandler.PushMail(0xF3551111); // handshake
|
||||||
}
|
}
|
||||||
@ -104,49 +104,64 @@ CUCode_Zelda::~CUCode_Zelda()
|
|||||||
|
|
||||||
u8 *CUCode_Zelda::GetARAMPointer(u32 address)
|
u8 *CUCode_Zelda::GetARAMPointer(u32 address)
|
||||||
{
|
{
|
||||||
if (m_CRC == 0xD643001F) // SMG
|
if (IsDMAVersion())
|
||||||
return (u8 *)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr)) + address;
|
return (u8 *)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr)) + address;
|
||||||
else
|
else
|
||||||
return (u8 *)(g_dspInitialize.pGetARAMPointer()) + address;
|
return (u8 *)(g_dspInitialize.pGetARAMPointer()) + address;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUCode_Zelda::LuigiStyle() const
|
|
||||||
{
|
|
||||||
switch (m_CRC)
|
|
||||||
{
|
|
||||||
case 0x42f64ac4: // Luigi
|
|
||||||
case 0x0267d05a: // http://forums.dolphin-emu.com/thread-2134.html Pikmin PAL
|
|
||||||
case 0x4be6a5cb: // AC, Pikmin
|
|
||||||
case 0x088e38a5: // IPL - JAP
|
|
||||||
case 0xd73338cf: // IPL
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUCode_Zelda::Update(int cycles)
|
void CUCode_Zelda::Update(int cycles)
|
||||||
{
|
{
|
||||||
// if (!m_rMailHandler.IsEmpty())
|
if (!IsLightVersion())
|
||||||
|
{
|
||||||
if (!LuigiStyle()) {
|
|
||||||
if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
|
if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
g_dspInitialize.pGenerateDSPInterrupt();
|
||||||
}
|
}
|
||||||
/* if (m_bSyncCmdPending && (m_CurBuffer == m_NumBuffers) && (m_rMailHandler.IsEmpty()))
|
|
||||||
{
|
|
||||||
m_rMailHandler.PushMail(DSP_FRAME_END);
|
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
|
||||||
|
|
||||||
soundStream->GetMixer()->SetHLEReady(true);
|
|
||||||
DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
|
||||||
soundStream->Update(); //do it in this thread to avoid sync problems
|
|
||||||
|
|
||||||
m_bSyncCmdPending = false;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUCode_Zelda::HandleMail(u32 _uMail)
|
void CUCode_Zelda::HandleMail(u32 _uMail)
|
||||||
|
{
|
||||||
|
if (IsLightVersion())
|
||||||
|
HandleMail_LightVersion(_uMail);
|
||||||
|
else
|
||||||
|
HandleMail_NormalVersion(_uMail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUCode_Zelda::HandleMail_LightVersion(u32 _uMail)
|
||||||
|
{
|
||||||
|
if (!m_bListInProgress)
|
||||||
|
{
|
||||||
|
switch ((_uMail >> 24) & 0x7F)
|
||||||
|
{
|
||||||
|
case 0x01: m_numSteps = 5; break; // DsetupTable
|
||||||
|
case 0x02: m_numSteps = 3; break; // DsyncFrame
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
m_numSteps = 0;
|
||||||
|
PanicAlert("Zelda uCode (light version): unknown/unsupported command %02X", (_uMail >> 24) & 0x7F);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bListInProgress = true;
|
||||||
|
m_step = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4)
|
||||||
|
PanicAlert("m_step out of range");
|
||||||
|
|
||||||
|
((u32*)m_Buffer)[m_step] = _uMail;
|
||||||
|
m_step++;
|
||||||
|
|
||||||
|
if (m_step >= m_numSteps)
|
||||||
|
{
|
||||||
|
ExecuteList();
|
||||||
|
m_bListInProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
|
||||||
{
|
{
|
||||||
// WARN_LOG(DSPHLE, "Zelda uCode: Handle mail %08X", _uMail);
|
// WARN_LOG(DSPHLE, "Zelda uCode: Handle mail %08X", _uMail);
|
||||||
if (m_bSyncInProgress)
|
if (m_bSyncInProgress)
|
||||||
@ -211,7 +226,6 @@ void CUCode_Zelda::HandleMail(u32 _uMail)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reread:
|
|
||||||
if (m_bListInProgress)
|
if (m_bListInProgress)
|
||||||
{
|
{
|
||||||
if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4)
|
if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4)
|
||||||
@ -231,17 +245,16 @@ reread:
|
|||||||
|
|
||||||
// Here holds: m_bSyncInProgress == false && m_bListInProgress == false
|
// Here holds: m_bSyncInProgress == false && m_bListInProgress == false
|
||||||
|
|
||||||
|
// Zelda-only mails:
|
||||||
|
// - 0000XXXX - Begin list
|
||||||
|
// - 00000000, 000X0000 - Sync mails
|
||||||
|
// - CDD1XXXX - comes after DsyncFrame completed, seems to be debugging stuff
|
||||||
|
|
||||||
if (_uMail == 0)
|
if (_uMail == 0)
|
||||||
{
|
{
|
||||||
if (!LuigiStyle())
|
m_bSyncInProgress = true;
|
||||||
m_bSyncInProgress = true;
|
|
||||||
else {
|
|
||||||
soundStream->GetMixer()->SetHLEReady(true);
|
|
||||||
soundStream->Update(); //do it in this thread to avoid sync problems
|
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!LuigiStyle() && (_uMail >> 16) == 0)
|
else if ((_uMail >> 16) == 0)
|
||||||
{
|
{
|
||||||
m_bListInProgress = true;
|
m_bListInProgress = true;
|
||||||
m_numSteps = _uMail;
|
m_numSteps = _uMail;
|
||||||
@ -250,6 +263,8 @@ reread:
|
|||||||
else if ((_uMail >> 16) == 0xCDD1) // A 0xCDD1000X mail should come right after we send a DSP_SYNCEND mail
|
else if ((_uMail >> 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
|
// 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 (_uMail & 0xFFFF)
|
switch (_uMail & 0xFFFF)
|
||||||
{
|
{
|
||||||
case 0x0003: // Do nothing
|
case 0x0003: // Do nothing
|
||||||
@ -266,34 +281,6 @@ reread:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (LuigiStyle() && (_uMail >> 28) == 0x8)
|
|
||||||
{
|
|
||||||
m_bListInProgress = true;
|
|
||||||
m_step = 0;
|
|
||||||
m_numSteps = 0;
|
|
||||||
// We have to guess the message size.
|
|
||||||
int command = (_uMail & 0xFFFF);
|
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
case 0x0000:
|
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
|
||||||
break;
|
|
||||||
case 0x0040:
|
|
||||||
m_numSteps = 5;
|
|
||||||
ERROR_LOG(DSPHLE, "WE GUESS STEPS: %i", m_numSteps);
|
|
||||||
break;
|
|
||||||
case 0x2000:
|
|
||||||
case 0x4000:
|
|
||||||
m_numSteps = 3;
|
|
||||||
ERROR_LOG(DSPHLE, "WE GUESS STEPS: %i", m_numSteps);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR_LOG(DSPHLE, "LUIGI UNKNOWN: %i", command);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// UGLY
|
|
||||||
goto reread;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN_LOG(DSPHLE, "Zelda uCode: unknown mail %08X", _uMail);
|
WARN_LOG(DSPHLE, "Zelda uCode: unknown mail %08X", _uMail);
|
||||||
@ -311,27 +298,8 @@ void CUCode_Zelda::ExecuteList()
|
|||||||
u32 Sync = CmdMail >> 16;
|
u32 Sync = CmdMail >> 16;
|
||||||
u32 ExtraData = CmdMail & 0xFFFF;
|
u32 ExtraData = CmdMail & 0xFFFF;
|
||||||
|
|
||||||
if (!LuigiStyle()) {
|
DEBUG_LOG(DSPHLE, "==============================================================================");
|
||||||
DEBUG_LOG(DSPHLE, "==============================================================================");
|
DEBUG_LOG(DSPHLE, "Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
|
||||||
DEBUG_LOG(DSPHLE, "Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Command = CmdMail & 0xFFFF;
|
|
||||||
DEBUG_LOG(DSPHLE, "==============================================================================");
|
|
||||||
DEBUG_LOG(DSPHLE, "Zelda UCode L-mode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
|
|
||||||
|
|
||||||
// Translate Luigi commands
|
|
||||||
switch (Command) {
|
|
||||||
case 0x0040: Command = 0x01; break;
|
|
||||||
case 0x2000:
|
|
||||||
case 0x4000: Command = 2; break;
|
|
||||||
default:
|
|
||||||
DEBUG_LOG(DSPHLE, "Luigi translate: FAIL %04x", Command);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (Command)
|
switch (Command)
|
||||||
{
|
{
|
||||||
@ -376,7 +344,7 @@ void CUCode_Zelda::ExecuteList()
|
|||||||
// DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
// DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
|
||||||
//soundStream->Update(); //do it in this thread to avoid sync problems
|
//soundStream->Update(); //do it in this thread to avoid sync problems
|
||||||
|
|
||||||
if (!LuigiStyle())
|
if (!IsLightVersion())
|
||||||
m_bSyncCmdPending = true;
|
m_bSyncCmdPending = true;
|
||||||
|
|
||||||
m_CurBuffer = 0;
|
m_CurBuffer = 0;
|
||||||
@ -394,7 +362,7 @@ void CUCode_Zelda::ExecuteList()
|
|||||||
DEBUG_LOG(DSPHLE, "Right buffer address: 0x%08x", m_RightBuffersAddr);
|
DEBUG_LOG(DSPHLE, "Right buffer address: 0x%08x", m_RightBuffersAddr);
|
||||||
DEBUG_LOG(DSPHLE, "Left buffer address: 0x%08x", m_LeftBuffersAddr);
|
DEBUG_LOG(DSPHLE, "Left buffer address: 0x%08x", m_LeftBuffersAddr);
|
||||||
|
|
||||||
if (LuigiStyle())
|
if (IsLightVersion())
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
@ -438,10 +406,16 @@ void CUCode_Zelda::ExecuteList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sync, we are ready
|
// sync, we are ready
|
||||||
m_rMailHandler.PushMail(DSP_SYNC);
|
if (IsLightVersion())
|
||||||
if (!LuigiStyle())
|
{
|
||||||
|
m_rMailHandler.PushMail(0x80000000 | Sync);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_rMailHandler.PushMail(DSP_SYNC);
|
||||||
g_dspInitialize.pGenerateDSPInterrupt();
|
g_dspInitialize.pGenerateDSPInterrupt();
|
||||||
m_rMailHandler.PushMail(0xF3550000 | Sync);
|
m_rMailHandler.PushMail(0xF3550000 | Sync);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,6 +127,9 @@ public:
|
|||||||
virtual ~CUCode_Zelda();
|
virtual ~CUCode_Zelda();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
|
void HandleMail_LightVersion(u32 _uMail);
|
||||||
|
void HandleMail_NormalVersion(u32 _uMail);
|
||||||
|
|
||||||
void Update(int cycles);
|
void Update(int cycles);
|
||||||
void MixAdd(short* buffer, int size);
|
void MixAdd(short* buffer, int size);
|
||||||
|
|
||||||
@ -160,7 +163,37 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// These map CRC to behaviour.
|
// These map CRC to behaviour.
|
||||||
bool LuigiStyle() const;
|
|
||||||
|
// DMA version
|
||||||
|
// - sound data transferred using DMA instead of accelerator
|
||||||
|
bool IsDMAVersion() const
|
||||||
|
{
|
||||||
|
switch (m_CRC)
|
||||||
|
{
|
||||||
|
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 0x42f64ac4: // Luigi
|
||||||
|
case 0x0267d05a: // http://forums.dolphin-emu.com/thread-2134.html Pikmin PAL
|
||||||
|
case 0x4be6a5cb: // AC, Pikmin
|
||||||
|
case 0x088e38a5: // IPL - JAP
|
||||||
|
case 0xd73338cf: // IPL
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 m_CRC;
|
u32 m_CRC;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user