mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-14 14:55:12 +01:00
[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:
parent
364d186789
commit
863c7254c9
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 |
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
187
core/cd_hw/cdd.c
187
core/cd_hw/cdd.c
@ -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) */
|
/* COOKED CD-ROM image (2048 bytes data blocks) */
|
||||||
cdd.sectorSize = 2048;
|
cdd.sectorSize = 2048;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* read next 16 bytes */
|
|
||||||
cdStreamRead(header, 0x10, 1, fd);
|
|
||||||
|
|
||||||
/* look for valid CD image identifier */
|
/* CD-ROM Mode 1 by default */
|
||||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
cdd.toc.tracks[0].type = TYPE_MODE1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* auto-detect CD-ROM synchro pattern */
|
||||||
|
else if (!memcmp(sync, header, 12))
|
||||||
{
|
{
|
||||||
/* RAW format (2352 bytes data blocks) */
|
/* RAW CD-ROM image (2352 bytes data blocks) */
|
||||||
cdd.sectorSize = 2352;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* valid CD image file ? */
|
/* supported CD-ROM image file ? */
|
||||||
if (cdd.sectorSize)
|
if ((cdd.toc.tracks[0].type == TYPE_MODE1) || (cdd.toc.tracks[0].type == TYPE_MODE2))
|
||||||
{
|
{
|
||||||
/* read CD image header + security code */
|
/* 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 */
|
||||||
@ -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);
|
||||||
@ -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,37 +1238,61 @@ 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) */
|
||||||
/* read Mode 1 sector data (2048 bytes only) */
|
cdStreamSeek(cdd.toc.tracks[0].fd, (cdd.lba * 2352) + 12 + 4, SEEK_SET);
|
||||||
cdStreamRead(dst, 2048, 1, cdd.toc.tracks[0].fd);
|
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 2 user data (max 2328 bytes) */
|
||||||
|
cdStreamRead(dst, 2328, 1, cdd.toc.tracks[0].fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdd_read_audio(unsigned int samples)
|
void cdd_read_audio(unsigned int samples)
|
||||||
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user