core: Consolidate core and system state, remove system module & cleanups.
This commit is contained in:
		@@ -33,7 +33,6 @@
 | 
			
		||||
#include "core/gdbstub/gdbstub.h"
 | 
			
		||||
#include "core/loader/loader.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "video_core/video_core.h"
 | 
			
		||||
 | 
			
		||||
static void PrintHelp(const char* argv0) {
 | 
			
		||||
@@ -145,7 +144,7 @@ int main(int argc, char** argv) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (emu_window->IsOpen()) {
 | 
			
		||||
        Core::RunLoop();
 | 
			
		||||
        system.RunLoop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,6 @@
 | 
			
		||||
#include "common/scm_rev.h"
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "video_core/debug_utils/debug_utils.h"
 | 
			
		||||
#include "video_core/video_core.h"
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +36,7 @@ void EmuThread::run() {
 | 
			
		||||
            if (!was_active)
 | 
			
		||||
                emit DebugModeLeft();
 | 
			
		||||
 | 
			
		||||
            Core::RunLoop();
 | 
			
		||||
            Core::System::GetInstance().RunLoop();
 | 
			
		||||
 | 
			
		||||
            was_active = running || exec_step;
 | 
			
		||||
            if (!was_active && !stop_run)
 | 
			
		||||
@@ -48,7 +46,7 @@ void EmuThread::run() {
 | 
			
		||||
                emit DebugModeLeft();
 | 
			
		||||
 | 
			
		||||
            exec_step = false;
 | 
			
		||||
            Core::SingleStep();
 | 
			
		||||
            Core::System::GetInstance().SingleStep();
 | 
			
		||||
            emit DebugModeEntered();
 | 
			
		||||
            yieldCurrentThread();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@
 | 
			
		||||
 | 
			
		||||
#include "citra_qt/configure_general.h"
 | 
			
		||||
#include "citra_qt/ui_settings.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "ui_configure_general.h"
 | 
			
		||||
 | 
			
		||||
ConfigureGeneral::ConfigureGeneral(QWidget* parent)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include "citra_qt/configure_graphics.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "ui_configure_graphics.h"
 | 
			
		||||
 | 
			
		||||
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
#include "citra_qt/ui_settings.h"
 | 
			
		||||
#include "core/hle/service/cfg/cfg.h"
 | 
			
		||||
#include "core/hle/service/fs/archive.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "ui_configure_system.h"
 | 
			
		||||
 | 
			
		||||
static const std::array<int, 12> days_in_month = {{
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ CallstackWidget::CallstackWidget(QWidget* parent) : QDockWidget(parent) {
 | 
			
		||||
 | 
			
		||||
void CallstackWidget::OnDebugModeEntered() {
 | 
			
		||||
    // Stack pointer
 | 
			
		||||
    const u32 sp = Core::g_app_core->GetReg(13);
 | 
			
		||||
    const u32 sp = Core::AppCore().GetReg(13);
 | 
			
		||||
 | 
			
		||||
    Clear();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -185,13 +185,13 @@ DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DisassemblerWidget::Init() {
 | 
			
		||||
    model->ParseFromAddress(Core::g_app_core->GetPC());
 | 
			
		||||
    model->ParseFromAddress(Core::AppCore().GetPC());
 | 
			
		||||
 | 
			
		||||
    disasm_ui.treeView->resizeColumnToContents(0);
 | 
			
		||||
    disasm_ui.treeView->resizeColumnToContents(1);
 | 
			
		||||
    disasm_ui.treeView->resizeColumnToContents(2);
 | 
			
		||||
 | 
			
		||||
    QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::g_app_core->GetPC());
 | 
			
		||||
    QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::AppCore().GetPC());
 | 
			
		||||
    disasm_ui.treeView->scrollTo(model_index);
 | 
			
		||||
    disasm_ui.treeView->selectionModel()->setCurrentIndex(
 | 
			
		||||
        model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
 | 
			
		||||
@@ -214,8 +214,8 @@ void DisassemblerWidget::OnPause() {
 | 
			
		||||
    emu_thread->SetRunning(false);
 | 
			
		||||
 | 
			
		||||
    // TODO: By now, the CPU might not have actually stopped...
 | 
			
		||||
    if (Core::g_app_core) {
 | 
			
		||||
        model->SetNextInstruction(Core::g_app_core->GetPC());
 | 
			
		||||
    if (Core::System::GetInstance().IsPoweredOn()) {
 | 
			
		||||
        model->SetNextInstruction(Core::AppCore().GetPC());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -224,7 +224,7 @@ void DisassemblerWidget::OnToggleStartStop() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DisassemblerWidget::OnDebugModeEntered() {
 | 
			
		||||
    u32 next_instr = Core::g_app_core->GetPC();
 | 
			
		||||
    u32 next_instr = Core::AppCore().GetPC();
 | 
			
		||||
 | 
			
		||||
    if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
 | 
			
		||||
        emu_thread->SetRunning(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -58,16 +58,16 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegistersWidget::OnDebugModeEntered() {
 | 
			
		||||
    if (!Core::g_app_core)
 | 
			
		||||
    if (!Core::System::GetInstance().IsPoweredOn())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < core_registers->childCount(); ++i)
 | 
			
		||||
        core_registers->child(i)->setText(
 | 
			
		||||
            1, QString("0x%1").arg(Core::g_app_core->GetReg(i), 8, 16, QLatin1Char('0')));
 | 
			
		||||
            1, QString("0x%1").arg(Core::AppCore().GetReg(i), 8, 16, QLatin1Char('0')));
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < vfp_registers->childCount(); ++i)
 | 
			
		||||
        vfp_registers->child(i)->setText(
 | 
			
		||||
            1, QString("0x%1").arg(Core::g_app_core->GetVFPReg(i), 8, 16, QLatin1Char('0')));
 | 
			
		||||
            1, QString("0x%1").arg(Core::AppCore().GetVFPReg(i), 8, 16, QLatin1Char('0')));
 | 
			
		||||
 | 
			
		||||
    UpdateCPSRValues();
 | 
			
		||||
    UpdateVFPSystemRegisterValues();
 | 
			
		||||
@@ -127,7 +127,7 @@ void RegistersWidget::CreateCPSRChildren() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegistersWidget::UpdateCPSRValues() {
 | 
			
		||||
    const u32 cpsr_val = Core::g_app_core->GetCPSR();
 | 
			
		||||
    const u32 cpsr_val = Core::AppCore().GetCPSR();
 | 
			
		||||
 | 
			
		||||
    cpsr->setText(1, QString("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
 | 
			
		||||
    cpsr->child(0)->setText(
 | 
			
		||||
@@ -191,10 +191,10 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RegistersWidget::UpdateVFPSystemRegisterValues() {
 | 
			
		||||
    const u32 fpscr_val = Core::g_app_core->GetVFPSystemReg(VFP_FPSCR);
 | 
			
		||||
    const u32 fpexc_val = Core::g_app_core->GetVFPSystemReg(VFP_FPEXC);
 | 
			
		||||
    const u32 fpinst_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST);
 | 
			
		||||
    const u32 fpinst2_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST2);
 | 
			
		||||
    const u32 fpscr_val = Core::AppCore().GetVFPSystemReg(VFP_FPSCR);
 | 
			
		||||
    const u32 fpexc_val = Core::AppCore().GetVFPSystemReg(VFP_FPEXC);
 | 
			
		||||
    const u32 fpinst_val = Core::AppCore().GetVFPSystemReg(VFP_FPINST);
 | 
			
		||||
    const u32 fpinst2_val = Core::AppCore().GetVFPSystemReg(VFP_FPINST2);
 | 
			
		||||
 | 
			
		||||
    QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
 | 
			
		||||
    fpscr->setText(1, QString("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));
 | 
			
		||||
 
 | 
			
		||||
@@ -391,7 +391,7 @@ WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WaitTreeWidget::OnDebugModeEntered() {
 | 
			
		||||
    if (!Core::g_app_core)
 | 
			
		||||
    if (!Core::System::GetInstance().IsPoweredOn())
 | 
			
		||||
        return;
 | 
			
		||||
    model->InitItems();
 | 
			
		||||
    view->setModel(model);
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,6 @@
 | 
			
		||||
#include "core/gdbstub/gdbstub.h"
 | 
			
		||||
#include "core/loader/loader.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
#include "qhexedit.h"
 | 
			
		||||
#include "video_core/video_core.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ResultStatus::Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Step the CPU one instruction
 | 
			
		||||
void SingleStep() {
 | 
			
		||||
    RunLoop(1);
 | 
			
		||||
System::ResultStatus System::SingleStep() {
 | 
			
		||||
    return RunLoop(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Halt the core
 | 
			
		||||
void Halt(const char* msg) {
 | 
			
		||||
    // 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Kill the core
 | 
			
		||||
void Stop() {
 | 
			
		||||
    // TODO(ShizZy): ImplementMe
 | 
			
		||||
}
 | 
			
		||||
System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
 | 
			
		||||
    if (app_core) {
 | 
			
		||||
        app_core.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Memory::Init();
 | 
			
		||||
 | 
			
		||||
/// Initialize the core
 | 
			
		||||
void 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");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								src/core/core.h
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								src/core/core.h
									
									
									
									
									
								
							@@ -5,11 +5,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#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
 | 
			
		||||
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
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
/// Start the core
 | 
			
		||||
void Start();
 | 
			
		||||
    /**
 | 
			
		||||
     * 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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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);
 | 
			
		||||
    /// Start the core
 | 
			
		||||
    void Start();
 | 
			
		||||
 | 
			
		||||
/// Step the CPU one instruction
 | 
			
		||||
void SingleStep();
 | 
			
		||||
    /**
 | 
			
		||||
     * 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);
 | 
			
		||||
 | 
			
		||||
/// Halt the core
 | 
			
		||||
void Halt(const char* msg);
 | 
			
		||||
    /**
 | 
			
		||||
     * Step the CPU one instruction
 | 
			
		||||
     * @return Result status, indicating whethor or not the operation succeeded.
 | 
			
		||||
     */
 | 
			
		||||
    ResultStatus SingleStep();
 | 
			
		||||
 | 
			
		||||
/// Kill the core
 | 
			
		||||
void Stop();
 | 
			
		||||
    /// Shutdown the emulated system.
 | 
			
		||||
    void Shutdown();
 | 
			
		||||
 | 
			
		||||
/// Initialize the core
 | 
			
		||||
void Init();
 | 
			
		||||
    /**
 | 
			
		||||
     * 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);
 | 
			
		||||
 | 
			
		||||
/// Shutdown the core
 | 
			
		||||
void Shutdown();
 | 
			
		||||
    /**
 | 
			
		||||
     * 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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
    /**
 | 
			
		||||
     * 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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ARM_Interface& AppCore() {
 | 
			
		||||
    return System::GetInstance().AppCore();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Core
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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(¶m_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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user