[Core/CD] added support for CD-ROM Mode 2 (Form 1 & 2) image files (fixes EBXA disc support in Wonder Library)

This commit is contained in:
ekeeke 2019-11-25 19:30:07 +01:00
parent 364d186789
commit 863c7254c9
6 changed files with 168 additions and 106 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 MiB

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

View File

@ -51,7 +51,6 @@
/* CTRL0 register bitmasks */ /* CTRL0 register bitmasks */
#define BIT_DECEN 0x80 #define BIT_DECEN 0x80
#define BIT_E01RQ 0x20
#define BIT_AUTORQ 0x10 #define BIT_AUTORQ 0x10
#define BIT_WRRQ 0x04 #define BIT_WRRQ 0x04
@ -60,7 +59,7 @@
#define BIT_FORMRQ 0x04 #define BIT_FORMRQ 0x04
#define BIT_SHDREN 0x01 #define BIT_SHDREN 0x01
/* CTRL2 register bitmask */ /* STAT3 register bitmask */
#define BIT_VALST 0x80 #define BIT_VALST 0x80
/* TODO: figure exact DMA transfer rate */ /* TODO: figure exact DMA transfer rate */
@ -248,7 +247,7 @@ void cdc_decoder_update(uint32 header)
/* data decoding enabled ? */ /* data decoding enabled ? */
if (cdc.ctrl[0] & BIT_DECEN) if (cdc.ctrl[0] & BIT_DECEN)
{ {
/* update HEAD registers */ /* update HEADx registers with current block header */
*(uint32 *)(cdc.head[0]) = header; *(uint32 *)(cdc.head[0]) = header;
/* set !VALST */ /* set !VALST */
@ -285,18 +284,50 @@ void cdc_decoder_update(uint32 header)
/* CDC buffer address */ /* CDC buffer address */
offset = cdc.pt.w & 0x3fff; offset = cdc.pt.w & 0x3fff;
/* write CDD block header (4 bytes) */ /* write current block header to RAM buffer (4 bytes) */
*(uint32 *)(cdc.ram + offset) = header; *(uint32 *)(cdc.ram + offset) = header;
offset += 4;
/* write CDD block data (2048 bytes) */ /* check decoded block mode */
cdd_read_data(cdc.ram + 4 + offset); if (cdc.head[0][3] == 0x01)
{
/* write Mode 1 user data to RAM buffer (2048 bytes) */
cdd_read_data(cdc.ram + offset, NULL);
offset += 2048;
}
else
{
/* check if CD-ROM Mode 2 decoding is enabled */
if (cdc.ctrl[1] & BIT_MODRQ)
{
/* update HEADx registers with current block sub-header & write Mode 2 user data to RAM buffer (max 2328 bytes) */
cdd_read_data(cdc.ram + offset + 8, cdc.head[1]);
/* write current block sub-header to RAM buffer (4 bytes x 2) */
*(uint32 *)(cdc.ram + offset) = *(uint32 *)(cdc.head[1]);
*(uint32 *)(cdc.ram + offset + 4) = *(uint32 *)(cdc.head[1]);
offset += 2336;
}
else
{
/* update HEADx registers with current block sub-header & write Mode 2 user data to RAM buffer (max 2328 bytes) */
/* NB: when Mode 2 decoding is disabled, sub-header is apparently not written to RAM buffer (required by Wonder Library) */
cdd_read_data(cdc.ram + offset, cdc.head[1]);
offset += 2328;
}
/* set STAT2 register FORM bit according to sub-header FORM bit when CTRL0 register AUTORQ bit is set */
if (cdc.ctrl[0] & BIT_AUTORQ)
{
cdc.stat[2] = (cdc.ctrl[1] & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
}
}
/* take care of buffer overrun */ /* take care of buffer overrun */
offset = offset + 2048 + 4 - 0x4000; if (offset > 0x4000)
if (offset > 0)
{ {
/* data should be written at the start of buffer */ /* data should be written at the start of buffer */
memcpy(cdc.ram, cdc.ram + 0x4000, offset); memcpy(cdc.ram, cdc.ram + 0x4000, offset - 0x4000);
} }
} }
} }
@ -484,15 +515,15 @@ void cdc_reg_w(unsigned char data)
/* set CRCOK bit only if decoding is enabled */ /* set CRCOK bit only if decoding is enabled */
cdc.stat[0] = data & BIT_DECEN; cdc.stat[0] = data & BIT_DECEN;
/* update decoding mode */ /* update STAT2 register */
if (data & BIT_AUTORQ) if (data & BIT_AUTORQ)
{ {
/* set MODE bit according to CTRL1 register & clear FORM bit */ /* set MODE bit according to CTRL1 register MODRQ bit & set FORM bit according to sub-header FORM bit*/
cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ; cdc.stat[2] = (cdc.ctrl[1] & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
} }
else else
{ {
/* set MODE & FORM bits according to CTRL1 register */ /* set MODE & FORM bits according to CTRL1 register MODRQ & FORMRQ bits */
cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ); cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
} }
@ -503,15 +534,15 @@ void cdc_reg_w(unsigned char data)
case 0x0b: /* CTRL1 */ case 0x0b: /* CTRL1 */
{ {
/* update decoding mode */ /* update STAT2 register */
if (cdc.ctrl[0] & BIT_AUTORQ) if (cdc.ctrl[0] & BIT_AUTORQ)
{ {
/* set MODE bit according to CTRL1 register & clear FORM bit */ /* set MODE bit according to CTRL1 register MODRQ bit & set FORM bit according to sub-header FORM bit*/
cdc.stat[2] = data & BIT_MODRQ; cdc.stat[2] = (data & BIT_MODRQ) | ((cdc.head[1][2] & 0x20) >> 3);
} }
else else
{ {
/* set MODE & FORM bits according to CTRL1 register */ /* set MODE & FORM bits according to CTRL1 register MODRQ & FORMRQ bits */
cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ); cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
} }

View File

@ -47,7 +47,9 @@
#define CD_SCAN_SPEED 30 #define CD_SCAN_SPEED 30
/* CD tracks type (CD-DA by default) */ /* CD tracks type (CD-DA by default) */
#define TYPE_CDROM 0x01 #define TYPE_AUDIO 0x00
#define TYPE_MODE1 0x01
#define TYPE_MODE2 0x02
/* BCD conversion lookup tables */ /* BCD conversion lookup tables */
static const uint8 lut_BCD_8[100] = static const uint8 lut_BCD_8[100] =
@ -394,19 +396,31 @@ int cdd_load(char *filename, char *header)
} }
else else
{ {
/* COOKED format (2048 bytes data blocks) */ if (!strcmp(type, "MODE1_RAW"))
if (!strcmp(type, "MODE1")) {
cdd.sectorSize = 2048; /* Mode 1 RAW format (2352 bytes data blocks) */
/* RAW format (2352 bytes data blocks) */
else if (!strcmp(type, "MODE1_RAW"))
cdd.sectorSize = 2352; cdd.sectorSize = 2352;
cdd.toc.tracks[0].type = TYPE_MODE1;
/* unsupported track format */ }
else if (!strcmp(type, "MODE1"))
{
/* Mode 1 COOKED format (2048 bytes data blocks) */
cdd.sectorSize = 2048;
cdd.toc.tracks[0].type = TYPE_MODE1;
}
else if (!strcmp(type, "MODE2_RAW"))
{
/* Mode 2 RAW format (2352 bytes data blocks) */
cdd.sectorSize = 2352;
cdd.toc.tracks[0].type = TYPE_MODE2;
}
else if (strcmp(type, "AUDIO")) else if (strcmp(type, "AUDIO"))
{
/* unsupported track format */
break; break;
}
/* Data track start LBA (2s pause assumed by default) */
/* First track start LBA (2s pause assumed by default) */
cdd.toc.tracks[0].start = 0; cdd.toc.tracks[0].start = 0;
} }
@ -442,9 +456,6 @@ int cdd_load(char *filename, char *header)
/* copy CD image header + security code (skip RAW sector 16-byte header) */ /* copy CD image header + security code (skip RAW sector 16-byte header) */
memcpy(header, cdd.chd.hunk + (cdd.toc.tracks[0].offset % cdd.chd.hunkbytes) + ((cdd.sectorSize == 2048) ? 0 : 16), 0x210); memcpy(header, cdd.chd.hunk + (cdd.toc.tracks[0].offset % cdd.chd.hunkbytes) + ((cdd.sectorSize == 2048) ? 0 : 16), 0x210);
/* there is a valid DATA track */
cdd.toc.tracks[0].type = TYPE_CDROM;
} }
/* valid CD image ? */ /* valid CD image ? */
@ -473,40 +484,43 @@ int cdd_load(char *filename, char *header)
{ {
int len; int len;
static const uint8 sync[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
/* read first 16 bytes */ /* read first 16 bytes */
cdStreamRead(header, 0x10, 1, fd); cdStreamRead(header, 0x10, 1, fd);
/* look for valid CD image identifier */ /* auto-detect valid Sega CD image */
if (!memcmp("SEGADISCSYSTEM", header, 14)) if (!memcmp("SEGADISCSYSTEM", header, 14))
{
/* COOKED format (2048 bytes data blocks) */
cdd.sectorSize = 2048;
}
else
{
/* read next 16 bytes */
cdStreamRead(header, 0x10, 1, fd);
/* look for valid CD image identifier */
if (!memcmp("SEGADISCSYSTEM", header, 14))
{
/* RAW format (2352 bytes data blocks) */
cdd.sectorSize = 2352;
}
}
/* valid CD image file ? */
if (cdd.sectorSize)
{ {
/* read CD image header + security code */ /* COOKED CD-ROM image (2048 bytes data blocks) */
cdd.sectorSize = 2048;
/* CD-ROM Mode 1 by default */
cdd.toc.tracks[0].type = TYPE_MODE1;
}
/* auto-detect CD-ROM synchro pattern */
else if (!memcmp(sync, header, 12))
{
/* RAW CD-ROM image (2352 bytes data blocks) */
cdd.sectorSize = 2352;
/* auto-detect CD-ROM mode from block header (byte 15) */
cdd.toc.tracks[0].type = header[15];
/* read next 16 bytes (start of user data) */
cdStreamRead(header, 0x10, 1, fd);
}
/* supported CD-ROM image file ? */
if ((cdd.toc.tracks[0].type == TYPE_MODE1) || (cdd.toc.tracks[0].type == TYPE_MODE2))
{
/* read Sega CD image header + security code */
cdStreamRead(header + 0x10, 0x200, 1, fd); cdStreamRead(header + 0x10, 0x200, 1, fd);
/* initialize first track file descriptor */ /* initialize first track file descriptor */
cdd.toc.tracks[0].fd = fd; cdd.toc.tracks[0].fd = fd;
/* this is a valid DATA track */
cdd.toc.tracks[0].type = TYPE_CDROM;
/* DATA track end LBA (based on DATA file length) */ /* DATA track end LBA (based on DATA file length) */
cdStreamSeek(fd, 0, SEEK_END); cdStreamSeek(fd, 0, SEEK_END);
cdd.toc.tracks[0].end = cdStreamTell(fd) / cdd.sectorSize; cdd.toc.tracks[0].end = cdStreamTell(fd) / cdd.sectorSize;
@ -527,7 +541,7 @@ int cdd_load(char *filename, char *header)
} }
else else
{ {
/* this is not a CD image file */ /* this is not a supported CD-ROM image file */
isCDfile = 0; isCDfile = 0;
/* close file */ /* close file */
@ -615,7 +629,7 @@ int cdd_load(char *filename, char *header)
unsigned char head[12]; unsigned char head[12];
cdStreamRead(head, 12, 1, cdd.toc.tracks[cdd.toc.last].fd); cdStreamRead(head, 12, 1, cdd.toc.tracks[cdd.toc.last].fd);
cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET); cdStreamSeek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
/* autodetect WAVE file */ /* autodetect WAVE file */
if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4)) if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4))
{ {
@ -673,42 +687,35 @@ int cdd_load(char *filename, char *header)
/* decode TRACK commands */ /* decode TRACK commands */
else if ((sscanf(lptr, "TRACK %02d %*s", &bb)) || (sscanf(lptr, "TRACK %d %*s", &bb))) else if ((sscanf(lptr, "TRACK %02d %*s", &bb)) || (sscanf(lptr, "TRACK %d %*s", &bb)))
{ {
/* check track number */ /* autodetect DATA track type (first track only) */
if (bb != (cdd.toc.last + 1))
{
/* close any opened file */
if (cdd.toc.tracks[cdd.toc.last].fd)
{
cdStreamClose(cdd.toc.tracks[cdd.toc.last].fd);
cdd.toc.tracks[cdd.toc.last].fd = 0;
}
/* missing tracks */
break;
}
/* autodetect DATA track (first track only) */
if (!cdd.toc.last) if (!cdd.toc.last)
{ {
/* CD-ROM Mode 1 support only */
if (strstr(lptr,"MODE1/2048")) if (strstr(lptr,"MODE1/2048"))
{ {
/* COOKED format (2048 bytes / block) */ /* Mode 1 COOKED format (2048 bytes / block) */
cdd.sectorSize = 2048; cdd.sectorSize = 2048;
cdd.toc.tracks[0].type = TYPE_MODE1;
} }
else if (strstr(lptr,"MODE1/2352")) else if (strstr(lptr,"MODE1/2352"))
{ {
/* RAW format (2352 bytes / block) */ /* Mode 1 RAW format (2352 bytes / block) */
cdd.sectorSize = 2352; cdd.sectorSize = 2352;
cdd.toc.tracks[0].type = TYPE_MODE1;
/* skip 16-byte header */ }
cdStreamSeek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET); else if (strstr(lptr,"MODE2/2352"))
{
/* Mode 2 RAW format (2352 bytes / block) */
cdd.sectorSize = 2352;
cdd.toc.tracks[0].type = TYPE_MODE2;
} }
if (cdd.sectorSize) if (cdd.sectorSize)
{ {
/* this is a valid DATA track */ if (cdd.sectorSize == 2352)
cdd.toc.tracks[0].type = TYPE_CDROM; {
/* skip 16-byte header */
cdStreamSeek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
}
/* read CD image header + security code */ /* read CD image header + security code */
cdStreamRead(header, 0x210, 1, cdd.toc.tracks[0].fd); cdStreamRead(header, 0x210, 1, cdd.toc.tracks[0].fd);
@ -888,7 +895,7 @@ int cdd_load(char *filename, char *header)
unsigned char head[12]; unsigned char head[12];
cdStreamRead(head, 12, 1, fd); cdStreamRead(head, 12, 1, fd);
cdStreamSeek(fd, 0, SEEK_SET); cdStreamSeek(fd, 0, SEEK_SET);
/* autodetect WAVE file */ /* autodetect WAVE file */
if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4)) if (!memcmp(head, "RIFF", 4) && !memcmp(head + 8, "WAVE", 4))
{ {
@ -1039,8 +1046,8 @@ int cdd_load(char *filename, char *header)
/* CD mounted */ /* CD mounted */
cdd.loaded = 1; cdd.loaded = 1;
/* Valid DATA track found ? */ /* Valid CD-ROM Mode 1 track found ? */
if (cdd.toc.tracks[0].type) if (cdd.toc.tracks[0].type == TYPE_MODE1)
{ {
/* simulate audio tracks if none found */ /* simulate audio tracks if none found */
if (cdd.toc.last == 1) if (cdd.toc.last == 1)
@ -1210,7 +1217,7 @@ void cdd_unload(void)
cdd.sectorSize = 0; cdd.sectorSize = 0;
} }
void cdd_read_data(uint8 *dst) void cdd_read_data(uint8 *dst, uint8 *subheader)
{ {
/* only allow reading (first) CD-ROM track sectors */ /* only allow reading (first) CD-ROM track sectors */
if (cdd.toc.tracks[cdd.index].type && (cdd.lba >= 0)) if (cdd.toc.tracks[cdd.index].type && (cdd.lba >= 0))
@ -1231,36 +1238,60 @@ void cdd_read_data(uint8 *dst)
cdd.chd.hunknum = hunknum; cdd.chd.hunknum = hunknum;
} }
/* copy Mode 1 sector data (2048 bytes only) */ /* check sector size */
if (cdd.sectorSize == 2048) if (cdd.sectorSize == 2048)
{ {
/* Mode 1 COOKED data (ISO) */ /* read Mode 1 user data (2048 bytes) */
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes), 2048); memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes), 2048);
} }
else else
{ {
/* Mode 1 RAW data (skip 16-byte header) */ /* check if sub-header is required (Mode 2 sector only) */
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 16, 2048); if (!subheader)
{
/* read Mode 1 user data (2048 bytes), skipping block sync pattern (12 bytes) + block header (4 bytes)*/
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4, 2048);
}
else
{
/* read Mode 2 sub-header (first 4 bytes), skipping block sync pattern (12 bytes) + block header (4 bytes)*/
memcpy(subheader, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4, 4);
/* read Mode 2 user data (max 2328 bytes), skipping Mode 2 sub-header (8 bytes) */
memcpy(dst, cdd.chd.hunk + (offset % cdd.chd.hunkbytes) + 12 + 4 + 8, 2328);
}
} }
return; return;
} }
#endif #endif
/* seek current track sector */ /* check sector size */
if (cdd.sectorSize == 2048) if (cdd.sectorSize == 2048)
{ {
/* Mode 1 COOKED data (ISO) */ /* read Mode 1 user data (2048 bytes) */
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET); cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET);
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
} }
else else
{ {
/* Mode 1 RAW data (skip 16-byte header) */ /* check if sub-header is required (Mode 2 sector only) */
cdStreamSeek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET); if (!subheader)
} {
/* skip block sync pattern (12 bytes) + block header (4 bytes) then read Mode 1 user data (2048 bytes) */
cdStreamSeek(cdd.toc.tracks[0].fd, (cdd.lba * 2352) + 12 + 4, SEEK_SET);
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
}
else
{
/* skip block sync pattern (12 bytes) + block header (4 bytes) + Mode 2 sub-header (first 4 bytes) then read Mode 2 sub-header (last 4 bytes) */
cdStreamSeek(cdd.toc.tracks[0].fd, (cdd.lba * 2352) + 12 + 4 + 4, SEEK_SET);
cdStreamRead(subheader, 4, 1, cdd.toc.tracks[0].fd);
/* read Mode 1 sector data (2048 bytes only) */ /* read Mode 2 user data (max 2328 bytes) */
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd); cdStreamRead(dst, 2328, 1, cdd.toc.tracks[0].fd);
}
}
} }
} }
@ -1580,13 +1611,13 @@ void cdd_update(void)
/* track type */ /* track type */
if (cdd.toc.tracks[cdd.index].type) if (cdd.toc.tracks[cdd.index].type)
{ {
/* CD-ROM (Mode 1) sector header */ /* CD-ROM sector header */
uint8 header[4]; uint8 header[4];
uint32 msf = cdd.lba + 150; uint32 msf = cdd.lba + 150;
header[0] = lut_BCD_8[(msf / 75) / 60]; header[0] = lut_BCD_8[(msf / 75) / 60];
header[1] = lut_BCD_8[(msf / 75) % 60]; header[1] = lut_BCD_8[(msf / 75) % 60];
header[2] = lut_BCD_8[(msf % 75)]; header[2] = lut_BCD_8[(msf % 75)];
header[3] = 0x01; header[3] = cdd.toc.tracks[cdd.index].type;
/* decode CD-ROM track sector */ /* decode CD-ROM track sector */
cdc_decoder_update(*(uint32 *)(header)); cdc_decoder_update(*(uint32 *)(header));
@ -1720,7 +1751,7 @@ void cdd_update(void)
} }
/* AUDIO track playing ? */ /* AUDIO track playing ? */
scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type; scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x01 : 0x00;
/* seek to current subcode position */ /* seek to current subcode position */
if (cdd.toc.sub) if (cdd.toc.sub)
@ -1819,7 +1850,7 @@ void cdd_process(void)
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */ scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x04 : 0x00; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
break; break;
} }
@ -1830,7 +1861,7 @@ void cdd_process(void)
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */ scd.regs[0x40>>1].byte.h = cdd.toc.tracks[cdd.index].type ? 0x04 : 0x00; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
break; break;
} }
@ -1873,7 +1904,7 @@ void cdd_process(void)
scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60]; scd.regs[0x3a>>1].w = lut_BCD_16[(lba/75)/60];
scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; scd.regs[0x3c>>1].w = lut_BCD_16[(lba/75)%60];
scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)]; scd.regs[0x3e>>1].w = lut_BCD_16[(lba%75)];
scd.regs[0x3e>>1].byte.h |= (cdd.toc.tracks[track-1].type << 3); /* RS6 bit 3 is set for CD-ROM track */ scd.regs[0x3e>>1].byte.h |= cdd.toc.tracks[track-1].type ? 0x08 : 0x00; /* RS6 bit 3 is set for CD-ROM track */
scd.regs[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */ scd.regs[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */
break; break;
} }
@ -1973,14 +2004,14 @@ void cdd_process(void)
if (cdd.chd.file) if (cdd.chd.file)
{ {
/* CHD file offset */ /* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE); cdd.chd.hunkofs = cdd.toc.tracks[index].offset + (lba * CD_FRAME_SIZE);
} }
else else
#endif #endif
if (cdd.toc.tracks[index].type) if (cdd.toc.tracks[index].type)
{ {
/* DATA track */ /* DATA track */
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); cdStreamSeek(cdd.toc.tracks[index].fd, lba * cdd.sectorSize, SEEK_SET);
} }
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS) #if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
else if (cdd.toc.tracks[index].vf.seekable) else if (cdd.toc.tracks[index].vf.seekable)
@ -2079,14 +2110,14 @@ void cdd_process(void)
if (cdd.chd.file) if (cdd.chd.file)
{ {
/* CHD file offset */ /* CHD file offset */
cdd.chd.hunkofs = cdd.toc.tracks[cdd.index].offset + (lba * CD_FRAME_SIZE); cdd.chd.hunkofs = cdd.toc.tracks[index].offset + (lba * CD_FRAME_SIZE);
} }
else else
#endif #endif
if (cdd.toc.tracks[index].type) if (cdd.toc.tracks[index].type)
{ {
/* DATA track */ /* DATA track */
cdStreamSeek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); cdStreamSeek(cdd.toc.tracks[index].fd, lba * cdd.sectorSize, SEEK_SET);
} }
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS) #if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
else if (cdd.toc.tracks[index].vf.seekable) else if (cdd.toc.tracks[index].vf.seekable)

View File

@ -136,7 +136,7 @@ extern int cdd_context_save(uint8 *state);
extern int cdd_context_load(uint8 *state); extern int cdd_context_load(uint8 *state);
extern int cdd_load(char *filename, char *header); extern int cdd_load(char *filename, char *header);
extern void cdd_unload(void); extern void cdd_unload(void);
extern void cdd_read_data(uint8 *dst); extern void cdd_read_data(uint8 *dst, uint8 *subheader);
extern void cdd_read_audio(unsigned int samples); extern void cdd_read_audio(unsigned int samples);
extern void cdd_update(void); extern void cdd_update(void);
extern void cdd_process(void); extern void cdd_process(void);