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)
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;
}
// 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++;
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;
}
}
}
/* 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))
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;
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];
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);
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;
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);
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);
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)
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;
}
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;
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);
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);
}
/* 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)
bool valid = false;
bool regenerate = true;
+ if (all)
+ return 0;
+
memset (buf, 0, SUBQ_SIZE);
p = buf;
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;
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]);