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