mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
DSP: Eliminate most global state
An unfortunately large single commit that deglobalizes the DSP code. (which I'm very sorry about). This would have otherwise been extremely difficult to separate due to extensive use of the globals in very coupling ways that would result in more scaffolding to work around than is worth it. Aside from the video code, I believe only the DSP code is the hairiest to deal with in terms of globals, so I guess it's best to get this dealt with right off the bat. A summary of what this commit does: - Turns the DSPInterpreter into its own class This is the most involved portion of this change. The bulk of the changes are turning non-member functions into member functions that would be situated into the Interpreter class. - Eliminates all usages to globals within DSPCore. This generally involves turning a lot of non-member functions into member functions that are either situated within SDSP or DSPCore. - Discards DSPDebugInterface (it wasn't hooked up to anything, and for the sake of eliminating global state, I'd rather get rid of it than think up ways for this class to be integrated with everything else. - Readjusts the DSP JIT to handle calling out to member functions. In most cases, this just means wrapping respective member function calles into thunk functions. Surprisingly, this doesn't even make use of the introduced System class. It was possible all along to do this without it. We can house everything within the DSPLLE class, which is quite nice =)
This commit is contained in:
@ -1,323 +0,0 @@
|
||||
// Copyright 2009 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/HW/DSPLLE/DSPDebugInterface.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Core/DSP/DSPCore.h"
|
||||
#include "Core/DSP/DSPMemoryMap.h"
|
||||
#include "Core/HW/DSPLLE/DSPSymbols.h"
|
||||
|
||||
namespace DSP::LLE
|
||||
{
|
||||
void DSPPatches::Patch(std::size_t index)
|
||||
{
|
||||
PanicAlertFmt("Patch functionality not supported in DSP module.");
|
||||
}
|
||||
|
||||
DSPDebugInterface::DSPDebugInterface() = default;
|
||||
DSPDebugInterface::~DSPDebugInterface() = default;
|
||||
|
||||
std::size_t DSPDebugInterface::SetWatch(u32 address, std::string name)
|
||||
{
|
||||
return m_watches.SetWatch(address, std::move(name));
|
||||
}
|
||||
|
||||
const Common::Debug::Watch& DSPDebugInterface::GetWatch(std::size_t index) const
|
||||
{
|
||||
return m_watches.GetWatch(index);
|
||||
}
|
||||
|
||||
const std::vector<Common::Debug::Watch>& DSPDebugInterface::GetWatches() const
|
||||
{
|
||||
return m_watches.GetWatches();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UnsetWatch(u32 address)
|
||||
{
|
||||
m_watches.UnsetWatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatch(std::size_t index, u32 address, std::string name)
|
||||
{
|
||||
return m_watches.UpdateWatch(index, address, std::move(name));
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatchAddress(std::size_t index, u32 address)
|
||||
{
|
||||
return m_watches.UpdateWatchAddress(index, address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UpdateWatchName(std::size_t index, std::string name)
|
||||
{
|
||||
return m_watches.UpdateWatchName(index, std::move(name));
|
||||
}
|
||||
|
||||
void DSPDebugInterface::EnableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.EnableWatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::DisableWatch(std::size_t index)
|
||||
{
|
||||
m_watches.DisableWatch(index);
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::HasEnabledWatch(u32 address) const
|
||||
{
|
||||
return m_watches.HasEnabledWatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::RemoveWatch(std::size_t index)
|
||||
{
|
||||
return m_watches.RemoveWatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::LoadWatchesFromStrings(const std::vector<std::string>& watches)
|
||||
{
|
||||
m_watches.LoadFromStrings(watches);
|
||||
}
|
||||
|
||||
std::vector<std::string> DSPDebugInterface::SaveWatchesToStrings() const
|
||||
{
|
||||
return m_watches.SaveToStrings();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearWatches()
|
||||
{
|
||||
m_watches.Clear();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::SetPatch(u32 address, u32 value)
|
||||
{
|
||||
m_patches.SetPatch(address, value);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::SetPatch(u32 address, std::vector<u8> value)
|
||||
{
|
||||
m_patches.SetPatch(address, std::move(value));
|
||||
}
|
||||
|
||||
const std::vector<Common::Debug::MemoryPatch>& DSPDebugInterface::GetPatches() const
|
||||
{
|
||||
return m_patches.GetPatches();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::UnsetPatch(u32 address)
|
||||
{
|
||||
m_patches.UnsetPatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::EnablePatch(std::size_t index)
|
||||
{
|
||||
m_patches.EnablePatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::DisablePatch(std::size_t index)
|
||||
{
|
||||
m_patches.DisablePatch(index);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::RemovePatch(std::size_t index)
|
||||
{
|
||||
m_patches.RemovePatch(index);
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::HasEnabledPatch(u32 address) const
|
||||
{
|
||||
return m_patches.HasEnabledPatch(address);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearPatches()
|
||||
{
|
||||
m_patches.ClearPatches();
|
||||
}
|
||||
|
||||
Common::Debug::Threads DSPDebugInterface::GetThreads() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string DSPDebugInterface::Disassemble(u32 address) const
|
||||
{
|
||||
// we'll treat addresses as line numbers.
|
||||
return Symbols::GetLineText(address);
|
||||
}
|
||||
|
||||
std::string DSPDebugInterface::GetRawMemoryString(int memory, u32 address) const
|
||||
{
|
||||
if (DSPCore_GetState() == State::Stopped)
|
||||
return "";
|
||||
|
||||
switch (memory)
|
||||
{
|
||||
case 0: // IMEM
|
||||
switch (address >> 12)
|
||||
{
|
||||
case 0:
|
||||
case 0x8:
|
||||
return fmt::format("{:04x}", dsp_imem_read(address));
|
||||
default:
|
||||
return "--IMEM--";
|
||||
}
|
||||
|
||||
case 1: // DMEM
|
||||
switch (address >> 12)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return fmt::format("{:04x} (DMEM)", dsp_dmem_read(address));
|
||||
case 0xf:
|
||||
return fmt::format("{:04x} (MMIO)", g_dsp.ifx_regs[address & 0xFF]);
|
||||
default:
|
||||
return "--DMEM--";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
u32 DSPDebugInterface::ReadMemory(u32 address) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 DSPDebugInterface::ReadInstruction(u32 address) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::IsAlive() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::IsBreakpoint(u32 address) const
|
||||
{
|
||||
int real_addr = Symbols::Line2Addr(address);
|
||||
if (real_addr >= 0)
|
||||
return g_dsp_breakpoints.IsAddressBreakPoint(real_addr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DSPDebugInterface::SetBreakpoint(u32 address)
|
||||
{
|
||||
int real_addr = Symbols::Line2Addr(address);
|
||||
|
||||
if (real_addr >= 0)
|
||||
{
|
||||
g_dsp_breakpoints.Add(real_addr);
|
||||
}
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearBreakpoint(u32 address)
|
||||
{
|
||||
int real_addr = Symbols::Line2Addr(address);
|
||||
|
||||
if (real_addr >= 0)
|
||||
{
|
||||
g_dsp_breakpoints.Remove(real_addr);
|
||||
}
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearAllBreakpoints()
|
||||
{
|
||||
g_dsp_breakpoints.Clear();
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ToggleBreakpoint(u32 address)
|
||||
{
|
||||
int real_addr = Symbols::Line2Addr(address);
|
||||
if (real_addr >= 0)
|
||||
{
|
||||
if (g_dsp_breakpoints.IsAddressBreakPoint(real_addr))
|
||||
g_dsp_breakpoints.Remove(real_addr);
|
||||
else
|
||||
g_dsp_breakpoints.Add(real_addr);
|
||||
}
|
||||
}
|
||||
|
||||
bool DSPDebugInterface::IsMemCheck(u32 address, size_t size) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ClearAllMemChecks()
|
||||
{
|
||||
PanicAlertFmt("MemCheck functionality not supported in DSP module.");
|
||||
}
|
||||
|
||||
void DSPDebugInterface::ToggleMemCheck(u32 address, bool read, bool write, bool log)
|
||||
{
|
||||
PanicAlertFmt("MemCheck functionality not supported in DSP module.");
|
||||
}
|
||||
|
||||
// =======================================================
|
||||
// Separate the blocks with colors.
|
||||
// -------------
|
||||
u32 DSPDebugInterface::GetColor(u32 address) const
|
||||
{
|
||||
// Scan backwards so we don't miss it. Hm, actually, let's not - it looks pretty good.
|
||||
int addr = -1;
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
addr = Symbols::Line2Addr(address - i);
|
||||
if (addr >= 0)
|
||||
break;
|
||||
}
|
||||
if (addr == -1)
|
||||
return 0xFFFFFF;
|
||||
|
||||
Common::Symbol* symbol = Symbols::g_dsp_symbol_db.GetSymbolFromAddr(addr);
|
||||
if (!symbol)
|
||||
return 0xFFFFFF;
|
||||
if (symbol->type != Common::Symbol::Type::Function)
|
||||
return 0xEEEEFF;
|
||||
|
||||
static constexpr std::array<u32, 6> colors{
|
||||
0xd0FFFF, // light cyan
|
||||
0xFFd0d0, // light red
|
||||
0xd8d8FF, // light blue
|
||||
0xFFd0FF, // light purple
|
||||
0xd0FFd0, // light green
|
||||
0xFFFFd0, // light yellow
|
||||
};
|
||||
return colors[symbol->index % colors.size()];
|
||||
}
|
||||
// =============
|
||||
|
||||
std::string DSPDebugInterface::GetDescription(u32 address) const
|
||||
{
|
||||
return ""; // g_symbolDB.GetDescription(address);
|
||||
}
|
||||
|
||||
u32 DSPDebugInterface::GetPC() const
|
||||
{
|
||||
return Symbols::Addr2Line(DSP::g_dsp.pc);
|
||||
}
|
||||
|
||||
void DSPDebugInterface::SetPC(u32 address)
|
||||
{
|
||||
int new_pc = Symbols::Line2Addr(address);
|
||||
if (new_pc > 0)
|
||||
g_dsp.pc = new_pc;
|
||||
}
|
||||
|
||||
void DSPDebugInterface::RunToBreakpoint()
|
||||
{
|
||||
}
|
||||
|
||||
void DSPDebugInterface::Clear()
|
||||
{
|
||||
ClearPatches();
|
||||
ClearWatches();
|
||||
}
|
||||
} // namespace DSP::LLE
|
@ -1,85 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Debug/MemoryPatches.h"
|
||||
#include "Common/Debug/Watches.h"
|
||||
#include "Common/DebugInterface.h"
|
||||
|
||||
namespace DSP::LLE
|
||||
{
|
||||
class DSPPatches : public Common::Debug::MemoryPatches
|
||||
{
|
||||
private:
|
||||
void Patch(std::size_t index) override;
|
||||
};
|
||||
|
||||
class DSPDebugInterface final : public Common::DebugInterface
|
||||
{
|
||||
public:
|
||||
DSPDebugInterface();
|
||||
~DSPDebugInterface() override;
|
||||
|
||||
// Watches
|
||||
std::size_t SetWatch(u32 address, std::string name = "") override;
|
||||
const Common::Debug::Watch& GetWatch(std::size_t index) const override;
|
||||
const std::vector<Common::Debug::Watch>& GetWatches() const override;
|
||||
void UnsetWatch(u32 address) override;
|
||||
void UpdateWatch(std::size_t index, u32 address, std::string name) override;
|
||||
void UpdateWatchAddress(std::size_t index, u32 address) override;
|
||||
void UpdateWatchName(std::size_t index, std::string name) override;
|
||||
void EnableWatch(std::size_t index) override;
|
||||
void DisableWatch(std::size_t index) override;
|
||||
bool HasEnabledWatch(u32 address) const override;
|
||||
void RemoveWatch(std::size_t index) override;
|
||||
void LoadWatchesFromStrings(const std::vector<std::string>& watches) override;
|
||||
std::vector<std::string> SaveWatchesToStrings() const override;
|
||||
void ClearWatches() override;
|
||||
|
||||
// Memory Patches
|
||||
void SetPatch(u32 address, u32 value) override;
|
||||
void SetPatch(u32 address, std::vector<u8> value) override;
|
||||
const std::vector<Common::Debug::MemoryPatch>& GetPatches() const override;
|
||||
void UnsetPatch(u32 address) override;
|
||||
void EnablePatch(std::size_t index) override;
|
||||
void DisablePatch(std::size_t index) override;
|
||||
void RemovePatch(std::size_t index) override;
|
||||
bool HasEnabledPatch(u32 address) const override;
|
||||
void ClearPatches() override;
|
||||
|
||||
// Threads
|
||||
Common::Debug::Threads GetThreads() const override;
|
||||
|
||||
std::string Disassemble(u32 address) const override;
|
||||
std::string GetRawMemoryString(int memory, u32 address) const override;
|
||||
bool IsAlive() const override;
|
||||
bool IsBreakpoint(u32 address) const override;
|
||||
void SetBreakpoint(u32 address) override;
|
||||
void ClearBreakpoint(u32 address) override;
|
||||
void ClearAllBreakpoints() override;
|
||||
void ToggleBreakpoint(u32 address) override;
|
||||
void ClearAllMemChecks() override;
|
||||
bool IsMemCheck(u32 address, size_t size) const override;
|
||||
void ToggleMemCheck(u32 address, bool read = true, bool write = true, bool log = true) override;
|
||||
u32 ReadMemory(u32 address) const override;
|
||||
u32 ReadInstruction(u32 address) const override;
|
||||
u32 GetPC() const override;
|
||||
void SetPC(u32 address) override;
|
||||
void Step() override {}
|
||||
void RunToBreakpoint() override;
|
||||
u32 GetColor(u32 address) const override;
|
||||
std::string GetDescription(u32 address) const override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
private:
|
||||
Common::Debug::Watches m_watches;
|
||||
DSPPatches m_patches;
|
||||
};
|
||||
} // namespace DSP::LLE
|
@ -68,31 +68,33 @@ void InterruptRequest()
|
||||
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
|
||||
}
|
||||
|
||||
void CodeLoaded(u32 addr, size_t size)
|
||||
void CodeLoaded(DSPCore& dsp, u32 addr, size_t size)
|
||||
{
|
||||
CodeLoaded(Memory::GetPointer(addr), size);
|
||||
CodeLoaded(dsp, Memory::GetPointer(addr), size);
|
||||
}
|
||||
|
||||
void CodeLoaded(const u8* ptr, size_t size)
|
||||
void CodeLoaded(DSPCore& dsp, const u8* ptr, size_t size)
|
||||
{
|
||||
g_dsp.iram_crc = Common::HashEctor(ptr, size);
|
||||
auto& state = dsp.DSPState();
|
||||
const u32 iram_crc = Common::HashEctor(ptr, size);
|
||||
state.iram_crc = iram_crc;
|
||||
|
||||
if (SConfig::GetInstance().m_DumpUCode)
|
||||
{
|
||||
DSP::DumpDSPCode(ptr, size, g_dsp.iram_crc);
|
||||
DSP::DumpDSPCode(ptr, size, iram_crc);
|
||||
}
|
||||
|
||||
NOTICE_LOG_FMT(DSPLLE, "g_dsp.iram_crc: {:08x}", g_dsp.iram_crc);
|
||||
NOTICE_LOG_FMT(DSPLLE, "g_dsp.iram_crc: {:08x}", iram_crc);
|
||||
|
||||
Symbols::Clear();
|
||||
Symbols::AutoDisassembly(0x0, 0x1000);
|
||||
Symbols::AutoDisassembly(0x8000, 0x9000);
|
||||
Symbols::AutoDisassembly(state, 0x0, 0x1000);
|
||||
Symbols::AutoDisassembly(state, 0x8000, 0x9000);
|
||||
|
||||
UpdateDebugger();
|
||||
|
||||
if (g_dsp_jit)
|
||||
g_dsp_jit->ClearIRAM();
|
||||
dsp.ClearIRAM();
|
||||
|
||||
Analyzer::Analyze();
|
||||
Analyzer::Analyze(state);
|
||||
}
|
||||
|
||||
void UpdateDebugger()
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "Core/DSP/DSPAccelerator.h"
|
||||
#include "Core/DSP/DSPCaptureLogger.h"
|
||||
#include "Core/DSP/DSPCore.h"
|
||||
#include "Core/DSP/DSPHWInterface.h"
|
||||
#include "Core/DSP/DSPHost.h"
|
||||
#include "Core/DSP/DSPTables.h"
|
||||
#include "Core/DSP/Interpreter/DSPInterpreter.h"
|
||||
@ -32,15 +31,11 @@
|
||||
|
||||
namespace DSP::LLE
|
||||
{
|
||||
static Common::Event s_dsp_event;
|
||||
static Common::Event s_ppc_event;
|
||||
static bool s_request_disable_thread;
|
||||
|
||||
DSPLLE::DSPLLE() = default;
|
||||
|
||||
DSPLLE::~DSPLLE()
|
||||
{
|
||||
DSPCore_Shutdown();
|
||||
m_dsp_core.Shutdown();
|
||||
DSP_StopSoundStream();
|
||||
}
|
||||
|
||||
@ -55,39 +50,8 @@ void DSPLLE::DoState(PointerWrap& p)
|
||||
p.SetMode(PointerWrap::MODE_VERIFY);
|
||||
return;
|
||||
}
|
||||
p.Do(g_dsp.r);
|
||||
p.Do(g_dsp.pc);
|
||||
#if PROFILE
|
||||
p.Do(g_dsp.err_pc);
|
||||
#endif
|
||||
p.Do(g_dsp.cr);
|
||||
p.Do(g_dsp.reg_stack_ptrs);
|
||||
p.Do(g_dsp.exceptions);
|
||||
p.Do(g_dsp.external_interrupt_waiting);
|
||||
|
||||
for (auto& stack : g_dsp.reg_stacks)
|
||||
{
|
||||
p.Do(stack);
|
||||
}
|
||||
|
||||
p.Do(g_dsp.step_counter);
|
||||
p.DoArray(g_dsp.ifx_regs);
|
||||
g_dsp.accelerator->DoState(p);
|
||||
p.Do(g_dsp.mbox[0]);
|
||||
p.Do(g_dsp.mbox[1]);
|
||||
Common::UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
|
||||
p.DoArray(g_dsp.iram, DSP_IRAM_SIZE);
|
||||
Common::WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
|
||||
// TODO: This uses the wrong endianness (producing bad disassembly)
|
||||
// and a bogus byte count (producing bad hashes)
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
Host::CodeLoaded(reinterpret_cast<const u8*>(g_dsp.iram), DSP_IRAM_BYTE_SIZE);
|
||||
p.DoArray(g_dsp.dram, DSP_DRAM_SIZE);
|
||||
p.Do(g_init_hax);
|
||||
m_dsp_core.DoState(p);
|
||||
p.Do(m_cycle_count);
|
||||
|
||||
if (g_dsp_jit)
|
||||
g_dsp_jit->DoState(p);
|
||||
}
|
||||
|
||||
// Regular thread
|
||||
@ -103,21 +67,21 @@ void DSPLLE::DSPThread(DSPLLE* dsp_lle)
|
||||
std::unique_lock dsp_thread_lock(dsp_lle->m_dsp_thread_mutex, std::try_to_lock);
|
||||
if (dsp_thread_lock)
|
||||
{
|
||||
if (g_dsp_jit)
|
||||
if (dsp_lle->m_dsp_core.IsJITCreated())
|
||||
{
|
||||
DSPCore_RunCycles(cycles);
|
||||
dsp_lle->m_dsp_core.RunCycles(cycles);
|
||||
}
|
||||
else
|
||||
{
|
||||
DSP::Interpreter::RunCyclesThread(cycles);
|
||||
dsp_lle->m_dsp_core.GetInterpreter().RunCyclesThread(cycles);
|
||||
}
|
||||
dsp_lle->m_cycle_count.store(0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
s_ppc_event.Set();
|
||||
s_dsp_event.Wait();
|
||||
dsp_lle->m_ppc_event.Set();
|
||||
dsp_lle->m_dsp_event.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,22 +137,22 @@ static bool FillDSPInitOptions(DSPInitOptions* opts)
|
||||
|
||||
bool DSPLLE::Initialize(bool wii, bool dsp_thread)
|
||||
{
|
||||
s_request_disable_thread = false;
|
||||
m_request_disable_thread = false;
|
||||
|
||||
DSPInitOptions opts;
|
||||
if (!FillDSPInitOptions(&opts))
|
||||
return false;
|
||||
if (!DSPCore_Init(opts))
|
||||
if (!m_dsp_core.Initialize(opts))
|
||||
return false;
|
||||
|
||||
// needs to be after DSPCore_Init for the dspjit ptr
|
||||
if (Core::WantsDeterminism() || !g_dsp_jit)
|
||||
if (Core::WantsDeterminism() || !m_dsp_core.IsJITCreated())
|
||||
dsp_thread = false;
|
||||
|
||||
m_wii = wii;
|
||||
m_is_dsp_on_thread = dsp_thread;
|
||||
|
||||
DSPCore_Reset();
|
||||
m_dsp_core.Reset();
|
||||
|
||||
InitInstructionTable();
|
||||
|
||||
@ -204,77 +168,70 @@ bool DSPLLE::Initialize(bool wii, bool dsp_thread)
|
||||
|
||||
void DSPLLE::DSP_StopSoundStream()
|
||||
{
|
||||
if (m_is_dsp_on_thread)
|
||||
{
|
||||
m_is_running.Clear();
|
||||
s_ppc_event.Set();
|
||||
s_dsp_event.Set();
|
||||
m_dsp_thread.join();
|
||||
}
|
||||
if (!m_is_dsp_on_thread)
|
||||
return;
|
||||
|
||||
m_is_running.Clear();
|
||||
m_ppc_event.Set();
|
||||
m_dsp_event.Set();
|
||||
m_dsp_thread.join();
|
||||
}
|
||||
|
||||
void DSPLLE::Shutdown()
|
||||
{
|
||||
DSPCore_Shutdown();
|
||||
m_dsp_core.Shutdown();
|
||||
}
|
||||
|
||||
u16 DSPLLE::DSP_WriteControlRegister(u16 value)
|
||||
{
|
||||
DSP::Interpreter::WriteCR(value);
|
||||
m_dsp_core.GetInterpreter().WriteCR(value);
|
||||
|
||||
if (value & 2)
|
||||
if ((value & 2) != 0)
|
||||
{
|
||||
if (!m_is_dsp_on_thread)
|
||||
{
|
||||
DSPCore_CheckExternalInterrupt();
|
||||
DSPCore_CheckExceptions();
|
||||
}
|
||||
else
|
||||
if (m_is_dsp_on_thread)
|
||||
{
|
||||
// External interrupt pending: this is the zelda ucode.
|
||||
// Disable the DSP thread because there is no performance gain.
|
||||
s_request_disable_thread = true;
|
||||
m_request_disable_thread = true;
|
||||
|
||||
DSPCore_SetExternalInterrupt(true);
|
||||
m_dsp_core.SetExternalInterrupt(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dsp_core.CheckExternalInterrupt();
|
||||
m_dsp_core.CheckExceptions();
|
||||
}
|
||||
}
|
||||
|
||||
return DSP::Interpreter::ReadCR();
|
||||
return DSP_ReadControlRegister();
|
||||
}
|
||||
|
||||
u16 DSPLLE::DSP_ReadControlRegister()
|
||||
{
|
||||
return DSP::Interpreter::ReadCR();
|
||||
return m_dsp_core.GetInterpreter().ReadCR();
|
||||
}
|
||||
|
||||
u16 DSPLLE::DSP_ReadMailBoxHigh(bool cpu_mailbox)
|
||||
{
|
||||
return gdsp_mbox_read_h(cpu_mailbox ? MAILBOX_CPU : MAILBOX_DSP);
|
||||
return m_dsp_core.ReadMailboxHigh(cpu_mailbox ? MAILBOX_CPU : MAILBOX_DSP);
|
||||
}
|
||||
|
||||
u16 DSPLLE::DSP_ReadMailBoxLow(bool cpu_mailbox)
|
||||
{
|
||||
return gdsp_mbox_read_l(cpu_mailbox ? MAILBOX_CPU : MAILBOX_DSP);
|
||||
return m_dsp_core.ReadMailboxLow(cpu_mailbox ? MAILBOX_CPU : MAILBOX_DSP);
|
||||
}
|
||||
|
||||
void DSPLLE::DSP_WriteMailBoxHigh(bool cpu_mailbox, u16 value)
|
||||
{
|
||||
if (cpu_mailbox)
|
||||
{
|
||||
if (gdsp_mbox_peek(MAILBOX_CPU) & 0x80000000)
|
||||
if ((m_dsp_core.PeekMailbox(MAILBOX_CPU) & 0x80000000) != 0)
|
||||
{
|
||||
// the DSP didn't read the previous value
|
||||
WARN_LOG_FMT(DSPLLE, "Mailbox isn't empty ... strange");
|
||||
}
|
||||
|
||||
#if PROFILE
|
||||
if (value == 0xBABE)
|
||||
{
|
||||
ProfilerStart();
|
||||
}
|
||||
#endif
|
||||
|
||||
gdsp_mbox_write_h(MAILBOX_CPU, value);
|
||||
m_dsp_core.WriteMailboxHigh(MAILBOX_CPU, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -286,7 +243,7 @@ void DSPLLE::DSP_WriteMailBoxLow(bool cpu_mailbox, u16 value)
|
||||
{
|
||||
if (cpu_mailbox)
|
||||
{
|
||||
gdsp_mbox_write_l(MAILBOX_CPU, value);
|
||||
m_dsp_core.WriteMailboxLow(MAILBOX_CPU, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -296,18 +253,18 @@ void DSPLLE::DSP_WriteMailBoxLow(bool cpu_mailbox, u16 value)
|
||||
|
||||
void DSPLLE::DSP_Update(int cycles)
|
||||
{
|
||||
int dsp_cycles = cycles / 6;
|
||||
const int dsp_cycles = cycles / 6;
|
||||
|
||||
if (dsp_cycles <= 0)
|
||||
return;
|
||||
|
||||
if (m_is_dsp_on_thread)
|
||||
{
|
||||
if (s_request_disable_thread || Core::WantsDeterminism())
|
||||
if (m_request_disable_thread || Core::WantsDeterminism())
|
||||
{
|
||||
DSP_StopSoundStream();
|
||||
m_is_dsp_on_thread = false;
|
||||
s_request_disable_thread = false;
|
||||
m_request_disable_thread = false;
|
||||
SConfig::GetInstance().bDSPThread = false;
|
||||
}
|
||||
}
|
||||
@ -316,14 +273,14 @@ void DSPLLE::DSP_Update(int cycles)
|
||||
if (!m_is_dsp_on_thread)
|
||||
{
|
||||
// ~1/6th as many cycles as the period PPC-side.
|
||||
DSPCore_RunCycles(dsp_cycles);
|
||||
m_dsp_core.RunCycles(dsp_cycles);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for DSP thread to complete its cycle. Note: this logic should be thought through.
|
||||
s_ppc_event.Wait();
|
||||
m_ppc_event.Wait();
|
||||
m_cycle_count.fetch_add(dsp_cycles);
|
||||
s_dsp_event.Set();
|
||||
m_dsp_event.Set();
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,8 +302,8 @@ void DSPLLE::PauseAndLock(bool do_lock, bool unpause_on_unlock)
|
||||
if (m_is_dsp_on_thread)
|
||||
{
|
||||
// Signal the DSP thread so it can perform any outstanding work now (if any)
|
||||
s_ppc_event.Wait();
|
||||
s_dsp_event.Set();
|
||||
m_ppc_event.Wait();
|
||||
m_dsp_event.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Flag.h"
|
||||
#include "Core/DSP/DSPCore.h"
|
||||
#include "Core/DSPEmulator.h"
|
||||
|
||||
class PointerWrap;
|
||||
@ -41,10 +42,15 @@ public:
|
||||
private:
|
||||
static void DSPThread(DSPLLE* dsp_lle);
|
||||
|
||||
DSPCore m_dsp_core;
|
||||
std::thread m_dsp_thread;
|
||||
std::mutex m_dsp_thread_mutex;
|
||||
bool m_is_dsp_on_thread = false;
|
||||
Common::Flag m_is_running;
|
||||
std::atomic<u32> m_cycle_count{};
|
||||
|
||||
Common::Event m_dsp_event;
|
||||
Common::Event m_ppc_event;
|
||||
bool m_request_disable_thread = false;
|
||||
};
|
||||
} // namespace DSP::LLE
|
||||
|
@ -69,7 +69,7 @@ Common::Symbol* DSPSymbolDB::GetSymbolFromAddr(u32 addr)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AutoDisassembly(u16 start_addr, u16 end_addr)
|
||||
void AutoDisassembly(const SDSP& dsp, u16 start_addr, u16 end_addr)
|
||||
{
|
||||
AssemblerSettings settings;
|
||||
settings.show_pc = true;
|
||||
@ -77,7 +77,7 @@ void AutoDisassembly(u16 start_addr, u16 end_addr)
|
||||
DSPDisassembler disasm(settings);
|
||||
|
||||
u16 addr = start_addr;
|
||||
const u16* ptr = (start_addr >> 15) ? g_dsp.irom : g_dsp.iram;
|
||||
const u16* ptr = (start_addr >> 15) != 0 ? dsp.irom : dsp.iram;
|
||||
while (addr < end_addr)
|
||||
{
|
||||
line_to_addr[line_counter] = addr;
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/SymbolDB.h"
|
||||
|
||||
namespace DSP
|
||||
{
|
||||
struct SDSP;
|
||||
}
|
||||
|
||||
namespace DSP::Symbols
|
||||
{
|
||||
class DSPSymbolDB : public Common::SymbolDB
|
||||
@ -21,7 +26,7 @@ public:
|
||||
|
||||
extern DSPSymbolDB g_dsp_symbol_db;
|
||||
|
||||
void AutoDisassembly(u16 start_addr, u16 end_addr);
|
||||
void AutoDisassembly(const SDSP& dsp, u16 start_addr, u16 end_addr);
|
||||
|
||||
void Clear();
|
||||
|
||||
|
Reference in New Issue
Block a user