diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/core.cpp | 135 |
1 files changed, 105 insertions, 30 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 49ac8be6e..202cd332b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -3,6 +3,8 @@ // Refer to the license.txt file included. #include <memory> + +#include "audio_core/audio_core.h" #include "common/logging/log.h" #include "core/arm/arm_interface.h" #include "core/arm/dynarmic/arm_dynarmic.h" @@ -10,19 +12,25 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/gdbstub/gdbstub.h" -#include "core/hle/hle.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/memory.h" #include "core/hle/kernel/thread.h" +#include "core/hle/service/service.h" #include "core/hw/hw.h" +#include "core/loader/loader.h" #include "core/settings.h" +#include "video_core/video_core.h" namespace Core { -std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core -std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core +/*static*/ System System::s_instance; + +System::ResultStatus System::RunLoop(int tight_loop) { + if (!cpu_core) { + return ResultStatus::ErrorNotInitialized; + } -/// Run the core CPU loop -void RunLoop(int tight_loop) { - if (GDBStub::g_server_enabled) { + if (GDBStub::IsServerEnabled()) { GDBStub::HandlePacket(); // If the loop is halted and we want to step, use a tiny (1) number of instructions to @@ -32,7 +40,7 @@ void RunLoop(int tight_loop) { GDBStub::SetCpuStepFlag(false); tight_loop = 1; } else { - return; + return ResultStatus::Success; } } } @@ -43,48 +51,115 @@ void RunLoop(int tight_loop) { LOG_TRACE(Core_ARM11, "Idling"); CoreTiming::Idle(); CoreTiming::Advance(); - HLE::Reschedule(__func__); + PrepareReschedule(); } else { - g_app_core->Run(tight_loop); + cpu_core->Run(tight_loop); } HW::Update(); - if (HLE::IsReschedulePending()) { - Kernel::Reschedule(); - } + Reschedule(); + + return ResultStatus::Success; +} + +System::ResultStatus System::SingleStep() { + return RunLoop(1); } -/// Step the CPU one instruction -void SingleStep() { - RunLoop(1); +System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { + if (app_loader) { + app_loader.reset(); + } + + app_loader = Loader::GetLoader(filepath); + + if (!app_loader) { + LOG_CRITICAL(Core, "Failed to obtain loader for %s!", filepath.c_str()); + return ResultStatus::ErrorGetLoader; + } + + boost::optional<u32> system_mode{app_loader->LoadKernelSystemMode()}; + if (!system_mode) { + LOG_CRITICAL(Core, "Failed to determine system mode!"); + return ResultStatus::ErrorSystemMode; + } + + ResultStatus init_result{Init(emu_window, system_mode.get())}; + if (init_result != ResultStatus::Success) { + LOG_CRITICAL(Core, "Failed to initialize system (Error %i)!", init_result); + System::Shutdown(); + return init_result; + } + + const Loader::ResultStatus load_result{app_loader->Load()}; + if (Loader::ResultStatus::Success != load_result) { + LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result); + System::Shutdown(); + + switch (load_result) { + case Loader::ResultStatus::ErrorEncrypted: + return ResultStatus::ErrorLoader_ErrorEncrypted; + case Loader::ResultStatus::ErrorInvalidFormat: + return ResultStatus::ErrorLoader_ErrorInvalidFormat; + default: + return ResultStatus::ErrorLoader; + } + } + return ResultStatus::Success; } -/// Halt the core -void Halt(const char* msg) { - // TODO(ShizZy): ImplementMe +void System::PrepareReschedule() { + cpu_core->PrepareReschedule(); + reschedule_pending = true; } -/// Kill the core -void Stop() { - // TODO(ShizZy): ImplementMe +void System::Reschedule() { + if (!reschedule_pending) { + return; + } + + reschedule_pending = false; + Kernel::Reschedule(); } -/// Initialize the core -void Init() { +System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { + if (cpu_core) { + cpu_core.reset(); + } + + Memory::Init(); + if (Settings::values.use_cpu_jit) { - g_sys_core = std::make_unique<ARM_Dynarmic>(USER32MODE); - g_app_core = std::make_unique<ARM_Dynarmic>(USER32MODE); + cpu_core = std::make_unique<ARM_Dynarmic>(USER32MODE); } else { - g_sys_core = std::make_unique<ARM_DynCom>(USER32MODE); - g_app_core = std::make_unique<ARM_DynCom>(USER32MODE); + cpu_core = std::make_unique<ARM_DynCom>(USER32MODE); + } + + CoreTiming::Init(); + HW::Init(); + Kernel::Init(system_mode); + Service::Init(); + AudioCore::Init(); + GDBStub::Init(); + + if (!VideoCore::Init(emu_window)) { + return ResultStatus::ErrorVideoCore; } LOG_DEBUG(Core, "Initialized OK"); + + return ResultStatus::Success; } -void Shutdown() { - g_app_core.reset(); - g_sys_core.reset(); +void System::Shutdown() { + GDBStub::Shutdown(); + AudioCore::Shutdown(); + VideoCore::Shutdown(); + Service::Shutdown(); + Kernel::Shutdown(); + HW::Shutdown(); + CoreTiming::Shutdown(); + cpu_core.reset(); LOG_DEBUG(Core, "Shutdown OK"); } |