openMSX
MSXMotherBoard.hh
Go to the documentation of this file.
1 #ifndef MSXMOTHERBOARD_HH
2 #define MSXMOTHERBOARD_HH
3 
4 #include "EmuTime.hh"
5 #include "VideoSourceSetting.hh"
6 #include "hash_map.hh"
7 #include "serialize_meta.hh"
8 #include "xxhash.hh"
9 #include "openmsx.hh"
10 #include "RecordedCommand.hh"
11 #include <cassert>
12 #include <memory>
13 #include <string_view>
14 #include <vector>
15 
16 namespace openmsx {
17 
18 class AddRemoveUpdate;
19 class BooleanSetting;
20 class CartridgeSlotManager;
21 class CassettePortInterface;
22 class CliComm;
23 class CommandController;
24 class Debugger;
25 class DeviceInfo;
26 class EventDelay;
27 class ExtCmd;
28 class FastForwardHelper;
29 class HardwareConfig;
30 class InfoCommand;
31 class JoyPortDebuggable;
32 class JoystickPortIf;
33 class LedStatus;
34 class ListExtCmd;
35 class LoadMachineCmd;
36 class MachineExtensionInfo;
37 class MachineNameInfo;
38 class MachineTypeInfo;
39 class MSXCliComm;
40 class MSXCommandController;
41 class MSXCPU;
42 class MSXCPUInterface;
43 class MSXDevice;
44 class MSXDeviceSwitch;
45 class MSXEventDistributor;
46 class MSXMapperIO;
47 class MSXMixer;
48 class PanasonicMemory;
49 class PluggingController;
50 class Reactor;
51 class RealTime;
52 class RemoveExtCmd;
53 class RenShaTurbo;
54 class ResetCmd;
55 class ReverseManager;
56 class SettingObserver;
57 class Scheduler;
58 class StateChangeDistributor;
59 
60 class MSXMotherBoard final
61 {
62 public:
63  MSXMotherBoard(const MSXMotherBoard&) = delete;
65 
66  explicit MSXMotherBoard(Reactor& reactor);
68 
69  [[nodiscard]] std::string_view getMachineID() const { return machineID; }
70  [[nodiscard]] std::string_view getMachineName() const { return machineName; }
71 
76  [[nodiscard]] bool execute();
77 
80  void fastForward(EmuTime::param time, bool fast);
81 
83  void exitCPULoopAsync();
84  void exitCPULoopSync();
85 
89  void pause();
90  void unpause();
91 
92  void powerUp();
93 
94  void doReset();
95  void activate(bool active);
96  [[nodiscard]] bool isActive() const { return active; }
97  [[nodiscard]] bool isFastForwarding() const { return fastForwarding; }
98 
99  [[nodiscard]] byte readIRQVector();
100 
101  [[nodiscard]] const HardwareConfig* getMachineConfig() const { return machineConfig; }
102  [[nodiscard]] HardwareConfig* getMachineConfig() { return machineConfig; }
103  void setMachineConfig(HardwareConfig* machineConfig);
104  [[nodiscard]] std::string_view getMachineType() const;
105  [[nodiscard]] bool isTurboR() const;
106 
107  std::string loadMachine(const std::string& machine);
108 
109  using Extensions = std::vector<std::unique_ptr<HardwareConfig>>;
110  [[nodiscard]] const Extensions& getExtensions() const { return extensions; }
111  [[nodiscard]] HardwareConfig* findExtension(std::string_view extensionName);
112  std::string loadExtension(std::string_view extensionName, std::string_view slotname);
113  std::string insertExtension(std::string_view name,
114  std::unique_ptr<HardwareConfig> extension);
115  void removeExtension(const HardwareConfig& extension);
116 
117  // The following classes are unique per MSX machine
118  [[nodiscard]] CliComm& getMSXCliComm();
119  [[nodiscard]] MSXCommandController& getMSXCommandController() { return *msxCommandController; }
120  [[nodiscard]] Scheduler& getScheduler() { return *scheduler; }
121  [[nodiscard]] MSXEventDistributor& getMSXEventDistributor() { return *msxEventDistributor; }
122  [[nodiscard]] StateChangeDistributor& getStateChangeDistributor() { return *stateChangeDistributor; }
123  [[nodiscard]] CartridgeSlotManager& getSlotManager() { return *slotManager; }
124  [[nodiscard]] RealTime& getRealTime() { return *realTime; }
125  [[nodiscard]] Debugger& getDebugger() { return *debugger; }
126  [[nodiscard]] MSXMixer& getMSXMixer() { return *msxMixer; }
127  [[nodiscard]] PluggingController& getPluggingController();
128  [[nodiscard]] MSXCPU& getCPU();
129  [[nodiscard]] MSXCPUInterface& getCPUInterface();
130  [[nodiscard]] PanasonicMemory& getPanasonicMemory();
131  [[nodiscard]] MSXDeviceSwitch& getDeviceSwitch();
132  [[nodiscard]] CassettePortInterface& getCassettePort();
133  [[nodiscard]] JoystickPortIf& getJoystickPort(unsigned port);
134  [[nodiscard]] RenShaTurbo& getRenShaTurbo();
135  [[nodiscard]] LedStatus& getLedStatus();
136  [[nodiscard]] ReverseManager& getReverseManager() { return *reverseManager; }
137  [[nodiscard]] Reactor& getReactor() { return reactor; }
138  [[nodiscard]] VideoSourceSetting& getVideoSource() { return videoSourceSetting; }
139 
140  // convenience methods
141  [[nodiscard]] CommandController& getCommandController();
142  [[nodiscard]] InfoCommand& getMachineInfoCommand();
143 
146  [[nodiscard]] EmuTime::param getCurrentTime();
147 
150  void addDevice(MSXDevice& device);
151  void removeDevice(MSXDevice& device);
152 
159  [[nodiscard]] MSXDevice* findDevice(std::string_view name);
160 
169  template<typename T, typename ... Args>
170  [[nodiscard]] std::shared_ptr<T> getSharedStuff(std::string_view name, Args&& ...args)
171  {
172  auto& weak = sharedStuffMap[name];
173  auto shared = std::static_pointer_cast<T>(weak.lock());
174  if (shared) return shared;
175 
176  shared = std::make_shared<T>(std::forward<Args>(args)...);
177  weak = shared;
178  return shared;
179  }
180 
184  [[nodiscard]] MSXMapperIO& createMapperIO();
185  [[nodiscard]] MSXMapperIO& getMapperIO() const
186  {
187  assert(mapperIOCounter);
188  return *mapperIO;
189  }
190  void destroyMapperIO();
191 
199  [[nodiscard]] std::string getUserName(const std::string& hwName);
200  void freeUserName(const std::string& hwName, const std::string& userName);
201 
202  template<typename Archive>
203  void serialize(Archive& ar, unsigned version);
204 
205 private:
206  void powerDown();
207  void deleteMachine();
208 
209 private:
210  Reactor& reactor;
211  std::string machineID;
212  std::string machineName;
213 
214  std::vector<MSXDevice*> availableDevices; // no ownership, no order
215 
218 
219  std::unique_ptr<MSXMapperIO> mapperIO;
220  unsigned mapperIOCounter;
221 
222  // These two should normally be the same, only during savestate loading
223  // machineConfig will already be filled in, but machineConfig2 not yet.
224  // This is important when an exception happens during loading of
225  // machineConfig2 (otherwise machineConfig2 gets deleted twice).
226  // See also HardwareConfig::serialize() and setMachineConfig()
227  std::unique_ptr<HardwareConfig> machineConfig2;
228  HardwareConfig* machineConfig;
229 
230  Extensions extensions; // order matters: later extension might depend on earlier ones
231 
232  // order of unique_ptr's is important!
233  std::unique_ptr<AddRemoveUpdate> addRemoveUpdate;
234  std::unique_ptr<MSXCliComm> msxCliComm;
235  std::unique_ptr<MSXEventDistributor> msxEventDistributor;
236  std::unique_ptr<StateChangeDistributor> stateChangeDistributor;
237  std::unique_ptr<MSXCommandController> msxCommandController;
238  std::unique_ptr<Scheduler> scheduler;
239  std::unique_ptr<EventDelay> eventDelay;
240  std::unique_ptr<RealTime> realTime;
241  std::unique_ptr<Debugger> debugger;
242  std::unique_ptr<MSXMixer> msxMixer;
243  std::unique_ptr<PluggingController> pluggingController;
244  std::unique_ptr<MSXCPU> msxCpu;
245  std::unique_ptr<MSXCPUInterface> msxCpuInterface;
246  std::unique_ptr<PanasonicMemory> panasonicMemory;
247  std::unique_ptr<MSXDeviceSwitch> deviceSwitch;
248  std::unique_ptr<CassettePortInterface> cassettePort;
249  std::unique_ptr<JoystickPortIf> joystickPort[2];
250  std::unique_ptr<JoyPortDebuggable> joyPortDebuggable;
251  std::unique_ptr<RenShaTurbo> renShaTurbo;
252  std::unique_ptr<LedStatus> ledStatus;
253  VideoSourceSetting videoSourceSetting;
254 
255  std::unique_ptr<CartridgeSlotManager> slotManager;
256  std::unique_ptr<ReverseManager> reverseManager;
257  std::unique_ptr<ResetCmd> resetCommand;
258  std::unique_ptr<LoadMachineCmd> loadMachineCommand;
259  std::unique_ptr<ListExtCmd> listExtCommand;
260  std::unique_ptr<ExtCmd> extCommand;
261  std::unique_ptr<RemoveExtCmd> removeExtCommand;
262  std::unique_ptr<MachineNameInfo> machineNameInfo;
263  std::unique_ptr<MachineTypeInfo> machineTypeInfo;
264  std::unique_ptr<MachineExtensionInfo> machineExtensionInfo;
265  std::unique_ptr<DeviceInfo> deviceInfo;
266  friend class DeviceInfo;
267 
268  std::unique_ptr<FastForwardHelper> fastForwardHelper;
269 
270  std::unique_ptr<SettingObserver> settingObserver;
271  friend class SettingObserver;
272  BooleanSetting& powerSetting;
273 
274  bool powered;
275  bool active;
276  bool fastForwarding;
277 };
279 
280 class ExtCmd final : public RecordedCommand
281 {
282 public:
283  ExtCmd(MSXMotherBoard& motherBoard, std::string commandName);
284  void execute(span<const TclObject> tokens, TclObject& result,
285  EmuTime::param time) override;
286  [[nodiscard]] std::string help(span<const TclObject> tokens) const override;
287  void tabCompletion(std::vector<std::string>& tokens) const override;
288 private:
289  MSXMotherBoard& motherBoard;
290  std::string commandName;
291 };
292 
293 } // namespace openmsx
294 
295 #endif
std::string help(span< const TclObject > tokens) const override
Print help for this command.
void tabCompletion(std::vector< std::string > &tokens) const override
Attempt tab completion for this command.
ExtCmd(MSXMotherBoard &motherBoard, std::string commandName)
void execute(span< const TclObject > tokens, TclObject &result, EmuTime::param time) override
This is like the execute() method of the Command class, it only has an extra time parameter.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:33
StateChangeDistributor & getStateChangeDistributor()
HardwareConfig * findExtension(std::string_view extensionName)
PluggingController & getPluggingController()
void activate(bool active)
void setMachineConfig(HardwareConfig *machineConfig)
RenShaTurbo & getRenShaTurbo()
void freeUserName(const std::string &hwName, const std::string &userName)
bool execute()
Run emulation.
MSXCPUInterface & getCPUInterface()
std::string getUserName(const std::string &hwName)
Keep track of which 'usernames' are in use.
EmuTime::param getCurrentTime()
Convenience method: This is the same as getScheduler().getCurrentTime().
VideoSourceSetting & getVideoSource()
CartridgeSlotManager & getSlotManager()
std::string loadMachine(const std::string &machine)
std::string_view getMachineName() const
ReverseManager & getReverseManager()
MSXEventDistributor & getMSXEventDistributor()
MSXMapperIO & getMapperIO() const
std::vector< std::unique_ptr< HardwareConfig > > Extensions
MSXDevice * findDevice(std::string_view name)
Find a MSXDevice by name.
CommandController & getCommandController()
void pause()
Pause MSX machine.
const Extensions & getExtensions() const
std::string insertExtension(std::string_view name, std::unique_ptr< HardwareConfig > extension)
void fastForward(EmuTime::param time, bool fast)
Run emulation until a certain time in fast forward mode.
void exitCPULoopAsync()
See CPU::exitCPULoopAsync().
MSXMotherBoard(const MSXMotherBoard &)=delete
bool isFastForwarding() const
MSXDeviceSwitch & getDeviceSwitch()
void serialize(Archive &ar, unsigned version)
void removeDevice(MSXDevice &device)
std::string_view getMachineID() const
MSXCommandController & getMSXCommandController()
MSXMotherBoard & operator=(const MSXMotherBoard &)=delete
const HardwareConfig * getMachineConfig() const
void removeExtension(const HardwareConfig &extension)
HardwareConfig * getMachineConfig()
JoystickPortIf & getJoystickPort(unsigned port)
std::string loadExtension(std::string_view extensionName, std::string_view slotname)
std::string_view getMachineType() const
std::shared_ptr< T > getSharedStuff(std::string_view name, Args &&...args)
Some MSX device parts are shared between several MSX devices (e.g.
CassettePortInterface & getCassettePort()
void addDevice(MSXDevice &device)
All MSXDevices should be registered by the MotherBoard.
PanasonicMemory & getPanasonicMemory()
MSXMapperIO & createMapperIO()
All memory mappers in one MSX machine share the same four (logical) memory mapper registers.
InfoCommand & getMachineInfoCommand()
Central administration of Connectors and Pluggables.
Contains the main loop of openMSX.
Definition: Reactor.hh:68
Commands that directly influence the MSX state should send and events so that they can be recorded by...
Ren-Sha Turbo is the autofire in several MSX 2+ models and in the MSX turbo R.
Definition: RenShaTurbo.hh:21
Definition: span.hh:126
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)