This is the result of my investigations on the Zelda ucode, and more spceially

on these famous mails (00000000,000000000, 00000000,00010000, 00000000,00020000,
00000000,00030000) and command 0x2 (SyncFrame) too (these two things are tied
together).
Super Mario Galaxy now keeps sending commands 0x2 followed by the famous mails. 
Is it what it is supposed to do?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3392 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
luigi2us 2009-06-09 19:51:19 +00:00
parent df91fc8648
commit 36026c62ed
2 changed files with 117 additions and 37 deletions

View File

@ -29,6 +29,15 @@
CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler)
, m_bSyncInProgress(false)
, m_SyncIndex(0)
, m_SyncStep(0)
, m_SyncMaxStep(0)
, m_bSyncCmdPending(false)
, m_SyncEndSync(0)
, m_SyncCurStep(0)
, m_SyncCount(0)
, m_SyncMax(0)
, m_numSteps(0)
, m_bListInProgress(false)
, m_step(0)
@ -36,8 +45,10 @@ CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler)
{
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
m_rMailHandler.PushMail(DSP_INIT);
m_rMailHandler.PushMail(0x80000000); // handshake
g_dspInitialize.pGenerateDSPInterrupt();
m_rMailHandler.PushMail(0xF3551111); // handshake
memset(m_Buffer, 0, sizeof(m_Buffer));
memset(m_SyncValues, 0, sizeof(m_SyncValues));
}
@ -50,15 +61,15 @@ CUCode_Zelda::~CUCode_Zelda()
void CUCode_Zelda::Update(int cycles)
{
// check if we have to sent something
if (!m_rMailHandler.IsEmpty())
g_dspInitialize.pGenerateDSPInterrupt();
//if (!m_rMailHandler.IsEmpty())
// g_dspInitialize.pGenerateDSPInterrupt();
}
void CUCode_Zelda::HandleMail(u32 _uMail)
{
//PanicAlert("Zelda mail 0x%08X, list in progress? %s", _uMail,
// m_bListInProgress ? "Yes" : "No");
DEBUG_LOG(DSPHLE, "Zelda mail 0x%08X, list in progress? %s, sync in progress? %s", _uMail,
m_bListInProgress ? "Yes" : "No", m_bSyncInProgress ? "Yes" : "No");
// SetupTable
// in WW we get SetDolbyDelay
// SyncFrame
@ -70,37 +81,53 @@ void CUCode_Zelda::HandleMail(u32 _uMail)
// 0
// 0x30000
// And then silence...
if (m_bListInProgress == false)
if (m_bSyncInProgress)
{
if(_uMail == 0) {
g_dspInitialize.pGenerateDSPInterrupt();
} else if((_uMail >> 16) == 0) {
m_bListInProgress = true;
m_numSteps = _uMail;
m_step = 0;
} else {
// Release halt
#if 0
// The _uMail seems to be 1,2,3 when bitshifted right 16
// after 3, we get some unknown values, probably supposed to be in the list
if((_uMail >> 16) == 1)
m_rMailHandler.PushMail(DSP_RESUME);
else if((_uMail >> 16) == 2)
m_rMailHandler.PushMail(DSP_YIELD);
else if((_uMail >> 16) == 3)
m_rMailHandler.PushMail(DSP_DONE);
else
{ /*Unknown values here*/}
#else
m_rMailHandler.PushMail(DSP_RESUME);
#endif
g_dspInitialize.pGenerateDSPInterrupt();
if (m_bSyncCmdPending)
{
u32 n = (_uMail >> 16) & 0xF;
m_SyncStep = (n + 1) << 4;
m_SyncValues[n] = _uMail & 0xFFFF;
m_bSyncInProgress = false;
m_SyncCurStep = m_SyncStep;
if (m_SyncCurStep == m_SyncMaxStep)
{
m_SyncCount++;
m_rMailHandler.PushMail(DSP_SYNC);
g_dspInitialize.pGenerateDSPInterrupt();
m_rMailHandler.PushMail(0xF355FF00 | m_SyncCount);
m_SyncCurStep = 0;
if (m_SyncCount == (m_SyncMax + 1))
{
m_rMailHandler.PushMail(DSP_UNKN);
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;
}
}
}
else
{
m_bSyncInProgress = false;
}
return;
}
else
if (m_bListInProgress)
{
if (m_step < 0 || m_step >= sizeof(m_Buffer)/4)
PanicAlert("m_step out of range");
((u32*)m_Buffer)[m_step] = _uMail;
m_step++;
@ -109,6 +136,23 @@ void CUCode_Zelda::HandleMail(u32 _uMail)
ExecuteList();
m_bListInProgress = false;
}
return;
}
if (_uMail == 0)
{
m_bSyncInProgress = true;
}
else if ((_uMail >> 16) == 0)
{
m_bListInProgress = true;
m_numSteps = _uMail;
m_step = 0;
}
else
{
DEBUG_LOG(DSPHLE, "Zelda uCode: unknown mail %08X", _uMail);
}
}
@ -122,9 +166,9 @@ void CUCode_Zelda::ExecuteList()
// begin with the list
m_readOffset = 0;
u32 Temp = Read32();
u32 Command = (Temp >> 24) & 0x7f;
u32 Sync = Temp >> 16;
u32 CmdMail = Read32();
u32 Command = (CmdMail >> 24) & 0x7f;
u32 Sync = CmdMail >> 16;
DEBUG_LOG(DSPHLE, "==============================================================================");
DEBUG_LOG(DSPHLE, "Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
@ -140,6 +184,8 @@ void CUCode_Zelda::ExecuteList()
tmp[2] = Read32();
tmp[3] = Read32();
m_SyncMaxStep = CmdMail & 0xFFFF;
DEBUG_LOG(DSPHLE, "DsetupTable");
DEBUG_LOG(DSPHLE, "???: 0x%08x", tmp[0]);
DEBUG_LOG(DSPHLE, "DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
@ -157,16 +203,21 @@ void CUCode_Zelda::ExecuteList()
tmp[2] = Read32();
// We're ready to mix
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
// 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 = true;
m_SyncEndSync = Sync;
m_SyncCount = 0;
m_SyncMax = (CmdMail >> 16) & 0xFF;
DEBUG_LOG(DSPHLE, "DsyncFrame");
DEBUG_LOG(DSPHLE, "???: 0x%08x", tmp[0]);
DEBUG_LOG(DSPHLE, "???: 0x%08x", tmp[1]);
DEBUG_LOG(DSPHLE, "DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
}
return;
break;
/*
@ -194,8 +245,21 @@ void CUCode_Zelda::ExecuteList()
break;
// Set VARAM
// Luigi__: in the real Zelda ucode, this opcode is dummy
// however, in the ucode used by SMG it isn't
case 0x0e:
// MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK);
{
/*
00b0 0080 037d lri $AR0, #0x037d
00b2 0e01 lris $AC0.M, #0x01
00b3 02bf 0065 call 0x0065
00b5 00de 037d lr $AC0.M, @0x037d
00b7 0240 7fff andi $AC0.M, #0x7fff
00b9 00fe 037d sr @0x037d, $AC0.M
00bb 029f 0041 jmp 0x0041
*/
//
}
break;
// default ... zelda ww jumps to 0x0043
@ -206,6 +270,7 @@ void CUCode_Zelda::ExecuteList()
// sync, we are rdy
m_rMailHandler.PushMail(DSP_SYNC);
g_dspInitialize.pGenerateDSPInterrupt();
m_rMailHandler.PushMail(0xF3550000 | Sync);
}

View File

@ -34,6 +34,21 @@ private:
DSP_UNKN = 0xDCD10005,
};
bool m_bSyncInProgress;
u32 m_SyncIndex;
u32 m_SyncStep;
u32 m_SyncValues[16];
// Command 0x1: SetupTable
u32 m_SyncMaxStep;
// Command 0x2: SyncFrame
bool m_bSyncCmdPending;
u32 m_SyncEndSync;
u32 m_SyncCurStep;
u32 m_SyncCount;
u32 m_SyncMax;
// List in progress
u32 m_numSteps;
bool m_bListInProgress;