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  EmuTime hldTime;
136 
137  RawTrack::Sector sectorInfo;
138  int dataCurrent; // which byte in track is next to be read/write
139  int dataAvailable; // how many bytes left to read/write
140 
141  CRC16 crc;
142 
143  FSMState fsmState;
144  byte statusReg;
145  byte commandReg;
146  byte sectorReg;
147  byte trackReg;
148  byte dataReg;
149  byte dataOutReg;
150 
151  bool directionIn;
152  bool immediateIRQ;
153  bool lastWasA1;
154  bool dataRegWritten;
155  bool lastWasCRC;
156 
157  const bool isWD1770;
158 };
160 
161 } // namespace openmsx
162 
163 #endif
openmsx::Scheduler
Definition: Scheduler.hh:34
CRC16.hh
openmsx::DiskDrive
This (abstract) class defines the DiskDrive interface.
Definition: DiskDrive.hh:13
serialize_meta.hh
openmsx::WD2793::getIRQ
bool getIRQ(EmuTime::param time)
Definition: WD2793.cc:105
openmsx::WD2793::getDataReg
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:260
openmsx::Schedulable
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
openmsx::WD2793::peekStatusReg
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:210
openmsx::WD2793::peekIRQ
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:110
Schedulable.hh
openmsx::WD2793::getStatusReg
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:170
openmsx::WD2793::FSM_NONE
@ FSM_NONE
Definition: WD2793.hh:50
openmsx::WD2793::getTrackReg
byte getTrackReg(EmuTime::param time)
Definition: WD2793.cc:221
openmsx::SERIALIZE_CLASS_VERSION
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
openmsx::DynamicClock
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:17
openmsx::WD2793::FSM_TYPE3_ROTATED
@ FSM_TYPE3_ROTATED
Definition: WD2793.hh:60
openmsx::WD2793::FSM_PRE_WRITE_SECTOR
@ FSM_PRE_WRITE_SECTOR
Definition: WD2793.hh:56
openmsx::WD2793::FSM_READ_TRACK
@ FSM_READ_TRACK
Definition: WD2793.hh:62
openmsx::CRC16
This class calculates CRC numbers for the polygon x^16 + x^12 + x^5 + 1.
Definition: CRC16.hh:36
openmsx::WD2793::serialize
void serialize(Archive &ar, unsigned version)
Definition: WD2793.cc:1122
openmsx::WD2793::getSectorReg
byte getSectorReg(EmuTime::param time)
Definition: WD2793.cc:236
openmsx::WD2793::FSM_WRITE_SECTOR
@ FSM_WRITE_SECTOR
Definition: WD2793.hh:57
openmsx::WD2793
Definition: WD2793.hh:17
openmsx::WD2793::FSM_SEEK
@ FSM_SEEK
Definition: WD2793.hh:51
openmsx::WD2793::FSMState
FSMState
Definition: WD2793.hh:49
openmsx::WD2793::setDataReg
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:246
openmsx::WD2793::FSM_IDX_IRQ
@ FSM_IDX_IRQ
Definition: WD2793.hh:63
openmsx::WD2793::FSM_CHECK_WRITE
@ FSM_CHECK_WRITE
Definition: WD2793.hh:55
RawTrack.hh
openmsx::WD2793::FSM_WRITE_TRACK
@ FSM_WRITE_TRACK
Definition: WD2793.hh:61
openmsx::WD2793::FSM_TYPE2_NOT_FOUND
@ FSM_TYPE2_NOT_FOUND
Definition: WD2793.hh:53
openmsx::RawTrack::Sector
Definition: RawTrack.hh:74
openmsx::WD2793::peekSectorReg
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:241
openmsx::WD2793::FSM_POST_WRITE_SECTOR
@ FSM_POST_WRITE_SECTOR
Definition: WD2793.hh:58
openmsx::WD2793::WD2793
WD2793(Scheduler &scheduler, DiskDrive &drive, CliComm &cliComm, EmuTime::param time, bool isWD1770)
This class has emulation for WD1770, WD1793, WD2793.
Definition: WD2793.cc:47
openmsx::CliComm
Definition: CliComm.hh:11
openmsx::WD2793::setCommandReg
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:122
openmsx::Scheduler
Scheduler
Definition: Scheduler.cc:132
DynamicClock.hh
openmsx::WD2793::peekDataReg
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:325
openmsx::WD2793::FSM_TYPE2_ROTATED
@ FSM_TYPE2_ROTATED
Definition: WD2793.hh:54
openmsx::WD2793::peekDTRQ
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:95
openmsx::WD2793::FSM_TYPE3_LOADED
@ FSM_TYPE3_LOADED
Definition: WD2793.hh:59
openmsx::WD2793::peekTrackReg
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:226
openmsx::WD2793::setSectorReg
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:231
openmsx::WD2793::getDTRQ
bool getDTRQ(EmuTime::param time)
Definition: WD2793.cc:90
openmsx::WD2793::setTrackReg
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:216
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::WD2793::reset
void reset(EmuTime::param time)
Definition: WD2793.cc:71
openmsx::WD2793::FSM_TYPE2_LOADED
@ FSM_TYPE2_LOADED
Definition: WD2793.hh:52