openMSX
MSXFDC.cc
Go to the documentation of this file.
1 #include "MSXFDC.hh"
2 #include "Rom.hh"
3 #include "RealDrive.hh"
4 #include "XMLElement.hh"
5 #include "StringOp.hh"
6 #include "MSXException.hh"
7 #include "serialize.hh"
8 #include "memory.hh"
9 
10 namespace openmsx {
11 
13  : MSXDevice(config)
14  , rom(make_unique<Rom>(getName() + " ROM", "rom", config))
15 {
16  bool singleSided = config.findChild("singlesided") != nullptr;
17  int numDrives = config.getChildDataAsInt("drives", 1);
18  if ((0 > numDrives) || (numDrives >= 4)) {
20  "Invalid number of drives: " << numDrives);
21  }
22  unsigned timeout = config.getChildDataAsInt("motor_off_timeout_ms", 0);
23  const XMLElement* styleEl = config.findChild("connectionstyle");
24  bool signalsNeedMotorOn = !styleEl || (styleEl->getData() == "Philips");
25  EmuDuration motorTimeout = EmuDuration::msec(timeout);
26  int i = 0;
27  for ( ; i < numDrives; ++i) {
28  drives[i] = make_unique<RealDrive>(
29  getMotherBoard(), motorTimeout, signalsNeedMotorOn,
30  !singleSided);
31  }
32  for ( ; i < 4; ++i) {
33  drives[i] = make_unique<DummyDrive>();
34  }
35 }
36 
38 {
39 }
40 
42 {
43  for (int i = 0; i < 4; ++i) {
44  drives[i]->setMotor(false, time);
45  }
46 }
47 
49 {
50  return *MSXFDC::getReadCacheLine(address);
51 }
52 
53 byte MSXFDC::peekMem(word address, EmuTime::param /*time*/) const
54 {
55  return *MSXFDC::getReadCacheLine(address);
56 }
57 
58 const byte* MSXFDC::getReadCacheLine(word start) const
59 {
60  return &(*rom)[start & 0x3FFF];
61 }
62 
63 
64 template<typename Archive>
65 void MSXFDC::serialize(Archive& ar, unsigned /*version*/)
66 {
67  ar.template serializeBase<MSXDevice>(*this);
68 
69  // Drives are already constructed at this point, so we cannot use the
70  // polymorphic object construction of the serialization framework.
71  // Destroying and reconstructing the drives is not an option because
72  // DriveMultiplexer already has pointers to the drives.
73  char tag[7] = { 'd', 'r', 'i', 'v', 'e', 'X', 0 };
74  for (int i = 0; i < 4; ++i) {
75  if (auto drive = dynamic_cast<RealDrive*>(drives[i].get())) {
76  tag[5] = char('a' + i);
77  ar.serialize(tag, *drive);
78  }
79  }
80 }
82 
83 } // namespace openmsx