30 while ((*cdInUse)[
id]) {
36 name[2] = char(
'a' +
id);
37 (*cdInUse)[
id] =
true;
45 remMedStatNotifEnabled =
false;
50 readSectorData =
false;
61 unsigned id = name[2] -
'a';
62 assert((*cdInUse)[
id]);
63 (*cdInUse)[
id] =
false;
78 return "OPENMSX CD-ROM";
88 buf[0 * 2 + 0] = 0xC4;
91 buf[0 * 2 + 1] = 0x85;
94 buf[ 83 * 2 + 0] = 0x10;
96 buf[ 86 * 2 + 0] = remMedStatNotifEnabled * 0x10;
98 buf[127 * 2 + 0] = 0x01;
103 assert(readSectorData);
106 file.
seek(transferOffset);
108 transferOffset +=
count;
128 executePacketCommand(buf);
146 if (remMedStatNotifEnabled) {
159 mediaChanged =
false;
169 remMedStatNotifEnabled =
false;
177 remMedStatNotifEnabled =
true;
189void IDECDROM::startPacketReadTransfer(
unsigned count)
196 unsigned packetSize = 512;
205void IDECDROM::executePacketCommand(AlignedBuffer& packet)
215 readSectorData =
false;
225 const int byteCount = 18;
226 startPacketReadTransfer(byteCount);
228 for (
auto i :
xrange(byteCount)) {
232 buf[ 2] = narrow_cast<byte>((senseKey >> 16) & 0xFF);
233 buf[12] = narrow_cast<byte>((senseKey >> 8) & 0xFF);
234 buf[13] = narrow_cast<byte>((senseKey >> 0) & 0xFF);
235 buf[ 7] = byteCount - 7;
241 int format = packet[2] & 0x0F;
259 fprintf(stderr,
" read TOC: format %d not implemented\n", format);
289 readSectorData =
true;
290 transferOffset = sectorNumber * 2048;
291 unsigned count = sectorCount * 2048;
292 startPacketReadTransfer(
count);
297 fprintf(stderr,
" unknown packet command 0x%02X\n", packet[0]);
306 senseKey = 0x06 << 16;
312 file =
File(filename);
314 senseKey = 0x06 << 16;
325 scheduler_, cd_.name)
333 if (tokens.size() == 1) {
334 auto& file = cd.file;
336 file.is_open() ? file.getURL() :
string{});
338 }
else if ((tokens.size() == 2) && (tokens[1] ==
one_of(
"eject",
"-eject"))) {
341 if (tokens[1] ==
"-eject") {
342 result =
"Warning: use of '-eject' is deprecated, "
343 "instead use the 'eject' subcommand";
345 }
else if ((tokens.size() == 2) ||
346 ((tokens.size() == 3) && (tokens[1] ==
"insert"))) {
348 if (tokens[1] ==
"insert") {
349 if (tokens.size() > 2) {
353 "Missing argument to insert subcommand");
358 tokens[fileToken].getString());
373 cd.name,
" : display the cd image for this CD-ROM drive\n",
374 cd.name,
" eject : eject the cd image from this CD-ROM drive\n",
375 cd.name,
" insert <filename> : change the cd image for this CD-ROM drive\n",
376 cd.name,
" <filename> : change the cd image for this CD-ROM drive\n");
381 using namespace std::literals;
382 static constexpr std::array extra = {
"eject"sv,
"insert"sv};
387template<
typename Archive>
390 ar.template serializeBase<AbstractIDEDevice>(*
this);
393 ar.serialize(
"filename", filename);
394 if constexpr (Archive::IS_LOADER) {
396 if (filename.empty()) {
403 ar.serialize(
"byteCountLimit", byteCountLimit,
404 "transferOffset", transferOffset,
405 "senseKey", senseKey,
406 "readSectorData", readSectorData,
407 "remMedStatNotifEnabled", remMedStatNotifEnabled,
408 "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)
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(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.
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 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?
void insert(const std::string &filename)
std::shared_ptr< T > getSharedStuff(std::string_view name, Args &&...args)
Some MSX device parts are shared between several MSX devices (e.g.
CliComm & getMSXCliComm()
void registerMediaInfo(std::string_view name, MediaInfoProvider &provider)
Register and unregister providers of media info, for the media info topic.
void unregisterMediaInfo(MediaInfoProvider &provider)
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)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
void format(SectorAccessibleDisk &disk, MSXBootSectorType bootType)
Format the given disk (= a single partition).
This file implemented 3 utility functions:
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
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)