32 , devName(config.getChildData(
"name",
"openMSX CD-ROM"))
37 while ((*cdInUse)[
id]) {
43 name[2] = char(
'a' +
id);
44 (*cdInUse)[
id] =
true;
52 remMedStatNotifEnabled =
false;
57 readSectorData =
false;
68 unsigned id = name[2] -
'a';
69 assert((*cdInUse)[
id]);
70 (*cdInUse)[
id] =
false;
95 buf[0 * 2 + 0] = 0xC4;
98 buf[0 * 2 + 1] = 0x85;
101 buf[ 83 * 2 + 0] = 0x10;
103 buf[ 86 * 2 + 0] = remMedStatNotifEnabled * 0x10;
105 buf[127 * 2 + 0] = 0x01;
110 assert(readSectorData);
113 file.
seek(transferOffset);
114 file.
read(std::span{buf.
data(), count});
115 transferOffset += count;
135 executePacketCommand(buf);
153 if (remMedStatNotifEnabled) {
166 mediaChanged =
false;
176 remMedStatNotifEnabled =
false;
184 remMedStatNotifEnabled =
true;
196void IDECDROM::startPacketReadTransfer(
unsigned count)
203 unsigned packetSize = 512;
207 unsigned size = std::min(packetSize, count);
212void IDECDROM::executePacketCommand(AlignedBuffer& packet)
222 readSectorData =
false;
232 const int byteCount = 18;
233 startPacketReadTransfer(byteCount);
235 for (
auto i :
xrange(byteCount)) {
239 buf[ 2] = narrow_cast<byte>((senseKey >> 16) & 0xFF);
240 buf[12] = narrow_cast<byte>((senseKey >> 8) & 0xFF);
241 buf[13] = narrow_cast<byte>((senseKey >> 0) & 0xFF);
242 buf[ 7] = byteCount - 7;
248 int format = packet[2] & 0x0F;
266 fprintf(stderr,
" read TOC: format %d not implemented\n", format);
296 readSectorData =
true;
297 transferOffset = sectorNumber * 2048;
298 unsigned count = sectorCount * 2048;
299 startPacketReadTransfer(count);
304 fprintf(stderr,
" unknown packet command 0x%02X\n", packet[0]);
313 senseKey = 0x06 << 16;
319 file =
File(filename);
321 senseKey = 0x06 << 16;
332 scheduler_, cd_.name)
340 if (tokens.size() == 1) {
341 const auto& file = cd.file;
343 file.is_open() ? file.getURL() : std::string{});
345 }
else if ((tokens.size() == 2) && (tokens[1] ==
one_of(
"eject",
"-eject"))) {
348 if (tokens[1] ==
"-eject") {
349 result =
"Warning: use of '-eject' is deprecated, "
350 "instead use the 'eject' subcommand";
352 }
else if ((tokens.size() == 2) ||
353 ((tokens.size() == 3) && (tokens[1] ==
"insert"))) {
355 if (tokens[1] ==
"insert") {
356 if (tokens.size() > 2) {
360 "Missing argument to insert subcommand");
365 tokens[fileToken].getString());
379 cd.name,
" : display the cd image for this CD-ROM drive\n",
380 cd.name,
" eject : eject the cd image from this CD-ROM drive\n",
381 cd.name,
" insert <filename> : change the cd image for this CD-ROM drive\n",
382 cd.name,
" <filename> : change the cd image for this CD-ROM drive\n");
387 using namespace std::literals;
388 static constexpr std::array extra = {
"eject"sv,
"insert"sv};
393template<
typename Archive>
396 ar.template serializeBase<AbstractIDEDevice>(*
this);
398 std::string filename = file.
is_open() ? file.
getURL() : std::string{};
399 ar.serialize(
"filename", filename);
400 if constexpr (Archive::IS_LOADER) {
402 if (filename.empty()) {
409 ar.serialize(
"byteCountLimit", byteCountLimit,
410 "transferOffset", transferOffset,
411 "senseKey", senseKey,
412 "readSectorData", readSectorData,
413 "remMedStatNotifEnabled", remMedStatNotifEnabled,
414 "mediaChanged", mediaChanged);
void startWriteTransfer(unsigned count)
Indicates the start of a write data transfer.
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.
MSXMotherBoard & getMotherBoard() const
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)
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(std::span< uint8_t > buffer)
Read from file.
bool is_open() const
Return true iff this file handle refers to an open file.
const std::string & getURL() const
Returns the URL of this file object.
std::string_view getDeviceName() override
Gets the device name to insert as "model number" into the identify block.
void serialize(Archive &ar, unsigned version)
std::bitset< MAX_CD > CDInUse
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...
IDECDROM(const DeviceConfig &config)
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.
static constexpr unsigned MAX_CD
void getMediaInfo(TclObject &result) override
This method gets called when information is required on the media inserted in the media slot of the p...
void executeCommand(byte cmd) override
Starts execution of an IDE command.
bool isPacketDevice() override
Is this device a packet (ATAPI) device?
static std::shared_ptr< CDInUse > getDrivesInUse(MSXMotherBoard &motherBoard)
void insert(const std::string &filename)
void update(UpdateType type, std::string_view name, std::string_view value) override
std::shared_ptr< T > getSharedStuff(std::string_view name, Args &&...args)
Some MSX device parts are shared between several MSX devices (e.g.
void registerMediaInfo(std::string_view name, MediaInfoProvider &provider)
Register and unregister providers of media info, for the media info topic.
void unregisterMediaInfo(MediaInfoProvider &provider)
MSXCliComm & getMSXCliComm()
Commands that directly influence the MSX state should send and events so that they can be recorded by...
void addListElement(const T &t)
void addDictKeyValue(const Key &key, const Value &value)
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)
void format(SectorAccessibleDisk &disk, MSXBootSectorType bootType)
Format the given disk (= a single partition).
This file implemented 3 utility functions:
const FileContext & userFileContext()
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)
constexpr auto xrange(T e)