openMSX
MSXMotherBoard.hh
Go to the documentation of this file.
1#ifndef MSXMOTHERBOARD_HH
2#define MSXMOTHERBOARD_HH
3
4#include "BooleanSetting.hh"
5#include "EmuTime.hh"
6#include "RecordedCommand.hh"
8#include "hash_map.hh"
9#include "openmsx.hh"
10#include "serialize_meta.hh"
11#include "xxhash.hh"
12
13#include <array>
14#include <cassert>
15#include <memory>
16#include <string_view>
17#include <vector>
18
19namespace openmsx {
20
21class AddRemoveUpdate;
22class CartridgeSlotManager;
23class CassettePortInterface;
24class CommandController;
25class Debugger;
26class DeviceInfo;
27class EventDelay;
28class ExtCmd;
29class FastForwardHelper;
30class HardwareConfig;
31class InfoCommand;
32class JoyPortDebuggable;
33class JoystickPortIf;
34class Keyboard;
35class LedStatus;
36class ListExtCmd;
37class LoadMachineCmd;
38class MachineExtensionInfo;
39class MachineMediaInfo;
40class MachineNameInfo;
41class MachineTypeInfo;
42class MSXCliComm;
43class MSXCommandController;
44class MSXCPU;
45class MSXCPUInterface;
46class MSXDevice;
47class MSXDeviceSwitch;
48class MSXEventDistributor;
49class MSXMapperIO;
50class MSXMixer;
51class PanasonicMemory;
52class PluggingController;
53class Reactor;
54class RealTime;
55class RemoveExtCmd;
56class RenShaTurbo;
57class ResetCmd;
58class ReverseManager;
59class SettingObserver;
60class Scheduler;
61class StateChangeDistributor;
62
64{
65public:
70
75 virtual void getMediaInfo(TclObject& result) = 0;
76
77protected:
78 MediaInfoProvider() = default;
79 ~MediaInfoProvider() = default;
80};
81
82
83class MSXMotherBoard final
84{
85public:
90
91 explicit MSXMotherBoard(Reactor& reactor);
93
94 [[nodiscard]] std::string_view getMachineID() const { return machineID; }
95 [[nodiscard]] std::string_view getMachineName() const { return machineName; }
96
101 [[nodiscard]] bool execute();
102
105 void fastForward(EmuTime::param time, bool fast);
106
108 void exitCPULoopAsync();
109 void exitCPULoopSync();
110
114 void pause();
115 void unpause();
116
117 void powerUp();
118 [[nodiscard]] bool isPowered() const { return powered; }
119
120 void doReset();
121 void activate(bool active);
122 [[nodiscard]] bool isActive() const { return active; }
123 [[nodiscard]] bool isFastForwarding() const { return fastForwarding; }
124
125 [[nodiscard]] byte readIRQVector() const;
126
127 [[nodiscard]] const HardwareConfig* getMachineConfig() const { return machineConfig; }
128 [[nodiscard]] HardwareConfig* getMachineConfig() { return machineConfig; }
129 void setMachineConfig(HardwareConfig* machineConfig);
130 [[nodiscard]] std::string_view getMachineType() const;
131 [[nodiscard]] bool isTurboR() const;
132 [[nodiscard]] bool hasToshibaEngine() const;
133
134 std::string loadMachine(const std::string& machine);
135
136 using Extensions = std::vector<std::unique_ptr<HardwareConfig>>;
137 [[nodiscard]] const Extensions& getExtensions() const { return extensions; }
138 [[nodiscard]] HardwareConfig* findExtension(std::string_view extensionName);
139 std::unique_ptr<HardwareConfig> loadExtension(std::string_view extensionName, std::string_view slotName);
140 std::string insertExtension(std::string_view name,
141 std::unique_ptr<HardwareConfig> extension);
142 void removeExtension(const HardwareConfig& extension);
143
144 // The following classes are unique per MSX machine
145 [[nodiscard]] MSXCliComm& getMSXCliComm();
146 [[nodiscard]] MSXCommandController& getMSXCommandController() { return *msxCommandController; }
147 [[nodiscard]] Scheduler& getScheduler() { return *scheduler; }
148 [[nodiscard]] MSXEventDistributor& getMSXEventDistributor() { return *msxEventDistributor; }
149 [[nodiscard]] StateChangeDistributor& getStateChangeDistributor() { return *stateChangeDistributor; }
150 [[nodiscard]] CartridgeSlotManager& getSlotManager() { return *slotManager; }
151 [[nodiscard]] RealTime& getRealTime() { return *realTime; }
152 [[nodiscard]] Debugger& getDebugger() { return *debugger; }
153 [[nodiscard]] MSXMixer& getMSXMixer() { return *msxMixer; }
155 [[nodiscard]] MSXCPU& getCPU();
156 [[nodiscard]] MSXCPUInterface& getCPUInterface();
157 [[nodiscard]] PanasonicMemory& getPanasonicMemory();
158 [[nodiscard]] MSXDeviceSwitch& getDeviceSwitch();
159 [[nodiscard]] CassettePortInterface& getCassettePort();
160 [[nodiscard]] JoystickPortIf& getJoystickPort(unsigned port);
161 [[nodiscard]] RenShaTurbo& getRenShaTurbo();
162 [[nodiscard]] LedStatus& getLedStatus();
163 [[nodiscard]] ReverseManager& getReverseManager() { return *reverseManager; }
164 [[nodiscard]] Reactor& getReactor() { return reactor; }
165 [[nodiscard]] VideoSourceSetting& getVideoSource() { return videoSourceSetting; }
166 [[nodiscard]] BooleanSetting& suppressMessages() { return suppressMessagesSetting; }
167
168 // convenience methods
170 [[nodiscard]] InfoCommand& getMachineInfoCommand();
171
174 [[nodiscard]] EmuTime::param getCurrentTime() const;
175
178 void addDevice(MSXDevice& device);
179 void removeDevice(MSXDevice& device);
180
187 [[nodiscard]] MSXDevice* findDevice(std::string_view name);
188
197 template<typename T, typename ... Args>
198 [[nodiscard]] std::shared_ptr<T> getSharedStuff(std::string_view name, Args&& ...args)
199 {
200 auto& weak = sharedStuffMap[name];
201 auto shared = std::static_pointer_cast<T>(weak.lock());
202 if (shared) return shared;
203
204 shared = std::make_shared<T>(std::forward<Args>(args)...);
205 weak = shared;
206 return shared;
207 }
208
212 [[nodiscard]] MSXMapperIO& createMapperIO();
213 [[nodiscard]] MSXMapperIO& getMapperIO() const
214 {
215 assert(mapperIOCounter);
216 return *mapperIO;
217 }
218 void destroyMapperIO();
219
227 [[nodiscard]] std::string getUserName(const std::string& hwName);
228 void freeUserName(const std::string& hwName, const std::string& userName);
229
233 void registerMediaInfo(std::string_view name, MediaInfoProvider& provider);
235
236 void registerKeyboard(Keyboard& keyboard) {
237 // Typically there's only 1 keyboard, but we shouldn't crash on
238 // configurations that artificially use 2 MSXPPI devices.
239 keyboards.push_back(&keyboard);
240 }
241 void unregisterKeyboard(Keyboard& keyboard) {
242 auto it = find_unguarded(keyboards, &keyboard);
243 keyboards.erase(it);
244 }
245 [[nodiscard]] Keyboard* getKeyboard() const {
246 // Typically there's exactly 1 keyboard, except for early during
247 // machine construction, or on artificial machine configs
248 // without MSXPPI (they don't make sense, but we shouldn't crash
249 // on it).
250 return keyboards.empty() ? nullptr : keyboards.front();
251 }
252
253 template<typename Archive>
254 void serialize(Archive& ar, unsigned version);
255
256private:
257 void powerDown();
258 void deleteMachine();
259
260private:
261 Reactor& reactor;
262 std::string machineID;
263 std::string machineName;
264
265 std::vector<MSXDevice*> availableDevices; // no ownership, no order
266
269
270 std::unique_ptr<MSXMapperIO> mapperIO;
271 unsigned mapperIOCounter = 0;
272
273 // These two should normally be the same, only during savestate loading
274 // machineConfig will already be filled in, but machineConfig2 not yet.
275 // This is important when an exception happens during loading of
276 // machineConfig2 (otherwise machineConfig2 gets deleted twice).
277 // See also HardwareConfig::serialize() and setMachineConfig()
278 std::unique_ptr<HardwareConfig> machineConfig2;
279 HardwareConfig* machineConfig = nullptr;
280
281 Extensions extensions; // order matters: later extension might depend on earlier ones
282
283 // order of unique_ptr's is important!
284 std::unique_ptr<AddRemoveUpdate> addRemoveUpdate;
285 std::unique_ptr<MSXCliComm> msxCliComm;
286 std::unique_ptr<MSXEventDistributor> msxEventDistributor;
287 std::unique_ptr<StateChangeDistributor> stateChangeDistributor;
288 std::unique_ptr<MSXCommandController> msxCommandController;
289 std::unique_ptr<Scheduler> scheduler;
290 std::unique_ptr<EventDelay> eventDelay;
291 std::unique_ptr<RealTime> realTime;
292 std::unique_ptr<Debugger> debugger;
293 std::unique_ptr<MSXMixer> msxMixer;
294 // machineMediaInfo must be BEFORE PluggingController!
295 std::unique_ptr<MachineMediaInfo> machineMediaInfo;
296 std::unique_ptr<PluggingController> pluggingController;
297 std::unique_ptr<MSXCPU> msxCpu;
298 std::unique_ptr<MSXCPUInterface> msxCpuInterface;
299 std::unique_ptr<PanasonicMemory> panasonicMemory;
300 std::unique_ptr<MSXDeviceSwitch> deviceSwitch;
301 std::unique_ptr<CassettePortInterface> cassettePort;
302 std::array<std::unique_ptr<JoystickPortIf>, 2> joystickPort;
303 std::unique_ptr<JoyPortDebuggable> joyPortDebuggable;
304 std::unique_ptr<RenShaTurbo> renShaTurbo;
305 std::unique_ptr<LedStatus> ledStatus;
306 VideoSourceSetting videoSourceSetting;
307 BooleanSetting suppressMessagesSetting;
308
309 std::unique_ptr<CartridgeSlotManager> slotManager;
310 std::unique_ptr<ReverseManager> reverseManager;
311 std::unique_ptr<ResetCmd> resetCommand;
312 std::unique_ptr<LoadMachineCmd> loadMachineCommand;
313 std::unique_ptr<ListExtCmd> listExtCommand;
314 std::unique_ptr<ExtCmd> extCommand;
315 std::unique_ptr<RemoveExtCmd> removeExtCommand;
316 std::unique_ptr<MachineNameInfo> machineNameInfo;
317 std::unique_ptr<MachineTypeInfo> machineTypeInfo;
318 std::unique_ptr<MachineExtensionInfo> machineExtensionInfo;
319 std::unique_ptr<DeviceInfo> deviceInfo;
320 friend class DeviceInfo;
321
322 std::unique_ptr<FastForwardHelper> fastForwardHelper;
323
324 std::unique_ptr<SettingObserver> settingObserver;
325 friend class SettingObserver;
326 BooleanSetting& powerSetting;
327
328 std::vector<Keyboard*> keyboards; // typically contains exactly 1 item
329
330 bool powered = false;
331 bool active = false;
332 bool fastForwarding = false;
333};
335
336class ExtCmd final : public RecordedCommand
337{
338public:
339 ExtCmd(MSXMotherBoard& motherBoard, std::string commandName);
340 void execute(std::span<const TclObject> tokens, TclObject& result,
341 EmuTime::param time) override;
342 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
343 void tabCompletion(std::vector<std::string>& tokens) const override;
344private:
345 MSXMotherBoard& motherBoard;
346 std::string commandName;
347};
348
349} // namespace openmsx
350
351#endif
void tabCompletion(std::vector< std::string > &tokens) const override
Attempt tab completion for this command.
void execute(std::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.
std::string help(std::span< const TclObject > tokens) const override
Print help for this command.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
HardwareConfig * findExtension(std::string_view extensionName)
PluggingController & getPluggingController()
VideoSourceSetting & getVideoSource()
void activate(bool active)
void setMachineConfig(HardwareConfig *machineConfig)
std::shared_ptr< T > getSharedStuff(std::string_view name, Args &&...args)
Some MSX device parts are shared between several MSX devices (e.g.
RenShaTurbo & getRenShaTurbo()
void freeUserName(const std::string &hwName, const std::string &userName)
bool execute()
Run emulation.
EmuTime::param getCurrentTime() const
Convenience method: This is the same as getScheduler().getCurrentTime().
const HardwareConfig * getMachineConfig() const
MSXMotherBoard(MSXMotherBoard &&)=delete
MSXCPUInterface & getCPUInterface()
MSXEventDistributor & getMSXEventDistributor()
std::unique_ptr< HardwareConfig > loadExtension(std::string_view extensionName, std::string_view slotName)
void registerKeyboard(Keyboard &keyboard)
std::string loadMachine(const std::string &machine)
std::string_view getMachineName() const
StateChangeDistributor & getStateChangeDistributor()
HardwareConfig * getMachineConfig()
void registerMediaInfo(std::string_view name, MediaInfoProvider &provider)
Register and unregister providers of media info, for the media info topic.
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.
Keyboard * getKeyboard() 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().
void unregisterKeyboard(Keyboard &keyboard)
MSXMapperIO & getMapperIO() const
MSXMotherBoard(const MSXMotherBoard &)=delete
void unregisterMediaInfo(MediaInfoProvider &provider)
BooleanSetting & suppressMessages()
MSXMotherBoard & operator=(MSXMotherBoard &&)=delete
MSXDeviceSwitch & getDeviceSwitch()
void serialize(Archive &ar, unsigned version)
CartridgeSlotManager & getSlotManager()
void removeDevice(MSXDevice &device)
std::string_view getMachineID() const
MSXMotherBoard & operator=(const MSXMotherBoard &)=delete
void removeExtension(const HardwareConfig &extension)
ReverseManager & getReverseManager()
JoystickPortIf & getJoystickPort(unsigned port)
std::string_view getMachineType() const
MSXCommandController & getMSXCommandController()
const Extensions & getExtensions() const
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()
MediaInfoProvider(const MediaInfoProvider &)=delete
virtual void getMediaInfo(TclObject &result)=0
This method gets called when information is required on the media inserted in the media slot of the p...
MediaInfoProvider & operator=(const MediaInfoProvider &)=delete
MediaInfoProvider & operator=(MediaInfoProvider &&)=delete
MediaInfoProvider(MediaInfoProvider &&)=delete
Central administration of Connectors and Pluggables.
Contains the main loop of openMSX.
Definition Reactor.hh:75
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.
This file implemented 3 utility functions:
Definition Autofire.cc:11
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)
ITER find_unguarded(ITER first, ITER last, const VAL &val, Proj proj={})
Faster alternative to 'find' when it's guaranteed that the value will be found (if not the behavior i...
Definition stl.hh:72