openMSX
MSXMotherBoard.cc
Go to the documentation of this file.
1 #include "MSXMotherBoard.hh"
2 #include "Reactor.hh"
3 #include "MSXDevice.hh"
4 #include "ReverseManager.hh"
5 #include "HardwareConfig.hh"
6 #include "ConfigException.hh"
7 #include "XMLElement.hh"
8 #include "MSXCliComm.hh"
9 #include "GlobalCliComm.hh"
10 #include "MSXCommandController.hh"
11 #include "Scheduler.hh"
12 #include "Schedulable.hh"
13 #include "CartridgeSlotManager.hh"
14 #include "EventDistributor.hh"
15 #include "Debugger.hh"
16 #include "SimpleDebuggable.hh"
17 #include "MSXMixer.hh"
18 #include "PluggingController.hh"
19 #include "MSXCPUInterface.hh"
20 #include "MSXCPU.hh"
21 #include "PanasonicMemory.hh"
22 #include "MSXDeviceSwitch.hh"
23 #include "MSXMapperIO.hh"
24 #include "CassettePort.hh"
25 #include "JoystickPort.hh"
26 #include "RenShaTurbo.hh"
27 #include "LedStatus.hh"
28 #include "MSXEventDistributor.hh"
30 #include "EventDelay.hh"
31 #include "RealTime.hh"
32 #include "DeviceFactory.hh"
33 #include "BooleanSetting.hh"
34 #include "GlobalSettings.hh"
35 #include "Command.hh"
36 #include "CommandException.hh"
37 #include "InfoTopic.hh"
38 #include "FileException.hh"
39 #include "TclObject.hh"
40 #include "Observer.hh"
41 #include "serialize.hh"
42 #include "serialize_stl.hh"
43 #include "ScopedAssign.hh"
44 #include "one_of.hh"
45 #include "ranges.hh"
46 #include "stl.hh"
47 #include "unreachable.hh"
48 #include "view.hh"
49 #include <cassert>
50 #include <functional>
51 #include <iostream>
52 #include <memory>
53 
54 using std::make_unique;
55 using std::string;
56 using std::unique_ptr;
57 using std::vector;
58 
59 namespace openmsx {
60 
62 {
63 public:
64  explicit AddRemoveUpdate(MSXMotherBoard& motherBoard);
66 private:
67  MSXMotherBoard& motherBoard;
68 };
69 
70 class ResetCmd final : public RecordedCommand
71 {
72 public:
73  explicit ResetCmd(MSXMotherBoard& motherBoard);
74  void execute(span<const TclObject> tokens, TclObject& result,
75  EmuTime::param time) override;
76  string help(const vector<string>& tokens) const override;
77 private:
78  MSXMotherBoard& motherBoard;
79 };
80 
81 class LoadMachineCmd final : public Command
82 {
83 public:
84  explicit LoadMachineCmd(MSXMotherBoard& motherBoard);
85  void execute(span<const TclObject> tokens, TclObject& result) override;
86  string help(const vector<string>& tokens) const override;
87  void tabCompletion(vector<string>& tokens) const override;
88 private:
89  MSXMotherBoard& motherBoard;
90 };
91 
92 class ListExtCmd final : public Command
93 {
94 public:
95  explicit ListExtCmd(MSXMotherBoard& motherBoard);
96  void execute(span<const TclObject> tokens, TclObject& result) override;
97  string help(const vector<string>& tokens) const override;
98 private:
99  MSXMotherBoard& motherBoard;
100 };
101 
102 class RemoveExtCmd final : public RecordedCommand
103 {
104 public:
105  explicit RemoveExtCmd(MSXMotherBoard& motherBoard);
106  void execute(span<const TclObject> tokens, TclObject& result,
107  EmuTime::param time) override;
108  string help(const vector<string>& tokens) const override;
109  void tabCompletion(vector<string>& tokens) const override;
110 private:
111  MSXMotherBoard& motherBoard;
112 };
113 
114 class MachineNameInfo final : public InfoTopic
115 {
116 public:
117  explicit MachineNameInfo(MSXMotherBoard& motherBoard);
118  void execute(span<const TclObject> tokens,
119  TclObject& result) const override;
120  string help(const vector<string>& tokens) const override;
121 private:
122  MSXMotherBoard& motherBoard;
123 };
124 
125 class MachineTypeInfo final : public InfoTopic
126 {
127 public:
128  explicit MachineTypeInfo(MSXMotherBoard& motherBoard);
129  void execute(span<const TclObject> tokens,
130  TclObject& result) const override;
131  string help(const vector<string>& tokens) const override;
132 private:
133  MSXMotherBoard& motherBoard;
134 };
135 
136 class DeviceInfo final : public InfoTopic
137 {
138 public:
139  explicit DeviceInfo(MSXMotherBoard& motherBoard);
140  void execute(span<const TclObject> tokens,
141  TclObject& result) const override;
142  string help(const vector<string>& tokens) const override;
143  void tabCompletion(vector<string>& tokens) const override;
144 private:
145  MSXMotherBoard& motherBoard;
146 };
147 
148 class FastForwardHelper final : private Schedulable
149 {
150 public:
151  explicit FastForwardHelper(MSXMotherBoard& motherBoard);
152  void setTarget(EmuTime::param targetTime);
153 private:
154  void executeUntil(EmuTime::param time) override;
155  MSXMotherBoard& motherBoard;
156 };
157 
159 {
160 public:
161  explicit JoyPortDebuggable(MSXMotherBoard& motherBoard);
162  byte read(unsigned address, EmuTime::param time) override;
163  void write(unsigned address, byte value) override;
164 };
165 
166 class SettingObserver final : public Observer<Setting>
167 {
168 public:
169  explicit SettingObserver(MSXMotherBoard& motherBoard);
170  void update(const Setting& setting) override;
171 private:
172  MSXMotherBoard& motherBoard;
173 };
174 
175 
176 static unsigned machineIDCounter = 0;
177 
179  : reactor(reactor_)
180  , machineID(strCat("machine", ++machineIDCounter))
181  , mapperIOCounter(0)
182  , machineConfig(nullptr)
183  , msxCliComm(make_unique<MSXCliComm>(*this, reactor.getGlobalCliComm()))
184  , msxEventDistributor(make_unique<MSXEventDistributor>())
185  , stateChangeDistributor(make_unique<StateChangeDistributor>())
186  , msxCommandController(make_unique<MSXCommandController>(
187  reactor.getGlobalCommandController(), reactor,
188  *this, *msxEventDistributor, machineID))
189  , scheduler(make_unique<Scheduler>())
190  , msxMixer(make_unique<MSXMixer>(
191  reactor.getMixer(), *this,
192  reactor.getGlobalSettings()))
193  , videoSourceSetting(*msxCommandController)
194  , fastForwardHelper(make_unique<FastForwardHelper>(*this))
195  , settingObserver(make_unique<SettingObserver>(*this))
196  , powerSetting(reactor.getGlobalSettings().getPowerSetting())
197  , powered(false)
198  , active(false)
199  , fastForwarding(false)
200 {
201  slotManager = make_unique<CartridgeSlotManager>(*this);
202  reverseManager = make_unique<ReverseManager>(*this);
203  resetCommand = make_unique<ResetCmd>(*this);
204  loadMachineCommand = make_unique<LoadMachineCmd>(*this);
205  listExtCommand = make_unique<ListExtCmd>(*this);
206  extCommand = make_unique<ExtCmd>(*this, "ext");
207  removeExtCommand = make_unique<RemoveExtCmd>(*this);
208  machineNameInfo = make_unique<MachineNameInfo>(*this);
209  machineTypeInfo = make_unique<MachineTypeInfo>(*this);
210  deviceInfo = make_unique<DeviceInfo>(*this);
211  debugger = make_unique<Debugger>(*this);
212 
213  msxMixer->mute(); // powered down
214 
215  // Do this before machine-specific settings are created, otherwise
216  // a setting-info clicomm message is send with a machine id that hasn't
217  // been announced yet over clicomm.
218  addRemoveUpdate = make_unique<AddRemoveUpdate>(*this);
219 
220  // TODO: Initialization of this field cannot be done much earlier because
221  // EventDelay creates a setting, calling getMSXCliComm()
222  // on MSXMotherBoard, so "pimpl" has to be set up already.
223  eventDelay = make_unique<EventDelay>(
224  *scheduler, *msxCommandController,
225  reactor.getEventDistributor(), *msxEventDistributor,
226  *reverseManager);
227  realTime = make_unique<RealTime>(
228  *this, reactor.getGlobalSettings(), *eventDelay);
229 
230  powerSetting.attach(*settingObserver);
231 }
232 
234 {
235  powerSetting.detach(*settingObserver);
236  deleteMachine();
237 
238  assert(mapperIOCounter == 0);
239  assert(availableDevices.empty());
240  assert(extensions.empty());
241  assert(!machineConfig2);
242  assert(!getMachineConfig());
243 }
244 
245 void MSXMotherBoard::deleteMachine()
246 {
247  while (!extensions.empty()) {
248  try {
249  removeExtension(*extensions.back());
250  } catch (MSXException& e) {
251  std::cerr << "Internal error: failed to remove "
252  "extension while deleting a machine: "
253  << e.getMessage() << '\n';
254  UNREACHABLE;
255  }
256  }
257 
258  machineConfig2.reset();
259  machineConfig = nullptr;
260 }
261 
263 {
264  assert(!getMachineConfig());
265  machineConfig = machineConfig_;
266 
267  // make sure the CPU gets instantiated from the main thread
268  assert(!msxCpu);
269  msxCpu = make_unique<MSXCPU>(*this);
270  msxCpuInterface = make_unique<MSXCPUInterface>(*this);
271 }
272 
274 {
275  const HardwareConfig* machine = getMachineConfig();
276  if (machine) {
277  return machine->getConfig().getChild("info").getChildData("type");
278  } else {
279  return "";
280  }
281 }
282 
284 {
285  const HardwareConfig* config = getMachineConfig();
286  assert(config);
287  return config->getConfig().getChild("devices").findChild("S1990") != nullptr;
288 }
289 
290 string MSXMotherBoard::loadMachine(const string& machine)
291 {
292  assert(machineName.empty());
293  assert(extensions.empty());
294  assert(!machineConfig2);
295  assert(!getMachineConfig());
296 
297  try {
298  machineConfig2 = HardwareConfig::createMachineConfig(*this, machine);
299  setMachineConfig(machineConfig2.get());
300  } catch (FileException& e) {
301  throw MSXException("Machine \"", machine, "\" not found: ",
302  e.getMessage());
303  } catch (MSXException& e) {
304  throw MSXException("Error in \"", machine, "\" machine: ",
305  e.getMessage());
306  }
307  try {
308  machineConfig->parseSlots();
309  machineConfig->createDevices();
310  } catch (MSXException& e) {
311  throw MSXException("Error in \"", machine, "\" machine: ",
312  e.getMessage());
313  }
314  if (powerSetting.getBoolean()) {
315  powerUp();
316  }
317  machineName = machine;
318  return machineName;
319 }
320 
321 string MSXMotherBoard::loadExtension(std::string_view name, string slotname)
322 {
323  unique_ptr<HardwareConfig> extension;
324  try {
326  *this, string(name), std::move(slotname));
327  } catch (FileException& e) {
328  throw MSXException(
329  "Extension \"", name, "\" not found: ", e.getMessage());
330  } catch (MSXException& e) {
331  throw MSXException(
332  "Error in \"", name, "\" extension: ", e.getMessage());
333  }
334  return insertExtension(name, std::move(extension));
335 }
336 
338  std::string_view name, unique_ptr<HardwareConfig> extension)
339 {
340  try {
341  extension->parseSlots();
342  extension->createDevices();
343  } catch (MSXException& e) {
344  throw MSXException(
345  "Error in \"", name, "\" extension: ", e.getMessage());
346  }
347  string result = extension->getName();
348  extensions.push_back(std::move(extension));
349  getMSXCliComm().update(CliComm::EXTENSION, result, "add");
350  return result;
351 }
352 
353 HardwareConfig* MSXMotherBoard::findExtension(std::string_view extensionName)
354 {
355  auto it = ranges::find_if(extensions, [&](auto& v) {
356  return v->getName() == extensionName;
357  });
358  return (it != end(extensions)) ? it->get() : nullptr;
359 }
360 
362 {
363  extension.testRemove();
364  getMSXCliComm().update(CliComm::EXTENSION, extension.getName(), "remove");
365  auto it = rfind_if_unguarded(extensions,
366  [&](auto& e) { return e.get() == &extension; });
367  extensions.erase(it);
368 }
369 
371 {
372  return *msxCliComm;
373 }
374 
376 {
377  assert(getMachineConfig()); // needed for PluggableFactory::createAll()
378  if (!pluggingController) {
379  pluggingController = make_unique<PluggingController>(*this);
380  }
381  return *pluggingController;
382 }
383 
385 {
386  assert(getMachineConfig()); // because CPU needs to know if we're
387  // emulating turbor or not
388  return *msxCpu;
389 }
390 
392 {
393  assert(getMachineConfig());
394  return *msxCpuInterface;
395 }
396 
398 {
399  if (!panasonicMemory) {
400  panasonicMemory = make_unique<PanasonicMemory>(*this);
401  }
402  return *panasonicMemory;
403 }
404 
406 {
407  if (!deviceSwitch) {
409  }
410  return *deviceSwitch;
411 }
412 
414 {
415  if (!cassettePort) {
416  assert(getMachineConfig());
417  if (getMachineConfig()->getConfig().findChild("CassettePort")) {
418  cassettePort = make_unique<CassettePort>(*getMachineConfig());
419  } else {
420  cassettePort = make_unique<DummyCassettePort>();
421  }
422  }
423  return *cassettePort;
424 }
425 
427 {
428  assert(port < 2);
429  if (!joystickPort[0]) {
430  assert(getMachineConfig());
431  // some MSX machines only have 1 instead of 2 joystick ports
432  std::string_view ports = getMachineConfig()->getConfig().getChildData(
433  "JoystickPorts", "AB");
434  if (ports != one_of("AB", "", "A", "B")) {
435  throw ConfigException(
436  "Invalid JoystickPorts specification, "
437  "should be one of '', 'A', 'B' or 'AB'.");
438  }
440  if (ports == one_of("AB", "A")) {
441  joystickPort[0] = make_unique<JoystickPort>(
442  ctrl, "joyporta", "MSX Joystick port A");
443  } else {
444  joystickPort[0] = make_unique<DummyJoystickPort>();
445  }
446  if (ports == one_of("AB", "B")) {
447  joystickPort[1] = make_unique<JoystickPort>(
448  ctrl, "joyportb", "MSX Joystick port B");
449  } else {
450  joystickPort[1] = make_unique<DummyJoystickPort>();
451  }
452  joyPortDebuggable = make_unique<JoyPortDebuggable>(*this);
453  }
454  return *joystickPort[port];
455 }
456 
458 {
459  if (!renShaTurbo) {
460  assert(getMachineConfig());
461  renShaTurbo = make_unique<RenShaTurbo>(
462  *msxCommandController,
463  getMachineConfig()->getConfig());
464  }
465  return *renShaTurbo;
466 }
467 
469 {
470  if (!ledStatus) {
471  getMSXCliComm(); // force init, to be on the safe side
472  ledStatus = make_unique<LedStatus>(
473  reactor.getRTScheduler(),
474  *msxCommandController,
475  *msxCliComm);
476  }
477  return *ledStatus;
478 }
479 
481 {
482  return *msxCommandController;
483 }
484 
486 {
487  return msxCommandController->getMachineInfoCommand();
488 }
489 
491 {
492  return scheduler->getCurrentTime();
493 }
494 
496 {
497  if (!powered) {
498  return false;
499  }
500  assert(getMachineConfig()); // otherwise powered cannot be true
501 
502  getCPU().execute(false);
503  return true;
504 }
505 
506 void MSXMotherBoard::fastForward(EmuTime::param time, bool fast)
507 {
508  assert(powered);
509  assert(getMachineConfig());
510 
511  if (time <= getCurrentTime()) return;
512 
513  ScopedAssign sa(fastForwarding, fast);
514  realTime->disable();
515  msxMixer->mute();
516  fastForwardHelper->setTarget(time);
517  while (time > getCurrentTime()) {
518  // note: this can run (slightly) past the requested time
519  getCPU().execute(true); // fast-forward mode
520  }
521  realTime->enable();
522  msxMixer->unmute();
523 }
524 
526 {
527  if (getMachineConfig()) {
528  getCPU().setPaused(true);
529  }
530  msxMixer->mute();
531 }
532 
534 {
535  if (getMachineConfig()) {
536  getCPU().setPaused(false);
537  }
538  msxMixer->unmute();
539 }
540 
542 {
543  availableDevices.push_back(&device);
544 }
545 
547 {
548  move_pop_back(availableDevices, rfind_unguarded(availableDevices, &device));
549 }
550 
552 {
553  if (!powered) return;
554  assert(getMachineConfig());
555 
556  EmuTime::param time = getCurrentTime();
558  for (auto& d : availableDevices) {
559  d->reset(time);
560  }
561  getCPU().doReset(time);
562  // let everyone know we're booting, note that the fact that this is
563  // done after the reset call to the devices is arbitrary here
565  std::make_shared<SimpleEvent>(OPENMSX_BOOT_EVENT));
566 }
567 
569 {
570  byte result = 0xff;
571  for (auto& d : availableDevices) {
572  result &= d->readIRQVector();
573  }
574  return result;
575 }
576 
578 {
579  if (powered) return;
580  if (!getMachineConfig()) return;
581 
582  powered = true;
583  // TODO: If our "powered" field is always equal to the power setting,
584  // there is not really a point in keeping it.
585  // TODO: assert disabled see note in Reactor::run() where this method
586  // is called
587  //assert(powerSetting.getBoolean() == powered);
588  powerSetting.setBoolean(true);
589  // TODO: We could make the power LED a device, so we don't have to handle
590  // it separately here.
592 
593  EmuTime::param time = getCurrentTime();
595  for (auto& d : availableDevices) {
596  d->powerUp(time);
597  }
598  getCPU().doReset(time);
599  msxMixer->unmute();
600  // let everyone know we're booting, note that the fact that this is
601  // done after the reset call to the devices is arbitrary here
603  std::make_shared<SimpleEvent>(OPENMSX_BOOT_EVENT));
604 }
605 
606 void MSXMotherBoard::powerDown()
607 {
608  if (!powered) return;
609 
610  powered = false;
611  // TODO: This assertion fails in 1 case: when quitting with a running MSX.
612  // How do we want the Reactor to shutdown: immediately or after
613  // handling all pending commands/events/updates?
614  //assert(powerSetting.getBoolean() == powered);
615  powerSetting.setBoolean(false);
617 
618  msxMixer->mute();
619 
620  EmuTime::param time = getCurrentTime();
621  for (auto& d : availableDevices) {
622  d->powerDown(time);
623  }
624 }
625 
626 void MSXMotherBoard::activate(bool active_)
627 {
628  active = active_;
629  auto event = std::make_shared<SimpleEvent>(
631  msxEventDistributor->distributeEvent(event, scheduler->getCurrentTime());
632  if (active) {
633  realTime->resync();
634  }
635 }
636 
638 {
639  if (getMachineConfig()) {
641  }
642 }
643 
645 {
647 }
648 
649 MSXDevice* MSXMotherBoard::findDevice(std::string_view name)
650 {
651  auto it = ranges::find_if(availableDevices,
652  [&](auto* d) { return d->getName() == name; });
653  return (it != end(availableDevices)) ? *it : nullptr;
654 }
655 
657 {
658  if (mapperIOCounter == 0) {
660 
661  MSXCPUInterface& cpuInterface = getCPUInterface();
662  cpuInterface.register_IO_Out(0xFC, mapperIO.get());
663  cpuInterface.register_IO_Out(0xFD, mapperIO.get());
664  cpuInterface.register_IO_Out(0xFE, mapperIO.get());
665  cpuInterface.register_IO_Out(0xFF, mapperIO.get());
666  cpuInterface.register_IO_In (0xFC, mapperIO.get());
667  cpuInterface.register_IO_In (0xFD, mapperIO.get());
668  cpuInterface.register_IO_In (0xFE, mapperIO.get());
669  cpuInterface.register_IO_In (0xFF, mapperIO.get());
670  }
671  ++mapperIOCounter;
672  return *mapperIO;
673 }
674 
676 {
677  assert(mapperIO);
678  assert(mapperIOCounter);
679  --mapperIOCounter;
680  if (mapperIOCounter == 0) {
681  MSXCPUInterface& cpuInterface = getCPUInterface();
682  cpuInterface.unregister_IO_Out(0xFC, mapperIO.get());
683  cpuInterface.unregister_IO_Out(0xFD, mapperIO.get());
684  cpuInterface.unregister_IO_Out(0xFE, mapperIO.get());
685  cpuInterface.unregister_IO_Out(0xFF, mapperIO.get());
686  cpuInterface.unregister_IO_In (0xFC, mapperIO.get());
687  cpuInterface.unregister_IO_In (0xFD, mapperIO.get());
688  cpuInterface.unregister_IO_In (0xFE, mapperIO.get());
689  cpuInterface.unregister_IO_In (0xFF, mapperIO.get());
690 
691  mapperIO.reset();
692  }
693 }
694 
695 string MSXMotherBoard::getUserName(const string& hwName)
696 {
697  auto& s = userNames[hwName];
698  unsigned n = 0;
699  string userName;
700  do {
701  userName = strCat("untitled", ++n);
702  } while (contains(s, userName));
703  s.push_back(userName);
704  return userName;
705 }
706 
707 void MSXMotherBoard::freeUserName(const string& hwName, const string& userName)
708 {
709  auto& s = userNames[hwName];
710  move_pop_back(s, rfind_unguarded(s, userName));
711 }
712 
713 // AddRemoveUpdate
714 
716  : motherBoard(motherBoard_)
717 {
718  motherBoard.getReactor().getGlobalCliComm().update(
719  CliComm::HARDWARE, motherBoard.getMachineID(), "add");
720 }
721 
723 {
724  motherBoard.getReactor().getGlobalCliComm().update(
725  CliComm::HARDWARE, motherBoard.getMachineID(), "remove");
726 }
727 
728 
729 // ResetCmd
731  : RecordedCommand(motherBoard_.getCommandController(),
732  motherBoard_.getStateChangeDistributor(),
733  motherBoard_.getScheduler(),
734  "reset")
735  , motherBoard(motherBoard_)
736 {
737 }
738 
739 void ResetCmd::execute(span<const TclObject> /*tokens*/, TclObject& /*result*/,
740  EmuTime::param /*time*/)
741 {
742  motherBoard.doReset();
743 }
744 
745 string ResetCmd::help(const vector<string>& /*tokens*/) const
746 {
747  return "Resets the MSX.";
748 }
749 
750 
751 // LoadMachineCmd
753  : Command(motherBoard_.getCommandController(), "load_machine")
754  , motherBoard(motherBoard_)
755 {
756  // The load_machine command should always directly follow a
757  // create_machine command:
758  // - It's not allowed to use load_machine on a machine that has
759  // already a machine configuration loaded earlier.
760  // - We also disallow executing most machine-specifc commands on an
761  // 'empty machine' (an 'empty machine', is a machine returned by
762  // create_machine before the load_machine command is executed, so a
763  // machine without a machine configuration). The only exception is
764  // this load_machine command and machine_info.
765  //
766  // So if the only allowed command on an empty machine is
767  // 'load_machine', (and an empty machine by itself isn't very useful),
768  // then why isn't create_machine and load_machine merged into a single
769  // command? The only reason for this is that load_machine sends out
770  // events (machine specific) and maybe you already want to know the ID
771  // of the new machine (this is returned by create_machine) before those
772  // events will be send.
773  //
774  // Why not allow all commands on an empty machine? In the past we did
775  // allow this, though it often was the source of bugs. We could in each
776  // command (when needed) check for an empty machine and then return
777  // some dummy/empty result or some error. But because I can't think of
778  // any really useful command for an empty machine, it seemed easier to
779  // just disallow most commands.
781 }
782 
784 {
785  checkNumArgs(tokens, 2, "machine");
786  if (motherBoard.getMachineConfig()) {
787  throw CommandException("Already loaded a config in this machine.");
788  }
789  result = motherBoard.loadMachine(string(tokens[1].getString()));
790 }
791 
792 string LoadMachineCmd::help(const vector<string>& /*tokens*/) const
793 {
794  return "Load a msx machine configuration into an empty machine.";
795 }
796 
797 void LoadMachineCmd::tabCompletion(vector<string>& tokens) const
798 {
799  auto machines = Reactor::getHwConfigs("machines");
800  completeString(tokens, machines);
801 }
802 
803 
804 // ListExtCmd
806  : Command(motherBoard_.getCommandController(), "list_extensions")
807  , motherBoard(motherBoard_)
808 {
809 }
810 
812 {
813  result.addListElements(
814  view::transform(motherBoard.getExtensions(),
815  [&](auto& e) { return e->getName(); }));
816 }
817 
818 string ListExtCmd::help(const vector<string>& /*tokens*/) const
819 {
820  return "Return a list of all inserted extensions.";
821 }
822 
823 
824 // ExtCmd
825 ExtCmd::ExtCmd(MSXMotherBoard& motherBoard_, std::string commandName_)
826  : RecordedCommand(motherBoard_.getCommandController(),
827  motherBoard_.getStateChangeDistributor(),
828  motherBoard_.getScheduler(),
829  commandName_)
830  , motherBoard(motherBoard_)
831  , commandName(std::move(commandName_))
832 {
833 }
834 
836  EmuTime::param /*time*/)
837 {
838  checkNumArgs(tokens, 2, "extension");
839  try {
840  auto slotname = (commandName.size() == 4)
841  ? std::string_view(&commandName[3], 1)
842  : "any";
843  result = motherBoard.loadExtension(
844  tokens[1].getString(), string(slotname));
845  } catch (MSXException& e) {
846  throw CommandException(std::move(e).getMessage());
847  }
848 }
849 
850 string ExtCmd::help(const vector<string>& /*tokens*/) const
851 {
852  return "Insert a hardware extension.";
853 }
854 
855 void ExtCmd::tabCompletion(vector<string>& tokens) const
856 {
857  auto extensions = Reactor::getHwConfigs("extensions");
858  completeString(tokens, extensions);
859 }
860 
861 
862 // RemoveExtCmd
864  : RecordedCommand(motherBoard_.getCommandController(),
865  motherBoard_.getStateChangeDistributor(),
866  motherBoard_.getScheduler(),
867  "remove_extension")
868  , motherBoard(motherBoard_)
869 {
870 }
871 
873  EmuTime::param /*time*/)
874 {
875  checkNumArgs(tokens, 2, "extension");
876  std::string_view extName = tokens[1].getString();
877  HardwareConfig* extension = motherBoard.findExtension(extName);
878  if (!extension) {
879  throw CommandException("No such extension: ", extName);
880  }
881  try {
882  motherBoard.removeExtension(*extension);
883  } catch (MSXException& e) {
884  throw CommandException("Can't remove extension '", extName,
885  "': ", e.getMessage());
886  }
887 }
888 
889 string RemoveExtCmd::help(const vector<string>& /*tokens*/) const
890 {
891  return "Remove an extension from the MSX machine.";
892 }
893 
894 void RemoveExtCmd::tabCompletion(vector<string>& tokens) const
895 {
896  if (tokens.size() == 2) {
897  auto names = to_vector(view::transform(
898  motherBoard.getExtensions(),
899  [](auto& e) { return e->getName(); }));
900  completeString(tokens, names);
901  }
902 }
903 
904 
905 // MachineNameInfo
906 
908  : InfoTopic(motherBoard_.getMachineInfoCommand(), "config_name")
909  , motherBoard(motherBoard_)
910 {
911 }
912 
914  TclObject& result) const
915 {
916  result = motherBoard.getMachineName();
917 }
918 
919 string MachineNameInfo::help(const vector<string>& /*tokens*/) const
920 {
921  return "Returns the configuration name for this machine.";
922 }
923 
924 // MachineTypeInfo
925 
927  : InfoTopic(motherBoard_.getMachineInfoCommand(), "type")
928  , motherBoard(motherBoard_)
929 {
930 }
931 
933  TclObject& result) const
934 {
935  result = motherBoard.getMachineType();
936 }
937 
938 string MachineTypeInfo::help(const vector<string>& /*tokens*/) const
939 {
940  return "Returns the machine type for this machine.";
941 }
942 
943 
944 // DeviceInfo
945 
947  : InfoTopic(motherBoard_.getMachineInfoCommand(), "device")
948  , motherBoard(motherBoard_)
949 {
950 }
951 
953 {
954  checkNumArgs(tokens, Between{2, 3}, Prefix{2}, "?device?");
955  switch (tokens.size()) {
956  case 2:
957  result.addListElements(
958  view::transform(motherBoard.availableDevices,
959  [](auto& d) { return d->getName(); }));
960  break;
961  case 3: {
962  std::string_view deviceName = tokens[2].getString();
963  MSXDevice* device = motherBoard.findDevice(deviceName);
964  if (!device) {
965  throw CommandException("No such device: ", deviceName);
966  }
967  device->getDeviceInfo(result);
968  break;
969  }
970  }
971 }
972 
973 string DeviceInfo::help(const vector<string>& /*tokens*/) const
974 {
975  return "Without any arguments, returns the list of used device names.\n"
976  "With a device name as argument, returns the type (and for some "
977  "devices the subtype) of the given device.";
978 }
979 
980 void DeviceInfo::tabCompletion(vector<string>& tokens) const
981 {
982  if (tokens.size() == 3) {
983  auto names = to_vector(view::transform(
984  motherBoard.availableDevices,
985  [](auto& d) { return d->getName(); }));
986  completeString(tokens, names);
987  }
988 }
989 
990 
991 // FastForwardHelper
992 
994  : Schedulable(motherBoard_.getScheduler())
995  , motherBoard(motherBoard_)
996 {
997 }
998 
999 void FastForwardHelper::setTarget(EmuTime::param targetTime)
1000 {
1001  setSyncPoint(targetTime);
1002 }
1003 
1004 void FastForwardHelper::executeUntil(EmuTime::param /*time*/)
1005 {
1006  motherBoard.exitCPULoopSync();
1007 }
1008 
1009 
1010 // class JoyPortDebuggable
1011 
1013  : SimpleDebuggable(motherBoard_, "joystickports", "MSX Joystick Ports", 2)
1014 {
1015 }
1016 
1017 byte JoyPortDebuggable::read(unsigned address, EmuTime::param time)
1018 {
1019  return getMotherBoard().getJoystickPort(address).read(time);
1020 }
1021 
1022 void JoyPortDebuggable::write(unsigned /*address*/, byte /*value*/)
1023 {
1024  // ignore
1025 }
1026 
1027 
1028 // class SettingObserver
1029 
1031  : motherBoard(motherBoard_)
1032 {
1033 }
1034 
1035 void SettingObserver::update(const Setting& setting)
1036 {
1037  if (&setting == &motherBoard.powerSetting) {
1038  if (motherBoard.powerSetting.getBoolean()) {
1039  motherBoard.powerUp();
1040  } else {
1041  motherBoard.powerDown();
1042  }
1043  } else {
1044  UNREACHABLE;
1045  }
1046 }
1047 
1048 
1049 // serialize
1050 // version 1: initial version
1051 // version 2: added reRecordCount
1052 // version 3: removed reRecordCount (moved to ReverseManager)
1053 // version 4: moved joystickportA/B from MSXPSG to here
1054 template<typename Archive>
1055 void MSXMotherBoard::serialize(Archive& ar, unsigned version)
1056 {
1057  // don't serialize:
1058  // machineID, userNames, availableDevices, addRemoveUpdate,
1059  // sharedStuffMap, msxCliComm, msxEventDistributor,
1060  // msxCommandController, slotManager, eventDelay,
1061  // debugger, msxMixer, panasonicMemory, renShaTurbo,
1062  // ledStatus
1063 
1064  // Scheduler must come early so that devices can query current time
1065  ar.serialize("scheduler", *scheduler);
1066  // MSXMixer has already set syncpoints, those are invalid now
1067  // the following call will fix this
1068  if (ar.isLoader()) {
1069  msxMixer->reInit();
1070  }
1071 
1072  ar.serialize("name", machineName);
1073  ar.serializeWithID("config", machineConfig2, std::ref(*this));
1074  assert(getMachineConfig() == machineConfig2.get());
1075  ar.serializeWithID("extensions", extensions, std::ref(*this));
1076 
1077  if (mapperIO) ar.serialize("mapperIO", *mapperIO);
1078 
1079  MSXDeviceSwitch& devSwitch = getDeviceSwitch();
1080  if (devSwitch.hasRegisteredDevices()) {
1081  ar.serialize("deviceSwitch", devSwitch);
1082  }
1083 
1084  if (getMachineConfig()) {
1085  ar.serialize("cpu", getCPU());
1086  }
1087  ar.serialize("cpuInterface", getCPUInterface());
1088 
1089  if (auto port = dynamic_cast<CassettePort*>(&getCassettePort())) {
1090  ar.serialize("cassetteport", *port);
1091  }
1092  if (ar.versionAtLeast(version, 4)) {
1093  if (auto port = dynamic_cast<JoystickPort*>(
1094  joystickPort[0].get())) {
1095  ar.serialize("joystickportA", *port);
1096  }
1097  if (auto port = dynamic_cast<JoystickPort*>(
1098  joystickPort[1].get())) {
1099  ar.serialize("joystickportB", *port);
1100  }
1101  }
1102 
1103  if (ar.isLoader()) {
1104  powered = true; // must come before changing power setting
1105  powerSetting.setBoolean(true);
1107  msxMixer->unmute();
1108  }
1109 
1110  if (version == 2) {
1111  assert(ar.isLoader());
1112  unsigned reRecordCount = 0; // silence warning
1113  ar.serialize("reRecordCount", reRecordCount);
1114  getReverseManager().setReRecordCount(reRecordCount);
1115  }
1116 }
1118 
1119 } // namespace openmsx
openmsx::LoadMachineCmd::execute
void execute(span< const TclObject > tokens, TclObject &result) override
Execute this command.
Definition: MSXMotherBoard.cc:783
openmsx::MSXMixer
Definition: MSXMixer.hh:27
openmsx::MSXMotherBoard::findExtension
HardwareConfig * findExtension(std::string_view extensionName)
Definition: MSXMotherBoard.cc:353
openmsx::LoadMachineCmd::tabCompletion
void tabCompletion(vector< string > &tokens) const override
Attempt tab completion for this command.
Definition: MSXMotherBoard.cc:797
openmsx::MSXDevice
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:31
openmsx::MSXMotherBoard::getReactor
Reactor & getReactor()
Definition: MSXMotherBoard.hh:135
openmsx::CommandException
Definition: CommandException.hh:8
openmsx::HardwareConfig::createMachineConfig
static std::unique_ptr< HardwareConfig > createMachineConfig(MSXMotherBoard &motherBoard, std::string machineName)
Definition: HardwareConfig.cc:30
openmsx::MSXMotherBoard::removeExtension
void removeExtension(const HardwareConfig &extension)
Definition: MSXMotherBoard.cc:361
one_of.hh
openmsx::Completer::checkNumArgs
void checkNumArgs(span< const TclObject > tokens, unsigned exactly, const char *errMessage) const
Definition: Completer.cc:178
openmsx::MachineTypeInfo::help
string help(const vector< string > &tokens) const override
Print help for this topic.
Definition: MSXMotherBoard.cc:938
openmsx::MSXMotherBoard::createMapperIO
MSXMapperIO & createMapperIO()
All memory mappers in one MSX machine share the same four (logical) memory mapper registers.
Definition: MSXMotherBoard.cc:656
HardwareConfig.hh
ConfigException.hh
openmsx::LoadMachineCmd
Definition: MSXMotherBoard.cc:81
FileException.hh
openmsx::LoadMachineCmd::help
string help(const vector< string > &tokens) const override
Print help for this command.
Definition: MSXMotherBoard.cc:792
openmsx::MSXMotherBoard::getExtensions
const Extensions & getExtensions() const
Definition: MSXMotherBoard.hh:108
openmsx::SettingObserver
Definition: MSXMotherBoard.cc:166
openmsx::LoadMachineCmd::LoadMachineCmd
LoadMachineCmd(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:752
openmsx::MSXMotherBoard::activate
void activate(bool active)
Definition: MSXMotherBoard.cc:626
openmsx::DeviceInfo::execute
void execute(span< const TclObject > tokens, TclObject &result) const override
Show info on this topic.
Definition: MSXMotherBoard.cc:952
openmsx::Scheduler
Definition: Scheduler.hh:33
openmsx::Completer::Between
Definition: Completer.hh:55
RenShaTurbo.hh
openmsx::RemoveExtCmd
Definition: MSXMotherBoard.cc:102
openmsx::MSXMotherBoard::getCurrentTime
EmuTime::param getCurrentTime()
Convenience method: This is the same as getScheduler().getCurrentTime().
Definition: MSXMotherBoard.cc:490
openmsx::Subject::detach
void detach(Observer< T > &observer)
Definition: Subject.hh:56
openmsx::CommandController
Definition: CommandController.hh:17
ScopedAssign
Assign new value to some variable and restore the original value when this object goes out of scope.
Definition: ScopedAssign.hh:7
serialize.hh
openmsx::OPENMSX_BOOT_EVENT
@ OPENMSX_BOOT_EVENT
Definition: Event.hh:36
openmsx::MSXMotherBoard::fastForward
void fastForward(EmuTime::param time, bool fast)
Run emulation until a certain time in fast forward mode.
Definition: MSXMotherBoard.cc:506
openmsx::MSXMotherBoard::doReset
void doReset()
Definition: MSXMotherBoard.cc:551
openmsx::DeviceInfo::DeviceInfo
DeviceInfo(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:946
MSXEventDistributor.hh
openmsx::ExtCmd::execute
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.
Definition: MSXMotherBoard.cc:835
openmsx::MSXCPU::exitCPULoopAsync
void exitCPULoopAsync()
See CPUCore::exitCPULoopAsync()
Definition: MSXCPU.cc:135
openmsx::MSXEventDistributor
Definition: MSXEventDistributor.hh:13
openmsx::JoyPortDebuggable
Definition: MSXMotherBoard.cc:158
openmsx::HardwareConfig::createDevices
void createDevices()
Definition: HardwareConfig.cc:321
TclObject.hh
openmsx::ListExtCmd
Definition: MSXMotherBoard.cc:92
openmsx::MachineNameInfo::MachineNameInfo
MachineNameInfo(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:907
openmsx::DeviceFactory::createDeviceSwitch
static std::unique_ptr< MSXDeviceSwitch > createDeviceSwitch(const HardwareConfig &hwConf)
Definition: DeviceFactory.cc:310
openmsx::DeviceInfo
Definition: MSXMotherBoard.cc:136
openmsx::InfoTopic
Definition: InfoTopic.hh:15
openmsx::DeviceFactory::createMapperIO
static std::unique_ptr< MSXMapperIO > createMapperIO(const HardwareConfig &hwConf)
Definition: DeviceFactory.cc:317
openmsx::ConfigException
Definition: ConfigException.hh:8
openmsx::MSXCPUInterface::register_IO_Out
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
Definition: MSXCPUInterface.cc:350
openmsx::CliComm::EXTENSION
@ EXTENSION
Definition: CliComm.hh:28
openmsx::SimpleDebuggable::getMotherBoard
MSXMotherBoard & getMotherBoard() const
Definition: SimpleDebuggable.hh:23
openmsx::SettingObserver::update
void update(const Setting &setting) override
Definition: MSXMotherBoard.cc:1035
openmsx::MSXMotherBoard::loadMachine
std::string loadMachine(const std::string &machine)
Definition: MSXMotherBoard.cc:290
openmsx::JoystickPort
Definition: JoystickPort.hh:22
openmsx::MSXMotherBoard::insertExtension
std::string insertExtension(std::string_view name, std::unique_ptr< HardwareConfig > extension)
Definition: MSXMotherBoard.cc:337
openmsx::MSXCPU::setPaused
void setPaused(bool paused)
(un)pause CPU.
Definition: MSXCPU.cc:365
openmsx::MSXDeviceSwitch::hasRegisteredDevices
bool hasRegisteredDevices() const
Definition: MSXDeviceSwitch.hh:64
openmsx::XMLElement::getChildData
const std::string & getChildData(std::string_view childName) const
Definition: XMLElement.cc:168
MSXCPU.hh
contains
bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition: stl.hh:92
openmsx::FastForwardHelper::setTarget
void setTarget(EmuTime::param targetTime)
Definition: MSXMotherBoard.cc:999
openmsx::MSXMotherBoard::loadExtension
std::string loadExtension(std::string_view extensionName, std::string slotname)
Definition: MSXMotherBoard.cc:321
openmsx::MSXDeviceSwitch
Definition: MSXDeviceSwitch.hh:55
openmsx::MSXMotherBoard::getJoystickPort
JoystickPortIf & getJoystickPort(unsigned port)
Definition: MSXMotherBoard.cc:426
openmsx::SimpleDebuggable
Definition: SimpleDebuggable.hh:11
openmsx::StateChangeDistributor
Definition: StateChangeDistributor.hh:14
openmsx::MSXMotherBoard::addDevice
void addDevice(MSXDevice &device)
All MSXDevices should be registered by the MotherBoard.
Definition: MSXMotherBoard.cc:541
openmsx::Schedulable
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
openmsx::CliComm::update
virtual void update(UpdateType type, std::string_view name, std::string_view value)=0
ranges.hh
openmsx::Reactor::getEventDistributor
EventDistributor & getEventDistributor()
Definition: Reactor.hh:81
Schedulable.hh
openmsx::MSXException
Definition: MSXException.hh:9
openmsx::MachineNameInfo
Definition: MSXMotherBoard.cc:114
GlobalCliComm.hh
openmsx::MSXCPU::doReset
void doReset(EmuTime::param time)
Reset CPU.
Definition: MSXCPU.cc:84
openmsx::MSXMotherBoard::getPanasonicMemory
PanasonicMemory & getPanasonicMemory()
Definition: MSXMotherBoard.cc:397
XMLElement.hh
JoystickPort.hh
openmsx::Subject::attach
void attach(Observer< T > &observer)
Definition: Subject.hh:50
openmsx::ExtCmd::tabCompletion
void tabCompletion(std::vector< std::string > &tokens) const override
Attempt tab completion for this command.
Definition: MSXMotherBoard.cc:855
openmsx::OPENMSX_MACHINE_DEACTIVATED
@ OPENMSX_MACHINE_DEACTIVATED
Definition: Event.hh:65
openmsx::MSXMotherBoard::removeDevice
void removeDevice(MSXDevice &device)
Definition: MSXMotherBoard.cc:546
openmsx::MSXMotherBoard::exitCPULoopAsync
void exitCPULoopAsync()
See CPU::exitCPULoopAsync().
Definition: MSXMotherBoard.cc:637
PluggingController.hh
openmsx::Setting
Definition: Setting.hh:119
openmsx::MSXMotherBoard::findDevice
MSXDevice * findDevice(std::string_view name)
Find a MSXDevice by name.
Definition: MSXMotherBoard.cc:649
openmsx::MSXMotherBoard::getCommandController
CommandController & getCommandController()
Definition: MSXMotherBoard.cc:480
BooleanSetting.hh
openmsx::MSXCPUInterface
Definition: MSXCPUInterface.hh:63
StateChangeDistributor.hh
ScopedAssign.hh
MSXMapperIO.hh
openmsx::HardwareConfig::getConfig
const XMLElement & getConfig() const
Definition: HardwareConfig.hh:46
openmsx::JoystickPortIf
Definition: JoystickPort.hh:12
openmsx::MSXMotherBoard::getDeviceSwitch
MSXDeviceSwitch & getDeviceSwitch()
Definition: MSXMotherBoard.cc:405
openmsx::CassettePort
Definition: CassettePort.hh:63
EventDelay.hh
openmsx::MSXMotherBoard::setMachineConfig
void setMachineConfig(HardwareConfig *machineConfig)
Definition: MSXMotherBoard.cc:262
span
Definition: span.hh:34
openmsx::Reactor
Contains the main loop of openMSX.
Definition: Reactor.hh:66
openmsx::AddRemoveUpdate::~AddRemoveUpdate
~AddRemoveUpdate()
Definition: MSXMotherBoard.cc:722
openmsx::TclObject::addListElements
void addListElements(ITER first, ITER last)
Definition: TclObject.hh:122
openmsx::RemoveExtCmd::RemoveExtCmd
RemoveExtCmd(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:863
openmsx::Completer::completeString
static void completeString(std::vector< std::string > &tokens, ITER begin, ITER end, bool caseSensitive=true)
Definition: Completer.hh:125
openmsx::RemoveExtCmd::tabCompletion
void tabCompletion(vector< string > &tokens) const override
Attempt tab completion for this command.
Definition: MSXMotherBoard.cc:894
openmsx::LedStatus::POWER
@ POWER
Definition: LedStatus.hh:20
openmsx::MSXMotherBoard::getRenShaTurbo
RenShaTurbo & getRenShaTurbo()
Definition: MSXMotherBoard.cc:457
openmsx::Schedulable::setSyncPoint
void setSyncPoint(EmuTime::param timestamp)
Definition: Schedulable.cc:23
LedStatus.hh
RealTime.hh
MSXDeviceSwitch.hh
openmsx::MSXMotherBoard::getPluggingController
PluggingController & getPluggingController()
Definition: MSXMotherBoard.cc:375
openmsx::XMLElement::findChild
const XMLElement * findChild(std::string_view childName) const
Definition: XMLElement.cc:93
Reactor.hh
openmsx::MachineNameInfo::help
string help(const vector< string > &tokens) const override
Print help for this topic.
Definition: MSXMotherBoard.cc:919
move_pop_back
void move_pop_back(VECTOR &v, typename VECTOR::iterator it)
Erase the pointed to element from the given vector.
Definition: stl.hh:177
view::transform
auto transform(Range &&range, UnaryOp op)
Definition: view.hh:306
openmsx::MSXMotherBoard::getMachineType
std::string getMachineType() const
Definition: MSXMotherBoard.cc:273
UNREACHABLE
#define UNREACHABLE
Definition: unreachable.hh:38
openmsx::MSXMotherBoard::unpause
void unpause()
Definition: MSXMotherBoard.cc:533
Observer.hh
ReverseManager.hh
openmsx::MSXMotherBoard::powerUp
void powerUp()
Definition: MSXMotherBoard.cc:577
openmsx::LedStatus
Definition: LedStatus.hh:16
openmsx::ExtCmd::help
std::string help(const std::vector< std::string > &tokens) const override
Print help for this command.
Definition: MSXMotherBoard.cc:850
openmsx::MSXMotherBoard::getMachineID
std::string_view getMachineID() const
Definition: MSXMotherBoard.hh:68
CassettePort.hh
openmsx::MSXMotherBoard::getMachineInfoCommand
InfoCommand & getMachineInfoCommand()
Definition: MSXMotherBoard.cc:485
openmsx::MSXMotherBoard::getReverseManager
ReverseManager & getReverseManager()
Definition: MSXMotherBoard.hh:134
openmsx::ResetCmd::help
string help(const vector< string > &tokens) const override
Print help for this command.
Definition: MSXMotherBoard.cc:745
openmsx::DeviceInfo::help
string help(const vector< string > &tokens) const override
Print help for this topic.
Definition: MSXMotherBoard.cc:973
openmsx::InfoCommand
Definition: InfoCommand.hh:11
openmsx::MSXDevice::getDeviceInfo
void getDeviceInfo(TclObject &result) const
Get device info.
Definition: MSXDevice.cc:391
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:59
one_of
Definition: one_of.hh:7
openmsx::MSXCPU
Definition: MSXCPU.hh:28
openmsx::MachineTypeInfo::MachineTypeInfo
MachineTypeInfo(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:926
EventDistributor.hh
openmsx::ReverseManager::setReRecordCount
void setReRecordCount(unsigned count)
Definition: ReverseManager.hh:49
openmsx::OPENMSX_MACHINE_ACTIVATED
@ OPENMSX_MACHINE_ACTIVATED
Send when a machine is (de)activated.
Definition: Event.hh:64
MSXDevice.hh
openmsx::MachineTypeInfo
Definition: MSXMotherBoard.cc:125
openmsx::MSXMotherBoard::execute
bool execute()
Run emulation.
Definition: MSXMotherBoard.cc:495
openmsx::PanasonicMemory
Definition: PanasonicMemory.hh:14
openmsx::CassettePortInterface
Definition: CassettePort.hh:18
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::FileException
Definition: FileException.hh:8
openmsx::GlobalCliComm::update
void update(UpdateType type, std::string_view name, std::string_view value) override
Definition: GlobalCliComm.cc:83
openmsx::HardwareConfig::createExtensionConfig
static std::unique_ptr< HardwareConfig > createExtensionConfig(MSXMotherBoard &motherBoard, std::string extensionName, std::string slotname)
Definition: HardwareConfig.cc:39
openmsx::ResetCmd::ResetCmd
ResetCmd(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:730
serialize_stl.hh
openmsx::MSXCPUInterface::reset
void reset()
Reset (the slot state)
Definition: MSXCPUInterface.cc:648
view.hh
openmsx::AddRemoveUpdate
Definition: MSXMotherBoard.cc:61
openmsx::MSXCPUInterface::register_IO_In
void register_IO_In(byte port, MSXDevice *device)
Devices can register their In ports.
Definition: MSXCPUInterface.cc:338
openmsx::MSXMotherBoard::readIRQVector
byte readIRQVector()
Definition: MSXMotherBoard.cc:568
openmsx::JoyPortDebuggable::JoyPortDebuggable
JoyPortDebuggable(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:1012
SimpleDebuggable.hh
openmsx::MachineNameInfo::execute
void execute(span< const TclObject > tokens, TclObject &result) const override
Show info on this topic.
Definition: MSXMotherBoard.cc:913
openmsx::AddRemoveUpdate::AddRemoveUpdate
AddRemoveUpdate(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:715
openmsx::MSXMotherBoard::destroyMapperIO
void destroyMapperIO()
Definition: MSXMotherBoard.cc:675
GlobalSettings.hh
Scheduler.hh
openmsx::MSXCPUInterface::unregister_IO_In
void unregister_IO_In(byte port, MSXDevice *device)
Definition: MSXCPUInterface.cc:344
openmsx::RemoveExtCmd::execute
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.
Definition: MSXMotherBoard.cc:872
openmsx::MSXCliComm
Definition: MSXCliComm.hh:13
openmsx::RemoveExtCmd::help
string help(const vector< string > &tokens) const override
Print help for this command.
Definition: MSXMotherBoard.cc:889
openmsx::Reactor::getGlobalSettings
GlobalSettings & getGlobalSettings()
Definition: Reactor.hh:103
openmsx::ListExtCmd::help
string help(const vector< string > &tokens) const override
Print help for this command.
Definition: MSXMotherBoard.cc:818
openmsx::SettingObserver::SettingObserver
SettingObserver(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:1030
openmsx::Reactor::getGlobalCliComm
GlobalCliComm & getGlobalCliComm()
Definition: Reactor.hh:82
openmsx::MSXMotherBoard::getUserName
std::string getUserName(const std::string &hwName)
Keep track of which 'usernames' are in use.
Definition: MSXMotherBoard.cc:695
span::size
constexpr index_type size() const noexcept
Definition: span.hh:296
openmsx::MSXMotherBoard::getLedStatus
LedStatus & getLedStatus()
Definition: MSXMotherBoard.cc:468
openmsx::MSXMotherBoard::getCPUInterface
MSXCPUInterface & getCPUInterface()
Definition: MSXMotherBoard.cc:391
openmsx::HardwareConfig::getName
const std::string & getName() const
Definition: HardwareConfig.hh:47
openmsx::MSXMotherBoard::MSXMotherBoard
MSXMotherBoard(const MSXMotherBoard &)=delete
MSXCPUInterface.hh
Command.hh
openmsx::RecordedCommand
Commands that directly influence the MSX state should send and events so that they can be recorded by...
Definition: RecordedCommand.hh:45
InfoTopic.hh
openmsx::MSXMapperIO
Definition: MSXMapperIO.hh:22
openmsx::Command
Definition: Command.hh:40
openmsx::CliComm
Definition: CliComm.hh:10
openmsx::ResetCmd
Definition: MSXMotherBoard.cc:70
openmsx::MSXMotherBoard::getMachineConfig
const HardwareConfig * getMachineConfig() const
Definition: MSXMotherBoard.hh:100
openmsx::ListExtCmd::ListExtCmd
ListExtCmd(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:805
openmsx::MSXMotherBoard::isTurboR
bool isTurboR() const
Definition: MSXMotherBoard.cc:283
openmsx::HardwareConfig
Definition: HardwareConfig.hh:21
stl.hh
openmsx::ExtCmd::ExtCmd
ExtCmd(MSXMotherBoard &motherBoard, std::string commandName)
Definition: MSXMotherBoard.cc:825
MSXCommandController.hh
openmsx::TclObject
Definition: TclObject.hh:21
CartridgeSlotManager.hh
openmsx::MSXCPU::exitCPULoopSync
void exitCPULoopSync()
See CPUCore::exitCPULoopsync()
Definition: MSXCPU.cc:130
openmsx::Reactor::getHwConfigs
static std::vector< std::string > getHwConfigs(std::string_view type)
Definition: Reactor.cc:326
openmsx::RenShaTurbo
Ren-Sha Turbo is the autofire in several MSX 2+ models and in the MSX turbo R.
Definition: RenShaTurbo.hh:20
openmsx::MachineTypeInfo::execute
void execute(span< const TclObject > tokens, TclObject &result) const override
Show info on this topic.
Definition: MSXMotherBoard.cc:932
openmsx::MSXCommandController
Definition: MSXCommandController.hh:20
ranges::find_if
auto find_if(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:113
openmsx::MSXMotherBoard::getCassettePort
CassettePortInterface & getCassettePort()
Definition: MSXMotherBoard.cc:413
openmsx::ResetCmd::execute
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.
Definition: MSXMotherBoard.cc:739
openmsx::ListExtCmd::execute
void execute(span< const TclObject > tokens, TclObject &result) override
Execute this command.
Definition: MSXMotherBoard.cc:811
openmsx::JoystickPortIf::read
virtual byte read(EmuTime::param time)=0
openmsx::MSXCPUInterface::unregister_IO_Out
void unregister_IO_Out(byte port, MSXDevice *device)
Definition: MSXCPUInterface.cc:356
openmsx::HardwareConfig::testRemove
void testRemove() const
Checks whether this HardwareConfig can be deleted.
Definition: HardwareConfig.cc:161
openmsx::LedStatus::setLed
void setLed(Led led, bool status)
Definition: LedStatus.cc:39
openmsx::JoyPortDebuggable::read
byte read(unsigned address, EmuTime::param time) override
Definition: MSXMotherBoard.cc:1017
unreachable.hh
openmsx::MSXException::getMessage
const std::string & getMessage() const &
Definition: MSXException.hh:23
DeviceFactory.hh
openmsx::MSXMotherBoard::serialize
void serialize(Archive &ar, unsigned version)
Definition: MSXMotherBoard.cc:1055
openmsx::Command::setAllowedInEmptyMachine
void setAllowedInEmptyMachine(bool value)
Definition: Command.hh:64
openmsx::BooleanSetting::setBoolean
void setBoolean(bool b)
Definition: BooleanSetting.hh:18
PanasonicMemory.hh
MSXMixer.hh
openmsx::PluggingController
Central administration of Connectors and Pluggables.
Definition: PluggingController.hh:21
openmsx::MSXMotherBoard::~MSXMotherBoard
~MSXMotherBoard()
Definition: MSXMotherBoard.cc:233
strCat
std::string strCat(Ts &&...ts)
Definition: strCat.hh:573
CommandException.hh
rfind_unguarded
auto rfind_unguarded(RANGE &range, const VAL &val)
Similar to the find(_if)_unguarded functions above, but searches from the back to front.
Definition: stl.hh:152
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
to_vector
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))>>
Definition: stl.hh:311
MSXMotherBoard.hh
openmsx::MSXMotherBoard::getMSXCliComm
CliComm & getMSXCliComm()
Definition: MSXMotherBoard.cc:370
openmsx::BooleanSetting::getBoolean
bool getBoolean() const noexcept
Definition: BooleanSetting.hh:17
openmsx::DeviceInfo::tabCompletion
void tabCompletion(vector< string > &tokens) const override
Attempt tab completion for this topic.
Definition: MSXMotherBoard.cc:980
openmsx::MSXMotherBoard::freeUserName
void freeUserName(const std::string &hwName, const std::string &userName)
Definition: MSXMotherBoard.cc:707
openmsx::Observer
Generic Gang-of-Four Observer class, templatized edition.
Definition: Observer.hh:9
openmsx::MSXMotherBoard::getMachineName
std::string_view getMachineName() const
Definition: MSXMotherBoard.hh:69
openmsx::CliComm::HARDWARE
@ HARDWARE
Definition: CliComm.hh:24
openmsx::Reactor::getRTScheduler
RTScheduler & getRTScheduler()
Definition: Reactor.hh:80
openmsx::JoyPortDebuggable::write
void write(unsigned address, byte value) override
Definition: MSXMotherBoard.cc:1022
rfind_if_unguarded
auto rfind_if_unguarded(RANGE &range, PRED pred)
Definition: stl.hh:160
openmsx::MSXMotherBoard::getCPU
MSXCPU & getCPU()
Definition: MSXMotherBoard.cc:384
openmsx::FastForwardHelper
Definition: MSXMotherBoard.cc:148
openmsx::XMLElement::getChild
const XMLElement & getChild(std::string_view childName) const
Definition: XMLElement.cc:142
openmsx::FastForwardHelper::FastForwardHelper
FastForwardHelper(MSXMotherBoard &motherBoard)
Definition: MSXMotherBoard.cc:993
Debugger.hh
openmsx::EventDistributor::distributeEvent
void distributeEvent(const EventPtr &event)
Schedule the given event for delivery.
Definition: EventDistributor.cc:44
openmsx::HardwareConfig::parseSlots
void parseSlots()
Definition: HardwareConfig.cc:235
openmsx::MSXMotherBoard::exitCPULoopSync
void exitCPULoopSync()
Definition: MSXMotherBoard.cc:644
openmsx::MSXMotherBoard::pause
void pause()
Pause MSX machine.
Definition: MSXMotherBoard.cc:525
MSXCliComm.hh
openmsx::Completer::Prefix
Definition: Completer.hh:56