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 RealDrive(MSXMotherBoard& motherBoard, EmuDuration::param motorTimeout,
23 bool signalsNeedMotorOn, bool doubleSided,
24 DiskDrive::TrackMode trackMode);
25 ~RealDrive() override;
26
27 // DiskDrive interface
28 [[nodiscard]] bool isDiskInserted() const override;
29 [[nodiscard]] bool isWriteProtected() const override;
30 [[nodiscard]] bool isDoubleSided() override;
31 [[nodiscard]] bool isTrack00() const override;
32 void setSide(bool side) override;
33 [[nodiscard]] bool getSide() const override;
34 void step(bool direction, EmuTime::param time) override;
35 void setMotor(bool status, EmuTime::param time) override;
36 [[nodiscard]] bool getMotor() const override;
37 [[nodiscard]] bool indexPulse(EmuTime::param time) override;
38 [[nodiscard]] EmuTime getTimeTillIndexPulse(EmuTime::param time, int count) override;
39
40 [[nodiscard]] unsigned getTrackLength() override;
41 void writeTrackByte(int idx, uint8_t val, bool addIdam) override;
42 [[nodiscard]] uint8_t readTrackByte(int idx) override;
43 EmuTime getNextSector(EmuTime::param time, RawTrack::Sector& sector) override;
44 void flushTrack() override;
45 bool diskChanged() override;
46 [[nodiscard]] bool peekDiskChanged() const override;
47 [[nodiscard]] bool isDummyDrive() const override;
48
49 void applyWd2793ReadTrackQuirk() override;
50 void invalidateWd2793ReadTrackQuirk() override;
51
52 // MediaInfoProvider
53 void getMediaInfo(TclObject& result) override;
54
55 template<typename Archive>
56 void serialize(Archive& ar, unsigned version);
57
58private:
59 struct SyncLoadingTimeout final : Schedulable {
60 friend class RealDrive;
61 explicit SyncLoadingTimeout(Scheduler& s) : Schedulable(s) {}
62 void executeUntil(EmuTime::param /*time*/) override {
63 auto& drive = OUTER(RealDrive, syncLoadingTimeout);
64 drive.execLoadingTimeout();
65 }
66 } syncLoadingTimeout;
67
68 struct SyncMotorTimeout final : Schedulable {
69 friend class RealDrive;
70 explicit SyncMotorTimeout(Scheduler& s) : Schedulable(s) {}
71 void executeUntil(EmuTime::param time) override {
72 auto& drive = OUTER(RealDrive, syncMotorTimeout);
73 drive.execMotorTimeout(time);
74 }
75 } syncMotorTimeout;
76
77 void execLoadingTimeout();
78 void execMotorTimeout(EmuTime::param time);
79 [[nodiscard]] EmuTime::param getCurrentTime() const { return syncLoadingTimeout.getCurrentTime(); }
80
81 void doSetMotor(bool status, EmuTime::param time);
82 void setLoading(EmuTime::param time);
83 [[nodiscard]] unsigned getCurrentAngle(EmuTime::param time) const;
84
85 [[nodiscard]] unsigned getMaxTrack() const;
86 [[nodiscard]] std::optional<unsigned> getDiskReadTrack() const;
87 [[nodiscard]] std::optional<unsigned> getDiskWriteTrack() const;
88 void getTrack();
89 void invalidateTrack();
90
91private:
92 static constexpr unsigned TICKS_PER_ROTATION = 200000;
93 static constexpr unsigned INDEX_DURATION = TICKS_PER_ROTATION / 50;
94
95 MSXMotherBoard& motherBoard;
96 LoadingIndicator loadingIndicator;
97 const EmuDuration motorTimeout;
98
100 MotorClock motorTimer;
101 std::optional<DiskChanger> changer; // delayed initialization
102 unsigned headPos = 0;
103 unsigned side = 0;
104 unsigned startAngle = 0;
105 bool motorStatus = false;
106 const bool doubleSizedDrive;
107 const bool signalsNeedMotorOn;
108 const DiskDrive::TrackMode trackMode;
109
110 static constexpr unsigned MAX_DRIVES = 26; // a-z
111 using DrivesInUse = std::bitset<MAX_DRIVES>;
112 std::shared_ptr<DrivesInUse> drivesInUse;
113
114 RawTrack track;
115 bool trackValid = false;
116 bool trackDirty = false;
117};
119
120} // namespace openmsx
121
122#endif
This (abstract) class defines the DiskDrive interface.
Definition: DiskDrive.hh:13
Used by a device to indicate when it is loading.
This class implements a real drive, single or double sided.
Definition: RealDrive.hh:20
void applyWd2793ReadTrackQuirk() override
See RawTrack::applyWd2793ReadTrackQuirk()
Definition: RealDrive.cc:472
bool peekDiskChanged() const override
Definition: RealDrive.cc:462
void serialize(Archive &ar, unsigned version)
Definition: RealDrive.cc:490
bool isTrack00() const override
Head above track 0.
Definition: RealDrive.cc:219
void step(bool direction, EmuTime::param time) override
Step head.
Definition: RealDrive.cc:198
bool isDoubleSided() override
Is disk double sided?
Definition: RealDrive.cc:124
void invalidateWd2793ReadTrackQuirk() override
Definition: RealDrive.cc:477
bool isWriteProtected() const override
Is disk write protected?
Definition: RealDrive.cc:116
bool getMotor() const override
Returns the previously set motor status.
Definition: RealDrive.cc:284
uint8_t readTrackByte(int idx) override
Definition: RealDrive.cc:407
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
Definition: RealDrive.cc:229
void setSide(bool side) override
Side select.
Definition: RealDrive.cc:130
bool diskChanged() override
Is disk changed?
Definition: RealDrive.cc:457
bool indexPulse(EmuTime::param time) override
Gets the state of the index pulse.
Definition: RealDrive.cc:342
RealDrive(MSXMotherBoard &motherBoard, EmuDuration::param motorTimeout, bool signalsNeedMotorOn, bool doubleSided, DiskDrive::TrackMode trackMode)
Definition: RealDrive.cc:19
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:353
~RealDrive() override
Definition: RealDrive.cc:53
bool isDummyDrive() const override
Is there a dummy (unconnected) drive?
Definition: RealDrive.cc:467
void flushTrack() override
Definition: RealDrive.cc:447
void writeTrackByte(int idx, uint8_t val, bool addIdam) override
Definition: RealDrive.cc:398
bool isDiskInserted() const override
Is drive ready?
Definition: RealDrive.cc:97
EmuTime getNextSector(EmuTime::param time, RawTrack::Sector &sector) override
Definition: RealDrive.cc:417
unsigned getTrackLength() override
Definition: RealDrive.cc:392
bool getSide() const override
Definition: RealDrive.cc:136
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:72
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
Definition: lz4.cc:147
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
#define OUTER(type, member)
Definition: outer.hh:41