openMSX
AbstractIDEDevice.hh
Go to the documentation of this file.
1 #ifndef ABSTRACTIDEDEVICE_HH
2 #define ABSTRACTIDEDEVICE_HH
3 
4 #include "IDEDevice.hh"
5 #include "AlignedBuffer.hh"
6 #include "serialize_meta.hh"
7 #include <string>
8 
9 namespace openmsx {
10 
11 class MSXMotherBoard;
12 
14 {
15 public:
16  void reset(EmuTime::param time) override;
17 
18  word readData(EmuTime::param time) override;
19  byte readReg(nibble reg, EmuTime::param time) override;
20 
21  void writeData(word value, EmuTime::param time) override;
22  void writeReg(nibble reg, byte value, EmuTime::param time) override;
23 
24  template<typename Archive>
25  void serialize(Archive& ar, unsigned version);
26 
27 protected:
28  // Bit flags for the status register:
29  static constexpr byte DRDY = 0x40;
30  static constexpr byte DSC = 0x10;
31  static constexpr byte DRQ = 0x08;
32  static constexpr byte ERR = 0x01;
33 
34  // Bit flags for the error register:
35  static constexpr byte UNC = 0x40;
36  static constexpr byte IDNF = 0x10;
37  static constexpr byte ABORT = 0x04;
38 
39  explicit AbstractIDEDevice(MSXMotherBoard& motherBoard);
40  ~AbstractIDEDevice() override = default;
41 
45  virtual bool isPacketDevice() = 0;
46 
51  virtual const std::string& getDeviceName() = 0;
52 
58  virtual void fillIdentifyBlock(AlignedBuffer& buffer) = 0;
59 
69  virtual unsigned readBlockStart(AlignedBuffer& buffer, unsigned count) = 0;
70 
74  virtual void readEnd();
75 
81  virtual void writeBlockComplete(AlignedBuffer& buffer, unsigned count) = 0;
82 
87  virtual void executeCommand(byte cmd);
88 
92  void setError(byte error);
93 
97  unsigned getSectorNumber() const;
98 
101  unsigned getNumSectors() const;
102 
107  void setInterruptReason(byte value);
108 
112  unsigned getByteCount() const;
113 
117  void setByteCount(unsigned count);
118 
122  void setSectorNumber(unsigned lba);
123 
130  void startLongReadTransfer(unsigned count);
131 
140 
143  void abortReadTransfer(byte error);
144 
148  void startWriteTransfer(unsigned count);
149 
152  void abortWriteTransfer(byte error);
153 
154  byte getFeatureReg() const { return featureReg; }
155  void setLBALow (byte value) { sectorNumReg = value; }
156  void setLBAMid (byte value) { cylinderLowReg = value; }
157  void setLBAHigh(byte value) { cylinderHighReg = value; }
158 
159  MSXMotherBoard& getMotherBoard() const { return motherBoard; }
160 
161 private:
165  byte diagnostic();
166 
172  void createSignature(bool preserveDevice = false);
173 
178  void createIdentifyBlock(AlignedBuffer& buffer);
179 
182  void startReadTransfer();
183 
187  void readNextBlock();
188 
191  void setTransferRead(bool status);
192 
196  void writeNextBlock();
197 
200  void setTransferWrite(bool status);
201 
202  MSXMotherBoard& motherBoard;
203 
209  AlignedByteArray<512> buffer;
210 
213  unsigned transferIdx;
214 
217  unsigned bufferLeft;
218 
222  unsigned transferCount;
223 
224  // ATA registers:
225  byte errorReg;
226  byte sectorCountReg;
227  byte sectorNumReg;
228  byte cylinderLowReg;
229  byte cylinderHighReg;
230  byte devHeadReg;
231  byte statusReg;
232  byte featureReg;
233 
234  bool transferRead;
235  bool transferWrite;
236 };
237 
239 
240 } // namespace openmsx
241 
242 #endif // ABSTRACTIDEDEVICE_HH
openmsx::AbstractIDEDevice::startWriteTransfer
void startWriteTransfer(unsigned count)
Indicates the start of a write data transfer.
Definition: AbstractIDEDevice.cc:374
openmsx::AbstractIDEDevice::~AbstractIDEDevice
~AbstractIDEDevice() override=default
openmsx::AbstractIDEDevice::readBlockStart
virtual unsigned readBlockStart(AlignedBuffer &buffer, unsigned count)=0
Called when a block of read data should be buffered by the controller: when the buffer is empty or at...
openmsx::AbstractIDEDevice::DRDY
static constexpr byte DRDY
Definition: AbstractIDEDevice.hh:29
openmsx::AbstractIDEDevice::setLBAMid
void setLBAMid(byte value)
Definition: AbstractIDEDevice.hh:156
openmsx::AbstractIDEDevice::getFeatureReg
byte getFeatureReg() const
Definition: AbstractIDEDevice.hh:154
openmsx::AlignedByteArray< 512 >
openmsx::AbstractIDEDevice::DSC
static constexpr byte DSC
Definition: AbstractIDEDevice.hh:30
openmsx::REGISTER_BASE_NAME_HELPER
REGISTER_BASE_NAME_HELPER(MSXFDC, "FDC")
openmsx::AbstractIDEDevice::IDNF
static constexpr byte IDNF
Definition: AbstractIDEDevice.hh:36
serialize_meta.hh
IDEDevice.hh
openmsx::AbstractIDEDevice::writeBlockComplete
virtual void writeBlockComplete(AlignedBuffer &buffer, unsigned count)=0
Called when a block of written data has been buffered by the controller: when the buffer is full or a...
openmsx::AbstractIDEDevice::setError
void setError(byte error)
Indicates an error: sets error register, error flag, aborts transfers.
Definition: AbstractIDEDevice.cc:231
LZ4::count
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
Definition: lz4.cc:207
openmsx::AbstractIDEDevice::fillIdentifyBlock
virtual void fillIdentifyBlock(AlignedBuffer &buffer)=0
Tells a subclass to fill the device specific parts of the identify block located in the buffer.
openmsx::AbstractIDEDevice::readData
word readData(EmuTime::param time) override
Definition: AbstractIDEDevice.cc:163
openmsx::AbstractIDEDevice::setLBAHigh
void setLBAHigh(byte value)
Definition: AbstractIDEDevice.hh:157
openmsx::AbstractIDEDevice::readEnd
virtual void readEnd()
Called when a read transfer completes.
Definition: AbstractIDEDevice.cc:279
openmsx::AbstractIDEDevice::getDeviceName
virtual const std::string & getDeviceName()=0
Gets the device name to insert as "model number" into the identify block.
openmsx::AbstractIDEDevice::ERR
static constexpr byte ERR
Definition: AbstractIDEDevice.hh:32
openmsx::AbstractIDEDevice::executeCommand
virtual void executeCommand(byte cmd)
Starts execution of an IDE command.
Definition: AbstractIDEDevice.cc:283
openmsx::AbstractIDEDevice::setByteCount
void setByteCount(unsigned count)
Writes the byte count of a packet transfer in the registers.
Definition: AbstractIDEDevice.cc:265
openmsx::nibble
uint8_t nibble
4 bit integer
Definition: openmsx.hh:23
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:61
openmsx::AbstractIDEDevice::setInterruptReason
void setInterruptReason(byte value)
Writes the interrupt reason register.
Definition: AbstractIDEDevice.cc:255
AlignedBuffer.hh
openmsx::AbstractIDEDevice::reset
void reset(EmuTime::param time) override
Definition: AbstractIDEDevice.cc:57
openmsx::AbstractIDEDevice::getByteCount
unsigned getByteCount() const
Reads the byte count limit of a packet transfer in the registers.
Definition: AbstractIDEDevice.cc:260
openmsx::AlignedBuffer
Definition: AlignedBuffer.hh:28
openmsx::AbstractIDEDevice::UNC
static constexpr byte UNC
Definition: AbstractIDEDevice.hh:35
openmsx::AbstractIDEDevice::ABORT
static constexpr byte ABORT
Definition: AbstractIDEDevice.hh:37
openmsx::AbstractIDEDevice::startLongReadTransfer
void startLongReadTransfer(unsigned count)
Indicates the start of a read data transfer which uses blocks.
Definition: AbstractIDEDevice.cc:354
openmsx::AbstractIDEDevice::getNumSectors
unsigned getNumSectors() const
Gets the number of sectors indicated by the sector count register.
Definition: AbstractIDEDevice.cc:250
openmsx::AbstractIDEDevice::setLBALow
void setLBALow(byte value)
Definition: AbstractIDEDevice.hh:155
openmsx::AbstractIDEDevice::writeReg
void writeReg(nibble reg, byte value, EmuTime::param time) override
Definition: AbstractIDEDevice.cc:109
openmsx::AbstractIDEDevice::DRQ
static constexpr byte DRQ
Definition: AbstractIDEDevice.hh:31
openmsx::AbstractIDEDevice::getSectorNumber
unsigned getSectorNumber() const
Creates an LBA sector address from the contents of the sectorNumReg, cylinderLowReg,...
Definition: AbstractIDEDevice.cc:244
openmsx::AbstractIDEDevice::abortWriteTransfer
void abortWriteTransfer(byte error)
Aborts the write transfer in progress.
Definition: AbstractIDEDevice.cc:382
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::AbstractIDEDevice::startShortReadTransfer
AlignedBuffer & startShortReadTransfer(unsigned count)
Indicates the start of a read data transfer where all data fits into the buffer at once.
Definition: AbstractIDEDevice.cc:341
openmsx::AbstractIDEDevice
Definition: AbstractIDEDevice.hh:14
openmsx::AbstractIDEDevice::AbstractIDEDevice
AbstractIDEDevice(MSXMotherBoard &motherBoard)
Definition: AbstractIDEDevice.cc:13
openmsx::AbstractIDEDevice::readReg
byte readReg(nibble reg, EmuTime::param time) override
Definition: AbstractIDEDevice.cc:67
openmsx::AbstractIDEDevice::writeData
void writeData(word value, EmuTime::param time) override
Definition: AbstractIDEDevice.cc:197
openmsx::AbstractIDEDevice::getMotherBoard
MSXMotherBoard & getMotherBoard() const
Definition: AbstractIDEDevice.hh:159
openmsx::AbstractIDEDevice::abortReadTransfer
void abortReadTransfer(byte error)
Aborts the read transfer in progress.
Definition: AbstractIDEDevice.cc:368
openmsx::IDEDevice
Definition: IDEDevice.hh:10
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::AbstractIDEDevice::setSectorNumber
void setSectorNumber(unsigned lba)
Writes a 28-bit LBA sector number in the registers.
Definition: AbstractIDEDevice.cc:271
openmsx::AbstractIDEDevice::serialize
void serialize(Archive &ar, unsigned version)
Definition: AbstractIDEDevice.cc:445
openmsx::AbstractIDEDevice::isPacketDevice
virtual bool isPacketDevice()=0
Is this device a packet (ATAPI) device?