diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll index 8fa5e10..cce7ba9 100644 Binary files a/builds/genesis_plus_gx_libretro.dll and b/builds/genesis_plus_gx_libretro.dll differ diff --git a/builds/genplus_cube.dol b/builds/genplus_cube.dol index a109a3d..d9f0ee9 100644 Binary files a/builds/genplus_cube.dol and b/builds/genplus_cube.dol differ diff --git a/builds/genplus_wii.dol b/builds/genplus_wii.dol index 46be82d..978bb71 100644 Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ diff --git a/core/cart_hw/sms_cart.c b/core/cart_hw/sms_cart.c index 841396c..171566d 100644 --- a/core/cart_hw/sms_cart.c +++ b/core/cart_hw/sms_cart.c @@ -514,7 +514,7 @@ void sms_cart_init(void) if (config.bios & 1) { /* load BIOS file */ - int bios_size = load_bios(); + int bios_size = load_bios(system_hw); if (bios_size > 0xC000) { diff --git a/core/cd_hw/cdc.c b/core/cd_hw/cdc.c index 3425931..dd75a59 100644 --- a/core/cd_hw/cdc.c +++ b/core/cd_hw/cdc.c @@ -2,7 +2,7 @@ * Genesis Plus * 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 * 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 */ if (cdc.ifctrl & BIT_DOUTEN) { - /* set !DTBSY */ - cdc.ifstat &= ~BIT_DTBSY; + /* set !DTBSY and !DTEN */ + cdc.ifstat &= ~(BIT_DTBSY | BIT_DTEN); /* clear DBCH bits 4-7 */ cdc.dbc.byte.h &= 0x0f; @@ -391,10 +391,7 @@ void cdc_reg_w(unsigned char data) case 2: /* MAIN-CPU host read */ case 3: /* SUB-CPU host read */ { - /* set !DTEN */ - cdc.ifstat &= ~BIT_DTEN; - - /* set DSR bit (register $04) */ + /* set DSR bit (SCD register $04) */ scd.regs[0x04>>1].byte.h |= 0x40; break; } @@ -645,7 +642,7 @@ unsigned char cdc_reg_r(void) unsigned short cdc_host_r(void) { /* 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 */ uint16 data = *(uint16 *)(cdc.ram + (cdc.dac.w & 0x3ffe)); diff --git a/core/cd_hw/cdc.h b/core/cd_hw/cdc.h index 463a8f0..651f992 100644 --- a/core/cd_hw/cdc.h +++ b/core/cd_hw/cdc.h @@ -2,7 +2,7 @@ * Genesis Plus * 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 * provided that the following conditions are met: diff --git a/core/cd_hw/cdd.c b/core/cd_hw/cdd.c index f0cf714..47fc8fe 100644 --- a/core/cd_hw/cdd.c +++ b/core/cd_hw/cdd.c @@ -43,6 +43,12 @@ #define SUPPORTED_EXT 10 #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 */ static const uint8 lut_BCD_8[100] = { @@ -246,14 +252,18 @@ int cdd_context_load(uint8 *state) 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 */ - if (!cdd.index) + if (cdd.toc.tracks[cdd.index].type) { /* DATA track */ - if (cdd.toc.tracks[0].fd) - { - fseek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET); - } + fseek(cdd.toc.tracks[cdd.index].fd, lba * cdd.sectorSize, SEEK_SET); } #if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS) 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); #endif /* 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 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) { - char fname[256]; + char fname[256+10]; char line[128]; - char *ptr = 0; - char *lptr = 0; + char *ptr, *lptr; FILE *fd; + + /* assume CD image file by default */ + int isCDfile = 1; /* first unmount any loaded disc */ cdd_unload(); /* open file */ fd = fopen(filename, "rb"); + if (!fd) return (-1); /* save a copy of base filename */ strncpy(fname, filename, 256); - /* autodetect .cue file */ - if (!memcmp(".cue", &filename[strlen(filename) - 4], 4) || !memcmp(".CUE", &filename[strlen(filename) - 4], 4)) + /* check loaded file extension */ + if (memcmp(".cue", &filename[strlen(filename) - 4], 4) && memcmp(".CUE", &filename[strlen(filename) - 4], 4)) { - if (fd) - { - /* find first FILE command */ - while (!lptr) + int len; + + /* read first 16 bytes */ + fread(header, 0x10, 1, fd); + + /* look for valid CD image identifier */ + if (!memcmp("SEGADISCSYSTEM", header, 14)) + { + /* COOKED format (2048 bytes data blocks) */ + cdd.sectorSize = 2048; + } + else + { + /* read next 16 bytes */ + fread(header, 0x10, 1, fd); + + /* look for valid CD image identifier */ + if (!memcmp("SEGADISCSYSTEM", header, 14)) { - 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; + /* RAW format (2352 bytes data blocks) */ + cdd.sectorSize = 2352; } } - } - 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); + /* valid CD image file ? */ + if (cdd.sectorSize) + { + /* read CD image header + security code */ + fread(header + 0x10, 0x200, 1, fd); + + /* initialize first track file descriptor */ + 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) */ + 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; + + /* initialize TOC */ + cdd.toc.end = cdd.toc.tracks[0].end; + cdd.toc.last = 1; + } + else + { + /* this is not a CD image file */ + isCDfile = 0; + + /* 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"); } - if (!cdd.toc.tracks[0].fd) - { - /* close any opened .cue file */ - if (fd) fclose(fd); - - /* error opening file */ - return -1; - } - - /* read first 16 bytes */ - fread(header, 0x10, 1, cdd.toc.tracks[0].fd); - - /* look for valid CD image ID string */ - if (memcmp("SEGADISCSYSTEM", header, 14)) - { - /* if not found, read next 16 bytes */ - fread(header, 0x10, 1, cdd.toc.tracks[0].fd); - - /* 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 - { - /* ISO format (2048 bytes data blocks) */ - cdd.sectorSize = 2048; - } - - /* read CD image header + security code */ - fread(header + 0x10, 0x200, 1, cdd.toc.tracks[0].fd); - - /* DATA track start time (based on DATA file length) */ - fseek(cdd.toc.tracks[0].fd, 0, SEEK_END); - cdd.toc.tracks[0].end = ftell(cdd.toc.tracks[0].fd) / cdd.sectorSize; - - /* DATA track start time (logical block 0) */ - fseek(cdd.toc.tracks[0].fd, 0, SEEK_SET); - cdd.toc.tracks[0].start = 0; - - /* initialize TOC */ - cdd.toc.end = cdd.toc.tracks[0].end; - cdd.toc.last = 1; - - /* automatically retrieve audio tracks infos from .cue file */ + /* parse CUE file */ if (fd) { - int pregap = 0; - int mm, ss, bb; - - /* skip first (DATA) track */ - while (!strstr(line, "INDEX 01") && !strstr(line, "INDEX 1")) + int mm, ss, bb, pregap = 0; + + /* DATA track already loaded ? */ + if (cdd.toc.last) { - if (fgets(line, 128, fd) == NULL) + /* skip first track */ + while (fgets(line, 128, fd)) { - break; + if (strstr(line, "INDEX 01") && !strstr(line, "INDEX 1")) + break; } } - /* read next lines until end of file */ - while (fgets(line, 128, fd) != NULL) + /* read lines until end of file */ + while (fgets(line, 128, fd)) { /* skip any SPACE characters */ lptr = line; @@ -432,25 +398,34 @@ int cdd_load(char *filename, char *header) /* decode FILE commands */ if (!(memcmp(lptr, "FILE", 4))) { - /* skip "FILE" attribute */ - lptr += 4; - - /* skip DOUBLE QUOTE or SPACE characters */ - while ((*lptr == 0x20) || (*lptr == '\"')) lptr++; - - /* set pointer at the end of filepath */ + /* retrieve current path */ ptr = fname + strlen(fname) - 1; while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--; if (ptr - fname) ptr++; - /* append filename characters after filepath */ - while ((*lptr != '\"') && (lptr <= (line + 128)) && (ptr < (fname + 255))) + /* skip "FILE" attribute */ + lptr += 4; + + /* skip SPACE characters */ + while (*lptr == 0x20) lptr++; + + /* retrieve full filename */ + if (*lptr == '\"') { - *ptr++ = *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 = 0; - /* open file & initialize track file descriptor */ + /* open current track file descriptor */ cdd.toc.tracks[cdd.toc.last].fd = fopen(fname, "rb"); if (!cdd.toc.tracks[cdd.toc.last].fd) { @@ -461,11 +436,11 @@ int cdd_load(char *filename, char *header) /* reset current file PREGAP length */ pregap = 0; - /* reset current file read offset */ + /* reset current track file read offset */ cdd.toc.tracks[cdd.toc.last].offset = 0; - /* check supported file types */ - if (!strstr(lptr,"BINARY")) + /* check supported audio file types */ + if (!strstr(lptr,"BINARY") && !strstr(lptr,"MOTOROLA")) { /* read file header */ 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); 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)) { /* adjust current track file read offset with WAVE header length */ @@ -504,7 +479,7 @@ int cdd_load(char *filename, char *header) } /* 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 */ if (bb != (cdd.toc.last + 1)) @@ -520,11 +495,42 @@ int cdd_load(char *filename, char *header) break; } - /* check if a single file is used for all tracks */ - if (!cdd.toc.tracks[cdd.toc.last].fd) + /* autodetect DATA track (first track only) */ + if (!cdd.toc.last) { - /* clear previous track end time */ - cdd.toc.tracks[cdd.toc.last - 1].end = 0; + /* 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) + { + /* clear previous track end time */ + cdd.toc.tracks[cdd.toc.last - 1].end = 0; + } } } @@ -537,43 +543,43 @@ int cdd_load(char *filename, char *header) /* decode INDEX commands */ 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 */ - if (!cdd.toc.tracks[cdd.toc.last].fd) + /* check if previous track end time needs to be set */ + 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; } } 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; - /* 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) { /* use common file descriptor */ 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; - /* check if previous track end time has not been already set (through INDEX00 command) */ - if (cdd.toc.tracks[cdd.toc.last - 1].end == 0) + /* check if previous track end time needs to be set */ + if (cdd.toc.last && !cdd.toc.tracks[cdd.toc.last - 1].end) { - /* set previous track end time (based on current absolute timee) */ - cdd.toc.tracks[cdd.toc.last - 1].end = bb + ss*75 + mm*60*75; + /* 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 = cdd.toc.tracks[cdd.toc.last].start; } } 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; - /* 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; #if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS) @@ -599,52 +605,75 @@ int cdd_load(char *filename, char *header) /* close VORBIS file structure to save memory */ ogg_free(cdd.toc.last); #endif - } + } else #endif { /* current track end time */ fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_END); - cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + ((ftell(cdd.toc.tracks[cdd.toc.last].fd) + 2351) / 2352); + 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); + } fseek(cdd.toc.tracks[cdd.toc.last].fd, 0, SEEK_SET); } /* update TOC end */ cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end; } - + /* increment track number */ cdd.toc.last++; + + /* max. 99 tracks */ + if (cdd.toc.last == 99) break; } } - /* check if a single file is used for all tracks */ - if (cdd.toc.tracks[cdd.toc.last - 1].fd == cdd.toc.tracks[0].fd) + /* check if last track end time needs to be set */ + 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; - /* last track end index */ + /* last track end time */ cdd.toc.tracks[cdd.toc.last - 1].end = cdd.toc.end; } - /* close .cue file */ + /* close any incomplete track file */ +#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); + } + + /* close CUE file */ fclose(fd); } - - /* .ISO audio tracks auto-detection */ - else if (cdd.sectorSize == 2048) + else { - int i, offset; + int i, offset = 1; /* 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 0) && (cdd.toc.tracks[i].fd == cdd.toc.tracks[i-1].fd)) { - /* exit loop */ - i = cdd.toc.last; + /* skip track */ + i++; + } + else + { + /* close file */ + fclose(cdd.toc.tracks[i].fd); } } } + /* close any opened subcode file */ + if (cdd.toc.sub) fclose(cdd.toc.sub); + /* CD unloaded */ cdd.loaded = 0; } @@ -924,19 +977,24 @@ void cdd_unload(void) /* reset TOC */ memset(&cdd.toc, 0x00, sizeof(cdd.toc)); - /* unknown CD image file format */ + /* no CD-ROM track */ cdd.sectorSize = 0; } void cdd_read_data(uint8 *dst) { - /* only read DATA track sectors */ - if ((cdd.lba >= 0) && (cdd.lba < cdd.toc.tracks[0].end)) + /* only allow reading (first) CD-ROM track sectors */ + if (cdd.toc.tracks[cdd.index].type && (cdd.lba >= 0)) { - /* BIN format ? */ - if (cdd.sectorSize == 2352) + /* seek current track sector */ + 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); } @@ -1106,6 +1164,48 @@ void cdd_read_audio(unsigned int 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) { @@ -1137,10 +1237,23 @@ void cdd_update(void) return; } - /* track type */ - if (!cdd.index) + /* end of disc detection */ + 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]; uint32 msf = cdd.lba + 150; header[0] = lut_BCD_8[(msf / 75) / 60]; @@ -1148,10 +1261,10 @@ void cdd_update(void) header[2] = lut_BCD_8[(msf % 75)]; header[3] = 0x01; - /* data track sector read is controlled by CDC */ - cdd.lba += cdc_decoder_update(*(uint32 *)(header)); + /* decode CD-ROM track sector */ + cdc_decoder_update(*(uint32 *)(header)); } - else if (cdd.index < cdd.toc.last) + else { /* check against audio track start index */ if (cdd.lba >= cdd.toc.tracks[cdd.index].start) @@ -1162,17 +1275,11 @@ void cdd_update(void) /* audio blocks are still sent to CDC as well as CD DAC/Fader */ cdc_decoder_update(0); - - /* next audio block is automatically read */ - cdd.lba++; - } - else - { - /* end of disc */ - cdd.status = CD_END; - return; } + /* read next sector */ + cdd.lba++; + /* check end of current track */ if (cdd.lba >= cdd.toc.tracks[cdd.index].end) { @@ -1199,7 +1306,7 @@ void cdd_update(void) /* VORBIS file need to be opened first */ ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0); #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 #endif @@ -1228,16 +1335,25 @@ void cdd_update(void) } #endif #endif + /* next track */ cdd.index++; - /* skip directly to track start position */ - cdd.lba = cdd.toc.tracks[cdd.index].start; - - /* AUDIO track playing ? */ - if (cdd.status == CD_PLAY) + /* check disc limits */ + if (cdd.index < cdd.toc.last) { - 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) @@ -1252,37 +1368,34 @@ void cdd_update(void) #endif #endif - /* previous track */ - cdd.index--; + /* check disc limits */ + if (cdd.index > 0) + { + /* previous track */ + cdd.index--; - /* skip directly to track end position */ - cdd.lba = cdd.toc.tracks[cdd.index].end; + /* skip directly to previous track end position */ + cdd.lba = cdd.toc.tracks[cdd.index].end; + } + else + { + /* start of first track */ + cdd.lba = 0; + } } - /* check disc limits */ - if (cdd.index < 0) - { - cdd.index = 0; - cdd.lba = 0; - } - else if (cdd.index >= cdd.toc.last) - { - /* no AUDIO track playing */ - scd.regs[0x36>>1].byte.h = 0x01; + /* AUDIO track playing ? */ + scd.regs[0x36>>1].byte.h = cdd.toc.tracks[cdd.index].type; - /* end of disc */ - cdd.index = cdd.toc.last; - cdd.lba = cdd.toc.end; - cdd.status = CD_END; - return; + /* seek to current subcode position */ + if (cdd.toc.sub) + { + fseek(cdd.toc.sub, cdd.lba * 96, SEEK_SET); } - /* seek to current block */ - if (!cdd.index) + /* seek to current track position */ + if (cdd.toc.tracks[cdd.index].type) { - /* no AUDIO track playing */ - scd.regs[0x36>>1].byte.h = 0x01; - /* DATA track */ fseek(cdd.toc.tracks[0].fd, cdd.lba * cdd.sectorSize, SEEK_SET); } @@ -1298,7 +1411,7 @@ void cdd_update(void) } #endif /* 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 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[0x3c>>1].w = lut_BCD_16[(lba/75)%60]; 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; } @@ -1374,7 +1487,7 @@ void cdd_process(void) scd.regs[0x3a>>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[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; } @@ -1417,12 +1530,8 @@ void cdd_process(void) scd.regs[0x3a>>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].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) */ - if (track == 1) - { - /* RS6 bit 3 is set for the first (DATA) track */ - scd.regs[0x3e>>1].byte.h |= 0x08; - } 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 */ /* 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 */ - /* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay (incl. seek time, so 6 is OK) */ - /* Jeopardy & ESPN Sunday Night NFL are picky about this as well: 10 interrupts delay (+ seek time) seems OK */ - cdd.latency = 10; + /* 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 7 is OK) */ + cdd.latency = 7; } /* CD drive seek time */ @@ -1506,9 +1614,15 @@ void cdd_process(void) { lba = cdd.toc.tracks[index].start; } + + /* seek to current subcode position */ + if (cdd.toc.sub) + { + fseek(cdd.toc.sub, lba * 96, SEEK_SET); + } - /* seek to current block */ - if (!index) + /* seek to current track position */ + if (cdd.toc.tracks[index].type) { /* DATA track */ 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) { /* 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 else if (cdd.toc.tracks[index].fd) @@ -1600,7 +1714,7 @@ void cdd_process(void) } /* seek to current block */ - if (!index) + if (cdd.toc.tracks[index].type) { /* DATA track */ 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) { /* 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 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); } + /* seek to current subcode position */ + if (cdd.toc.sub) + { + fseek(cdd.toc.sub, lba * 96, SEEK_SET); + } + /* no audio track playing */ scd.regs[0x36>>1].byte.h = 0x01; diff --git a/core/cd_hw/cdd.h b/core/cd_hw/cdd.h index 77db95b..c02b75c 100644 --- a/core/cd_hw/cdd.h +++ b/core/cd_hw/cdd.h @@ -58,9 +58,6 @@ #define CD_STOP 0x09 #define CD_END 0x0C -/* CD blocks scanning speed */ -#define CD_SCAN_SPEED 30 - #define CD_MAX_TRACKS 100 /* CD track */ @@ -73,6 +70,7 @@ typedef struct int offset; int start; int end; + int type; } track_t; /* CD TOC */ @@ -81,6 +79,7 @@ typedef struct int end; int last; track_t tracks[CD_MAX_TRACKS]; + FILE *sub; } toc_t; /* CDD hardware */ diff --git a/core/cd_hw/scd.c b/core/cd_hw/scd.c index db07170..c2a1abd 100644 --- a/core/cd_hw/scd.c +++ b/core/cd_hw/scd.c @@ -475,8 +475,8 @@ static void s68k_poll_sync(unsigned int reg_mask) static unsigned int scd_read_byte(unsigned int address) { - /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ - if (address < 0xff8000) + /* PCM area (8K) mirrored into $xF0000-$xF7FFF */ + if (!(address & 0x8000)) { /* get /LDS only */ 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); #endif + /* only A1-A8 are used for decoding */ + address &= 0x1ff; + /* Memory Mode */ - if (address == 0xff8003) + if (address == 0x03) { s68k_poll_detect(1<<0x03); return scd.regs[0x03>>1].byte.l; } /* MAIN-CPU communication flags */ - if (address == 0xff800e) + if (address == 0x0e) { s68k_poll_detect(1<<0x0e); return scd.regs[0x0e>>1].byte.h; } /* CDC transfer status */ - if (address == 0xff8004) + if (address == 0x04) { s68k_poll_detect(1<<0x04); return scd.regs[0x04>>1].byte.h; } /* GFX operation status */ - if (address == 0xff8058) + if (address == 0x58) { s68k_poll_detect(1<<0x08); return scd.regs[0x58>>1].byte.h; } /* CDC register data (controlled by BIOS, byte access only ?) */ - if (address == 0xff8007) + if (address == 0x07) { unsigned int data = cdc_reg_r(); #ifdef LOG_CDC @@ -530,21 +533,21 @@ static unsigned int scd_read_byte(unsigned int address) } /* LED status */ - if (address == 0xff8000) + if (address == 0x00) { /* register $00 is reserved for MAIN-CPU, we use $06 instead */ return scd.regs[0x06>>1].byte.h; } /* RESET status */ - if (address == 0xff8001) + if (address == 0x01) { /* always return 1 */ return 0x01; } /* Font data */ - if ((address >= 0xff8050) && (address <= 0xff8056)) + if ((address >= 0x50) && (address <= 0x56)) { /* shifted 4-bit input (xxxx00) */ 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)); } + /* Subcode buffer */ + else if (address & 0x100) + { + /* 64 x 16-bit mirrored */ + address &= 0x17f; + } + /* default registers */ if (address & 1) { /* register LSB */ - return scd.regs[(address >> 1) & 0xff].byte.l; + return scd.regs[address >> 1].byte.l; } /* 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) { - /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ - if (address < 0xff8000) + /* PCM area (8K) mirrored into $xF0000-$xF7FFF */ + if (!(address & 0x8000)) { /* get /LDS only */ 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); #endif + /* only A1-A8 are used for decoding */ + address &= 0x1ff; + /* Memory Mode */ - if (address == 0xff8002) + if (address == 0x02) { s68k_poll_detect(1<<0x03); return scd.regs[0x03>>1].w; } /* CDC host data (word access only ?) */ - if (address == 0xff8008) + if (address == 0x08) { return cdc_host_r(); } /* LED & RESET status */ - if (address == 0xff8000) + if (address == 0x00) { /* register $00 is reserved for MAIN-CPU, we use $06 instead */ return scd.regs[0x06>>1].w; } /* Stopwatch counter (word access only ?) */ - if (address == 0xff800c) + if (address == 0x0c) { /* cycle-accurate counter value */ return (scd.regs[0x0c>>1].w + ((s68k.cycles - scd.stopwatch) / TIMERS_SCYCLES_RATIO)) & 0xfff; } /* Font data */ - if ((address >= 0xff8050) && (address <= 0xff8056)) + if ((address >= 0x50) && (address <= 0x56)) { /* shifted 4-bit input (xxxx00) */ 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)); } + /* Subcode buffer */ + else if (address & 0x100) + { + /* 64 x 16-bit mirrored */ + address &= 0x17f; + } + /* default registers */ - return scd.regs[(address >> 1) & 0xff].w; + return scd.regs[address >> 1].w; } 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) { - /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ - if (address < 0xff8000) + /* PCM area (8K) mirrored into $xF0000-$xF7FFF */ + if (!(address & 0x8000)) { /* get /LDS only */ 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) { - /* PCM area (8K) is mirrored into $FF0000-$FF7FFF */ - if (address < 0xff8000) + /* PCM area (8K) mirrored into $xF0000-$xF7FFF */ + if (!(address & 0x8000)) { /* get /LDS only */ pcm_write((address >> 1) & 0x1fff, data); diff --git a/core/loadrom.c b/core/loadrom.c index 798b931..e93de41 100644 --- a/core/loadrom.c +++ b/core/loadrom.c @@ -2,7 +2,7 @@ * Genesis Plus * 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) * * 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) * ***************************************************************************/ -int load_bios(void) +int load_bios(int system) { int size = 0; - switch (system_hw) + switch (system) { case SYSTEM_MCD: { @@ -532,10 +532,11 @@ int load_rom(char *filename) int i, size; #ifdef USE_DYNAMIC_ALLOC - /* allocate memory for Cartridge /CD hardware buffer if required */ - if (ext == NULL) + if (!ext) { + /* allocate memory for Cartridge / CD hardware if required */ ext = (external_t *)malloc(sizeof(external_t)); + if (!ext) return (0); } #endif @@ -550,30 +551,28 @@ int load_rom(char *filename) cdd.loaded = 0; } - /* auto-detect CD image files */ + /* auto-detect CD image file */ size = cdd_load(filename, (char *)(cart.rom)); if (size < 0) { /* 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; + + /* boot from CD hardware */ + scd.cartridge.boot = 0x00; } else { /* load file into ROM buffer */ char extension[4]; - size = load_archive(filename, cart.rom, sizeof(cart.rom), extension); - if (!size) - { - /* mark all BOOTROM as unloaded since they could have been overwritten */ - system_bios &= ~(0x10 | SYSTEM_SMS | SYSTEM_GG); - return 0; - } + size = load_archive(filename, cart.rom, cdd.loaded ? 0x800000 : MAXROMSIZE, extension); /* mark BOOTROM as unloaded if they have been overwritten by cartridge ROM */ 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 */ 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); + + /* error loading file */ + return 0; + } - /* convert lower case to upper case */ + /* convert lower case file extension to upper case */ *(uint32 *)(extension) &= 0xdfdfdfdf; /* auto-detect system hardware from ROM file extension */ @@ -608,7 +615,7 @@ int load_rom(char *filename) } else { - /* Mega Drive hardware (Genesis mode) */ + /* default is Mega Drive / Genesis hardware (16-bit mode) */ system_hw = SYSTEM_MD; /* decode .MDX format */ @@ -641,7 +648,7 @@ int load_rom(char *filename) size -= 512; 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) { for (i = 0; i < (size / 0x4000); i++) @@ -661,26 +668,9 @@ int load_rom(char *filename) /* set console region */ 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 /* 16-bit ROM specific */ - else if (system_hw == SYSTEM_MD) + if (system_hw == SYSTEM_MD) { /* Byteswap ROM to optimize 16-bit access */ for (i = 0; i < cart.romsize; i += 2) @@ -701,14 +691,28 @@ int load_rom(char *filename) /* Save auto-detected system hardware */ 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 */ - if (strstr(rominfo.ROMType, "BR") != NULL) + else if (strstr(rominfo.ROMType, "BR") != NULL) { /* enable CD hardware */ system_hw = SYSTEM_MCD; - /* boot from CD */ + /* boot from CD hardware */ scd.cartridge.boot = 0x00; /* copy ROM to BOOTROM area */ @@ -721,7 +725,26 @@ int load_rom(char *filename) 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) || (strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) || (strstr(rominfo.product,"T-5740") != NULL)) @@ -729,33 +752,23 @@ int load_rom(char *filename) /* check if console hardware is set to AUTO */ if (!config.system) { - /* auto-enable CD hardware */ - system_hw = SYSTEM_MCD; - /* try to load CD BOOTROM */ - if (load_bios()) + if (load_bios(SYSTEM_MCD)) { char fname[256]; 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 */ 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) { /* security code */ - switch (romheader[0x20b]) + switch ((unsigned char)romheader[0x20b]) { - case 0x7a: - region_code = REGION_USA; - break; - case 0x64: region_code = REGION_EUROPE; break; - default: + case 0xa1: region_code = REGION_JAPAN_NTSC; break; + + default: + region_code = REGION_USA; + break; } } diff --git a/core/loadrom.h b/core/loadrom.h index 4eb5bf3..ca1d51f 100644 --- a/core/loadrom.h +++ b/core/loadrom.h @@ -2,7 +2,7 @@ * Genesis Plus * 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) * * Redistribution and use of this code or any derivative works are permitted @@ -64,7 +64,7 @@ extern ROMINFO rominfo; extern uint8 romtype; /* Function prototypes */ -extern int load_bios(void); +extern int load_bios(int system); extern int load_rom(char *filename); extern void get_region(char *romheader); extern char *get_company(void); diff --git a/gx/config.c b/gx/config.c index 3aa2e63..3d1c67f 100644 --- a/gx/config.c +++ b/gx/config.c @@ -3,7 +3,7 @@ * * 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 * provided that the following conditions are met: @@ -259,7 +259,10 @@ void config_default(void) /* try to restore user config */ 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 */ if (VIDEO_HaveComponentCable()) { diff --git a/gx/config.h b/gx/config.h index 952f488..3aad3db 100644 --- a/gx/config.h +++ b/gx/config.h @@ -3,7 +3,7 @@ * * 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 * provided that the following conditions are met: diff --git a/gx/gx_input.c b/gx/gx_input.c index d51aab0..ccf7a12 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -1128,7 +1128,6 @@ void gx_input_Init(void) PAD_Init(); #ifdef HW_RVL WPAD_Init(); - WPAD_SetIdleTimeout(config.autosleep ? 300 : 1800); WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); WPAD_SetVRes(WPAD_CHAN_ALL,640,480); #endif