openMSX
MSXDevice.cc
Go to the documentation of this file.
1 #include "MSXDevice.hh"
2 #include "XMLElement.hh"
3 #include "MSXMotherBoard.hh"
4 #include "HardwareConfig.hh"
6 #include "MSXCPUInterface.hh"
7 #include "MSXCPU.hh"
8 #include "CacheLine.hh"
9 #include "TclObject.hh"
10 #include "Math.hh"
11 #include "MSXException.hh"
12 #include "ranges.hh"
13 #include "serialize.hh"
14 #include "stl.hh"
15 #include "unreachable.hh"
16 #include "view.hh"
17 #include <cassert>
18 #include <cstring>
19 #include <iterator> // for back_inserter
20 
21 using std::string;
22 
23 namespace openmsx {
24 
25 MSXDevice::MSXDevice(const DeviceConfig& config, const string& name)
26  : deviceConfig(config)
27 {
28  initName(name);
29 }
30 
32  : deviceConfig(config)
33 {
34  initName(getDeviceConfig().getAttribute("id"));
35 }
36 
37 void MSXDevice::initName(const string& name)
38 {
39  deviceName = name;
40  if (getMotherBoard().findDevice(deviceName)) {
41  unsigned n = 0;
42  do {
43  deviceName = strCat(name, " (", ++n, ')');
44  } while (getMotherBoard().findDevice(deviceName));
45  }
46 }
47 
49 {
50  staticInit();
51 
52  lockDevices();
53  registerSlots();
54  registerPorts();
55 }
56 
58 {
59  unregisterPorts();
60  unregisterSlots();
61  unlockDevices();
62  assert(referencedBy.empty());
63 }
64 
65 void MSXDevice::staticInit()
66 {
67  static bool alreadyInit = false;
68  if (alreadyInit) return;
69  alreadyInit = true;
70 
71  memset(unmappedRead, 0xFF, sizeof(unmappedRead));
72 }
73 
75 {
77 }
78 
79 void MSXDevice::testRemove(Devices removed) const
80 {
81  auto all = referencedBy;
82  ranges::sort(all);
83  ranges::sort(removed);
84  Devices rest;
85  ranges::set_difference(all, removed, back_inserter(rest));
86  if (!rest.empty()) {
87  string msg = "Still in use by";
88  for (auto& d : rest) {
89  strAppend(msg, ' ', d->getName());
90  }
91  throw MSXException(std::move(msg));
92  }
93 }
94 
95 void MSXDevice::lockDevices()
96 {
97  // This code can only handle backward references: the thing that is
98  // referenced must already be instantiated, we don't try to change the
99  // instantiation order. For the moment this is good enough (only ADVRAM
100  // (an extension) uses it to refer to the VDP (inside a machine)). If
101  // needed we can implement something more sophisticated later without
102  // changing the format of the config files.
103  for (auto& c : getDeviceConfig().getChildren("device")) {
104  const auto& name = c->getAttribute("idref");
105  auto* dev = getMotherBoard().findDevice(name);
106  if (!dev) {
107  throw MSXException(
108  "Unsatisfied dependency: '", getName(),
109  "' depends on unavailable device '",
110  name, "'.");
111  }
112  references.push_back(dev);
113  dev->referencedBy.push_back(this);
114  }
115 }
116 
117 void MSXDevice::unlockDevices()
118 {
119  for (auto& r : references) {
120  move_pop_back(r->referencedBy, rfind_unguarded(r->referencedBy, this));
121  }
122 }
123 
125 {
126  // init() must already be called
127  return references;
128 }
129 
130 EmuTime::param MSXDevice::getCurrentTime() const
131 {
132  return getMotherBoard().getCurrentTime();
133 }
135 {
136  return getMotherBoard().getCPU();
137 }
139 {
140  return getMotherBoard().getCPUInterface();
141 }
143 {
144  return getMotherBoard().getScheduler();
145 }
147 {
148  return getMotherBoard().getMSXCliComm();
149 }
151 {
152  return getMotherBoard().getReactor();
153 }
155 {
157 }
159 {
160  return getMotherBoard().getLedStatus();
161 }
163 {
165 }
166 
167 void MSXDevice::registerSlots()
168 {
169  MemRegions tmpMemRegions;
170  unsigned align = getBaseSizeAlignment();
171  assert(Math::ispow2(align));
172  for (auto& m : getDeviceConfig().getChildren("mem")) {
173  unsigned base = m->getAttributeAsInt("base");
174  unsigned size = m->getAttributeAsInt("size");
175  if ((base >= 0x10000) || (size > 0x10000) || ((base + size) > 0x10000)) {
176  throw MSXException(
177  "Invalid memory specification for device ",
178  getName(), " should be in range "
179  "[0x0000,0x10000).");
180  }
181  if ((base & (align - 1)) || (size & (align - 1))) {
182  throw MSXException(
183  "invalid memory specification for device ",
184  getName(), " should be aligned on at least 0x",
185  hex_string<4>(align), '.');
186  }
187  tmpMemRegions.emplace_back(base, size);
188  }
189  if (tmpMemRegions.empty()) {
190  return;
191  }
192 
193  // find primary and secondary slot specification
194  auto& slotManager = getMotherBoard().getSlotManager();
195  auto* primaryConfig = getDeviceConfig2().getPrimary();
196  auto* secondaryConfig = getDeviceConfig2().getSecondary();
197  if (primaryConfig) {
198  ps = slotManager.getSlotNum(primaryConfig->getAttribute("slot"));
199  } else {
200  throw MSXException("Invalid memory specification");
201  }
202  if (secondaryConfig) {
203  const auto& ss_str = secondaryConfig->getAttribute("slot");
204  ss = slotManager.getSlotNum(ss_str);
205  if ((-16 <= ss) && (ss <= -1) && (ss != ps)) {
206  throw MSXException(
207  "Invalid secondary slot specification: \"",
208  ss_str, "\".");
209  }
210  } else {
211  ss = 0;
212  }
213 
214  // This is only for backwards compatibility: in the past we added extra
215  // attributes "primary_slot" and "secondary_slot" (in each MSXDevice
216  // config) instead of changing the 'any' value of the slot attribute of
217  // the (possibly shared) <primary> and <secondary> tags. When loading
218  // an old savestate these tags can still occur, so keep this code. Also
219  // remove these attributes to convert to the new format.
220  const auto& config = getDeviceConfig();
221  if (config.hasAttribute("primary_slot")) {
222  auto& mutableConfig = const_cast<XMLElement&>(config);
223  const auto& primSlot = config.getAttribute("primary_slot");
224  ps = slotManager.getSlotNum(primSlot);
225  mutableConfig.removeAttribute("primary_slot");
226  if (config.hasAttribute("secondary_slot")) {
227  const auto& secondSlot = config.getAttribute("secondary_slot");
228  ss = slotManager.getSlotNum(secondSlot);
229  mutableConfig.removeAttribute("secondary_slot");
230  }
231  }
232 
233  // decode special values for 'ss'
234  if ((-128 <= ss) && (ss < 0)) {
235  if ((0 <= ps) && (ps < 4) &&
236  getCPUInterface().isExpanded(ps)) {
237  ss += 128;
238  } else {
239  ss = 0;
240  }
241  }
242 
243  // decode special values for 'ps'
244  if (ps == -256) {
245  slotManager.getAnyFreeSlot(ps, ss);
246  } else if (ps < 0) {
247  // specified slot by name (carta, cartb, ...)
248  slotManager.getSpecificSlot(-ps - 1, ps, ss);
249  } else {
250  // numerical specified slot (0, 1, 2, 3)
251  }
252  assert((0 <= ps) && (ps <= 3));
253 
254  if (!getCPUInterface().isExpanded(ps)) {
255  ss = -1;
256  }
257 
258  // Store actual slot in config. This has two purposes:
259  // - Make sure that devices that are grouped under the same
260  // <primary>/<secondary> tags actually use the same slot. (This
261  // matters when the value of some of the slot attributes is "any").
262  // - Fix the slot number so that it remains the same after a
263  // savestate/loadstate.
264  assert(primaryConfig);
265  primaryConfig->setAttribute("slot", strCat(ps));
266  if (secondaryConfig) {
267  string slot = (ss == -1) ? "X" : strCat(ss);
268  secondaryConfig->setAttribute("slot", slot);
269  } else {
270  if (ss != -1) {
271  throw MSXException(
272  "Missing <secondary> tag for device", getName());
273  }
274  }
275 
276  int logicalSS = (ss == -1) ? 0 : ss;
277  for (auto& r : tmpMemRegions) {
279  *this, ps, logicalSS, r.first, r.second);
280  memRegions.push_back(r);
281  }
282 
283  // Mark the slot as 'in-use' so that future searches for free external
284  // slots don't return this slot anymore. If the slot was not an
285  // external slot, this call has no effect. Multiple MSXDevices from the
286  // same extension (the same HardwareConfig) can all allocate the same
287  // slot (later they should also all free this slot).
288  slotManager.allocateSlot(ps, ss, getHardwareConfig());
289 }
290 
291 void MSXDevice::unregisterSlots()
292 {
293  if (memRegions.empty()) return;
294 
295  int logicalSS = (ss == -1) ? 0 : ss;
296  for (const auto& [base, size] : memRegions) {
298  *this, ps, logicalSS, base, size);
299  }
300 
301  // See comments above about allocateSlot() for more details:
302  // - has no effect for non-external slots
303  // - can be called multiple times for the same slot
305 }
306 
307 void MSXDevice::getVisibleMemRegion(unsigned& base, unsigned& size) const
308 {
309  // init() must already be called
310  if (memRegions.empty()) {
311  base = 0;
312  size = 0;
313  return;
314  }
315 
316  auto lowest = min_value(view::transform(memRegions,
317  [](auto& r) { return r.first; }));
318  auto highest = max_value(view::transform(memRegions,
319  [](auto& r) { return r.first + r.second; }));
320  assert(lowest <= highest);
321  base = lowest;
322  size = highest - lowest;
323 }
324 
325 void MSXDevice::registerPorts()
326 {
327  for (auto& i : getDeviceConfig().getChildren("io")) {
328  unsigned base = i->getAttributeAsInt("base");
329  unsigned num = i->getAttributeAsInt("num");
330  const auto& type = i->getAttribute("type", "IO");
331  if (((base + num) > 256) || (num == 0) ||
332  ((type != "I") && (type != "O") && (type != "IO"))) {
333  throw MSXException("Invalid IO port specification");
334  }
335  for (unsigned port = base; port < base + num; ++port) {
336  if ((type == "I") || (type == "IO")) {
337  getCPUInterface().register_IO_In(port, this);
338  inPorts.push_back(port);
339  }
340  if ((type == "O") || (type == "IO")) {
341  getCPUInterface().register_IO_Out(port, this);
342  outPorts.push_back(port);
343  }
344  }
345  }
346 }
347 
348 void MSXDevice::unregisterPorts()
349 {
350  for (auto& p : inPorts) {
352  }
353  for (auto& p : outPorts) {
355  }
356 }
357 
358 
359 void MSXDevice::reset(EmuTime::param /*time*/)
360 {
361  // nothing
362 }
363 
365 {
366  return 0xFF;
367 }
368 
369 void MSXDevice::powerDown(EmuTime::param /*time*/)
370 {
371  // nothing
372 }
373 
374 void MSXDevice::powerUp(EmuTime::param time)
375 {
376  reset(time);
377 }
378 
379 string MSXDevice::getName() const
380 {
381  return deviceName;
382 }
383 
385 {
386  result.addListElement(getName());
387 }
388 
390 {
391  result.addDictKeyValue("type", getDeviceConfig().getName());
392  getExtraDeviceInfo(result);
393 }
394 
396 {
397  // nothing
398 }
399 
401 {
402  return CacheLine::SIZE;
403 }
404 
405 
406 byte MSXDevice::readIO(word /*port*/, EmuTime::param /*time*/)
407 {
408  // read from unmapped IO
409  return 0xFF;
410 }
411 
412 void MSXDevice::writeIO(word /*port*/, byte /*value*/, EmuTime::param /*time*/)
413 {
414  // write to unmapped IO, do nothing
415 }
416 
417 byte MSXDevice::peekIO(word /*port*/, EmuTime::param /*time*/) const
418 {
419  return 0xFF;
420 }
421 
422 
423 byte MSXDevice::readMem(word /*address*/, EmuTime::param /*time*/)
424 {
425  // read from unmapped memory
426  return 0xFF;
427 }
428 
429 const byte* MSXDevice::getReadCacheLine(word /*start*/) const
430 {
431  return nullptr; // uncacheable
432 }
433 
434 void MSXDevice::writeMem(word /*address*/, byte /*value*/,
435  EmuTime::param /*time*/)
436 {
437  // write to unmapped memory, do nothing
438 }
439 
440 byte MSXDevice::peekMem(word address, EmuTime::param /*time*/) const
441 {
442  word base = address & CacheLine::HIGH;
443  if (const byte* cache = getReadCacheLine(base)) {
444  word offset = address & CacheLine::LOW;
445  return cache[offset];
446  } else {
447  // peek not supported for this device
448  return 0xFF;
449  }
450 }
451 
452 void MSXDevice::globalWrite(word /*address*/, byte /*value*/,
453  EmuTime::param /*time*/)
454 {
455  UNREACHABLE;
456 }
457 
458 void MSXDevice::globalRead(word /*address*/, EmuTime::param /*time*/)
459 {
460  UNREACHABLE;
461 }
462 
463 byte* MSXDevice::getWriteCacheLine(word /*start*/) const
464 {
465  return nullptr; // uncacheable
466 }
467 
468 
469 // calls 'action(<start2>, <size2>, args..., ps, ss)'
470 // with 'start', 'size' clipped to each of the ranges in 'memRegions'
471 template<typename Action, typename... Args>
472 void MSXDevice::clip(unsigned start, unsigned size, Action action, Args... args)
473 {
474  int ss2 = (ss != -1) ? ss : 0;
475  unsigned end = start + size;
476  for (auto [base, fullBsize] : memRegions) {
477  // split on 16kB boundaries
478  while (fullBsize > 0) {
479  unsigned bsize = std::min(fullBsize, ((base + 0x4000) & ~0x3fff) - base);
480 
481  unsigned baseEnd = base + bsize;
482  // intersect [start, end) with [base, baseEnd) -> [clipStart, clipEnd)
483  unsigned clipStart = std::max(start, base);
484  unsigned clipEnd = std::min(end, baseEnd);
485  if (clipStart < clipEnd) { // non-empty
486  unsigned clipSize = clipEnd - clipStart;
487  action(clipStart, clipSize, args..., ps, ss2);
488  }
489 
490  base += bsize;
491  fullBsize -= bsize;
492  }
493  }
494 }
495 
496 void MSXDevice::invalidateDeviceRWCache(unsigned start, unsigned size)
497 {
498  clip(start, size, [&](auto... args) { getCPUInterface().invalidateRWCache(args...); });
499 }
500 void MSXDevice::invalidateDeviceRCache(unsigned start, unsigned size)
501 {
502  clip(start, size, [&](auto... args) { getCPUInterface().invalidateRCache(args...); });
503 }
504 void MSXDevice::invalidateDeviceWCache(unsigned start, unsigned size)
505 {
506  clip(start, size, [&](auto... args) { getCPUInterface().invalidateWCache(args...); });
507 }
508 
509 void MSXDevice::fillDeviceRWCache(unsigned start, unsigned size, byte* rwData)
510 {
511  fillDeviceRWCache(start, size, rwData, rwData);
512 }
513 void MSXDevice::fillDeviceRWCache(unsigned start, unsigned size, const byte* rData, byte* wData)
514 {
515  clip(start, size, [&](auto... args) { getCPUInterface().fillRWCache(args...); }, rData, wData);
516 }
517 void MSXDevice::fillDeviceRCache(unsigned start, unsigned size, const byte* rData)
518 {
519  clip(start, size, [&](auto... args) { getCPUInterface().fillRCache(args...); }, rData);
520 }
521 void MSXDevice::fillDeviceWCache(unsigned start, unsigned size, byte* wData)
522 {
523  clip(start, size, [&](auto... args) { getCPUInterface().fillWCache(args...); }, wData);
524 }
525 
526 template<typename Archive>
527 void MSXDevice::serialize(Archive& ar, unsigned /*version*/)
528 {
529  // When this method is called, the method init() has already been
530  // called (thus also registerSlots() and registerPorts()).
531  ar.serialize("name", deviceName);
532 }
534 
535 } // namespace openmsx
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
HardwareConfig.hh
openmsx::MSXDevice::MSXDevice
MSXDevice(const MSXDevice &)=delete
openmsx::MSXMotherBoard::getSlotManager
CartridgeSlotManager & getSlotManager()
Definition: MSXMotherBoard.hh:121
openmsx::Scheduler
Definition: Scheduler.hh:33
min_value
auto min_value(InputIterator first, InputIterator last)
Definition: stl.hh:248
openmsx::MSXDevice::fillDeviceRCache
void fillDeviceRCache(unsigned start, unsigned size, const byte *rData)
Definition: MSXDevice.cc:517
gl::min
vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:274
openmsx::MSXMotherBoard::getCurrentTime
EmuTime::param getCurrentTime()
Convenience method: This is the same as getScheduler().getCurrentTime().
Definition: MSXMotherBoard.cc:490
openmsx::MSXDevice::writeIO
virtual void writeIO(word port, byte value, EmuTime::param time)
Write a byte to a given IO port at a certain time to this device.
Definition: MSXDevice.cc:412
openmsx::MSXDevice::getReadCacheLine
virtual const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXDevice.cc:429
openmsx::CommandController
Definition: CommandController.hh:17
serialize.hh
ranges::sort
void sort(RandomAccessRange &&range)
Definition: ranges.hh:35
TclObject.hh
openmsx::MSXDevice::readMem
virtual byte readMem(word address, EmuTime::param time)
Read a byte from a location at a certain time from this device.
Definition: MSXDevice.cc:423
openmsx::MSXDevice::globalRead
virtual void globalRead(word address, EmuTime::param time)
Global reads.
Definition: MSXDevice.cc:458
openmsx::MSXDevice::~MSXDevice
virtual ~MSXDevice()=0
Definition: MSXDevice.cc:57
openmsx::MSXDevice::getWriteCacheLine
virtual byte * getWriteCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: MSXDevice.cc:463
openmsx::MSXDevice::getScheduler
Scheduler & getScheduler() const
Definition: MSXDevice.cc:142
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
utf8::unchecked::size
size_t size(std::string_view utf8)
Definition: utf8_unchecked.hh:227
openmsx::MSXCPUInterface::register_IO_Out
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
Definition: MSXCPUInterface.cc:350
ranges::set_difference
auto set_difference(InputRange1 &&range1, InputRange2 &&range2, OutputIter out)
Definition: ranges.hh:221
MSXCPU.hh
openmsx::DeviceConfig::getPrimary
XMLElement * getPrimary() const
Definition: DeviceConfig.hh:51
ranges.hh
openmsx::MSXDevice::serialize
void serialize(Archive &ar, unsigned version)
Definition: MSXDevice.cc:527
MSXException.hh
openmsx::MSXException
Definition: MSXException.hh:9
openmsx::MSXCPUInterface::invalidateRCache
void invalidateRCache(word start, unsigned size, int ps, int ss)
Definition: MSXCPUInterface.cc:621
openmsx::MSXDevice::globalWrite
virtual void globalWrite(word address, byte value, EmuTime::param time)
Global writes.
Definition: MSXDevice.cc:452
Math::ispow2
constexpr bool ispow2(T x) noexcept
Is the given number an integral power of two? That is, does it have exactly one 1-bit in binary repre...
Definition: Math.hh:57
openmsx::MSXCPUInterface::invalidateWCache
void invalidateWCache(word start, unsigned size, int ps, int ss)
Definition: MSXCPUInterface.cc:626
XMLElement.hh
openmsx::MSXDevice::Devices
std::vector< MSXDevice * > Devices
Definition: MSXDevice.hh:37
openmsx::MSXDevice::getCPUInterface
MSXCPUInterface & getCPUInterface() const
Definition: MSXDevice.cc:138
openmsx::CacheLine::HIGH
constexpr unsigned HIGH
Definition: CacheLine.hh:10
openmsx::MSXDevice::writeMem
virtual void writeMem(word address, byte value, EmuTime::param time)
Write a given byte to a given location at a certain time to this device.
Definition: MSXDevice.cc:434
strAppend
void strAppend(std::string &result, Ts &&...ts)
Definition: strCat.hh:644
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
openmsx::MSXCPUInterface
Definition: MSXCPUInterface.hh:63
openmsx::MSXDevice::peekMem
virtual byte peekMem(word address, EmuTime::param time) const
Read a byte from a given memory location.
Definition: MSXDevice.cc:440
openmsx::MSXDevice::readIRQVector
virtual byte readIRQVector()
Gets IRQ vector used in IM2.
Definition: MSXDevice.cc:364
openmsx::MSXDevice::reset
virtual void reset(EmuTime::param time)
This method is called on reset.
Definition: MSXDevice.cc:359
openmsx::Reactor
Contains the main loop of openMSX.
Definition: Reactor.hh:66
openmsx::MSXCPUInterface::registerMemDevice
void registerMemDevice(MSXDevice &device, int ps, int ss, int base, int size)
Devices can register themself in the MSX slotstructure.
Definition: MSXCPUInterface.cc:513
openmsx::MSXMotherBoard::getPluggingController
PluggingController & getPluggingController()
Definition: MSXMotherBoard.cc:374
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
UNREACHABLE
#define UNREACHABLE
Definition: unreachable.hh:38
openmsx::TclObject::addListElement
void addListElement(T t)
Definition: TclObject.hh:121
max_value
auto max_value(InputIterator first, InputIterator last)
Definition: stl.hh:267
openmsx::LedStatus
Definition: LedStatus.hh:16
openmsx::MSXDevice::fillDeviceWCache
void fillDeviceWCache(unsigned start, unsigned size, byte *wData)
Definition: MSXDevice.cc:521
openmsx::MSXDevice::invalidateDeviceWCache
void invalidateDeviceWCache()
Definition: MSXDevice.hh:210
openmsx::MSXDevice::getVisibleMemRegion
void getVisibleMemRegion(unsigned &base, unsigned &size) const
Returns the range where this device is visible in memory.
Definition: MSXDevice.cc:307
openmsx::MSXDevice::getCurrentTime
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:130
openmsx::MSXDevice::getDeviceInfo
void getDeviceInfo(TclObject &result) const
Get device info.
Definition: MSXDevice.cc:389
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:59
openmsx::MSXCPU
Definition: MSXCPU.hh:28
MSXDevice.hh
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::MSXDevice::getMotherBoard
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition: MSXDevice.cc:74
openmsx::CacheLine::SIZE
constexpr unsigned SIZE
Definition: CacheLine.hh:7
openmsx::MSXMotherBoard::getScheduler
Scheduler & getScheduler()
Definition: MSXMotherBoard.hh:118
CacheLine.hh
openmsx::MSXCPUInterface::fillWCache
void fillWCache(unsigned start, unsigned size, byte *wData, int ps, int ss)
Definition: MSXCPUInterface.cc:642
view.hh
openmsx::TclObject::addDictKeyValue
void addDictKeyValue(const Key &key, const Value &value)
Definition: TclObject.hh:135
openmsx::MSXCPUInterface::register_IO_In
void register_IO_In(byte port, MSXDevice *device)
Devices can register their In ports.
Definition: MSXCPUInterface.cc:338
openmsx::MSXDevice::getLedStatus
LedStatus & getLedStatus() const
Definition: MSXDevice.cc:158
openmsx::MSXDevice::getDeviceConfig2
const DeviceConfig & getDeviceConfig2() const
Definition: MSXDevice.hh:233
openmsx::MSXDevice::getCliComm
CliComm & getCliComm() const
Definition: MSXDevice.cc:146
openmsx::MSXDevice::invalidateDeviceRCache
void invalidateDeviceRCache()
Definition: MSXDevice.hh:209
openmsx::MSXDevice::invalidateDeviceRWCache
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:208
openmsx::MSXCPUInterface::unregister_IO_In
void unregister_IO_In(byte port, MSXDevice *device)
Definition: MSXCPUInterface.cc:344
openmsx::CacheLine::LOW
constexpr unsigned LOW
Definition: CacheLine.hh:9
openmsx::MSXDevice::powerDown
virtual void powerDown(EmuTime::param time)
This method is called when MSX is powered down.
Definition: MSXDevice.cc:369
openmsx::MSXDevice::getBaseSizeAlignment
virtual unsigned getBaseSizeAlignment() const
The 'base' and 'size' attribute values need to be at least aligned to CacheLine::SIZE.
Definition: MSXDevice.cc:400
openmsx::MSXDevice::getReferences
const Devices & getReferences() const
Get the device references that are specified for this device.
Definition: MSXDevice.cc:124
openmsx::MSXDevice::getCommandController
CommandController & getCommandController() const
Definition: MSXDevice.cc:154
openmsx::MSXCPUInterface::fillRWCache
void fillRWCache(unsigned start, unsigned size, const byte *rData, byte *wData, int ps, int ss)
Definition: MSXCPUInterface.cc:632
openmsx::MSXDevice::getPluggingController
PluggingController & getPluggingController() const
Definition: MSXDevice.cc:162
openmsx::MSXDevice::getName
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:379
openmsx::MSXDevice::readIO
virtual byte readIO(word port, EmuTime::param time)
Read a byte from an IO port at a certain time from this device.
Definition: MSXDevice.cc:406
openmsx::MSXMotherBoard::getLedStatus
LedStatus & getLedStatus()
Definition: MSXMotherBoard.cc:468
openmsx::CartridgeSlotManager::freeSlot
void freeSlot(int ps, int ss, const HardwareConfig &hwConfig)
Definition: CartridgeSlotManager.cc:247
openmsx::MSXMotherBoard::getCPUInterface
MSXCPUInterface & getCPUInterface()
Definition: MSXMotherBoard.cc:390
openmsx::MSXDevice::unmappedRead
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:292
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::MSXDevice::init
virtual void init()
Definition: MSXDevice.cc:48
MSXCPUInterface.hh
openmsx::CliComm
Definition: CliComm.hh:10
gl::max
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:292
stl.hh
openmsx::MSXDevice::getHardwareConfig
const HardwareConfig & getHardwareConfig() const
Returns the hardwareconfig this device belongs to.
Definition: MSXDevice.hh:43
openmsx::TclObject
Definition: TclObject.hh:21
CartridgeSlotManager.hh
openmsx::MSXCPUInterface::unregister_IO_Out
void unregister_IO_Out(byte port, MSXDevice *device)
Definition: MSXCPUInterface.cc:356
unreachable.hh
openmsx::DeviceConfig::getSecondary
XMLElement * getSecondary() const
Definition: DeviceConfig.hh:55
openmsx::MSXDevice::getNameList
virtual void getNameList(TclObject &result) const
Returns list of name(s) of this device.
Definition: MSXDevice.cc:384
Math.hh
openmsx::MSXCPUInterface::invalidateRWCache
void invalidateRWCache(word start, unsigned size, int ps, int ss)
Definition: MSXCPUInterface.cc:616
openmsx::MSXCPUInterface::unregisterMemDevice
void unregisterMemDevice(MSXDevice &device, int ps, int ss, int base, int size)
Definition: MSXCPUInterface.cc:543
openmsx::MSXDevice::peekIO
virtual byte peekIO(word port, EmuTime::param time) const
Read a byte from a given IO port.
Definition: MSXDevice.cc:417
openmsx::MSXDevice::testRemove
void testRemove(Devices alreadyRemoved) const
Checks whether this device can be removed (no other device has a reference to it).
Definition: MSXDevice.cc:79
openmsx::PluggingController
Central administration of Connectors and Pluggables.
Definition: PluggingController.hh:21
strCat
std::string strCat(Ts &&...ts)
Definition: strCat.hh:573
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
openmsx::MSXDevice::getReactor
Reactor & getReactor() const
Definition: MSXDevice.cc:150
openmsx::MSXCPUInterface::fillRCache
void fillRCache(unsigned start, unsigned size, const byte *rData, int ps, int ss)
Definition: MSXCPUInterface.cc:637
MSXMotherBoard.hh
openmsx::MSXMotherBoard::getMSXCliComm
CliComm & getMSXCliComm()
Definition: MSXMotherBoard.cc:369
openmsx::MSXDevice::getExtraDeviceInfo
virtual void getExtraDeviceInfo(TclObject &result) const
Definition: MSXDevice.cc:395
openmsx::MSXMotherBoard::getCPU
MSXCPU & getCPU()
Definition: MSXMotherBoard.cc:383
openmsx::MSXDevice::powerUp
virtual void powerUp(EmuTime::param time)
This method is called when MSX is powered up.
Definition: MSXDevice.cc:374
openmsx::MSXDevice::getCPU
MSXCPU & getCPU() const
Definition: MSXDevice.cc:134
openmsx::MSXDevice::getDeviceConfig
const XMLElement & getDeviceConfig() const
Get the configuration section for this device.
Definition: MSXDevice.hh:230
openmsx::HardwareConfig::getMotherBoard
MSXMotherBoard & getMotherBoard() const
Definition: HardwareConfig.hh:41
openmsx::MSXDevice::fillDeviceRWCache
void fillDeviceRWCache(unsigned start, unsigned size, byte *rwData)
Calls MSXCPUInterface::fillXXCache() for the specific (part of) the slot that this device is located ...
Definition: MSXDevice.cc:509