Commit dfe36728 authored by ekeeke's avatar ekeeke
Browse files

[Core/MD] added support for MegaSD CD hardware overlay (MD+ hacks) and...

[Core/MD] added support for MegaSD CD hardware overlay (MD+ hacks) and extended SSF2 / ROM write mappers
parent 7989db28
......@@ -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
......
No preview for this file type
No preview for this file type
......@@ -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;
}
......
......@@ -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
......
......@@ -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
{
......
......@@ -86,6 +86,8 @@ typedef struct
int start;
int end;
int type;
int loopEnabled;
int loopOffset;
} track_t;
/* CD TOC */
......
......@@ -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 */
......
......@@ -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
......@@ -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;
}
......
......@@ -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))
{
/* enable CD hardware */
system_hw = SYSTEM_MCD;
/* boot from cartridge */
scd.cartridge.boot = 0x40;
}
else
if ((rominfo.peripherals & PCDROM) || (strstr(rominfo.domestic,"FLUX") != NULL) ||
(config.add_on == HW_ADDON_MEGACD) || ((config.add_on | cdd.loaded) == HW_ADDON_MEGACD))
{
/* 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();
}
}
}
......
......@@ -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:
......
......@@ -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);
......
......@@ -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:
......
......@@ -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 \
......
......@@ -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 */
......
......@@ -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];
......
......@@ -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 */
......
......@@ -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];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment