MSXMotherBoard.hh 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #ifndef MSXMOTHERBOARD_HH
  2. #define MSXMOTHERBOARD_HH
  3. #include "EmuTime.hh"
  4. #include "VideoSourceSetting.hh"
  5. #include "hash_map.hh"
  6. #include "serialize_meta.hh"
  7. #include "string_view.hh"
  8. #include "xxhash.hh"
  9. #include "openmsx.hh"
  10. #include "RecordedCommand.hh"
  11. #include <cassert>
  12. #include <memory>
  13. #include <vector>
  14. namespace openmsx {
  15. class AddRemoveUpdate;
  16. class BooleanSetting;
  17. class CartridgeSlotManager;
  18. class CassettePortInterface;
  19. class CliComm;
  20. class CommandController;
  21. class Debugger;
  22. class DeviceInfo;
  23. class EventDelay;
  24. class ExtCmd;
  25. class FastForwardHelper;
  26. class HardwareConfig;
  27. class InfoCommand;
  28. class JoyPortDebuggable;
  29. class JoystickPortIf;
  30. class LedStatus;
  31. class ListExtCmd;
  32. class LoadMachineCmd;
  33. class MachineNameInfo;
  34. class MachineTypeInfo;
  35. class MSXCliComm;
  36. class MSXCommandController;
  37. class MSXCPU;
  38. class MSXCPUInterface;
  39. class MSXDevice;
  40. class MSXDeviceSwitch;
  41. class MSXEventDistributor;
  42. class MSXMapperIO;
  43. class MSXMixer;
  44. class PanasonicMemory;
  45. class PluggingController;
  46. class Reactor;
  47. class RealTime;
  48. class RemoveExtCmd;
  49. class RenShaTurbo;
  50. class ResetCmd;
  51. class ReverseManager;
  52. class SettingObserver;
  53. class Scheduler;
  54. class Setting;
  55. class StateChangeDistributor;
  56. class MSXMotherBoard final
  57. {
  58. public:
  59. MSXMotherBoard(const MSXMotherBoard&) = delete;
  60. MSXMotherBoard& operator=(const MSXMotherBoard&) = delete;
  61. explicit MSXMotherBoard(Reactor& reactor);
  62. ~MSXMotherBoard();
  63. const std::string& getMachineID() const { return machineID; }
  64. const std::string& getMachineName() const { return machineName; }
  65. /** Run emulation.
  66. * @return True if emulation steps were done,
  67. * false if emulation is suspended.
  68. */
  69. bool execute();
  70. /** Run emulation until a certain time in fast forward mode.
  71. */
  72. void fastForward(EmuTime::param time, bool fast);
  73. /** See CPU::exitCPULoopAsync(). */
  74. void exitCPULoopAsync();
  75. void exitCPULoopSync();
  76. /** Pause MSX machine. Only CPU is paused, other devices continue
  77. * running. Used by turbor hardware pause.
  78. */
  79. void pause();
  80. void unpause();
  81. void powerUp();
  82. void doReset();
  83. void activate(bool active);
  84. bool isActive() const { return active; }
  85. bool isFastForwarding() const { return fastForwarding; }
  86. byte readIRQVector();
  87. const HardwareConfig* getMachineConfig() const { return machineConfig; }
  88. void setMachineConfig(HardwareConfig* machineConfig);
  89. std::string getMachineType() const;
  90. bool isTurboR() const;
  91. std::string loadMachine(const std::string& machine);
  92. using Extensions = std::vector<std::unique_ptr<HardwareConfig>>;
  93. const Extensions& getExtensions() const { return extensions; }
  94. HardwareConfig* findExtension(string_view extensionName);
  95. std::string loadExtension(string_view extensionName, string_view slotname);
  96. std::string insertExtension(string_view name,
  97. std::unique_ptr<HardwareConfig> extension);
  98. void removeExtension(const HardwareConfig& extension);
  99. // The following classes are unique per MSX machine
  100. CliComm& getMSXCliComm();
  101. MSXCommandController& getMSXCommandController() { return *msxCommandController; }
  102. Scheduler& getScheduler() { return *scheduler; }
  103. MSXEventDistributor& getMSXEventDistributor() { return *msxEventDistributor; }
  104. StateChangeDistributor& getStateChangeDistributor() { return *stateChangeDistributor; }
  105. CartridgeSlotManager& getSlotManager() { return *slotManager; }
  106. RealTime& getRealTime() { return *realTime; }
  107. Debugger& getDebugger() { return *debugger; }
  108. MSXMixer& getMSXMixer() { return *msxMixer; }
  109. PluggingController& getPluggingController();
  110. MSXCPU& getCPU();
  111. MSXCPUInterface& getCPUInterface();
  112. PanasonicMemory& getPanasonicMemory();
  113. MSXDeviceSwitch& getDeviceSwitch();
  114. CassettePortInterface& getCassettePort();
  115. JoystickPortIf& getJoystickPort(unsigned port);
  116. RenShaTurbo& getRenShaTurbo();
  117. LedStatus& getLedStatus();
  118. ReverseManager& getReverseManager() { return *reverseManager; }
  119. Reactor& getReactor() { return reactor; }
  120. VideoSourceSetting& getVideoSource() { return videoSourceSetting; }
  121. // convenience methods
  122. CommandController& getCommandController();
  123. InfoCommand& getMachineInfoCommand();
  124. /** Convenience method:
  125. * This is the same as getScheduler().getCurrentTime(). */
  126. EmuTime::param getCurrentTime();
  127. /** All MSXDevices should be registered by the MotherBoard.
  128. */
  129. void addDevice(MSXDevice& device);
  130. void removeDevice(MSXDevice& device);
  131. /** Find a MSXDevice by name
  132. * @param name The name of the device as returned by
  133. * MSXDevice::getName()
  134. * @return A pointer to the device or nullptr if the device could not
  135. * be found.
  136. */
  137. MSXDevice* findDevice(string_view name);
  138. /** Some MSX device parts are shared between several MSX devices
  139. * (e.g. all memory mappers share IO ports 0xFC-0xFF). But this
  140. * sharing is limited to one MSX machine. This method offers the
  141. * storage to implement per-machine reference counted objects.
  142. * TODO This doesn't play nicely with savestates. For example memory
  143. * mappers don't use this mechanism anymore because of this.
  144. * Maybe this method can be removed when savestates are finished.
  145. */
  146. template<typename T, typename ... Args>
  147. std::shared_ptr<T> getSharedStuff(string_view name, Args&& ...args)
  148. {
  149. auto& weak = sharedStuffMap[name];
  150. auto shared = std::static_pointer_cast<T>(weak.lock());
  151. if (shared) return shared;
  152. shared = std::make_shared<T>(std::forward<Args>(args)...);
  153. weak = shared;
  154. return shared;
  155. }
  156. /** All memory mappers in one MSX machine share the same four (logical)
  157. * memory mapper registers. These two methods handle this sharing.
  158. */
  159. MSXMapperIO& createMapperIO();
  160. MSXMapperIO& getMapperIO() const
  161. {
  162. assert(mapperIOCounter);
  163. return *mapperIO;
  164. }
  165. void destroyMapperIO();
  166. /** Keep track of which 'usernames' are in use.
  167. * For example to be able to use several fmpac extensions at once, each
  168. * with its own SRAM file, we need to generate unique filenames. We
  169. * also want to reuse existing filenames as much as possible.
  170. * ATM the usernames always have the format 'untitled[N]'. In the future
  171. * we might allow really user specified names.
  172. */
  173. std::string getUserName(const std::string& hwName);
  174. void freeUserName(const std::string& hwName, const std::string& userName);
  175. template<typename Archive>
  176. void serialize(Archive& ar, unsigned version);
  177. private:
  178. void powerDown();
  179. void deleteMachine();
  180. Reactor& reactor;
  181. std::string machineID;
  182. std::string machineName;
  183. std::vector<MSXDevice*> availableDevices; // no ownership, no order
  184. hash_map<string_view, std::weak_ptr<void>, XXHasher> sharedStuffMap;
  185. hash_map<std::string, std::vector<std::string>, XXHasher> userNames;
  186. std::unique_ptr<MSXMapperIO> mapperIO;
  187. unsigned mapperIOCounter;
  188. // These two should normally be the same, only during savestate loading
  189. // machineConfig will already be filled in, but machineConfig2 not yet.
  190. // This is important when an exception happens during loading of
  191. // machineConfig2 (otherwise machineConfig2 gets deleted twice).
  192. // See also HardwareConfig::serialize() and setMachineConfig()
  193. std::unique_ptr<HardwareConfig> machineConfig2;
  194. HardwareConfig* machineConfig;
  195. Extensions extensions; // order matters: later extension might depend on earlier ones
  196. // order of unique_ptr's is important!
  197. std::unique_ptr<AddRemoveUpdate> addRemoveUpdate;
  198. std::unique_ptr<MSXCliComm> msxCliComm;
  199. std::unique_ptr<MSXEventDistributor> msxEventDistributor;
  200. std::unique_ptr<StateChangeDistributor> stateChangeDistributor;
  201. std::unique_ptr<MSXCommandController> msxCommandController;
  202. std::unique_ptr<Scheduler> scheduler;
  203. std::unique_ptr<EventDelay> eventDelay;
  204. std::unique_ptr<RealTime> realTime;
  205. std::unique_ptr<Debugger> debugger;
  206. std::unique_ptr<MSXMixer> msxMixer;
  207. std::unique_ptr<PluggingController> pluggingController;
  208. std::unique_ptr<MSXCPU> msxCpu;
  209. std::unique_ptr<MSXCPUInterface> msxCpuInterface;
  210. std::unique_ptr<PanasonicMemory> panasonicMemory;
  211. std::unique_ptr<MSXDeviceSwitch> deviceSwitch;
  212. std::unique_ptr<CassettePortInterface> cassettePort;
  213. std::unique_ptr<JoystickPortIf> joystickPort[2];
  214. std::unique_ptr<JoyPortDebuggable> joyPortDebuggable;
  215. std::unique_ptr<RenShaTurbo> renShaTurbo;
  216. std::unique_ptr<LedStatus> ledStatus;
  217. VideoSourceSetting videoSourceSetting;
  218. std::unique_ptr<CartridgeSlotManager> slotManager;
  219. std::unique_ptr<ReverseManager> reverseManager;
  220. std::unique_ptr<ResetCmd> resetCommand;
  221. std::unique_ptr<LoadMachineCmd> loadMachineCommand;
  222. std::unique_ptr<ListExtCmd> listExtCommand;
  223. std::unique_ptr<ExtCmd> extCommand;
  224. std::unique_ptr<RemoveExtCmd> removeExtCommand;
  225. std::unique_ptr<MachineNameInfo> machineNameInfo;
  226. std::unique_ptr<MachineTypeInfo> machineTypeInfo;
  227. std::unique_ptr<DeviceInfo> deviceInfo;
  228. friend class DeviceInfo;
  229. std::unique_ptr<FastForwardHelper> fastForwardHelper;
  230. std::unique_ptr<SettingObserver> settingObserver;
  231. friend class SettingObserver;
  232. BooleanSetting& powerSetting;
  233. bool powered;
  234. bool active;
  235. bool fastForwarding;
  236. };
  237. SERIALIZE_CLASS_VERSION(MSXMotherBoard, 4);
  238. class ExtCmd final : public RecordedCommand
  239. {
  240. public:
  241. ExtCmd(MSXMotherBoard& motherBoard, std::string commandName);
  242. void execute(array_ref<TclObject> tokens, TclObject& result,
  243. EmuTime::param time) override;
  244. std::string help(const std::vector<std::string>& tokens) const override;
  245. void tabCompletion(std::vector<std::string>& tokens) const override;
  246. private:
  247. MSXMotherBoard& motherBoard;
  248. std::string commandName;
  249. };
  250. } // namespace openmsx
  251. #endif