|
|
@@ -44,138 +44,138 @@ extern "C" {
|
|
|
|
|
|
static const uint8_t SimpleTOC[] =
|
|
|
{
|
|
|
- 0x00, // toc length, MSB
|
|
|
- 0x12, // toc length, LSB
|
|
|
- 0x01, // First track number
|
|
|
- 0x01, // Last track number,
|
|
|
- // TRACK 1 Descriptor
|
|
|
- 0x00, // reserved
|
|
|
- 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
- 0x01, // Track 1,
|
|
|
- 0x00, // Reserved
|
|
|
- 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
- 0x00, // reserved
|
|
|
- 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
- 0xAA, // Leadout Track
|
|
|
- 0x00, // Reserved
|
|
|
- 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
+ 0x00, // toc length, MSB
|
|
|
+ 0x12, // toc length, LSB
|
|
|
+ 0x01, // First track number
|
|
|
+ 0x01, // Last track number,
|
|
|
+ // TRACK 1 Descriptor
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
+ 0x01, // Track 1,
|
|
|
+ 0x00, // Reserved
|
|
|
+ 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
+ 0xAA, // Leadout Track
|
|
|
+ 0x00, // Reserved
|
|
|
+ 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
};
|
|
|
|
|
|
static const uint8_t LeadoutTOC[] =
|
|
|
{
|
|
|
- 0x00, // toc length, MSB
|
|
|
- 0x0A, // toc length, LSB
|
|
|
- 0x01, // First track number
|
|
|
- 0x01, // Last track number,
|
|
|
- 0x00, // reserved
|
|
|
- 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
- 0xAA, // Leadout Track
|
|
|
- 0x00, // Reserved
|
|
|
- 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
+ 0x00, // toc length, MSB
|
|
|
+ 0x0A, // toc length, LSB
|
|
|
+ 0x01, // First track number
|
|
|
+ 0x01, // Last track number,
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
+ 0xAA, // Leadout Track
|
|
|
+ 0x00, // Reserved
|
|
|
+ 0x00,0x00,0x00,0x00, // Track start sector (LBA)
|
|
|
};
|
|
|
|
|
|
static const uint8_t SessionTOC[] =
|
|
|
{
|
|
|
- 0x00, // toc length, MSB
|
|
|
- 0x0A, // toc length, LSB
|
|
|
- 0x01, // First session number
|
|
|
- 0x01, // Last session number,
|
|
|
- // TRACK 1 Descriptor
|
|
|
- 0x00, // reserved
|
|
|
- 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
- 0x01, // First track number in last complete session
|
|
|
- 0x00, // Reserved
|
|
|
- 0x00,0x00,0x00,0x00 // LBA of first track in last session
|
|
|
+ 0x00, // toc length, MSB
|
|
|
+ 0x0A, // toc length, LSB
|
|
|
+ 0x01, // First session number
|
|
|
+ 0x01, // Last session number,
|
|
|
+ // TRACK 1 Descriptor
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x14, // Q sub-channel encodes current position, Digital track
|
|
|
+ 0x01, // First track number in last complete session
|
|
|
+ 0x00, // Reserved
|
|
|
+ 0x00,0x00,0x00,0x00 // LBA of first track in last session
|
|
|
};
|
|
|
|
|
|
|
|
|
static const uint8_t FullTOC[] =
|
|
|
{
|
|
|
- 0x00, // 0: toc length, MSB
|
|
|
- 0x44, // 1: toc length, LSB
|
|
|
- 0x01, // 2: First session number
|
|
|
- 0x01, // 3: Last session number,
|
|
|
- // A0 Descriptor
|
|
|
- 0x01, // 4: session number
|
|
|
- 0x14, // 5: ADR/Control
|
|
|
- 0x00, // 6: TNO
|
|
|
- 0xA0, // 7: POINT
|
|
|
- 0x00, // 8: Min
|
|
|
- 0x00, // 9: Sec
|
|
|
- 0x00, // 10: Frame
|
|
|
- 0x00, // 11: Zero
|
|
|
- 0x01, // 12: First Track number.
|
|
|
- 0x00, // 13: Disc type 00 = Mode 1
|
|
|
- 0x00, // 14: PFRAME
|
|
|
- // A1
|
|
|
- 0x01, // 15: session number
|
|
|
- 0x14, // 16: ADR/Control
|
|
|
- 0x00, // 17: TNO
|
|
|
- 0xA1, // 18: POINT
|
|
|
- 0x00, // 19: Min
|
|
|
- 0x00, // 20: Sec
|
|
|
- 0x00, // 21: Frame
|
|
|
- 0x00, // 22: Zero
|
|
|
- 0x01, // 23: Last Track number
|
|
|
- 0x00, // 24: PSEC
|
|
|
- 0x00, // 25: PFRAME
|
|
|
- // A2
|
|
|
- 0x01, // 26: session number
|
|
|
- 0x14, // 27: ADR/Control
|
|
|
- 0x00, // 28: TNO
|
|
|
- 0xA2, // 29: POINT
|
|
|
- 0x00, // 30: Min
|
|
|
- 0x00, // 31: Sec
|
|
|
- 0x00, // 32: Frame
|
|
|
- 0x00, // 33: Zero
|
|
|
- 0x79, // 34: LEADOUT position BCD
|
|
|
- 0x59, // 35: leadout PSEC BCD
|
|
|
- 0x74, // 36: leadout PFRAME BCD
|
|
|
- // TRACK 1 Descriptor
|
|
|
- 0x01, // 37: session number
|
|
|
- 0x14, // 38: ADR/Control
|
|
|
- 0x00, // 39: TNO
|
|
|
- 0x01, // 40: Point
|
|
|
- 0x00, // 41: Min
|
|
|
- 0x00, // 42: Sec
|
|
|
- 0x00, // 43: Frame
|
|
|
- 0x00, // 44: Zero
|
|
|
- 0x00, // 45: PMIN
|
|
|
- 0x00, // 46: PSEC
|
|
|
- 0x00, // 47: PFRAME
|
|
|
- // b0
|
|
|
- 0x01, // 48: session number
|
|
|
- 0x54, // 49: ADR/Control
|
|
|
- 0x00, // 50: TNO
|
|
|
- 0xB1, // 51: POINT
|
|
|
- 0x79, // 52: Min BCD
|
|
|
- 0x59, // 53: Sec BCD
|
|
|
- 0x74, // 54: Frame BCD
|
|
|
- 0x00, // 55: Zero
|
|
|
- 0x79, // 56: PMIN BCD
|
|
|
- 0x59, // 57: PSEC BCD
|
|
|
- 0x74, // 58: PFRAME BCD
|
|
|
- // c0
|
|
|
- 0x01, // 59: session number
|
|
|
- 0x54, // 60: ADR/Control
|
|
|
- 0x00, // 61: TNO
|
|
|
- 0xC0, // 62: POINT
|
|
|
- 0x00, // 63: Min
|
|
|
- 0x00, // 64: Sec
|
|
|
- 0x00, // 65: Frame
|
|
|
- 0x00, // 66: Zero
|
|
|
- 0x00, // 67: PMIN
|
|
|
- 0x00, // 68: PSEC
|
|
|
- 0x00 // 69: PFRAME
|
|
|
+ 0x00, // 0: toc length, MSB
|
|
|
+ 0x44, // 1: toc length, LSB
|
|
|
+ 0x01, // 2: First session number
|
|
|
+ 0x01, // 3: Last session number,
|
|
|
+ // A0 Descriptor
|
|
|
+ 0x01, // 4: session number
|
|
|
+ 0x14, // 5: ADR/Control
|
|
|
+ 0x00, // 6: TNO
|
|
|
+ 0xA0, // 7: POINT
|
|
|
+ 0x00, // 8: Min
|
|
|
+ 0x00, // 9: Sec
|
|
|
+ 0x00, // 10: Frame
|
|
|
+ 0x00, // 11: Zero
|
|
|
+ 0x01, // 12: First Track number.
|
|
|
+ 0x00, // 13: Disc type 00 = Mode 1
|
|
|
+ 0x00, // 14: PFRAME
|
|
|
+ // A1
|
|
|
+ 0x01, // 15: session number
|
|
|
+ 0x14, // 16: ADR/Control
|
|
|
+ 0x00, // 17: TNO
|
|
|
+ 0xA1, // 18: POINT
|
|
|
+ 0x00, // 19: Min
|
|
|
+ 0x00, // 20: Sec
|
|
|
+ 0x00, // 21: Frame
|
|
|
+ 0x00, // 22: Zero
|
|
|
+ 0x01, // 23: Last Track number
|
|
|
+ 0x00, // 24: PSEC
|
|
|
+ 0x00, // 25: PFRAME
|
|
|
+ // A2
|
|
|
+ 0x01, // 26: session number
|
|
|
+ 0x14, // 27: ADR/Control
|
|
|
+ 0x00, // 28: TNO
|
|
|
+ 0xA2, // 29: POINT
|
|
|
+ 0x00, // 30: Min
|
|
|
+ 0x00, // 31: Sec
|
|
|
+ 0x00, // 32: Frame
|
|
|
+ 0x00, // 33: Zero
|
|
|
+ 0x79, // 34: LEADOUT position BCD
|
|
|
+ 0x59, // 35: leadout PSEC BCD
|
|
|
+ 0x74, // 36: leadout PFRAME BCD
|
|
|
+ // TRACK 1 Descriptor
|
|
|
+ 0x01, // 37: session number
|
|
|
+ 0x14, // 38: ADR/Control
|
|
|
+ 0x00, // 39: TNO
|
|
|
+ 0x01, // 40: Point
|
|
|
+ 0x00, // 41: Min
|
|
|
+ 0x00, // 42: Sec
|
|
|
+ 0x00, // 43: Frame
|
|
|
+ 0x00, // 44: Zero
|
|
|
+ 0x00, // 45: PMIN
|
|
|
+ 0x00, // 46: PSEC
|
|
|
+ 0x00, // 47: PFRAME
|
|
|
+ // b0
|
|
|
+ 0x01, // 48: session number
|
|
|
+ 0x54, // 49: ADR/Control
|
|
|
+ 0x00, // 50: TNO
|
|
|
+ 0xB1, // 51: POINT
|
|
|
+ 0x79, // 52: Min BCD
|
|
|
+ 0x59, // 53: Sec BCD
|
|
|
+ 0x74, // 54: Frame BCD
|
|
|
+ 0x00, // 55: Zero
|
|
|
+ 0x79, // 56: PMIN BCD
|
|
|
+ 0x59, // 57: PSEC BCD
|
|
|
+ 0x74, // 58: PFRAME BCD
|
|
|
+ // c0
|
|
|
+ 0x01, // 59: session number
|
|
|
+ 0x54, // 60: ADR/Control
|
|
|
+ 0x00, // 61: TNO
|
|
|
+ 0xC0, // 62: POINT
|
|
|
+ 0x00, // 63: Min
|
|
|
+ 0x00, // 64: Sec
|
|
|
+ 0x00, // 65: Frame
|
|
|
+ 0x00, // 66: Zero
|
|
|
+ 0x00, // 67: PMIN
|
|
|
+ 0x00, // 68: PSEC
|
|
|
+ 0x00 // 69: PFRAME
|
|
|
};
|
|
|
|
|
|
static uint8_t SimpleHeader[] =
|
|
|
{
|
|
|
- 0x01, // 2048byte user data, L-EC in 288 byte aux field.
|
|
|
- 0x00, // reserved
|
|
|
- 0x00, // reserved
|
|
|
- 0x00, // reserved
|
|
|
- 0x00,0x00,0x00,0x00 // Track start sector (LBA or MSF)
|
|
|
+ 0x01, // 2048byte user data, L-EC in 288 byte aux field.
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x00, // reserved
|
|
|
+ 0x00,0x00,0x00,0x00 // Track start sector (LBA or MSF)
|
|
|
};
|
|
|
|
|
|
static const uint8_t DiscInformation[] =
|
|
|
@@ -219,169 +219,169 @@ static const uint8_t DiscInformation[] =
|
|
|
// Convert logical block address to CD-ROM time in formatted TOC format
|
|
|
static void LBA2MSF(uint32_t LBA, uint8_t* MSF)
|
|
|
{
|
|
|
- MSF[0] = 0; // reserved.
|
|
|
- MSF[3] = LBA % 75; // Frames
|
|
|
- uint32_t rem = LBA / 75;
|
|
|
+ MSF[0] = 0; // reserved.
|
|
|
+ MSF[3] = LBA % 75; // Frames
|
|
|
+ uint32_t rem = LBA / 75;
|
|
|
|
|
|
- MSF[2] = rem % 60; // Seconds
|
|
|
- MSF[1] = rem / 60; // Minutes
|
|
|
+ MSF[2] = rem % 60; // Seconds
|
|
|
+ MSF[1] = rem / 60; // Minutes
|
|
|
}
|
|
|
|
|
|
static void doReadTOCSimple(bool MSF, uint8_t track, uint16_t allocationLength)
|
|
|
{
|
|
|
- if (track == 0xAA)
|
|
|
- {
|
|
|
- // 0xAA requests only lead-out track information (reports capacity)
|
|
|
- uint32_t len = sizeof(LeadoutTOC);
|
|
|
- memcpy(scsiDev.data, LeadoutTOC, len);
|
|
|
-
|
|
|
- uint32_t capacity = getScsiCapacity(
|
|
|
- scsiDev.target->cfg->sdSectorStart,
|
|
|
- scsiDev.target->liveCfg.bytesPerSector,
|
|
|
- scsiDev.target->cfg->scsiSectors);
|
|
|
-
|
|
|
- // Replace start of leadout track
|
|
|
- if (MSF)
|
|
|
- {
|
|
|
- LBA2MSF(capacity, scsiDev.data + 8);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- scsiDev.data[8] = capacity >> 24;
|
|
|
- scsiDev.data[9] = capacity >> 16;
|
|
|
- scsiDev.data[10] = capacity >> 8;
|
|
|
- scsiDev.data[11] = capacity;
|
|
|
- }
|
|
|
-
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
- }
|
|
|
- else if (track <= 1)
|
|
|
- {
|
|
|
- // We only support track 1.
|
|
|
- // track 0 means "return all tracks"
|
|
|
- uint32_t len = sizeof(SimpleTOC);
|
|
|
- memcpy(scsiDev.data, SimpleTOC, len);
|
|
|
-
|
|
|
- uint32_t capacity = getScsiCapacity(
|
|
|
- scsiDev.target->cfg->sdSectorStart,
|
|
|
- scsiDev.target->liveCfg.bytesPerSector,
|
|
|
- scsiDev.target->cfg->scsiSectors);
|
|
|
-
|
|
|
- // Replace start of leadout track
|
|
|
- if (MSF)
|
|
|
- {
|
|
|
- LBA2MSF(capacity, scsiDev.data + 0x10);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- scsiDev.data[0x10] = capacity >> 24;
|
|
|
- scsiDev.data[0x11] = capacity >> 16;
|
|
|
- scsiDev.data[0x12] = capacity >> 8;
|
|
|
- scsiDev.data[0x13] = capacity;
|
|
|
- }
|
|
|
-
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- scsiDev.status = CHECK_CONDITION;
|
|
|
- scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
- scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
- scsiDev.phase = STATUS;
|
|
|
- }
|
|
|
+ if (track == 0xAA)
|
|
|
+ {
|
|
|
+ // 0xAA requests only lead-out track information (reports capacity)
|
|
|
+ uint32_t len = sizeof(LeadoutTOC);
|
|
|
+ memcpy(scsiDev.data, LeadoutTOC, len);
|
|
|
+
|
|
|
+ uint32_t capacity = getScsiCapacity(
|
|
|
+ scsiDev.target->cfg->sdSectorStart,
|
|
|
+ scsiDev.target->liveCfg.bytesPerSector,
|
|
|
+ scsiDev.target->cfg->scsiSectors);
|
|
|
+
|
|
|
+ // Replace start of leadout track
|
|
|
+ if (MSF)
|
|
|
+ {
|
|
|
+ LBA2MSF(capacity, scsiDev.data + 8);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ scsiDev.data[8] = capacity >> 24;
|
|
|
+ scsiDev.data[9] = capacity >> 16;
|
|
|
+ scsiDev.data[10] = capacity >> 8;
|
|
|
+ scsiDev.data[11] = capacity;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
+ }
|
|
|
+ else if (track <= 1)
|
|
|
+ {
|
|
|
+ // We only support track 1.
|
|
|
+ // track 0 means "return all tracks"
|
|
|
+ uint32_t len = sizeof(SimpleTOC);
|
|
|
+ memcpy(scsiDev.data, SimpleTOC, len);
|
|
|
+
|
|
|
+ uint32_t capacity = getScsiCapacity(
|
|
|
+ scsiDev.target->cfg->sdSectorStart,
|
|
|
+ scsiDev.target->liveCfg.bytesPerSector,
|
|
|
+ scsiDev.target->cfg->scsiSectors);
|
|
|
+
|
|
|
+ // Replace start of leadout track
|
|
|
+ if (MSF)
|
|
|
+ {
|
|
|
+ LBA2MSF(capacity, scsiDev.data + 0x10);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ scsiDev.data[0x10] = capacity >> 24;
|
|
|
+ scsiDev.data[0x11] = capacity >> 16;
|
|
|
+ scsiDev.data[0x12] = capacity >> 8;
|
|
|
+ scsiDev.data[0x13] = capacity;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ scsiDev.status = CHECK_CONDITION;
|
|
|
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
+ scsiDev.phase = STATUS;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void doReadSessionInfoSimple(uint8_t session, uint16_t allocationLength)
|
|
|
{
|
|
|
- uint32_t len = sizeof(SessionTOC);
|
|
|
- memcpy(scsiDev.data, SessionTOC, len);
|
|
|
-
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ uint32_t len = sizeof(SessionTOC);
|
|
|
+ memcpy(scsiDev.data, SessionTOC, len);
|
|
|
+
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
static inline uint8_t
|
|
|
fromBCD(uint8_t val)
|
|
|
{
|
|
|
- return ((val >> 4) * 10) + (val & 0xF);
|
|
|
+ return ((val >> 4) * 10) + (val & 0xF);
|
|
|
}
|
|
|
|
|
|
static void doReadFullTOCSimple(int convertBCD, uint8_t session, uint16_t allocationLength)
|
|
|
{
|
|
|
- // We only support session 1.
|
|
|
- if (session > 1)
|
|
|
- {
|
|
|
- scsiDev.status = CHECK_CONDITION;
|
|
|
- scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
- scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
- scsiDev.phase = STATUS;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- uint32_t len = sizeof(FullTOC);
|
|
|
- memcpy(scsiDev.data, FullTOC, len);
|
|
|
-
|
|
|
- if (convertBCD)
|
|
|
- {
|
|
|
- int descriptor = 4;
|
|
|
- while (descriptor < len)
|
|
|
- {
|
|
|
- int i;
|
|
|
- for (i = 0; i < 7; ++i)
|
|
|
- {
|
|
|
- scsiDev.data[descriptor + i] =
|
|
|
- fromBCD(scsiDev.data[descriptor + 4 + i]);
|
|
|
- }
|
|
|
- descriptor += 11;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
- }
|
|
|
+ // We only support session 1.
|
|
|
+ if (session > 1)
|
|
|
+ {
|
|
|
+ scsiDev.status = CHECK_CONDITION;
|
|
|
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
+ scsiDev.phase = STATUS;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ uint32_t len = sizeof(FullTOC);
|
|
|
+ memcpy(scsiDev.data, FullTOC, len);
|
|
|
+
|
|
|
+ if (convertBCD)
|
|
|
+ {
|
|
|
+ int descriptor = 4;
|
|
|
+ while (descriptor < len)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < 7; ++i)
|
|
|
+ {
|
|
|
+ scsiDev.data[descriptor + i] =
|
|
|
+ fromBCD(scsiDev.data[descriptor + 4 + i]);
|
|
|
+ }
|
|
|
+ descriptor += 11;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void doReadHeaderSimple(bool MSF, uint32_t lba, uint16_t allocationLength)
|
|
|
{
|
|
|
- uint32_t len = sizeof(SimpleHeader);
|
|
|
- memcpy(scsiDev.data, SimpleHeader, len);
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ uint32_t len = sizeof(SimpleHeader);
|
|
|
+ memcpy(scsiDev.data, SimpleHeader, len);
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
void doReadDiscInformationSimple(uint16_t allocationLength)
|
|
|
{
|
|
|
uint32_t len = sizeof(DiscInformation);
|
|
|
- memcpy(scsiDev.data, DiscInformation, len);
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ memcpy(scsiDev.data, DiscInformation, len);
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
/*********************************/
|
|
|
@@ -518,9 +518,9 @@ static void doReadTOC(bool MSF, uint8_t track, uint16_t allocationLength)
|
|
|
{
|
|
|
// Unknown track requested
|
|
|
scsiDev.status = CHECK_CONDITION;
|
|
|
- scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
- scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
- scsiDev.phase = STATUS;
|
|
|
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
+ scsiDev.phase = STATUS;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -547,7 +547,7 @@ static void doReadSessionInfo(uint8_t session, uint16_t allocationLength)
|
|
|
}
|
|
|
|
|
|
uint32_t len = sizeof(SessionTOC);
|
|
|
- memcpy(scsiDev.data, SessionTOC, len);
|
|
|
+ memcpy(scsiDev.data, SessionTOC, len);
|
|
|
|
|
|
// Replace first track info in the session table
|
|
|
// based on data from CUE sheet.
|
|
|
@@ -557,31 +557,31 @@ static void doReadSessionInfo(uint8_t session, uint16_t allocationLength)
|
|
|
formatTrackInfo(trackinfo, &scsiDev.data[4], false);
|
|
|
}
|
|
|
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
// Convert logical block address to CD-ROM time in the raw TOC format
|
|
|
static void LBA2MSFRaw(uint32_t LBA, uint8_t* MSF)
|
|
|
{
|
|
|
MSF[2] = LBA % 75; // Frames
|
|
|
- uint32_t rem = LBA / 75;
|
|
|
+ uint32_t rem = LBA / 75;
|
|
|
|
|
|
- MSF[1] = rem % 60; // Seconds
|
|
|
- MSF[0] = rem / 60; // Minutes
|
|
|
+ MSF[1] = rem % 60; // Seconds
|
|
|
+ MSF[0] = rem / 60; // Minutes
|
|
|
}
|
|
|
|
|
|
// Convert logical block address to CD-ROM time in binary coded decimal format
|
|
|
static void LBA2MSFBCD(uint32_t LBA, uint8_t* MSF)
|
|
|
{
|
|
|
uint8_t fra = LBA % 75;
|
|
|
- uint32_t rem = LBA / 75;
|
|
|
- uint8_t sec = rem % 60;
|
|
|
- uint8_t min = rem / 60;
|
|
|
+ uint32_t rem = LBA / 75;
|
|
|
+ uint8_t sec = rem % 60;
|
|
|
+ uint8_t min = rem / 60;
|
|
|
|
|
|
MSF[0] = ((min / 10) << 4) | (min % 10);
|
|
|
MSF[1] = ((sec / 10) << 4) | (sec % 10);
|
|
|
@@ -629,14 +629,14 @@ static void doReadFullTOC(int convertBCD, uint8_t session, uint16_t allocationLe
|
|
|
}
|
|
|
|
|
|
// We only support session 1.
|
|
|
- if (session > 1)
|
|
|
- {
|
|
|
- scsiDev.status = CHECK_CONDITION;
|
|
|
- scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
- scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
- scsiDev.phase = STATUS;
|
|
|
+ if (session > 1)
|
|
|
+ {
|
|
|
+ scsiDev.status = CHECK_CONDITION;
|
|
|
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
+ scsiDev.phase = STATUS;
|
|
|
return;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
// Take the beginning of the hardcoded TOC as base
|
|
|
uint32_t len = 4 + 11 * 3; // Header, A0, A1, A2
|
|
|
@@ -695,7 +695,7 @@ void doReadHeader(bool MSF, uint32_t lba, uint16_t allocationLength)
|
|
|
|
|
|
// Take the hardcoded header as base
|
|
|
uint32_t len = sizeof(SimpleHeader);
|
|
|
- memcpy(scsiDev.data, SimpleHeader, len);
|
|
|
+ memcpy(scsiDev.data, SimpleHeader, len);
|
|
|
|
|
|
// Search the track with the requested LBA
|
|
|
CUETrackInfo trackinfo = {};
|
|
|
@@ -721,11 +721,11 @@ void doReadHeader(bool MSF, uint32_t lba, uint16_t allocationLength)
|
|
|
}
|
|
|
|
|
|
if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
void doReadDiscInformation(uint16_t allocationLength)
|
|
|
@@ -740,7 +740,7 @@ void doReadDiscInformation(uint16_t allocationLength)
|
|
|
|
|
|
// Take the hardcoded header as base
|
|
|
uint32_t len = sizeof(DiscInformation);
|
|
|
- memcpy(scsiDev.data, DiscInformation, len);
|
|
|
+ memcpy(scsiDev.data, DiscInformation, len);
|
|
|
|
|
|
// Find first and last track number
|
|
|
int firsttrack = -1;
|
|
|
@@ -756,12 +756,12 @@ void doReadDiscInformation(uint16_t allocationLength)
|
|
|
scsiDev.data[5] = firsttrack;
|
|
|
scsiDev.data[6] = lasttrack;
|
|
|
|
|
|
- if (len > allocationLength)
|
|
|
- {
|
|
|
- len = allocationLength;
|
|
|
- }
|
|
|
- scsiDev.dataLen = len;
|
|
|
- scsiDev.phase = DATA_IN;
|
|
|
+ if (len > allocationLength)
|
|
|
+ {
|
|
|
+ len = allocationLength;
|
|
|
+ }
|
|
|
+ scsiDev.dataLen = len;
|
|
|
+ scsiDev.phase = DATA_IN;
|
|
|
}
|
|
|
|
|
|
/****************************************/
|
|
|
@@ -1237,9 +1237,9 @@ static void doReadSubchannel(bool time, bool subq, uint8_t parameter, uint8_t tr
|
|
|
extern "C" int scsiCDRomCommand()
|
|
|
{
|
|
|
image_config_t &img = *(image_config_t*)scsiDev.target->cfg;
|
|
|
- int commandHandled = 1;
|
|
|
+ int commandHandled = 1;
|
|
|
|
|
|
- uint8_t command = scsiDev.cdb[0];
|
|
|
+ uint8_t command = scsiDev.cdb[0];
|
|
|
if (command == 0x1B && (scsiDev.cdb[4] & 2))
|
|
|
{
|
|
|
// CD-ROM load & eject
|
|
|
@@ -1257,49 +1257,49 @@ extern "C" int scsiCDRomCommand()
|
|
|
img.cdrom_events = 3; // Media removal
|
|
|
}
|
|
|
}
|
|
|
- else if (command == 0x43)
|
|
|
- {
|
|
|
- // CD-ROM Read TOC
|
|
|
- bool MSF = (scsiDev.cdb[1] & 0x02);
|
|
|
- uint8_t track = scsiDev.cdb[6];
|
|
|
- uint16_t allocationLength =
|
|
|
- (((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;
|
|
|
- switch (format)
|
|
|
- {
|
|
|
- case 0: doReadTOC(MSF, track, allocationLength); break; // SCSI-2
|
|
|
- case 1: doReadSessionInfo(MSF, allocationLength); break; // MMC2
|
|
|
- case 2: doReadFullTOC(0, track, allocationLength); break; // MMC2
|
|
|
- case 3: doReadFullTOC(1, track, allocationLength); break; // MMC2
|
|
|
- default:
|
|
|
- {
|
|
|
- scsiDev.status = CHECK_CONDITION;
|
|
|
- scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
- scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
- scsiDev.phase = STATUS;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (command == 0x44)
|
|
|
- {
|
|
|
- // CD-ROM Read Header
|
|
|
- bool MSF = (scsiDev.cdb[1] & 0x02);
|
|
|
- uint32_t lba = 0; // IGNORED for now
|
|
|
- uint16_t allocationLength =
|
|
|
- (((uint32_t) scsiDev.cdb[7]) << 8) +
|
|
|
- scsiDev.cdb[8];
|
|
|
- doReadHeader(MSF, lba, allocationLength);
|
|
|
- }
|
|
|
+ else if (command == 0x43)
|
|
|
+ {
|
|
|
+ // CD-ROM Read TOC
|
|
|
+ bool MSF = (scsiDev.cdb[1] & 0x02);
|
|
|
+ uint8_t track = scsiDev.cdb[6];
|
|
|
+ uint16_t allocationLength =
|
|
|
+ (((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;
|
|
|
+ switch (format)
|
|
|
+ {
|
|
|
+ case 0: doReadTOC(MSF, track, allocationLength); break; // SCSI-2
|
|
|
+ case 1: doReadSessionInfo(MSF, allocationLength); break; // MMC2
|
|
|
+ case 2: doReadFullTOC(0, track, allocationLength); break; // MMC2
|
|
|
+ case 3: doReadFullTOC(1, track, allocationLength); break; // MMC2
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ scsiDev.status = CHECK_CONDITION;
|
|
|
+ scsiDev.target->sense.code = ILLEGAL_REQUEST;
|
|
|
+ scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
|
|
|
+ scsiDev.phase = STATUS;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (command == 0x44)
|
|
|
+ {
|
|
|
+ // CD-ROM Read Header
|
|
|
+ bool MSF = (scsiDev.cdb[1] & 0x02);
|
|
|
+ uint32_t lba = 0; // IGNORED for now
|
|
|
+ uint16_t allocationLength =
|
|
|
+ (((uint32_t) scsiDev.cdb[7]) << 8) +
|
|
|
+ scsiDev.cdb[8];
|
|
|
+ doReadHeader(MSF, lba, allocationLength);
|
|
|
+ }
|
|
|
else if (command == 0x51)
|
|
|
{
|
|
|
uint16_t allocationLength =
|
|
|
- (((uint32_t) scsiDev.cdb[7]) << 8) +
|
|
|
- scsiDev.cdb[8];
|
|
|
+ (((uint32_t) scsiDev.cdb[7]) << 8) +
|
|
|
+ scsiDev.cdb[8];
|
|
|
doReadDiscInformation(allocationLength);
|
|
|
}
|
|
|
else if (command == 0x4A)
|
|
|
@@ -1434,9 +1434,9 @@ extern "C" int scsiCDRomCommand()
|
|
|
doReadCD(lba, blocks, 0, 0x10, 0);
|
|
|
}
|
|
|
else
|
|
|
- {
|
|
|
- commandHandled = 0;
|
|
|
- }
|
|
|
+ {
|
|
|
+ commandHandled = 0;
|
|
|
+ }
|
|
|
|
|
|
- return commandHandled;
|
|
|
+ return commandHandled;
|
|
|
}
|