openMSX
RealDrive.hh
Go to the documentation of this file.
1#ifndef REALDRIVE_HH
2#define REALDRIVE_HH
3
4#include "DiskDrive.hh"
5#include "DiskChanger.hh"
6#include "Clock.hh"
7#include "Schedulable.hh"
8#include "ThrottleManager.hh"
9#include "MSXMotherBoard.hh"
10#include "outer.hh"
11#include "serialize_meta.hh"
12#include <bitset>
13#include <optional>
14
15namespace openmsx {
16
19class RealDrive final : public DiskDrive, public MediaInfoProvider
20{
21public:
22 static constexpr unsigned MAX_DRIVES = 26; // a-z
23 using DrivesInUse = std::bitset<MAX_DRIVES>;
24 static std::shared_ptr<DrivesInUse> getDrivesInUse(MSXMotherBoard& motherBoard);
25
26public:
27 RealDrive(MSXMotherBoard& motherBoard, EmuDuration::param motorTimeout,
28 bool signalsNeedMotorOn, bool doubleSided,
29 DiskDrive::TrackMode trackMode);
30 ~RealDrive() override;
31
32 // DiskDrive interface
33 [[nodiscard]] bool isDiskInserted() const override;
34 [[nodiscard]] bool isWriteProtected() const override;
35 [[nodiscard]] bool isDoubleSided() override;
36 [[nodiscard]] bool isTrack00() const override;
37 void setSide(bool side) override;
38 [[nodiscard]] bool getSide() const override;
39 void step(bool direction, EmuTime::param time) override;
40 void setMotor(bool status, EmuTime::param time) override;
41 [[nodiscard]] bool getMotor() const override;
42 [[nodiscard]] bool indexPulse(EmuTime::param time) override;
43 [[nodiscard]] EmuTime getTimeTillIndexPulse(EmuTime::param time, int count) override;
44
45 [[nodiscard]] unsigned getTrackLength() override;
46 void writeTrackByte(int idx, uint8_t val, bool addIdam) override;
47 [[nodiscard]] uint8_t readTrackByte(int idx) override;
48 EmuTime getNextSector(EmuTime::param time, RawTrack::Sector& sector) override;
49 void flushTrack() override;
50 bool diskChanged() override;
51 [[nodiscard]] bool peekDiskChanged() const override;
52 [[nodiscard]] bool isDummyDrive() const override;
53
54 void applyWd2793ReadTrackQuirk() override;
55 void invalidateWd2793ReadTrackQuirk() override;
56
57 // MediaInfoProvider
58 void getMediaInfo(TclObject& result) override;
59
60 template<typename Archive>
61 void serialize(Archive& ar, unsigned version);
62
63private:
64 struct SyncLoadingTimeout final : Schedulable {
65 friend class RealDrive;
66 explicit SyncLoadingTimeout(Scheduler& s) : Schedulable(s) {}
67 void executeUntil(EmuTime::param /*time*/) override {
68 auto& drive = OUTER(RealDrive, syncLoadingTimeout);
69 drive.execLoadingTimeout();
70 }
71 } syncLoadingTimeout;
72
73 struct SyncMotorTimeout final : Schedulable {
74 friend class RealDrive;
75 explicit SyncMotorTimeout(Scheduler& s) : Schedulable(s) {}
76 void executeUntil(EmuTime::param time) override {
77 auto& drive = OUTER(RealDrive, syncMotorTimeout);
78 drive.execMotorTimeout(time);
79 }
80 } syncMotorTimeout;
81
82 void execLoadingTimeout();
83 void execMotorTimeout(EmuTime::param time);
84 [[nodiscard]] EmuTime::param getCurrentTime() const { return syncLoadingTimeout.getCurrentTime(); }
85
86 void doSetMotor(bool status, EmuTime::param time);
87 void setLoading(EmuTime::param time);
88 [[nodiscard]] unsigned getCurrentAngle(EmuTime::param time) const;
89
90 [[nodiscard]] unsigned getMaxTrack() const;
91 [[nodiscard]] std::optional<unsigned> getDiskReadTrack() const;
92 [[nodiscard]] std::optional<unsigned> getDiskWriteTrack() const;
93 void getTrack();
94 void invalidateTrack();
95
96private:
97 static constexpr unsigned TICKS_PER_ROTATION = 200000;
98 static constexpr unsigned INDEX_DURATION = TICKS_PER_ROTATION / 50;
99
100 MSXMotherBoard& motherBoard;
101 LoadingIndicator loadingIndicator;
102 const EmuDuration motorTimeout;
103
104 using MotorClock = Clock<TICKS_PER_ROTATION * ROTATIONS_PER_SECOND>;
105 MotorClock motorTimer;
106 std::optional<DiskChanger> changer; // delayed initialization
107 unsigned headPos = 0;
108 unsigned side = 0;
109 unsigned startAngle = 0;
110 bool motorStatus = false;
111 const bool doubleSizedDrive;
112 const bool signalsNeedMotorOn;
113 const DiskDrive::TrackMode trackMode;
114
115 std::shared_ptr<DrivesInUse> drivesInUse;
116
117 RawTrack track;
118 bool trackValid = false;
119 bool trackDirty = false;
120};
122
123} // namespace openmsx
124
125#endif
This (abstract) class defines the DiskDrive interface.
Definition DiskDrive.hh:13
This class implements a real drive, single or double sided.
Definition RealDrive.hh:20
void applyWd2793ReadTrackQuirk() override
See RawTrack::applyWd2793ReadTrackQuirk()
Definition RealDrive.cc:484
static constexpr unsigned MAX_DRIVES
Definition RealDrive.hh:22
bool peekDiskChanged() const override
Definition RealDrive.cc:474
void serialize(Archive &ar, unsigned version)
Definition RealDrive.cc:502
static std::shared_ptr< DrivesInUse > getDrivesInUse(MSXMotherBoard &motherBoard)
Definition RealDrive.cc:21
bool isTrack00() const override
Head above track 0.
Definition RealDrive.cc:227
void step(bool direction, EmuTime::param time) override
Step head.
Definition RealDrive.cc:206
bool isDoubleSided() override
Is disk double sided?
Definition RealDrive.cc:135
void invalidateWd2793ReadTrackQuirk() override
Definition RealDrive.cc:489
bool isWriteProtected() const override
Is disk write protected?
Definition RealDrive.cc:127
bool getMotor() const override
Returns the previously set motor status.
Definition RealDrive.cc:292
uint8_t readTrackByte(int idx) override
Definition RealDrive.cc:417
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
Definition RealDrive.cc:237
void setSide(bool side) override
Side select.
Definition RealDrive.cc:141
std::bitset< MAX_DRIVES > DrivesInUse
Definition RealDrive.hh:23
bool diskChanged() override
Is disk changed?
Definition RealDrive.cc:469
bool indexPulse(EmuTime::param time) override
Gets the state of the index pulse.
Definition RealDrive.cc:350
EmuTime getTimeTillIndexPulse(EmuTime::param time, int count) override
Return the time till the start of the next index pulse When there is no disk in the drive or when the...
Definition RealDrive.cc:361
~RealDrive() override
Definition RealDrive.cc:60
bool isDummyDrive() const override
Is there a dummy (unconnected) drive?
Definition RealDrive.cc:479
void flushTrack() override
Definition RealDrive.cc:457
void writeTrackByte(int idx, uint8_t val, bool addIdam) override
Definition RealDrive.cc:408
bool isDiskInserted() const override
Is drive ready?
Definition RealDrive.cc:108
EmuTime getNextSector(EmuTime::param time, RawTrack::Sector &sector) override
Definition RealDrive.cc:427
unsigned getTrackLength() override
Definition RealDrive.cc:402
bool getSide() const override
Definition RealDrive.cc:147
void getMediaInfo(TclObject &result) override
This method gets called when information is required on the media inserted in the media slot of the p...
Definition RealDrive.cc:79
Every class that wants to get scheduled at some point must inherit from this class.
Schedulable(const Schedulable &)=delete
This file implemented 3 utility functions:
Definition Autofire.cc:11
#define OUTER(type, member)
Definition outer.hh:42
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)