mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-28 12:11:50 +01:00
Merge git://github.com/ekeeke/Genesis-Plus-GX
This commit is contained in:
commit
5e11a35fe7
@ -67,6 +67,8 @@ static void mapper_sf004_w(uint32 address, uint32 data);
|
|||||||
static uint32 mapper_sf004_r(uint32 address);
|
static uint32 mapper_sf004_r(uint32 address);
|
||||||
static void mapper_t5740_w(uint32 address, uint32 data);
|
static void mapper_t5740_w(uint32 address, uint32 data);
|
||||||
static uint32 mapper_t5740_r(uint32 address);
|
static uint32 mapper_t5740_r(uint32 address);
|
||||||
|
static uint32 mapper_smw_64_r(uint32 address);
|
||||||
|
static void mapper_smw_64_w(uint32 address, uint32 data);
|
||||||
static void mapper_realtec_w(uint32 address, uint32 data);
|
static void mapper_realtec_w(uint32 address, uint32 data);
|
||||||
static void mapper_seganet_w(uint32 address, uint32 data);
|
static void mapper_seganet_w(uint32 address, uint32 data);
|
||||||
static void mapper_32k_w(uint32 data);
|
static void mapper_32k_w(uint32 data);
|
||||||
@ -704,6 +706,38 @@ void md_cart_init(void)
|
|||||||
zbank_memory_map[i].write = zbank_unused_w;
|
zbank_memory_map[i].write = zbank_unused_w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((*(uint16 *)(cart.rom + 0x08) == 0x6000) && (*(uint16 *)(cart.rom + 0x0a) == 0x01f6))
|
||||||
|
{
|
||||||
|
/* Super Mario World 64 (unlicensed) mapper */
|
||||||
|
for (i=0x08; i<0x10; i++)
|
||||||
|
{
|
||||||
|
/* lower 512KB mirrored */
|
||||||
|
m68k.memory_map[i].base = cart.rom + ((i & 7) << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0x10; i<0x40; i++)
|
||||||
|
{
|
||||||
|
/* unused area */
|
||||||
|
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||||
|
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||||
|
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||||
|
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||||
|
zbank_memory_map[i].read = m68k_read_bus_8;
|
||||||
|
zbank_memory_map[i].write = zbank_unused_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0x60; i<0x70; i++)
|
||||||
|
{
|
||||||
|
/* custom hardware */
|
||||||
|
m68k.memory_map[i].base = cart.rom + 0x0f0000;
|
||||||
|
m68k.memory_map[i].read8 = ((i & 0x07) < 0x04) ? NULL : mapper_smw_64_r;
|
||||||
|
m68k.memory_map[i].read16 = ((i & 0x07) < 0x04) ? NULL : mapper_smw_64_r;
|
||||||
|
m68k.memory_map[i].write8 = mapper_smw_64_w;
|
||||||
|
m68k.memory_map[i].write16 = mapper_smw_64_w;
|
||||||
|
zbank_memory_map[i].read = ((i & 0x07) < 0x04) ? NULL : mapper_smw_64_r;
|
||||||
|
zbank_memory_map[i].write = mapper_smw_64_w;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (cart.romsize > 0x400000)
|
else if (cart.romsize > 0x400000)
|
||||||
{
|
{
|
||||||
/* assume linear ROM mapper without bankswitching (max. 10MB) */
|
/* assume linear ROM mapper without bankswitching (max. 10MB) */
|
||||||
@ -1271,6 +1305,173 @@ static uint32 mapper_t5740_r(uint32 address)
|
|||||||
return READ_BYTE(cart.rom, address);
|
return READ_BYTE(cart.rom, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Super Mario World 64 (unlicensed) mapper
|
||||||
|
*/
|
||||||
|
static void mapper_smw_64_w(uint32 address, uint32 data)
|
||||||
|
{
|
||||||
|
/* internal registers (saved to backup RAM) */
|
||||||
|
switch ((address >> 16) & 0x07)
|
||||||
|
{
|
||||||
|
case 0x00: /* $60xxxx */
|
||||||
|
{
|
||||||
|
if (address & 2)
|
||||||
|
{
|
||||||
|
/* $600003 data write mode ? */
|
||||||
|
switch (sram.sram[0x00] & 0x07)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
{
|
||||||
|
/* update value returned at $660001-$660003 */
|
||||||
|
sram.sram[0x06] = ((sram.sram[0x06] ^ sram.sram[0x01]) ^ data) & 0xFE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x01:
|
||||||
|
{
|
||||||
|
/* update value returned at $660005-$660007 */
|
||||||
|
sram.sram[0x07] = data & 0xFE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x07:
|
||||||
|
{
|
||||||
|
/* update selected ROM bank (upper 512K) mapped at $610000-$61ffff */
|
||||||
|
m68k.memory_map[0x61].base = m68k.memory_map[0x69].base = cart.rom + 0x080000 + ((data & 0x1c) << 14);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* unknown mode */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* $600003 data register */
|
||||||
|
sram.sram[0x01] = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* $600001 ctrl register */
|
||||||
|
sram.sram[0x00] = data;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x01: /* $61xxxx */
|
||||||
|
{
|
||||||
|
if (address & 2)
|
||||||
|
{
|
||||||
|
/* $610003 ctrl register */
|
||||||
|
sram.sram[0x02] = data;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x04: /* $64xxxx */
|
||||||
|
{
|
||||||
|
if (address & 2)
|
||||||
|
{
|
||||||
|
/* $640003 data register */
|
||||||
|
sram.sram[0x04] = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* $640001 data register */
|
||||||
|
sram.sram[0x03] = data;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x06: /* $66xxxx */
|
||||||
|
{
|
||||||
|
/* unknown */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x07: /* $67xxxx */
|
||||||
|
{
|
||||||
|
if (!(address & 2))
|
||||||
|
{
|
||||||
|
/* $670001 ctrl register */
|
||||||
|
sram.sram[0x05] = data;
|
||||||
|
|
||||||
|
/* upper 512K ROM bank-switching enabled ? */
|
||||||
|
if (sram.sram[0x02] & 0x80)
|
||||||
|
{
|
||||||
|
/* update selected ROM bank (upper 512K) mapped at $600000-$60ffff */
|
||||||
|
m68k.memory_map[0x60].base = m68k.memory_map[0x68].base = cart.rom + 0x080000 + ((data & 0x1c) << 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: /* not used */
|
||||||
|
{
|
||||||
|
m68k_unused_8_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 mapper_smw_64_r(uint32 address)
|
||||||
|
{
|
||||||
|
/* internal registers (saved to backup RAM) */
|
||||||
|
switch ((address >> 16) & 0x03)
|
||||||
|
{
|
||||||
|
case 0x02: /* $66xxxx */
|
||||||
|
{
|
||||||
|
switch ((address >> 1) & 7)
|
||||||
|
{
|
||||||
|
case 0x00: return sram.sram[0x06];
|
||||||
|
case 0x01: return sram.sram[0x06] + 1;
|
||||||
|
case 0x02: return sram.sram[0x07];
|
||||||
|
case 0x03: return sram.sram[0x07] + 1;
|
||||||
|
case 0x04: return sram.sram[0x08];
|
||||||
|
case 0x05: return sram.sram[0x08] + 1;
|
||||||
|
case 0x06: return sram.sram[0x08] + 2;
|
||||||
|
case 0x07: return sram.sram[0x08] + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x03: /* $67xxxx */
|
||||||
|
{
|
||||||
|
uint8 data = (sram.sram[0x02] & 0x80) ? ((sram.sram[0x05] & 0x40) ? (sram.sram[0x03] & sram.sram[0x04]) : (sram.sram[0x03] ^ 0xFF)) : 0x00;
|
||||||
|
|
||||||
|
if (address & 2)
|
||||||
|
{
|
||||||
|
/* $670003 */
|
||||||
|
data &= 0x7f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* $66xxxx data registers update */
|
||||||
|
if (sram.sram[0x05] & 0x80)
|
||||||
|
{
|
||||||
|
if (sram.sram[0x05] & 0x20)
|
||||||
|
{
|
||||||
|
/* update $660009-$66000f data register */
|
||||||
|
sram.sram[0x08] = (sram.sram[0x04] << 2) & 0xFC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* update $660001-$660003 data register */
|
||||||
|
sram.sram[0x06] = (sram.sram[0x01] ^ (sram.sram[0x03] << 1)) & 0xFE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: /* 64xxxx-$65xxxx */
|
||||||
|
{
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Realtec ROM bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter)
|
Realtec ROM bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter)
|
||||||
(Note: register usage is inverted in TascoDlx documentation)
|
(Note: register usage is inverted in TascoDlx documentation)
|
||||||
|
@ -84,6 +84,12 @@ static const uint16 toc_lunar[52] =
|
|||||||
685, 3167
|
685, 3167
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint32 toc_shadow[15] =
|
||||||
|
{
|
||||||
|
10226, 70054, 11100, 12532, 12444, 11923, 10059, 10167, 10138, 13792,
|
||||||
|
11637, 2547, 2521, 3856, 900
|
||||||
|
};
|
||||||
|
|
||||||
/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
|
/* supported WAVE file header (16-bit stereo samples @44.1kHz) */
|
||||||
static const unsigned char waveHeader[32] =
|
static const unsigned char waveHeader[32] =
|
||||||
{
|
{
|
||||||
@ -91,7 +97,7 @@ static const unsigned char waveHeader[32] =
|
|||||||
0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61
|
0x44,0xac,0x00,0x00,0x10,0xb1,0x02,0x00,0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61
|
||||||
};
|
};
|
||||||
|
|
||||||
/* supported file extensions */
|
/* supported WAVE file extensions */
|
||||||
static const char extensions[10][16] =
|
static const char extensions[10][16] =
|
||||||
{
|
{
|
||||||
"%02d.wav",
|
"%02d.wav",
|
||||||
@ -595,7 +601,7 @@ int cdd_load(char *filename, char *header)
|
|||||||
/* Simulate audio tracks if none found */
|
/* Simulate audio tracks if none found */
|
||||||
if (cdd.toc.last == 1)
|
if (cdd.toc.last == 1)
|
||||||
{
|
{
|
||||||
/* Some games require specific TOC infos */
|
/* Some games require exact TOC infos */
|
||||||
if (strstr(header + 0x180,"T-95035") != NULL)
|
if (strstr(header + 0x180,"T-95035") != NULL)
|
||||||
{
|
{
|
||||||
/* Snatcher */
|
/* Snatcher */
|
||||||
@ -622,6 +628,19 @@ int cdd_load(char *filename, char *header)
|
|||||||
}
|
}
|
||||||
while (cdd.toc.last < 52);
|
while (cdd.toc.last < 52);
|
||||||
}
|
}
|
||||||
|
else if (strstr(header + 0x180,"T-113045") != NULL)
|
||||||
|
{
|
||||||
|
/* Shadow of the Beast II */
|
||||||
|
cdd.toc.last = cdd.toc.end = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cdd.toc.tracks[cdd.toc.last].start = cdd.toc.end;
|
||||||
|
cdd.toc.tracks[cdd.toc.last].end = cdd.toc.tracks[cdd.toc.last].start + toc_shadow[cdd.toc.last];
|
||||||
|
cdd.toc.end = cdd.toc.tracks[cdd.toc.last].end;
|
||||||
|
cdd.toc.last++;
|
||||||
|
}
|
||||||
|
while (cdd.toc.last < 15);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* default TOC (99 tracks & 2s per audio tracks) */
|
/* default TOC (99 tracks & 2s per audio tracks) */
|
||||||
@ -1063,9 +1082,10 @@ void cdd_process(void)
|
|||||||
{
|
{
|
||||||
/* Fixes a few games hanging during intro because they expect data to be read with some delay */
|
/* Fixes a few games hanging during intro because they expect data to be read with some delay */
|
||||||
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */
|
/* Wolf Team games (Anet Futatabi, Cobra Command, Road Avenger & Time Gal) need at least 6 interrupts delay */
|
||||||
/* Radical Rex need at least one interrupt delay */
|
/* Radical Rex needs at least one interrupt delay */
|
||||||
/* Jeopardy need at least 9 interrupts delay (without counting seek time delay below )*/
|
/* Jeopardy needs at least 9 interrupts delay */
|
||||||
cdd.latency = 9;
|
/* Space Adventure Cobra (2nd morgue scene) needs at least 13 interrupts delay */
|
||||||
|
cdd.latency = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update current track index */
|
/* update current track index */
|
||||||
@ -1161,7 +1181,7 @@ void cdd_process(void)
|
|||||||
/* no audio track playing */
|
/* no audio track playing */
|
||||||
scd.regs[0x36>>1].byte.h = 0x01;
|
scd.regs[0x36>>1].byte.h = 0x01;
|
||||||
|
|
||||||
/* update status (TODO: figure what is returned in RS1-RS8) */
|
/* update status */
|
||||||
cdd.status = CD_READY;
|
cdd.status = CD_READY;
|
||||||
scd.regs[0x38>>1].w = CD_SEEK << 8;
|
scd.regs[0x38>>1].w = CD_SEEK << 8;
|
||||||
scd.regs[0x3a>>1].w = 0x0000;
|
scd.regs[0x3a>>1].w = 0x0000;
|
||||||
@ -1176,7 +1196,7 @@ void cdd_process(void)
|
|||||||
/* no audio track playing */
|
/* no audio track playing */
|
||||||
scd.regs[0x36>>1].byte.h = 0x01;
|
scd.regs[0x36>>1].byte.h = 0x01;
|
||||||
|
|
||||||
/* update status (TODO: figure what is returned in RS1-RS8) */
|
/* update status */
|
||||||
cdd.status = CD_READY;
|
cdd.status = CD_READY;
|
||||||
scd.regs[0x38>>1].w = CD_READY << 8;
|
scd.regs[0x38>>1].w = CD_READY << 8;
|
||||||
scd.regs[0x3a>>1].w = 0x0000;
|
scd.regs[0x3a>>1].w = 0x0000;
|
||||||
@ -1203,7 +1223,7 @@ void cdd_process(void)
|
|||||||
cdd.scanOffset = CD_SCAN_SPEED;
|
cdd.scanOffset = CD_SCAN_SPEED;
|
||||||
cdd.status = CD_SCAN;
|
cdd.status = CD_SCAN;
|
||||||
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
||||||
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A;
|
||||||
scd.regs[0x3c>>1].w = 0x0000;
|
scd.regs[0x3c>>1].w = 0x0000;
|
||||||
scd.regs[0x3e>>1].w = 0x0000;
|
scd.regs[0x3e>>1].w = 0x0000;
|
||||||
scd.regs[0x40>>1].byte.h = 0x00;
|
scd.regs[0x40>>1].byte.h = 0x00;
|
||||||
@ -1215,7 +1235,7 @@ void cdd_process(void)
|
|||||||
cdd.scanOffset = -CD_SCAN_SPEED;
|
cdd.scanOffset = -CD_SCAN_SPEED;
|
||||||
cdd.status = CD_SCAN;
|
cdd.status = CD_SCAN;
|
||||||
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
scd.regs[0x38>>1].w = (CD_SCAN << 8) | 0x02;
|
||||||
scd.regs[0x3a>>1].w = lut_BCD_16[cdd.index+1];
|
scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A;
|
||||||
scd.regs[0x3c>>1].w = 0x0000;
|
scd.regs[0x3c>>1].w = 0x0000;
|
||||||
scd.regs[0x3e>>1].w = 0x0000;
|
scd.regs[0x3e>>1].w = 0x0000;
|
||||||
scd.regs[0x40>>1].byte.h = 0x00;
|
scd.regs[0x40>>1].byte.h = 0x00;
|
||||||
|
Loading…
Reference in New Issue
Block a user