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 <array>
8#include <memory>
9
10namespace openmsx {
11
12MSXFDC::MSXFDC(const DeviceConfig& config, const std::string& romId, bool needROM,
13 DiskDrive::TrackMode trackMode)
14 : MSXDevice(config)
15 , rom(needROM
16 ? std::optional<Rom>(std::in_place, getName() + " ROM", "rom", config, romId)
17 : std::nullopt) // e.g. Spectravideo_SVI-328 doesn't have a disk rom
18{
19 if (needROM && (rom->size() == 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 auto* 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
43void MSXFDC::powerDown(EmuTime::param time)
44{
45 for (const auto& drive : drives) {
46 drive->setMotor(false, time);
47 }
48}
49
50byte MSXFDC::readMem(word address, EmuTime::param /*time*/)
51{
52 return *MSXFDC::getReadCacheLine(address);
53}
54
55byte MSXFDC::peekMem(word address, EmuTime::param /*time*/) const
56{
57 return *MSXFDC::getReadCacheLine(address);
58}
59
60const byte* MSXFDC::getReadCacheLine(word start) const
61{
62 return &(*rom)[start & 0x3FFF];
63}
64
66{
67 if (rom) {
68 rom->getInfo(result);
69 }
70}
71
72
73template<typename Archive>
74void MSXFDC::serialize(Archive& ar, unsigned /*version*/)
75{
76 ar.template serializeBase<MSXDevice>(*this);
77
78 // Drives are already constructed at this point, so we cannot use the
79 // polymorphic object construction of the serialization framework.
80 // Destroying and reconstructing the drives is not an option because
81 // DriveMultiplexer already has pointers to the drives.
82 std::array<char, 7> tag = {'d', 'r', 'i', 'v', 'e', 'X', 0};
83 for (auto [i, drv] : enumerate(drives)) {
84 if (auto* drive = dynamic_cast<RealDrive*>(drv.get())) {
85 tag[5] = char('a' + i);
86 ar.serialize(tag.data(), *drive);
87 }
88 }
89}
91
92} // namespace openmsx
const XMLElement * findChild(std::string_view name) const
int getChildDataAsInt(std::string_view name, int defaultValue) const
static constexpr EmuDuration msec(unsigned x)
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition MSXDevice.cc:70
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition MSXDevice.cc:375
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition MSXFDC.cc:55
void powerDown(EmuTime::param time) override
This method is called when MSX is powered down.
Definition MSXFDC.cc:43
std::optional< Rom > rom
Definition MSXFDC.hh:33
std::array< std::unique_ptr< DiskDrive >, 4 > drives
Definition MSXFDC.hh:34
MSXFDC(const DeviceConfig &config, const std::string &romId={}, bool needROM=true, DiskDrive::TrackMode trackMode=DiskDrive::TrackMode::NORMAL)
Definition MSXFDC.cc:12
void getExtraDeviceInfo(TclObject &result) const override
Definition MSXFDC.cc:65
void serialize(Archive &ar, unsigned version)
Definition MSXFDC.cc:74
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
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
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
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)