2009-07-28 21:32:10 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
2009-03-23 09:10:32 +00:00
|
|
|
|
|
|
|
// 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/
|
|
|
|
|
|
|
|
|
2010-07-20 03:23:25 +00:00
|
|
|
#include "Common.h"
|
|
|
|
#include "CommonPaths.h"
|
2010-05-29 21:34:34 +00:00
|
|
|
#include "Atomic.h"
|
2009-03-23 09:10:32 +00:00
|
|
|
#include "CommonTypes.h"
|
2009-07-12 21:58:32 +00:00
|
|
|
#include "LogManager.h"
|
|
|
|
#include "Thread.h"
|
|
|
|
#include "ChunkFile.h"
|
2011-01-14 15:09:30 +00:00
|
|
|
#include "IniFile.h"
|
2009-03-23 09:10:32 +00:00
|
|
|
|
|
|
|
#include "Globals.h" // Local
|
2009-06-28 10:24:44 +00:00
|
|
|
#include "DSPInterpreter.h"
|
|
|
|
#include "DSPHWInterface.h"
|
2009-03-23 09:10:32 +00:00
|
|
|
#include "disassemble.h"
|
2009-06-21 08:39:21 +00:00
|
|
|
#include "DSPSymbols.h"
|
2009-03-23 20:55:32 +00:00
|
|
|
#include "Config.h"
|
|
|
|
|
2009-03-26 09:29:14 +00:00
|
|
|
#include "AudioCommon.h"
|
2009-07-12 21:58:32 +00:00
|
|
|
#include "Mixer.h"
|
2009-03-23 09:10:32 +00:00
|
|
|
|
2009-04-01 20:22:43 +00:00
|
|
|
#include "DSPTables.h"
|
2009-05-01 20:06:24 +00:00
|
|
|
#include "DSPCore.h"
|
2009-04-01 20:22:43 +00:00
|
|
|
|
2009-03-29 21:00:26 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
|
|
#include "DSPConfigDlgLLE.h"
|
2009-07-02 17:11:27 +00:00
|
|
|
DSPConfigDialogLLE* m_ConfigFrame = NULL;
|
2009-07-12 17:08:48 +00:00
|
|
|
#include "Debugger/DSPDebugWindow.h"
|
2009-03-29 21:00:26 +00:00
|
|
|
#endif
|
|
|
|
|
2009-03-23 09:10:32 +00:00
|
|
|
PLUGIN_GLOBALS* globals = NULL;
|
|
|
|
DSPInitialize g_dspInitialize;
|
2009-03-30 06:28:15 +00:00
|
|
|
Common::Thread *g_hDSPThread = NULL;
|
2009-03-23 20:55:32 +00:00
|
|
|
SoundStream *soundStream = NULL;
|
2009-12-23 15:34:14 +00:00
|
|
|
bool g_InitMixer = false;
|
2009-03-23 20:55:32 +00:00
|
|
|
|
2009-03-30 06:28:15 +00:00
|
|
|
bool bIsRunning = false;
|
2010-05-29 21:34:34 +00:00
|
|
|
volatile u32 cycle_count = 0;
|
2009-03-23 09:10:32 +00:00
|
|
|
|
2009-07-02 19:00:27 +00:00
|
|
|
// Standard crap to make wxWidgets happy
|
2009-07-02 17:11:27 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
HINSTANCE g_hInstance;
|
|
|
|
|
2011-01-14 15:09:30 +00:00
|
|
|
wxLocale *InitLanguageSupport()
|
|
|
|
{
|
|
|
|
wxLocale *m_locale;
|
|
|
|
unsigned int language = 0;
|
|
|
|
|
|
|
|
IniFile ini;
|
|
|
|
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
|
|
|
ini.Get("Interface", "Language", &language, wxLANGUAGE_DEFAULT);
|
|
|
|
|
|
|
|
// Load language if possible, fall back to system default otherwise
|
|
|
|
if(wxLocale::IsAvailable(language))
|
|
|
|
{
|
|
|
|
m_locale = new wxLocale(language);
|
|
|
|
|
|
|
|
m_locale->AddCatalogLookupPathPrefix(wxT("Languages"));
|
|
|
|
|
|
|
|
m_locale->AddCatalog(wxT("dolphin-emu"));
|
|
|
|
|
|
|
|
if(!m_locale->IsOk())
|
|
|
|
{
|
|
|
|
PanicAlertT("Error loading selected language. Falling back to system default.");
|
|
|
|
delete m_locale;
|
|
|
|
m_locale = new wxLocale(wxLANGUAGE_DEFAULT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PanicAlertT("The selected language is not supported by your system. Falling back to system default.");
|
|
|
|
m_locale = new wxLocale(wxLANGUAGE_DEFAULT);
|
|
|
|
}
|
|
|
|
return m_locale;
|
|
|
|
}
|
|
|
|
|
2009-03-29 21:00:26 +00:00
|
|
|
class wxDLLApp : public wxApp
|
|
|
|
{
|
|
|
|
bool OnInit()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
2009-07-02 17:11:27 +00:00
|
|
|
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
|
2009-03-29 21:00:26 +00:00
|
|
|
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
|
|
|
|
2011-01-14 15:09:30 +00:00
|
|
|
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2011-01-14 15:09:30 +00:00
|
|
|
static wxLocale *m_locale;
|
2009-03-23 09:10:32 +00:00
|
|
|
switch (dwReason)
|
|
|
|
{
|
2009-03-29 21:00:26 +00:00
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
{
|
|
|
|
wxSetInstance((HINSTANCE)hinstDLL);
|
2010-02-22 04:59:57 +00:00
|
|
|
wxInitialize();
|
2011-01-14 15:09:30 +00:00
|
|
|
m_locale = InitLanguageSupport();
|
2009-03-29 21:00:26 +00:00
|
|
|
}
|
2009-07-02 17:11:27 +00:00
|
|
|
break;
|
2009-03-29 21:00:26 +00:00
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
2010-02-22 04:59:57 +00:00
|
|
|
wxUninitialize();
|
2011-01-14 15:09:30 +00:00
|
|
|
delete m_locale;
|
2009-03-29 21:00:26 +00:00
|
|
|
break;
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_hInstance = hinstDLL;
|
2009-07-02 17:11:27 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-03-23 09:10:32 +00:00
|
|
|
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
|
|
|
{
|
|
|
|
_PluginInfo->Version = 0x0100;
|
|
|
|
_PluginInfo->Type = PLUGIN_TYPE_DSP;
|
|
|
|
|
|
|
|
#ifdef DEBUGFAST
|
2010-02-25 12:35:31 +00:00
|
|
|
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (DebugFast)");
|
2011-01-14 15:09:30 +00:00
|
|
|
#elif defined _DEBUG
|
2010-02-25 12:35:31 +00:00
|
|
|
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (Debug)");
|
2011-01-14 15:09:30 +00:00
|
|
|
#else
|
|
|
|
sprintf(_PluginInfo->Name, _trans("Dolphin DSP-LLE Plugin"));
|
2009-03-23 09:10:32 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
|
|
|
{
|
|
|
|
globals = _pPluginGlobals;
|
|
|
|
LogManager::SetInstance((LogManager *)globals->logManager);
|
|
|
|
}
|
|
|
|
|
2010-07-30 03:51:49 +00:00
|
|
|
void DllConfig(void *_hParent)
|
2009-03-23 20:55:32 +00:00
|
|
|
{
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2010-07-30 03:51:49 +00:00
|
|
|
m_ConfigFrame = new DSPConfigDialogLLE((wxWindow *)_hParent);
|
2009-03-23 20:55:32 +00:00
|
|
|
|
2010-02-25 06:12:35 +00:00
|
|
|
// add backends
|
|
|
|
std::vector<std::string> backends = AudioCommon::GetSoundBackends();
|
2009-03-27 14:26:44 +00:00
|
|
|
|
2010-02-25 06:12:35 +00:00
|
|
|
for (std::vector<std::string>::const_iterator iter = backends.begin();
|
|
|
|
iter != backends.end(); ++iter)
|
|
|
|
{
|
|
|
|
m_ConfigFrame->AddBackend((*iter).c_str());
|
|
|
|
}
|
2009-03-23 20:55:32 +00:00
|
|
|
|
2010-03-05 07:03:44 +00:00
|
|
|
m_ConfigFrame->ShowModal();
|
2010-02-25 17:50:08 +00:00
|
|
|
|
|
|
|
m_ConfigFrame->Destroy();
|
2009-03-23 20:55:32 +00:00
|
|
|
#endif
|
|
|
|
}
|
2009-03-23 09:10:32 +00:00
|
|
|
|
2009-03-29 21:00:26 +00:00
|
|
|
void DoState(unsigned char **ptr, int mode)
|
|
|
|
{
|
2009-03-23 09:10:32 +00:00
|
|
|
PointerWrap p(ptr, mode);
|
2009-12-23 15:34:14 +00:00
|
|
|
p.Do(g_InitMixer);
|
2010-01-12 21:38:39 +00:00
|
|
|
|
|
|
|
// Enable this when the HLE is fixed to save/load the same amount of data,
|
|
|
|
// no matter how bogus, so that one can switch LLE->HLE. The other way is unlikely to work very well.
|
|
|
|
#if 0
|
|
|
|
p.Do(g_dsp.r);
|
|
|
|
p.Do(g_dsp.pc);
|
|
|
|
p.Do(g_dsp.err_pc);
|
|
|
|
p.Do(g_dsp.cr);
|
|
|
|
p.Do(g_dsp.reg_stack_ptr);
|
|
|
|
p.Do(g_dsp.exceptions);
|
|
|
|
p.Do(g_dsp.exceptions_in_progress);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
p.Do(g_dsp.reg_stack[i]);
|
|
|
|
}
|
|
|
|
p.Do(g_dsp.iram_crc);
|
|
|
|
p.Do(g_dsp.step_counter);
|
|
|
|
p.Do(g_dsp.ifx_regs);
|
|
|
|
p.Do(g_dsp.mbox[0]);
|
|
|
|
p.Do(g_dsp.mbox[1]);
|
|
|
|
p.DoArray(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
|
|
|
|
p.DoArray(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
|
|
|
|
#endif
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
|
|
|
void EmuStateChange(PLUGIN_EMUSTATE newState)
|
|
|
|
{
|
2010-01-13 14:18:13 +00:00
|
|
|
DSP_ClearAudioBuffer((newState == PLUGIN_EMUSTATE_PLAY) ? false : true);
|
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
|
|
|
}
|
|
|
|
|
2010-07-22 02:05:28 +00:00
|
|
|
void *DllDebugger(void *_hParent, bool Show)
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2009-03-30 13:21:22 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2010-07-22 02:05:28 +00:00
|
|
|
m_DebuggerFrame = new DSPDebuggerLLE((wxWindow *)_hParent);
|
|
|
|
return (void *)m_DebuggerFrame;
|
|
|
|
#else
|
|
|
|
return NULL;
|
2009-03-30 13:21:22 +00:00
|
|
|
#endif
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-29 09:35:40 +00:00
|
|
|
// Regular thread
|
2009-03-29 21:00:26 +00:00
|
|
|
THREAD_RETURN dsp_thread(void* lpParameter)
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2009-03-30 06:28:15 +00:00
|
|
|
while (bIsRunning)
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2010-05-29 21:34:34 +00:00
|
|
|
int cycles = (int)cycle_count;
|
|
|
|
if (cycles > 0) {
|
2010-11-28 09:49:41 +00:00
|
|
|
if (jit)
|
|
|
|
DSPCore_RunCycles(cycles);
|
|
|
|
else
|
|
|
|
DSPInterpreter::RunCycles(cycles);
|
|
|
|
|
2010-05-29 21:34:34 +00:00
|
|
|
Common::AtomicAdd(cycle_count, -cycles);
|
2010-04-07 15:04:45 +00:00
|
|
|
}
|
2010-05-29 21:34:34 +00:00
|
|
|
// yield?
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
2009-03-30 06:28:15 +00:00
|
|
|
return 0;
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSP_DebugBreak()
|
|
|
|
{
|
2009-04-02 12:50:47 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2009-06-28 16:23:40 +00:00
|
|
|
// if (m_DebuggerFrame)
|
|
|
|
// m_DebuggerFrame->DebugBreak();
|
2009-04-02 12:50:47 +00:00
|
|
|
#endif
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Initialize(void *init)
|
|
|
|
{
|
2009-12-23 15:34:14 +00:00
|
|
|
g_InitMixer = false;
|
2011-01-04 02:04:52 +00:00
|
|
|
bool bCanWork = true;
|
|
|
|
char irom_file[MAX_PATH];
|
|
|
|
char coef_file[MAX_PATH];
|
|
|
|
g_dspInitialize = *(DSPInitialize*)init;
|
2009-03-23 09:10:32 +00:00
|
|
|
|
2009-03-30 09:55:50 +00:00
|
|
|
g_Config.Load();
|
2009-04-05 15:46:47 +00:00
|
|
|
|
2011-01-04 02:04:52 +00:00
|
|
|
snprintf(irom_file, MAX_PATH, "%s%s",
|
2011-01-04 13:59:44 +00:00
|
|
|
File::GetSysDirectory().c_str(), GC_SYS_DIR DIR_SEP DSP_IROM);
|
|
|
|
if (!File::Exists(irom_file))
|
|
|
|
snprintf(irom_file, MAX_PATH, "%s%s",
|
|
|
|
File::GetUserPath(D_GCUSER_IDX), DIR_SEP DSP_IROM);
|
2011-01-04 02:04:52 +00:00
|
|
|
snprintf(coef_file, MAX_PATH, "%s%s",
|
2011-01-04 13:59:44 +00:00
|
|
|
File::GetSysDirectory().c_str(), GC_SYS_DIR DIR_SEP DSP_COEF);
|
|
|
|
if (!File::Exists(coef_file))
|
|
|
|
snprintf(coef_file, MAX_PATH, "%s%s",
|
|
|
|
File::GetUserPath(D_GCUSER_IDX), DIR_SEP DSP_COEF);
|
2011-01-04 02:04:52 +00:00
|
|
|
bCanWork = DSPCore_Init(irom_file, coef_file, AudioCommon::UseJIT());
|
2009-07-02 21:20:47 +00:00
|
|
|
|
2009-03-23 09:10:32 +00:00
|
|
|
g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0);
|
2009-06-07 11:06:40 +00:00
|
|
|
DSPCore_Reset();
|
2009-04-05 15:46:47 +00:00
|
|
|
|
2009-04-08 20:26:33 +00:00
|
|
|
if (!bCanWork)
|
|
|
|
{
|
2009-06-07 11:06:40 +00:00
|
|
|
DSPCore_Shutdown();
|
2011-01-13 03:46:34 +00:00
|
|
|
// No way to shutdown Core from here? Hardcore shutdown!
|
|
|
|
exit(EXIT_FAILURE);
|
2009-04-08 12:37:15 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-03-30 06:28:15 +00:00
|
|
|
|
|
|
|
bIsRunning = true;
|
2009-04-05 15:46:47 +00:00
|
|
|
|
2009-04-06 18:47:21 +00:00
|
|
|
InitInstructionTable();
|
|
|
|
|
2009-04-08 20:26:33 +00:00
|
|
|
if (g_dspInitialize.bOnThread)
|
|
|
|
{
|
|
|
|
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
|
|
|
|
}
|
2009-04-18 19:06:47 +00:00
|
|
|
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2009-06-21 08:39:21 +00:00
|
|
|
if (m_DebuggerFrame)
|
2009-04-18 19:06:47 +00:00
|
|
|
m_DebuggerFrame->Refresh();
|
|
|
|
#endif
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSP_StopSoundStream()
|
|
|
|
{
|
2009-05-01 22:17:22 +00:00
|
|
|
DSPInterpreter::Stop();
|
2009-04-03 12:21:02 +00:00
|
|
|
bIsRunning = false;
|
2009-04-08 20:26:33 +00:00
|
|
|
if (g_dspInitialize.bOnThread)
|
|
|
|
{
|
|
|
|
delete g_hDSPThread;
|
|
|
|
g_hDSPThread = NULL;
|
|
|
|
}
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
2009-04-06 18:47:21 +00:00
|
|
|
void Shutdown()
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2009-03-27 14:26:44 +00:00
|
|
|
AudioCommon::ShutdownSoundStream();
|
2009-06-07 11:06:40 +00:00
|
|
|
DSPCore_Shutdown();
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u16 DSP_WriteControlRegister(u16 _uFlag)
|
|
|
|
{
|
2009-12-23 15:34:14 +00:00
|
|
|
UDSPControl Temp(_uFlag);
|
|
|
|
if (!g_InitMixer)
|
|
|
|
{
|
|
|
|
if (!Temp.DSPHalt && Temp.DSPInit)
|
|
|
|
{
|
2009-12-25 11:59:04 +00:00
|
|
|
unsigned int AISampleRate, DACSampleRate;
|
|
|
|
g_dspInitialize.pGetSampleRate(AISampleRate, DACSampleRate);
|
|
|
|
soundStream = AudioCommon::InitSoundStream(new CMixer(AISampleRate, DACSampleRate));
|
2009-12-23 15:34:14 +00:00
|
|
|
if(!soundStream) PanicAlert("Error starting up sound stream");
|
|
|
|
// Mixer is initialized
|
|
|
|
g_InitMixer = true;
|
|
|
|
}
|
|
|
|
}
|
2009-05-01 22:17:22 +00:00
|
|
|
DSPInterpreter::WriteCR(_uFlag);
|
2011-01-03 14:19:11 +00:00
|
|
|
|
|
|
|
// Check if the CPU has set an external interrupt (CR_EXTERNAL_INT)
|
|
|
|
// and immediately process it, if it has.
|
|
|
|
if (_uFlag & 2)
|
|
|
|
{
|
2011-01-16 11:13:23 +00:00
|
|
|
if (!g_dspInitialize.bOnThread)
|
|
|
|
{
|
|
|
|
DSPCore_CheckExternalInterrupt();
|
|
|
|
DSPCore_CheckExceptions();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DSPCore_SetExternalInterrupt(true);
|
|
|
|
}
|
|
|
|
|
2011-01-03 14:19:11 +00:00
|
|
|
}
|
|
|
|
|
2009-05-01 22:17:22 +00:00
|
|
|
return DSPInterpreter::ReadCR();
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u16 DSP_ReadControlRegister()
|
|
|
|
{
|
2009-05-01 22:17:22 +00:00
|
|
|
return DSPInterpreter::ReadCR();
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u16 DSP_ReadMailboxHigh(bool _CPUMailbox)
|
|
|
|
{
|
|
|
|
if (_CPUMailbox)
|
2009-04-05 15:46:47 +00:00
|
|
|
return gdsp_mbox_read_h(GDSP_MBOX_CPU);
|
2009-03-23 09:10:32 +00:00
|
|
|
else
|
2009-04-05 15:46:47 +00:00
|
|
|
return gdsp_mbox_read_h(GDSP_MBOX_DSP);
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u16 DSP_ReadMailboxLow(bool _CPUMailbox)
|
|
|
|
{
|
|
|
|
if (_CPUMailbox)
|
2009-04-05 15:46:47 +00:00
|
|
|
return gdsp_mbox_read_l(GDSP_MBOX_CPU);
|
2009-03-23 09:10:32 +00:00
|
|
|
else
|
2009-04-05 15:46:47 +00:00
|
|
|
return gdsp_mbox_read_l(GDSP_MBOX_DSP);
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DSP_WriteMailboxHigh(bool _CPUMailbox, u16 _uHighMail)
|
|
|
|
{
|
|
|
|
if (_CPUMailbox)
|
|
|
|
{
|
|
|
|
if (gdsp_mbox_peek(GDSP_MBOX_CPU) & 0x80000000)
|
|
|
|
{
|
2009-04-06 17:12:05 +00:00
|
|
|
ERROR_LOG(DSPLLE, "Mailbox isnt empty ... strange");
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if PROFILE
|
|
|
|
if ((_uHighMail) == 0xBABE)
|
|
|
|
{
|
|
|
|
ProfilerStart();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
gdsp_mbox_write_h(GDSP_MBOX_CPU, _uHighMail);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-04-06 17:12:05 +00:00
|
|
|
ERROR_LOG(DSPLLE, "CPU cant write to DSP mailbox");
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail)
|
|
|
|
{
|
|
|
|
if (_CPUMailbox)
|
|
|
|
{
|
|
|
|
gdsp_mbox_write_l(GDSP_MBOX_CPU, _uLowMail);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-04-06 17:12:05 +00:00
|
|
|
ERROR_LOG(DSPLLE, "CPU cant write to DSP mailbox");
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSP_Update(int cycles)
|
|
|
|
{
|
2010-05-30 05:25:32 +00:00
|
|
|
unsigned int dsp_cycles = cycles / 6; //(jit?20:6);
|
2010-05-29 21:34:34 +00:00
|
|
|
|
2009-12-25 11:59:04 +00:00
|
|
|
// Sound stream update job has been handled by AudioDMA routine, which is more efficient
|
|
|
|
/*
|
2009-04-08 20:26:33 +00:00
|
|
|
// This gets called VERY OFTEN. The soundstream update might be expensive so only do it 200 times per second or something.
|
2009-11-14 17:45:35 +00:00
|
|
|
int cycles_between_ss_update;
|
|
|
|
|
|
|
|
if (g_dspInitialize.bWii)
|
|
|
|
cycles_between_ss_update = 121500000 / 200;
|
|
|
|
else
|
|
|
|
cycles_between_ss_update = 81000000 / 200;
|
|
|
|
|
2009-04-08 20:26:33 +00:00
|
|
|
cycle_count += cycles;
|
|
|
|
if (cycle_count > cycles_between_ss_update)
|
|
|
|
{
|
|
|
|
while (cycle_count > cycles_between_ss_update)
|
|
|
|
cycle_count -= cycles_between_ss_update;
|
|
|
|
soundStream->Update();
|
|
|
|
}
|
2009-12-25 11:59:04 +00:00
|
|
|
*/
|
2009-04-08 20:26:33 +00:00
|
|
|
// If we're not on a thread, run cycles here.
|
|
|
|
if (!g_dspInitialize.bOnThread)
|
|
|
|
{
|
2010-04-07 15:04:45 +00:00
|
|
|
// ~1/6th as many cycles as the period PPC-side.
|
2010-05-29 21:34:34 +00:00
|
|
|
DSPCore_RunCycles(dsp_cycles);
|
2010-04-07 15:04:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-05-29 21:34:34 +00:00
|
|
|
// Wait for dsp thread to catch up reasonably. Note: this logic should be thought through.
|
|
|
|
while (cycle_count > dsp_cycles)
|
|
|
|
;
|
|
|
|
Common::AtomicAdd(cycle_count, dsp_cycles);
|
2009-04-08 20:26:33 +00:00
|
|
|
}
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
2009-12-25 11:59:04 +00:00
|
|
|
void DSP_SendAIBuffer(unsigned int address, unsigned int num_samples)
|
2009-03-23 09:10:32 +00:00
|
|
|
{
|
2009-12-23 15:34:14 +00:00
|
|
|
if (!soundStream)
|
|
|
|
return;
|
|
|
|
|
2010-01-12 21:38:39 +00:00
|
|
|
CMixer *pMixer = soundStream->GetMixer();
|
2009-12-23 15:34:14 +00:00
|
|
|
|
2010-01-12 21:38:39 +00:00
|
|
|
if (pMixer != 0 && address != 0)
|
2009-03-26 09:29:14 +00:00
|
|
|
{
|
2010-01-12 21:38:39 +00:00
|
|
|
short *samples = (short *)Memory_Get_Pointer(address);
|
2009-12-25 11:59:04 +00:00
|
|
|
pMixer->PushSamples(samples, num_samples);
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
|
|
|
|
2009-12-23 15:34:14 +00:00
|
|
|
soundStream->Update();
|
2009-03-23 09:10:32 +00:00
|
|
|
}
|
2009-11-07 20:01:39 +00:00
|
|
|
|
2010-01-13 14:18:13 +00:00
|
|
|
void DSP_ClearAudioBuffer(bool mute)
|
2009-11-07 20:01:39 +00:00
|
|
|
{
|
2010-01-12 21:38:39 +00:00
|
|
|
if (soundStream)
|
2010-01-13 14:18:13 +00:00
|
|
|
soundStream->Clear(mute);
|
2009-11-07 20:01:39 +00:00
|
|
|
}
|
|
|
|
|