mirror of
https://github.com/libretro/FBNeo.git
synced 2026-11-07 02:55:59 -10:00
megadrive: add segacd support
This commit is contained in:
1 parent
097d45ab3a
commit
8d19a50878
32 files changed
+2810
-30
No files matched your search
+1
-1
@@ -160,7 +160,7 @@ depobj = burn.o burn_bitmap.o burn_gun.o burn_led.o burn_shift.o burn_memory.o
|
||||
\
|
||||
toa_bcu2.o toa_extratext.o toa_gp9001.o toa_palette.o toaplan1.o toaplan.o \
|
||||
\
|
||||
megadrive.o stm95.o \
|
||||
megadrive.o segacd.o stm95.o \
|
||||
\
|
||||
pce.o pce_cd.o \
|
||||
\
|
||||
|
||||
@@ -704,6 +704,7 @@ rm %(Filename).exe</Command>
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\dcs2k.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_kinst.cpp" />
|
||||
|
||||
@@ -3018,6 +3018,9 @@
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp">
|
||||
<Filter>burn\snd</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp">
|
||||
<Filter>Burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp">
|
||||
<Filter>Burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -655,6 +655,7 @@ del %(Filename).exe</Command>
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\dcs2k.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_kinst.cpp" />
|
||||
|
||||
@@ -2059,6 +2059,9 @@
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp">
|
||||
<Filter>burn\snd</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -655,6 +655,7 @@ del %(Filename).exe</Command>
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\dcs2k.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_kinst.cpp" />
|
||||
|
||||
@@ -2059,6 +2059,9 @@
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp">
|
||||
<Filter>burn\snd</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -655,6 +655,7 @@ del %(Filename).exe</Command>
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\dcs2k.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_kinst.cpp" />
|
||||
|
||||
@@ -2059,6 +2059,9 @@
|
||||
<ClCompile Include="..\..\src\burn\snd\timeplt_snd.cpp">
|
||||
<Filter>burn\snd</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -348,6 +348,7 @@
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_mdarcbl.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\d_megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_kinst.cpp" />
|
||||
<ClCompile Include="..\..\src\burn\drv\midway\d_tunit.cpp" />
|
||||
|
||||
@@ -952,6 +952,9 @@
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\megadrive.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\segacd.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\burn\drv\megadrive\stm95.cpp">
|
||||
<Filter>burn\drv\megadrive</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -746,6 +746,7 @@ int BurnComputeSHA1(const UINT8 *buffer, int buffer_size, char *hash_str);
|
||||
#define HARDWARE_SEGA_GAME_GEAR (HARDWARE_PREFIX_SEGA_GAME_GEAR)
|
||||
|
||||
#define HARDWARE_SEGA_MEGADRIVE (HARDWARE_PREFIX_SEGA_MEGADRIVE)
|
||||
#define HARDWARE_SEGA_MEGACD (HARDWARE_PREFIX_SEGA_MEGADRIVE | 0x00010000)
|
||||
|
||||
#define HARDWARE_SEGA_SG1000 (HARDWARE_PREFIX_SEGA_SG1000)
|
||||
#define HARDWARE_SEGA_SG1000_RAMEXP_A (0x1000)
|
||||
|
||||
@@ -483,6 +483,47 @@ INT32 MegadriveGetZipName(char** pszName, UINT32 i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sega CD / Mega-CD system (bios), the disc image is selected separately
|
||||
|
||||
static struct BurnDIPInfo SegaCDDIPList[] = {
|
||||
DIP_OFFSET(0x19)
|
||||
{0x00, 0xff, 0xff, 0x00, NULL },
|
||||
{0x01, 0xff, 0xff, 0x03, NULL },
|
||||
|
||||
{0, 0xfd, 0, 4, "Bios" },
|
||||
{0x00, 0x01, 0x03, 0x00, "Auto (disc region)" },
|
||||
{0x00, 0x01, 0x03, 0x01, "Sega CD (USA, v1.10)" },
|
||||
{0x00, 0x01, 0x03, 0x02, "Mega-CD (Europe, v1.00)" },
|
||||
{0x00, 0x01, 0x03, 0x03, "Mega-CD (Japan, v1.00P)" },
|
||||
|
||||
{0, 0xfe, 0, 4, "32-Col Mode Draw" },
|
||||
{0x01, 0x01, 0x03, 0x00, "No Change" },
|
||||
{0x01, 0x01, 0x03, 0x01, "Center" },
|
||||
{0x01, 0x01, 0x03, 0x02, "Inner Zoom" },
|
||||
{0x01, 0x01, 0x03, 0x03, "Resize Screen/Window" },
|
||||
};
|
||||
|
||||
STDDIPINFO(SegaCD)
|
||||
|
||||
static struct BurnRomInfo md_segacdRomDesc[] = {
|
||||
{ "Sega CD BIOS (USA, v1.10).bin", 0x020000, 0xc6d10268, BRF_PRG | BRF_ESS },
|
||||
{ "Mega-CD BIOS (Europe, v1.00).bin", 0x020000, 0x529ac15a, BRF_PRG | BRF_ESS | BRF_OPT },
|
||||
{ "Mega-CD BIOS (Japan, v1.00P).bin", 0x020000, 0x9d2da8f2, BRF_PRG | BRF_ESS | BRF_OPT },
|
||||
};
|
||||
|
||||
STD_ROM_PICK(md_segacd)
|
||||
STD_ROM_FN(md_segacd)
|
||||
|
||||
struct BurnDriver BurnDrvmd_segacd = {
|
||||
"md_segacd", NULL, NULL, NULL, "1992",
|
||||
"Sega CD / Mega-CD System\0", "System - media selected separately", "Sega", "Sega CD / Mega-CD",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_16BIT_ONLY, 2, HARDWARE_SEGA_MEGACD, GBF_BIOS, 0,
|
||||
MegadriveGetZipName, md_segacdRomInfo, md_segacdRomName, NULL, NULL, NULL, NULL, MegadriveInputInfo, SegaCDDIPInfo,
|
||||
MegadriveInitSegaCD, MegadriveExit, MegadriveFrame, MegadriveDraw, MegadriveScan,
|
||||
&bMegadriveRecalcPalette, 0x100, 320, 224, 4, 3
|
||||
};
|
||||
|
||||
// 16 Ton (Japan, SegaNet)
|
||||
static struct BurnRomInfo md_16tonRomDesc[] = {
|
||||
{ "16 Ton (Japan, SegaNet)(1991)(Sega).bin", 0x040000, 0x537f04b6, BRF_PRG | SEGA_MD_ROM_LOAD16_WORD_SWAP | SEGA_MD_ROM_OFFS_000000 },
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "m68000_debug.h"
|
||||
#include "i2ceeprom.h" // i2c eeprom for MD
|
||||
#include "burn_gun.h" // menacer, justifier
|
||||
#include "segacd.h"
|
||||
|
||||
UINT8 MegadriveUnmappedRom = 0xff;
|
||||
|
||||
@@ -67,7 +68,7 @@ static INT32 SekCyclesDoneFrameF() { return ( (SekCycleCnt - SekCycleCntDELTA) -
|
||||
#define SekCyclesBurn(c) { SekCycleCnt += c; }
|
||||
#define SekEndRun(after) { SekCycleCnt -= m68k_ICount - (after); m68k_ICount = after; }
|
||||
|
||||
static void SekRunM68k(INT32 cyc)
|
||||
static void SekRunM68kSlice(INT32 cyc)
|
||||
{
|
||||
INT32 cyc_do;
|
||||
|
||||
@@ -81,6 +82,24 @@ static void SekRunM68k(INT32 cyc)
|
||||
m68k_ICount = 0;
|
||||
}
|
||||
|
||||
// Sega CD: the sub cpu catches up with the main cpu in small slices
|
||||
#define SEGACD_SLICE 122
|
||||
|
||||
static void SekRunM68k(INT32 cyc)
|
||||
{
|
||||
if (SegaCDMode) {
|
||||
while (cyc > 0) {
|
||||
INT32 slice = (cyc > SEGACD_SLICE) ? SEGACD_SLICE : cyc;
|
||||
SekRunM68kSlice(slice);
|
||||
SegaCDRunSub(SekCyclesDoneFrame());
|
||||
cyc -= slice;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SekRunM68kSlice(cyc);
|
||||
}
|
||||
|
||||
static UINT64 z80_cycle_cnt;
|
||||
static INT32 Z80HasBus = 0;
|
||||
static INT32 MegadriveZ80Reset = 0;
|
||||
@@ -275,6 +294,12 @@ static INT32 dma_xfers = 0; // vdp dma
|
||||
static INT32 BlankedLine = 0;
|
||||
static INT32 interlacemode2 = 0;
|
||||
|
||||
// VSRAM writes done once the next line's display has started, kept out of that line (Puggsy FMV)
|
||||
static INT32 vsram_late_count = 0;
|
||||
static UINT8 vsram_late_idx[0x40];
|
||||
static UINT16 vsram_late_val[0x40];
|
||||
static void VSRAMLateWrite(INT32 idx);
|
||||
|
||||
static UINT8 Hardware;
|
||||
static UINT8 bNoDebug = 0;
|
||||
static INT32 bForce3Button = 0;
|
||||
@@ -293,6 +318,12 @@ static UINT8 __fastcall MegadriveReadByte(UINT32 address);
|
||||
|
||||
static void MegadriveCheckHardware()
|
||||
{
|
||||
if (SegaCDMode) {
|
||||
Hardware = SegaCDGetHardware();
|
||||
bprintf(PRINT_IMPORTANT, _T("Emulating %s Mega CD / Sega CD\n"), ((Hardware & 0xc0) == 0xc0) ? _T("Europe PAL") : ((Hardware & 0x80) ? _T("USA NTSC") : _T("Japan NTSC")));
|
||||
return;
|
||||
}
|
||||
|
||||
Hardware = MegadriveDIP[0] & 0xe0;
|
||||
if (MegadriveDIP[0] & 0x01) {
|
||||
// Auto Detect Region and SECAM
|
||||
@@ -752,6 +783,11 @@ static void DmaSlow(INT32 len)
|
||||
if ((source & 0xe00000) == 0xe00000) { // RAM
|
||||
pd = (UINT16 *)(Ram68K + (source & 0xfffe));
|
||||
pdend = (UINT16 *)(Ram68K + 0x10000);
|
||||
} else if (SegaCDMode && source < 0x400000) { // Sega CD: bios, prg-ram window, word ram
|
||||
fromrom = 1;
|
||||
source &= ~1;
|
||||
// dma from word ram responds with a one-access delay
|
||||
if ((source & 0x3c0000) == 0x200000) source -= 2;
|
||||
} else if( source < RomSize) { // ROM
|
||||
if (papriummode || psolarmode) fromrom = 1;
|
||||
fromrom = 1;
|
||||
@@ -762,7 +798,7 @@ static void DmaSlow(INT32 len)
|
||||
} else return; // Invalid source address
|
||||
|
||||
// overflow protection, might break something..
|
||||
if (len > pdend - pd) {
|
||||
if (pd && len > pdend - pd) {
|
||||
len = pdend - pd;
|
||||
//bprintf(0, _T("DmaSlow() overflow(!).\n"));
|
||||
}
|
||||
@@ -852,7 +888,12 @@ static void DmaSlow(INT32 len)
|
||||
a |= RamVReg->addr_u << 16;
|
||||
for(; len; len--)
|
||||
{
|
||||
VideoWrite128(a, BURN_ENDIAN_SWAP_INT16(*pd++));
|
||||
if (pd == NULL) {
|
||||
VideoWrite128(a, SekReadWord(source));
|
||||
source += 2;
|
||||
} else {
|
||||
VideoWrite128(a, BURN_ENDIAN_SWAP_INT16(*pd++));
|
||||
}
|
||||
// AutoIncrement
|
||||
a = (a + inc) & 0x1ffff;
|
||||
}
|
||||
@@ -860,6 +901,7 @@ static void DmaSlow(INT32 len)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// remember addr
|
||||
RamVReg->addr = (UINT16)a;
|
||||
UpdateDMARegs();
|
||||
@@ -1057,6 +1099,32 @@ struct h_ { UINT16 hres; UINT8 hint; UINT8 start; UINT8 end; };
|
||||
|
||||
static const h_ hints[2] = { {256, 0x85, 0x94, 0xe9}, {320, 0xa5, 0xb7, 0xe5} };
|
||||
|
||||
static void VSRAMLateWrite(INT32 idx)
|
||||
{
|
||||
INT32 cyc = SekCyclesLine();
|
||||
if (cyc < 400 || cyc >= 512) return;
|
||||
|
||||
const UINT8 *hc = (RamVReg->reg[12] & 1) ? hcounts_40 : hcounts_32;
|
||||
if (hc[cyc] >= 0x80) return; // display of the next line not started yet
|
||||
|
||||
for (INT32 i = 0; i < vsram_late_count; i++)
|
||||
if (vsram_late_idx[i] == idx) return;
|
||||
|
||||
vsram_late_idx[vsram_late_count] = idx;
|
||||
vsram_late_val[vsram_late_count] = RamSVid[idx];
|
||||
vsram_late_count++;
|
||||
}
|
||||
|
||||
// exchanges the late values with the ones they replaced
|
||||
static void VSRAMLateSwap()
|
||||
{
|
||||
for (INT32 i = 0; i < vsram_late_count; i++) {
|
||||
UINT16 t = RamSVid[vsram_late_idx[i]];
|
||||
RamSVid[vsram_late_idx[i]] = vsram_late_val[i];
|
||||
vsram_late_val[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT16 __fastcall MegadriveVideoReadWord(UINT32 sekAddress)
|
||||
{
|
||||
if (sekAddress > 0xC0001F)
|
||||
@@ -1179,6 +1247,8 @@ static void __fastcall MegadriveVideoWriteWord(UINT32 sekAddress, UINT16 wordVal
|
||||
CalcCol((RamVReg->addr >> 1) & 0x003f, wordValue);
|
||||
break;
|
||||
case 5:
|
||||
// limited to Sega CD for safety, but should be valid for regular MD games too
|
||||
if (SegaCDMode) VSRAMLateWrite((RamVReg->addr >> 1) & 0x003f);
|
||||
RamSVid[(RamVReg->addr >> 1) & 0x003f] = BURN_ENDIAN_SWAP_INT16(wordValue & 0x7ff);
|
||||
break;
|
||||
case 0x81: {
|
||||
@@ -1603,6 +1673,10 @@ static INT32 MegadriveResetDo()
|
||||
m68k_megadrive_sr_checkint_mode(1);
|
||||
SekClose();
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDReset();
|
||||
}
|
||||
|
||||
ZetOpen(0);
|
||||
ZetReset();
|
||||
ZetClose();
|
||||
@@ -1622,6 +1696,10 @@ static INT32 MegadriveResetDo()
|
||||
|
||||
MegadriveCheckHardware();
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDSetPAL(Hardware & 0x40);
|
||||
}
|
||||
|
||||
if (last_hardware != Hardware) {
|
||||
bprintf(0, _T("** Megadrive Region/Hardware change, %dhz\n"), (Hardware & 0x40) ? 50 : 60);
|
||||
if (Hardware & 0x40) {
|
||||
@@ -1707,6 +1785,7 @@ static INT32 MegadriveResetDo()
|
||||
RamVReg->rendstatus = 0;
|
||||
bMegadriveRecalcPalette = 1;
|
||||
interlacemode2 = 0;
|
||||
vsram_late_count = 0;
|
||||
|
||||
SekCyclesReset();
|
||||
z80CyclesReset();
|
||||
@@ -1731,7 +1810,13 @@ static INT32 __fastcall MegadriveIrqCallback(INT32 irq)
|
||||
case 4: RamVReg->pending_ints = 0x00; break;
|
||||
case 6: RamVReg->pending_ints &= ~0x20; break;
|
||||
}
|
||||
SekSetIRQLine(0, CPU_IRQSTATUS_NONE);
|
||||
// a pending h-int stays asserted once the v-int is acknowledged (SoulStar demo)
|
||||
// limited to Sega CD for safety, but should be valid for regular MD games too
|
||||
if (SegaCDMode && irq == 6 && (RamVReg->pending_ints & 0x10) && (RamVReg->reg[0] & 0x10)) {
|
||||
SekSetIRQLine(4, CPU_IRQSTATUS_ACK);
|
||||
} else {
|
||||
SekSetIRQLine(0, CPU_IRQSTATUS_NONE);
|
||||
}
|
||||
return M68K_INT_ACK_AUTOVECTOR;
|
||||
}
|
||||
|
||||
@@ -3825,6 +3910,14 @@ INT32 MegadriveInitColocodx()
|
||||
return rc;
|
||||
}
|
||||
|
||||
INT32 MegadriveInitSegaCD()
|
||||
{
|
||||
SegaCDMode = 1;
|
||||
SegaCDMainCycles = SekCyclesDoneFrameF;
|
||||
|
||||
return MegadriveInit();
|
||||
}
|
||||
|
||||
INT32 MegadriveInit()
|
||||
{
|
||||
BurnAllocMemIndex();
|
||||
@@ -3835,8 +3928,14 @@ INT32 MegadriveInit()
|
||||
|
||||
memset(RomMain, MegadriveUnmappedRom, MAX_CARTRIDGE_SIZE);
|
||||
|
||||
MegadriveLoadRoms(0);
|
||||
if (MegadriveLoadRoms(1)) return 1;
|
||||
if (SegaCDMode) {
|
||||
if (SegaCDLoadBios(RomMain)) return 1;
|
||||
RomNum = 1;
|
||||
RomSize = 0x20000;
|
||||
} else {
|
||||
MegadriveLoadRoms(0);
|
||||
if (MegadriveLoadRoms(1)) return 1;
|
||||
}
|
||||
|
||||
{
|
||||
SekInit(0, 0x68000); // Allocate 68000
|
||||
@@ -3905,8 +4004,12 @@ INT32 MegadriveInit()
|
||||
SN76496SetBuffered(SekCyclesDoneFrameF, OSC_NTSC / 7);
|
||||
SN76496SetRoute(0, 0.50, BURN_SND_ROUTE_BOTH);
|
||||
|
||||
MegadriveSetupSRAM();
|
||||
SetupCustomCartridgeMappers();
|
||||
if (SegaCDMode) {
|
||||
if (SegaCDInit(RomMain)) return 1;
|
||||
} else {
|
||||
MegadriveSetupSRAM();
|
||||
SetupCustomCartridgeMappers();
|
||||
}
|
||||
|
||||
if (MegadriveCallback) MegadriveCallback();
|
||||
|
||||
@@ -3960,6 +4063,10 @@ INT32 MegadriveExit()
|
||||
sot4wmode = 0;
|
||||
}
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDExit();
|
||||
}
|
||||
|
||||
if (has_gun != 0) {
|
||||
BurnGunExit();
|
||||
|
||||
@@ -5520,6 +5627,10 @@ INT32 MegadriveFrame()
|
||||
SekCyclesNewFrame(); // for sound sync
|
||||
ZetNewFrame();
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDNewFrame();
|
||||
}
|
||||
|
||||
SekOpen(0);
|
||||
ZetOpen(0);
|
||||
|
||||
@@ -5666,6 +5777,8 @@ INT32 MegadriveFrame()
|
||||
}
|
||||
|
||||
// decide if we draw this line
|
||||
INT32 vsram_late = vsram_late_count;
|
||||
if (vsram_late) VSRAMLateSwap();
|
||||
if ((!(RamVReg->reg[1]&8) && y<=224) || ((RamVReg->reg[1]&8) && y<240)) {
|
||||
if (interlacemode2) {
|
||||
RamVReg->field = 0;
|
||||
@@ -5678,6 +5791,10 @@ INT32 MegadriveFrame()
|
||||
PicoLine(y);
|
||||
}
|
||||
}
|
||||
if (vsram_late) {
|
||||
VSRAMLateSwap();
|
||||
vsram_late_count = 0;
|
||||
}
|
||||
|
||||
z80CyclesSync();
|
||||
|
||||
@@ -5710,6 +5827,10 @@ INT32 MegadriveFrame()
|
||||
#endif
|
||||
}
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDEndFrame(SekCyclesDoneFrame());
|
||||
}
|
||||
|
||||
if (pBurnDraw) MegadriveDraw();
|
||||
|
||||
if (pBurnSoundOut) {
|
||||
@@ -5727,6 +5848,10 @@ INT32 MegadriveFrame()
|
||||
vx_render(pBurnSoundOut, nBurnSoundLen);
|
||||
}
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDSoundUpdate(pBurnSoundOut, nBurnSoundLen);
|
||||
}
|
||||
|
||||
SekClose();
|
||||
ZetClose();
|
||||
|
||||
@@ -5801,6 +5926,10 @@ INT32 MegadriveScan(INT32 nAction, INT32 *pnMin)
|
||||
md_eeprom_stm95_scan(nAction);
|
||||
}
|
||||
|
||||
if (SegaCDMode) {
|
||||
SegaCDScan(nAction, pnMin);
|
||||
}
|
||||
|
||||
if (nAction & ACB_WRITE && (BurnDrvGetHardwareCode() & 0xff) == HARDWARE_SEGA_MEGADRIVE_PCB_SSF2) {
|
||||
for (INT32 i = 0; i < 7; i++) {
|
||||
Ssf2BankWriteByte(0xa130f3 + (i*2), RamMisc->MapperBank[i+1]);
|
||||
|
||||
@@ -36,6 +36,7 @@ INT32 MegadriveInitPaprium();
|
||||
INT32 MegadriveInitPsolar();
|
||||
INT32 MegadriveInitSot4w();
|
||||
INT32 MegadriveInitColocodx();
|
||||
INT32 MegadriveInitSegaCD();
|
||||
|
||||
INT32 MegadriveExit();
|
||||
INT32 MegadriveFrame();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
group_desc = 'Sega Mega Drive drivers'
|
||||
group_srcs = [
|
||||
'megadrive.cpp',
|
||||
'segacd.cpp',
|
||||
'stm95.cpp',
|
||||
]
|
||||
drivers = {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#ifndef SEGACD_H
|
||||
#define SEGACD_H
|
||||
|
||||
extern INT32 SegaCDMode;
|
||||
extern INT32 (*SegaCDMainCycles)(); // main cpu cycles done in the current frame
|
||||
|
||||
// bios / region
|
||||
INT32 SegaCDLoadBios(UINT8 *dest);
|
||||
UINT8 SegaCDGetHardware();
|
||||
|
||||
// main cpu (cpu #0) must be initialised and closed when calling these
|
||||
INT32 SegaCDInit(UINT8 *bios);
|
||||
void SegaCDExit();
|
||||
void SegaCDReset();
|
||||
void SegaCDSetPAL(INT32 pal);
|
||||
|
||||
// frame handling, called with cpu #0 closed
|
||||
void SegaCDNewFrame();
|
||||
// called with cpu #0 open
|
||||
void SegaCDRunSub(INT32 main_cycles);
|
||||
void SegaCDEndFrame(INT32 main_cycles);
|
||||
void SegaCDSoundUpdate(INT16 *output, INT32 samples);
|
||||
|
||||
INT32 SegaCDScan(INT32 nAction, INT32 *pnMin);
|
||||
|
||||
#endif
|
||||
+151
-1
@@ -2,9 +2,11 @@
|
||||
#include "cdlist.h"
|
||||
#include "neocdlist.h"
|
||||
#include "pcecdlist.h"
|
||||
#include "segacdlist.h"
|
||||
#include "cd_img.h"
|
||||
#include "neocdlist_games.h"
|
||||
#include "pcecdlist_games.h"
|
||||
#include "segacdlist_games.h"
|
||||
|
||||
static NGCDGAME* pNeoGame;
|
||||
|
||||
@@ -268,6 +270,25 @@ static INT32 IsGamesExpress(CDImage* pImage, const CDImageTrack* pTrack, UINT8*
|
||||
return nCrc == 0xd7b47c06 || nCrc == 0x86aec522 || nCrc == 0xc8d1b5ef || nCrc == 0x0bdbde64;
|
||||
}
|
||||
|
||||
// Sega CD / Mega-CD disc header: system id at 0x000, titles at 0x120 (domestic) / 0x150 (overseas), region at 0x1f0
|
||||
static INT32 IsSegaCDHeader(const UINT8* pSector, INT32 nSize)
|
||||
{
|
||||
return nSize >= 0x200 && (!memcmp(pSector, "SEGADISCSYSTEM", 14) || !memcmp(pSector, "SEGABOOTDISC", 12));
|
||||
}
|
||||
|
||||
static void SegaCDHeaderText(TCHAR* pszDest, UINT32 nDest, const UINT8* pText, INT32 nLength)
|
||||
{
|
||||
UINT32 n = 0;
|
||||
for (INT32 i = 0; i < nLength && n + 1 < nDest; i++) {
|
||||
UINT8 c = pText[i];
|
||||
if (c < 0x20 || c > 0x7e) c = ' ';
|
||||
if (c == ' ' && (n == 0 || pszDest[n - 1] == _T(' '))) continue;
|
||||
pszDest[n++] = (TCHAR)c;
|
||||
}
|
||||
while (n && pszDest[n - 1] == _T(' ')) n--;
|
||||
pszDest[n] = 0;
|
||||
}
|
||||
|
||||
static INT32 IdentifyPlatform(CDImage* pImage, CDListResult* pResult)
|
||||
{
|
||||
static const UINT8 pPceMagic[32] = {
|
||||
@@ -293,6 +314,18 @@ static INT32 IdentifyPlatform(CDImage* pImage, CDListResult* pResult)
|
||||
return 0;
|
||||
|
||||
INT32 nSize = 0;
|
||||
if (ReadSector(pImage, pTrack->nIndex1LBA, sector, &nSize) && IsSegaCDHeader(sector, nSize)) {
|
||||
pResult->nPlatform = CDLIST_PLATFORM_SEGACD;
|
||||
pResult->nSource = CDLIST_SOURCE_MAGIC;
|
||||
pResult->nConfidence = CDLIST_CONFIDENCE_EXACT;
|
||||
SegaCDHeaderText(pResult->Metadata.szTitle, CDLIST_TEXT_SIZE, sector + 0x150, 0x30);
|
||||
if (!pResult->Metadata.szTitle[0])
|
||||
SegaCDHeaderText(pResult->Metadata.szTitle, CDLIST_TEXT_SIZE, sector + 0x120, 0x30);
|
||||
SegaCDHeaderText(pResult->Metadata.szRegion, 64, sector + 0x1f0, 0x10);
|
||||
CopyText(pResult->Metadata.szRequirement, CDLIST_TEXT_SIZE, _T("Sega CD / Mega-CD BIOS"));
|
||||
CopyText(pResult->Metadata.szDescriptor, CDLIST_TEXT_SIZE, _T("Sega CD disc system header"));
|
||||
return 1;
|
||||
}
|
||||
if (ReadSector(pImage, pTrack->nIndex1LBA, sector, &nSize) && nSize >= 32 && !memcmp(sector, pPceMagic, sizeof(pPceMagic))) {
|
||||
pResult->nPlatform = CDLIST_PLATFORM_PCECD;
|
||||
pResult->nSource = CDLIST_SOURCE_MAGIC;
|
||||
@@ -320,6 +353,18 @@ static INT32 IdentifyPlatform(CDImage* pImage, CDListResult* pResult)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const sega_cd_game* FindSegaCDGame(const TCHAR* pszSha1)
|
||||
{
|
||||
if (!pszSha1 || !pszSha1[0])
|
||||
return NULL;
|
||||
|
||||
for (UINT32 i = 0; i < sizeof(segacd_games) / sizeof(segacd_games[0]); i++) {
|
||||
if (segacd_games[i].sha1[0] && !_tcscmp(segacd_games[i].sha1, pszSha1))
|
||||
return &segacd_games[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void FillNeoMetadata(CDListResult* pResult)
|
||||
{
|
||||
NGCDGAME* pGame = GetNeoGeoCDInfo(pResult->nNeoID);
|
||||
@@ -391,6 +436,17 @@ INT32 CDListIdentifyEx(const TCHAR* pszPath, CDListResult* pResult, UINT32 nFlag
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pResult->nPlatform == CDLIST_PLATFORM_SEGACD) {
|
||||
const sega_cd_game* pGame = FindSegaCDGame(pResult->szTOCSha1);
|
||||
if (pGame) {
|
||||
CopyText(pResult->Metadata.szTitle, CDLIST_TEXT_SIZE, pGame->name);
|
||||
CopyText(pResult->Metadata.szName, CDLIST_TEXT_SIZE, pGame->id);
|
||||
CopyText(pResult->Metadata.szYear, 32, pGame->year);
|
||||
CopyText(pResult->Metadata.szCompany, CDLIST_TEXT_SIZE, pGame->company);
|
||||
pResult->nSource = CDLIST_SOURCE_GAMEDB;
|
||||
}
|
||||
}
|
||||
}
|
||||
CDImageClose(pImage);
|
||||
return pResult->nPlatform != CDLIST_PLATFORM_UNKNOWN;
|
||||
@@ -598,6 +654,98 @@ void PceCDInfo_Exit()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
static CDListMetadata SegaCdInfo;
|
||||
static INT32 nSegaCdInfoValid = 0;
|
||||
|
||||
static INT32 IsSegaCD()
|
||||
{
|
||||
return (BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD;
|
||||
}
|
||||
|
||||
INT32 SegaCDInfo_Init()
|
||||
{
|
||||
SegaCDInfo_Exit();
|
||||
|
||||
if (!IsSegaCD() || !CDEmuImage[0]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the short name comes from the image file name, so that each image gets its own saves
|
||||
TCHAR szFile[CDLIST_TEXT_SIZE];
|
||||
const TCHAR* pszBase = _tcsrchr(CDEmuImage, _T('\\'));
|
||||
pszBase = pszBase ? pszBase + 1 : CDEmuImage;
|
||||
const TCHAR* pszSlash = _tcsrchr(pszBase, _T('/'));
|
||||
if (pszSlash) {
|
||||
pszBase = pszSlash + 1;
|
||||
}
|
||||
CopyText(szFile, CDLIST_TEXT_SIZE, pszBase);
|
||||
TCHAR* pszDot = _tcsrchr(szFile, _T('.'));
|
||||
if (pszDot) {
|
||||
*pszDot = _T('\0');
|
||||
}
|
||||
|
||||
INT32 nLen = 0;
|
||||
for (INT32 i = 0; szFile[i] && nLen < 32; i++) {
|
||||
TCHAR c = _totlower(szFile[i]);
|
||||
if (c == _T('-') || c == _T('(') || c == _T('[')) break;
|
||||
if ((c >= _T('a') && c <= _T('z')) || (c >= _T('0') && c <= _T('9'))) {
|
||||
SegaCdInfo.szName[nLen++] = c;
|
||||
}
|
||||
}
|
||||
SegaCdInfo.szName[nLen] = _T('\0');
|
||||
if (nLen == 0) {
|
||||
_tcscpy(SegaCdInfo.szName, _T("unknown"));
|
||||
}
|
||||
|
||||
const sega_cd_game* pGame = FindSegaCDGame(ANSIToTCHAR((char*)CDEmuImageTOCSHA1, NULL, 0));
|
||||
if (pGame) {
|
||||
bprintf(0, _T("segacdlist_games db: found entry %s\n"), pGame->id);
|
||||
CopyText(SegaCdInfo.szTitle, CDLIST_TEXT_SIZE, pGame->name);
|
||||
CopyText(SegaCdInfo.szName, CDLIST_TEXT_SIZE, pGame->id);
|
||||
CopyText(SegaCdInfo.szYear, 32, pGame->year);
|
||||
CopyText(SegaCdInfo.szCompany, CDLIST_TEXT_SIZE, pGame->company);
|
||||
} else {
|
||||
CDListResult Result;
|
||||
if (CDListIdentifyEx(CDEmuImage, &Result, CDLIST_IDENTIFY_FAST, NULL, NULL, NULL) && Result.nPlatform == CDLIST_PLATFORM_SEGACD && Result.Metadata.szTitle[0]) {
|
||||
CopyText(SegaCdInfo.szTitle, CDLIST_TEXT_SIZE, Result.Metadata.szTitle);
|
||||
} else {
|
||||
CopyText(SegaCdInfo.szTitle, CDLIST_TEXT_SIZE, szFile);
|
||||
}
|
||||
}
|
||||
|
||||
nSegaCdInfoValid = 1;
|
||||
|
||||
bprintf(PRINT_NORMAL, _T(" Title: %s\n" ), SegaCdInfo.szTitle);
|
||||
bprintf(PRINT_NORMAL, _T(" Shortname: %s\n"), SegaCdInfo.szName);
|
||||
if (SegaCdInfo.szYear[0]) bprintf(PRINT_NORMAL, _T(" Year: %s\n" ), SegaCdInfo.szYear);
|
||||
if (SegaCdInfo.szCompany[0]) bprintf(PRINT_NORMAL, _T(" Company: %s\n"), SegaCdInfo.szCompany);
|
||||
|
||||
return nSegaCdInfoValid;
|
||||
}
|
||||
|
||||
TCHAR* SegaCDInfo_Text(INT32 nText)
|
||||
{
|
||||
if (!IsSegaCD() || !nSegaCdInfoValid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (nText) {
|
||||
case DRV_FULLNAME: return SegaCdInfo.szTitle;
|
||||
case DRV_NAME: return SegaCdInfo.szName;
|
||||
case DRV_MANUFACTURER: return SegaCdInfo.szCompany[0] ? SegaCdInfo.szCompany : NULL;
|
||||
case DRV_DATE: return SegaCdInfo.szYear[0] ? SegaCdInfo.szYear : NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SegaCDInfo_Exit()
|
||||
{
|
||||
memset(&SegaCdInfo, 0, sizeof(SegaCdInfo));
|
||||
nSegaCdInfoValid = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
TCHAR* CDInfo_Text(INT32 nText)
|
||||
{
|
||||
static TCHAR szNone[] = _T("NOGAME");
|
||||
@@ -608,6 +756,8 @@ TCHAR* CDInfo_Text(INT32 nText)
|
||||
return NeoCDInfo_Text(nText);
|
||||
case CDGAME_PCE:
|
||||
return PceCDInfo_Text(nText);
|
||||
case CDGAME_SEGACD:
|
||||
return SegaCDInfo_Text(nText);
|
||||
default:
|
||||
return szNone;
|
||||
}
|
||||
@@ -617,7 +767,7 @@ TCHAR *CDInfo_GamePrefix()
|
||||
{
|
||||
static TCHAR buffer[128];
|
||||
|
||||
TCHAR g_sys_prefixes[3][20] = { _T("none_"), _T("ngcd_"), _T("pcecd_") };
|
||||
TCHAR g_sys_prefixes[4][20] = { _T("none_"), _T("ngcd_"), _T("pcecd_"), _T("segacd_") };
|
||||
const INT32 g_type = CDGameType();
|
||||
|
||||
_stprintf(buffer, _T("%s%s"), g_sys_prefixes[g_type], CDInfo_Text(DRV_NAME));
|
||||
|
||||
+7
-2
@@ -11,7 +11,8 @@
|
||||
enum {
|
||||
CDGAME_NONE = 0, // not a CD game
|
||||
CDGAME_NEOGEO, // Neo Geo CD
|
||||
CDGAME_PCE // PC Engine CD
|
||||
CDGAME_PCE, // PC Engine CD
|
||||
CDGAME_SEGACD // Sega CD / Mega-CD
|
||||
};
|
||||
|
||||
static inline INT32 CDGameType()
|
||||
@@ -23,6 +24,9 @@ static inline INT32 CDGameType()
|
||||
if (nHardware == HARDWARE_PCENGINE_PCE_CD) {
|
||||
return CDGAME_PCE;
|
||||
}
|
||||
if (nHardware == HARDWARE_SEGA_MEGACD) {
|
||||
return CDGAME_SEGACD;
|
||||
}
|
||||
return CDGAME_NONE;
|
||||
}
|
||||
|
||||
@@ -38,7 +42,8 @@ enum CDListPlatform {
|
||||
CDLIST_PLATFORM_UNKNOWN = 0,
|
||||
CDLIST_PLATFORM_NEOCD,
|
||||
CDLIST_PLATFORM_PCECD,
|
||||
CDLIST_PLATFORM_PCFX
|
||||
CDLIST_PLATFORM_PCFX,
|
||||
CDLIST_PLATFORM_SEGACD
|
||||
};
|
||||
|
||||
enum CDListSource {
|
||||
|
||||
+6
-2
@@ -177,6 +177,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
}
|
||||
|
||||
if ((((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_PCENGINE)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_PCE_CD)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_TG16)
|
||||
@@ -198,7 +199,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) && (bType == DAT_MEGADRIVE_ONLY)) {
|
||||
if (((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) && ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGACD) && (bType == DAT_MEGADRIVE_ONLY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -345,6 +346,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
}
|
||||
|
||||
remove_driver_leader(HARDWARE_SEGA_MEGADRIVE, 3, 1)
|
||||
remove_driver_leader(HARDWARE_SEGA_MEGACD, 3, 1)
|
||||
remove_driver_leader(HARDWARE_PCENGINE_TG16, 3, 1)
|
||||
remove_driver_leader(HARDWARE_COLECO, 3, 1)
|
||||
remove_driver_leader(HARDWARE_SEGA_SG1000, 5, 1)
|
||||
@@ -696,6 +698,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
}
|
||||
|
||||
if ((((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_PCENGINE)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_PCE_CD)
|
||||
|| ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_PCENGINE_TG16)
|
||||
@@ -717,7 +720,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) && (bType == DAT_MEGADRIVE_ONLY)) {
|
||||
if (((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) && ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGACD) && (bType == DAT_MEGADRIVE_ONLY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -797,6 +800,7 @@ INT32 write_datfile(INT32 bType, FILE* fDat)
|
||||
#endif
|
||||
|
||||
remove_driver_leader(HARDWARE_SEGA_MEGADRIVE, 3, 0)
|
||||
remove_driver_leader(HARDWARE_SEGA_MEGACD, 3, 0)
|
||||
remove_driver_leader(HARDWARE_PCENGINE_TG16, 3, 0)
|
||||
remove_driver_leader(HARDWARE_COLECO, 3, 0)
|
||||
remove_driver_leader(HARDWARE_SEGA_SG1000, 5, 0)
|
||||
|
||||
+4
-2
@@ -59,7 +59,8 @@ UINT8 *lua_hotkeys[] = {
|
||||
|
||||
#define HW_NEOGEO ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_NEOGEO) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_NEOCD) )
|
||||
#define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
|
||||
#define HW_MISC ( (! HW_NEOGEO) && (! HW_NES) && ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) != HARDWARE_SEGA_MEGADRIVE) )
|
||||
#define HW_MEGADRIVE ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD) )
|
||||
#define HW_MISC ( (! HW_NEOGEO) && (! HW_NES) && (! HW_MEGADRIVE) )
|
||||
#define SETS_VS ( (BurnDrvGetGenreFlags() & GBF_VSFIGHT) && ((BurnDrvGetFamilyFlags() & FBF_SF) || (BurnDrvGetFamilyFlags() & FBF_DSTLK) || (BurnDrvGetFamilyFlags() &FBF_PWRINST) || HW_NEOGEO) )
|
||||
|
||||
#ifdef BUILD_MACOS
|
||||
@@ -1102,7 +1103,7 @@ static void GameInpInitMacros()
|
||||
nMacroCount++;
|
||||
pgi++;
|
||||
}
|
||||
if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE) {
|
||||
if (HW_MEGADRIVE) {
|
||||
pgi->nInput = GIT_MACRO_AUTO;
|
||||
pgi->nType = BIT_DIGITAL;
|
||||
pgi->Macro.nMode = 0;
|
||||
@@ -2179,6 +2180,7 @@ tIniStruct gamehw_cfg[] = {
|
||||
{_T("MegaDrive hardware"), _T("config/presets/megadrive.ini"), true, { HARDWARE_SEGA_MEGADRIVE, 0 }, "\t\t\t<item list=\"megadriv\" name=\"" },
|
||||
{_T("PCE/SGX hardware"), _T("config/presets/pce.ini"), true, { HARDWARE_PCENGINE_PCENGINE, HARDWARE_PCENGINE_SGX, 0 }, "\t\t\t<item list=\"pce\" name=\"" },
|
||||
{_T("PCE CD hardware"), _T("config/presets/pcecd.ini"), true, { HARDWARE_PCENGINE_PCE_CD, 0 }, "\t\t\t<item list=\"pce_cd\" name=\"" },
|
||||
{_T("Sega CD hardware"), _T("config/presets/megadrive.ini"), true, { HARDWARE_SEGA_MEGACD, 0 }, "\t\t\t<item list=\"segacd\" name=\"" },
|
||||
{_T("TG16 hardware"), _T("config/presets/pce.ini"), true, { HARDWARE_PCENGINE_TG16, 0 }, "\t\t\t<item list=\"tg16\" name=\"" },
|
||||
{_T("MSX1 hardware"), _T("config/presets/msx.ini"), false, { HARDWARE_MSX, 0 }, "\t\t\t<item list=\"msx1_cart\" name=\"" },
|
||||
{_T("Coleco hardware"), _T("config/presets/coleco.ini"), true, { HARDWARE_COLECO, 0 }, "\t\t\t<item list=\"coleco\" name=\"" },
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "burner.h"
|
||||
#include "neocdlist.h"
|
||||
#include "pcecdlist.h"
|
||||
#include "segacdlist.h"
|
||||
int bDrvOkay = 0; // 1 if the Driver has been initted okay, and it's okay to use the BurnDrv functions
|
||||
|
||||
char szAppRomPaths[DIRS_MAX][MAX_PATH] = { { "/usr/local/share/roms/" }, { "roms/" }, };
|
||||
@@ -86,7 +87,7 @@ int DrvInit(int nDrvNum, bool bRestore)
|
||||
nBurnDrvActive = nDrvNum; // Set the driver number
|
||||
|
||||
INT32 nHardware = BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK;
|
||||
if (nHardware == HARDWARE_SNK_NEOCD || nHardware == HARDWARE_PCENGINE_PCE_CD) {
|
||||
if (nHardware == HARDWARE_SNK_NEOCD || nHardware == HARDWARE_PCENGINE_PCE_CD || nHardware == HARDWARE_SEGA_MEGACD) {
|
||||
if (CDEmuInit()) {
|
||||
printf("CD emu failed\n");
|
||||
return 1;
|
||||
@@ -98,6 +99,10 @@ int DrvInit(int nDrvNum, bool bRestore)
|
||||
NeoCDZRateChange();
|
||||
} else if (nHardware == HARDWARE_PCENGINE_PCE_CD) {
|
||||
PceCDInfo_Init();
|
||||
} else if (nHardware == HARDWARE_SEGA_MEGACD) {
|
||||
SegaCDInfo_Init();
|
||||
|
||||
NeoCDZRateChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SEGACDLIST_H_
|
||||
#define SEGACDLIST_H_
|
||||
|
||||
#include "cdlist.h"
|
||||
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
INT32 SegaCDInfo_Init();
|
||||
TCHAR* SegaCDInfo_Text(INT32 nText);
|
||||
void SegaCDInfo_Exit();
|
||||
#else
|
||||
static inline INT32 SegaCDInfo_Init() { return 0; }
|
||||
static inline TCHAR* SegaCDInfo_Text(INT32) { return NULL; }
|
||||
static inline void SegaCDInfo_Exit() { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// sega cd / mega-cd game detection via SHA1 of toc (toc-hash, printed in the log as "TOC Hash")
|
||||
// discs not listed here fall back to the disc header title and a short name made from the file name
|
||||
|
||||
struct sega_cd_game {
|
||||
TCHAR *sha1;
|
||||
TCHAR *name;
|
||||
TCHAR *id;
|
||||
TCHAR *year;
|
||||
TCHAR *company;
|
||||
};
|
||||
|
||||
static sega_cd_game segacd_games[] = {
|
||||
{ _T("1ba98761123bc815d3b4eecd072438b54e9dbd01"), _T("Dune (USA)"), _T("dune"), _T("1993"), _T("Virgin Games / Cryo") },
|
||||
{ _T("4c77e0b81a72aeb763c80dfa168a7700f39ab21f"), _T("Keio Flying Squadron (USA)"), _T("keiofs"), _T("1994"), _T("JVC / Victor Entertainment") },
|
||||
{ _T("cfea7696b9280bef7f82bb693435e86fd6c7c5f3"), _T("Lunar: The Silver Star (USA)"), _T("lunar"), _T("1993"), _T("Working Designs / Game Arts") },
|
||||
{ _T("ce0b4c6cf602cc471451e8a451792112bc4e40e1"), _T("Lunar: Eternal Blue (USA)"), _T("lunar2"), _T("1994"), _T("Working Designs / Game Arts") },
|
||||
{ _T("f321fffaf0e8c3bcd42af118918cf0a73e83f806"), _T("Mortal Kombat Kanzenban (Japan)"), _T("mkkanzen"), _T("1994"), _T("Acclaim / Probe Software") },
|
||||
{ _T("2d252bd6afc1ef76db0769505a7bcdd4cec77cec"), _T("Puggsy (USA)"), _T("puggsy"), _T("1994"), _T("Psygnosis") },
|
||||
{ _T("7c391316df9cb6b22d1537393ce711a94f036130"), _T("Sol-Feace (Europe)"), _T("solfeace"), _T("1992"), _T("Wolf Team") },
|
||||
{ _T("46eff97ebe56033ede2a27492541b3e597023fd8"), _T("SoulStar + Battlecorps (Europe) (Demo)"), _T("soulstbcdemo"), _T("1994"), _T("Core Design") },
|
||||
};
|
||||
@@ -246,6 +246,10 @@ static INT32 CDLibraryPlatformEnabled(INT32 nPlatform)
|
||||
#ifdef BUILD_PCE
|
||||
if (nPlatform == CDLIST_PLATFORM_PCECD)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
if (nPlatform == CDLIST_PLATFORM_SEGACD)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "burner.h"
|
||||
#include "neocdlist.h"
|
||||
#include "pcecdlist.h"
|
||||
#include "segacdlist.h"
|
||||
|
||||
int bDrvOkay = 0; // 1 if the Driver has been initted okay, and it's okay to use the BurnDrv functions
|
||||
|
||||
@@ -173,7 +174,7 @@ static void NeoCDZRateChange()
|
||||
{
|
||||
if (nAudSampleRate[nAudSelect] != 44100) {
|
||||
nNeoCDZnAudSampleRateSave = nAudSampleRate[nAudSelect];
|
||||
bprintf(PRINT_IMPORTANT, _T("Switching sound rate to 44100hz (from %dhz) as required by NeoGeo & PCE CD\n"), nNeoCDZnAudSampleRateSave);
|
||||
bprintf(PRINT_IMPORTANT, _T("Switching sound rate to 44100hz (from %dhz) as required by NeoGeo, PCE & Sega CD\n"), nNeoCDZnAudSampleRateSave);
|
||||
nAudSampleRate[nAudSelect] = 44100; // force 44100hz for CDDA
|
||||
}
|
||||
}
|
||||
@@ -200,7 +201,7 @@ int DrvInit(int nDrvNum, bool bRestore)
|
||||
}
|
||||
|
||||
INT32 nHardware = BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK;
|
||||
if (nHardware == HARDWARE_SNK_NEOCD || nHardware == HARDWARE_PCENGINE_PCE_CD) {
|
||||
if (nHardware == HARDWARE_SNK_NEOCD || nHardware == HARDWARE_PCENGINE_PCE_CD || nHardware == HARDWARE_SEGA_MEGACD) {
|
||||
if (CDEmuInit()) {
|
||||
FBAPopupAddText(PUF_TEXT_DEFAULT, MAKEINTRESOURCE(IDS_ERR_CDEMU_INI_FAIL));
|
||||
FBAPopupDisplay(PUF_TYPE_ERROR);
|
||||
@@ -215,6 +216,9 @@ int DrvInit(int nDrvNum, bool bRestore)
|
||||
} else if (nHardware == HARDWARE_PCENGINE_PCE_CD) {
|
||||
PceCDInfo_Init();
|
||||
NeoCDZRateChange();
|
||||
} else if (nHardware == HARDWARE_SEGA_MEGACD) {
|
||||
SegaCDInfo_Init();
|
||||
NeoCDZRateChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ TCHAR szNeoCDCoverDir[MAX_PATH] = _T("support/cdcovers/");
|
||||
TCHAR szNeoCDPreviewDir[MAX_PATH] = _T("support/cdpreviews/");
|
||||
TCHAR szNeoCDGamesDir[MAX_PATH] = _T("cdiso/");
|
||||
|
||||
#if defined(BUILD_NEOGEO) || defined(BUILD_PCE)
|
||||
#if defined(BUILD_NEOGEO) || defined(BUILD_PCE) || defined(BUILD_MEGADRIVE)
|
||||
|
||||
struct PNGRESOLUTION { INT32 nWidth; INT32 nHeight; };
|
||||
|
||||
@@ -243,7 +243,7 @@ static void LoadEntryPreview(const CDLibraryEntry* pEntry, INT32 nSide, void** p
|
||||
const TCHAR* pszName = GetPreviewName(pEntry);
|
||||
TCHAR szPath[MAX_PATH];
|
||||
TCHAR tszName[MAX_PATH];
|
||||
_stprintf(tszName, _T("%s%s"), (pEntry->nPlatform == CDLIST_PLATFORM_PCECD) ? _T("pcecd_") : _T("ngcd_"), pszName);
|
||||
_stprintf(tszName, _T("%s%s"), (pEntry->nPlatform == CDLIST_PLATFORM_PCECD) ? _T("pcecd_") : ((pEntry->nPlatform == CDLIST_PLATFORM_SEGACD) ? _T("segacd_") : _T("ngcd_")), pszName);
|
||||
|
||||
if (!nSide) {
|
||||
BuildPreviewPath(szPath, MAX_PATH, szNeoCDCoverDir, tszName);
|
||||
@@ -308,6 +308,8 @@ static const TCHAR* PlatformText(INT32 nPlatform)
|
||||
return _T("Neo Geo CD");
|
||||
if (nPlatform == CDLIST_PLATFORM_PCECD)
|
||||
return _T("PCE CD");
|
||||
if (nPlatform == CDLIST_PLATFORM_SEGACD)
|
||||
return _T("Sega CD");
|
||||
|
||||
return _T("Unknown");
|
||||
}
|
||||
@@ -606,6 +608,20 @@ static void ShowZoom(INT32 nSide)
|
||||
nZoomPngSize = 0;
|
||||
}
|
||||
|
||||
static INT32 PlatformAvailable(INT32 nPlatform)
|
||||
{
|
||||
#ifdef BUILD_NEOGEO
|
||||
if (nPlatform == CDLIST_PLATFORM_NEOCD) return 1;
|
||||
#endif
|
||||
#ifdef BUILD_PCE
|
||||
if (nPlatform == CDLIST_PLATFORM_PCECD) return 1;
|
||||
#endif
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
if (nPlatform == CDLIST_PLATFORM_SEGACD) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool SelectForPlay()
|
||||
{
|
||||
const CDLibraryEntry* pEntry = GetLibraryEntry(nSelectedItem);
|
||||
@@ -613,13 +629,7 @@ static bool SelectForPlay()
|
||||
MessageBox(hNeoCDWnd, _T("Select a CD image first."), _T(APP_TITLE), MB_OK | MB_ICONWARNING);
|
||||
return false;
|
||||
}
|
||||
#if !defined(BUILD_NEOGEO)
|
||||
if (pEntry->nPlatform != CDLIST_PLATFORM_PCECD) {
|
||||
#elif !defined(BUILD_PCE)
|
||||
if (pEntry->nPlatform != CDLIST_PLATFORM_NEOCD) {
|
||||
#else
|
||||
if (pEntry->nPlatform != CDLIST_PLATFORM_NEOCD && pEntry->nPlatform != CDLIST_PLATFORM_PCECD) {
|
||||
#endif
|
||||
if (!PlatformAvailable(pEntry->nPlatform)) {
|
||||
MessageBox(hNeoCDWnd, _T("The required CD driver is unavailable in this build."), _T(APP_TITLE), MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
@@ -629,6 +639,12 @@ static bool SelectForPlay()
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
if (pEntry->nPlatform == CDLIST_PLATFORM_SEGACD && BurnDrvGetIndex((char*)"md_segacd") < 0) {
|
||||
MessageBox(hNeoCDWnd, _T("The Sega CD driver is unavailable."), _T(APP_TITLE), MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#ifdef BUILD_PCE
|
||||
if (pEntry->nPlatform == CDLIST_PLATFORM_PCECD && BurnDrvGetIndex((char*)"pce_scdsys") < 0) {
|
||||
MessageBox(hNeoCDWnd, _T("The PCE CD driver is unavailable."), _T(APP_TITLE), MB_OK | MB_ICONERROR);
|
||||
@@ -709,6 +725,9 @@ static INT_PTR CALLBACK NeoCDList_WndProc(HWND hDlg, UINT nMessage, WPARAM wPara
|
||||
#endif
|
||||
#ifdef BUILD_PCE
|
||||
if (nPlatform == CDLIST_PLATFORM_PCECD) BurnerLoadDriver(_T("pce_scdsys"));
|
||||
#endif
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
if (nPlatform == CDLIST_PLATFORM_SEGACD) BurnerLoadDriver(_T("md_segacd"));
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Screen Window
|
||||
#include "burner.h"
|
||||
#include "pcecdlist.h"
|
||||
#include "segacdlist.h"
|
||||
#include <process.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
@@ -22,6 +23,17 @@ static void SetPCECDTitle()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
static void SetSegaCDTitle()
|
||||
{
|
||||
TCHAR szText[1024] = _T("");
|
||||
TCHAR* pszTitle = SegaCDInfo_Text(DRV_FULLNAME);
|
||||
_sntprintf(szText, _countof(szText), _T(APP_TITLE) _T(" v%.20s") _T(SEPERATOR_1) _T("%s") _T(SEPERATOR_1) _T("%s"), szAppBurnVer, BurnDrvGetText(DRV_FULLNAME), pszTitle ? pszTitle : FBALoadStringEx(hAppInst, IDS_UNIDENTIFIED_CD, true));
|
||||
szText[_countof(szText) - 1] = _T('\0');
|
||||
SetWindowText(hScrnWnd, szText);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_NEOGEO
|
||||
static void SetNeoCDTitle(TCHAR* pszTitle)
|
||||
{
|
||||
@@ -1100,6 +1112,7 @@ static t_hw_Struct scrn_gamehw_cfg[] = {
|
||||
{ "neogeo", { HARDWARE_SNK_NEOGEO, HARDWARE_SNK_MVS, HARDWARE_SNK_DEDICATED_PCB, 0 } },
|
||||
{ "neogeocd", { HARDWARE_SNK_NEOCD, 0 } },
|
||||
{ "pcecd", { HARDWARE_PCENGINE_PCE_CD, 0 } },
|
||||
{ "segacd", { HARDWARE_SEGA_MEGACD, 0 } },
|
||||
{ "arcade", { ~0, 0 } }, // default, if not found above
|
||||
{ "\0", { 0 } } // end
|
||||
};
|
||||
@@ -1608,6 +1621,9 @@ INT32 BurnerQuickLoad(const INT32 nMode, const TCHAR* pszSelect)
|
||||
case CDLIST_PLATFORM_PCECD:
|
||||
pszDrvName = _T("pce_scdsys");
|
||||
break;
|
||||
case CDLIST_PLATFORM_SEGACD:
|
||||
pszDrvName = _T("md_segacd");
|
||||
break;
|
||||
default:
|
||||
FBAPopupAddText(PUF_TEXT_DEFAULT, MAKEINTRESOURCE(IDS_ERR_CD_IMAGE_IDENTIFY), pszSelect);
|
||||
FBAPopupDisplay(PUF_TYPE_ERROR);
|
||||
@@ -4727,6 +4743,12 @@ int ScrnTitle()
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef BUILD_MEGADRIVE
|
||||
if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD) {
|
||||
SetSegaCDTitle();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
_stprintf(szText, _T(APP_TITLE) _T( " v%.20s") _T(SEPERATOR_1) _T("[%s]"), szAppBurnVer, FBALoadStringEx(hAppInst, IDS_SCRN_NOGAME, true));
|
||||
|
||||
@@ -2056,7 +2056,7 @@ void LoadDrvIcons()
|
||||
|
||||
// By hardwares
|
||||
if (bIconsByHardwares) {
|
||||
if ((nCode & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE) {
|
||||
if ((nCode & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGADRIVE || (nCode & HARDWARE_PUBLIC_MASK) == HARDWARE_SEGA_MEGACD) {
|
||||
hDrvIcon[nDrvIndex] = pIconsCache[nDrvCount + ICON_MEGADRIVE]; continue;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1756,6 +1756,18 @@ static UINT8* cdimgReadTOC(INT32 track)
|
||||
return TOCEntry;
|
||||
}
|
||||
|
||||
if (track & CDEmuTOC_TRACKEND) {
|
||||
track = bcd(track & 0xff);
|
||||
if (track >= cdimgTOC->FirstTrack && track <= cdimgTOC->LastTrack) {
|
||||
TOCEntry[0] = cdimgTOC->TrackData[track - 1].EndAddress[1];
|
||||
TOCEntry[1] = cdimgTOC->TrackData[track - 1].EndAddress[2];
|
||||
TOCEntry[2] = cdimgTOC->TrackData[track - 1].EndAddress[3];
|
||||
TOCEntry[3] = cdimgTOC->TrackData[track - 1].Control >> 4;
|
||||
}
|
||||
|
||||
return TOCEntry;
|
||||
}
|
||||
|
||||
track = bcd(track);
|
||||
if (track >= cdimgTOC->FirstTrack && track <= cdimgTOC->LastTrack) {
|
||||
TOCEntry[0] = cdimgTOC->TrackData[track - 1].Address[1];
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
// CD emulation module
|
||||
|
||||
enum CDEmuStatusValue { idle = 0, reading, playing, paused, seeking, fastforward, fastreverse };
|
||||
enum CDEmuReadTOCFlags { CDEmuTOC_FIRSTLAST = 0x1000, CDEmuTOC_LASTMSF, CDEmuTOC_FIRSTINDEX, CDEmuTOC_ENDOFDISC };
|
||||
// CDEmuTOC_TRACKEND is or'ed with a bcd track number: msf where the track ends (start of the next track's pregap)
|
||||
enum CDEmuReadTOCFlags { CDEmuTOC_FIRSTLAST = 0x1000, CDEmuTOC_LASTMSF, CDEmuTOC_FIRSTINDEX, CDEmuTOC_ENDOFDISC, CDEmuTOC_TRACKEND = 0x2000 };
|
||||
|
||||
extern TCHAR CDEmuImage[MAX_PATH];
|
||||
extern UINT8 CDEmuImageTOCSHA1[MAX_PATH];
|
||||
|
||||
Reference in new issue
Block a user