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 "Clock.hh"
6 #include "Schedulable.hh"
7 #include "ThrottleManager.hh"
8 #include "outer.hh"
9 #include "serialize_meta.hh"
10 #include <bitset>
11 #include <memory>
12 #include <optional>
13 
14 namespace openmsx {
15 
16 class MSXMotherBoard;
17 class DiskChanger;
18 
21 class RealDrive final : public DiskDrive
22 {
23 public:
24  RealDrive(MSXMotherBoard& motherBoard, EmuDuration::param motorTimeout,
25  bool signalsNeedMotorOn, bool doubleSided,
26  DiskDrive::TrackMode trackMode);
27  ~RealDrive() override;
28 
29  // DiskDrive interface
30  [[nodiscard]] bool isDiskInserted() const override;
31  [[nodiscard]] bool isWriteProtected() const override;
32  [[nodiscard]] bool isDoubleSided() const override;
33  [[nodiscard]] bool isTrack00() const override;
34  void setSide(bool side) override;
35  [[nodiscard]] bool getSide() const override;
36  void step(bool direction, EmuTime::param time) override;
37  void setMotor(bool status, EmuTime::param time) override;
38  [[nodiscard]] bool getMotor() const override;
39  [[nodiscard]] bool indexPulse(EmuTime::param time) override;
40  [[nodiscard]] EmuTime getTimeTillIndexPulse(EmuTime::param time, int count) override;
41 
42  [[nodiscard]] unsigned getTrackLength() override;
43  void writeTrackByte(int idx, byte val, bool addIdam) override;
44  [[nodiscard]] byte readTrackByte(int idx) override;
45  EmuTime getNextSector(EmuTime::param time, RawTrack::Sector& sector) override;
46  void flushTrack() override;
47  bool diskChanged() override;
48  [[nodiscard]] bool peekDiskChanged() const override;
49  [[nodiscard]] bool isDummyDrive() const override;
50 
51  void applyWd2793ReadTrackQuirk() override;
52  void invalidateWd2793ReadTrackQuirk() override;
53 
54  template<typename Archive>
55  void serialize(Archive& ar, unsigned version);
56 
57 private:
58  struct SyncLoadingTimeout final : Schedulable {
59  friend class RealDrive;
60  explicit SyncLoadingTimeout(Scheduler& s) : Schedulable(s) {}
61  void executeUntil(EmuTime::param /*time*/) override {
62  auto& drive = OUTER(RealDrive, syncLoadingTimeout);
63  drive.execLoadingTimeout();
64  }
65  } syncLoadingTimeout;
66 
67  struct SyncMotorTimeout final : Schedulable {
68  friend class RealDrive;
69  explicit SyncMotorTimeout(Scheduler& s) : Schedulable(s) {}
70  void executeUntil(EmuTime::param time) override {
71  auto& drive = OUTER(RealDrive, syncMotorTimeout);
72  drive.execMotorTimeout(time);
73  }
74  } syncMotorTimeout;
75 
76  void execLoadingTimeout();
77  void execMotorTimeout(EmuTime::param time);
78  [[nodiscard]] EmuTime::param getCurrentTime() const { return syncLoadingTimeout.getCurrentTime(); }
79 
80  void doSetMotor(bool status, EmuTime::param time);
81  void setLoading(EmuTime::param time);
82  [[nodiscard]] unsigned getCurrentAngle(EmuTime::param time) const;
83 
84  [[nodiscard]] unsigned getMaxTrack() const;
85  [[nodiscard]] std::optional<unsigned> getDiskReadTrack() const;
86  [[nodiscard]] std::optional<unsigned> getDiskWriteTrack() const;
87  void getTrack();
88  void invalidateTrack();
89 
90 private:
91  static constexpr unsigned TICKS_PER_ROTATION = 200000;
92  static constexpr unsigned INDEX_DURATION = TICKS_PER_ROTATION / 50;
93 
94  MSXMotherBoard& motherBoard;
95  LoadingIndicator loadingIndicator;
96  const EmuDuration motorTimeout;
97 
99  MotorClock motorTimer;
100  std::unique_ptr<DiskChanger> changer;
101  unsigned headPos;
102  unsigned side;
103  unsigned startAngle;
104  bool motorStatus;
105  const bool doubleSizedDrive;
106  const bool signalsNeedMotorOn;
107  const DiskDrive::TrackMode trackMode;
108 
109  static constexpr unsigned MAX_DRIVES = 26; // a-z
110  using DrivesInUse = std::bitset<MAX_DRIVES>;
111  std::shared_ptr<DrivesInUse> drivesInUse;
112 
113  RawTrack track;
114  bool trackValid;
115  bool trackDirty;
116 };
118 
119 } // namespace openmsx
120 
121 #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:22
void applyWd2793ReadTrackQuirk() override
See RawTrack::applyWd2793ReadTrackQuirk()
Definition: RealDrive.cc:447
bool isDoubleSided() const override
Is disk double sided?
Definition: RealDrive.cc:99
bool peekDiskChanged() const override
Definition: RealDrive.cc:437
void serialize(Archive &ar, unsigned version)
Definition: RealDrive.cc:465
bool isTrack00() const override
Head above track 0.
Definition: RealDrive.cc:194
void step(bool direction, EmuTime::param time) override
Step head.
Definition: RealDrive.cc:173
void invalidateWd2793ReadTrackQuirk() override
Definition: RealDrive.cc:452
void writeTrackByte(int idx, byte val, bool addIdam) override
Definition: RealDrive.cc:373
bool isWriteProtected() const override
Is disk write protected?
Definition: RealDrive.cc:91
bool getMotor() const override
Returns the previously set motor status.
Definition: RealDrive.cc:259
void setMotor(bool status, EmuTime::param time) override
Set motor on/off.
Definition: RealDrive.cc:204
void setSide(bool side) override
Side select.
Definition: RealDrive.cc:105
byte readTrackByte(int idx) override
Definition: RealDrive.cc:382
bool diskChanged() override
Is disk changed?
Definition: RealDrive.cc:432
bool indexPulse(EmuTime::param time) override
Gets the state of the index pulse.
Definition: RealDrive.cc:317
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:328
~RealDrive() override
Definition: RealDrive.cc:55
bool isDummyDrive() const override
Is there a dummy (unconnected) drive?
Definition: RealDrive.cc:442
void flushTrack() override
Definition: RealDrive.cc:422
bool isDiskInserted() const override
Is drive ready?
Definition: RealDrive.cc:72
EmuTime getNextSector(EmuTime::param time, RawTrack::Sector &sector) override
Definition: RealDrive.cc:392
unsigned getTrackLength() override
Definition: RealDrive.cc:367
bool getSide() const override
Definition: RealDrive.cc:111
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:207
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
#define OUTER(type, member)
Definition: outer.hh:41