openMSX
MSXFDC.cc
Go to the documentation of this file.
1 #include "MSXFDC.hh"
2 #include "RealDrive.hh"
3 #include "Rom.hh"
4 #include "XMLElement.hh"
5 #include "MSXException.hh"
6 #include "enumerate.hh"
7 #include "serialize.hh"
8 #include <memory>
9 
10 namespace openmsx {
11 
12 MSXFDC::MSXFDC(const DeviceConfig& config, const std::string& romId, bool needROM,
13  DiskDrive::TrackMode trackMode)
14  : MSXDevice(config)
15  , rom(needROM
16  ? std::make_unique<Rom>(getName() + " ROM", "rom", config, romId)
17  : nullptr) // e.g. Spectravideo_SVI-328 doesn't have a diskrom
18 {
19  if (needROM && (rom->getSize() == 0)) {
20  throw MSXException(
21  "Empty ROM not allowed for \"", getName(), "\".");
22  }
23  bool singleSided = config.findChild("singlesided") != nullptr;
24  int numDrives = config.getChildDataAsInt("drives", 1);
25  if ((0 > numDrives) || (numDrives >= 4)) {
26  throw MSXException("Invalid number of drives: ", numDrives);
27  }
28  unsigned timeout = config.getChildDataAsInt("motor_off_timeout_ms", 0);
29  const XMLElement* styleEl = config.findChild("connectionstyle");
30  bool signalsNeedMotorOn = !styleEl || (styleEl->getData() == "Philips");
31  EmuDuration motorTimeout = EmuDuration::msec(timeout);
32  int i = 0;
33  for (; i < numDrives; ++i) {
34  drives[i] = std::make_unique<RealDrive>(
35  getMotherBoard(), motorTimeout, signalsNeedMotorOn,
36  !singleSided, trackMode);
37  }
38  for (; i < 4; ++i) {
39  drives[i] = std::make_unique<DummyDrive>();
40  }
41 }
42 
43 MSXFDC::~MSXFDC() = default;
44 
45 void MSXFDC::powerDown(EmuTime::param time)
46 {
47  for (auto& drive : drives) {
48  drive->setMotor(false, time);
49  }
50 }
51 
52 byte MSXFDC::readMem(word address, EmuTime::param /*time*/)
53 {
54  return *MSXFDC::getReadCacheLine(address);
55 }
56 
57 byte MSXFDC::peekMem(word address, EmuTime::param /*time*/) const
58 {
59  return *MSXFDC::getReadCacheLine(address);
60 }
61 
62 const byte* MSXFDC::getReadCacheLine(word start) const
63 {
64  return &(*rom)[start & 0x3FFF];
65 }
66 
67 
68 template<typename Archive>
69 void MSXFDC::serialize(Archive& ar, unsigned /*version*/)
70 {
71  ar.template serializeBase<MSXDevice>(*this);
72 
73  // Drives are already constructed at this point, so we cannot use the
74  // polymorphic object construction of the serialization framework.
75  // Destroying and reconstructing the drives is not an option because
76  // DriveMultiplexer already has pointers to the drives.
77  char tag[7] = { 'd', 'r', 'i', 'v', 'e', 'X', 0 };
78  for (auto [i, drv] : enumerate(drives)) {
79  if (auto* drive = dynamic_cast<RealDrive*>(drv.get())) {
80  tag[5] = char('a' + i);
81  ar.serialize(tag, *drive);
82  }
83  }
84 }
86 
87 } // namespace openmsx
const XMLElement * findChild(std::string_view name) const
Definition: DeviceConfig.cc:61
int getChildDataAsInt(std::string_view name, int defaultValue=0) const
Definition: DeviceConfig.cc:52
static constexpr EmuDuration msec(unsigned x)
Definition: EmuDuration.hh:41
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:32
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition: MSXDevice.cc:76
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:382
std::unique_ptr< DiskDrive > drives[4]
Definition: MSXFDC.hh:32
std::unique_ptr< Rom > rom
Definition: MSXFDC.hh:31
~MSXFDC() override
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXFDC.cc:57
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
Definition: MSXFDC.cc:45
MSXFDC(const DeviceConfig &config, const std::string &romId={}, bool needROM=true, DiskDrive::TrackMode trackMode=DiskDrive::TrackMode::NORMAL)
Definition: MSXFDC.cc:12
void serialize(Archive &ar, unsigned version)
Definition: MSXFDC.cc:69
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXFDC.cc:62
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXFDC.cc:52
This class implements a real drive, single or double sided.
Definition: RealDrive.hh:22
const std::string & getData() const
Definition: XMLElement.hh:54
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
Definition: enumerate.hh:28
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:742
This file implemented 3 utility functions:
Definition: Autofire.cc:5
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:983