| 
									
										
										
										
											2014-04-08 19:15:46 -04:00
										 |  |  | // Copyright 2014 Citra Emulator Project
 | 
					
						
							| 
									
										
										
										
											2014-12-16 21:38:14 -08:00
										 |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							| 
									
										
										
										
											2014-04-08 19:15:46 -04:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2013-09-05 18:33:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-08 19:15:46 -04:00
										 |  |  | #pragma once
 | 
					
						
							| 
									
										
										
										
											2013-09-05 18:33:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 18:03:08 -05:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:30:09 -02:00
										 |  |  | #include "common/common_types.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:53:35 -04:00
										 |  |  | #include "core/loader/loader.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | #include "core/memory.h"
 | 
					
						
							| 
									
										
										
										
											2017-02-19 14:34:47 -08:00
										 |  |  | #include "core/perf_stats.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-02 00:09:15 -04:00
										 |  |  | #include "core/telemetry_session.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-22 04:30:09 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | class EmuWindow; | 
					
						
							| 
									
										
										
										
											2014-12-22 04:30:09 -02:00
										 |  |  | class ARM_Interface; | 
					
						
							| 
									
										
										
										
											2014-04-03 21:22:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-05 18:33:46 -04:00
										 |  |  | namespace Core { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2016-12-17 01:20:47 -05:00
										 |  |  |         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
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |         ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
 | 
					
						
							| 
									
										
										
										
											2016-12-17 01:20:47 -05:00
										 |  |  |         ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
 | 
					
						
							|  |  |  |                                         /// invalid format
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:28:30 -05:00
										 |  |  |         ErrorSystemFiles,               ///< Error in finding system files
 | 
					
						
							|  |  |  |         ErrorSharedFont,                ///< Error in finding shared font
 | 
					
						
							| 
									
										
										
										
											2016-12-17 01:20:47 -05:00
										 |  |  |         ErrorVideoCore,                 ///< Error in the video core
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:28:30 -05:00
										 |  |  |         ErrorUnknown                    ///< Any other error
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Run the core CPU loop | 
					
						
							| 
									
										
										
										
											2016-12-17 01:20:47 -05:00
										 |  |  |      * 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). | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |      * @param tight_loop Number of instructions to execute. | 
					
						
							|  |  |  |      * @return Result status, indicating whethor or not the operation succeeded. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-01-04 16:52:16 -05:00
										 |  |  |     ResultStatus RunLoop(int tight_loop = 100000); | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Step the CPU one instruction | 
					
						
							|  |  |  |      * @return Result status, indicating whethor or not the operation succeeded. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     ResultStatus SingleStep(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Shutdown the emulated system.
 | 
					
						
							|  |  |  |     void Shutdown(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Load an executable application. | 
					
						
							|  |  |  |      * @param emu_window Pointer to the host-system window used for video output and keyboard input. | 
					
						
							|  |  |  |      * @param filepath String path to the executable application to load on the host file system. | 
					
						
							|  |  |  |      * @returns ResultStatus code, indicating if the operation succeeded. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     ResultStatus Load(EmuWindow* emu_window, const std::string& filepath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * Indicates if the emulated system is powered on (all subsystems initialized and able to run an | 
					
						
							|  |  |  |      * application). | 
					
						
							|  |  |  |      * @returns True if the emulated system is powered on, otherwise false. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     bool IsPoweredOn() const { | 
					
						
							| 
									
										
										
										
											2016-12-22 00:00:01 -05:00
										 |  |  |         return cpu_core != nullptr; | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 00:09:15 -04:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Returns a reference to the telemetry session for this emulation session. | 
					
						
							|  |  |  |      * @returns Reference to the telemetry session. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     Core::TelemetrySession& TelemetrySession() const { | 
					
						
							|  |  |  |         return *telemetry_session; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-16 00:37:38 -05:00
										 |  |  |     /// Prepare the core emulation for a reschedule
 | 
					
						
							|  |  |  |     void PrepareReschedule(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-19 14:34:47 -08:00
										 |  |  |     PerfStats::Results GetAndResetPerfStats(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     /**
 | 
					
						
							| 
									
										
										
										
											2016-12-22 00:00:01 -05:00
										 |  |  |      * Gets a reference to the emulated CPU. | 
					
						
							|  |  |  |      * @returns A reference to the emulated CPU. | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-12-22 00:00:01 -05:00
										 |  |  |     ARM_Interface& CPU() { | 
					
						
							|  |  |  |         return *cpu_core; | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-20 13:56:58 -08:00
										 |  |  |     PerfStats perf_stats; | 
					
						
							| 
									
										
										
										
											2017-02-20 16:31:59 -08:00
										 |  |  |     FrameLimiter frame_limiter; | 
					
						
							| 
									
										
										
										
											2017-02-19 14:34:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:03:38 -04:00
										 |  |  |     void SetStatus(ResultStatus new_status, const char* details = nullptr) { | 
					
						
							| 
									
										
										
										
											2017-04-13 01:15:23 -04:00
										 |  |  |         status = new_status; | 
					
						
							| 
									
										
										
										
											2017-06-02 17:03:38 -04:00
										 |  |  |         if (details) { | 
					
						
							|  |  |  |             status_details = details; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-04-13 01:15:23 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:03:38 -04:00
										 |  |  |     const std::string& GetStatusDetails() const { | 
					
						
							| 
									
										
										
										
											2017-04-13 01:15:23 -04:00
										 |  |  |         return status_details; | 
					
						
							| 
									
										
										
										
											2017-03-08 16:28:30 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 19:53:35 -04:00
										 |  |  |     Loader::AppLoader& GetAppLoader() const { | 
					
						
							|  |  |  |         return *app_loader; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2016-12-16 00:37:38 -05:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * 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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// Reschedule the core emulation
 | 
					
						
							|  |  |  |     void Reschedule(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     /// AppLoader used to load the current executing application
 | 
					
						
							|  |  |  |     std::unique_ptr<Loader::AppLoader> app_loader; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-22 00:00:01 -05:00
										 |  |  |     ///< ARM11 CPU core
 | 
					
						
							|  |  |  |     std::unique_ptr<ARM_Interface> cpu_core; | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-16 00:37:38 -05:00
										 |  |  |     /// When true, signals that a reschedule should happen
 | 
					
						
							|  |  |  |     bool reschedule_pending{}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 00:09:15 -04:00
										 |  |  |     /// Telemetry session for this emulation session
 | 
					
						
							|  |  |  |     std::unique_ptr<Core::TelemetrySession> telemetry_session; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  |     static System s_instance; | 
					
						
							| 
									
										
										
										
											2017-04-13 01:15:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 17:03:38 -04:00
										 |  |  |     ResultStatus status = ResultStatus::Success; | 
					
						
							|  |  |  |     std::string status_details = ""; | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-09-05 18:33:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-29 23:17:07 +01:00
										 |  |  | inline ARM_Interface& CPU() { | 
					
						
							| 
									
										
										
										
											2016-12-22 00:00:01 -05:00
										 |  |  |     return System::GetInstance().CPU(); | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-05 00:01:07 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 00:09:15 -04:00
										 |  |  | inline TelemetrySession& Telemetry() { | 
					
						
							|  |  |  |     return System::GetInstance().TelemetrySession(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-15 19:01:48 -05:00
										 |  |  | } // namespace Core
 |