Skip to content

Commit

Permalink
IDE: If the user mounts the empty CD-ROM drive "image", then always r…
Browse files Browse the repository at this point in the history
…eturn "Medium Not Present" for Test Unit Ready and any attempt to read
  • Loading branch information
joncampbell123 committed Feb 29, 2024
1 parent aff3f13 commit 9169cc8
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/dos/cdrom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ bool CDROM_Interface_Fake :: GetAudioStatus(bool& playing, bool& pause) {
}

bool CDROM_Interface_Fake :: GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) {
mediaPresent = true;
mediaPresent = !isEmpty;
mediaChanged = false;
trayOpen = false;
return true;
Expand Down
12 changes: 12 additions & 0 deletions src/dos/cdrom.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ extern int CDROM_GetMountType(const char* path, int forceCD);
class CDROM_Interface
{
public:
enum INTERFACE_TYPE {
ID_BASE=0,
ID_FAKE,
ID_IMAGE
};

// CDROM_Interface (void);
virtual ~CDROM_Interface (void) {};

Expand Down Expand Up @@ -143,6 +149,8 @@ class CDROM_Interface

//! \brief TODO?
virtual void InitNewMedia (void) {};

INTERFACE_TYPE class_id = ID_BASE;
};

//! \brief CD-ROM interface to SDL 1.x CD-ROM support
Expand Down Expand Up @@ -206,6 +214,10 @@ class CDROM_Interface_Fake : public CDROM_Interface
bool ReadSectorsHost (void* buffer, bool raw, unsigned long sector, unsigned long num);

bool LoadUnloadMedia (bool /*unload*/) { return true; };

CDROM_Interface_Fake() { class_id = ID_FAKE; }

bool isEmpty = false;
};

//! \brief Image CD-ROM interface
Expand Down
1 change: 1 addition & 0 deletions src/dos/cdrom_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player;
CDROM_Interface_Image::CDROM_Interface_Image(uint8_t subUnit)
:subUnit(subUnit)
{
class_id = ID_IMAGE;
images[subUnit] = this;
if (refCount == 0) {
if (player.channel == NULL) {
Expand Down
19 changes: 12 additions & 7 deletions src/dos/dos_mscdex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,18 @@ int CMscdex::AddDrive(uint16_t _drive, char* physicalPath, uint8_t& subUnit)
cdrom[numDrives] = new CDROM_Interface_Image((uint8_t)numDrives);
break;
case 0x02: // fake cdrom interface (directories)
cdrom[numDrives] = new CDROM_Interface_Fake;
if (!strcmp(physicalPath,"empty")) {
}
else {
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath);
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You won't have full MSCDEX support !");
result = 5;
{
CDROM_Interface_Fake *fake = new CDROM_Interface_Fake;
cdrom[numDrives] = fake;
assert(fake->class_id == CDROM_Interface::INTERFACE_TYPE::ID_FAKE);
if (!strcmp(physicalPath,"empty")) {
fake->isEmpty = true;
}
else {
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath);
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You won't have full MSCDEX support !");
result = 5;
}
}
break;
default : // weird result
Expand Down
36 changes: 30 additions & 6 deletions src/hardware/ide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,16 @@ bool IDEATAPICDROMDevice::common_spinup_response(bool trigger,bool wait) {
}
}

/* if the CD-ROM drive has mounted the empty drive, then ALWAYS return Medium Not Present */
CDROM_Interface *cdrom = getMSCDEXDrive();
if (cdrom) {
if (cdrom->class_id == CDROM_Interface::INTERFACE_TYPE::ID_FAKE) {
set_sense(/*SK=*/0x02,/*ASC=*/0x3A); /* Medium Not Present */
// LOG_MSG("ATAPI: Medium Not Ready");
return false;
}
}

switch (loading_mode) {
case LOAD_NO_DISC:
case LOAD_INSERT_CD:
Expand Down Expand Up @@ -1183,9 +1193,16 @@ void IDEATAPICDROMDevice::on_atapi_busy_time() {
status = IDE_STATUS_DRIVE_READY|IDE_STATUS_DRQ|IDE_STATUS_DRIVE_SEEK_COMPLETE;
}
else {
LOG_MSG("ATAPI: Failed to read %lu sectors at %lu\n",
(unsigned long)TransferLength,(unsigned long)LBA);
set_sense(/*SK=*/0x03,/*ASC=*/0x11); /* Medium Error: Unrecovered Read Error */
if (cdrom->class_id == CDROM_Interface::INTERFACE_TYPE::ID_FAKE) {
set_sense(/*SK=*/0x02,/*ASC=*/0x3A); /* Not Ready: Medium Not Present */
LOG_MSG("ATAPI: Rejecting read %lu sectors at %lu as Medium Not Present\n",
(unsigned long)TransferLength,(unsigned long)LBA);
}
else {
set_sense(/*SK=*/0x03,/*ASC=*/0x11); /* Medium Error: Unrecovered Read Error */
LOG_MSG("ATAPI: Failed to read %lu sectors at %lu\n",
(unsigned long)TransferLength,(unsigned long)LBA);
}
feature = 0xF4; /* abort sense=0xF */
count = 0x03; /* no more transfer */
sector_total = 0;/*nothing to transfer */
Expand Down Expand Up @@ -1257,9 +1274,16 @@ void IDEATAPICDROMDevice::on_atapi_busy_time() {
status = IDE_STATUS_DRIVE_READY|IDE_STATUS_DRQ|IDE_STATUS_DRIVE_SEEK_COMPLETE;
}
else {
LOG_MSG("ATAPI: Failed to read %lu sectors at %lu\n",
(unsigned long)TransferLength,(unsigned long)LBA);
set_sense(/*SK=*/0x03,/*ASC=*/0x11); /* Medium Error: Unrecovered Read Error */
if (cdrom->class_id == CDROM_Interface::INTERFACE_TYPE::ID_FAKE) {
set_sense(/*SK=*/0x02,/*ASC=*/0x3A); /* Not Ready: Medium Not Present */
LOG_MSG("ATAPI: Rejecting read %lu sectors at %lu as Medium Not Present\n",
(unsigned long)TransferLength,(unsigned long)LBA);
}
else {
set_sense(/*SK=*/0x03,/*ASC=*/0x11); /* Medium Error: Unrecovered Read Error */
LOG_MSG("ATAPI: Failed to read %lu sectors at %lu\n",
(unsigned long)TransferLength,(unsigned long)LBA);
}
feature = 0xF4; /* abort sense=0xF */
count = 0x03; /* no more transfer */
sector_total = 0;/*nothing to transfer */
Expand Down

0 comments on commit 9169cc8

Please sign in to comment.