30 while ((*cdInUse)[
id]) {
36 name[2] = char(
'a' +
id);
37 (*cdInUse)[
id] =
true;
45 remMedStatNotifEnabled =
false;
50 readSectorData =
false;
59 unsigned id = name[2] -
'a';
60 assert((*cdInUse)[
id]);
61 (*cdInUse)[
id] =
false;
71 return "OPENMSX CD-ROM";
81 buf[0 * 2 + 0] = 0xC4;
84 buf[0 * 2 + 1] = 0x85;
87 buf[ 83 * 2 + 0] = 0x10;
89 buf[ 86 * 2 + 0] = remMedStatNotifEnabled * 0x10;
91 buf[127 * 2 + 0] = 0x01;
96 assert(readSectorData);
99 file.
seek(transferOffset);
101 transferOffset +=
count;
121 executePacketCommand(buf);
139 if (remMedStatNotifEnabled) {
152 mediaChanged =
false;
162 remMedStatNotifEnabled =
false;
170 remMedStatNotifEnabled =
true;
182 void IDECDROM::startPacketReadTransfer(
unsigned count)
189 unsigned packetSize = 512;
198 void IDECDROM::executePacketCommand(AlignedBuffer& packet)
208 readSectorData =
false;
218 const int byteCount = 18;
219 startPacketReadTransfer(byteCount);
221 for (
auto i :
xrange(byteCount)) {
225 buf[ 2] = senseKey >> 16;
226 buf[12] = (senseKey >> 8) & 0xFF;
227 buf[13] = senseKey & 0xFF;
228 buf[ 7] = byteCount - 7;
234 int format = packet[2] & 0x0F;
252 fprintf(stderr,
" read TOC: format %d not implemented\n", format);
282 readSectorData =
true;
283 transferOffset = sectorNumber * 2048;
284 unsigned count = sectorCount * 2048;
285 startPacketReadTransfer(
count);
290 fprintf(stderr,
" unknown packet command 0x%02X\n", packet[0]);
299 senseKey = 0x06 << 16;
307 senseKey = 0x06 << 16;
318 scheduler_, cd_.name)
326 if (tokens.size() == 1) {
327 auto& file = cd.file;
329 file.is_open() ? file.getURL() :
string{});
331 }
else if ((tokens.size() == 2) && (tokens[1] ==
one_of(
"eject",
"-eject"))) {
334 if (tokens[1] ==
"-eject") {
335 result =
"Warning: use of '-eject' is deprecated, "
336 "instead use the 'eject' subcommand";
338 }
else if ((tokens.size() == 2) ||
339 ((tokens.size() == 3) && (tokens[1] ==
"insert"))) {
341 if (tokens[1] ==
"insert") {
342 if (tokens.size() > 2) {
346 "Missing argument to insert subcommand");
351 tokens[fileToken].getString());
366 cd.name,
" : display the cd image for this CD-ROM drive\n",
367 cd.name,
" eject : eject the cd image from this CD-ROM drive\n",
368 cd.name,
" insert <filename> : change the cd image for this CD-ROM drive\n",
369 cd.name,
" <filename> : change the cd image for this CD-ROM drive\n");
374 using namespace std::literals;
375 static constexpr std::array extra = {
"eject"sv,
"insert"sv};
380 template<
typename Archive>
383 ar.template serializeBase<AbstractIDEDevice>(*
this);
385 string filename = file.is_open() ? file.getURL() :
string{};
387 if constexpr (Archive::IS_LOADER) {
396 ar.serialize(
"byteCountLimit", byteCountLimit,
397 "transferOffset", transferOffset,
398 "senseKey", senseKey,
399 "readSectorData", readSectorData,
400 "remMedStatNotifEnabled", remMedStatNotifEnabled,
401 "mediaChanged", mediaChanged);
void startWriteTransfer(unsigned count)
Indicates the start of a write data transfer.
MSXMotherBoard & getMotherBoard() const
byte getFeatureReg() const
AlignedBuffer & startShortReadTransfer(unsigned count)
Indicates the start of a read data transfer where all data fits into the buffer at once.
void startLongReadTransfer(unsigned count)
Indicates the start of a read data transfer which uses blocks.
virtual void executeCommand(byte cmd)
Starts execution of an IDE command.
void setByteCount(unsigned count)
Writes the byte count of a packet transfer in the registers.
void abortReadTransfer(byte error)
Aborts the read transfer in progress.
unsigned getByteCount() const
Reads the byte count limit of a packet transfer in the registers.
void setLBAMid(byte value)
void setError(byte error)
Indicates an error: sets error register, error flag, aborts transfers.
void setLBAHigh(byte value)
void setInterruptReason(byte value)
Writes the interrupt reason register.
static constexpr byte ABORT
void execute(std::span< const TclObject > tokens, TclObject &result, EmuTime::param time) override
This is like the execute() method of the Command class, it only has an extra time parameter.
std::string help(std::span< const TclObject > tokens) const override
Print help for this command.
void tabCompletion(std::vector< std::string > &tokens) const override
Attempt tab completion for this command.
CDXCommand(CommandController &commandController, StateChangeDistributor &stateChangeDistributor, Scheduler &scheduler, IDECDROM &cd)
virtual void update(UpdateType type, std::string_view name, std::string_view value)=0
static void completeFileName(std::vector< std::string > &tokens, const FileContext &context, const RANGE &extra)
std::string resolve(std::string_view filename) const
void close()
Close the current file.
void seek(size_t pos)
Move read/write pointer to the specified position.
void read(void *buffer, size_t num)
Read from file.
bool is_open() const
Return true iff this file handle refers to an open file.
IDECDROM(const IDECDROM &)=delete
std::string_view getDeviceName() override
Gets the device name to insert as "model number" into the identify block.
void serialize(Archive &ar, unsigned version)
unsigned readBlockStart(AlignedBuffer &buffer, unsigned count) override
Called when a block of read data should be buffered by the controller: when the buffer is empty or at...
void writeBlockComplete(AlignedBuffer &buffer, unsigned count) override
Called when a block of written data has been buffered by the controller: when the buffer is full or a...
void readEnd() override
Called when a read transfer completes.
void fillIdentifyBlock(AlignedBuffer &buffer) override
Tells a subclass to fill the device specific parts of the identify block located in the buffer.
void executeCommand(byte cmd) override
Starts execution of an IDE command.
bool isPacketDevice() override
Is this device a packet (ATAPI) device?
void insert(const std::string &filename)
CliComm & getMSXCliComm()
std::shared_ptr< T > getSharedStuff(std::string_view name, Args &&...args)
Some MSX device parts are shared between several MSX devices (e.g.
Commands that directly influence the MSX state should send and events so that they can be recorded by...
void addListElement(const T &t)
ALWAYS_INLINE uint32_t read_UA_B32(const void *p)
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).
This file implemented 3 utility functions:
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
constexpr const char *const filename
FileContext userFileContext(string_view savePath)
size_t size(std::string_view utf8)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)
std::string strCat(Ts &&...ts)
constexpr auto xrange(T e)