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  [[nodiscard]] bool hasToshibaEngine() const;
107 
108  std::string loadMachine(const std::string& machine);
109 
110  using Extensions = std::vector<std::unique_ptr<HardwareConfig>>;
111  [[nodiscard]] const Extensions& getExtensions() const { return extensions; }
112  [[nodiscard]] HardwareConfig* findExtension(std::string_view extensionName);
113  std::string loadExtension(std::string_view extensionName, std::string_view slotname);
114  std::string insertExtension(std::string_view name,
115  std::unique_ptr<HardwareConfig> extension);
116  void removeExtension(const HardwareConfig& extension);
117 
118  // The following classes are unique per MSX machine
119  [[nodiscard]] CliComm& getMSXCliComm();
120  [[nodiscard]] MSXCommandController& getMSXCommandController() { return *msxCommandController; }
121  [[nodiscard]] Scheduler& getScheduler() { return *scheduler; }
122  [[nodiscard]] MSXEventDistributor& getMSXEventDistributor() { return *msxEventDistributor; }
123  [[nodiscard]] StateChangeDistributor& getStateChangeDistributor() { return *stateChangeDistributor; }
124  [[nodiscard]] CartridgeSlotManager& getSlotManager() { return *slotManager; }
125  [[nodiscard]] RealTime& getRealTime() { return *realTime; }
126  [[nodiscard]] Debugger& getDebugger() { return *debugger; }
127  [[nodiscard]] MSXMixer& getMSXMixer() { return *msxMixer; }
128  [[nodiscard]] PluggingController& getPluggingController();
129  [[nodiscard]] MSXCPU& getCPU();
130  [[nodiscard]] MSXCPUInterface& getCPUInterface();
131  [[nodiscard]] PanasonicMemory& getPanasonicMemory();
132  [[nodiscard]] MSXDeviceSwitch& getDeviceSwitch();
133  [[nodiscard]] CassettePortInterface& getCassettePort();
134  [[nodiscard]] JoystickPortIf& getJoystickPort(unsigned port);
135  [[nodiscard]] RenShaTurbo& getRenShaTurbo();
136  [[nodiscard]] LedStatus& getLedStatus();
137  [[nodiscard]] ReverseManager& getReverseManager() { return *reverseManager; }
138  [[nodiscard]] Reactor& getReactor() { return reactor; }
139  [[nodiscard]] VideoSourceSetting& getVideoSource() { return videoSourceSetting; }
140 
141  // convenience methods
142  [[nodiscard]] CommandController& getCommandController();
143  [[nodiscard]] InfoCommand& getMachineInfoCommand();
144 
147  [[nodiscard]] EmuTime::param getCurrentTime();
148 
151  void addDevice(MSXDevice& device);
152  void removeDevice(MSXDevice& device);
153 
160  [[nodiscard]] MSXDevice* findDevice(std::string_view name);
161 
170  template<typename T, typename ... Args>
171  [[nodiscard]] std::shared_ptr<T> getSharedStuff(std::string_view name, Args&& ...args)
172  {
173  auto& weak = sharedStuffMap[name];
174  auto shared = std::static_pointer_cast<T>(weak.lock());
175  if (shared) return shared;
176 
177  shared = std::make_shared<T>(std::forward<Args>(args)...);
178  weak = shared;
179  return shared;
180  }
181 
185  [[nodiscard]] MSXMapperIO& createMapperIO();
186  [[nodiscard]] MSXMapperIO& getMapperIO() const
187  {
188  assert(mapperIOCounter);
189  return *mapperIO;
190  }
191  void destroyMapperIO();
192 
200  [[nodiscard]] std::string getUserName(const std::string& hwName);
201  void freeUserName(const std::string& hwName, const std::string& userName);
202 
203  template<typename Archive>
204  void serialize(Archive& ar, unsigned version);
205 
206 private:
207  void powerDown();
208  void deleteMachine();
209 
210 private:
211  Reactor& reactor;
212  std::string machineID;
213  std::string machineName;
214 
215  std::vector<MSXDevice*> availableDevices; // no ownership, no order
216 
219 
220  std::unique_ptr<MSXMapperIO> mapperIO;
221  unsigned mapperIOCounter;
222 
223  // These two should normally be the same, only during savestate loading
224  // machineConfig will already be filled in, but machineConfig2 not yet.
225  // This is important when an exception happens during loading of
226  // machineConfig2 (otherwise machineConfig2 gets deleted twice).
227  // See also HardwareConfig::serialize() and setMachineConfig()
228  std::unique_ptr<HardwareConfig> machineConfig2;
229  HardwareConfig* machineConfig;
230 
231  Extensions extensions; // order matters: later extension might depend on earlier ones
232 
233  // order of unique_ptr's is important!
234  std::unique_ptr<AddRemoveUpdate> addRemoveUpdate;
235  std::unique_ptr<MSXCliComm> msxCliComm;
236  std::unique_ptr<MSXEventDistributor> msxEventDistributor;
237  std::unique_ptr<StateChangeDistributor> stateChangeDistributor;
238  std::unique_ptr<MSXCommandController> msxCommandController;
239  std::unique_ptr<Scheduler> scheduler;
240  std::unique_ptr<EventDelay> eventDelay;
241  std::unique_ptr<RealTime> realTime;
242  std::unique_ptr<Debugger> debugger;
243  std::unique_ptr<MSXMixer> msxMixer;
244  std::unique_ptr<PluggingController> pluggingController;
245  std::unique_ptr<MSXCPU> msxCpu;
246  std::unique_ptr<MSXCPUInterface> msxCpuInterface;
247  std::unique_ptr<PanasonicMemory> panasonicMemory;
248  std::unique_ptr<MSXDeviceSwitch> deviceSwitch;
249  std::unique_ptr<CassettePortInterface> cassettePort;
250  std::unique_ptr<JoystickPortIf> joystickPort[2];
251  std::unique_ptr<JoyPortDebuggable> joyPortDebuggable;
252  std::unique_ptr<RenShaTurbo> renShaTurbo;
253  std::unique_ptr<LedStatus> ledStatus;
254  VideoSourceSetting videoSourceSetting;
255 
256  std::unique_ptr<CartridgeSlotManager> slotManager;
257  std::unique_ptr<ReverseManager> reverseManager;
258  std::unique_ptr<ResetCmd> resetCommand;
259  std::unique_ptr<LoadMachineCmd> loadMachineCommand;
260  std::unique_ptr<ListExtCmd> listExtCommand;
261  std::unique_ptr<ExtCmd> extCommand;
262  std::unique_ptr<RemoveExtCmd> removeExtCommand;
263  std::unique_ptr<MachineNameInfo> machineNameInfo;
264  std::unique_ptr<MachineTypeInfo> machineTypeInfo;
265  std::unique_ptr<MachineExtensionInfo> machineExtensionInfo;
266  std::unique_ptr<DeviceInfo> deviceInfo;
267  friend class DeviceInfo;
268 
269  std::unique_ptr<FastForwardHelper> fastForwardHelper;
270 
271  std::unique_ptr<SettingObserver> settingObserver;
272  friend class SettingObserver;
273  BooleanSetting& powerSetting;
274 
275  bool powered;
276  bool active;
277  bool fastForwarding;
278 };
280 
281 class ExtCmd final : public RecordedCommand
282 {
283 public:
284  ExtCmd(MSXMotherBoard& motherBoard, std::string commandName);
285  void execute(span<const TclObject> tokens, TclObject& result,
286  EmuTime::param time) override;
287  [[nodiscard]] std::string help(span<const TclObject> tokens) const override;
288  void tabCompletion(std::vector<std::string>& tokens) const override;
289 private:
290  MSXMotherBoard& motherBoard;
291  std::string commandName;
292 };
293 
294 } // namespace openmsx
295 
296 #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)