DSP: New non-threaded mode for the LLE plugin, with some idle skipping enabled. Use Dolphin Main config to set it. Some minor optimization and some spelling fixes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2937 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-04-08 20:26:33 +00:00
parent 5dbdc4e6cf
commit 8c3bb3796b
16 changed files with 149 additions and 82 deletions

View File

@ -63,7 +63,7 @@ void SConfig::SaveSettings()
ini.Set("General", tmp, m_ISOFolder[i]); ini.Set("General", tmp, m_ISOFolder[i]);
} }
ini.Set("General", "RecersiveGCMPaths", m_RecersiveISOFolder); ini.Set("General", "RecersiveGCMPaths", m_RecursiveISOFolder);
} }
@ -87,6 +87,7 @@ void SConfig::SaveSettings()
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios); ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT); ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore); ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
ini.Set("Core", "DSPThread", m_LocalCoreStartupParameter.bDSPThread);
ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle); ini.Set("Core", "SkipIdle", m_LocalCoreStartupParameter.bSkipIdle);
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads); ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM); ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
@ -168,7 +169,7 @@ void SConfig::LoadSettings()
} }
} }
ini.Get("General", "RecersiveGCMPaths", &m_RecersiveISOFolder, false); ini.Get("General", "RecersiveGCMPaths", &m_RecursiveISOFolder, false);
} }
{ {
@ -188,11 +189,12 @@ void SConfig::LoadSettings()
ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false); ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false);
// Core // Core
ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true); ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true);
ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true); ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true);
ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false); ini.Get("Core", "DSPThread", &m_LocalCoreStartupParameter.bDSPThread, true);
ini.Get("Core", "SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true); ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false);
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true); ini.Get("Core", "SkipIdle", &m_LocalCoreStartupParameter.bSkipIdle, true);
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true);
ini.Get("Core", "DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM); ini.Get("Core", "DefaultGCM", &m_LocalCoreStartupParameter.m_strDefaultGCM);
ini.Get("Core", "DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot); ini.Get("Core", "DVDRoot", &m_LocalCoreStartupParameter.m_strDVDRoot);
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true); ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);

View File

@ -50,8 +50,8 @@ struct SConfig
std::string m_LastFilename; std::string m_LastFilename;
// gcm folder // gcm folder
std::vector<std::string>m_ISOFolder; std::vector<std::string> m_ISOFolder;
bool m_RecersiveISOFolder; bool m_RecursiveISOFolder;
SCoreStartupParameter m_LocalCoreStartupParameter; SCoreStartupParameter m_LocalCoreStartupParameter;

View File

@ -414,6 +414,7 @@ THREAD_RETURN EmuThread(void *pArg)
dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming; dspInit.pGetAudioStreaming = AudioInterface::Callback_GetStreaming;
dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr(); dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr();
dspInit.bWii = _CoreParameter.bWii; dspInit.bWii = _CoreParameter.bWii;
dspInit.bOnThread = _CoreParameter.bDSPThread;
// May be needed for Stop and Start // May be needed for Stop and Start
#ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT #ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT
Plugins.FreeDSP(); Plugins.FreeDSP();

View File

@ -41,6 +41,7 @@ void SCoreStartupParameter::LoadDefaults()
bUseDualCore = false; bUseDualCore = false;
bSkipIdle = false; bSkipIdle = false;
bRunCompareServer = false; bRunCompareServer = false;
bDSPThread = true;
bLockThreads = true; bLockThreads = true;
bWii = false; bWii = false;
SelectedLanguage = 0; SelectedLanguage = 0;

View File

@ -57,6 +57,7 @@ struct SCoreStartupParameter
bool bJITBranchOff; bool bJITBranchOff;
bool bUseDualCore; bool bUseDualCore;
bool bDSPThread;
bool bSkipIdle; bool bSkipIdle;
bool bNTSC; bool bNTSC;
bool bHLEBios; bool bHLEBios;

View File

@ -210,7 +210,7 @@ void DecrementerCallback(u64 userdata, int cyclesLate)
void DecrementerSet() void DecrementerSet()
{ {
u32 decValue = PowerPC::ppcState.spr[SPR_DEC]; u32 decValue = PowerPC::ppcState.spr[SPR_DEC];
fakeDec = decValue*TIMER_RATIO; fakeDec = decValue * TIMER_RATIO;
CoreTiming::RemoveEvent(et_Dec); CoreTiming::RemoveEvent(et_Dec);
CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec); CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
} }
@ -221,8 +221,8 @@ void AdvanceCallback(int cyclesExecuted)
return; return;
fakeDec -= cyclesExecuted; fakeDec -= cyclesExecuted;
u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO; //works since we are little endian and TL comes first :) u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO;
*(u64*)&TL = timebase_ticks + startTimeBaseTicks; *(u64*)&TL = timebase_ticks + startTimeBaseTicks; //works since we are little endian and TL comes first :)
if (fakeDec >= 0) if (fakeDec >= 0)
PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO; PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO;
} }
@ -243,10 +243,15 @@ void Init()
CPU_CORE_CLOCK = 729000000u; CPU_CORE_CLOCK = 729000000u;
VI_PERIOD = GetTicksPerSecond() / (60*120); VI_PERIOD = GetTicksPerSecond() / (60*120);
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
// These are the big question marks IMHO :) if (!Core::GetStartupParameter().bDSPThread) {
DSP_PERIOD = 12000; // TO BE TWEAKED
} else {
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
}
// This is the biggest question mark.
AI_PERIOD = GetTicksPerSecond() / 80; AI_PERIOD = GetTicksPerSecond() / 80;
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f); IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
} }
@ -255,10 +260,15 @@ void Init()
CPU_CORE_CLOCK = 486000000; CPU_CORE_CLOCK = 486000000;
VI_PERIOD = GetTicksPerSecond() / (60*120); VI_PERIOD = GetTicksPerSecond() / (60*120);
SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers
// These are the big question marks IMHO :) if (!Core::GetStartupParameter().bDSPThread) {
DSP_PERIOD = 12000; // TO BE TWEAKED
} else {
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f);
}
// This is the biggest question mark.
AI_PERIOD = GetTicksPerSecond() / 80; AI_PERIOD = GetTicksPerSecond() / 80;
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f);
} }
Common::Timer::IncreaseResolution(); Common::Timer::IncreaseResolution();
// store and convert localtime at boot to timebase ticks // store and convert localtime at boot to timebase ticks

View File

@ -49,6 +49,7 @@ EVT_CHOICE(ID_INTERFACE_LANG, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_ALLWAYS_HLEBIOS, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_ALLWAYS_HLEBIOS, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_USEDYNAREC, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_USEDYNAREC, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_USEDUALCORE, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_USEDUALCORE, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_DSPTHREAD, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_LOCKTHREADS, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_LOCKTHREADS, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_OPTIMIZEQUANTIZERS, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_OPTIMIZEQUANTIZERS, CConfigMain::CoreSettingsChanged)
EVT_CHECKBOX(ID_IDLESKIP, CConfigMain::CoreSettingsChanged) EVT_CHECKBOX(ID_IDLESKIP, CConfigMain::CoreSettingsChanged)
@ -131,7 +132,7 @@ void CConfigMain::UpdateGUI()
if(Core::GetState() != Core::CORE_UNINITIALIZED) if(Core::GetState() != Core::CORE_UNINITIALIZED)
{ {
// Disable the Core stuff on GeneralPage // Disable the Core stuff on GeneralPage
AllwaysHLEBIOS->Disable(); AlwaysUseHLEBIOS->Disable();
UseDynaRec->Disable(); UseDynaRec->Disable();
UseDualCore->Disable(); UseDualCore->Disable();
LockThreads->Disable(); LockThreads->Disable();
@ -182,13 +183,15 @@ void CConfigMain::CreateGUIControls()
// Core Settings - Basic // Core Settings - Basic
UseDualCore = new wxCheckBox(GeneralPage, ID_USEDUALCORE, wxT("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); UseDualCore = new wxCheckBox(GeneralPage, ID_USEDUALCORE, wxT("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
UseDualCore->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore); UseDualCore->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore);
DSPThread = new wxCheckBox(GeneralPage, ID_DSPTHREAD, wxT("LLE DSP on thread"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
DSPThread->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread);
SkipIdle = new wxCheckBox(GeneralPage, ID_IDLESKIP, wxT("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); SkipIdle = new wxCheckBox(GeneralPage, ID_IDLESKIP, wxT("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle); SkipIdle->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle);
EnableCheats = new wxCheckBox(GeneralPage, ID_ENABLECHEATS, wxT("Enable Cheats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); EnableCheats = new wxCheckBox(GeneralPage, ID_ENABLECHEATS, wxT("Enable Cheats"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats); EnableCheats->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats);
// Core Settings - Advanced // Core Settings - Advanced
AllwaysHLEBIOS = new wxCheckBox(GeneralPage, ID_ALLWAYS_HLEBIOS, wxT("HLE the BIOS all the time"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); AlwaysUseHLEBIOS = new wxCheckBox(GeneralPage, ID_ALLWAYS_HLEBIOS, wxT("HLE the BIOS all the time"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
AllwaysHLEBIOS->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios); AlwaysUseHLEBIOS->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios);
UseDynaRec = new wxCheckBox(GeneralPage, ID_USEDYNAREC, wxT("Enable the JIT dynarec"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); UseDynaRec = new wxCheckBox(GeneralPage, ID_USEDYNAREC, wxT("Enable the JIT dynarec"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
UseDynaRec->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT); UseDynaRec->SetValue(SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT);
LockThreads = new wxCheckBox(GeneralPage, ID_LOCKTHREADS, wxT("Lock threads to cores"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); LockThreads = new wxCheckBox(GeneralPage, ID_LOCKTHREADS, wxT("Lock threads to cores"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
@ -260,10 +263,11 @@ void CConfigMain::CreateGUIControls()
sCore = new wxBoxSizer(wxHORIZONTAL); sCore = new wxBoxSizer(wxHORIZONTAL);
sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Basic Settings")); sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Basic Settings"));
sbBasic->Add(UseDualCore, 0, wxALL, 5); sbBasic->Add(UseDualCore, 0, wxALL, 5);
sbBasic->Add(DSPThread, 0, wxALL, 5);
sbBasic->Add(SkipIdle, 0, wxALL, 5); sbBasic->Add(SkipIdle, 0, wxALL, 5);
sbBasic->Add(EnableCheats, 0, wxALL, 5); sbBasic->Add(EnableCheats, 0, wxALL, 5);
sbAdvanced = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Advanced Settings")); sbAdvanced = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, wxT("Advanced Settings"));
sbAdvanced->Add(AllwaysHLEBIOS, 0, wxALL, 5); sbAdvanced->Add(AlwaysUseHLEBIOS, 0, wxALL, 5);
sbAdvanced->Add(UseDynaRec, 0, wxALL, 5); sbAdvanced->Add(UseDynaRec, 0, wxALL, 5);
sbAdvanced->Add(LockThreads, 0, wxALL, 5); sbAdvanced->Add(LockThreads, 0, wxALL, 5);
sbAdvanced->Add(OptimizeQuantizers, 0, wxALL, 5); sbAdvanced->Add(OptimizeQuantizers, 0, wxALL, 5);
@ -443,7 +447,7 @@ void CConfigMain::CreateGUIControls()
RemoveISOPath = new wxButton(PathsPage, ID_REMOVEISOPATH, wxT("Remove"), wxDefaultPosition, wxDefaultSize, 0); RemoveISOPath = new wxButton(PathsPage, ID_REMOVEISOPATH, wxT("Remove"), wxDefaultPosition, wxDefaultSize, 0);
RemoveISOPath->Enable(false); RemoveISOPath->Enable(false);
RecersiveISOPath = new wxCheckBox(PathsPage, ID_RECERSIVEISOPATH, wxT("Search Subfolders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); RecersiveISOPath = new wxCheckBox(PathsPage, ID_RECERSIVEISOPATH, wxT("Search Subfolders"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
RecersiveISOPath->SetValue(SConfig::GetInstance().m_RecersiveISOFolder); RecersiveISOPath->SetValue(SConfig::GetInstance().m_RecursiveISOFolder);
DefaultISOText = new wxStaticText(PathsPage, ID_DEFAULTISO_TEXT, wxT("Default ISO:"), wxDefaultPosition, wxDefaultSize); DefaultISOText = new wxStaticText(PathsPage, ID_DEFAULTISO_TEXT, wxT("Default ISO:"), wxDefaultPosition, wxDefaultSize);
DefaultISO = new wxFilePickerCtrl(PathsPage, ID_DEFAULTISO, wxEmptyString, wxT("Choose a default ISO:"), DefaultISO = new wxFilePickerCtrl(PathsPage, ID_DEFAULTISO, wxEmptyString, wxT("Choose a default ISO:"),
wxString::Format(wxT("All GC/Wii images (gcm, iso, gcz)|*.gcm;*.iso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr), wxString::Format(wxT("All GC/Wii images (gcm, iso, gcz)|*.gcm;*.iso;*.gcz|All files (%s)|%s"), wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr),
@ -611,7 +615,7 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
break; break;
case ID_ALLWAYS_HLEBIOS: // Core case ID_ALLWAYS_HLEBIOS: // Core
SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios = AllwaysHLEBIOS->IsChecked(); SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios = AlwaysUseHLEBIOS->IsChecked();
break; break;
case ID_USEDYNAREC: case ID_USEDYNAREC:
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT = UseDynaRec->IsChecked(); SConfig::GetInstance().m_LocalCoreStartupParameter.bUseJIT = UseDynaRec->IsChecked();
@ -619,6 +623,9 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
case ID_USEDUALCORE: case ID_USEDUALCORE:
SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = UseDualCore->IsChecked(); SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = UseDualCore->IsChecked();
break; break;
case ID_DSPTHREAD:
SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = DSPThread->IsChecked();
break;
case ID_LOCKTHREADS: case ID_LOCKTHREADS:
SConfig::GetInstance().m_LocalCoreStartupParameter.bLockThreads = LockThreads->IsChecked(); SConfig::GetInstance().m_LocalCoreStartupParameter.bLockThreads = LockThreads->IsChecked();
break; break;
@ -843,7 +850,7 @@ void CConfigMain::AddRemoveISOPaths(wxCommandEvent& event)
void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event)) void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event))
{ {
SConfig::GetInstance().m_RecersiveISOFolder = RecersiveISOPath->IsChecked(); SConfig::GetInstance().m_RecursiveISOFolder = RecersiveISOPath->IsChecked();
bRefreshList = true; bRefreshList = true;
} }

View File

@ -60,9 +60,10 @@ class CConfigMain
wxBoxSizer* sCore; wxBoxSizer* sCore;
wxStaticBoxSizer* sbBasic, *sbAdvanced, *sbInterface; wxStaticBoxSizer* sbBasic, *sbAdvanced, *sbInterface;
wxCheckBox* AllwaysHLEBIOS; wxCheckBox* AlwaysUseHLEBIOS;
wxCheckBox* UseDynaRec; wxCheckBox* UseDynaRec;
wxCheckBox* UseDualCore; wxCheckBox* UseDualCore;
wxCheckBox* DSPThread;
wxCheckBox* LockThreads; wxCheckBox* LockThreads;
wxCheckBox* OptimizeQuantizers; wxCheckBox* OptimizeQuantizers;
wxCheckBox* SkipIdle; wxCheckBox* SkipIdle;
@ -213,6 +214,7 @@ class CConfigMain
ID_ALLWAYS_HLEBIOS, ID_ALLWAYS_HLEBIOS,
ID_USEDYNAREC, ID_USEDYNAREC,
ID_USEDUALCORE, ID_USEDUALCORE,
ID_DSPTHREAD,
ID_LOCKTHREADS, ID_LOCKTHREADS,
ID_OPTIMIZEQUANTIZERS, ID_OPTIMIZEQUANTIZERS,
ID_IDLESKIP, ID_IDLESKIP,

View File

@ -375,7 +375,7 @@ void CGameListCtrl::ScanForISOs()
m_ISOFiles.clear(); m_ISOFiles.clear();
CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder); CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder);
if (SConfig::GetInstance().m_RecersiveISOFolder) if (SConfig::GetInstance().m_RecursiveISOFolder)
{ {
for (u32 i = 0; i < Directories.size(); i++) for (u32 i = 0; i < Directories.size(); i++)
{ {

View File

@ -30,6 +30,7 @@ typedef struct
TAudioGetStreaming pGetAudioStreaming; TAudioGetStreaming pGetAudioStreaming;
int *pEmulatorState; int *pEmulatorState;
bool bWii; bool bWii;
bool bOnThread;
} DSPInitialize; } DSPInitialize;

View File

@ -23,7 +23,7 @@
namespace DSPAnalyzer { namespace DSPAnalyzer {
// Holds data about all instructions in RAM. // Holds data about all instructions in RAM.
u8 inst_flags[ISPACE]; u8 code_flags[ISPACE];
// Good candidates for idle skipping is mail wait loops. If we're time slicing // Good candidates for idle skipping is mail wait loops. If we're time slicing
// between the main CPU and the DSP, if the DSP runs into one of these, it might // between the main CPU and the DSP, if the DSP runs into one of these, it might
@ -39,24 +39,24 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
{ 0x26fc, // LRS $30, @DMBH { 0x26fc, // LRS $30, @DMBH
0x02c0, 0x8000, // ANDCF $30, #0x8000 0x02c0, 0x8000, // ANDCF $30, #0x8000
0x029d, 0xFFFF, // JLZ 0x027a 0x029d, 0xFFFF, // JLZ 0x027a
0x02df, 0 }, // RET 0, 0 }, // RET
{ 0x27fc, // LRS $31, @DMBH { 0x27fc, // LRS $31, @DMBH
0x03c0, 0x8000, // ANDCF $31, #0x8000 0x03c0, 0x8000, // ANDCF $31, #0x8000
0x029d, 0xFFFF, // JLZ 0x027a 0x029d, 0xFFFF, // JLZ 0x027a
0x02df, 0 }, // RET 0, 0 }, // RET
{ 0x26fe, // LRS $30, @CMBH { 0x26fe, // LRS $30, @CMBH
0x02c0, 0x8000, // ANDCF $30, #0x8000 0x02c0, 0x8000, // ANDCF $30, #0x8000
0x029c, 0xFFFF, // JLNZ 0x0280 0x029c, 0xFFFF, // JLNZ 0x0280
0x02df, 0 }, // RET 0, 0 }, // RET
{ 0x27fe, // LRS $31, @CMBH { 0x27fe, // LRS $31, @CMBH
0x03c0, 0x8000, // ANDCF $31, #0x8000 0x03c0, 0x8000, // ANDCF $31, #0x8000
0x029c, 0xFFFF, // JLNZ 0x0280 0x029c, 0xFFFF, // JLNZ 0x0280
0x02df, 0 }, // RET 0, 0 }, // RET
}; };
void Reset() void Reset()
{ {
memset(inst_flags, 0, sizeof(inst_flags)); memset(code_flags, 0, sizeof(code_flags));
} }
void AnalyzeRange(int start_addr, int end_addr) void AnalyzeRange(int start_addr, int end_addr)
@ -76,7 +76,7 @@ void AnalyzeRange(int start_addr, int end_addr)
addr++; addr++;
continue; continue;
} }
inst_flags[addr] |= CODE_START_OF_INST; code_flags[addr] |= CODE_START_OF_INST;
addr += opcode->size; addr += opcode->size;
} }
@ -98,7 +98,7 @@ void AnalyzeRange(int start_addr, int end_addr)
if (found) if (found)
{ {
NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr); NOTICE_LOG(DSPLLE, "Idle skip location found at %02x", addr);
inst_flags[addr] |= CODE_IDLE_SKIP; code_flags[addr] |= CODE_IDLE_SKIP;
// TODO: actually use this flag somewhere. // TODO: actually use this flag somewhere.
} }
} }

View File

@ -395,14 +395,3 @@ void InitInstructionTable()
} }
} }
} }
void ComputeInstruction(const UDSPInstruction& inst)
{
if (prologueTable[inst.hex])
prologueTable[inst.hex](inst);
opTable[inst.hex](inst);
if (epilogueTable[inst.hex])
epilogueTable[inst.hex](inst);
}

View File

@ -113,10 +113,21 @@ extern const u32 opcodes_ext_size;
extern u8 opSize[OPTABLE_SIZE]; extern u8 opSize[OPTABLE_SIZE];
extern dspInstFunc opTable[]; extern dspInstFunc opTable[];
extern dspInstFunc prologueTable[OPTABLE_SIZE];
extern dspInstFunc epilogueTable[OPTABLE_SIZE];
void InitInstructionTable(); void InitInstructionTable();
void ComputeInstruction(const UDSPInstruction& inst); inline void ExecuteInstruction(const UDSPInstruction& inst)
{
// TODO: Move the prologuetable calls into the relevant instructions themselves.
// Better not do things like this until things work correctly though.
if (prologueTable[inst.hex])
prologueTable[inst.hex](inst);
opTable[inst.hex](inst);
if (epilogueTable[inst.hex])
epilogueTable[inst.hex](inst);
}
// This one's pretty slow, try to use it only at init or seldomly. // This one's pretty slow, try to use it only at init or seldomly.
// returns NULL if no matching instruction. // returns NULL if no matching instruction.

View File

@ -38,8 +38,7 @@
SDSP g_dsp; SDSP g_dsp;
bool gdsp_running; volatile u32 gdsp_running;
extern volatile u32 dsp_running;
static bool cr_halt = true; static bool cr_halt = true;
static bool cr_external_int = false; static bool cr_external_int = false;
@ -231,14 +230,14 @@ void gdsp_step()
#endif #endif
u16 opc = dsp_fetch_code(); u16 opc = dsp_fetch_code();
ComputeInstruction(UDSPInstruction(opc)); ExecuteInstruction(UDSPInstruction(opc));
u16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3];
// Handle looping hardware.
u16& rLoopCounter = g_dsp.r[DSP_REG_ST3];
if (rLoopCounter > 0) if (rLoopCounter > 0)
{ {
const u16& rCallAddress = g_dsp.r[DSP_REG_ST0 + 0]; const u16 rCallAddress = g_dsp.r[DSP_REG_ST0];
const u16& rLoopAddress = g_dsp.r[DSP_REG_ST0 + 2]; const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2];
if (g_dsp.pc == (rLoopAddress + 1)) if (g_dsp.pc == (rLoopAddress + 1))
{ {
@ -292,15 +291,14 @@ void gdsp_step()
} }
} }
// Used by thread mode.
bool gdsp_run() void gdsp_run()
{ {
gdsp_running = true; gdsp_running = true;
while (!cr_halt) while (!cr_halt)
{ {
// Are we running? // Are we running?
if(*g_dspInitialize.pEmulatorState) if (*g_dspInitialize.pEmulatorState)
break; break;
gdsp_step(); gdsp_step();
@ -308,9 +306,41 @@ bool gdsp_run()
if (!gdsp_running) if (!gdsp_running)
break; break;
} }
gdsp_running = false; gdsp_running = false;
return true; }
// Used by non-thread mode.
void gdsp_run_cycles(int cycles)
{
// First, let's run a few cycles with no idle skipping so that things can progress a bit.
for (int i = 0; i < 8; i++)
{
if (cr_halt)
return;
gdsp_step();
cycles--;
}
// Next, let's run a few cycles with idle skipping, so that we can skip loops.
for (int i = 0; i < 8; i++)
{
if (cr_halt)
return;
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
return;
gdsp_step();
cycles--;
}
// Now, run the rest of the block without idle skipping. It might trip into a
// idle loop and if so we waste some time here. Might be beneficial to slice even further.
while (cycles > 0)
{
if (cr_halt)
return;
gdsp_step();
cycles--;
// We don't bother directly supporting pause - if the main emu pauses,
// it just won't call this function anymore.
}
} }
void gdsp_stop() void gdsp_stop()

View File

@ -103,11 +103,11 @@ bool gdsp_load_coef(const char *fname);
// steps through DSP code, returns false if error occured // steps through DSP code, returns false if error occured
void gdsp_step(void); void gdsp_step();
void gdsp_loop_step(); void gdsp_loop_step();
bool gdsp_run(void); void gdsp_run();
bool gdsp_runx(u16 cnt); void gdsp_run_cycles(int cycles);
void gdsp_stop(void); void gdsp_stop();
void gdsp_write_cr(u16 val); void gdsp_write_cr(u16 val);
u16 gdsp_read_cr(void); u16 gdsp_read_cr(void);

View File

@ -116,12 +116,12 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
_PluginInfo->Type = PLUGIN_TYPE_DSP; _PluginInfo->Type = PLUGIN_TYPE_DSP;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (DebugFast)"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (DebugFast)");
#else #else
#ifndef _DEBUG #ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin");
#else #else
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (Debug)"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (Debug)");
#endif #endif
#endif #endif
} }
@ -176,11 +176,7 @@ THREAD_RETURN dsp_thread(void* lpParameter)
{ {
while (bIsRunning) while (bIsRunning)
{ {
if (!gdsp_run()) gdsp_run();
{
ERROR_LOG(AUDIO, "DSP Halt");
return 0;
}
} }
return 0; return 0;
} }
@ -225,7 +221,8 @@ void Initialize(void *init)
PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE); PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE);
} }
if (!bCanWork) { if (!bCanWork)
{
gdsp_shutdown(); gdsp_shutdown();
return; return;
} }
@ -234,7 +231,10 @@ void Initialize(void *init)
InitInstructionTable(); InitInstructionTable();
g_hDSPThread = new Common::Thread(dsp_thread, NULL); if (g_dspInitialize.bOnThread)
{
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
}
soundStream = AudioCommon::InitSoundStream(); soundStream = AudioCommon::InitSoundStream();
} }
@ -242,8 +242,11 @@ void DSP_StopSoundStream()
{ {
gdsp_stop(); gdsp_stop();
bIsRunning = false; bIsRunning = false;
delete g_hDSPThread; if (g_dspInitialize.bOnThread)
g_hDSPThread = NULL; {
delete g_hDSPThread;
g_hDSPThread = NULL;
}
} }
void Shutdown() void Shutdown()
@ -330,13 +333,22 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail)
void DSP_Update(int cycles) void DSP_Update(int cycles)
{ {
soundStream->Update(); // This gets called VERY OFTEN. The soundstream update might be expensive so only do it 200 times per second or something.
const int cycles_between_ss_update = 80000000 / 200;
static int cycle_count = 0;
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();
}
#if defined(HAVE_WX) && HAVE_WX // If we're not on a thread, run cycles here.
// TODO fix? dunno how we should handle debug thread or whatever if (!g_dspInitialize.bOnThread)
// if (m_DebuggerFrame->CanDoStep()) {
// gdsp_runx(100); // cycles gdsp_run_cycles(cycles);
#endif }
} }
void DSP_SendAIBuffer(unsigned int address, int sample_rate) void DSP_SendAIBuffer(unsigned int address, int sample_rate)