]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
READ CD-DA and READ CD-DA MSF emulation.
authorToni Wilen <twilen@winuae.net>
Sun, 19 Nov 2017 14:57:54 +0000 (16:57 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 19 Nov 2017 14:57:54 +0000 (16:57 +0200)
blkdev.cpp
blkdev_cdimage.cpp

index ec667ec33c40cb87704cb98c1640aa68ba03f64a..ed81ccb6a86577820f32e9ec8b5bf7465303d94a 100644 (file)
@@ -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)
index 7f9848b597d6b3aee867be8fac6fb6a82fe7a929..b4ca0dbe392793e6d414fb09ebeb5aa3901d9661 100644 (file)
@@ -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;