mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-01-30 19:56:45 +01:00
commit
d291c543f0
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.8 MiB After Width: | Height: | Size: 3.8 MiB |
@ -514,7 +514,7 @@ void sms_cart_init(void)
|
|||||||
if (config.bios & 1)
|
if (config.bios & 1)
|
||||||
{
|
{
|
||||||
/* load BIOS file */
|
/* load BIOS file */
|
||||||
int bios_size = load_bios();
|
int bios_size = load_bios(system_hw);
|
||||||
|
|
||||||
if (bios_size > 0xC000)
|
if (bios_size > 0xC000)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* CD data controller (LC89510 compatible)
|
* CD data controller (LC89510 compatible)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2012-2015 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -376,8 +376,8 @@ void cdc_reg_w(unsigned char data)
|
|||||||
/* start data transfer if data output is enabled */
|
/* start data transfer if data output is enabled */
|
||||||
if (cdc.ifctrl & BIT_DOUTEN)
|
if (cdc.ifctrl & BIT_DOUTEN)
|
||||||
{
|
{
|
||||||
/* set !DTBSY */
|
/* set !DTBSY and !DTEN */
|
||||||
cdc.ifstat &= ~BIT_DTBSY;
|
cdc.ifstat &= ~(BIT_DTBSY | BIT_DTEN);
|
||||||
|
|
||||||
/* clear DBCH bits 4-7 */
|
/* clear DBCH bits 4-7 */
|
||||||
cdc.dbc.byte.h &= 0x0f;
|
cdc.dbc.byte.h &= 0x0f;
|
||||||
@ -391,10 +391,7 @@ void cdc_reg_w(unsigned char data)
|
|||||||
case 2: /* MAIN-CPU host read */
|
case 2: /* MAIN-CPU host read */
|
||||||
case 3: /* SUB-CPU host read */
|
case 3: /* SUB-CPU host read */
|
||||||
{
|
{
|
||||||
/* set !DTEN */
|
/* set DSR bit (SCD register $04) */
|
||||||
cdc.ifstat &= ~BIT_DTEN;
|
|
||||||
|
|
||||||
/* set DSR bit (register $04) */
|
|
||||||
scd.regs[0x04>>1].byte.h |= 0x40;
|
scd.regs[0x04>>1].byte.h |= 0x40;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -645,7 +642,7 @@ unsigned char cdc_reg_r(void)
|
|||||||
unsigned short cdc_host_r(void)
|
unsigned short cdc_host_r(void)
|
||||||
{
|
{
|
||||||
/* check if data is available */
|
/* check if data is available */
|
||||||
if (!(cdc.ifstat & BIT_DTEN))
|
if (scd.regs[0x04>>1].byte.h & 0x40)
|
||||||
{
|
{
|
||||||
/* read data word from CDC RAM buffer */
|
/* read data word from CDC RAM buffer */
|
||||||
uint16 data = *(uint16 *)(cdc.ram + (cdc.dac.w & 0x3ffe));
|
uint16 data = *(uint16 *)(cdc.ram + (cdc.dac.w & 0x3ffe));
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* CD data controller (LC89510 compatible)
|
* CD data controller (LC89510 compatible)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2012-2015 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
|
604
core/cd_hw/cdd.c
604
core/cd_hw/cdd.c
@ -43,6 +43,12 @@
|
|||||||
#define SUPPORTED_EXT 10
|
#define SUPPORTED_EXT 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* CD blocks scanning speed */
|
||||||
|
#define CD_SCAN_SPEED 30
|
||||||
|
|
||||||
|
/* CD tracks type (CD-DA by default) */
|
||||||
|
#define TYPE_CDROM 0x01
|
||||||
|
|
||||||
/* BCD conversion lookup tables */
|
/* BCD conversion lookup tables */
|
||||||
static const uint8 lut_BCD_8[100] =
|
static const uint8 lut_BCD_8[100] =
|
||||||
{
|
{
|
||||||
@ -246,14 +252,18 @@ int cdd_context_load(uint8 *state)
|
|||||||
lba = cdd.toc.tracks[cdd.index].start;
|
lba = cdd.toc.tracks[cdd.index].start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* seek to current subcode position */
|
||||||
|
if (cdd.toc.sub)
|
||||||
|
{
|
||||||
|
/* 96 bytes per sector */
|
||||||
|
fseek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
/* seek to current track position */
|
/* seek to current track position */
|
||||||
if (!cdd.index)
|
if (cdd.toc.tracks[cdd.index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
if (cdd.toc.tracks[0].fd)
|
fseek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
{
|
|
||||||
fseek(cdd.toc.tracks[0].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[cdd.index].vf.seekable)
|
else if (cdd.toc.tracks[cdd.index].vf.seekable)
|
||||||
@ -263,7 +273,7 @@ int cdd_context_load(uint8 *state)
|
|||||||
ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
|
ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
|
||||||
#endif
|
#endif
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba * 588) - cdd.toc.tracks[cdd.index].offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cdd.toc.tracks[cdd.index].fd)
|
else if (cdd.toc.tracks[cdd.index].fd)
|
||||||
@ -277,153 +287,109 @@ int cdd_context_load(uint8 *state)
|
|||||||
|
|
||||||
int cdd_load(char *filename, char *header)
|
int cdd_load(char *filename, char *header)
|
||||||
{
|
{
|
||||||
char fname[256];
|
char fname[256+10];
|
||||||
char line[128];
|
char line[128];
|
||||||
char *ptr = 0;
|
char *ptr, *lptr;
|
||||||
char *lptr = 0;
|
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
|
||||||
|
/* assume CD image file by default */
|
||||||
|
int isCDfile = 1;
|
||||||
|
|
||||||
/* first unmount any loaded disc */
|
/* first unmount any loaded disc */
|
||||||
cdd_unload();
|
cdd_unload();
|
||||||
|
|
||||||
/* open file */
|
/* open file */
|
||||||
fd = fopen(filename, "rb");
|
fd = fopen(filename, "rb");
|
||||||
|
if (!fd) return (-1);
|
||||||
|
|
||||||
/* save a copy of base filename */
|
/* save a copy of base filename */
|
||||||
strncpy(fname, filename, 256);
|
strncpy(fname, filename, 256);
|
||||||
|
|
||||||
/* autodetect .cue file */
|
/* check loaded file extension */
|
||||||
if (!memcmp(".cue", &filename[strlen(filename) - 4], 4) || !memcmp(".CUE", &filename[strlen(filename) - 4], 4))
|
if (memcmp(".cue", &filename[strlen(filename) - 4], 4) && memcmp(".CUE", &filename[strlen(filename) - 4], 4))
|
||||||
{
|
{
|
||||||
if (fd)
|
int len;
|
||||||
{
|
|
||||||
/* find first FILE command */
|
|
||||||
while (!lptr)
|
|
||||||
{
|
|
||||||
if (fgets(line, 128, fd) == NULL)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lptr = strstr(line, "FILE");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get BINARY file name */
|
|
||||||
if (lptr && strstr(line, " BINARY"))
|
|
||||||
{
|
|
||||||
/* skip "FILE" attribute */
|
|
||||||
lptr += 4;
|
|
||||||
|
|
||||||
/* skip DOUBLE QUOTE or SPACE characters */
|
|
||||||
while ((*lptr == 0x20) || (*lptr == '\"')) lptr++;
|
|
||||||
|
|
||||||
/* set pointer at the end of filepath */
|
|
||||||
ptr = fname + strlen(fname) - 1;
|
|
||||||
while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--;
|
|
||||||
if (ptr - fname) ptr++;
|
|
||||||
|
|
||||||
/* append filename characters after filepath */
|
|
||||||
while ((*lptr != '\"') && memcmp(lptr, " BINARY", 7) && (ptr < (fname + 255)))
|
|
||||||
{
|
|
||||||
*ptr++ = *lptr++;
|
|
||||||
}
|
|
||||||
*ptr = 0;
|
|
||||||
|
|
||||||
/* open file & initialize DATA track file descriptor */
|
|
||||||
cdd.toc.tracks[0].fd = fopen(fname, "rb");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* close .cue file */
|
|
||||||
fclose(fd);
|
|
||||||
|
|
||||||
/* invalid .cue file */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* initialize DATA track file descriptor */
|
|
||||||
cdd.toc.tracks[0].fd = fd;
|
|
||||||
|
|
||||||
/* automatically try to open associated .cue file */
|
|
||||||
strncpy(&fname[strlen(fname) - 4], ".cue", 4);
|
|
||||||
fd = fopen(fname, "rb");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cdd.toc.tracks[0].fd)
|
|
||||||
{
|
|
||||||
/* close any opened .cue file */
|
|
||||||
if (fd) fclose(fd);
|
|
||||||
|
|
||||||
/* error opening file */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read first 16 bytes */
|
/* read first 16 bytes */
|
||||||
fread(header, 0x10, 1, cdd.toc.tracks[0].fd);
|
fread(header, 0x10, 1, fd);
|
||||||
|
|
||||||
/* look for valid CD image ID string */
|
/* look for valid CD image identifier */
|
||||||
if (memcmp("SEGADISCSYSTEM", header, 14))
|
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||||
{
|
{
|
||||||
/* if not found, read next 16 bytes */
|
/* COOKED format (2048 bytes data blocks) */
|
||||||
fread(header, 0x10, 1, cdd.toc.tracks[0].fd);
|
cdd.sectorSize = 2048;
|
||||||
|
|
||||||
/* look again for valid CD image ID string */
|
|
||||||
if (memcmp("SEGADISCSYSTEM", header, 14))
|
|
||||||
{
|
|
||||||
/* close any opened .cue file */
|
|
||||||
if (fd) fclose(fd);
|
|
||||||
|
|
||||||
/* close binary file */
|
|
||||||
fclose(cdd.toc.tracks[0].fd);
|
|
||||||
cdd.toc.tracks[0].fd = 0;
|
|
||||||
|
|
||||||
/* not a CD image file */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BIN format (2352 bytes data blocks) */
|
|
||||||
cdd.sectorSize = 2352;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ISO format (2048 bytes data blocks) */
|
/* read next 16 bytes */
|
||||||
cdd.sectorSize = 2048;
|
fread(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 */
|
/* read CD image header + security code */
|
||||||
fread(header + 0x10, 0x200, 1, cdd.toc.tracks[0].fd);
|
fread(header + 0x10, 0x200, 1, fd);
|
||||||
|
|
||||||
/* DATA track start time (based on DATA file length) */
|
/* initialize first track file descriptor */
|
||||||
fseek(cdd.toc.tracks[0].fd, 0, SEEK_END);
|
cdd.toc.tracks[0].fd = fd;
|
||||||
cdd.toc.tracks[0].end = ftell(cdd.toc.tracks[0].fd) / cdd.sectorSize;
|
|
||||||
|
|
||||||
/* DATA track start time (logical block 0) */
|
/* this is a valid DATA track */
|
||||||
fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
|
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||||
|
|
||||||
|
/* DATA track end LBA (based on DATA file length) */
|
||||||
|
fseek(fd, 0, SEEK_END);
|
||||||
|
cdd.toc.tracks[0].end = ftell(fd) / cdd.sectorSize;
|
||||||
|
|
||||||
|
/* DATA track start LBA (logical block 0) */
|
||||||
|
fseek(fd, 0, SEEK_SET);
|
||||||
cdd.toc.tracks[0].start = 0;
|
cdd.toc.tracks[0].start = 0;
|
||||||
|
|
||||||
/* initialize TOC */
|
/* initialize TOC */
|
||||||
cdd.toc.end = cdd.toc.tracks[0].end;
|
cdd.toc.end = cdd.toc.tracks[0].end;
|
||||||
cdd.toc.last = 1;
|
cdd.toc.last = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this is not a CD image file */
|
||||||
|
isCDfile = 0;
|
||||||
|
|
||||||
/* automatically retrieve audio tracks infos from .cue file */
|
/* close file */
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* automatically try to mount CD associated CUE file */
|
||||||
|
len = strlen(fname);
|
||||||
|
while ((len && (fname[len] != '.')) || (len > 251)) len--;
|
||||||
|
strcpy(&fname[len], ".cue");
|
||||||
|
fd = fopen(fname, "rb");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse CUE file */
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
int pregap = 0;
|
int mm, ss, bb, pregap = 0;
|
||||||
int mm, ss, bb;
|
|
||||||
|
|
||||||
/* skip first (DATA) track */
|
/* DATA track already loaded ? */
|
||||||
while (!strstr(line, "INDEX 01") && !strstr(line, "INDEX 1"))
|
if (cdd.toc.last)
|
||||||
{
|
{
|
||||||
if (fgets(line, 128, fd) == NULL)
|
/* skip first track */
|
||||||
|
while (fgets(line, 128, fd))
|
||||||
{
|
{
|
||||||
|
if (strstr(line, "INDEX 01") && !strstr(line, "INDEX 1"))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read next lines until end of file */
|
/* read lines until end of file */
|
||||||
while (fgets(line, 128, fd) != NULL)
|
while (fgets(line, 128, fd))
|
||||||
{
|
{
|
||||||
/* skip any SPACE characters */
|
/* skip any SPACE characters */
|
||||||
lptr = line;
|
lptr = line;
|
||||||
@ -432,25 +398,34 @@ int cdd_load(char *filename, char *header)
|
|||||||
/* decode FILE commands */
|
/* decode FILE commands */
|
||||||
if (!(memcmp(lptr, "FILE", 4)))
|
if (!(memcmp(lptr, "FILE", 4)))
|
||||||
{
|
{
|
||||||
/* skip "FILE" attribute */
|
/* retrieve current path */
|
||||||
lptr += 4;
|
|
||||||
|
|
||||||
/* skip DOUBLE QUOTE or SPACE characters */
|
|
||||||
while ((*lptr == 0x20) || (*lptr == '\"')) lptr++;
|
|
||||||
|
|
||||||
/* set pointer at the end of filepath */
|
|
||||||
ptr = fname + strlen(fname) - 1;
|
ptr = fname + strlen(fname) - 1;
|
||||||
while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--;
|
while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--;
|
||||||
if (ptr - fname) ptr++;
|
if (ptr - fname) ptr++;
|
||||||
|
|
||||||
/* append filename characters after filepath */
|
/* skip "FILE" attribute */
|
||||||
while ((*lptr != '\"') && (lptr <= (line + 128)) && (ptr < (fname + 255)))
|
lptr += 4;
|
||||||
|
|
||||||
|
/* skip SPACE characters */
|
||||||
|
while (*lptr == 0x20) lptr++;
|
||||||
|
|
||||||
|
/* retrieve full filename */
|
||||||
|
if (*lptr == '\"')
|
||||||
{
|
{
|
||||||
|
/* skip first DOUBLE QUOTE character */
|
||||||
|
lptr++;
|
||||||
|
while ((*lptr != '\"') && (lptr <= (line + 128)) && (ptr < (fname + 255)))
|
||||||
|
*ptr++ = *lptr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no DOUBLE QUOTE used */
|
||||||
|
while ((*lptr != 0x20) && (lptr <= (line + 128)) && (ptr < (fname + 255)))
|
||||||
*ptr++ = *lptr++;
|
*ptr++ = *lptr++;
|
||||||
}
|
}
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
|
|
||||||
/* open file & initialize track file descriptor */
|
/* open current track file descriptor */
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = fopen(fname, "rb");
|
cdd.toc.tracks[cdd.toc.last].fd = fopen(fname, "rb");
|
||||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
@ -461,11 +436,11 @@ int cdd_load(char *filename, char *header)
|
|||||||
/* reset current file PREGAP length */
|
/* reset current file PREGAP length */
|
||||||
pregap = 0;
|
pregap = 0;
|
||||||
|
|
||||||
/* reset current file read offset */
|
/* reset current track file read offset */
|
||||||
cdd.toc.tracks[cdd.toc.last].offset = 0;
|
cdd.toc.tracks[cdd.toc.last].offset = 0;
|
||||||
|
|
||||||
/* check supported file types */
|
/* check supported audio file types */
|
||||||
if (!strstr(lptr,"BINARY"))
|
if (!strstr(lptr,"BINARY") && !strstr(lptr,"MOTOROLA"))
|
||||||
{
|
{
|
||||||
/* read file header */
|
/* read file header */
|
||||||
unsigned char head[32];
|
unsigned char head[32];
|
||||||
@ -473,7 +448,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
fread(head, 32, 1, cdd.toc.tracks[cdd.toc.last].fd);
|
fread(head, 32, 1, cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* autodetect WAVE file header (16-bit stereo @44.1kHz only) */
|
/* autodetect WAVE file header (44.1KHz 16-bit stereo format only) */
|
||||||
if (!memcmp(head, waveHeader, 32))
|
if (!memcmp(head, waveHeader, 32))
|
||||||
{
|
{
|
||||||
/* adjust current track file read offset with WAVE header length */
|
/* adjust current track file read offset with WAVE header length */
|
||||||
@ -504,7 +479,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* decode TRACK commands */
|
/* decode TRACK commands */
|
||||||
else if ((sscanf(lptr, "TRACK %02d AUDIO", &bb)) || (sscanf(lptr, "TRACK %d AUDIO", &bb)))
|
else if ((sscanf(lptr, "TRACK %02d %*s", &bb)) || (sscanf(lptr, "TRACK %d %*s", &bb)))
|
||||||
{
|
{
|
||||||
/* check track number */
|
/* check track number */
|
||||||
if (bb != (cdd.toc.last + 1))
|
if (bb != (cdd.toc.last + 1))
|
||||||
@ -520,13 +495,44 @@ int cdd_load(char *filename, char *header)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if a single file is used for all tracks */
|
/* autodetect DATA track (first track only) */
|
||||||
|
if (!cdd.toc.last)
|
||||||
|
{
|
||||||
|
/* CD-ROM Mode 1 support only */
|
||||||
|
if (strstr(lptr,"MODE1/2048"))
|
||||||
|
{
|
||||||
|
/* COOKED format (2048 bytes / block) */
|
||||||
|
cdd.sectorSize = 2048;
|
||||||
|
}
|
||||||
|
else if (strstr(lptr,"MODE1/2352"))
|
||||||
|
{
|
||||||
|
/* RAW format (2352 bytes / block) */
|
||||||
|
cdd.sectorSize = 2352;
|
||||||
|
|
||||||
|
/* skip 16-byte header */
|
||||||
|
fseek(cdd.toc.tracks[0].fd, 0x10, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdd.sectorSize)
|
||||||
|
{
|
||||||
|
/* this is a valid DATA track */
|
||||||
|
cdd.toc.tracks[0].type = TYPE_CDROM;
|
||||||
|
|
||||||
|
/* read CD image header + security code */
|
||||||
|
fread(header, 0x210, 1, cdd.toc.tracks[0].fd);
|
||||||
|
fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* check if same file is used for consecutive tracks */
|
||||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
/* clear previous track end time */
|
/* clear previous track end time */
|
||||||
cdd.toc.tracks[cdd.toc.last - 1].end = 0;
|
cdd.toc.tracks[cdd.toc.last - 1].end = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* decode PREGAP commands */
|
/* decode PREGAP commands */
|
||||||
else if (sscanf(lptr, "PREGAP %02d:%02d:%02d", &mm, &ss, &bb) == 3)
|
else if (sscanf(lptr, "PREGAP %02d:%02d:%02d", &mm, &ss, &bb) == 3)
|
||||||
@ -539,41 +545,41 @@ int cdd_load(char *filename, char *header)
|
|||||||
else if ((sscanf(lptr, "INDEX 00 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
else if ((sscanf(lptr, "INDEX 00 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
||||||
(sscanf(lptr, "INDEX 0 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
(sscanf(lptr, "INDEX 0 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
||||||
{
|
{
|
||||||
/* check if a single file is used for all tracks */
|
/* check if previous track end time needs to be set */
|
||||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
if (cdd.toc.last && !cdd.toc.tracks[cdd.toc.last - 1].end)
|
||||||
{
|
{
|
||||||
/* set previous track end time */
|
/* set previous track end time (current file absolute time + PREGAP length) */
|
||||||
cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75 + pregap;
|
cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75 + pregap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((sscanf(lptr, "INDEX 01 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
else if ((sscanf(lptr, "INDEX 01 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
||||||
(sscanf(lptr, "INDEX 1 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
(sscanf(lptr, "INDEX 1 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
||||||
{
|
{
|
||||||
/* adjust file read offset for current track with current file PREGAP length */
|
/* adjust current track file read offset with current file PREGAP length (only used for AUDIO track) */
|
||||||
cdd.toc.tracks[cdd.toc.last].offset += pregap * 2352;
|
cdd.toc.tracks[cdd.toc.last].offset += pregap * 2352;
|
||||||
|
|
||||||
/* check if a single file is used for all tracks */
|
/* check if a single file is used for consecutive tracks */
|
||||||
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
if (!cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
{
|
{
|
||||||
/* use common file descriptor */
|
/* use common file descriptor */
|
||||||
cdd.toc.tracks[cdd.toc.last].fd = cdd.toc.tracks[0].fd;
|
cdd.toc.tracks[cdd.toc.last].fd = cdd.toc.tracks[0].fd;
|
||||||
|
|
||||||
/* current track start time (based on current absolute time) */
|
/* current track start time (based on current file absolute time + PREGAP length) */
|
||||||
cdd.toc.tracks[cdd.toc.last].start = bb + ss*75 + mm*60*75 + pregap;
|
cdd.toc.tracks[cdd.toc.last].start = bb + ss*75 + mm*60*75 + pregap;
|
||||||
|
|
||||||
/* check if previous track end time has not been already set (through INDEX00 command) */
|
/* check if previous track end time needs to be set */
|
||||||
if (cdd.toc.tracks[cdd.toc.last - 1].end == 0)
|
if (cdd.toc.last && !cdd.toc.tracks[cdd.toc.last - 1].end)
|
||||||
{
|
{
|
||||||
/* set previous track end time (based on current absolute timee) */
|
/* set previous track end time (based on current track start time, ignoring any "PREGAP"-type pause if no INDEX00) */
|
||||||
cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75;
|
cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.tracks[cdd.toc.last].start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* current track start time (based on previous track end time) */
|
/* current track start time (based on previous track end time + current file absolute time + PREGAP length) */
|
||||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + bb + ss*75 + mm*60*75 + pregap;
|
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end + bb + ss*75 + mm*60*75 + pregap;
|
||||||
|
|
||||||
/* adjust file read offset with previous track end time */
|
/* adjust current track file read offset with previous track end time (only used for AUDIO track) */
|
||||||
cdd.toc.tracks[cdd.toc.last].offset += cdd.toc.end * 2352;
|
cdd.toc.tracks[cdd.toc.last].offset += cdd.toc.end * 2352;
|
||||||
|
|
||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
@ -605,7 +611,16 @@ int cdd_load(char *filename, char *header)
|
|||||||
{
|
{
|
||||||
/* current track end time */
|
/* current track end time */
|
||||||
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END);
|
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END);
|
||||||
|
if (cdd.toc.tracks[cdd.toc.last].type)
|
||||||
|
{
|
||||||
|
/* DATA track length */
|
||||||
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(cdd.toc.tracks[cdd.toc.last].fd) + cdd.sectorSize - 1) / cdd.sectorSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* AUDIO track length */
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352);
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352);
|
||||||
|
}
|
||||||
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,36 +630,50 @@ int cdd_load(char *filename, char *header)
|
|||||||
|
|
||||||
/* increment track number */
|
/* increment track number */
|
||||||
cdd.toc.last++;
|
cdd.toc.last++;
|
||||||
|
|
||||||
|
/* max. 99 tracks */
|
||||||
|
if (cdd.toc.last == 99) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if a single file is used for all tracks */
|
/* check if last track end time needs to be set */
|
||||||
if (cdd.toc.tracks[cdd.toc.last - 1].fd == cdd.toc.tracks[0].fd)
|
if (cdd.toc.last && !cdd.toc.tracks[cdd.toc.last - 1].end)
|
||||||
{
|
{
|
||||||
/* adjust TOC end */
|
/* adjust TOC end with current file PREGAP length */
|
||||||
cdd.toc.end += pregap;
|
cdd.toc.end += pregap;
|
||||||
|
|
||||||
/* last track end index */
|
/* last track end time */
|
||||||
cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.end;
|
cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close .cue file */
|
/* close any incomplete track file */
|
||||||
fclose(fd);
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
|
if (cdd.toc.tracks[cdd.toc.last].vf.datasource)
|
||||||
|
{
|
||||||
|
ov_clear(&cdd.toc.tracks[cdd.toc.last].vf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (cdd.toc.tracks[cdd.toc.last].fd)
|
||||||
|
{
|
||||||
|
fclose(cdd.toc.tracks[cdd.toc.last].fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .ISO audio tracks auto-detection */
|
/* close CUE file */
|
||||||
else if (cdd.sectorSize == 2048)
|
fclose(fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int i, offset;
|
int i, offset = 1;
|
||||||
|
|
||||||
/* set pointer at the end of filename */
|
/* set pointer at the end of filename */
|
||||||
ptr = fname + strlen(fname) - 4;
|
ptr = fname + strlen(fname) - 4;
|
||||||
|
|
||||||
/* auto-detect track file extensions */
|
/* autodetect audio track file extensions */
|
||||||
for (i=0; i<SUPPORTED_EXT; i++)
|
for (i=0; i<SUPPORTED_EXT; i++)
|
||||||
{
|
{
|
||||||
/* auto-detect bad rips with wrong track indexes */
|
/* auto-detect wrong initial track index */
|
||||||
sprintf(ptr, extensions[i], 1);
|
sprintf(ptr, extensions[i], cdd.toc.last);
|
||||||
fd = fopen(fname, "rb");
|
fd = fopen(fname, "rb");
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
@ -652,13 +681,9 @@ int cdd_load(char *filename, char *header)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(ptr, extensions[i], 2);
|
sprintf(ptr, extensions[i], cdd.toc.last + 1);
|
||||||
fd = fopen(fname, "rb");
|
fd = fopen(fname, "rb");
|
||||||
if (fd)
|
if (fd) break;
|
||||||
{
|
|
||||||
offset = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* repeat until no more valid track files can be found */
|
/* repeat until no more valid track files can be found */
|
||||||
@ -670,7 +695,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
fread(head, 32, 1, fd);
|
fread(head, 32, 1, fd);
|
||||||
fseek(fd, 0, SEEK_SET);
|
fseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* check if this is a valid WAVE file (16-bit stereo @44.1kHz only) */
|
/* check if this is a valid WAVE file (44.1KHz 16-bit stereo format only) */
|
||||||
if (!memcmp(head, waveHeader, 32))
|
if (!memcmp(head, waveHeader, 32))
|
||||||
{
|
{
|
||||||
/* initialize current track file descriptor */
|
/* initialize current track file descriptor */
|
||||||
@ -684,7 +709,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
|
|
||||||
/* current track end time */
|
/* current track end time */
|
||||||
fseek(fd, 0, SEEK_END);
|
fseek(fd, 0, SEEK_END);
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(fd) + 2351) / 2352);
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(fd) - 44 + 2351) / 2352);
|
||||||
|
|
||||||
/* initialize file read offset for current track */
|
/* initialize file read offset for current track */
|
||||||
cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].start * 2352;
|
cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].start * 2352;
|
||||||
@ -731,7 +756,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
cdd.toc.tracks[cdd.toc.last].start += 150;
|
cdd.toc.tracks[cdd.toc.last].start += 150;
|
||||||
|
|
||||||
/* current track end time */
|
/* current track end time */
|
||||||
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ov_pcm_total(&cdd.toc.tracks[cdd.toc.last].vf,-1)/588;
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ov_pcm_total(&cdd.toc.tracks[cdd.toc.last].vf,-1) + 587) / 588);
|
||||||
if (cdd.toc.tracks[cdd.toc.last].end <= cdd.toc.tracks[cdd.toc.last].start)
|
if (cdd.toc.tracks[cdd.toc.last].end <= cdd.toc.tracks[cdd.toc.last].start)
|
||||||
{
|
{
|
||||||
/* invalid file length */
|
/* invalid file length */
|
||||||
@ -742,6 +767,9 @@ int cdd_load(char *filename, char *header)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize file read offset for current track */
|
||||||
|
cdd.toc.tracks[cdd.toc.last].offset = cdd.toc.tracks[cdd.toc.last].start * 588;
|
||||||
|
|
||||||
/* auto-detect PAUSE within audio files */
|
/* auto-detect PAUSE within audio files */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.toc.last].vf, 100 * 588);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.toc.last].vf, 100 * 588);
|
||||||
#if defined(USE_LIBVORBIS)
|
#if defined(USE_LIBVORBIS)
|
||||||
@ -776,16 +804,31 @@ int cdd_load(char *filename, char *header)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* max. 99 tracks */
|
||||||
|
if (cdd.toc.last == 99) break;
|
||||||
|
|
||||||
/* try to open next audio track file */
|
/* try to open next audio track file */
|
||||||
sprintf(ptr, extensions[i], cdd.toc.last + offset);
|
sprintf(ptr, extensions[i], cdd.toc.last + offset);
|
||||||
fd = fopen(fname, "rb");
|
fd = fopen(fname, "rb");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simulate audio tracks if none found */
|
/* CD tracks found ? */
|
||||||
|
if (cdd.toc.last)
|
||||||
|
{
|
||||||
|
/* Lead-out */
|
||||||
|
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||||
|
|
||||||
|
/* CD mounted */
|
||||||
|
cdd.loaded = 1;
|
||||||
|
|
||||||
|
/* Valid DATA track found ? */
|
||||||
|
if (cdd.toc.tracks[0].type)
|
||||||
|
{
|
||||||
|
/* simulate audio tracks if none found */
|
||||||
if (cdd.toc.last == 1)
|
if (cdd.toc.last == 1)
|
||||||
{
|
{
|
||||||
/* Some games require exact TOC infos */
|
/* some games require exact TOC infos */
|
||||||
if (strstr(header + 0x180,"T-95035") != NULL)
|
if (strstr(header + 0x180,"T-95035") != NULL)
|
||||||
{
|
{
|
||||||
/* Snatcher */
|
/* Snatcher */
|
||||||
@ -877,13 +920,18 @@ int cdd_load(char *filename, char *header)
|
|||||||
while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75));
|
while ((cdd.toc.last < 99) && (cdd.toc.end < 56*60*75));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lead-out */
|
/* Automatically try to open associated subcode data file */
|
||||||
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
strncpy(&fname[strlen(fname) - 4], ".sub", 4);
|
||||||
|
cdd.toc.sub = fopen(fname, "rb");
|
||||||
|
|
||||||
/* CD loaded */
|
/* return 1 if loaded file is CD image file */
|
||||||
cdd.loaded = 1;
|
return (isCDfile);
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
/* no CD image file loaded */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdd_unload(void)
|
void cdd_unload(void)
|
||||||
@ -898,24 +946,29 @@ void cdd_unload(void)
|
|||||||
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
#if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS)
|
||||||
if (cdd.toc.tracks[i].vf.datasource)
|
if (cdd.toc.tracks[i].vf.datasource)
|
||||||
{
|
{
|
||||||
/* close VORBIS file (if still opened) */
|
/* close any opened VORBIS file */
|
||||||
ov_clear(&cdd.toc.tracks[i].vf);
|
ov_clear(&cdd.toc.tracks[i].vf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (cdd.toc.tracks[i].fd)
|
if (cdd.toc.tracks[i].fd)
|
||||||
|
{
|
||||||
|
/* check if single file is used for consecutive tracks */
|
||||||
|
if ((i > 0) && (cdd.toc.tracks[i].fd == cdd.toc.tracks[i-1].fd))
|
||||||
|
{
|
||||||
|
/* skip track */
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* close file */
|
/* close file */
|
||||||
fclose(cdd.toc.tracks[i].fd);
|
fclose(cdd.toc.tracks[i].fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* detect single file images */
|
/* close any opened subcode file */
|
||||||
if (cdd.toc.tracks[i+1].fd == cdd.toc.tracks[i].fd)
|
if (cdd.toc.sub) fclose(cdd.toc.sub);
|
||||||
{
|
|
||||||
/* exit loop */
|
|
||||||
i = cdd.toc.last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CD unloaded */
|
/* CD unloaded */
|
||||||
cdd.loaded = 0;
|
cdd.loaded = 0;
|
||||||
@ -924,19 +977,24 @@ void cdd_unload(void)
|
|||||||
/* reset TOC */
|
/* reset TOC */
|
||||||
memset(&cdd.toc, 0x00, sizeof(cdd.toc));
|
memset(&cdd.toc, 0x00, sizeof(cdd.toc));
|
||||||
|
|
||||||
/* unknown CD image file format */
|
/* no CD-ROM track */
|
||||||
cdd.sectorSize = 0;
|
cdd.sectorSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdd_read_data(uint8 *dst)
|
void cdd_read_data(uint8 *dst)
|
||||||
{
|
{
|
||||||
/* only read DATA track sectors */
|
/* only allow reading (first) CD-ROM track sectors */
|
||||||
if ((cdd.lba >= 0) && (cdd.lba < cdd.toc.tracks[0].end))
|
if (cdd.toc.tracks[cdd.index].type && (cdd.lba >= 0))
|
||||||
{
|
{
|
||||||
/* BIN format ? */
|
/* seek current track sector */
|
||||||
if (cdd.sectorSize == 2352)
|
if (cdd.sectorSize == 2048)
|
||||||
{
|
{
|
||||||
/* skip 16-byte header */
|
/* Mode 1 COOKED data (ISO) */
|
||||||
|
fseek(cdd.toc.tracks[0].fd, cdd.lba * 2048, SEEK_SET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Mode 1 RAW data (skip 16-byte header) */
|
||||||
fseek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET);
|
fseek(cdd.toc.tracks[0].fd, cdd.lba * 2352 + 16, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,6 +1164,48 @@ void cdd_read_audio(unsigned int samples)
|
|||||||
blip_end_frame(snd.blips[2][1], samples);
|
blip_end_frame(snd.blips[2][1], samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cdd_read_subcode(void)
|
||||||
|
{
|
||||||
|
uint8 subc[96];
|
||||||
|
int i,j,index;
|
||||||
|
|
||||||
|
/* update subcode buffer pointer address */
|
||||||
|
scd.regs[0x68>>1].byte.l = (scd.regs[0x68>>1].byte.l + 98) & 0x7e;
|
||||||
|
|
||||||
|
/* 16-bit register index */
|
||||||
|
index = (scd.regs[0x68>>1].byte.l + 0x100) >> 1;
|
||||||
|
|
||||||
|
/* read interleaved subcode data from .sub file (12 x 8-bit of P subchannel first, then Q subchannel, etc) */
|
||||||
|
fread(subc, 1, 96, cdd.toc.sub);
|
||||||
|
|
||||||
|
/* convert back to raw subcode format (96 bytes with 8 x P-W subchannel bits per byte) */
|
||||||
|
for (i=0; i<96; i+=2)
|
||||||
|
{
|
||||||
|
int code = 0;
|
||||||
|
for (j=0; j<8; j++)
|
||||||
|
{
|
||||||
|
int bits = (subc[(j*12)+(i/8)] >> (6 - (i & 6))) & 3;
|
||||||
|
code |= ((bits & 1) << (7 - j));
|
||||||
|
code |= ((bits >> 1) << (15 - j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subcode buffer is accessed as 16-bit words */
|
||||||
|
scd.regs[index].w = code;
|
||||||
|
|
||||||
|
/* subcode buffer is limited to 64 x 16-bit words */
|
||||||
|
index = (index + 1) & 0xbf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* level 6 interrupt enabled ? */
|
||||||
|
if (scd.regs[0x32>>1].byte.l & 0x40)
|
||||||
|
{
|
||||||
|
/* trigger level 6 interrupt */
|
||||||
|
scd.pending |= (1 << 6);
|
||||||
|
|
||||||
|
/* update IRQ level */
|
||||||
|
s68k_update_irq((scd.pending & scd.regs[0x32>>1].byte.l) >> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cdd_update(void)
|
void cdd_update(void)
|
||||||
{
|
{
|
||||||
@ -1137,10 +1237,23 @@ void cdd_update(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* track type */
|
/* end of disc detection */
|
||||||
if (!cdd.index)
|
if (cdd.index >= cdd.toc.last)
|
||||||
{
|
{
|
||||||
/* DATA sector header (CD-ROM Mode 1) */
|
cdd.status = CD_END;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* subcode data processing */
|
||||||
|
if (cdd.toc.sub)
|
||||||
|
{
|
||||||
|
cdd_read_subcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* track type */
|
||||||
|
if (cdd.toc.tracks[cdd.index].type)
|
||||||
|
{
|
||||||
|
/* CD-ROM (Mode 1) 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];
|
||||||
@ -1148,10 +1261,10 @@ void cdd_update(void)
|
|||||||
header[2] = lut_BCD_8[(msf % 75)];
|
header[2] = lut_BCD_8[(msf % 75)];
|
||||||
header[3] = 0x01;
|
header[3] = 0x01;
|
||||||
|
|
||||||
/* data track sector read is controlled by CDC */
|
/* decode CD-ROM track sector */
|
||||||
cdd.lba += cdc_decoder_update(*(uint32 *)(header));
|
cdc_decoder_update(*(uint32 *)(header));
|
||||||
}
|
}
|
||||||
else if (cdd.index < cdd.toc.last)
|
else
|
||||||
{
|
{
|
||||||
/* check against audio track start index */
|
/* check against audio track start index */
|
||||||
if (cdd.lba >= cdd.toc.tracks[cdd.index].start)
|
if (cdd.lba >= cdd.toc.tracks[cdd.index].start)
|
||||||
@ -1162,16 +1275,10 @@ void cdd_update(void)
|
|||||||
|
|
||||||
/* audio blocks are still sent to CDC as well as CD DAC/Fader */
|
/* audio blocks are still sent to CDC as well as CD DAC/Fader */
|
||||||
cdc_decoder_update(0);
|
cdc_decoder_update(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* next audio block is automatically read */
|
/* read next sector */
|
||||||
cdd.lba++;
|
cdd.lba++;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* end of disc */
|
|
||||||
cdd.status = CD_END;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check end of current track */
|
/* check end of current track */
|
||||||
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
|
if (cdd.lba >= cdd.toc.tracks[cdd.index].end)
|
||||||
@ -1199,7 +1306,7 @@ void cdd_update(void)
|
|||||||
/* VORBIS file need to be opened first */
|
/* VORBIS file need to be opened first */
|
||||||
ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
|
ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
|
||||||
#endif
|
#endif
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, -cdd.toc.tracks[cdd.index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.toc.tracks[cdd.index].start * 588) - cdd.toc.tracks[cdd.index].offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -1228,16 +1335,25 @@ void cdd_update(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* next track */
|
/* next track */
|
||||||
cdd.index++;
|
cdd.index++;
|
||||||
|
|
||||||
/* skip directly to track start position */
|
/* check disc limits */
|
||||||
cdd.lba = cdd.toc.tracks[cdd.index].start;
|
if (cdd.index < cdd.toc.last)
|
||||||
|
|
||||||
/* AUDIO track playing ? */
|
|
||||||
if (cdd.status == CD_PLAY)
|
|
||||||
{
|
{
|
||||||
scd.regs[0x36>>1].byte.h = 0x00;
|
/* skip directly to next track start position */
|
||||||
|
cdd.lba = cdd.toc.tracks[cdd.index].start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* end of disc */
|
||||||
|
cdd.lba = cdd.toc.end;
|
||||||
|
cdd.status = CD_END;
|
||||||
|
|
||||||
|
/* no AUDIO track playing */
|
||||||
|
scd.regs[0x36>>1].byte.h = 0x01;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cdd.lba < cdd.toc.tracks[cdd.index].start)
|
else if (cdd.lba < cdd.toc.tracks[cdd.index].start)
|
||||||
@ -1252,37 +1368,34 @@ void cdd_update(void)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* check disc limits */
|
||||||
|
if (cdd.index > 0)
|
||||||
|
{
|
||||||
/* previous track */
|
/* previous track */
|
||||||
cdd.index--;
|
cdd.index--;
|
||||||
|
|
||||||
/* skip directly to track end position */
|
/* skip directly to previous track end position */
|
||||||
cdd.lba = cdd.toc.tracks[cdd.index].end;
|
cdd.lba = cdd.toc.tracks[cdd.index].end;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* check disc limits */
|
|
||||||
if (cdd.index < 0)
|
|
||||||
{
|
{
|
||||||
cdd.index = 0;
|
/* start of first track */
|
||||||
cdd.lba = 0;
|
cdd.lba = 0;
|
||||||
}
|
}
|
||||||
else if (cdd.index >= cdd.toc.last)
|
|
||||||
{
|
|
||||||
/* no AUDIO track playing */
|
|
||||||
scd.regs[0x36>>1].byte.h = 0x01;
|
|
||||||
|
|
||||||
/* end of disc */
|
|
||||||
cdd.index = cdd.toc.last;
|
|
||||||
cdd.lba = cdd.toc.end;
|
|
||||||
cdd.status = CD_END;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current block */
|
/* AUDIO track playing ? */
|
||||||
if (!cdd.index)
|
scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type;
|
||||||
{
|
|
||||||
/* no AUDIO track playing */
|
|
||||||
scd.regs[0x36>>1].byte.h = 0x01;
|
|
||||||
|
|
||||||
|
/* seek to current subcode position */
|
||||||
|
if (cdd.toc.sub)
|
||||||
|
{
|
||||||
|
fseek(cdd.toc.sub, cdd.lba * 96, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seek to current track position */
|
||||||
|
if (cdd.toc.tracks[cdd.index].type)
|
||||||
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
fseek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET);
|
fseek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET);
|
||||||
}
|
}
|
||||||
@ -1298,7 +1411,7 @@ void cdd_update(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (cdd.lba * 588) - cdd.toc.tracks[cdd.index].offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cdd.toc.tracks[cdd.index].fd)
|
else if (cdd.toc.tracks[cdd.index].fd)
|
||||||
@ -1363,7 +1476,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.index ? 0x00 : 0x04; /* 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 << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,7 +1487,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.index ? 0x00 : 0x04; /* 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 << 2; /* Current block flags in RS8 (bit0 = mute status, bit1: pre-emphasis status, bit2: track type) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,12 +1530,8 @@ 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[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */
|
scd.regs[0x40>>1].byte.h = track % 10; /* Track Number (low digit) */
|
||||||
if (track == 1)
|
|
||||||
{
|
|
||||||
/* RS6 bit 3 is set for the first (DATA) track */
|
|
||||||
scd.regs[0x3e>>1].byte.h |= 0x08;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1452,10 +1561,9 @@ void cdd_process(void)
|
|||||||
{
|
{
|
||||||
/* Fixes a few games hanging during intro because they expect data to be read with some delay */
|
/* Fixes a few games hanging during intro because they expect data to be read with some delay */
|
||||||
/* Radical Rex needs at least one interrupt delay */
|
/* Radical Rex needs at least one interrupt delay */
|
||||||
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */
|
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 7 interrupts delay */
|
||||||
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 6 is OK) */
|
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 7 is OK) */
|
||||||
/* Jeopardy & ESPN Sunday Night NFL are picky about this as well: 10 interrupts delay (+ seek time) seems OK */
|
cdd.latency = 7;
|
||||||
cdd.latency = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CD drive seek time */
|
/* CD drive seek time */
|
||||||
@ -1507,8 +1615,14 @@ void cdd_process(void)
|
|||||||
lba = cdd.toc.tracks[index].start;
|
lba = cdd.toc.tracks[index].start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current block */
|
/* seek to current subcode position */
|
||||||
if (!index)
|
if (cdd.toc.sub)
|
||||||
|
{
|
||||||
|
fseek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* seek to current track position */
|
||||||
|
if (cdd.toc.tracks[index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
@ -1517,7 +1631,7 @@ void cdd_process(void)
|
|||||||
else if (cdd.toc.tracks[index].vf.seekable)
|
else if (cdd.toc.tracks[index].vf.seekable)
|
||||||
{
|
{
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba * 588) - cdd.toc.tracks[index].offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cdd.toc.tracks[index].fd)
|
else if (cdd.toc.tracks[index].fd)
|
||||||
@ -1600,7 +1714,7 @@ void cdd_process(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* seek to current block */
|
/* seek to current block */
|
||||||
if (!index)
|
if (cdd.toc.tracks[index].type)
|
||||||
{
|
{
|
||||||
/* DATA track */
|
/* DATA track */
|
||||||
fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
|
||||||
@ -1609,7 +1723,7 @@ void cdd_process(void)
|
|||||||
else if (cdd.toc.tracks[index].vf.seekable)
|
else if (cdd.toc.tracks[index].vf.seekable)
|
||||||
{
|
{
|
||||||
/* VORBIS AUDIO track */
|
/* VORBIS AUDIO track */
|
||||||
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba - cdd.toc.tracks[index].start) * 588 - cdd.toc.tracks[index].offset);
|
ov_pcm_seek(&cdd.toc.tracks[index].vf, (lba * 588) - cdd.toc.tracks[index].offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cdd.toc.tracks[index].fd)
|
else if (cdd.toc.tracks[index].fd)
|
||||||
@ -1618,6 +1732,12 @@ void cdd_process(void)
|
|||||||
fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
fseek(cdd.toc.tracks[index].fd, (lba * 2352) - cdd.toc.tracks[index].offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* seek to current subcode position */
|
||||||
|
if (cdd.toc.sub)
|
||||||
|
{
|
||||||
|
fseek(cdd.toc.sub, lba * 96, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
/* no audio track playing */
|
/* no audio track playing */
|
||||||
scd.regs[0x36>>1].byte.h = 0x01;
|
scd.regs[0x36>>1].byte.h = 0x01;
|
||||||
|
|
||||||
|
@ -58,9 +58,6 @@
|
|||||||
#define CD_STOP 0x09
|
#define CD_STOP 0x09
|
||||||
#define CD_END 0x0C
|
#define CD_END 0x0C
|
||||||
|
|
||||||
/* CD blocks scanning speed */
|
|
||||||
#define CD_SCAN_SPEED 30
|
|
||||||
|
|
||||||
#define CD_MAX_TRACKS 100
|
#define CD_MAX_TRACKS 100
|
||||||
|
|
||||||
/* CD track */
|
/* CD track */
|
||||||
@ -73,6 +70,7 @@ typedef struct
|
|||||||
int offset;
|
int offset;
|
||||||
int start;
|
int start;
|
||||||
int end;
|
int end;
|
||||||
|
int type;
|
||||||
} track_t;
|
} track_t;
|
||||||
|
|
||||||
/* CD TOC */
|
/* CD TOC */
|
||||||
@ -81,6 +79,7 @@ typedef struct
|
|||||||
int end;
|
int end;
|
||||||
int last;
|
int last;
|
||||||
track_t tracks[CD_MAX_TRACKS];
|
track_t tracks[CD_MAX_TRACKS];
|
||||||
|
FILE *sub;
|
||||||
} toc_t;
|
} toc_t;
|
||||||
|
|
||||||
/* CDD hardware */
|
/* CDD hardware */
|
||||||
|
@ -475,8 +475,8 @@ static void s68k_poll_sync(unsigned int reg_mask)
|
|||||||
|
|
||||||
static unsigned int scd_read_byte(unsigned int address)
|
static unsigned int scd_read_byte(unsigned int address)
|
||||||
{
|
{
|
||||||
/* PCM area (8K) is mirrored into $FF0000-$FF7FFF */
|
/* PCM area (8K) mirrored into $xF0000-$xF7FFF */
|
||||||
if (address < 0xff8000)
|
if (!(address & 0x8000))
|
||||||
{
|
{
|
||||||
/* get /LDS only */
|
/* get /LDS only */
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
@ -491,36 +491,39 @@ static unsigned int scd_read_byte(unsigned int address)
|
|||||||
error("[%d][%d]read byte CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc);
|
error("[%d][%d]read byte CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* only A1-A8 are used for decoding */
|
||||||
|
address &= 0x1ff;
|
||||||
|
|
||||||
/* Memory Mode */
|
/* Memory Mode */
|
||||||
if (address == 0xff8003)
|
if (address == 0x03)
|
||||||
{
|
{
|
||||||
s68k_poll_detect(1<<0x03);
|
s68k_poll_detect(1<<0x03);
|
||||||
return scd.regs[0x03>>1].byte.l;
|
return scd.regs[0x03>>1].byte.l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MAIN-CPU communication flags */
|
/* MAIN-CPU communication flags */
|
||||||
if (address == 0xff800e)
|
if (address == 0x0e)
|
||||||
{
|
{
|
||||||
s68k_poll_detect(1<<0x0e);
|
s68k_poll_detect(1<<0x0e);
|
||||||
return scd.regs[0x0e>>1].byte.h;
|
return scd.regs[0x0e>>1].byte.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CDC transfer status */
|
/* CDC transfer status */
|
||||||
if (address == 0xff8004)
|
if (address == 0x04)
|
||||||
{
|
{
|
||||||
s68k_poll_detect(1<<0x04);
|
s68k_poll_detect(1<<0x04);
|
||||||
return scd.regs[0x04>>1].byte.h;
|
return scd.regs[0x04>>1].byte.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GFX operation status */
|
/* GFX operation status */
|
||||||
if (address == 0xff8058)
|
if (address == 0x58)
|
||||||
{
|
{
|
||||||
s68k_poll_detect(1<<0x08);
|
s68k_poll_detect(1<<0x08);
|
||||||
return scd.regs[0x58>>1].byte.h;
|
return scd.regs[0x58>>1].byte.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CDC register data (controlled by BIOS, byte access only ?) */
|
/* CDC register data (controlled by BIOS, byte access only ?) */
|
||||||
if (address == 0xff8007)
|
if (address == 0x07)
|
||||||
{
|
{
|
||||||
unsigned int data = cdc_reg_r();
|
unsigned int data = cdc_reg_r();
|
||||||
#ifdef LOG_CDC
|
#ifdef LOG_CDC
|
||||||
@ -530,21 +533,21 @@ static unsigned int scd_read_byte(unsigned int address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* LED status */
|
/* LED status */
|
||||||
if (address == 0xff8000)
|
if (address == 0x00)
|
||||||
{
|
{
|
||||||
/* register $00 is reserved for MAIN-CPU, we use $06 instead */
|
/* register $00 is reserved for MAIN-CPU, we use $06 instead */
|
||||||
return scd.regs[0x06>>1].byte.h;
|
return scd.regs[0x06>>1].byte.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RESET status */
|
/* RESET status */
|
||||||
if (address == 0xff8001)
|
if (address == 0x01)
|
||||||
{
|
{
|
||||||
/* always return 1 */
|
/* always return 1 */
|
||||||
return 0x01;
|
return 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Font data */
|
/* Font data */
|
||||||
if ((address >= 0xff8050) && (address <= 0xff8056))
|
if ((address >= 0x50) && (address <= 0x56))
|
||||||
{
|
{
|
||||||
/* shifted 4-bit input (xxxx00) */
|
/* shifted 4-bit input (xxxx00) */
|
||||||
uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2;
|
uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2;
|
||||||
@ -573,21 +576,28 @@ static unsigned int scd_read_byte(unsigned int address)
|
|||||||
s68k_poll_detect(1 << (address & 0x1f));
|
s68k_poll_detect(1 << (address & 0x1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subcode buffer */
|
||||||
|
else if (address & 0x100)
|
||||||
|
{
|
||||||
|
/* 64 x 16-bit mirrored */
|
||||||
|
address &= 0x17f;
|
||||||
|
}
|
||||||
|
|
||||||
/* default registers */
|
/* default registers */
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
{
|
{
|
||||||
/* register LSB */
|
/* register LSB */
|
||||||
return scd.regs[(address >> 1) & 0xff].byte.l;
|
return scd.regs[address >> 1].byte.l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register MSB */
|
/* register MSB */
|
||||||
return scd.regs[(address >> 1) & 0xff].byte.h;
|
return scd.regs[address >> 1].byte.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int scd_read_word(unsigned int address)
|
static unsigned int scd_read_word(unsigned int address)
|
||||||
{
|
{
|
||||||
/* PCM area (8K) is mirrored into $FF0000-$FF7FFF */
|
/* PCM area (8K) mirrored into $xF0000-$xF7FFF */
|
||||||
if (address < 0xff8000)
|
if (!(address & 0x8000))
|
||||||
{
|
{
|
||||||
/* get /LDS only */
|
/* get /LDS only */
|
||||||
return pcm_read((address >> 1) & 0x1fff);
|
return pcm_read((address >> 1) & 0x1fff);
|
||||||
@ -597,35 +607,38 @@ static unsigned int scd_read_word(unsigned int address)
|
|||||||
error("[%d][%d]read word CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc);
|
error("[%d][%d]read word CD register %X (%X)\n", v_counter, s68k.cycles, address, s68k.pc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* only A1-A8 are used for decoding */
|
||||||
|
address &= 0x1ff;
|
||||||
|
|
||||||
/* Memory Mode */
|
/* Memory Mode */
|
||||||
if (address == 0xff8002)
|
if (address == 0x02)
|
||||||
{
|
{
|
||||||
s68k_poll_detect(1<<0x03);
|
s68k_poll_detect(1<<0x03);
|
||||||
return scd.regs[0x03>>1].w;
|
return scd.regs[0x03>>1].w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CDC host data (word access only ?) */
|
/* CDC host data (word access only ?) */
|
||||||
if (address == 0xff8008)
|
if (address == 0x08)
|
||||||
{
|
{
|
||||||
return cdc_host_r();
|
return cdc_host_r();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LED & RESET status */
|
/* LED & RESET status */
|
||||||
if (address == 0xff8000)
|
if (address == 0x00)
|
||||||
{
|
{
|
||||||
/* register $00 is reserved for MAIN-CPU, we use $06 instead */
|
/* register $00 is reserved for MAIN-CPU, we use $06 instead */
|
||||||
return scd.regs[0x06>>1].w;
|
return scd.regs[0x06>>1].w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stopwatch counter (word access only ?) */
|
/* Stopwatch counter (word access only ?) */
|
||||||
if (address == 0xff800c)
|
if (address == 0x0c)
|
||||||
{
|
{
|
||||||
/* cycle-accurate counter value */
|
/* cycle-accurate counter value */
|
||||||
return (scd.regs[0x0c>>1].w + ((s68k.cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff;
|
return (scd.regs[0x0c>>1].w + ((s68k.cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Font data */
|
/* Font data */
|
||||||
if ((address >= 0xff8050) && (address <= 0xff8056))
|
if ((address >= 0x50) && (address <= 0x56))
|
||||||
{
|
{
|
||||||
/* shifted 4-bit input (xxxx00) */
|
/* shifted 4-bit input (xxxx00) */
|
||||||
uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2;
|
uint8 bits = (scd.regs[0x4e>>1].w >> (((address & 6) ^ 6) << 1)) << 2;
|
||||||
@ -663,8 +676,15 @@ static unsigned int scd_read_word(unsigned int address)
|
|||||||
s68k_poll_detect(3 << (address & 0x1e));
|
s68k_poll_detect(3 << (address & 0x1e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subcode buffer */
|
||||||
|
else if (address & 0x100)
|
||||||
|
{
|
||||||
|
/* 64 x 16-bit mirrored */
|
||||||
|
address &= 0x17f;
|
||||||
|
}
|
||||||
|
|
||||||
/* default registers */
|
/* default registers */
|
||||||
return scd.regs[(address >> 1) & 0xff].w;
|
return scd.regs[address >> 1].w;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void word_ram_switch(uint8 mode)
|
INLINE void word_ram_switch(uint8 mode)
|
||||||
@ -731,8 +751,8 @@ INLINE void word_ram_switch(uint8 mode)
|
|||||||
|
|
||||||
static void scd_write_byte(unsigned int address, unsigned int data)
|
static void scd_write_byte(unsigned int address, unsigned int data)
|
||||||
{
|
{
|
||||||
/* PCM area (8K) is mirrored into $FF0000-$FF7FFF */
|
/* PCM area (8K) mirrored into $xF0000-$xF7FFF */
|
||||||
if (address < 0xff8000)
|
if (!(address & 0x8000))
|
||||||
{
|
{
|
||||||
/* get /LDS only */
|
/* get /LDS only */
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
@ -1012,8 +1032,8 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
|||||||
|
|
||||||
static void scd_write_word(unsigned int address, unsigned int data)
|
static void scd_write_word(unsigned int address, unsigned int data)
|
||||||
{
|
{
|
||||||
/* PCM area (8K) is mirrored into $FF0000-$FF7FFF */
|
/* PCM area (8K) mirrored into $xF0000-$xF7FFF */
|
||||||
if (address < 0xff8000)
|
if (!(address & 0x8000))
|
||||||
{
|
{
|
||||||
/* get /LDS only */
|
/* get /LDS only */
|
||||||
pcm_write((address >> 1) & 0x1fff, data);
|
pcm_write((address >> 1) & 0x1fff, data);
|
||||||
|
145
core/loadrom.c
145
core/loadrom.c
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* ROM Loading Support
|
* ROM Loading Support
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2015 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2015 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
@ -389,11 +389,11 @@ void getrominfo(char *romheader)
|
|||||||
* Return loaded size (-1 if already loaded)
|
* Return loaded size (-1 if already loaded)
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int load_bios(void)
|
int load_bios(int system)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
switch (system_hw)
|
switch (system)
|
||||||
{
|
{
|
||||||
case SYSTEM_MCD:
|
case SYSTEM_MCD:
|
||||||
{
|
{
|
||||||
@ -532,10 +532,11 @@ int load_rom(char *filename)
|
|||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
#ifdef USE_DYNAMIC_ALLOC
|
#ifdef USE_DYNAMIC_ALLOC
|
||||||
/* allocate memory for Cartridge /CD hardware buffer if required */
|
if (!ext)
|
||||||
if (ext == NULL)
|
|
||||||
{
|
{
|
||||||
|
/* allocate memory for Cartridge / CD hardware if required */
|
||||||
ext = (external_t *)malloc(sizeof(external_t));
|
ext = (external_t *)malloc(sizeof(external_t));
|
||||||
|
if (!ext) return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -550,30 +551,28 @@ int load_rom(char *filename)
|
|||||||
cdd.loaded = 0;
|
cdd.loaded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* auto-detect CD image files */
|
/* auto-detect CD image file */
|
||||||
size = cdd_load(filename, (char *)(cart.rom));
|
size = cdd_load(filename, (char *)(cart.rom));
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
{
|
{
|
||||||
/* error opening file */
|
/* error opening file */
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0)
|
/* CD image file ? */
|
||||||
|
if (size)
|
||||||
{
|
{
|
||||||
/* CD image file loaded */
|
/* enable CD hardware */
|
||||||
system_hw = SYSTEM_MCD;
|
system_hw = SYSTEM_MCD;
|
||||||
|
|
||||||
|
/* boot from CD hardware */
|
||||||
|
scd.cartridge.boot = 0x00;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* load file into ROM buffer */
|
/* load file into ROM buffer */
|
||||||
char extension[4];
|
char extension[4];
|
||||||
size = load_archive(filename, cart.rom, sizeof(cart.rom), extension);
|
size = load_archive(filename, cart.rom, cdd.loaded ? 0x800000 : MAXROMSIZE, extension);
|
||||||
if (!size)
|
|
||||||
{
|
|
||||||
/* mark all BOOTROM as unloaded since they could have been overwritten */
|
|
||||||
system_bios &= ~(0x10 | SYSTEM_SMS | SYSTEM_GG);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mark BOOTROM as unloaded if they have been overwritten by cartridge ROM */
|
/* mark BOOTROM as unloaded if they have been overwritten by cartridge ROM */
|
||||||
if (size > 0x800000)
|
if (size > 0x800000)
|
||||||
@ -586,8 +585,16 @@ int load_rom(char *filename)
|
|||||||
/* Master System or Game Gear BIOS ROM are loaded within $400000-$4FFFFF area */
|
/* Master System or Game Gear BIOS ROM are loaded within $400000-$4FFFFF area */
|
||||||
system_bios &= ~(SYSTEM_SMS | SYSTEM_GG);
|
system_bios &= ~(SYSTEM_SMS | SYSTEM_GG);
|
||||||
}
|
}
|
||||||
|
else if (size <= 0)
|
||||||
|
{
|
||||||
|
/* mark all BOOTROM as unloaded since they could have been overwritten */
|
||||||
|
system_bios &= ~(0x10 | SYSTEM_SMS | SYSTEM_GG);
|
||||||
|
|
||||||
/* convert lower case to upper case */
|
/* error loading file */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert lower case file extension to upper case */
|
||||||
*(uint32 *)(extension) &= 0xdfdfdfdf;
|
*(uint32 *)(extension) &= 0xdfdfdfdf;
|
||||||
|
|
||||||
/* auto-detect system hardware from ROM file extension */
|
/* auto-detect system hardware from ROM file extension */
|
||||||
@ -608,7 +615,7 @@ int load_rom(char *filename)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Mega Drive hardware (Genesis mode) */
|
/* default is Mega Drive / Genesis hardware (16-bit mode) */
|
||||||
system_hw = SYSTEM_MD;
|
system_hw = SYSTEM_MD;
|
||||||
|
|
||||||
/* decode .MDX format */
|
/* decode .MDX format */
|
||||||
@ -641,7 +648,7 @@ int load_rom(char *filename)
|
|||||||
size -= 512;
|
size -= 512;
|
||||||
memcpy (cart.rom, cart.rom + 512, size);
|
memcpy (cart.rom, cart.rom + 512, size);
|
||||||
|
|
||||||
/* assume interleaved Genesis ROM format (.smd) */
|
/* assume interleaved Mega Drive / Genesis ROM format (.smd) */
|
||||||
if (system_hw == SYSTEM_MD)
|
if (system_hw == SYSTEM_MD)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (size / 0x4000); i++)
|
for (i = 0; i < (size / 0x4000); i++)
|
||||||
@ -661,26 +668,9 @@ int load_rom(char *filename)
|
|||||||
/* set console region */
|
/* set console region */
|
||||||
get_region((char *)(cart.rom));
|
get_region((char *)(cart.rom));
|
||||||
|
|
||||||
/* CD image file */
|
|
||||||
if (system_hw == SYSTEM_MCD)
|
|
||||||
{
|
|
||||||
/* load CD BOOT ROM */
|
|
||||||
if (!load_bios())
|
|
||||||
{
|
|
||||||
/* unmount CD image */
|
|
||||||
cdd_unload();
|
|
||||||
|
|
||||||
/* error loading CD BOOT ROM */
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* boot from CD */
|
|
||||||
scd.cartridge.boot = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LSB_FIRST
|
#ifdef LSB_FIRST
|
||||||
/* 16-bit ROM specific */
|
/* 16-bit ROM specific */
|
||||||
else if (system_hw == SYSTEM_MD)
|
if (system_hw == SYSTEM_MD)
|
||||||
{
|
{
|
||||||
/* Byteswap ROM to optimize 16-bit access */
|
/* Byteswap ROM to optimize 16-bit access */
|
||||||
for (i = 0; i < cart.romsize; i += 2)
|
for (i = 0; i < cart.romsize; i += 2)
|
||||||
@ -702,13 +692,27 @@ int load_rom(char *filename)
|
|||||||
/* Save auto-detected system hardware */
|
/* Save auto-detected system hardware */
|
||||||
romtype = system_hw;
|
romtype = system_hw;
|
||||||
|
|
||||||
|
/* CD image file */
|
||||||
|
if (system_hw == SYSTEM_MCD)
|
||||||
|
{
|
||||||
|
/* try to load CD BOOTROM for selected region */
|
||||||
|
if (!load_bios(SYSTEM_MCD))
|
||||||
|
{
|
||||||
|
/* unmount CD image */
|
||||||
|
cdd_unload();
|
||||||
|
|
||||||
|
/* error booting from CD */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* CD BOOTROM */
|
/* CD BOOTROM */
|
||||||
if (strstr(rominfo.ROMType, "BR") != NULL)
|
else if (strstr(rominfo.ROMType, "BR") != NULL)
|
||||||
{
|
{
|
||||||
/* enable CD hardware */
|
/* enable CD hardware */
|
||||||
system_hw = SYSTEM_MCD;
|
system_hw = SYSTEM_MCD;
|
||||||
|
|
||||||
/* boot from CD */
|
/* boot from CD hardware */
|
||||||
scd.cartridge.boot = 0x00;
|
scd.cartridge.boot = 0x00;
|
||||||
|
|
||||||
/* copy ROM to BOOTROM area */
|
/* copy ROM to BOOTROM area */
|
||||||
@ -721,7 +725,26 @@ int load_rom(char *filename)
|
|||||||
system_bios = (system_bios & 0xf0) | (region_code >> 4);
|
system_bios = (system_bios & 0xf0) | (region_code >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ROM cartridges with CD support */
|
/* ROM cartridge with CD loaded */
|
||||||
|
else if (cdd.loaded)
|
||||||
|
{
|
||||||
|
/* try to load CD BOOTROM */
|
||||||
|
if (load_bios(SYSTEM_MCD))
|
||||||
|
{
|
||||||
|
/* enable CD hardware */
|
||||||
|
system_hw = SYSTEM_MCD;
|
||||||
|
|
||||||
|
/* boot from cartridge */
|
||||||
|
scd.cartridge.boot = 0x40;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unmount CD image */
|
||||||
|
cdd_unload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ROM cartridge with CD support */
|
||||||
else if ((strstr(rominfo.domestic,"FLUX") != NULL) ||
|
else if ((strstr(rominfo.domestic,"FLUX") != NULL) ||
|
||||||
(strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) ||
|
(strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) ||
|
||||||
(strstr(rominfo.product,"T-5740") != NULL))
|
(strstr(rominfo.product,"T-5740") != NULL))
|
||||||
@ -729,33 +752,23 @@ int load_rom(char *filename)
|
|||||||
/* check if console hardware is set to AUTO */
|
/* check if console hardware is set to AUTO */
|
||||||
if (!config.system)
|
if (!config.system)
|
||||||
{
|
{
|
||||||
/* auto-enable CD hardware */
|
|
||||||
system_hw = SYSTEM_MCD;
|
|
||||||
|
|
||||||
/* try to load CD BOOTROM */
|
/* try to load CD BOOTROM */
|
||||||
if (load_bios())
|
if (load_bios(SYSTEM_MCD))
|
||||||
{
|
{
|
||||||
char fname[256];
|
char fname[256];
|
||||||
int len = strlen(filename);
|
int len = strlen(filename);
|
||||||
|
|
||||||
|
/* automatically try to load associated .iso file */
|
||||||
|
while ((len && (filename[len] != '.')) || (len > 251)) len--;
|
||||||
|
strncpy(fname, filename, len);
|
||||||
|
strcpy(&fname[len], ".iso");
|
||||||
|
cdd_load(fname, (char *)cdc.ram);
|
||||||
|
|
||||||
|
/* enable CD hardware */
|
||||||
|
system_hw = SYSTEM_MCD;
|
||||||
|
|
||||||
/* boot from cartridge */
|
/* boot from cartridge */
|
||||||
scd.cartridge.boot = 0x40;
|
scd.cartridge.boot = 0x40;
|
||||||
|
|
||||||
/* change ROM filename extension to .iso */
|
|
||||||
while (len && (filename[len-1] != '.')) len--;
|
|
||||||
if (len < 253)
|
|
||||||
{
|
|
||||||
strncpy(fname, filename, len);
|
|
||||||
strcpy(&fname[len], "iso");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* automatically load associated .iso image */
|
|
||||||
cdd_load(fname, (char *)cdc.ram);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* if not found, disable CD hardware */
|
|
||||||
system_hw = SYSTEM_MD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -980,19 +993,19 @@ void get_region(char *romheader)
|
|||||||
if (system_hw == SYSTEM_MCD)
|
if (system_hw == SYSTEM_MCD)
|
||||||
{
|
{
|
||||||
/* security code */
|
/* security code */
|
||||||
switch (romheader[0x20b])
|
switch ((unsigned char)romheader[0x20b])
|
||||||
{
|
{
|
||||||
case 0x7a:
|
|
||||||
region_code = REGION_USA;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x64:
|
case 0x64:
|
||||||
region_code = REGION_EUROPE;
|
region_code = REGION_EUROPE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case 0xa1:
|
||||||
region_code = REGION_JAPAN_NTSC;
|
region_code = REGION_JAPAN_NTSC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
region_code = REGION_USA;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* ROM Loading Support
|
* ROM Loading Support
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998-2003 Charles Mac Donald (original code)
|
||||||
* Copyright (C) 2007-2015 Eke-Eke (Genesis Plus GX)
|
* Copyright (C) 2007-2015 Eke-Eke (Genesis Plus GX)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
@ -64,7 +64,7 @@ extern ROMINFO rominfo;
|
|||||||
extern uint8 romtype;
|
extern uint8 romtype;
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
extern int load_bios(void);
|
extern int load_bios(int system);
|
||||||
extern int load_rom(char *filename);
|
extern int load_rom(char *filename);
|
||||||
extern void get_region(char *romheader);
|
extern void get_region(char *romheader);
|
||||||
extern char *get_company(void);
|
extern char *get_company(void);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Genesis Plus GX configuration file support
|
* Genesis Plus GX configuration file support
|
||||||
*
|
*
|
||||||
* Copyright Eke-Eke (2007-2014)
|
* Copyright Eke-Eke (2007-2015)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
@ -259,7 +259,10 @@ void config_default(void)
|
|||||||
/* try to restore user config */
|
/* try to restore user config */
|
||||||
int loaded = config_load();
|
int loaded = config_load();
|
||||||
|
|
||||||
#ifndef HW_RVL
|
#ifdef HW_RVL
|
||||||
|
/* initialize WPAD timeout */
|
||||||
|
WPAD_SetIdleTimeout(config.autosleep ? 300 : 1800);
|
||||||
|
#else
|
||||||
/* check if component cable was detected */
|
/* check if component cable was detected */
|
||||||
if (VIDEO_HaveComponentCable())
|
if (VIDEO_HaveComponentCable())
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Genesis Plus GX configuration file support
|
* Genesis Plus GX configuration file support
|
||||||
*
|
*
|
||||||
* Copyright Eke-Eke (2007-2014)
|
* Copyright Eke-Eke (2007-2015)
|
||||||
*
|
*
|
||||||
* Redistribution and use of this code or any derivative works are permitted
|
* Redistribution and use of this code or any derivative works are permitted
|
||||||
* provided that the following conditions are met:
|
* provided that the following conditions are met:
|
||||||
|
@ -1128,7 +1128,6 @@ void gx_input_Init(void)
|
|||||||
PAD_Init();
|
PAD_Init();
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
WPAD_Init();
|
WPAD_Init();
|
||||||
WPAD_SetIdleTimeout(config.autosleep ? 300 : 1800);
|
|
||||||
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
|
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
|
||||||
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
|
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user