mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 22:00:05 +00:00 
			
		
		
		
	core: Consolidate core and system state, remove system module & cleanups.
This commit is contained in:
		
							parent
							
								
									707cc66362
								
							
						
					
					
						commit
						232ef55c1a
					
				
					 22 changed files with 278 additions and 330 deletions
				
			
		|  | @ -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
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue