diff --git a/SConstruct b/SConstruct
index 908d948192..8ab9c0b099 100644
--- a/SConstruct
+++ b/SConstruct
@@ -66,6 +66,7 @@ dirs = [
'Source/Plugins/Plugin_VideoOGL/Src',
'Source/Plugins/Plugin_DSP_HLE/Src',
'Source/Plugins/Plugin_DSP_LLE/Src',
+ 'Source/Plugins/Plugin_DSP_NULL/Src',
'Source/Plugins/Plugin_PadSimple/Src',
'Source/Plugins/Plugin_nJoy_SDL/Src',
'Source/Plugins/Plugin_Wiimote_Test/Src',
diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln
index 6f957195cf..9d5a543067 100644
--- a/Source/Dolphin.sln
+++ b/Source/Dolphin.sln
@@ -47,23 +47,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Commo
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DolphinWX", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
ProjectSection(ProjectDependencies) = postProject
- {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C}
- {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
- {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684}
- {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} = {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77}
- {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510}
+ {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}
+ {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160} = {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8} = {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}
- {521498BE-6089-4780-8223-E67C22F4E068} = {521498BE-6089-4780-8223-E67C22F4E068}
- {805B34AA-82A5-4875-8DC7-3C85BDC0BCEE} = {805B34AA-82A5-4875-8DC7-3C85BDC0BCEE}
+ {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
+ {8D612734-FAA5-4B8A-804F-4DEA2367D495} = {8D612734-FAA5-4B8A-804F-4DEA2367D495}
{9A183B48-ECC2-4121-876A-9B3793686073} = {9A183B48-ECC2-4121-876A-9B3793686073}
{636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18} = {636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18}
- {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160} = {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}
- {8D612734-FAA5-4B8A-804F-4DEA2367D495} = {8D612734-FAA5-4B8A-804F-4DEA2367D495}
- {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA}
- {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
{33546D62-7F34-4EA6-A88E-D538B36E16BF} = {33546D62-7F34-4EA6-A88E-D538B36E16BF}
- {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
- {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}
+ {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
+ {805B34AA-82A5-4875-8DC7-3C85BDC0BCEE} = {805B34AA-82A5-4875-8DC7-3C85BDC0BCEE}
+ {521498BE-6089-4780-8223-E67C22F4E068} = {521498BE-6089-4780-8223-E67C22F4E068}
+ {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA}
+ {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510}
+ {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} = {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77}
+ {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684}
+ {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
+ {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxBase28", "..\Externals\wxWidgets\build\msw\wx_base.vcproj", "{48AD7E0A-25B1-4974-A1E3-03F8C438D34F}"
@@ -102,9 +102,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZO", "..\Externals\LZO\LZO
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_Wiimote", "Plugins\Plugin_Wiimote_Test\Plugin_Wiimote_Test.vcproj", "{8D612734-FAA5-4B8A-804F-4DEA2367D495}"
ProjectSection(ProjectDependencies) = postProject
- {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
- {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
{48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F}
+ {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0}
+ {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_DSP_NULL", "Plugins\Plugin_DSP_NULL\Plugin_DSP_NULL.vcproj", "{C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
EndProjectSection
EndProject
Global
@@ -345,6 +350,18 @@ Global
{8D612734-FAA5-4B8A-804F-4DEA2367D495}.Release|Win32.Build.0 = Release|Win32
{8D612734-FAA5-4B8A-804F-4DEA2367D495}.Release|x64.ActiveCfg = Release|x64
{8D612734-FAA5-4B8A-804F-4DEA2367D495}.Release|x64.Build.0 = Release|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Debug|Win32.Build.0 = Debug|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Debug|x64.ActiveCfg = Debug|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Debug|x64.Build.0 = Debug|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.DebugFast|Win32.Build.0 = DebugFast|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.DebugFast|x64.ActiveCfg = DebugFast|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.DebugFast|x64.Build.0 = DebugFast|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Release|Win32.ActiveCfg = Release|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Release|Win32.Build.0 = Release|Win32
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Release|x64.ActiveCfg = Release|x64
+ {C6CC7A52-0FDD-433A-B2CF-9C6F187DA807}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj b/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj
new file mode 100644
index 0000000000..06bdf54fa6
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj
@@ -0,0 +1,686 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.cpp
new file mode 100644
index 0000000000..a1e365e5ab
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.cpp
@@ -0,0 +1,86 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "DSPHandler.h"
+
+CDSPHandler* CDSPHandler::m_pInstance = NULL;
+
+CDSPHandler::CDSPHandler()
+ : m_pUCode(NULL),
+ m_bHalt(false),
+ m_bAssertInt(false)
+{
+ SetUCode(UCODE_ROM);
+ m_DSPControl.DSPHalt = 1;
+ m_DSPControl.DSPInit = 1;
+}
+
+CDSPHandler::~CDSPHandler()
+{
+ delete m_pUCode;
+ m_pUCode = NULL;
+}
+
+void CDSPHandler::Update()
+{
+ if (m_pUCode != NULL)
+ m_pUCode->Update();
+}
+
+unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value)
+{
+ UDSPControl Temp(_Value);
+ if (Temp.DSPReset)
+ {
+ SetUCode(UCODE_ROM);
+ Temp.DSPReset = 0;
+ }
+ if (Temp.DSPInit == 0)
+ {
+ // copy 128 byte from ARAM 0x000000 to IMEM
+ SetUCode(UCODE_INIT_AUDIO_SYSTEM);
+ Temp.DSPInitCode = 0;
+ // MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK);
+ }
+
+ m_DSPControl.Hex = Temp.Hex;
+ return m_DSPControl.Hex;
+}
+
+unsigned short CDSPHandler::ReadControlRegister()
+{
+ return m_DSPControl.Hex;
+}
+
+void CDSPHandler::SendMailToDSP(u32 _uMail)
+{
+ if (m_pUCode != NULL)
+ m_pUCode->HandleMail(_uMail);
+}
+
+IUCode* CDSPHandler::GetUCode()
+{
+ return m_pUCode;
+}
+
+void CDSPHandler::SetUCode(u32 _crc)
+{
+ delete m_pUCode;
+ m_pUCode = NULL;
+ m_MailHandler.Clear();
+ m_pUCode = UCodeFactory(_crc, m_MailHandler);
+}
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.h b/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.h
new file mode 100644
index 0000000000..1b5030b129
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/DSPHandler.h
@@ -0,0 +1,99 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _DSPHANDLER_H
+#define _DSPHANDLER_H
+
+#include "Common.h"
+#include "MailHandler.h"
+#include "UCodes/UCodes.h"
+
+class CDSPHandler
+{
+public:
+ void Update();
+ unsigned short WriteControlRegister(unsigned short _Value);
+ unsigned short ReadControlRegister();
+ void SendMailToDSP(u32 _uMail);
+ IUCode* GetUCode();
+ void SetUCode(u32 _crc);
+
+ CMailHandler& AccessMailHandler() { return m_MailHandler; }
+
+ static CDSPHandler& GetInstance()
+ {
+ return *m_pInstance;
+ }
+
+ static void Destroy()
+ {
+ delete m_pInstance;
+ m_pInstance = NULL;
+ }
+
+ static CDSPHandler& CreateInstance()
+ {
+ if (!m_pInstance)
+ m_pInstance = new CDSPHandler();
+
+ return *m_pInstance;
+ }
+
+private:
+ CDSPHandler();
+ ~CDSPHandler();
+
+ // UDSPControl
+ union UDSPControl
+ {
+ u16 Hex;
+ struct
+ {
+ unsigned DSPReset : 1; // Write 1 to reset and waits for 0
+ unsigned DSPAssertInt : 1;
+ unsigned DSPHalt : 1;
+
+ unsigned AI : 1;
+ unsigned AI_mask : 1;
+ unsigned ARAM : 1;
+ unsigned ARAM_mask : 1;
+ unsigned DSP : 1;
+ unsigned DSP_mask : 1;
+
+ unsigned ARAM_DMAState : 1; // DSPGetDMAStatus() uses this flag
+ unsigned DSPInitCode : 1;
+ unsigned DSPInit : 1; // DSPInit() writes to this flag
+ unsigned pad : 4;
+ };
+
+ UDSPControl(u16 _Hex = 0)
+ : Hex(_Hex)
+ {}
+ };
+
+ // singleton instance
+ static CDSPHandler* m_pInstance;
+
+ IUCode* m_pUCode;
+ UDSPControl m_DSPControl;
+ CMailHandler m_MailHandler;
+
+ bool m_bHalt;
+ bool m_bAssertInt;
+};
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/Globals.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/Globals.cpp
new file mode 100644
index 0000000000..bd939bfb3a
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/Globals.cpp
@@ -0,0 +1,53 @@
+#include
+#include
+
+#include "Common.h"
+#include "Globals.h"
+
+void __Log(int, const char *fmt, ...)
+{
+ DebugLog(fmt);
+}
+
+void DebugLog(const char* _fmt, ...)
+{
+#ifdef _DEBUG
+ char Msg[512];
+ va_list ap;
+
+ va_start(ap, _fmt);
+ vsprintf(Msg, _fmt, ap);
+ va_end(ap);
+
+ g_dspInitialize.pLog(Msg);
+#endif
+}
+
+extern u8* g_pMemory;
+
+// TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM.
+#define RAM_MASK 0x1FFFFFF
+
+u8 Memory_Read_U8(u32 _uAddress)
+{
+ _uAddress &= RAM_MASK;
+ return g_pMemory[_uAddress];
+}
+
+u16 Memory_Read_U16(u32 _uAddress)
+{
+ _uAddress &= RAM_MASK;
+ return Common::swap16(*(u16*)&g_pMemory[_uAddress]);
+}
+
+u32 Memory_Read_U32(u32 _uAddress)
+{
+ _uAddress &= RAM_MASK;
+ return Common::swap32(*(u32*)&g_pMemory[_uAddress]);
+}
+
+float Memory_Read_Float(u32 _uAddress)
+{
+ u32 uTemp = Memory_Read_U32(_uAddress);
+ return *(float*)&uTemp;
+}
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/Globals.h b/Source/Plugins/Plugin_DSP_NULL/Src/Globals.h
new file mode 100644
index 0000000000..1919ce044e
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/Globals.h
@@ -0,0 +1,16 @@
+#ifndef _GLOBALS_H
+#define _GLOBALS_H
+
+
+#include "Common.h"
+#include "pluginspecs_dsp.h"
+
+extern DSPInitialize g_dspInitialize;
+void DebugLog(const char* _fmt, ...);
+
+u8 Memory_Read_U8(u32 _uAddress);
+u16 Memory_Read_U16(u32 _uAddress);
+u32 Memory_Read_U32(u32 _uAddress);
+float Memory_Read_Float(u32 _uAddress);
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.cpp
new file mode 100644
index 0000000000..2119351e14
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.cpp
@@ -0,0 +1,96 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "MailHandler.h"
+
+CMailHandler::CMailHandler()
+{
+
+}
+
+CMailHandler::~CMailHandler()
+{
+ Clear();
+}
+
+void CMailHandler::PushMail(u32 _Mail)
+{
+ m_Mails.push(_Mail);
+
+ Update();
+}
+
+u16 CMailHandler::ReadDSPMailboxHigh()
+{
+ // check if we have a mail for the core
+ if (!m_Mails.empty())
+ {
+ u16 result = (m_Mails.front() >> 16) & 0xFFFF;
+ Update();
+ return result;
+ }
+
+ return 0x00;
+}
+
+u16 CMailHandler::ReadDSPMailboxLow()
+{
+ // check if we have a mail for the core
+ if (!m_Mails.empty())
+ {
+ u16 result = m_Mails.front() & 0xFFFF;
+ m_Mails.pop();
+
+ Update();
+
+ return(result);
+ }
+
+ return 0x00;
+}
+
+void CMailHandler::Clear()
+{
+ while (!m_Mails.empty())
+ m_Mails.pop();
+}
+
+bool CMailHandler::IsEmpty()
+{
+ return m_Mails.empty();
+}
+
+void CMailHandler::Halt(bool _Halt)
+{
+ if (_Halt)
+ {
+ Clear();
+ m_Mails.push(0x80544348);
+ }
+
+ Update();
+}
+
+void CMailHandler::Update()
+{
+ if (!IsEmpty())
+ {
+ // g_dspInitialize.pGenerateDSPInterrupt();
+ }
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.h b/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.h
new file mode 100644
index 0000000000..c1858fa733
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/MailHandler.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _MAILHANDLER_H
+#define _MAILHANDLER_H
+
+#include
+
+#include "Common.h"
+
+class CMailHandler
+{
+public:
+ CMailHandler();
+ ~CMailHandler();
+
+ void PushMail(u32 _Mail);
+ void Clear();
+ void Halt(bool _Halt);
+ bool IsEmpty();
+
+ u16 ReadDSPMailboxHigh();
+ u16 ReadDSPMailboxLow();
+ void Update();
+
+private:
+ // mail handler
+ std::queue m_Mails;
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/SConscript b/Source/Plugins/Plugin_DSP_NULL/Src/SConscript
new file mode 100644
index 0000000000..aca7f8cbab
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/SConscript
@@ -0,0 +1,30 @@
+# -*- python -*-
+
+Import('env')
+import sys
+
+if sys.platform == 'darwin':
+ output = "../../../../Binary/mac/Plugins/dspnull.so"
+else:
+ output = "../../../../Binary/linux/Plugins/dspnull.so"
+
+files = [
+ "DSPHandler.cpp",
+ "MailHandler.cpp",
+ "main.cpp",
+ "Globals.cpp",
+ "UCodes/UCode_AX.cpp",
+ "UCodes/UCode_CARD.cpp",
+ "UCodes/UCode_InitAudioSystem.cpp",
+ "UCodes/UCode_Jac.cpp",
+ "UCodes/UCode_ROM.cpp",
+ "UCodes/UCodes.cpp",
+ "UCodes/UCode_Zelda.cpp",
+ ]
+
+dspenv = env.Clone()
+dspenv.Append(
+ CXXFLAGS = [ '-fPIC' ],
+ LIBS = [ 'common' ],
+ )
+dspenv.SharedLibrary(output, files)
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.cpp
new file mode 100644
index 0000000000..4b39845f42
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.cpp
@@ -0,0 +1,574 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+
+#include "../MailHandler.h"
+
+#include "UCodes.h"
+#include "UCode_AXStructs.h"
+#include "UCode_AX.h"
+
+CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii)
+ : IUCode(_rMailHandler)
+ , m_addressPBs(0xFFFFFFFF)
+ , wii_mode(wii)
+{
+ // we got loaded
+ m_rMailHandler.PushMail(0xDCD10000);
+ m_rMailHandler.PushMail(0x80000000); // handshake ??? only (crc == 0xe2136399) needs it ...
+
+ templbuffer = new int[1024 * 1024];
+ temprbuffer = new int[1024 * 1024];
+}
+
+CUCode_AX::~CUCode_AX()
+{
+ m_rMailHandler.Clear();
+ delete [] templbuffer;
+ delete [] temprbuffer;
+}
+
+void CUCode_AX::HandleMail(u32 _uMail)
+{
+ if ((_uMail & 0xFFFF0000) == MAIL_AX_ALIST)
+ {
+ // a new List
+ }
+ else
+ {
+ AXTask(_uMail);
+ }
+}
+
+s16 CUCode_AX::ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac)
+{
+ PBADPCMInfo &adpcm = pb.adpcm;
+
+ while (samplePos < newSamplePos)
+ {
+ if ((samplePos & 15) == 0)
+ {
+ adpcm.pred_scale = g_dspInitialize.pARAM_Read_U8((samplePos & ~15) >> 1);
+ samplePos += 2;
+ newSamplePos += 2;
+ }
+
+ int scale = 1 << (adpcm.pred_scale & 0xF);
+ int coef_idx = adpcm.pred_scale >> 4;
+
+ s32 coef1 = adpcm.coefs[coef_idx * 2 + 0];
+ s32 coef2 = adpcm.coefs[coef_idx * 2 + 1];
+
+ int temp = (samplePos & 1) ?
+ (g_dspInitialize.pARAM_Read_U8(samplePos >> 1) & 0xF) :
+ (g_dspInitialize.pARAM_Read_U8(samplePos >> 1) >> 4);
+
+ if (temp >= 8)
+ temp -= 16;
+
+ // 0x400 = 0.5 in 11-bit fixed point
+ int val = (scale * temp) + ((0x400 + coef1 * adpcm.yn1 + coef2 * adpcm.yn2) >> 11);
+
+ if (val > 0x7FFF)
+ val = 0x7FFF;
+ else if (val < -0x7FFF)
+ val = -0x7FFF;
+
+ adpcm.yn2 = adpcm.yn1;
+ adpcm.yn1 = val;
+
+ samplePos++;
+ }
+
+ return adpcm.yn1;
+}
+
+void ADPCM_Loop(AXParamBlock& pb)
+{
+ if (!pb.is_stream)
+ {
+ pb.adpcm.yn1 = pb.adpcm_loop_info.yn1;
+ pb.adpcm.yn2 = pb.adpcm_loop_info.yn2;
+ pb.adpcm.pred_scale = pb.adpcm_loop_info.pred_scale;
+ }
+ //else stream and we should not attempt to replace values
+}
+
+void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
+{
+ AXParamBlock PBs[NUMBER_OF_PBS];
+
+ if (_iSize > 1024 * 1024)
+ _iSize = 1024 * 1024;
+
+ memset(templbuffer, 0, _iSize * sizeof(int));
+ memset(temprbuffer, 0, _iSize * sizeof(int));
+ // read out pbs
+ int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS);
+
+ float ratioFactor = 32000.0f / 44100.0f;
+
+ for (int i = 0; i < numberOfPBs; i++)
+ {
+ AXParamBlock& pb = PBs[i];
+
+ if (pb.running)
+ {
+ // =======================================================================================
+ // Set initial parameters
+ // ---------------------------------------------------------------------------------------
+ //constants
+ const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo;
+ const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo;
+ const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor);
+
+ //variables
+ u32 samplePos = (pb.audio_addr.cur_addr_hi << 16) | pb.audio_addr.cur_addr_lo;
+ u32 frac = pb.src.cur_addr_frac;
+ // =======================================================================================
+
+
+
+ // =======================================================================================
+ // Handle no-src streams - No src streams have pb.src_type == 2 and have pb.src.ratio_hi = 0
+ // and pb.src.ratio_lo = 0. We handle that by setting the sampling ratio integer to 1. This
+ // makes samplePos update in the correct way.
+ // ---------------------------------------------------------------------------------------
+ // Stream settings
+ // src_type = 2 (most other games have src_type = 0)
+ // ---------------------------------------------------------------------------------------
+ // Affected games:
+ // Baten Kaitos - Eternal Wings (2003)
+ // Baten Kaitos - Origins (2006)?
+ // ?
+ // ---------------------------------------------------------------------------------------
+ if(pb.src_type == 2)
+ {
+ pb.src.ratio_hi = 1;
+ }
+ // =======================================================================================
+
+
+ // =======================================================================================
+ // Games that use looping to play non-looping music streams. SSBM has info in all pb.adpcm_loop_info
+ // parameters but has pb.audio_addr.looping = 0. If we treat these streams like any other looping
+ // streams the music works.
+ // ---------------------------------------------------------------------------------------
+ if(pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2)
+ {
+ pb.audio_addr.looping = 1;
+ }
+ // =======================================================================================
+
+
+ // =======================================================================================
+ // Streaming music and volume - A lot of music in Paper Mario use the exat same settings, namely
+ // these:
+ // Base settings
+ // is_stream = 1
+ // src_type = 0
+ // coef (unknown1) = 1
+ // PBAudioAddr
+ // audio_addr.looping = 1 (adpcm_loop_info.pred_scale = value, .yn1 = 0, .yn2 = 0)
+ // However. Some of the ingame music and seemingly randomly some other music incorrectly get
+ // volume = 0 for both left and right. There's also an issue of a hanging very similar to the Baten
+ // hanging. The Baten issue fixed itself when the music stream was allowed to play to the end and
+ // then stop. However, all five music streams that is playing when the gate locks up in Paper Mario
+ // is loooping streams... I don't know what may be wrong.
+ // ---------------------------------------------------------------------------------------
+ // A game that may be used as a comparison is Starfox Assault also has is_stream = 1, but it
+ // has src_type = 1, coef (unknown1) = 0 and its pb.src.ratio_lo (fraction) != 0
+ // =======================================================================================
+
+
+ // =======================================================================================
+ // Walk through _iSize
+ for (int s = 0; s < _iSize; s++)
+ {
+ int sample = 0;
+ frac += ratio;
+ u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac
+
+
+ // =======================================================================================
+ // Process sample format
+ // ---------------------------------------------------------------------------------------
+ switch (pb.audio_addr.sample_format)
+ {
+ case AUDIOFORMAT_PCM8:
+ pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample
+ pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8;
+
+ if (pb.src_type == SRCTYPE_NEAREST)
+ {
+ sample = pb.adpcm.yn1;
+ }
+ else //linear interpolation
+ {
+ sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16;
+ }
+
+ samplePos = newSamplePos;
+ break;
+
+ case AUDIOFORMAT_PCM16:
+ pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample
+ pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1))));
+ if (pb.src_type == SRCTYPE_NEAREST)
+ sample = pb.adpcm.yn1;
+ else //linear interpolation
+ sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16;
+
+ samplePos = newSamplePos;
+ break;
+
+ case AUDIOFORMAT_ADPCM:
+ sample = ADPCM_Step(pb, samplePos, newSamplePos, frac);
+ break;
+
+ default:
+ break;
+ }
+ // =======================================================================================
+
+
+ // =======================================================================================
+ // Volume control
+ frac &= 0xffff;
+
+ int vol = pb.vol_env.cur_volume >> 9;
+ sample = sample * vol >> 8;
+
+ if (pb.mixer_control & MIXCONTROL_RAMPING)
+ {
+ int x = pb.vol_env.cur_volume;
+ x += pb.vol_env.cur_volume_delta;
+ if (x < 0) x = 0;
+ if (x >= 0x7fff) x = 0x7fff;
+ pb.vol_env.cur_volume = x; // maybe not per sample?? :P
+ }
+
+ int leftmix = pb.mixer.volume_left >> 5;
+ int rightmix = pb.mixer.volume_right >> 5;
+ // =======================================================================================
+
+
+ int left = sample * leftmix >> 8;
+ int right = sample * rightmix >> 8;
+
+ //adpcm has to walk from oldSamplePos to samplePos here
+ templbuffer[s] += left;
+ temprbuffer[s] += right;
+
+ if (samplePos >= sampleEnd)
+ {
+ if (pb.audio_addr.looping == 1)
+ {
+ samplePos = loopPos;
+ if (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM)
+ ADPCM_Loop(pb);
+ }
+ else
+ {
+ pb.running = 0;
+ break;
+ }
+ }
+ } // end of the _iSize loop
+ // =======================================================================================
+
+
+ pb.src.cur_addr_frac = (u16)frac;
+ pb.audio_addr.cur_addr_hi = samplePos >> 16;
+ pb.audio_addr.cur_addr_lo = (u16)samplePos;
+ }
+ }
+
+ for (int i = 0; i < _iSize; i++)
+ {
+ // Clamp into 16-bit. Maybe we should add a volume compressor here.
+ int left = templbuffer[i];
+ int right = temprbuffer[i];
+ if (left < -32767) left = -32767;
+ if (left > 32767) left = 32767;
+ if (right < -32767) right = -32767;
+ if (right > 32767) right = 32767;
+ *_pBuffer++ += left;
+ *_pBuffer++ += right;
+ }
+
+ // write back out pbs
+ WriteBackPBs(PBs, numberOfPBs);
+}
+
+void CUCode_AX::Update()
+{
+ // check if we have to sent something
+ if (!m_rMailHandler.IsEmpty())
+ {
+ g_dspInitialize.pGenerateDSPInterrupt();
+ }
+}
+
+// AX seems to bootup one task only and waits for resume-callbacks
+// everytime the DSP has "spare time" it sends a resume-mail to the CPU
+// and the __DSPHandler calls a AX-Callback which generates a new AXFrame
+bool CUCode_AX::AXTask(u32& _uMail)
+{
+ u32 uAddress = _uMail;
+ DebugLog("AXTask - AXCommandList-Addr: 0x%08x", uAddress);
+
+ u32 Addr__AXStudio;
+ u32 Addr__AXOutSBuffer;
+ u32 Addr__AXOutSBuffer_1;
+ u32 Addr__AXOutSBuffer_2;
+ u32 Addr__A;
+ u32 Addr__12;
+ u32 Addr__4_1;
+ u32 Addr__4_2;
+ u32 Addr__5_1;
+ u32 Addr__5_2;
+ u32 Addr__6;
+ u32 Addr__9;
+
+ bool bExecuteList = true;
+
+ while (bExecuteList)
+ {
+ static int last_valid_command = 0;
+ u16 iCommand = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ switch (iCommand)
+ {
+ case AXLIST_STUDIOADDR: //00
+ Addr__AXStudio = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ if (wii_mode)
+ uAddress += 6;
+ DebugLog("AXLIST studio address: %08x", Addr__AXStudio);
+ break;
+
+ case 0x001:
+ {
+ u32 address = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ u16 param1 = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ u16 param2 = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ u16 param3 = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ DebugLog("AXLIST 1: %08x, %04x, %04x, %04x", address, param1, param2, param3);
+ }
+ break;
+
+ //
+ // Somewhere we should be getting a bitmask of AX_SYNC values
+ // that tells us what has been updated
+ // Dunno if important
+ //
+ case AXLIST_PBADDR: //02
+ {
+ m_addressPBs = Memory_Read_U32(uAddress);
+ uAddress += 4;
+
+ DebugLog("AXLIST PB address: %08x", m_addressPBs);
+ }
+ break;
+
+ case 0x0003:
+ DebugLog("AXLIST command 0x0003 ????");
+ break;
+
+ case 0x0004:
+ Addr__4_1 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ Addr__4_2 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DebugLog("AXLIST 4_1 4_2 addresses: %08x %08x", Addr__4_1, Addr__4_2);
+ break;
+
+ case 0x0005:
+ Addr__5_1 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ Addr__5_2 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DebugLog("AXLIST 5_1 5_2 addresses: %08x %08x", Addr__5_1, Addr__5_2);
+ break;
+
+ case 0x0006:
+ Addr__6 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DebugLog("AXLIST 6 address: %08x", Addr__6);
+ break;
+
+ case AXLIST_SBUFFER:
+ // Hopefully this is where in main ram to write.
+ Addr__AXOutSBuffer = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ if (wii_mode) {
+ uAddress += 12;
+ }
+ DebugLog("AXLIST OutSBuffer address: %08x", Addr__AXOutSBuffer);
+ break;
+
+ case 0x0009:
+ Addr__9 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DebugLog("AXLIST 6 address: %08x", Addr__9);
+ break;
+
+ case AXLIST_COMPRESSORTABLE: // 0xa
+ Addr__A = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ if (wii_mode) {
+ // There's one more here.
+// uAddress += 4;
+ }
+ DebugLog("AXLIST CompressorTable address: %08x", Addr__A);
+ break;
+
+ case 0x000e:
+ Addr__AXOutSBuffer_1 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ Addr__AXOutSBuffer_2 = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DebugLog("AXLIST sbuf2 addresses: %08x %08x", Addr__AXOutSBuffer_1, Addr__AXOutSBuffer_2);
+ break;
+
+ case AXLIST_END:
+ bExecuteList = false;
+ DebugLog("AXLIST end");
+ break;
+
+ case 0x0010: //Super Monkey Ball 2
+ DebugLog("AXLIST unknown");
+ //should probably read/skip stuff here
+ uAddress += 8;
+ break;
+
+ case 0x0011:
+ uAddress += 4;
+ break;
+
+ case 0x0012:
+ Addr__12 = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ break;
+
+ case 0x0013:
+ uAddress += 6 * 4; // 6 Addresses.
+ break;
+
+ case 0x000d:
+ if (wii_mode) {
+ uAddress += 4 * 4; // 4 addresses. another aux?
+ break;
+ }
+ // non-wii : fall through
+
+ case 0x000b:
+ if (wii_mode) {
+ uAddress += 2; // one 0x8000 in rabbids
+ uAddress += 4 * 2; // then two RAM addressses
+ break;
+ }
+ // non-wii : fall through
+
+ default:
+ {
+ static bool bFirst = true;
+ if (bFirst == true)
+ {
+ char szTemp[2048];
+ sprintf(szTemp, "Unknown AX-Command 0x%x (address: 0x%08x). Last valid: %02x\n",
+ iCommand, uAddress - 2, last_valid_command);
+ int num = -32;
+ while (num < 64+32)
+ {
+ char szTemp2[128] = "";
+ sprintf(szTemp2, "%s0x%04x\n", num == 0 ? ">>" : " ", Memory_Read_U16(uAddress + num));
+ strcat(szTemp, szTemp2);
+ num += 2;
+ }
+
+ PanicAlert(szTemp);
+ bFirst = false;
+ }
+
+ // unknown command so stop the execution of this TaskList
+ bExecuteList = false;
+ }
+ break;
+ }
+ if (bExecuteList)
+ last_valid_command = iCommand;
+ }
+ DebugLog("AXTask - done, send resume");
+
+ // i hope resume is okay AX
+ m_rMailHandler.PushMail(0xDCD10001);
+ return true;
+}
+
+int CUCode_AX::ReadOutPBs(AXParamBlock* _pPBs, int _num)
+{
+ int count = 0;
+ u32 blockAddr = m_addressPBs;
+
+ // reading and 'halfword' swap
+ for (int i = 0; i < _num; i++)
+ {
+ const short *pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr);
+ if (pSrc != NULL)
+ {
+ short *pDest = (short *)&_pPBs[i];
+ for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
+ {
+ pDest[p] = Common::swap16(pSrc[p]);
+ }
+ blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
+ count++;
+ }
+ else
+ break;
+ }
+
+ // return the number of readed PBs
+ return count;
+}
+
+void CUCode_AX::WriteBackPBs(AXParamBlock* _pPBs, int _num)
+{
+ u32 blockAddr = m_addressPBs;
+
+ // write back and 'halfword'swap
+ for (int i = 0; i < _num; i++)
+ {
+ short* pSrc = (short*)&_pPBs[i];
+ short* pDest = (short*)g_dspInitialize.pGetMemoryPointer(blockAddr);
+ for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
+ {
+ pDest[p] = Common::swap16(pSrc[p]);
+ }
+
+ // next block
+ blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
+ }
+}
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.h
new file mode 100644
index 0000000000..7f8aedfda6
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AX.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_AX
+#define _UCODE_AX
+
+#include "UCode_AXStructs.h"
+
+class CUCode_AX : public IUCode
+{
+public:
+ CUCode_AX(CMailHandler& _rMailHandler, bool wii = false);
+ virtual ~CUCode_AX();
+
+ void HandleMail(u32 _uMail);
+ void MixAdd(short* _pBuffer, int _iSize);
+ void Update();
+
+private:
+
+ enum
+ {
+ NUMBER_OF_PBS = 64
+ };
+
+ enum
+ {
+ MAIL_AX_ALIST = 0xBABE0000,
+ AXLIST_STUDIOADDR = 0x0000,
+ AXLIST_PBADDR = 0x0002,
+ AXLIST_SBUFFER = 0x0007,
+ AXLIST_COMPRESSORTABLE = 0x000A,
+ AXLIST_END = 0x000F
+ };
+
+ // PBs
+ u32 m_addressPBs;
+
+ int *templbuffer;
+ int *temprbuffer;
+
+ bool wii_mode;
+
+ // ax task message handler
+ bool AXTask(u32& _uMail);
+
+ void SendMail(u32 _uMail);
+ int ReadOutPBs(AXParamBlock *_pPBs, int _num);
+ void WriteBackPBs(AXParamBlock *_pPBs, int _num);
+ s16 ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac);
+};
+
+#endif // _UCODE_AX
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AXStructs.h
new file mode 100644
index 0000000000..207e8d932c
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_AXStructs.h
@@ -0,0 +1,141 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef UCODE_AX_STRUCTS
+#define UCODE_AX_STRUCTS
+
+struct PBMixer
+{
+ u16 volume_left;
+ u16 unknown;
+ u16 volume_right;
+ u16 unknown2;
+
+ u16 unknown3[8];
+ u16 unknown4[6];
+};
+
+struct PBInitialTimeDelay
+{
+ u16 unknown[7];
+};
+
+// Update data - read these each 1ms subframe and use them!
+// It seems that to provide higher time precisions for MIDI events, some games
+// use this thing to update the parameter blocks per 1ms sub-block (a block is 5ms).
+// Using this data should fix games that are missing MIDI notes.
+struct PBUpdates
+{
+ u16 num_updates[5];
+ u16 data_hi; // These point to main RAM. Not sure about the structure of the data.
+ u16 data_lo;
+};
+
+struct PBUnknown
+{
+ s16 unknown[9];
+};
+
+struct PBVolumeEnvelope
+{
+ u16 cur_volume;
+ s16 cur_volume_delta;
+};
+
+struct PBUnknown2
+{
+ u16 unknown_reserved[3];
+};
+
+struct PBAudioAddr
+{
+ u16 looping;
+ u16 sample_format;
+ u16 loop_addr_hi; // Start of loop (this will point to a shared "zero" buffer if one-shot mode is active)
+ u16 loop_addr_lo;
+ u16 end_addr_hi; // End of sample (and loop), inclusive
+ u16 end_addr_lo;
+ u16 cur_addr_hi;
+ u16 cur_addr_lo;
+};
+
+struct PBADPCMInfo
+{
+ s16 coefs[16];
+ u16 unknown;
+ u16 pred_scale;
+ s16 yn1;
+ s16 yn2;
+};
+
+struct PBSampleRateConverter
+{
+ u16 ratio_hi;
+ u16 ratio_lo;
+ u16 cur_addr_frac;
+ u16 last_samples[4];
+};
+
+struct PBADPCMLoopInfo
+{
+ u16 pred_scale;
+ u16 yn1;
+ u16 yn2;
+};
+
+struct AXParamBlock
+{
+ u16 next_pb_hi;
+ u16 next_pb_lo;
+
+ u16 this_pb_hi;
+ u16 this_pb_lo;
+
+ u16 src_type; // Type of sample rate converter (none, ?, linear)
+ u16 unknown1;
+
+ u16 mixer_control;
+ u16 running; // 1=RUN 0=STOP
+ u16 is_stream; // 1 = stream, 0 = one shot
+
+ PBMixer mixer;
+ PBInitialTimeDelay initial_time_delay;
+ PBUpdates updates;
+ PBUnknown unknown2;
+ PBVolumeEnvelope vol_env;
+ PBUnknown2 unknown3;
+ PBAudioAddr audio_addr;
+ PBADPCMInfo adpcm;
+ PBSampleRateConverter src;
+ PBADPCMLoopInfo adpcm_loop_info;
+ u16 unknown_maybe_padding[3];
+};
+
+enum {
+ AUDIOFORMAT_ADPCM = 0,
+ AUDIOFORMAT_PCM8 = 0x19,
+ AUDIOFORMAT_PCM16 = 0xA,
+};
+
+enum {
+ SRCTYPE_LINEAR = 1,
+ SRCTYPE_NEAREST = 2,
+ MIXCONTROL_RAMPING = 8,
+};
+
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.cpp
new file mode 100644
index 0000000000..de9e919946
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.cpp
@@ -0,0 +1,63 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+#include "../DSPHandler.h"
+#include "UCodes.h"
+#include "UCode_CARD.h"
+
+
+CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler)
+ : IUCode(_rMailHandler)
+{
+ DebugLog("CUCode_CARD - initialized");
+ m_rMailHandler.PushMail(DSP_INIT);
+}
+
+
+CUCode_CARD::~CUCode_CARD()
+{
+ m_rMailHandler.Clear();
+}
+
+
+void CUCode_CARD::Update()
+{
+ // check if we have to sent something
+ if (!m_rMailHandler.IsEmpty())
+ {
+ g_dspInitialize.pGenerateDSPInterrupt();
+ }
+}
+
+void CUCode_CARD::HandleMail(u32 _uMail)
+{
+ if (_uMail == 0xFF000000) // unlock card
+ {
+ // m_Mails.push(0x00000001); // ACK (actualy anything != 0)
+ }
+ else
+ {
+ DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail);
+ }
+
+ m_rMailHandler.PushMail(DSP_DONE);
+ CDSPHandler::GetInstance().SetUCode(UCODE_ROM);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.h
new file mode 100644
index 0000000000..528a5672f8
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_CARD.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_CARD_H
+#define _UCODE_CARD_H
+
+#include "UCodes.h"
+
+class CUCode_CARD : public IUCode
+{
+private:
+ enum EDSP_Codes
+ {
+ DSP_INIT = 0xDCD10000,
+ DSP_RESUME = 0xDCD10001,
+ DSP_YIELD = 0xDCD10002,
+ DSP_DONE = 0xDCD10003,
+ DSP_SYNC = 0xDCD10004,
+ DSP_UNKN = 0xDCD10005,
+ };
+
+public:
+ CUCode_CARD(CMailHandler& _rMailHandler);
+ virtual ~CUCode_CARD();
+
+ void HandleMail(u32 _uMail);
+ void Update();
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.cpp
new file mode 100644
index 0000000000..741fd446f2
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.cpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+#include "../DSPHandler.h"
+#include "UCodes.h"
+#include "UCode_InitAudioSystem.h"
+
+CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler)
+ : IUCode(_rMailHandler)
+ , m_BootTask_numSteps(0)
+ , m_NextParameter(0)
+ , IsInitialized(false)
+{
+ DebugLog("CUCode_InitAudioSystem - initialized");
+}
+
+
+CUCode_InitAudioSystem::~CUCode_InitAudioSystem()
+{}
+
+
+void CUCode_InitAudioSystem::Init()
+{}
+
+
+void CUCode_InitAudioSystem::Update()
+{
+ if (m_rMailHandler.IsEmpty())
+ {
+ m_rMailHandler.PushMail(0x80544348);
+ // HALT
+ }
+}
+
+void CUCode_InitAudioSystem::HandleMail(u32 _uMail)
+{}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.h
new file mode 100644
index 0000000000..24231f7628
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_InitAudioSystem.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_INITAUDIOSYSTEM
+#define _UCODE_INITAUDIOSYSTEM
+
+#include "UCodes.h"
+
+class CUCode_InitAudioSystem : public IUCode
+{
+public:
+ CUCode_InitAudioSystem(CMailHandler& _rMailHandler);
+ virtual ~CUCode_InitAudioSystem();
+
+ void HandleMail(u32 _uMail);
+ void Update();
+ void Init();
+
+private:
+ struct SUCode
+ {
+ u32 m_RAMAddress;
+ u32 m_Length;
+ u32 m_IMEMAddress;
+ u32 m_Unk;
+ u32 m_StartPC;
+ };
+
+ SUCode m_CurrentUCode;
+ int m_BootTask_numSteps;
+
+ u32 m_NextParameter;
+
+ bool IsInitialized;
+
+ void BootUCode();
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.cpp
new file mode 100644
index 0000000000..a1f6ff3544
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.cpp
@@ -0,0 +1,162 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+#include "UCodes.h"
+#include "UCode_Jac.h"
+#include "../MailHandler.h"
+
+CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler)
+ : IUCode(_rMailHandler)
+ , m_bListInProgress(false)
+{
+ DebugLog("CUCode_Jac: init");
+ m_rMailHandler.PushMail(0xDCD10000);
+ m_rMailHandler.PushMail(0x80000000);
+}
+
+
+CUCode_Jac::~CUCode_Jac()
+{
+ m_rMailHandler.Clear();
+}
+
+
+void CUCode_Jac::HandleMail(u32 _uMail)
+{
+ // this is prolly totally bullshit and should work like the zelda one...
+ // but i am to lazy to change it atm
+
+ if (m_bListInProgress == false)
+ {
+ // get the command to find out how much steps it has
+ switch (_uMail & 0xFFFF)
+ {
+ // release halt
+ case 0x00:
+ // m_Mails.push(0x80000000);
+ g_dspInitialize.pGenerateDSPInterrupt();
+ break;
+
+ case 0x40:
+ m_step = 0;
+ ((u32*)m_Buffer)[m_step++] = _uMail;
+ m_bListInProgress = true;
+ m_numSteps = 5;
+ break;
+
+ case 0x2000:
+ case 0x4000:
+ m_step = 0;
+ ((u32*)m_Buffer)[m_step++] = _uMail;
+ m_bListInProgress = true;
+ m_numSteps = 3;
+ break;
+
+ default:
+ PanicAlert("UCode Jac");
+ DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF);
+ break;
+ }
+ }
+ else
+ {
+ ((u32*)m_Buffer)[m_step] = _uMail;
+ m_step++;
+
+ if (m_step == m_numSteps)
+ {
+ ExecuteList();
+ m_bListInProgress = false;
+ }
+ }
+}
+
+
+void CUCode_Jac::Update()
+{
+ // check if we have to sent something
+/* if (!g_MailHandler.empty())
+ {
+ g_dspInitialize.pGenerateDSPInterrupt();
+ }*/
+}
+
+
+void CUCode_Jac::ExecuteList()
+{
+ // begin with the list
+ m_readOffset = 0;
+
+ u16 cmd = Read16();
+ u16 sync = Read16();
+
+ DebugLog("==============================================================================");
+ DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync);
+
+ switch (cmd)
+ {
+ // ==============================================================================
+ // DsetupTable
+ // ==============================================================================
+ case 0x40:
+ {
+ u32 tmp[4];
+ tmp[0] = Read32();
+ tmp[1] = Read32();
+ tmp[2] = Read32();
+ tmp[3] = Read32();
+
+ DebugLog("DsetupTable");
+ DebugLog("???: 0x%08x", tmp[0]);
+ DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
+ DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
+ DebugLog("???: 0x%08x", tmp[3]);
+ }
+ break;
+
+ // ==============================================================================
+ // UpdateDSPChannel
+ // ==============================================================================
+ case 0x2000:
+ case 0x4000: // animal crossing
+ {
+ u32 tmp[3];
+ tmp[0] = Read32();
+ tmp[1] = Read32();
+ tmp[2] = Read32();
+
+ DebugLog("UpdateDSPChannel");
+ DebugLog("audiomemory: 0x%08x", tmp[0]);
+ DebugLog("audiomemory: 0x%08x", tmp[1]);
+ DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]);
+ }
+ break;
+
+ default:
+ PanicAlert("UCode Jac unknown cmd: %s (size %)", cmd, m_numSteps);
+ DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps);
+ break;
+ }
+
+ // sync, we are rdy
+ m_rMailHandler.PushMail(DSP_SYNC);
+ m_rMailHandler.PushMail(0xF3550000 | sync);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.h
new file mode 100644
index 0000000000..1a8a02acd4
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Jac.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_JAC
+#define _UCODE_JAC
+
+#include "UCodes.h"
+
+class CUCode_Jac : public IUCode
+{
+private:
+
+ enum EDSP_Codes
+ {
+ DSP_INIT = 0xDCD10000,
+ DSP_RESUME = 0xDCD10001,
+ DSP_YIELD = 0xDCD10002,
+ DSP_DONE = 0xDCD10003,
+ DSP_SYNC = 0xDCD10004,
+ DSP_UNKN = 0xDCD10005,
+ };
+
+ bool m_bListInProgress;
+ int m_numSteps;
+ int m_step;
+ u8 m_Buffer[1024];
+ void ExecuteList();
+
+ u32 m_readOffset;
+
+ u8 Read8()
+ {
+ return(m_Buffer[m_readOffset++]);
+ }
+
+ // Hmm, don't these need bswaps?
+ u16 Read16()
+ {
+ u16 res = *(u16*)&m_Buffer[m_readOffset];
+ m_readOffset += 2;
+ return(res);
+ }
+
+ u32 Read32()
+ {
+ u32 res = *(u32*)&m_Buffer[m_readOffset];
+ m_readOffset += 4;
+ return(res);
+ }
+
+public:
+ CUCode_Jac(CMailHandler& _rMailHandler);
+ virtual ~CUCode_Jac();
+
+ void HandleMail(u32 _uMail);
+ void Update();
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.cpp
new file mode 100644
index 0000000000..435852fd1a
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.cpp
@@ -0,0 +1,113 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+#include "../DSPHandler.h"
+#include "UCodes.h"
+#include "UCode_ROM.h"
+
+CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler)
+ : IUCode(_rMailHandler)
+ , m_BootTask_numSteps(0)
+ , m_NextParameter(0)
+{
+ DebugLog("UCode_Rom - initialized");
+ m_rMailHandler.Clear();
+ m_rMailHandler.PushMail(0x8071FEED);
+}
+
+CUCode_Rom::~CUCode_Rom()
+{}
+
+void CUCode_Rom::Update()
+{}
+
+void CUCode_Rom::HandleMail(u32 _uMail)
+{
+ if (m_NextParameter == 0)
+ {
+ // wait for beginning of UCode
+ if ((_uMail & 0xFFFF0000) != 0x80F30000)
+ {
+ u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF);
+ m_rMailHandler.PushMail(Message);
+ }
+ else
+ {
+ m_NextParameter = _uMail;
+ }
+ }
+ else
+ {
+ switch (m_NextParameter)
+ {
+ case 0x80F3A001:
+ m_CurrentUCode.m_RAMAddress = _uMail;
+ break;
+
+ case 0x80F3A002:
+ m_CurrentUCode.m_Length = _uMail;
+ break;
+
+ case 0x80F3C002:
+ m_CurrentUCode.m_IMEMAddress = _uMail;
+ break;
+
+ case 0x80F3B002:
+ m_CurrentUCode.m_Unk = _uMail;
+ break;
+
+ case 0x80F3D001:
+ {
+ m_CurrentUCode.m_StartPC = _uMail;
+ BootUCode();
+ return; // FIXES THE OVERWRITE
+ }
+ break;
+ }
+
+ // THE GODDAMN OVERWRITE WAS HERE. Without the return above, since BootUCode may delete "this", well ...
+ m_NextParameter = 0;
+ }
+}
+
+void CUCode_Rom::BootUCode()
+{
+ // simple non-scientific crc invented by ector :P
+ // too annoying to change now, and probably good enough anyway
+ u32 crc = 0;
+
+ for (u32 i = 0; i < m_CurrentUCode.m_Length; i++)
+ {
+ crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i);
+ //let's rol
+ crc = (crc << 3) | (crc >> 29);
+ }
+
+ DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress);
+ DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length);
+ DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress);
+ DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk);
+ DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC);
+ DebugLog("CurrentUCode CRC: 0x%08x", crc);
+ DebugLog("BootTask - done");
+
+ CDSPHandler::GetInstance().SetUCode(crc);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.h
new file mode 100644
index 0000000000..82d438485b
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_ROM.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_ROM
+#define _UCODE_ROM
+
+#include "UCodes.h"
+
+class CUCode_Rom : public IUCode
+{
+public:
+ CUCode_Rom(CMailHandler& _rMailHandler);
+ virtual ~CUCode_Rom();
+
+ void HandleMail(u32 _uMail);
+ void Update();
+
+private:
+ struct SUCode
+ {
+ u32 m_RAMAddress;
+ u32 m_Length;
+ u32 m_IMEMAddress;
+ u32 m_Unk;
+ u32 m_StartPC;
+ };
+
+ SUCode m_CurrentUCode;
+ int m_BootTask_numSteps;
+
+ u32 m_NextParameter;
+
+ void BootUCode();
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.cpp
new file mode 100644
index 0000000000..68734d669c
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.cpp
@@ -0,0 +1,166 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// Games that uses this UCode:
+// Zelda: The Windwaker, Mario Sunshine, Mario Kart
+
+#include "Common.h"
+#include "../Globals.h"
+#include "UCodes.h"
+#include "UCode_Zelda.h"
+#include "../MailHandler.h"
+
+
+CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler)
+ : IUCode(_rMailHandler)
+ , m_numSteps(0)
+ , m_bListInProgress(false)
+ , m_step(0)
+ , m_readOffset(0)
+{
+ DebugLog("UCode_Zelda - add boot mails for handshake");
+ m_rMailHandler.PushMail(DSP_INIT);
+ m_rMailHandler.PushMail(0x80000000); // handshake
+ memset(m_Buffer, 0, sizeof(m_Buffer));
+}
+
+
+CUCode_Zelda::~CUCode_Zelda()
+{
+ m_rMailHandler.Clear();
+}
+
+
+void CUCode_Zelda::Update()
+{
+ // check if we have to sent something
+ if (!m_rMailHandler.IsEmpty())
+ g_dspInitialize.pGenerateDSPInterrupt();
+}
+
+
+void CUCode_Zelda::HandleMail(u32 _uMail)
+{
+ if (m_bListInProgress == false)
+ {
+ m_bListInProgress = true;
+ m_numSteps = _uMail;
+ m_step = 0;
+ }
+ else
+ {
+ 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::ExecuteList()
+{
+ // begin with the list
+ m_readOffset = 0;
+
+ u32 Temp = Read32();
+ u32 Command = (Temp >> 24) & 0x7f;
+ u32 Sync = Temp >> 16;
+
+ DebugLog("==============================================================================");
+ DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
+
+ switch (Command)
+ {
+ // DsetupTable ... zelda ww jumps to 0x0095
+ case 0x01:
+ {
+ u32 tmp[4];
+ tmp[0] = Read32();
+ tmp[1] = Read32();
+ tmp[2] = Read32();
+ tmp[3] = Read32();
+
+ DebugLog("DsetupTable");
+ DebugLog("???: 0x%08x", tmp[0]);
+ DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
+ DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
+ DebugLog("???: 0x%08x", tmp[3]);
+ }
+ break;
+
+ // SyncFrame ... zelda ww jumps to 0x0243
+ case 0x02:
+ {
+ u32 tmp[3];
+ tmp[0] = Read32();
+ tmp[1] = Read32();
+ tmp[2] = Read32();
+
+ DebugLog("DsyncFrame");
+ DebugLog("???: 0x%08x", tmp[0]);
+ DebugLog("???: 0x%08x", tmp[1]);
+ DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
+ }
+ break;
+
+/*
+ case 0x03: break; // dunno ... zelda ww jmps to 0x0073
+ 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[2];
+ tmp[0] = Read32();
+ tmp[1] = Read32();
+
+ DebugLog("DSetDolbyDelay");
+ DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]);
+ DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]);
+ }
+ break;
+
+ // Set VARAM
+ case 0x0e:
+// MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK);
+ break;
+
+ // default ... zelda ww jumps to 0x0043
+ default:
+ PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps);
+ break;
+ }
+
+ // sync, we are rdy
+ m_rMailHandler.PushMail(DSP_SYNC);
+ m_rMailHandler.PushMail(0xF3550000 | Sync);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.h
new file mode 100644
index 0000000000..e2c4d87cdf
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCode_Zelda.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODE_ZELDA_H
+#define _UCODE_ZELDA_H
+
+#include "Common.h"
+#include "UCodes.h"
+
+class CUCode_Zelda : public IUCode
+{
+private:
+ enum EDSP_Codes
+ {
+ DSP_INIT = 0xDCD10000,
+ DSP_RESUME = 0xDCD10001,
+ DSP_YIELD = 0xDCD10002,
+ DSP_DONE = 0xDCD10003,
+ DSP_SYNC = 0xDCD10004,
+ DSP_UNKN = 0xDCD10005,
+ };
+
+ // List in progress
+ int m_numSteps;
+ bool m_bListInProgress;
+ int m_step;
+ u8 m_Buffer[1024];
+ void ExecuteList();
+
+ u32 m_readOffset;
+
+ u8 Read8()
+ {
+ return m_Buffer[m_readOffset++];
+ }
+
+ u16 Read16()
+ {
+ u16 res = *(u16*)&m_Buffer[m_readOffset];
+ m_readOffset += 2;
+ return res;
+ }
+
+ u32 Read32()
+ {
+ u32 res = *(u32*)&m_Buffer[m_readOffset];
+ m_readOffset += 4;
+ return res;
+ }
+public:
+
+ CUCode_Zelda(CMailHandler& _rMailHandler);
+ virtual ~CUCode_Zelda();
+
+ void HandleMail(u32 _uMail);
+ void Update();
+};
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.cpp
new file mode 100644
index 0000000000..28cfaeca52
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.cpp
@@ -0,0 +1,87 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Common.h"
+#include "../Globals.h"
+
+#include "UCodes.h"
+
+#include "UCode_AX.h"
+#include "UCode_Zelda.h"
+#include "UCode_Jac.h"
+#include "UCode_ROM.h"
+#include "UCode_CARD.h"
+#include "UCode_InitAudioSystem.h"
+
+IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler)
+{
+ switch (_CRC)
+ {
+ case UCODE_ROM:
+ return new CUCode_Rom(_rMailHandler);
+
+ case UCODE_INIT_AUDIO_SYSTEM:
+ return new CUCode_InitAudioSystem(_rMailHandler);
+
+ case 0x65d6cc6f: // CARD
+ return new CUCode_CARD(_rMailHandler);
+
+ case 0x088e38a5: // IPL - JAP
+ case 0xd73338cf: // IPL
+ case 0x42f64ac4: // Luigi (after fix)
+ case 0x4be6a5cb: // AC, Pikmin (after fix)
+ DebugLog("JAC ucode chosen");
+ return new CUCode_Jac(_rMailHandler);
+
+ case 0x3ad3b7ac: // Naruto3
+ case 0x3daf59b9: // Alien Hominid
+ case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario,
+ // capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat,
+ // smugglers run warzone, smash brothers, sonic mega collection, ZooCube
+ // nddemo, starfox
+ case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2,
+ // Zelda:OOT, Tony hawk, viewtiful joe
+ case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080
+ DebugLog("AX ucode chosen, yay!");
+ return new CUCode_AX(_rMailHandler);
+
+ case 0x6CA33A6D: // DK Jungle Beat
+ case 0x86840740: // zelda
+ case 0x56d36052: // mario
+ case 0x2fcdf1ec: // mariokart, zelda 4 swords
+ DebugLog("Zelda ucode chosen");
+ return new CUCode_Zelda(_rMailHandler);
+
+ // WII CRCs
+ case 0x6c3f6f94: // zelda - PAL
+ case 0xd643001f: // mario galaxy - PAL
+ DebugLog("Zelda Wii ucode chosen");
+ return new CUCode_Zelda(_rMailHandler);
+
+ case 0x347112ba: // raving rabbits
+ DebugLog("Wii - AX chosen");
+ return new CUCode_AX(_rMailHandler, true);
+
+ default:
+ PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC);
+ return new CUCode_AX(_rMailHandler);
+ }
+
+ return NULL;
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.h b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.h
new file mode 100644
index 0000000000..b7da4d0b6e
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/UCodes/UCodes.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _UCODES_H
+#define _UCODES_H
+
+#include "Common.h"
+
+#define UCODE_ROM 0x0000000
+#define UCODE_INIT_AUDIO_SYSTEM 0x0000001
+
+class CMailHandler;
+
+class IUCode
+{
+public:
+ IUCode(CMailHandler& _rMailHandler)
+ : m_rMailHandler(_rMailHandler)
+ {}
+
+ virtual ~IUCode()
+ {}
+
+ virtual void HandleMail(u32 _uMail) = 0;
+ virtual void Update(void) = 0;
+ virtual void MixAdd(short* buffer, int size) {}
+
+protected:
+ CMailHandler& m_rMailHandler;
+};
+
+extern IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler);
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_NULL/Src/main.cpp b/Source/Plugins/Plugin_DSP_NULL/Src/main.cpp
new file mode 100644
index 0000000000..3967a5461b
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_NULL/Src/main.cpp
@@ -0,0 +1,203 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+//#include "Common.h"
+#include "ChunkFile.h"
+#include "pluginspecs_dsp.h"
+
+#include "DSPHandler.h"
+
+DSPInitialize g_dspInitialize;
+u8* g_pMemory;
+
+struct DSPState
+{
+ u32 CPUMailbox;
+ bool CPUMailbox_Written[2];
+
+ u32 DSPMailbox;
+ bool DSPMailbox_Read[2];
+
+ DSPState()
+ {
+ CPUMailbox = 0x00000000;
+ CPUMailbox_Written[0] = false;
+ CPUMailbox_Written[1] = false;
+
+ DSPMailbox = 0x00000000;
+ DSPMailbox_Read[0] = true;
+ DSPMailbox_Read[1] = true;
+ }
+};
+
+DSPState g_dspState;
+
+#ifdef _WIN32
+HINSTANCE g_hInstance = NULL;
+
+BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
+ DWORD dwReason, // reason called
+ LPVOID lpvReserved) // reserved
+{
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ break;
+
+ case DLL_PROCESS_DETACH:
+ break;
+
+ default:
+ break;
+ }
+
+ g_hInstance = hinstDLL;
+ return(TRUE);
+}
+
+#endif
+
+void DllDebugger(HWND _hParent)
+{
+ // TODO: implement
+}
+
+void GetDllInfo(PLUGIN_INFO* _PluginInfo)
+{
+ _PluginInfo->Version = 0x0100;
+ _PluginInfo->Type = PLUGIN_TYPE_DSP;
+#ifdef DEBUGFAST
+ sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (DebugFast) ");
+#else
+#ifndef _DEBUG
+ sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin ");
+#else
+ sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (Debug) ");
+#endif
+#endif
+}
+
+void DllAbout(HWND _hParent)
+{
+}
+
+void DllConfig(HWND _hParent)
+{
+}
+
+void DSP_Initialize(DSPInitialize _dspInitialize)
+{
+ g_dspInitialize = _dspInitialize;
+
+ g_pMemory = g_dspInitialize.pGetMemoryPointer(0);
+
+ CDSPHandler::CreateInstance();
+}
+
+void DSP_Shutdown()
+{
+
+ CDSPHandler::Destroy();
+}
+
+void DSP_DoState(unsigned char **ptr, int mode) {
+ PointerWrap p(ptr, mode);
+}
+
+unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox)
+{
+ if (_CPUMailbox)
+ {
+ return (g_dspState.CPUMailbox >> 16) & 0xFFFF;
+ }
+ else
+ {
+ return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh();
+ }
+}
+
+unsigned short DSP_ReadMailboxLow(bool _CPUMailbox)
+{
+ if (_CPUMailbox)
+ {
+ return g_dspState.CPUMailbox & 0xFFFF;
+ }
+ else
+ {
+ return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow();
+ }
+}
+
+void Update_DSP_WriteRegister()
+{
+ // check if the whole message is complete and if we can send it
+ if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1])
+ {
+ CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox);
+ g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false;
+ g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed
+ }
+}
+
+void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value)
+{
+ if (_CPUMailbox)
+ {
+ g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16);
+ g_dspState.CPUMailbox_Written[0] = true;
+
+ Update_DSP_WriteRegister();
+ }
+ else
+ {
+ PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
+ }
+}
+
+void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value)
+{
+ if (_CPUMailbox)
+ {
+ g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value;
+ g_dspState.CPUMailbox_Written[1] = true;
+
+ Update_DSP_WriteRegister();
+ }
+ else
+ {
+ PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
+ }
+}
+
+unsigned short DSP_WriteControlRegister(unsigned short _Value)
+{
+ return CDSPHandler::GetInstance().WriteControlRegister(_Value);
+}
+
+unsigned short DSP_ReadControlRegister()
+{
+ return CDSPHandler::GetInstance().ReadControlRegister();
+}
+
+void DSP_Update(int cycles)
+{
+ CDSPHandler::GetInstance().Update();
+}
+
+void DSP_SendAIBuffer(unsigned int address, int sample_rate)
+{
+}