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) +{ +}