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