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
9namespace openmsx {
10
11MSXFDC::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
42void MSXFDC::powerDown(EmuTime::param time)
43{
44 for (auto& drive : drives) {
45 drive->setMotor(false, time);
46 }
47}
48
49byte MSXFDC::readMem(word address, EmuTime::param /*time*/)
50{
51 return *MSXFDC::getReadCacheLine(address);
52}
53
54byte MSXFDC::peekMem(word address, EmuTime::param /*time*/) const
55{
56 return *MSXFDC::getReadCacheLine(address);
57}
58
59const byte* MSXFDC::getReadCacheLine(word start) const
60{
61 return &(*rom)[start & 0x3FFF];
62}
63
64
65template<typename Archive>
66void 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:42
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:20
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:727
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009