diff --git a/HISTORY.txt b/HISTORY.txt index e3a085b..58de36f 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -54,6 +54,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke) * added support for more X-in-1 pirate mappers * added support for some new unlicensed games with copy protection (Thunderbolt II, Tom Clown, Chaoji Puke / Super Poker, Rock Heaven, Rock World) * added support for Everdrive extended SSF mapper +* added support for MegaSD CD hardware overlay (MD+ hacks) and extended SSF2 / ROM write mappers * added (very basic) emulation of Flashkit MD hardware * added emulation of Micro Machines USA on-board TMSS bypass logic hardware * added SRAM support for games larger than 8MB diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll index 8b2b316..a2c4475 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 f96379a..3ecdbfa 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 ae96736..550bcbf 100644 Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ diff --git a/core/cart_hw/md_cart.c b/core/cart_hw/md_cart.c index 6ff9e9f..694c525 100644 --- a/core/cart_hw/md_cart.c +++ b/core/cart_hw/md_cart.c @@ -44,6 +44,7 @@ #include "shared.h" #include "eeprom_i2c.h" #include "eeprom_spi.h" +#include "megasd.h" /* Cart database entry */ typedef struct @@ -518,6 +519,21 @@ void md_cart_init(void) /* cartridge ROM mapping is reinitialized on /VRES */ cart.hw.bankshift = 1; } + else if ((strstr(rominfo.consoletype,"SEGA SSF2") != NULL) && (cart.romsize <= 0x800000)) + { + /* MegaSD enhanced SSF2 mapper (max. 8MB ROM) */ + cart.special |= HW_MEGASD; + cart.hw.time_w = megasd_enhanced_ssf2_mapper_w; + + /* cartridge ROM mapping is reinitialized on /VRES */ + cart.hw.bankshift = 1; + } + else if ((strstr(rominfo.consoletype,"SEGA MEGASD") != NULL) && (cart.romsize <= 0x400000)) + { + /* MegaSD ROM write mapper (max. 4MB ROM) */ + cart.special |= HW_MEGASD; + cart.hw.time_w = megasd_rom_mapper_w; + } else if (strstr(rominfo.domestic,"SUPER STREET FIGHTER2")) { /* SSF2 mapper */ @@ -760,6 +776,26 @@ void md_cart_init(void) break; } } + + /********************************************** + MEGASD ADD-ON + ***********************************************/ + /* enable MegaSD overlay for cartridge ROM (max. 8MB) when Mega CD hardware is disabled and either MegaSD add-on is forced enabled or automatic add-on detection is enabled and MegaSD compatible disc image is loaded */ + if ((cart.romsize <= 0x800000) && (system_hw == SYSTEM_MD) && ((config.add_on == HW_ADDON_MEGASD) || ((config.add_on | cdd.loaded) == HW_ADDON_MEGASD))) + { + cart.special |= HW_MEGASD; + } + + /* force Mega CD sound hardware initialization when MegaSD overlay is enabled (if not already initialized) */ + if ((cart.special & HW_MEGASD) && !snd.blips[1] && !snd.blips[2]) + { + /* allocate blip buffers for PCM and CD-DA audio streams */ + snd.blips[1] = blip_new(snd.sample_rate / 10); + snd.blips[2] = blip_new(snd.sample_rate / 10); + + /* initialize PCM and CD-DA audio */ + audio_set_rate(snd.sample_rate, snd.frame_rate); + } } /* hardware that need to be reseted on power on */ @@ -775,7 +811,13 @@ void md_cart_reset(int hard_reset) m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); } } - + + /* MegaSD hardware */ + if (cart.special & HW_MEGASD) + { + megasd_reset(); + } + /* SVP chip */ if (svp) { @@ -828,7 +870,7 @@ int md_cart_context_save(uint8 *state) { /* get base address */ base = m68k.memory_map[i].base; - + if (base == sram.sram) { /* SRAM */ @@ -857,6 +899,12 @@ int md_cart_context_save(uint8 *state) save_param(&svp->ssp1601,sizeof(ssp1601_t)); } + /* MegaSD hardware */ + if (cart.special & HW_MEGASD) + { + bufferptr += megasd_context_save(&state[bufferptr]); + } + return bufferptr; } @@ -913,6 +961,12 @@ int md_cart_context_load(uint8 *state) load_param(&svp->ssp1601,sizeof(ssp1601_t)); } + /* MegaSD hardware */ + if (cart.special & HW_MEGASD) + { + bufferptr += megasd_context_load(&state[bufferptr]); + } + return bufferptr; } diff --git a/core/cart_hw/md_cart.h b/core/cart_hw/md_cart.h index b34fb8f..7bdfcae 100644 --- a/core/cart_hw/md_cart.h +++ b/core/cart_hw/md_cart.h @@ -55,9 +55,16 @@ #define TYPE_AR 0x02 /* (Pro) Action Replay */ #define TYPE_SK 0x03 /* Sonic & Knuckles */ +/* CD hardware add-on (MD mode) */ +#define HW_ADDON_AUTO 0x00 +#define HW_ADDON_MEGACD 0x01 +#define HW_ADDON_MEGASD 0x02 +#define HW_ADDON_NONE 0x03 + /* Special hardware (0x01 & 0x02 reserved for Master System 3-D glasses & Terebi Oekaki) */ #define HW_J_CART 0x04 #define HW_LOCK_ON 0x08 +#define HW_MEGASD 0x10 /* Cartridge extra hardware */ typedef struct diff --git a/core/cd_hw/cdd.c b/core/cd_hw/cdd.c index 43be53c..3eac694 100644 --- a/core/cd_hw/cdd.c +++ b/core/cd_hw/cdd.c @@ -36,6 +36,7 @@ * ****************************************************************************************/ #include "shared.h" +#include "megasd.h" #if defined(USE_LIBTREMOR) || defined(USE_LIBVORBIS) #define SUPPORTED_EXT 20 @@ -363,8 +364,9 @@ int cdd_load(char *filename, char *header) char *ptr, *lptr; cdStream *fd; - /* assume CD image file by default */ + /* assume normal CD image file by default */ int isCDfile = 1; + int isMSDfile = 0; /* first unmount any loaded disc */ cdd_unload(); @@ -395,7 +397,7 @@ int cdd_load(char *filename, char *header) /* retrieve CHD header */ head = chd_get_header(cdd.chd.file); - + /* detect invalid hunk size */ if ((head->hunkbytes == 0) || (head->hunkbytes % CD_FRAME_SIZE)) { @@ -526,7 +528,7 @@ int cdd_load(char *filename, char *header) cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; /* CD mounted */ - cdd.loaded = 1; + cdd.loaded = HW_ADDON_MEGACD; return 1; } @@ -537,8 +539,9 @@ int cdd_load(char *filename, char *header) } #endif - /* save a copy of base filename */ - strncpy(fname, filename, 256); + /* save a copy of base filename (max. 255 characters) */ + strncpy(fname, filename, 255); + fname[256] = 0; /* check loaded file extension */ if (memcmp("cue", &filename[strlen(filename) - 3], 3) && memcmp("CUE", &filename[strlen(filename) - 3], 3)) @@ -794,6 +797,28 @@ int cdd_load(char *filename, char *header) } } + /* decode REM LOOP xxx command (MegaSD specific command) */ + else if (sscanf(lptr, "REM LOOP %d", &bb) == 1) + { + cdd.toc.tracks[cdd.toc.last].loopEnabled = 1; + cdd.toc.tracks[cdd.toc.last].loopOffset = bb; + isMSDfile = 1; + } + + /* decode REM LOOP command (MegaSD specific command) */ + else if (strstr(lptr,"REM LOOP")) + { + cdd.toc.tracks[cdd.toc.last].loopEnabled = 1; + isMSDfile = 1; + } + + /* decode REM NOLOOP command (MegaSD specific command) */ + else if (strstr(lptr,"REM NOLOOP")) + { + cdd.toc.tracks[cdd.toc.last].loopEnabled = -1; + isMSDfile = 1; + } + /* decode PREGAP commands */ else if (sscanf(lptr, "PREGAP %02d:%02d:%02d", &mm, &ss, &bb) == 3) { @@ -1211,7 +1236,7 @@ int cdd_load(char *filename, char *header) cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end; /* CD mounted */ - cdd.loaded = 1; + cdd.loaded = isMSDfile ? HW_ADDON_MEGASD : HW_ADDON_MEGACD; /* Automatically try to open associated subcode data file */ memcpy(&fname[strlen(fname) - 4], ".sub", 4); @@ -1617,6 +1642,12 @@ void cdd_read_audio(unsigned int samples) /* save last audio output for next frame */ cdd.audio[0] = prev_l; cdd.audio[1] = prev_r; + + /* check CD-DA track end (Mega SD add-on specific)*/ + if (cart.special & HW_MEGASD) + { + megasd_update_cdda(samples); + } } else { diff --git a/core/cd_hw/cdd.h b/core/cd_hw/cdd.h index dae50c2..c3d6c80 100644 --- a/core/cd_hw/cdd.h +++ b/core/cd_hw/cdd.h @@ -86,6 +86,8 @@ typedef struct int start; int end; int type; + int loopEnabled; + int loopOffset; } track_t; /* CD TOC */ diff --git a/core/cd_hw/pcm.c b/core/cd_hw/pcm.c index e068d70..80ae3e6 100644 --- a/core/cd_hw/pcm.c +++ b/core/cd_hw/pcm.c @@ -2,7 +2,7 @@ * Genesis Plus * PCM sound chip (315-5476A) (RF5C164 compatible) * - * Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -226,10 +226,10 @@ void pcm_update(unsigned int samples) pcm.cycles = 0; } -void pcm_write(unsigned int address, unsigned char data) +void pcm_write(unsigned int address, unsigned char data, unsigned int cycles) { - /* synchronize PCM chip with SUB-CPU */ - int clocks = s68k.cycles - pcm.cycles; + /* synchronize PCM chip with CPU */ + int clocks = cycles - pcm.cycles; if (clocks > 0) { /* number of internal clocks (samples) to run */ @@ -350,10 +350,10 @@ void pcm_write(unsigned int address, unsigned char data) } } -unsigned char pcm_read(unsigned int address) +unsigned char pcm_read(unsigned int address, unsigned int cycles) { /* synchronize PCM chip with SUB-CPU */ - int clocks = s68k.cycles - pcm.cycles; + int clocks = cycles - pcm.cycles; if (clocks > 0) { /* number of internal clocks (samples) to run */ diff --git a/core/cd_hw/pcm.h b/core/cd_hw/pcm.h index eef847d..03e1a59 100644 --- a/core/cd_hw/pcm.h +++ b/core/cd_hw/pcm.h @@ -2,7 +2,7 @@ * Genesis Plus * PCM sound chip (315-5476A) (RF5C164 compatible) * - * Copyright (C) 2012-2016 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2012-2021 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -70,8 +70,8 @@ extern void pcm_reset(void); extern int pcm_context_save(uint8 *state); extern int pcm_context_load(uint8 *state); extern void pcm_update(unsigned int samples); -extern void pcm_write(unsigned int address, unsigned char data); -extern unsigned char pcm_read(unsigned int address); +extern void pcm_write(unsigned int address, unsigned char data, unsigned int cycles); +extern unsigned char pcm_read(unsigned int address, unsigned int cycles); extern void pcm_ram_dma_w(unsigned int words); #endif diff --git a/core/cd_hw/scd.c b/core/cd_hw/scd.c index d776e45..edb728d 100644 --- a/core/cd_hw/scd.c +++ b/core/cd_hw/scd.c @@ -482,7 +482,7 @@ static unsigned int scd_read_byte(unsigned int address) /* get /LDS only */ if (address & 1) { - return pcm_read((address >> 1) & 0x1fff); + return pcm_read((address >> 1) & 0x1fff, s68k.cycles); } return s68k_read_bus_8(address); @@ -601,7 +601,7 @@ static unsigned int scd_read_word(unsigned int address) if (!(address & 0x8000)) { /* get /LDS only */ - return pcm_read((address >> 1) & 0x1fff); + return pcm_read((address >> 1) & 0x1fff, s68k.cycles); } #ifdef LOG_SCD @@ -764,7 +764,7 @@ static void scd_write_byte(unsigned int address, unsigned int data) /* get /LDS only */ if (address & 1) { - pcm_write((address >> 1) & 0x1fff, data); + pcm_write((address >> 1) & 0x1fff, data, s68k.cycles); return; } @@ -1028,7 +1028,7 @@ static void scd_write_word(unsigned int address, unsigned int data) if (!(address & 0x8000)) { /* get /LDS only */ - pcm_write((address >> 1) & 0x1fff, data); + pcm_write((address >> 1) & 0x1fff, data & 0xff, s68k.cycles); return; } diff --git a/core/loadrom.c b/core/loadrom.c index 9f14c3f..f92f40d 100644 --- a/core/loadrom.c +++ b/core/loadrom.c @@ -3,7 +3,7 @@ * ROM Loading Support * * Copyright (C) 1998-2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -58,20 +58,21 @@ #define ROMMEMO 456 #define ROMCOUNTRY 496 -#define P3BUTTONS 1 -#define P6BUTTONS 2 -#define PKEYBOARD 4 -#define PPRINTER 8 -#define PBALL 16 -#define PFLOPPY 32 -#define PACTIVATOR 64 -#define PTEAMPLAYER 128 -#define PMSYSTEMPAD 256 -#define PSERIAL 512 -#define PTABLET 1024 -#define PPADDLE 2048 -#define PCDROM 4096 -#define PMOUSE 8192 +#define P3BUTTONS 0x0001 +#define P6BUTTONS 0x0002 +#define PKEYBOARD 0x0004 +#define PPRINTER 0x0008 +#define PBALL 0x0010 +#define PFLOPPY 0x0020 +#define PACTIVATOR 0x0040 +#define PTEAMPLAYER 0x0080 +#define PMSYSTEMPAD 0x0100 +#define PSERIAL 0x0200 +#define PTABLET 0x0400 +#define PPADDLE 0x0800 +#define PCDROM 0x1000 +#define PMOUSE 0x2000 +#define PMENACER 0x4000 #define MAXCOMPANY 64 #define MAXPERIPHERALS 15 @@ -288,7 +289,7 @@ void getrominfo(char *romheader) /* Supported peripherals */ rominfo.peripherals = 0; for (i = 0; i < 14; i++) - for (j=0; j < 14; j++) + for (j=0; j < MAXPERIPHERALS; j++) if (romheader[ROMIOSUPPORT+i] == peripheralinfo[j].pID[0]) rominfo.peripherals |= (1 << j); } @@ -581,9 +582,6 @@ int load_rom(char *filename) { /* enable CD hardware */ system_hw = SYSTEM_MCD; - - /* boot from CD hardware */ - scd.cartridge.boot = 0x00; } else { @@ -710,10 +708,10 @@ 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)) { @@ -723,6 +721,9 @@ int load_rom(char *filename) /* error booting from CD */ return (0); } + + /* boot from CD hardware */ + scd.cartridge.boot = 0x00; } /* CD BOOTROM */ @@ -744,44 +745,26 @@ int load_rom(char *filename) system_bios = (system_bios & 0xf0) | (region_code >> 4); } - /* ROM cartridge (max. 8MB) with CD loaded */ - else if ((cart.romsize <= 0x800000) && cdd.loaded) + /* 16-bit ROM cartridge (max. 8MB) with optional CD hardware add-on support enabled */ + else if ((system_hw == SYSTEM_MD) && (cart.romsize <= 0x800000) && (config.add_on != HW_ADDON_NONE)) { - /* try to load CD BOOTROM */ - if (load_bios(SYSTEM_MCD)) + if ((rominfo.peripherals & PCDROM) || (strstr(rominfo.domestic,"FLUX") != NULL) || + (config.add_on == HW_ADDON_MEGACD) || ((config.add_on | cdd.loaded) == HW_ADDON_MEGACD)) { - /* 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)) - { - /* check if console hardware is set to AUTO */ - if (!config.system) - { - /* try to load CD BOOTROM */ + /* try to load CD BOOTROM for selected region */ 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); + /* automatically try to load associated .iso file if no CD image loaded yet */ + if (!cdd.loaded) + { + char fname[256]; + int len = strlen(filename); + while ((len && (filename[len] != '.')) || (len > 251)) len--; + strncpy(fname, filename, len); + strcpy(&fname[len], ".iso"); + fname[len+4] = 0; + cdd_load(fname, (char *)cdc.ram); + } /* enable CD hardware */ system_hw = SYSTEM_MCD; @@ -789,6 +772,11 @@ int load_rom(char *filename) /* boot from cartridge */ scd.cartridge.boot = 0x40; } + else + { + /* unmount any loaded CD image */ + cdd_unload(); + } } } diff --git a/core/loadrom.h b/core/loadrom.h index b3efb4e..ce9b5f4 100644 --- a/core/loadrom.h +++ b/core/loadrom.h @@ -3,7 +3,7 @@ * ROM Loading Support * * Copyright (C) 1998-2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2020 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2021 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/system.c b/core/system.c index 358262e..8ca2ed9 100644 --- a/core/system.c +++ b/core/system.c @@ -5,7 +5,7 @@ * Support for 16-bit & 8-bit hardware modes * * Copyright (C) 1998-2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2021 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -130,8 +130,8 @@ void audio_set_rate(int samplerate, double framerate) /* resampled to desired rate at the end of each frame, using Blip Buffer. */ blip_set_rates(snd.blips[0], mclk, samplerate); - /* Mega CD sound hardware */ - if (system_hw == SYSTEM_MCD) + /* Mega CD sound hardware enabled ? */ + if (snd.blips[1] && snd.blips[2]) { /* number of SCD master clocks run per second */ mclk = (mclk / system_clock) * SCD_CLOCK; @@ -195,8 +195,8 @@ int audio_update(int16 *buffer) /* run sound chips until end of frame */ int size = sound_update(mcycles_vdp); - /* Mega CD specific */ - if (system_hw == SYSTEM_MCD) + /* Mega CD sound hardware enabled ? */ + if (snd.blips[1] && snd.blips[2]) { /* sync PCM chip with other sound chips */ pcm_update(size); diff --git a/core/system.h b/core/system.h index ac72727..d7ca95f 100644 --- a/core/system.h +++ b/core/system.h @@ -5,7 +5,7 @@ * Support for 16-bit & 8-bit hardware modes * * Copyright (C) 1998-2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2018 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2021 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/gcw0/Makefile b/gcw0/Makefile index 2400056..3d4d95e 100644 --- a/gcw0/Makefile +++ b/gcw0/Makefile @@ -88,7 +88,8 @@ OBJECTS += $(OBJDIR)/sram.o \ $(OBJDIR)/eeprom_i2c.o \ $(OBJDIR)/eeprom_spi.o \ $(OBJDIR)/md_cart.o \ - $(OBJDIR)/sms_cart.o + $(OBJDIR)/sms_cart.o \ + $(OBJDIR)/megasd.o OBJECTS += $(OBJDIR)/scd.o \ $(OBJDIR)/cdd.o \ diff --git a/gcw0/config.c b/gcw0/config.c index 7ed0265..3c9c941 100644 --- a/gcw0/config.c +++ b/gcw0/config.c @@ -62,7 +62,8 @@ void set_config_defaults(void) config.force_dtack = 0; config.addr_error = 1; config.bios = 0; - config.lock_on = 0; /* = OFF (can be TYPE_SK, TYPE_GG & TYPE_AR) */ + config.lock_on = 0; /* = OFF (or TYPE_SK, TYPE_GG & TYPE_AR) */ + config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_NONE) */ config.ntsc = 0; config.lcd = 0; /* 0.8 fixed point */ diff --git a/gcw0/config.h b/gcw0/config.h index 9c9f1eb..116d8b8 100644 --- a/gcw0/config.h +++ b/gcw0/config.h @@ -40,6 +40,7 @@ typedef struct uint8 addr_error; uint8 bios; uint8 lock_on; + uint8 add_on; uint8 hot_swap; uint8 invert_mouse; uint8 gun_cursor[2]; diff --git a/gx/config.c b/gx/config.c index 209ddfc..3ab7faa 100644 --- a/gx/config.c +++ b/gx/config.c @@ -122,6 +122,7 @@ void config_default(void) config.addr_error = 1; config.bios = 0; config.lock_on = 0; + config.add_on = HW_ADDON_AUTO; config.hot_swap = 0; /* video options */ diff --git a/gx/config.h b/gx/config.h index 353007d..034aae7 100644 --- a/gx/config.h +++ b/gx/config.h @@ -71,6 +71,7 @@ typedef struct uint8 addr_error; uint8 bios; uint8 lock_on; + uint8 add_on; uint8 hot_swap; uint8 invert_mouse; uint8 gun_cursor[2]; diff --git a/gx/gui/menu.c b/gx/gui/menu.c index 186030f..f5e7bf0 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -3,7 +3,7 @@ * * Genesis Plus GX menu * - * Copyright Eke-Eke (2009-2019) + * Copyright Eke-Eke (2009-2021) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -385,6 +385,7 @@ static gui_item items_system[] = {NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48}, {NULL,NULL,"System Lockups: ON", "Enable/Disable original system lock-ups", 56,132,276,48}, {NULL,NULL,"68k Address Error: ON", "Enable/Disable 68k address error exceptions", 56,132,276,48}, + {NULL,NULL,"CD Add-on: MEGA/SEGA CD", "Select cartridge mode CD hardware add-on", 56,132,276,48}, {NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48}, {NULL,NULL,"Cartridge Swap: OFF", "Enable/Disable cartridge hot swap", 56,132,276,48}, {NULL,NULL,"BIOS & Lock-On ROM paths","Configure BIOS & Lock-On ROM paths", 56,132,276,48}, @@ -1311,25 +1312,34 @@ static void systemmenu () sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON"); sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF"); - if (config.lock_on == TYPE_GG) - sprintf (items[7].text, "Lock-On: GAME GENIE"); - else if (config.lock_on == TYPE_AR) - sprintf (items[7].text, "Lock-On: ACTION REPLAY"); - else if (config.lock_on == TYPE_SK) - sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES"); + if (config.add_on == HW_ADDON_AUTO) + sprintf (items[7].text, "CD Add-on: AUTO"); + else if (config.add_on == HW_ADDON_MEGACD) + sprintf (items[7].text, "CD Add-on: MEGA/SEGA CD"); + else if (config.add_on == HW_ADDON_MEGASD) + sprintf (items[7].text, "CD Add-on: MEGASD"); else - sprintf (items[7].text, "Lock-On: OFF"); + sprintf (items[7].text, "CD Add-on: NONE"); - sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); + if (config.lock_on == TYPE_GG) + sprintf (items[8].text, "Lock-On: GAME GENIE"); + else if (config.lock_on == TYPE_AR) + sprintf (items[8].text, "Lock-On: ACTION REPLAY"); + else if (config.lock_on == TYPE_SK) + sprintf (items[8].text, "Lock-On: SONIC&KNUCKLES"); + else + sprintf (items[8].text, "Lock-On: OFF"); + + sprintf (items[9].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); if (svp) { - sprintf (items[10].text, "SVP Cycles: %d", SVP_cycles); - m->max_items = 11; + sprintf (items[11].text, "SVP Cycles: %d", SVP_cycles); + m->max_items = 12; } else { - m->max_items = 10; + m->max_items = 11; } GUI_InitMenu(m); @@ -1520,17 +1530,31 @@ static void systemmenu () break; } - case 7: /*** Cart Lock-On ***/ + case 7: /*** CD add-on ***/ + { + config.add_on = (config.add_on + 1) % (HW_ADDON_NONE + 1); + if (config.add_on == HW_ADDON_AUTO) + sprintf (items[7].text, "CD Add-on: AUTO"); + else if (config.add_on == HW_ADDON_MEGACD) + sprintf (items[7].text, "CD Add-on: MEGA/SEGA CD"); + else if (config.add_on == HW_ADDON_MEGASD) + sprintf (items[7].text, "CD Add-on: MEGASD"); + else + sprintf (items[7].text, "CD Add-on: NONE"); + break; + } + + case 8: /*** Cart Lock-On ***/ { config.lock_on = (config.lock_on + 1) % (TYPE_SK + 1); if (config.lock_on == TYPE_GG) - sprintf (items[7].text, "Lock-On: GAME GENIE"); + sprintf (items[8].text, "Lock-On: GAME GENIE"); else if (config.lock_on == TYPE_AR) - sprintf (items[7].text, "Lock-On: ACTION REPLAY"); + sprintf (items[8].text, "Lock-On: ACTION REPLAY"); else if (config.lock_on == TYPE_SK) - sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES"); + sprintf (items[8].text, "Lock-On: SONIC&KNUCKLES"); else - sprintf (items[7].text, "Lock-On: OFF"); + sprintf (items[8].text, "Lock-On: OFF"); if ((system_hw == SYSTEM_MD) || (system_hw == SYSTEM_PICO)) { @@ -1564,14 +1588,14 @@ static void systemmenu () break; } - case 8: /*** Cartridge Hot Swap ***/ + case 9: /*** Cartridge Hot Swap ***/ { config.hot_swap ^= 1; - sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); + sprintf (items[9].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF"); break; } - case 9: /*** System ROM paths ***/ + case 10: /*** System ROM paths ***/ { GUI_DeleteMenu(m); rompathmenu(); @@ -1579,10 +1603,10 @@ static void systemmenu () break; } - case 10: /*** SVP cycles per line ***/ + case 11: /*** SVP cycles per line ***/ { GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1); - sprintf (items[10].text, "SVP Cycles: %d", SVP_cycles); + sprintf (items[11].text, "SVP Cycles: %d", SVP_cycles); break; } diff --git a/gx/gui/menu.h b/gx/gui/menu.h index ac3b36a..d2425f2 100644 --- a/gx/gui/menu.h +++ b/gx/gui/menu.h @@ -3,7 +3,7 @@ * * Genesis Plus GX menus * - * Copyright Eke-Eke (2009-2019) + * Copyright Eke-Eke (2009-2021) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/libretro/libretro.c b/libretro/libretro.c index 7d95f53..3ee1729 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -3,7 +3,7 @@ * * Genesis Plus GX libretro port * - * Copyright Eke-Eke (2007-2020) + * Copyright Eke-Eke (2007-2021) * * Copyright Daniel De Matteis (2012-2016) * @@ -608,6 +608,7 @@ static void config_default(void) config.addr_error = 1; config.bios = 0; config.lock_on = 0; + config.add_on = HW_ADDON_AUTO; config.lcd = 0; /* 0.8 fixed point */ #ifdef HAVE_OVERCLOCK config.overclock = 100; @@ -1104,6 +1105,21 @@ static void check_variables(void) m68k.aerr_enabled = config.addr_error = 0; } + var.key = "genesis_plus_gx_add_on"; + environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); + { + orig_value = config.add_on; + if (var.value && !strcmp(var.value, "sega/mega cd")) + config.add_on = HW_ADDON_MEGACD; + else if (var.value && !strcmp(var.value, "megasd")) + config.add_on = HW_ADDON_MEGASD; + else if (var.value && !strcmp(var.value, "none")) + config.add_on = HW_ADDON_NONE; + else + config.add_on = HW_ADDON_AUTO; + /* note: game needs to be reloaded for change to take effect */ + } + var.key = "genesis_plus_gx_lock_on"; environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); { @@ -1986,6 +2002,7 @@ void retro_set_environment(retro_environment_t cb) { "genesis_plus_gx_bios", "System bootrom; disabled|enabled" }, { "genesis_plus_gx_bram", "CD System BRAM; per bios|per game" }, { "genesis_plus_gx_addr_error", "68k address error; enabled|disabled" }, + { "genesis_plus_gx_add_on", "CD add-on (MD mode); auto|sega/mega cd|megasd|none" }, { "genesis_plus_gx_lock_on", "Cartridge lock-on; disabled|game genie|action replay (pro)|sonic & knuckles" }, { "genesis_plus_gx_ym2413", "Master System FM (YM2413); auto|disabled|enabled" }, #ifdef HAVE_OPLL_CORE diff --git a/libretro/osd.h b/libretro/osd.h index 8f83c83..e8c7461 100644 --- a/libretro/osd.h +++ b/libretro/osd.h @@ -3,7 +3,7 @@ * * Genesis Plus GX libretro port * - * Copyright Eke-Eke (2007-2016) + * Copyright Eke-Eke (2007-2021) * * Copyright Daniel De Matteis (2012-2016) * @@ -118,6 +118,7 @@ typedef struct uint8 addr_error; uint8 bios; uint8 lock_on; + uint8 add_on; uint8 overscan; uint8 aspect_ratio; uint8 ntsc; diff --git a/psp2/Makefile b/psp2/Makefile index 6c6a743..81230c8 100644 --- a/psp2/Makefile +++ b/psp2/Makefile @@ -86,7 +86,8 @@ OBJECTS += $(OBJDIR)/sram.o \ $(OBJDIR)/eeprom_i2c.o \ $(OBJDIR)/eeprom_spi.o \ $(OBJDIR)/md_cart.o \ - $(OBJDIR)/sms_cart.o + $(OBJDIR)/sms_cart.o \ + $(OBJDIR)/megasd.o OBJECTS += $(OBJDIR)/scd.o \ $(OBJDIR)/cdd.o \ diff --git a/psp2/config.c b/psp2/config.c index 208e078..22ca60d 100644 --- a/psp2/config.c +++ b/psp2/config.c @@ -32,6 +32,7 @@ void set_config_defaults(void) config.addr_error = 1; config.bios = 0; config.lock_on = 0; /* = OFF (can be TYPE_SK, TYPE_GG & TYPE_AR) */ + config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_NONE) */ config.ntsc = 0; config.lcd = 0; /* 0.8 fixed point */ diff --git a/psp2/config.h b/psp2/config.h index 657d6ef..cce1455 100644 --- a/psp2/config.h +++ b/psp2/config.h @@ -39,6 +39,7 @@ typedef struct uint8 addr_error; uint8 bios; uint8 lock_on; + uint8 add_on; uint8 hot_swap; uint8 invert_mouse; uint8 gun_cursor[2]; diff --git a/sdl/Makefile.sdl1 b/sdl/Makefile.sdl1 index 4783878..f83f52a 100644 --- a/sdl/Makefile.sdl1 +++ b/sdl/Makefile.sdl1 @@ -96,7 +96,8 @@ OBJECTS += $(OBJDIR)/sram.o \ $(OBJDIR)/eeprom_i2c.o \ $(OBJDIR)/eeprom_spi.o \ $(OBJDIR)/md_cart.o \ - $(OBJDIR)/sms_cart.o + $(OBJDIR)/sms_cart.o \ + $(OBJDIR)/megasd.o OBJECTS += $(OBJDIR)/scd.o \ $(OBJDIR)/cdd.o \ diff --git a/sdl/Makefile.sdl2 b/sdl/Makefile.sdl2 index 488d341..8ecbfaf 100644 --- a/sdl/Makefile.sdl2 +++ b/sdl/Makefile.sdl2 @@ -96,7 +96,8 @@ OBJECTS += $(OBJDIR)/sram.o \ $(OBJDIR)/eeprom_i2c.o \ $(OBJDIR)/eeprom_spi.o \ $(OBJDIR)/md_cart.o \ - $(OBJDIR)/sms_cart.o + $(OBJDIR)/sms_cart.o \ + $(OBJDIR)/megasd.o OBJECTS += $(OBJDIR)/scd.o \ $(OBJDIR)/cdd.o \ diff --git a/sdl/config.c b/sdl/config.c index 482ce46..1acf53b 100644 --- a/sdl/config.c +++ b/sdl/config.c @@ -34,7 +34,8 @@ void set_config_defaults(void) config.force_dtack = 0; config.addr_error = 1; config.bios = 0; - config.lock_on = 0; /* = OFF (can be TYPE_SK, TYPE_GG & TYPE_AR) */ + config.lock_on = 0; /* = OFF (or TYPE_SK, TYPE_GG & TYPE_AR) */ + config.add_on = 0; /* = HW_ADDON_AUTO (or HW_ADDON_MEGACD, HW_ADDON_MEGASD & HW_ADDON_ONE) */ config.ntsc = 0; config.lcd = 0; /* 0.8 fixed point */ diff --git a/sdl/config.h b/sdl/config.h index f39642d..200701f 100644 --- a/sdl/config.h +++ b/sdl/config.h @@ -39,6 +39,7 @@ typedef struct uint8 addr_error; uint8 bios; uint8 lock_on; + uint8 add_on; uint8 hot_swap; uint8 invert_mouse; uint8 gun_cursor[2];