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