return v;
}
-static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_info *di)
+static int scsi_read_cd_da(int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_info *di)
+{
+ struct blkdevstate *st = &state[unitnum];
+ int msf = cmd[0] == 0xd9;
+ int start = msf ? msf2lsn(rl(cmd + 2) & 0x00ffffff) : rl(cmd + 2);
+ int len = rl(cmd + 5) & 0x00ffffff;
+ int sectorsize;
+ uae_u8 subcode = cmd[10];
+ switch (subcode)
+ {
+ case 0:
+ sectorsize = 2352;
+ break;
+ case 1:
+ sectorsize = 2368;
+ break;
+ case 2:
+ sectorsize = 2448;
+ break;
+ case 3:
+ sectorsize = 96;
+ break;
+ default:
+ return -1;
+ }
+ if (msf) {
+ int end = msf2lsn(len);
+ len = end - start;
+ if (len < 0)
+ return -1;
+ }
+ if (len == 0)
+ return 0;
+ int v = sys_command_cd_rawread(unitnum, data, start, len, sectorsize);
+ if (v > 0)
+ st->current_pos = start + len;
+ return v;
+}
+
+static int scsi_read_cd(int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_info *di)
{
struct blkdevstate *st = &state[unitnum];
int msf = cmd[0] == 0xb9;
}
}
break;
+ case 0xd8: // READ CD-DA
+ case 0xd9: // READ CD-DA MSF
+ if (nodisk(&di))
+ goto nodisk;
+ scsi_len = scsi_read_cd_da(unitnum, cmdbuf, scsi_data, &di);
+ if (scsi_len == -2)
+ goto notdatatrack;
+ if (scsi_len == -1)
+ goto errreq;
+ break;
case 0xbe: // READ CD
case 0xb9: // READ CD MSF
if (nodisk (&di))
goto nodisk;
- scsi_len = scsi_read_cd (unitnum, cmdbuf, scsi_data, &di);
+ scsi_len = scsi_read_cd(unitnum, cmdbuf, scsi_data, &di);
if (scsi_len == -2)
goto notdatatrack;
if (scsi_len == -1)
ssize = t->size + t->skipsize;
cdda_stop (cdu);
if (sectorsize > 0) {
- if (sectorsize == 2352 && t->size == 2336) {
+ if ((sectorsize == 2352 || sectorsize == 2368 || sectorsize == 2448) && t->size == 2336) {
// 2336 -> 2352
while (size-- > 0) {
int address = asector + 150;
asector++;
data += sectorsize;
ret += sectorsize;
+ if (sectorsize == 2448) {
+ // all subs
+ getsub_deinterleaved(data - SUB_CHANNEL_SIZE, cdu, t, sector);
+ } else if (sectorsize == 2368) {
+ // sub q only
+ uae_u8 subs[SUB_CHANNEL_SIZE];
+ getsub_deinterleaved(subs, cdu, t, sector);
+ memcpy(data - SUBQ_SIZE, subs + SUBQ_SIZE, SUBQ_SIZE);
+ }
}
- } else if (sectorsize == 2352 && t->size == 2048) {
+ } else if ((sectorsize == 2352 || sectorsize == 2368 || sectorsize == 2448) && t->size == 2048) {
// 2048 -> 2352
while (size-- > 0) {
memset (data, 0, 16);
asector++;
data += sectorsize;
ret += sectorsize;
+ if (sectorsize == 2448) {
+ // all subs
+ getsub_deinterleaved(data - SUB_CHANNEL_SIZE, cdu, t, sector);
+ } else if (sectorsize == 2368) {
+ // sub q only
+ uae_u8 subs[SUB_CHANNEL_SIZE];
+ getsub_deinterleaved(subs, cdu, t, sector);
+ memcpy(data - SUBQ_SIZE, subs + SUBQ_SIZE, SUBQ_SIZE);
+ }
}
} else if (sectorsize == 2048 && t->size == 2352) {
// 2352 -> 2048
data += sectorsize;
ret++;
}
+ } else if (sectorsize == 96) {
+ // subchannels only
+ while (size-- > 0) {
+ getsub_deinterleaved(data, cdu, t, sector);
+ data += SUB_CHANNEL_SIZE;
+ ret += SUB_CHANNEL_SIZE;
+ sector++;
+ }
}
cdu->cd_last_pos = asector;