From: Toni Wilen Date: Sun, 19 Nov 2017 14:57:54 +0000 (+0200) Subject: READ CD-DA and READ CD-DA MSF emulation. X-Git-Tag: 3600~65 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=4ae57b5bb6fab417abbeb36b7e11c3b43a0e78e1;p=francis%2Fwinuae.git READ CD-DA and READ CD-DA MSF emulation. --- diff --git a/blkdev.cpp b/blkdev.cpp index ec667ec3..ed81ccb6 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -1247,7 +1247,46 @@ static int scsiemudrv (int unitnum, uae_u8 *cmd) 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; @@ -1395,11 +1434,21 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, } } 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) diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 7f9848b5..b4ca0dbe 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -912,7 +912,7 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int 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; @@ -927,8 +927,17 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int 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); @@ -938,6 +947,15 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int 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 @@ -972,6 +990,14 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int 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;