31 TclObject& result, EmuTime::param time)
override;
32 [[nodiscard]]
string help(
const vector<string>& tokens)
const override;
46 while ((*cdInUse)[id]) {
52 name[2] = char(
'a' +
id);
53 (*cdInUse)[id] =
true;
54 cdxCommand = std::make_unique<CDXCommand>(
61 remMedStatNotifEnabled =
false;
66 readSectorData =
false;
75 unsigned id = name[2] -
'a';
76 assert((*cdInUse)[
id]);
77 (*cdInUse)[id] =
false;
87 return "OPENMSX CD-ROM";
97 buf[0 * 2 + 0] = 0xC4;
100 buf[0 * 2 + 1] = 0x85;
103 buf[ 83 * 2 + 0] = 0x10;
105 buf[ 86 * 2 + 0] = remMedStatNotifEnabled * 0x10;
107 buf[127 * 2 + 0] = 0x01;
112 assert(readSectorData);
115 file.
seek(transferOffset);
117 transferOffset +=
count;
137 executePacketCommand(buf);
155 if (remMedStatNotifEnabled) {
168 mediaChanged =
false;
178 remMedStatNotifEnabled =
false;
186 remMedStatNotifEnabled =
true;
198 void IDECDROM::startPacketReadTransfer(
unsigned count)
205 unsigned packetSize = 512;
214 void IDECDROM::executePacketCommand(AlignedBuffer& packet)
224 readSectorData =
false;
234 const int byteCount = 18;
235 startPacketReadTransfer(byteCount);
237 for (
auto i :
xrange(byteCount)) {
241 buf[ 2] = senseKey >> 16;
242 buf[12] = (senseKey >> 8) & 0xFF;
243 buf[13] = senseKey & 0xFF;
244 buf[ 7] = byteCount - 7;
250 int format = packet[2] & 0x0F;
268 fprintf(stderr,
" read TOC: format %d not implemented\n", format);
298 readSectorData =
true;
299 transferOffset = sectorNumber * 2048;
300 unsigned count = sectorCount * 2048;
301 startPacketReadTransfer(
count);
306 fprintf(stderr,
" unknown packet command 0x%02X\n", packet[0]);
315 senseKey = 0x06 << 16;
323 senseKey = 0x06 << 16;
334 scheduler_, cd_.name)
342 if (tokens.
size() == 1) {
343 auto& file = cd.file;
345 file.is_open() ? file.getURL() :
string{});
347 }
else if ((tokens.
size() == 2) && (tokens[1] ==
one_of(
"eject",
"-eject"))) {
350 if (tokens[1] ==
"-eject") {
351 result =
"Warning: use of '-eject' is deprecated, "
352 "instead use the 'eject' subcommand";
354 }
else if ((tokens.
size() == 2) ||
355 ((tokens.
size() == 3) && (tokens[1] ==
"insert"))) {
357 if (tokens[1] ==
"insert") {
358 if (tokens.
size() > 2) {
362 "Missing argument to insert subcommand");
367 tokens[fileToken].getString());
382 cd.name,
" : display the cd image for this CD-ROM drive\n",
383 cd.name,
" eject : eject the cd image from this CD-ROM drive\n",
384 cd.name,
" insert <filename> : change the cd image for this CD-ROM drive\n",
385 cd.name,
" <filename> : change the cd image for this CD-ROM drive\n");
390 using namespace std::literals;
391 static constexpr std::array extra = {
"eject"sv,
"insert"sv};
396 template<
typename Archive>
399 ar.template serializeBase<AbstractIDEDevice>(*
this);
401 string filename = file.is_open() ? file.getURL() :
string{};
412 ar.serialize(
"byteCountLimit", byteCountLimit,
413 "transferOffset", transferOffset,
414 "senseKey", senseKey,
415 "readSectorData", readSectorData,
416 "remMedStatNotifEnabled", remMedStatNotifEnabled,
417 "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(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.
CDXCommand(CommandController &commandController, StateChangeDistributor &stateChangeDistributor, Scheduler &scheduler, IDECDROM &cd)
string help(const vector< string > &tokens) const override
Print help for this command.
void tabCompletion(vector< string > &tokens) const override
Attempt tab completion for this command.
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)
const std::string & getMessage() const &
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)
constexpr index_type size() const noexcept
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)