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