Эх сурвалжийг харах

Implement some vendor-specific behavior the Apple driver expects.

saybur 2 жил өмнө
parent
commit
c744433761
1 өөрчлөгдсөн 42 нэмэгдсэн , 11 устгасан
  1. 42 11
      src/BlueSCSI_cdrom.cpp

+ 42 - 11
src/BlueSCSI_cdrom.cpp

@@ -337,7 +337,7 @@ static void doReadSessionInfoSimple(bool msf, uint16_t allocationLength)
     scsiDev.phase = DATA_IN;
 }
 
-static void doReadFullTOCSimple(uint8_t session, uint16_t allocationLength)
+static void doReadFullTOCSimple(uint8_t session, uint16_t allocationLength, bool useBCD)
 {
     // We only support session 1.
     if (session > 1)
@@ -358,7 +358,11 @@ static void doReadFullTOCSimple(uint8_t session, uint16_t allocationLength)
             scsiDev.target->cfg->sdSectorStart,
             scsiDev.target->liveCfg.bytesPerSector,
             scsiDev.target->cfg->scsiSectors);
-        LBA2MSF(capacity, &scsiDev.data[34], false);
+        if (useBCD) {
+            LBA2MSFBCD(capacity, &scsiDev.data[34], false);
+        } else {
+            LBA2MSF(capacity, &scsiDev.data[34], false);
+        }
 
         if (len > allocationLength)
         {
@@ -562,7 +566,7 @@ static void doReadSessionInfo(bool msf, uint16_t allocationLength)
 
 // Format track info read from cue sheet into the format used by ReadFullTOC command.
 // Refer to T10/1545-D MMC-4 Revision 5a, "Response Format 0010b: Raw TOC"
-static void formatRawTrackInfo(const CUETrackInfo *track, uint8_t *dest)
+static void formatRawTrackInfo(const CUETrackInfo *track, uint8_t *dest, bool useBCD)
 {
     uint8_t control_adr = 0x14; // Digital track
 
@@ -584,17 +588,21 @@ static void formatRawTrackInfo(const CUETrackInfo *track, uint8_t *dest)
     dest[6] = 0x00;
     dest[7] = 0; // HOUR
 
-    LBA2MSF(track->data_start, &dest[8], false);
+    if (useBCD) {
+        LBA2MSFBCD(track->data_start, &dest[8], false);
+    } else {
+        LBA2MSF(track->data_start, &dest[8], false);
+    }
 }
 
-static void doReadFullTOC(uint8_t session, uint16_t allocationLength)
+static void doReadFullTOC(uint8_t session, uint16_t allocationLength, bool useBCD)
 {
     image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
     CUEParser parser;
     if (!loadCueSheet(img, parser))
     {
         // No CUE sheet, use hardcoded data
-        return doReadFullTOCSimple(session, allocationLength);
+        return doReadFullTOCSimple(session, allocationLength, useBCD);
     }
 
     // We only support session 1.
@@ -628,7 +636,7 @@ static void doReadFullTOC(uint8_t session, uint16_t allocationLength)
         }
         lasttrack = trackinfo;
 
-        formatRawTrackInfo(trackinfo, &scsiDev.data[len]);
+        formatRawTrackInfo(trackinfo, &scsiDev.data[len], useBCD);
         trackcount += 1;
         len += 11;
     }
@@ -646,7 +654,11 @@ static void doReadFullTOC(uint8_t session, uint16_t allocationLength)
     }
 
     // Leadout track position
-    LBA2MSF(getLeadOutLBA(lasttrack), &scsiDev.data[34], false);
+    if (useBCD) {
+        LBA2MSFBCD(getLeadOutLBA(lasttrack), &scsiDev.data[34], false);
+    } else {
+        LBA2MSF(getLeadOutLBA(lasttrack), &scsiDev.data[34], false);
+    }
 
     // Correct the record length in header
     uint16_t toclen = len - 2;
@@ -1521,15 +1533,34 @@ extern "C" int scsiCDRomCommand()
             (((uint32_t) scsiDev.cdb[7]) << 8) +
             scsiDev.cdb[8];
 
-        // Reject MMC commands for now, otherwise the TOC data format
-        // won't be understood.
         // The "format" field is reserved for SCSI-2
         uint8_t format = scsiDev.cdb[2] & 0x0F;
+
+        // Matshita SCSI-2 drives appear to use the high 2 bits of the CDB
+        // control byte to switch on session info (0x40) and full toc (0x80)
+        // responses that are very similar to the standard formats described
+        // in MMC-1. These vendor flags must have been pretty common because
+        // even a modern SATA drive (ASUS DRW-24B1ST j) responds to them
+        // (though it always replies in hex rather than bcd)
+        //
+        // The session information page is identical to MMC. The full TOC page
+        // is identical _except_ it returns addresses in bcd rather than hex.
+        bool useBCD = false;
+        if (format == 0 && scsiDev.cdb[9] == 0x80)
+        {
+            format = 2;
+            useBCD = true;
+        }
+        else if (format == 0 && scsiDev.cdb[9] == 0x40)
+        {
+            format = 1;
+        }
+
         switch (format)
         {
             case 0: doReadTOC(MSF, track, allocationLength); break; // SCSI-2
             case 1: doReadSessionInfo(MSF, allocationLength); break; // MMC2
-            case 2: doReadFullTOC(track, allocationLength); break; // MMC2
+            case 2: doReadFullTOC(track, allocationLength, useBCD); break; // MMC2
             default:
             {
                 scsiDev.status = CHECK_CONDITION;