]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Data track subchannel support.
authorToni Wilen <twilen@winuae.net>
Wed, 18 May 2016 16:21:32 +0000 (19:21 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 18 May 2016 16:21:32 +0000 (19:21 +0300)
akiko.cpp
blkdev.cpp
blkdev_cdimage.cpp
cdtv.cpp
include/blkdev.h
od-win32/blkdev_win32_ioctl.cpp
scsiemul.cpp

index 2f59e0e2fc3ec318aa30d0edb9d6b081c888ab7d..22a798356cfc84a86f3026bdb392028088787c13 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -467,7 +467,7 @@ static bool isaudiotrack (int startlsn)
 
 static struct cd_toc *get_track (int startlsn)
 {
-       for (int i = cdrom_toc_cd_buffer.first_track_offset + 1; i <= cdrom_toc_cd_buffer.last_track_offset; i++) {
+       for (int i = cdrom_toc_cd_buffer.first_track_offset + 1; i <= cdrom_toc_cd_buffer.last_track_offset + 1; i++) {
                struct cd_toc *s = &cdrom_toc_cd_buffer.toc[i];
                uae_u32 addr = s->paddress;
                if (startlsn < addr)
@@ -1090,6 +1090,23 @@ static void cdrom_run_read (void)
                        if ((cdrom_flags & CDFLAG_RAW) || !(cdrom_flags & CDFLAG_CAS))
                                write_log(_T("Akiko warning: Flags = %08x!\n"), cdrom_flags);
 
+                       if (cdrom_flags & CDFLAG_SUBCODE) {
+                               uae_u8 subbuf[SUB_CHANNEL_SIZE] = { 0 };
+                               uae_u8 subbuf2[SUB_CHANNEL_SIZE];
+                               if (sys_command_cd_qcode(unitnum, subbuf2, sector, true))
+                                       sub_to_interleaved(subbuf2, subbuf);
+                               if (cdrom_subcodeoffset >= 128)
+                                       cdrom_subcodeoffset = 0;
+                               else
+                                       cdrom_subcodeoffset = 128;
+                               // 96 byte subchannel data
+                               for (int i = 0; i < SUB_CHANNEL_SIZE; i++)
+                                       put_byte(subcode_address + cdrom_subcodeoffset + i, subbuf[i]);
+                               put_long(subcode_address + cdrom_subcodeoffset + SUB_CHANNEL_SIZE, 0xffff0000);
+                               cdrom_subcodeoffset += 100;
+                               set_status(CDINTERRUPT_SUBCODE);
+                       }
+
                } else {
                        inc = 0;
                }
@@ -1221,7 +1238,7 @@ void AKIKO_hsync_handler (void)
                                // 96 byte subchannel data
                                for (int i = 0; i < SUB_CHANNEL_SIZE; i++)
                                        put_byte (subcode_address + cdrom_subcodeoffset + i, subcodebuffer[subcodebufferoffset * SUB_CHANNEL_SIZE + i]);
-                               put_long (subcode_address + cdrom_subcodeoffset + SUB_CHANNEL_SIZE, 0xffffffff);
+                               put_long (subcode_address + cdrom_subcodeoffset + SUB_CHANNEL_SIZE, 0xffff0000);
                                subcodebufferinuse[subcodebufferoffset] = 0;
                                cdrom_subcodeoffset += 100;
                                subcodebufferoffset++;
@@ -1280,7 +1297,7 @@ static void *akiko_thread (void *null)
 
                if (frame2counter <= 0) {
                        frame2counter = 312 * 50 / 2;
-                       if (unitnum >= 0 && sys_command_cd_qcode (unitnum, qcode_buf)) {
+                       if (unitnum >= 0 && sys_command_cd_qcode (unitnum, qcode_buf, -1, false)) {
                                qcode_valid = 1;
                        }
                }
index f88af487c276d3d218ff4e29c79ba579fa9999ba..05b9732674e323dbc949238311fcc83777fcc8f4 100644 (file)
@@ -827,7 +827,7 @@ uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_
 }
 
 /* read qcode */
-int sys_command_cd_qcode (int unitnum, uae_u8 *buf)
+int sys_command_cd_qcode (int unitnum, uae_u8 *buf, int sector, bool all)
 {
        int v;
        if (failunit (unitnum))
@@ -835,10 +835,14 @@ int sys_command_cd_qcode (int unitnum, uae_u8 *buf)
        if (!getsem (unitnum))
                return 0;
        if (state[unitnum].device_func->qcode == NULL) {
-               uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0};
-               v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
+               if (all) {
+                       v = 0;
+               } else {
+                       uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0};
+                       v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
+               }
        } else {
-               v = state[unitnum].device_func->qcode (unitnum, buf, -1);
+               v = state[unitnum].device_func->qcode (unitnum, buf, sector, all);
        }
        freesem (unitnum);
        return v;
@@ -1786,7 +1790,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
 
                        if (nodisk (&di))
                                goto nodisk;
-                       sys_command_cd_qcode (unitnum, buf);
+                       sys_command_cd_qcode (unitnum, buf, -1, false);
                        scsi_len = 4;
                        scsi_data[0] = 0;
                        scsi_data[1] = buf[1];
@@ -1903,7 +1907,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                int start = rl (cmdbuf + 2) & 0x00ffffff;
                if (start == 0x00ffffff) {
                        uae_u8 buf[SUBQ_SIZE] = { 0 };
-                       sys_command_cd_qcode (unitnum, buf);
+                       sys_command_cd_qcode (unitnum, buf, -1, false);
                        start = fromlongbcd (buf + 4 + 7);
                }
                int end = msf2lsn (rl (cmdbuf + 5) & 0x00ffffff);
@@ -1933,7 +1937,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                if (len > 0) {
                        if (start == -1) {
                                uae_u8 buf[SUBQ_SIZE] = { 0 };
-                               sys_command_cd_qcode (unitnum, buf);
+                               sys_command_cd_qcode (unitnum, buf, -1, false);
                                start = msf2lsn (fromlongbcd (buf + 4 + 7));
                        }
                        int end = start + len;
@@ -1976,7 +1980,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                        goto nodisk;
                uae_u8 buf[SUBQ_SIZE] = { 0 };
                int resume = cmdbuf[8] & 1;
-               sys_command_cd_qcode (unitnum, buf);
+               sys_command_cd_qcode (unitnum, buf, -1, false);
                if (buf[1] != AUDIO_STATUS_IN_PROGRESS && buf[1] != AUDIO_STATUS_PAUSED)
                        goto errreq;
                sys_command_cd_pause (unitnum, resume ? 0 : 1);
@@ -2243,7 +2247,7 @@ uae_u8 *save_cd (int num, int *len)
        save_u32 (currprefs.cdslots[num].type);
        save_u32 (0);
        save_u32 (0);
-       sys_command_cd_qcode (num, st->play_qcode);
+       sys_command_cd_qcode (num, st->play_qcode, -1, false);
        for (int i = 0; i < SUBQ_SIZE; i++)
                save_u8 (st->play_qcode[i]);
        save_u32 (st->play_end_pos);
index 5f922c65d4febf79e8d79560e624d4d5e2969dd1..9a9506ce573707593fb9d079ec714eacfda5863a 100644 (file)
@@ -790,7 +790,7 @@ static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_s
        return 1;
 }
 
-static int command_qcode (int unitnum, uae_u8 *buf, int sector)
+static int command_qcode (int unitnum, uae_u8 *buf, int sector, bool all)
 {
        struct cdunit *cdu = unitisopen (unitnum);
        if (!cdu)
@@ -833,7 +833,11 @@ static int command_qcode (int unitnum, uae_u8 *buf, int sector)
        if (!td)
                return 0;
        getsub_deinterleaved (subbuf, cdu, td, pos);
-       memcpy (p, subbuf + 12, 12);
+       if (all)  {
+               memcpy(buf, subbuf, SUB_CHANNEL_SIZE);
+       } else {
+               memcpy (p, subbuf + 12, 12);
+       }
 
        return 1;
 }
index 33eedaf1523b90ecf08dddedc92d2c73511d68b5..8d8065e7a96c3e1a68283e7dfc79cadad4b67302 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -134,7 +134,7 @@ static int get_toc (void)
 
 static int get_qcode (void)
 {
-       if (!sys_command_cd_qcode (unitnum, cdrom_qcode))
+       if (!sys_command_cd_qcode (unitnum, cdrom_qcode, -1, false))
                return 0;
        cdrom_qcode[1] = cd_audio_status;
        return 1;
index fc176aa3dba100fc68ece48e60710029981ae5c2..a3769848a93f31e9b749e2cd0876a2f4b4d81f19 100644 (file)
@@ -121,7 +121,7 @@ typedef int (*pause_func)(int, int);
 typedef int (*stop_func)(int);
 typedef int (*play_func)(int, int, int, int, play_status_callback, play_subchannel_callback);
 typedef uae_u32 (*volume_func)(int, uae_u16, uae_u16);
-typedef int (*qcode_func)(int, uae_u8*, int);
+typedef int (*qcode_func)(int, uae_u8*, int, bool);
 typedef int (*toc_func)(int, struct cd_toc_head*);
 typedef int (*read_func)(int, uae_u8*, int, int);
 typedef int (*rawread_func)(int, uae_u8*, int, int, int, uae_u32);
@@ -170,7 +170,7 @@ extern void sys_command_cd_stop (int unitnum);
 extern int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int);
 extern int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc);
 extern uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_right);
-extern int sys_command_cd_qcode (int unitnum, uae_u8*);
+extern int sys_command_cd_qcode (int unitnum, uae_u8*, int lsn, bool all);
 extern int sys_command_cd_toc (int unitnum, struct cd_toc_head*);
 extern int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size);
 extern int sys_command_cd_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize);
index ed8a3814446aa2c2a2dfe0ac85934bc0a096cb44..b34b88df4b41dbbb71b88254b970b37c8d218b50 100644 (file)
@@ -806,7 +806,7 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan,
 }
 
 /* read qcode */
-static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector)
+static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector, bool all)
 {
        struct dev_info_ioctl *ciw = unitisopen (unitnum);
        if (!ciw)
@@ -822,6 +822,9 @@ static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector)
        bool valid = false;
        bool regenerate = true;
 
+       if (all)
+               return 0;
+
        memset (buf, 0, SUBQ_SIZE);
        p = buf;
 
index eaa75a6f4e9c63ac5e92014ec1652b26651da752..51be268cdb7c702de5d2850374c31292ffd86394 100644 (file)
@@ -850,7 +850,7 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf,
                struct cd_toc_head toc;
                uae_u8 cdinfo[34] = { 0 };
                uae_u8 subq[SUBQ_SIZE] = { 0 };
-               sys_command_cd_qcode (dev->di.unitnum, subq);
+               sys_command_cd_qcode (dev->di.unitnum, subq, -1, false);
                status |= 1 << 0; // door closed
                if (dev->di.media_inserted) {
                        status |= 1 << 1;
@@ -948,7 +948,7 @@ static int dev_do_io_cd (TrapContext *ctx, struct devstruct *dev, uae_u8 *iobuf,
        case CD_QCODELSN:
        {
                uae_u8 subq[SUBQ_SIZE];
-               if (sys_command_cd_qcode (dev->di.unitnum, subq)) {
+               if (sys_command_cd_qcode (dev->di.unitnum, subq, -1, false)) {
                        if (subq[1] == AUDIO_STATUS_IN_PROGRESS || subq[1] == AUDIO_STATUS_PAUSED) {
                                uae_u8 subqdata[12];
                                put_byte_host(subqdata + 0, subq[4 + 0]);