summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorluigi2us <luigi2us@gmail.com>2009-07-12 23:51:18 +0000
committerluigi2us <luigi2us@gmail.com>2009-07-12 23:51:18 +0000
commitddd09eda84c34e09986df04deba7fd6a03561499 (patch)
treedbebdb5fba3d4bf5fe2d204710a5d436362b4376 /Source
parent5c7844df691c71752fd98c5cc8c45045ca59f190 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp162
-rw-r--r--Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h35
2 files changed, 102 insertions, 95 deletions
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp
index 5f16cc70e3..a11f94ead4 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp
@@ -67,16 +67,16 @@ CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler, u32 _CRC)
m_PBAddress2(0)
{
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
- if (LuigiStyle())
- NOTICE_LOG(DSPHLE, "Luigi Stylee!");
- m_rMailHandler.PushMail(DSP_INIT);
- if (LuigiStyle())
+ if (IsLightVersion())
{
- 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
{
+ m_rMailHandler.PushMail(DSP_INIT);
g_dspInitialize.pGenerateDSPInterrupt();
m_rMailHandler.PushMail(0xF3551111); // handshake
}
@@ -104,49 +104,64 @@ CUCode_Zelda::~CUCode_Zelda()
u8 *CUCode_Zelda::GetARAMPointer(u32 address)
{
- if (m_CRC == 0xD643001F) // SMG
+ if (IsDMAVersion())
return (u8 *)(g_dspInitialize.pGetMemoryPointer(m_DMABaseAddr)) + address;
else
return (u8 *)(g_dspInitialize.pGetARAMPointer()) + address;
}
-bool CUCode_Zelda::LuigiStyle() const
+void CUCode_Zelda::Update(int cycles)
{
- switch (m_CRC)
+ if (!IsLightVersion())
{
- 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;
+ if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
+ g_dspInitialize.pGenerateDSPInterrupt();
}
}
-void CUCode_Zelda::Update(int cycles)
+void CUCode_Zelda::HandleMail(u32 _uMail)
{
- // if (!m_rMailHandler.IsEmpty())
+ if (IsLightVersion())
+ HandleMail_LightVersion(_uMail);
+ else
+ HandleMail_NormalVersion(_uMail);
+}
- if (!LuigiStyle()) {
- if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
- g_dspInitialize.pGenerateDSPInterrupt();
- }
-/* if (m_bSyncCmdPending && (m_CurBuffer == m_NumBuffers) && (m_rMailHandler.IsEmpty()))
+void CUCode_Zelda::HandleMail_LightVersion(u32 _uMail)
+{
+ if (!m_bListInProgress)
{
- m_rMailHandler.PushMail(DSP_FRAME_END);
- g_dspInitialize.pGenerateDSPInterrupt();
+ 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;
+ }
- 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_bListInProgress = true;
+ m_step = 0;
+ }
+
+ if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4)
+ PanicAlert("m_step out of range");
- m_bSyncCmdPending = false;
- }*/
+ ((u32*)m_Buffer)[m_step] = _uMail;
+ m_step++;
+
+ if (m_step >= m_numSteps)
+ {
+ ExecuteList();
+ m_bListInProgress = false;
+ }
}
-void CUCode_Zelda::HandleMail(u32 _uMail)
+void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail)
{
// WARN_LOG(DSPHLE, "Zelda uCode: Handle mail %08X", _uMail);
if (m_bSyncInProgress)
@@ -211,7 +226,6 @@ void CUCode_Zelda::HandleMail(u32 _uMail)
return;
}
-reread:
if (m_bListInProgress)
{
if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4)
@@ -231,17 +245,16 @@ reread:
// 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 (!LuigiStyle())
- m_bSyncInProgress = true;
- else {
- soundStream->GetMixer()->SetHLEReady(true);
- soundStream->Update(); //do it in this thread to avoid sync problems
- g_dspInitialize.pGenerateDSPInterrupt();
- }
+ m_bSyncInProgress = true;
}
- else if (!LuigiStyle() && (_uMail >> 16) == 0)
+ else if ((_uMail >> 16) == 0)
{
m_bListInProgress = true;
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
{
// 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)
{
case 0x0003: // Do nothing
@@ -266,34 +281,6 @@ reread:
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
{
WARN_LOG(DSPHLE, "Zelda uCode: unknown mail %08X", _uMail);
@@ -311,27 +298,8 @@ void CUCode_Zelda::ExecuteList()
u32 Sync = CmdMail >> 16;
u32 ExtraData = CmdMail & 0xFFFF;
- if (!LuigiStyle()) {
- DEBUG_LOG(DSPHLE, "==============================================================================");
- 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;
- }
- }
-
+ DEBUG_LOG(DSPHLE, "==============================================================================");
+ DEBUG_LOG(DSPHLE, "Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
switch (Command)
{
@@ -376,7 +344,7 @@ void CUCode_Zelda::ExecuteList()
// DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync");
//soundStream->Update(); //do it in this thread to avoid sync problems
- if (!LuigiStyle())
+ if (!IsLightVersion())
m_bSyncCmdPending = true;
m_CurBuffer = 0;
@@ -394,7 +362,7 @@ void CUCode_Zelda::ExecuteList()
DEBUG_LOG(DSPHLE, "Right buffer address: 0x%08x", m_RightBuffersAddr);
DEBUG_LOG(DSPHLE, "Left buffer address: 0x%08x", m_LeftBuffersAddr);
- if (LuigiStyle())
+ if (IsLightVersion())
break;
else
return;
@@ -438,10 +406,16 @@ void CUCode_Zelda::ExecuteList()
}
// sync, we are ready
- m_rMailHandler.PushMail(DSP_SYNC);
- if (!LuigiStyle())
+ if (IsLightVersion())
+ {
+ m_rMailHandler.PushMail(0x80000000 | Sync);
+ }
+ else
+ {
+ m_rMailHandler.PushMail(DSP_SYNC);
g_dspInitialize.pGenerateDSPInterrupt();
- m_rMailHandler.PushMail(0xF3550000 | Sync);
+ m_rMailHandler.PushMail(0xF3550000 | Sync);
+ }
}
diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h
index 49a8f39fa7..be3cc3e5f4 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h
+++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h
@@ -127,6 +127,9 @@ public:
virtual ~CUCode_Zelda();
void HandleMail(u32 _uMail);
+ void HandleMail_LightVersion(u32 _uMail);
+ void HandleMail_NormalVersion(u32 _uMail);
+
void Update(int cycles);
void MixAdd(short* buffer, int size);
@@ -160,7 +163,37 @@ private:
};
// 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;