summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/core.cpp112
-rw-r--r--src/core/core.h132
-rw-r--r--src/core/core_timing.cpp27
-rw-r--r--src/core/gdbstub/gdbstub.cpp39
-rw-r--r--src/core/hle/function_wrappers.h60
-rw-r--r--src/core/hle/hle.cpp4
-rw-r--r--src/core/hle/kernel/thread.cpp6
-rw-r--r--src/core/hle/service/ldr_ro/ldr_ro.cpp8
-rw-r--r--src/core/hle/svc.cpp12
-rw-r--r--src/core/system.cpp90
-rw-r--r--src/core/system.h83
12 files changed, 264 insertions, 311 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index af224166a..d547b0746 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -155,7 +155,6 @@ set(SRCS
tracer/recorder.cpp
memory.cpp
settings.cpp
- system.cpp
)
set(HEADERS
@@ -325,7 +324,6 @@ set(HEADERS
memory_setup.h
mmio.h
settings.h
- system.h
)
include_directories(../../externals/dynarmic/include)
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 6efa18159..b4df90efd 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"
@@ -11,17 +13,23 @@
#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/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 (!app_core) {
+ return ResultStatus::ErrorNotInitialized;
+ }
-/// Run the core CPU loop
-void RunLoop(int tight_loop) {
if (GDBStub::IsServerEnabled()) {
GDBStub::HandlePacket();
@@ -32,7 +40,7 @@ void RunLoop(int tight_loop) {
GDBStub::SetCpuStepFlag(false);
tight_loop = 1;
} else {
- return;
+ return ResultStatus::Success;
}
}
}
@@ -45,46 +53,100 @@ void RunLoop(int tight_loop) {
CoreTiming::Advance();
HLE::Reschedule(__func__);
} else {
- g_app_core->Run(tight_loop);
+ app_core->Run(tight_loop);
}
HW::Update();
if (HLE::IsReschedulePending()) {
Kernel::Reschedule();
}
-}
-/// Step the CPU one instruction
-void SingleStep() {
- RunLoop(1);
+ return ResultStatus::Success;
}
-/// Halt the core
-void Halt(const char* msg) {
- // TODO(ShizZy): ImplementMe
+System::ResultStatus System::SingleStep() {
+ return RunLoop(1);
}
-/// Kill the core
-void Stop() {
- // TODO(ShizZy): ImplementMe
+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;
}
-/// Initialize the core
-void Init() {
+System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
+ if (app_core) {
+ app_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);
+ app_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);
+ app_core = std::make_unique<ARM_DynCom>(USER32MODE);
+ }
+
+ CoreTiming::Init();
+ HW::Init();
+ Kernel::Init(system_mode);
+ HLE::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();
+ HLE::Shutdown();
+ Kernel::Shutdown();
+ HW::Shutdown();
+ CoreTiming::Shutdown();
LOG_DEBUG(Core, "Shutdown OK");
}
diff --git a/src/core/core.h b/src/core/core.h
index ffbfa91c3..f4326161d 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -5,11 +5,17 @@
#pragma once
#include <memory>
+#include <string>
+
#include "common/common_types.h"
+#include "core/memory.h"
+class EmuWindow;
class ARM_Interface;
-////////////////////////////////////////////////////////////////////////////////////////////////////
+namespace Loader {
+class AppLoader;
+}
namespace Core {
@@ -24,37 +30,97 @@ struct ThreadContext {
u32 fpexc;
};
-extern std::unique_ptr<ARM_Interface> g_app_core; ///< ARM11 application core
-extern std::unique_ptr<ARM_Interface> g_sys_core; ///< ARM11 system (OS) core
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// Start the core
-void Start();
-
-/**
- * Run the core CPU loop
- * This function runs the core for the specified number of CPU instructions before trying to update
- * hardware. This is much faster than SingleStep (and should be equivalent), as the CPU is not
- * required to do a full dispatch with each instruction. NOTE: the number of instructions requested
- * is not guaranteed to run, as this will be interrupted preemptively if a hardware update is
- * requested (e.g. on a thread switch).
- */
-void RunLoop(int tight_loop = 1000);
-
-/// Step the CPU one instruction
-void SingleStep();
-
-/// Halt the core
-void Halt(const char* msg);
-
-/// Kill the core
-void Stop();
-
-/// Initialize the core
-void Init();
+class System {
+public:
+ /**
+ * Gets the instance of the System singleton class.
+ * @returns Reference to the instance of the System singleton class.
+ */
+ static System& GetInstance() {
+ return s_instance;
+ }
+
+ /// Enumeration representing the return values of the System Initialize and Load process.
+ enum class ResultStatus : u32 {
+ Success, ///< Succeeded
+ ErrorNotInitialized, ///< Error trying to use core prior to initialization
+ ErrorGetLoader, ///< Error finding the correct application loader
+ ErrorSystemMode, ///< Error determining the system mode
+ ErrorLoader, ///< Error loading the specified application
+ ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
+ ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an invalid format
+ ErrorVideoCore, ///< Error in the video core
+ };
+
+ /**
+ * Initialize the emulated system.
+ * @param emu_window Pointer to the host-system window used for video output and keyboard input.
+ * @param system_mode The system mode.
+ * @return ResultStatus code, indicating if the operation succeeded.
+ */
+ ResultStatus Init(EmuWindow* emu_window, u32 system_mode);
+
+ /// Start the core
+ void Start();
+
+ /**
+ * Run the core CPU loop
+ * This function runs the core for the specified number of CPU instructions before trying to update
+ * hardware. This is much faster than SingleStep (and should be equivalent), as the CPU is not
+ * required to do a full dispatch with each instruction. NOTE: the number of instructions requested
+ * is not guaranteed to run, as this will be interrupted preemptively if a hardware update is
+ * requested (e.g. on a thread switch).
+ * @param tight_loop Number of instructions to execute.
+ * @return Result status, indicating whethor or not the operation succeeded.
+ */
+ ResultStatus RunLoop(int tight_loop = 1000);
+
+ /**
+ * Step the CPU one instruction
+ * @return Result status, indicating whethor or not the operation succeeded.
+ */
+ ResultStatus SingleStep();
+
+ /// Shutdown the emulated system.
+ void Shutdown();
+
+ /**
+ * Load an executable application.
+ * @param emu_window Pointer to the host-system window used for video output and keyboard input.
+ * @param filepath String path to the executable application to load on the host file system.
+ * @returns ResultStatus code, indicating if the operation succeeded.
+ */
+ ResultStatus Load(EmuWindow* emu_window, const std::string& filepath);
+
+ /**
+ * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
+ * application).
+ * @returns True if the emulated system is powered on, otherwise false.
+ */
+ bool IsPoweredOn() const {
+ return app_core != nullptr;
+ }
+
+ /**
+ * Gets a reference to the emulated AppCore CPU.
+ * @returns A reference to the emulated AppCore CPU.
+ */
+ ARM_Interface& AppCore() {
+ return *app_core;
+ }
+
+private:
+ /// AppLoader used to load the current executing application
+ std::unique_ptr<Loader::AppLoader> app_loader;
+
+ ///< ARM11 application core
+ std::unique_ptr<ARM_Interface> app_core;
+
+ static System s_instance;
+};
-/// Shutdown the core
-void Shutdown();
+static ARM_Interface& AppCore() {
+ return System::GetInstance().AppCore();
+}
-} // namespace
+} // namespace Core
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 5220b55ea..9fe374795 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -130,7 +130,6 @@ int RegisterEvent(const char* name, TimedCallback callback) {
static void AntiCrashCallback(u64 userdata, int cycles_late) {
LOG_CRITICAL(Core_Timing, "Savestate broken: an unregistered event was called.");
- Core::Halt("invalid timing events");
}
void RestoreRegisterEvent(int event_type, const char* name, TimedCallback callback) {
@@ -147,7 +146,7 @@ void UnregisterAllEvents() {
}
void Init() {
- Core::g_app_core->down_count = INITIAL_SLICE_LENGTH;
+ Core::AppCore().down_count = INITIAL_SLICE_LENGTH;
g_slice_length = INITIAL_SLICE_LENGTH;
global_timer = 0;
idled_cycles = 0;
@@ -187,7 +186,7 @@ void Shutdown() {
}
u64 GetTicks() {
- return (u64)global_timer + g_slice_length - Core::g_app_core->down_count;
+ return (u64)global_timer + g_slice_length - Core::AppCore().down_count;
}
u64 GetIdleTicks() {
@@ -461,18 +460,18 @@ void MoveEvents() {
}
void ForceCheck() {
- s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
+ s64 cycles_executed = g_slice_length - Core::AppCore().down_count;
global_timer += cycles_executed;
// This will cause us to check for new events immediately.
- Core::g_app_core->down_count = 0;
+ Core::AppCore().down_count = 0;
// But let's not eat a bunch more time in Advance() because of this.
g_slice_length = 0;
}
void Advance() {
- s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
+ s64 cycles_executed = g_slice_length - Core::AppCore().down_count;
global_timer += cycles_executed;
- Core::g_app_core->down_count = g_slice_length;
+ Core::AppCore().down_count = g_slice_length;
if (has_ts_events)
MoveEvents();
@@ -481,7 +480,7 @@ void Advance() {
if (!first) {
if (g_slice_length < 10000) {
g_slice_length += 10000;
- Core::g_app_core->down_count += g_slice_length;
+ Core::AppCore().down_count += g_slice_length;
}
} else {
// Note that events can eat cycles as well.
@@ -491,7 +490,7 @@ void Advance() {
const int diff = target - g_slice_length;
g_slice_length += diff;
- Core::g_app_core->down_count += diff;
+ Core::AppCore().down_count += diff;
}
if (advance_callback)
advance_callback(static_cast<int>(cycles_executed));
@@ -507,12 +506,12 @@ void LogPendingEvents() {
}
void Idle(int max_idle) {
- s64 cycles_down = Core::g_app_core->down_count;
+ s64 cycles_down = Core::AppCore().down_count;
if (max_idle != 0 && cycles_down > max_idle)
cycles_down = max_idle;
if (first && cycles_down > 0) {
- s64 cycles_executed = g_slice_length - Core::g_app_core->down_count;
+ s64 cycles_executed = g_slice_length - Core::AppCore().down_count;
s64 cycles_next_event = first->time - global_timer;
if (cycles_next_event < cycles_executed + cycles_down) {
@@ -527,9 +526,9 @@ void Idle(int max_idle) {
cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
idled_cycles += cycles_down;
- Core::g_app_core->down_count -= cycles_down;
- if (Core::g_app_core->down_count == 0)
- Core::g_app_core->down_count = -1;
+ Core::AppCore().down_count -= cycles_down;
+ if (Core::AppCore().down_count == 0)
+ Core::AppCore().down_count = -1;
}
std::string GetScheduledEventsSummary() {
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index f96cbde64..9acdd402b 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -30,6 +30,7 @@
#include <unistd.h>
#endif
+#include "core/loader/loader.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/arm/arm_interface.h"
@@ -450,8 +451,8 @@ static void SendSignal(u32 signal) {
latest_signal = signal;
std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
- htonl(Core::g_app_core->GetPC()), 13,
- htonl(Core::g_app_core->GetReg(13)));
+ htonl(Core::AppCore().GetPC()), 13,
+ htonl(Core::AppCore().GetReg(13)));
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
SendReply(buffer.c_str());
}
@@ -538,15 +539,15 @@ static void ReadRegister() {
}
if (id <= R15_REGISTER) {
- IntToGdbHex(reply, Core::g_app_core->GetReg(id));
+ IntToGdbHex(reply, Core::AppCore().GetReg(id));
} else if (id == CPSR_REGISTER) {
- IntToGdbHex(reply, Core::g_app_core->GetCPSR());
+ IntToGdbHex(reply, Core::AppCore().GetCPSR());
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
- IntToGdbHex(reply, Core::g_app_core->GetVFPReg(
+ IntToGdbHex(reply, Core::AppCore().GetVFPReg(
id - CPSR_REGISTER -
1)); // VFP registers should start at 26, so one after CSPR_REGISTER
} else if (id == FPSCR_REGISTER) {
- IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
+ IntToGdbHex(reply, Core::AppCore().GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
IntToGdbHex(reply + 8, 0);
} else {
return SendReply("E01");
@@ -563,22 +564,22 @@ static void ReadRegisters() {
u8* bufptr = buffer;
for (int reg = 0; reg <= R15_REGISTER; reg++) {
- IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetReg(reg));
+ IntToGdbHex(bufptr + reg * CHAR_BIT, Core::AppCore().GetReg(reg));
}
bufptr += (16 * CHAR_BIT);
- IntToGdbHex(bufptr, Core::g_app_core->GetCPSR());
+ IntToGdbHex(bufptr, Core::AppCore().GetCPSR());
bufptr += CHAR_BIT;
for (int reg = 0; reg <= 31; reg++) {
- IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetVFPReg(reg));
+ IntToGdbHex(bufptr + reg * CHAR_BIT, Core::AppCore().GetVFPReg(reg));
}
bufptr += (32 * CHAR_BIT);
- IntToGdbHex(bufptr, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR));
+ IntToGdbHex(bufptr, Core::AppCore().GetVFPSystemReg(VFP_FPSCR));
SendReply(reinterpret_cast<char*>(buffer));
}
@@ -595,13 +596,13 @@ static void WriteRegister() {
}
if (id <= R15_REGISTER) {
- Core::g_app_core->SetReg(id, GdbHexToInt(buffer_ptr));
+ Core::AppCore().SetReg(id, GdbHexToInt(buffer_ptr));
} else if (id == CPSR_REGISTER) {
- Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr));
+ Core::AppCore().SetCPSR(GdbHexToInt(buffer_ptr));
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
- Core::g_app_core->SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
+ Core::AppCore().SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
} else if (id == FPSCR_REGISTER) {
- Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr));
+ Core::AppCore().SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr));
} else {
return SendReply("E01");
}
@@ -618,20 +619,20 @@ static void WriteRegisters() {
for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
if (reg <= R15_REGISTER) {
- Core::g_app_core->SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
+ Core::AppCore().SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} else if (reg == CPSR_REGISTER) {
- Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
+ Core::AppCore().SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} else if (reg == CPSR_REGISTER - 1) {
// Dummy FPA register, ignore
} else if (reg < CPSR_REGISTER) {
// Dummy FPA registers, ignore
i += 2;
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
- Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1,
+ Core::AppCore().SetVFPReg(reg - CPSR_REGISTER - 1,
GdbHexToInt(buffer_ptr + i * CHAR_BIT));
i++; // Skip padding
} else if (reg == FPSCR_REGISTER) {
- Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
+ Core::AppCore().SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
}
}
@@ -908,7 +909,7 @@ void ToggleServer(bool status) {
server_enabled = status;
// Start server
- if (!IsConnected() && Core::g_sys_core != nullptr) {
+ if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
Init();
}
} else {
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 8ce0f6d2b..0f2a04e30 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -14,7 +14,7 @@
namespace HLE {
-#define PARAM(n) Core::g_app_core->GetReg(n)
+#define PARAM(n) Core::AppCore().GetReg(n)
/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
static const ResultCode RESULT_INVALID(0xDEADC0DE);
@@ -24,7 +24,7 @@ static const ResultCode RESULT_INVALID(0xDEADC0DE);
* @param res Result to return
*/
static inline void FuncReturn(u32 res) {
- Core::g_app_core->SetReg(0, res);
+ Core::AppCore().SetReg(0, res);
}
/**
@@ -33,8 +33,8 @@ static inline void FuncReturn(u32 res) {
* @todo Verify that this function is correct
*/
static inline void FuncReturn64(u64 res) {
- Core::g_app_core->SetReg(0, (u32)(res & 0xFFFFFFFF));
- Core::g_app_core->SetReg(1, (u32)((res >> 32) & 0xFFFFFFFF));
+ Core::AppCore().SetReg(0, (u32)(res & 0xFFFFFFFF));
+ Core::AppCore().SetReg(1, (u32)((res >> 32) & 0xFFFFFFFF));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -49,7 +49,7 @@ template <ResultCode func(u32*, u32, u32, u32, u32, u32)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -57,7 +57,7 @@ template <ResultCode func(u32*, s32, u32, u32, u32, s32)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -69,7 +69,7 @@ void Wrap() {
.raw;
if (retval != RESULT_INVALID.raw) {
- Core::g_app_core->SetReg(1, (u32)param_1);
+ Core::AppCore().SetReg(1, (u32)param_1);
FuncReturn(retval);
}
}
@@ -84,7 +84,7 @@ template <ResultCode func(u32*)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -102,11 +102,11 @@ void Wrap() {
MemoryInfo memory_info = {};
PageInfo page_info = {};
u32 retval = func(&memory_info, &page_info, PARAM(2)).raw;
- Core::g_app_core->SetReg(1, memory_info.base_address);
- Core::g_app_core->SetReg(2, memory_info.size);
- Core::g_app_core->SetReg(3, memory_info.permission);
- Core::g_app_core->SetReg(4, memory_info.state);
- Core::g_app_core->SetReg(5, page_info.flags);
+ Core::AppCore().SetReg(1, memory_info.base_address);
+ Core::AppCore().SetReg(2, memory_info.size);
+ Core::AppCore().SetReg(3, memory_info.permission);
+ Core::AppCore().SetReg(4, memory_info.state);
+ Core::AppCore().SetReg(5, page_info.flags);
FuncReturn(retval);
}
@@ -115,11 +115,11 @@ void Wrap() {
MemoryInfo memory_info = {};
PageInfo page_info = {};
u32 retval = func(&memory_info, &page_info, PARAM(2), PARAM(3)).raw;
- Core::g_app_core->SetReg(1, memory_info.base_address);
- Core::g_app_core->SetReg(2, memory_info.size);
- Core::g_app_core->SetReg(3, memory_info.permission);
- Core::g_app_core->SetReg(4, memory_info.state);
- Core::g_app_core->SetReg(5, page_info.flags);
+ Core::AppCore().SetReg(1, memory_info.base_address);
+ Core::AppCore().SetReg(2, memory_info.size);
+ Core::AppCore().SetReg(3, memory_info.permission);
+ Core::AppCore().SetReg(4, memory_info.state);
+ Core::AppCore().SetReg(5, page_info.flags);
FuncReturn(retval);
}
@@ -127,7 +127,7 @@ template <ResultCode func(s32*, u32)>
void Wrap() {
s32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -140,7 +140,7 @@ template <ResultCode func(u32*, u32)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -160,7 +160,7 @@ template <ResultCode func(u32*, const char*)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -168,7 +168,7 @@ template <ResultCode func(u32*, s32, s32)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -176,7 +176,7 @@ template <ResultCode func(s32*, u32, s32)>
void Wrap() {
s32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -184,8 +184,8 @@ template <ResultCode func(s64*, u32, s32)>
void Wrap() {
s64 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
- Core::g_app_core->SetReg(1, (u32)param_1);
- Core::g_app_core->SetReg(2, (u32)(param_1 >> 32));
+ Core::AppCore().SetReg(1, (u32)param_1);
+ Core::AppCore().SetReg(2, (u32)(param_1 >> 32));
FuncReturn(retval);
}
@@ -194,7 +194,7 @@ void Wrap() {
u32 param_1 = 0;
// The last parameter is passed in R0 instead of R4
u32 retval = func(&param_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw;
- Core::g_app_core->SetReg(1, param_1);
+ Core::AppCore().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -209,8 +209,8 @@ template <ResultCode func(s64*, Handle, u32)>
void Wrap() {
s64 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
- Core::g_app_core->SetReg(1, (u32)param_1);
- Core::g_app_core->SetReg(2, (u32)(param_1 >> 32));
+ Core::AppCore().SetReg(1, (u32)param_1);
+ Core::AppCore().SetReg(2, (u32)(param_1 >> 32));
FuncReturn(retval);
}
@@ -227,8 +227,8 @@ void Wrap() {
reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
.raw;
// The first out parameter is moved into R2 and the second is moved into R1.
- Core::g_app_core->SetReg(1, param_2);
- Core::g_app_core->SetReg(2, param_1);
+ Core::AppCore().SetReg(1, param_2);
+ Core::AppCore().SetReg(2, param_1);
FuncReturn(retval);
}
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index 41b772163..d73d98a70 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -26,9 +26,9 @@ void Reschedule(const char* reason) {
// routines. This simulates that time by artificially advancing the number of CPU "ticks".
// The value was chosen empirically, it seems to work well enough for everything tested, but
// is likely not ideal. We should find a more accurate way to simulate timing with HLE.
- Core::g_app_core->AddTicks(4000);
+ Core::AppCore().AddTicks(4000);
- Core::g_app_core->PrepareReschedule();
+ Core::AppCore().PrepareReschedule();
reschedule = true;
}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 18b696f72..91c05fc42 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -188,7 +188,7 @@ static void SwitchContext(Thread* new_thread) {
// Save context for previous thread
if (previous_thread) {
previous_thread->last_running_ticks = CoreTiming::GetTicks();
- Core::g_app_core->SaveContext(previous_thread->context);
+ Core::AppCore().SaveContext(previous_thread->context);
if (previous_thread->status == THREADSTATUS_RUNNING) {
// This is only the case when a reschedule is triggered without the current thread
@@ -214,8 +214,8 @@ static void SwitchContext(Thread* new_thread) {
// Restores thread to its nominal priority if it has been temporarily changed
new_thread->current_priority = new_thread->nominal_priority;
- Core::g_app_core->LoadContext(new_thread->context);
- Core::g_app_core->SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
+ Core::AppCore().LoadContext(new_thread->context);
+ Core::AppCore().SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
} else {
current_thread = nullptr;
}
diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp
index 9e5d6a318..614f16d44 100644
--- a/src/core/hle/service/ldr_ro/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp
@@ -457,7 +457,7 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
}
}
- Core::g_app_core->ClearInstructionCache();
+ Core::AppCore().ClearInstructionCache();
LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
cro_address, cro_address + fix_size);
@@ -562,7 +562,7 @@ static void UnloadCRO(Interface* self) {
memory_synchronizer.RemoveMemoryBlock(cro_address, cro_buffer_ptr);
}
- Core::g_app_core->ClearInstructionCache();
+ Core::AppCore().ClearInstructionCache();
cmd_buff[1] = result.raw;
}
@@ -624,7 +624,7 @@ static void LinkCRO(Interface* self) {
}
memory_synchronizer.SynchronizeOriginalMemory();
- Core::g_app_core->ClearInstructionCache();
+ Core::AppCore().ClearInstructionCache();
cmd_buff[1] = result.raw;
}
@@ -686,7 +686,7 @@ static void UnlinkCRO(Interface* self) {
}
memory_synchronizer.SynchronizeOriginalMemory();
- Core::g_app_core->ClearInstructionCache();
+ Core::AppCore().ClearInstructionCache();
cmd_buff[1] = result.raw;
}
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 5839d7230..b20f2aaa4 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -582,7 +582,7 @@ static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point
/// Called when a thread exits
static void ExitThread() {
- LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::g_app_core->GetPC());
+ LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::AppCore().GetPC());
Kernel::ExitCurrentThread();
}
@@ -612,7 +612,7 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
using Kernel::Mutex;
SharedPtr<Mutex> mutex = Mutex::Create(initial_locked != 0);
- mutex->name = Common::StringFromFormat("mutex-%08x", Core::g_app_core->GetReg(14));
+ mutex->name = Common::StringFromFormat("mutex-%08x", Core::AppCore().GetReg(14));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex)));
LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X",
@@ -683,7 +683,7 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max
using Kernel::Semaphore;
CASCADE_RESULT(SharedPtr<Semaphore> semaphore, Semaphore::Create(initial_count, max_count));
- semaphore->name = Common::StringFromFormat("semaphore-%08x", Core::g_app_core->GetReg(14));
+ semaphore->name = Common::StringFromFormat("semaphore-%08x", Core::AppCore().GetReg(14));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(semaphore)));
LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X",
@@ -740,7 +740,7 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
using Kernel::Event;
SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type));
- evt->name = Common::StringFromFormat("event-%08x", Core::g_app_core->GetReg(14));
+ evt->name = Common::StringFromFormat("event-%08x", Core::AppCore().GetReg(14));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt)));
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
@@ -787,7 +787,7 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
using Kernel::Timer;
SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type));
- timer->name = Common::StringFromFormat("timer-%08x", Core::g_app_core->GetReg(14));
+ timer->name = Common::StringFromFormat("timer-%08x", Core::AppCore().GetReg(14));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer)));
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
@@ -854,7 +854,7 @@ static void SleepThread(s64 nanoseconds) {
static s64 GetSystemTick() {
s64 result = CoreTiming::GetTicks();
// Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
- Core::g_app_core->AddTicks(
+ Core::AppCore().AddTicks(
150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
return result;
}
diff --git a/src/core/system.cpp b/src/core/system.cpp
deleted file mode 100644
index fa8bd0317..000000000
--- a/src/core/system.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "audio_core/audio_core.h"
-#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/hw/hw.h"
-#include "core/system.h"
-#include "video_core/video_core.h"
-
-namespace Core {
-
-/*static*/ System System::s_instance;
-
-System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
- Core::Init();
- CoreTiming::Init();
- Memory::Init();
- HW::Init();
- Kernel::Init(system_mode);
- HLE::Init();
- AudioCore::Init();
- GDBStub::Init();
-
- if (!VideoCore::Init(emu_window)) {
- return ResultStatus::ErrorVideoCore;
- }
-
- is_powered_on = true;
-
- return ResultStatus::Success;
-}
-
-void System::Shutdown() {
- GDBStub::Shutdown();
- AudioCore::Shutdown();
- VideoCore::Shutdown();
- HLE::Shutdown();
- Kernel::Shutdown();
- HW::Shutdown();
- CoreTiming::Shutdown();
- Core::Shutdown();
-
- is_powered_on = false;
-}
-
-System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
- state.app_loader = Loader::GetLoader(filepath);
-
- if (!state.app_loader) {
- LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str());
- return ResultStatus::ErrorGetLoader;
- }
-
- boost::optional<u32> system_mode{ state.app_loader->LoadKernelSystemMode() };
- if (!system_mode) {
- LOG_CRITICAL(Frontend, "Failed to determine system mode!");
- return ResultStatus::ErrorSystemMode;
- }
-
- ResultStatus init_result{ Init(emu_window, system_mode.get()) };
- if (init_result != ResultStatus::Success) {
- LOG_CRITICAL(Frontend, "Failed to initialize system (Error %i)!", init_result);
- System::Shutdown();
- return init_result;
- }
-
- const Loader::ResultStatus load_result{ state.app_loader->Load() };
- if (Loader::ResultStatus::Success != load_result) {
- LOG_CRITICAL(Frontend, "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;
-}
-
-} // namespace Core
diff --git a/src/core/system.h b/src/core/system.h
deleted file mode 100644
index 192a9c447..000000000
--- a/src/core/system.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <string>
-
-#include "core/loader/loader.h"
-
-class EmuWindow;
-
-namespace Core {
-
-class System {
-public:
- struct State {
- std::unique_ptr<Loader::AppLoader> app_loader;
- };
-
- /**
- * Gets the instance of the System singleton class.
- * @returns Reference to the instance of the System singleton class.
- */
- static System& GetInstance() {
- return s_instance;
- }
-
- /// Enumeration representing the return values of the System Initialize and Load process.
- enum class ResultStatus : u32 {
- Success, ///< Succeeded
- ErrorGetLoader, ///< Error finding the correct application loader
- ErrorSystemMode, ///< Error determining the system mode
- ErrorLoader, ///< Error loading the specified application
- ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
- ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an invalid format
- ErrorVideoCore, ///< Error in the video core
- };
-
- /**
- * Initialize the emulated system.
- * @param emu_window Pointer to the host-system window used for video output and keyboard input.
- * @param system_mode The system mode.
- * @returns ResultStatus code, indicating if the operation succeeded.
- */
- ResultStatus Init(EmuWindow* emu_window, u32 system_mode);
-
- /// Shutdown the emulated system.
- void Shutdown();
-
- /**
- * Load an executable application.
- * @param emu_window Pointer to the host-system window used for video output and keyboard input.
- * @param filepath String path to the executable application to load on the host file system.
- * @returns ResultStatus code, indicating if the operation succeeded.
- */
- ResultStatus Load(EmuWindow* emu_window, const std::string& filepath);
-
- /**
- * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
- * application).
- * @returns True if the emulated system is powered on, otherwise false.
- */
- bool IsPoweredOn() const {
- return is_powered_on;
- }
-
- /**
- * Gets the internal state of the emulated system.
- * @returns The internal state of the emulated system
- */
- State& GetState() {
- return state;
- }
-
-private:
- bool is_powered_on{};
- State state;
-
- static System s_instance;
-};
-
-} // namespace Core