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
10namespace openmsx {
11
12class Scheduler;
13class DiskDrive;
14class CliComm;
15
16class WD2793 final : public Schedulable
17{
18public:
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) const;
26 byte getSectorReg(EmuTime::param time) const;
27 byte getDataReg (EmuTime::param time);
28
29 [[nodiscard]] byte peekStatusReg(EmuTime::param time) const;
30 [[nodiscard]] byte peekTrackReg (EmuTime::param time) const;
31 [[nodiscard]] byte peekSectorReg(EmuTime::param time) const;
32 [[nodiscard]] 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) const;
40 bool getDTRQ(EmuTime::param time) const;
41
42 [[nodiscard]] bool peekIRQ (EmuTime::param time) const;
43 [[nodiscard]] 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
66private:
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 [[nodiscard]] bool isReady() const;
102
103 void schedule(FSMState state, EmuTime::param time);
104
105private:
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
This class calculates CRC numbers for the polygon x^16 + x^12 + x^5 + 1.
Definition: CRC16.hh:17
This (abstract) class defines the DiskDrive interface.
Definition: DiskDrive.hh:13
Represents a clock with a variable frequency.
Definition: DynamicClock.hh:16
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
bool peekIRQ(EmuTime::param time) const
Definition: WD2793.cc:108
byte peekStatusReg(EmuTime::param time) const
Definition: WD2793.cc:208
@ FSM_POST_WRITE_SECTOR
Definition: WD2793.hh:58
@ FSM_TYPE2_LOADED
Definition: WD2793.hh:52
@ FSM_WRITE_SECTOR
Definition: WD2793.hh:57
@ FSM_TYPE2_NOT_FOUND
Definition: WD2793.hh:53
@ FSM_PRE_WRITE_SECTOR
Definition: WD2793.hh:56
@ FSM_TYPE3_ROTATED
Definition: WD2793.hh:60
@ FSM_TYPE3_LOADED
Definition: WD2793.hh:59
@ FSM_TYPE2_ROTATED
Definition: WD2793.hh:54
byte getTrackReg(EmuTime::param time) const
Definition: WD2793.cc:219
byte getDataReg(EmuTime::param time)
Definition: WD2793.cc:258
byte getSectorReg(EmuTime::param time) const
Definition: WD2793.cc:234
WD2793(Scheduler &scheduler, DiskDrive &drive, CliComm &cliComm, EmuTime::param time, bool isWD1770)
This class has emulation for WD1770, WD1793, WD2793.
Definition: WD2793.cc:47
bool peekDTRQ(EmuTime::param time) const
Definition: WD2793.cc:93
bool getDTRQ(EmuTime::param time) const
Definition: WD2793.cc:88
byte getStatusReg(EmuTime::param time)
Definition: WD2793.cc:168
byte peekTrackReg(EmuTime::param time) const
Definition: WD2793.cc:224
void serialize(Archive &ar, unsigned version)
Definition: WD2793.cc:1120
void setTrackReg(byte value, EmuTime::param time)
Definition: WD2793.cc:214
void setDataReg(byte value, EmuTime::param time)
Definition: WD2793.cc:244
byte peekDataReg(EmuTime::param time) const
Definition: WD2793.cc:323
void setCommandReg(byte value, EmuTime::param time)
Definition: WD2793.cc:120
bool getIRQ(EmuTime::param time) const
Definition: WD2793.cc:103
void reset(EmuTime::param time)
Definition: WD2793.cc:69
void setSectorReg(byte value, EmuTime::param time)
Definition: WD2793.cc:229
byte peekSectorReg(EmuTime::param time) const
Definition: WD2793.cc:239
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)