openMSX
WD2793.hh
Go to the documentation of this file.
1 #ifndef WD2793_HH
2 #define WD2793_HH
3 
4 #include "RawTrack.hh"
5 #include "DynamicClock.hh"
6 #include "Schedulable.hh"
7 #include "CRC16.hh"
8 #include "serialize_meta.hh"
9 
10 namespace openmsx {
11 
12 class Scheduler;
13 class DiskDrive;
14 class CliComm;
15 
16 class WD2793 final : public Schedulable
17 {
18 public:
19  WD2793(Scheduler& scheduler, DiskDrive& drive, CliComm& cliComm,
20  EmuTime::param time, bool isWD1770);
21 
22  void reset(EmuTime::param time);
23 
24  byte getStatusReg(EmuTime::param time);
25  byte getTrackReg (EmuTime::param time);
26  byte getSectorReg(EmuTime::param time);
27  byte getDataReg (EmuTime::param time);
28 
29  byte peekStatusReg(EmuTime::param time) const;
30  byte peekTrackReg (EmuTime::param time) const;
31  byte peekSectorReg(EmuTime::param time) const;
32  byte peekDataReg (EmuTime::param time) const;
33 
34  void setCommandReg(byte value, EmuTime::param time);
35  void setTrackReg (byte value, EmuTime::param time);
36  void setSectorReg (byte value, EmuTime::param time);
37  void setDataReg (byte value, EmuTime::param time);
38 
39  bool getIRQ (EmuTime::param time);
40  bool getDTRQ(EmuTime::param time);
41 
42  bool peekIRQ (EmuTime::param time) const;
43  bool peekDTRQ(EmuTime::param time) const;
44 
45  template<typename Archive>
46  void serialize(Archive& ar, unsigned version);
47 
48  // public for serialize
49  enum FSMState {
64  };
65 
66 private:
67  void executeUntil(EmuTime::param time) override;
68 
69  void startType1Cmd(EmuTime::param time);
70 
71  void seek(EmuTime::param time);
72  void step(EmuTime::param time);
73  void seekNext(EmuTime::param time);
74  void endType1Cmd(EmuTime::param time);
75 
76  void startType2Cmd (EmuTime::param time);
77  void type2Loaded (EmuTime::param time);
78  void type2Search (EmuTime::param time);
79  void type2NotFound (EmuTime::param time);
80  void type2Rotated (EmuTime::param time);
81  void startReadSector (EmuTime::param time);
82  void startWriteSector(EmuTime::param time);
83  void checkStartWrite (EmuTime::param time);
84  void preWriteSector (EmuTime::param time);
85  void writeSectorData (EmuTime::param time);
86  void postWriteSector (EmuTime::param time);
87 
88  void startType3Cmd (EmuTime::param time);
89  void type3Loaded (EmuTime::param time);
90  void type3Rotated (EmuTime::param time);
91  void readAddressCmd (EmuTime::param time);
92  void readTrackCmd (EmuTime::param time);
93  void startWriteTrack (EmuTime::param time);
94  void writeTrackData (EmuTime::param time);
95 
96  void startType4Cmd(EmuTime::param time);
97 
98  void endCmd(EmuTime::param time);
99 
100  void setDrqRate(unsigned trackLength);
101  bool isReady() const;
102 
103  void schedule(FSMState state, EmuTime::param time);
104 
105 private:
106  DiskDrive& drive;
107  CliComm& cliComm;
108 
109  // DRQ is high iff current time is past this time.
110  // This clock ticks at the 'byte-rate' of the current track,
111  // typically '6250 bytes/rotation * 5 rotations/second'.
112  DynamicClock drqTime;
113 
114  // INTRQ is high iff current time is past this time.
115  EmuTime irqTime;
116 
117  EmuTime pulse5; // time at which the 5th index pulse will be received
118 
119  // HLD/HLT timing
120  // 1) now < hldTime (typically: hldTime == EmuTime::infinity)
121  // ==> HLD=false, WD2793 did not request head to be loaded
122  // 2) hldTime <= now < hldTime + LOAD
123  // ==> HLD=true, HLT=false, head loading is in progress
124  // 3) hldTime + LOAD <= now < hldTime + LOAD + IDLE
125  // ==> HLD=true, HLT=true, head is loaded
126  // 4) hldTime + LOAD + IDLE <= now
127  // ==> HLD=false, idle for 15 revolutions HLD made deactive again
128  // Note: is all MSX machines I've checked so far, WD2793 pins
129  // - HLD (pin 28) is unconnected
130  // - HLT (pin 40) is connected to +5V
131  // This means there is no head-load delay, or IOW as soon as the WD2793
132  // requests to load the disk head, the drive responds with "ok, done".
133  // So 'LOAD' is zero, and phase 2) doesn't exist. Therefor the current
134  // implementation mostly ignores 'LOAD'.
135  static const EmuDuration IDLE;
136  EmuTime hldTime;
137 
138  RawTrack::Sector sectorInfo;
139  int dataCurrent; // which byte in track is next to be read/write
140  int dataAvailable; // how many bytes left to read/write
141 
142  CRC16 crc;
143 
144  FSMState fsmState;
145  byte statusReg;
146  byte commandReg;
147  byte sectorReg;
148  byte trackReg;
149  byte dataReg;
150  byte dataOutReg;
151 
152  bool directionIn;
153  bool immediateIRQ;
154  bool lastWasA1;
155  bool dataRegWritten;
156  bool lastWasCRC;
157 
158  const bool isWD1770;
159 };
161 
162 } // namespace openmsx
163 
164 #endif
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:319
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:121
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:165
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:236
byte getSectorReg(EmuTime::param time)
Definition: WD2793.cc:231
bool getDTRQ(EmuTime::param time)
Definition: WD2793.cc:89
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
void serialize(Archive &ar, unsigned version)
Definition: WD2793.cc:1112
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
This class calculates CRC numbers for the polygon x^16 + x^12 + x^5 + 1.
Definition: CRC16.hh:13
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:15
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:226
void reset(EmuTime::param time)
Definition: WD2793.cc:70
WD2793(Scheduler &scheduler, DiskDrive &drive, CliComm &cliComm, EmuTime::param time, bool isWD1770)
This class has emulation for WD1770, WD1793, WD2793.
Definition: WD2793.cc:47
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:255
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:205
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:109
This (abstract) class defines the DiskDrive interface.
Definition: DiskDrive.hh:12
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:221
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:211
bool getIRQ(EmuTime::param time)
Definition: WD2793.cc:104
byte getTrackReg(EmuTime::param time)
Definition: WD2793.cc:216
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:94
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:241