HW/CPU: Refactor to class, move to System.

This commit is contained in:
Admiral H. Curtiss
2023-03-07 04:02:48 +01:00
parent 0b9002ec2a
commit 3b364c5c16
22 changed files with 368 additions and 276 deletions

View File

@ -298,7 +298,7 @@ void Stop() // - Hammertime!
// Stop the CPU
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(true, "Stop CPU"));
CPU::Stop();
system.GetCPU().Stop();
if (system.IsDualCoreMode())
{
@ -410,7 +410,8 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
}
// Enter CPU run loop. When we leave it - we are done.
CPU::Run();
auto& system = Core::System::GetInstance();
system.GetCPU().Run();
#ifdef USE_MEMORYWATCHER
s_memory_watcher.reset();
@ -446,7 +447,8 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
s_is_started = true;
CPUSetInitialExecutionState();
CPU::Run();
auto& system = Core::System::GetInstance();
system.GetCPU().Run();
s_is_started = false;
PowerPC::InjectExternalCPUCore(nullptr);
@ -583,7 +585,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
s_is_booting.Clear();
// Set execution state to known values (CPU/FIFO/Audio Paused)
CPU::Break();
system.GetCPU().Break();
// Load GCM/DOL/ELF whatever ... we boot with the interpreter core
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
@ -674,18 +676,19 @@ void SetState(State state)
if (!IsRunningAndStarted())
return;
auto& system = Core::System::GetInstance();
switch (state)
{
case State::Paused:
// NOTE: GetState() will return State::Paused immediately, even before anything has
// stopped (including the CPU).
CPU::EnableStepping(true); // Break
system.GetCPU().EnableStepping(true); // Break
Wiimote::Pause();
ResetRumble();
break;
case State::Running:
{
CPU::EnableStepping(false);
system.GetCPU().EnableStepping(false);
Wiimote::Resume();
break;
}
@ -704,7 +707,8 @@ State GetState()
if (s_hardware_initialized)
{
if (CPU::IsStepping() || s_frame_step)
auto& system = Core::System::GetInstance();
if (system.GetCPU().IsStepping() || s_frame_step)
return State::Paused;
return State::Running;
@ -763,7 +767,7 @@ void SaveScreenShot(std::string_view name)
});
}
static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unlock)
{
// WARNING: PauseAndLock is not fully threadsafe so is only valid on the Host Thread
if (!IsRunningAndStarted())
@ -775,7 +779,7 @@ static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
// first pause the CPU
// This acquires a wrapper mutex and converts the current thread into
// a temporary replacement CPU Thread.
was_unpaused = CPU::PauseAndLock(true);
was_unpaused = system.GetCPU().PauseAndLock(true);
}
ExpansionInterface::PauseAndLock(do_lock, false);
@ -785,7 +789,6 @@ static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
// video has to come after CPU, because CPU thread can wait for video thread
// (s_efbAccessRequested).
auto& system = Core::System::GetInstance();
system.GetFifo().PauseAndLock(system, do_lock, false);
ResetRumble();
@ -798,7 +801,7 @@ static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
// mechanism to unpause them. If we unpaused the systems above when releasing
// the locks then they could call CPU::Break which would require detecting it
// and re-pausing with CPU::EnableStepping.
was_unpaused = CPU::PauseAndLock(false, unpause_on_unlock, true);
was_unpaused = system.GetCPU().PauseAndLock(false, unpause_on_unlock, true);
}
return was_unpaused;
@ -806,15 +809,16 @@ static bool PauseAndLock(bool do_lock, bool unpause_on_unlock)
void RunAsCPUThread(std::function<void()> function)
{
auto& system = Core::System::GetInstance();
const bool is_cpu_thread = IsCPUThread();
bool was_unpaused = false;
if (!is_cpu_thread)
was_unpaused = PauseAndLock(true, true);
was_unpaused = PauseAndLock(system, true, true);
function();
if (!is_cpu_thread)
PauseAndLock(false, was_unpaused);
PauseAndLock(system, false, was_unpaused);
}
void RunOnCPUThread(std::function<void()> function, bool wait_for_completion)
@ -826,26 +830,28 @@ void RunOnCPUThread(std::function<void()> function, bool wait_for_completion)
return;
}
auto& system = Core::System::GetInstance();
// Pause the CPU (set it to stepping mode).
const bool was_running = PauseAndLock(true, true);
const bool was_running = PauseAndLock(system, true, true);
// Queue the job function.
if (wait_for_completion)
{
// Trigger the event after executing the function.
s_cpu_thread_job_finished.Reset();
CPU::AddCPUThreadJob([&function]() {
system.GetCPU().AddCPUThreadJob([&function]() {
function();
s_cpu_thread_job_finished.Set();
});
}
else
{
CPU::AddCPUThreadJob(std::move(function));
system.GetCPU().AddCPUThreadJob(std::move(function));
}
// Release the CPU thread, and let it execute the callback.
PauseAndLock(false, was_running);
PauseAndLock(system, false, was_running);
// If we're waiting for completion, block until the event fires.
if (wait_for_completion)
@ -869,7 +875,7 @@ void Callback_FramePresented(double actual_emulation_speed)
}
// Called from VideoInterface::Update (CPU thread) at emulated field boundaries
void Callback_NewField()
void Callback_NewField(Core::System& system)
{
if (s_frame_step)
{
@ -883,7 +889,7 @@ void Callback_NewField()
if (s_stop_frame_step.load())
{
s_frame_step = false;
CPU::Break();
system.GetCPU().Break();
CallOnStateChangedCallbacks(Core::GetState());
}
}
@ -1055,13 +1061,13 @@ void UpdateInputGate(bool require_focus, bool require_full_focus)
CPUThreadGuard::CPUThreadGuard() : m_was_cpu_thread(IsCPUThread())
{
if (!m_was_cpu_thread)
m_was_unpaused = PauseAndLock(true, true);
m_was_unpaused = PauseAndLock(Core::System::GetInstance(), true, true);
}
CPUThreadGuard::~CPUThreadGuard()
{
if (!m_was_cpu_thread)
PauseAndLock(false, m_was_unpaused);
PauseAndLock(Core::System::GetInstance(), false, m_was_unpaused);
}
} // namespace Core