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 "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::make_unique<Rom>(getName() + " ROM", "rom", config, romId)
16  : nullptr) // 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 XMLElement* 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 MSXFDC::~MSXFDC() = default;
43 
44 void MSXFDC::powerDown(EmuTime::param time)
45 {
46  for (auto& drive : drives) {
47  drive->setMotor(false, time);
48  }
49 }
50 
51 byte MSXFDC::readMem(word address, EmuTime::param /*time*/)
52 {
53  return *MSXFDC::getReadCacheLine(address);
54 }
55 
56 byte MSXFDC::peekMem(word address, EmuTime::param /*time*/) const
57 {
58  return *MSXFDC::getReadCacheLine(address);
59 }
60 
61 const byte* MSXFDC::getReadCacheLine(word start) const
62 {
63  return &(*rom)[start & 0x3FFF];
64 }
65 
66 
67 template<typename Archive>
68 void MSXFDC::serialize(Archive& ar, unsigned /*version*/)
69 {
70  ar.template serializeBase<MSXDevice>(*this);
71 
72  // Drives are already constructed at this point, so we cannot use the
73  // polymorphic object construction of the serialization framework.
74  // Destroying and reconstructing the drives is not an option because
75  // DriveMultiplexer already has pointers to the drives.
76  char tag[7] = { 'd', 'r', 'i', 'v', 'e', 'X', 0 };
77  for (int i = 0; i < 4; ++i) {
78  if (auto drive = dynamic_cast<RealDrive*>(drives[i].get())) {
79  tag[5] = char('a' + i);
80  ar.serialize(tag, *drive);
81  }
82  }
83 }
85 
86 } // namespace openmsx
openmsx::MSXDevice
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:32
openmsx::MSXFDC::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXFDC.cc:51
openmsx::MSXFDC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXFDC.cc:56
serialize.hh
Rom.hh
openmsx::EmuDuration
Definition: EmuDuration.hh:19
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
openmsx::YM2413NukeYKT::rom
constexpr Rom rom
Definition: YM2413NukeYKT.cc:71
openmsx::DeviceConfig::findChild
const XMLElement * findChild(std::string_view name) const
Definition: DeviceConfig.cc:61
MSXException.hh
openmsx::MSXException
Definition: MSXException.hh:10
XMLElement.hh
openmsx::MSXFDC::MSXFDC
MSXFDC(const DeviceConfig &config, const std::string &romId={}, bool needROM=true, DiskDrive::TrackMode trackMode=DiskDrive::TrackMode::NORMAL)
Definition: MSXFDC.cc:11
openmsx::RealDrive
This class implements a real drive, single or double sided.
Definition: RealDrive.hh:22
openmsx::MSXFDC
Definition: MSXFDC.hh:14
openmsx::MSXFDC::~MSXFDC
~MSXFDC() override
openmsx::XMLElement
Definition: XMLElement.hh:16
openmsx::Keys::getName
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:740
RealDrive.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:75
openmsx::Rom
Definition: Rom.hh:21
MSXFDC.hh
openmsx::MSXFDC::rom
std::unique_ptr< Rom > rom
Definition: MSXFDC.hh:30
openmsx::MSXDevice::getName
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:381
openmsx::DeviceConfig::getChildDataAsInt
int getChildDataAsInt(std::string_view name, int defaultValue=0) const
Definition: DeviceConfig.cc:52
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::XMLElement::getData
const std::string & getData() const
Definition: XMLElement.hh:36
openmsx::EmuDuration::msec
static constexpr EmuDuration msec(unsigned x)
Definition: EmuDuration.hh:41
openmsx::MSXFDC::serialize
void serialize(Archive &ar, unsigned version)
Definition: MSXFDC.cc:68
openmsx::MSXFDC::powerDown
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
Definition: MSXFDC.cc:44
openmsx::MSXFDC::getReadCacheLine
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:61
openmsx::MSXFDC::drives
std::unique_ptr< DiskDrive > drives[4]
Definition: MSXFDC.hh:31
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::DiskDrive::TrackMode
TrackMode
Definition: DiskDrive.hh:15