Selaa lähdekoodia

Fold doReadD8 into doReadCD to save buffer space

The Plextor vendor command doReadD8 now calls doReadCD to save buffer
space in SRAM. doReadCD now internally checks VendorExtensions to
properly output the data over the SCSI bus.
Morio 1 vuosi sitten
vanhempi
sitoutus
7ee940a172
1 muutettua tiedostoa jossa 43 lisäystä ja 77 poistoa
  1. 43 77
      src/ZuluSCSI_cdrom.cpp

+ 43 - 77
src/ZuluSCSI_cdrom.cpp

@@ -31,6 +31,7 @@
 #include "ZuluSCSI_cdrom.h"
 #include "ZuluSCSI_log.h"
 #include "ZuluSCSI_config.h"
+#include "ZuluSCSI_settings.h"
 #include <CUEParser.h>
 #include <assert.h>
 #include <minIni.h>
@@ -219,6 +220,11 @@ static const uint8_t TrackInformation[] =
     0x00,   // 27: track size (LSB)
 };
 
+enum sector_type_t
+{
+     SECTOR_TYPE_VENDOR_PLEXTOR = 100,
+};
+
 // Convert logical block address to CD-ROM time
 static void LBA2MSF(int32_t LBA, uint8_t* MSF, bool relative)
 {
@@ -1491,12 +1497,38 @@ static void doReadCD(uint32_t lba, uint32_t length, uint8_t sector_type,
     getTrackFromLBA(parser, lba, &trackinfo);
 
     // Figure out the data offset in the file
-    uint64_t offset = trackinfo.file_offset + trackinfo.sector_length * (lba - trackinfo.track_start);
-    dbgmsg("------ Read CD: ", (int)length, " sectors starting at ", (int)lba,
-           ", track number ", trackinfo.track_number, ", sector size ", (int)trackinfo.sector_length,
-           ", main channel ", main_channel, ", sub channel ", sub_channel,
-           ", data offset in file ", (int)offset);
+    uint64_t offset;
+    if (sector_type == SECTOR_TYPE_VENDOR_PLEXTOR &&
+         g_scsi_settings.getDevice(img.scsiId & 0x7)->vendorExtensions & VENDOR_EXTENSION_OPTICAL_PLEXTOR)
+    {
+        // This overrides values so doReadCD can be used with the
+        // Vendor specific Plextor 0xD8 command to read raw CD data
+        if (lba < 2)
+        {
+            logmsg("WARNING: Plextor CD-ROM vendor extension 0xd8 lba start below 2 is not implemented. LBA is ", lba);
+            scsiDev.status = CHECK_CONDITION;
+            scsiDev.target->sense.code = ILLEGAL_REQUEST;
+            scsiDev.target->sense.asc = LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+            scsiDev.phase = STATUS;
+            return;
+        }
 
+        const uint16_t PLEXTOR_D8_SECTOR_LENGTH =  2352;
+        trackinfo.sector_length = PLEXTOR_D8_SECTOR_LENGTH;
+        trackinfo.track_mode = CUETrack_AUDIO;
+        offset = (uint64_t)(lba - 2) * trackinfo.sector_length;
+        dbgmsg("------ Read CD Vendor Plextor (0xd8): ", (int)length, " sectors starting at ", (int)lba -2,
+               ", sector size ", (int) PLEXTOR_D8_SECTOR_LENGTH,
+               ", data offset in file ", (int)offset);
+    }
+    else
+    {
+        offset = trackinfo.file_offset + trackinfo.sector_length * (lba - trackinfo.track_start);
+        dbgmsg("------ Read CD: ", (int)length, " sectors starting at ", (int)lba,
+            ", track number ", trackinfo.track_number, ", sector size ", (int)trackinfo.sector_length,
+            ", main channel ", main_channel, ", sub channel ", sub_channel,
+            ", data offset in file ", (int)offset);
+    }
     // Ensure read is not out of range of the image
     uint64_t readend = offset + trackinfo.sector_length * length;
     if (readend > img.file.size())
@@ -1522,6 +1554,11 @@ static void doReadCD(uint32_t lba, uint32_t length, uint8_t sector_type,
         {
             sector_type_ok = true;
         }
+        else if (sector_type == SECTOR_TYPE_VENDOR_PLEXTOR && 
+            g_scsi_settings.getDevice(img.scsiId & 0x7)->vendorExtensions & VENDOR_EXTENSION_OPTICAL_PLEXTOR)
+        {
+            sector_type_ok = true;
+        }
 
         if (!sector_type_ok)
         {
@@ -1841,77 +1878,7 @@ static bool doReadCapacity(uint32_t lba, uint8_t pmi)
 
 static void doReadD8(uint32_t lba, uint32_t length)
 {
-    const uint32_t CD_SECTOR_SIZE = 2352;
-    const uint32_t SD_BLOCKSIZE =  512;
-    const uint32_t bytes_per_sector = CD_SECTOR_SIZE;
-    const uint32_t bytes_per_block = SD_BLOCKSIZE;
-
-    image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
-    uint8_t *buf0 = scsiDev.data;
-    uint8_t *buf1 = buf0 + (sizeof(scsiDev.data)/2);
-    // Adjust for plextor d8 offset
-    if ((int)lba - 2 < 0)
-    {
-        logmsg("ERROR: Plextor vendor 0xD8 command LBA must be greater than 2, given: ", (int)lba);
-        scsiDev.status = CHECK_CONDITION;
-        scsiDev.target->sense.code = ILLEGAL_REQUEST;
-        scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
-        scsiDev.phase = STATUS;
-        return;
-    }
-    lba = lba -2;
-
-    uint64_t offset = lba * bytes_per_sector;
-
-
-    scsiDev.phase = DATA_IN;
-    scsiDev.dataLen = 0;
-    scsiDev.dataPtr = 0;
-    scsiEnterPhase(DATA_IN);
-    // Format the sectors for transfer
-    for (uint32_t idx = 0; idx < length; idx++)
-    {
-        platform_poll();
-        diskEjectButtonUpdate(false);
-
-        // Where in bytes the sector starts in the image file
-        uint64_t sector_start = offset + idx * bytes_per_sector;
-        // Where to start reading the image file in bytes, aligned at or before sector start
-        uint64_t aligned_start = (sector_start / bytes_per_block) * bytes_per_block;
-        // The difference between the sector start and aligned start
-        uint32_t sector_start_offset = (uint32_t)(sector_start - aligned_start);
-        // Where the sector on the CD ends in bytes
-        uint64_t sector_end = sector_start + bytes_per_sector - 1;
-        // The number of aligned blocks on the image file to read rounded up
-        uint32_t number_of_read_sectors = (sector_end - aligned_start + bytes_per_block - 1) / bytes_per_block;
-        // How many bytes to read from the image file
-        uint32_t aligned_read_length = number_of_read_sectors * bytes_per_block;
-        img.file.seek(aligned_start);
-
-        // Verify that previous write using this buffer has finished
-        uint8_t *buf = ((idx & 1) ? buf1 : buf0);
-        uint8_t *bufstart = buf + sector_start_offset;
-        uint32_t start = millis();
-        while (!scsiIsWriteFinished(bufstart + bytes_per_sector - 1) && !scsiDev.resetFlag)
-        {
-            if ((uint32_t)(millis() - start) > 5000)
-            {
-                logmsg("doReadD8() timeout waiting for previous to finish");
-                scsiDev.resetFlag = 1;
-            }
-            platform_poll();
-            diskEjectButtonUpdate(false);
-        }
-        if (scsiDev.resetFlag) break;
-
-        img.file.read(buf, aligned_read_length);
-
-        scsiStartWrite(bufstart, bytes_per_sector);
-    }
-
-    scsiFinishWrite();
-    scsiDev.status = 0;
-    scsiDev.phase = STATUS;
+    doReadCD(lba, length, SECTOR_TYPE_VENDOR_PLEXTOR, true, false, false );
 }
 
 /**************************************/
@@ -2249,7 +2216,6 @@ extern "C" int scsiCDRomCommand()
                 (((uint32_t) scsiDev.cdb[7]) << 16) +
                 (((uint32_t) scsiDev.cdb[8]) << 8) +
                 scsiDev.cdb[9];
-            dbgmsg("Plextor vendor 0xD8 command CDDA Read, starting: ", (int)lba, " length: ",(int)blocks);
             doReadD8(lba, blocks);
         }
     }