improved cartridge emulation (SRAM mapping & detection, ROM mirroring)

fixed Lock-ON option configuration
This commit is contained in:
ekeeke31 2009-08-07 17:30:14 +00:00
parent 5b888e725b
commit 5d1f29637e
5 changed files with 56 additions and 52 deletions

View File

@ -126,6 +126,8 @@ static uint8 mem_chunk[0x10000];
/* cart hardware detection */
void cart_hw_init()
{
int i;
/***************************************************************************************************************
CARTRIDGE ROM MIRRORING
***************************************************************************************************************
@ -176,6 +178,7 @@ void cart_hw_init()
while (cart.romsize > size) size <<= 1;
/* total ROM size is not a factor of 2 */
/* TODO: handle more possible ROM configurations (using cartridge database ???) */
if ((size < MAXROMSIZE) && (cart.romsize < size))
{
/* two chips with different size */
@ -200,20 +203,15 @@ void cart_hw_init()
}
/* ROM is mirrored each 2^k bytes */
int i = size;
while (i < 0x400000)
{
memcpy(cart.rom + i, cart.rom, size);
i += size;
}
cart.mask = size -1;
/**********************************************
DEFAULT CARTRIDGE MAPPING
***********************************************/
for (i=0; i<0x40; i++)
{
/* cartridge ROM */
m68k_memory_map[i].base = cart.rom + (i<<16);
m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask);
m68k_memory_map[i].read8 = NULL;
m68k_memory_map[i].read16 = NULL;
m68k_memory_map[i].write8 = m68k_unused_8_w;
@ -325,7 +323,7 @@ void cart_hw_init()
break;
case TYPE_SK:
/* be sure we have enough place to copy everything */
/* be sure we have enough place to store both ROMs */
if (cart.romsize < 0x700000)
{
/* load Sonic & Knuckles ROM (2 MBytes) */
@ -340,16 +338,11 @@ void cart_hw_init()
fread(cart.rom+0x900000,1,0x40000,f);
fclose(f);
/* ROM is mirrored each 256K */
memcpy(cart.rom+0x940000,cart.rom+0x900000,0x40000);
memcpy(cart.rom+0x980000,cart.rom+0x900000,0x40000);
memcpy(cart.rom+0x9C0000,cart.rom+0x900000,0x40000);
#ifdef LSB_FIRST
/* Byteswap ROM */
int i;
uint8 temp;
for(i = 0; i < 0x300000; i += 2)
for(i = 0; i < 0x240000; i += 2)
{
temp = cart.rom[i+0x700000];
cart.rom[i+0x700000] = cart.rom[i+1+0x700000];
@ -357,6 +350,10 @@ void cart_hw_init()
}
#endif
/*$000000-$1fffff is mapped to S&K ROM */
for (i=0x00; i<0x20; i++)
m68k_memory_map[i].base = (cart.rom + 0x700000) + (i<<16);
cart.lock_on = 1;
}
@ -449,7 +446,7 @@ void cart_hw_reset()
if (cart.hw.bankshift)
{
for (i=0x00; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + (i<<16);
m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask);
}
/* Realtec mapper */
@ -482,10 +479,8 @@ void cart_hw_reset()
if (cart.lock_on)
{
/* reset memory map */
for (i=0x00; i<0x20; i++)
m68k_memory_map[i].base = cart.rom + 0x700000 + (i<<16);
for (i=0x30; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + (i<<16);
m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask);
}
break;
@ -516,41 +511,52 @@ static void sega_mapper_w(uint32 address, uint32 data)
/* ROM/SRAM switch (Phantasy Star IV, Story of Thor/Beyond Oasis, Sonic 3 & Knuckles) */
if (data & 1)
{
/* SRAM enabled */
m68k_memory_map[0x20].base = sram.sram;
/* $200000-$3fffff is mapped to SRAM (only if SRAM exists) */
if (sram.on)
{
for (i=0x20; i<0x40; i++)
m68k_memory_map[i].base = sram.sram;
if (data & 2)
{
/* SRAM write disabled */
m68k_memory_map[0x20].write8 = m68k_unused_8_w;
m68k_memory_map[0x20].write16 = m68k_unused_16_w;
zbank_memory_map[0x20].write = zbank_unused_w;
}
else
{
/* SRAM write enabled */
m68k_memory_map[0x20].write8 = NULL;
m68k_memory_map[0x20].write16 = NULL;
zbank_memory_map[0x20].write = NULL;
if (data & 2)
{
/* SRAM write disabled */
for (i=0x20; i<0x40; i++)
{
m68k_memory_map[i].write8 = m68k_unused_8_w;
m68k_memory_map[i].write16 = m68k_unused_16_w;
zbank_memory_map[i].write = zbank_unused_w;
}
}
else
{
/* SRAM write enabled */
for (i=0x20; i<0x40; i++)
{
m68k_memory_map[0x20].write8 = NULL;
m68k_memory_map[0x20].write16 = NULL;
zbank_memory_map[0x20].write = NULL;
}
}
}
if (cart.lock_on)
{
/* enable UPMEM chip at $300000-$3fffff */
for (i=0x30; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + 0x600000 + (i<<16);
m68k_memory_map[i].base = (cart.rom + 0x900000) + ((i & 3)<<16);
}
}
else
{
/* ROM enabled */
m68k_memory_map[0x20].base = cart.rom + 0x200000;
for (i=0x20; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask);
if (cart.lock_on)
{
/* enable cartridge ROM at $300000-$3fffff */
for (i=0x30; i<0x40; i++)
m68k_memory_map[i].base = cart.rom + (i<<16);
m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask);
}
}
break;

View File

@ -28,9 +28,9 @@
#define _CART_HW_H_
/* Lock-ON cartridge type */
#define TYPE_GG 0x10 /* Game Genie */
#define TYPE_AR 0x20 /* Action Replay (Pro) */
#define TYPE_SK 0x40 /* Sonic & Knuckles */
#define TYPE_GG 0x01 /* Game Genie */
#define TYPE_AR 0x02 /* Action Replay (Pro) */
#define TYPE_SK 0x03 /* Sonic & Knuckles */
/* Cartridge extra hardware */
typedef struct
@ -52,6 +52,7 @@ typedef struct
{
uint8 *rom; /* ROM data */
uint8 *base; /* ROM area (slot 0) */
uint32 mask; /* mask ROM */
uint32 lock_on; /* 1: Lock-On enabled */
uint32 romsize; /* ROM size */
T_CART_HW hw; /* Custom hardware */

View File

@ -100,7 +100,6 @@ void eeprom_init()
{
sram.custom = 1;
sram.on = 1;
sram.write = 1;
memcpy(&eeprom.type, &database[i].type, sizeof(T_EEPROM_TYPE));
}
}
@ -114,8 +113,7 @@ void eeprom_init()
{
sram.custom = 1;
sram.on = 1;
sram.write = 1;
/* set SEGA mapper as default */
memcpy(&eeprom.type, &database[9].type, sizeof(T_EEPROM_TYPE));
}

View File

@ -57,6 +57,7 @@ void sram_init()
sram.end = sram.start + 0xffff;
sram.start &= 0xfffffffe;
sram.end |= 1;
sram.on = 1;
}
else
{
@ -66,24 +67,24 @@ void sram_init()
}
/* set SRAM ON by default when ROM is not mapped */
if (cart.romsize <= sram.start)
{
sram.on = 1;
sram.write = 1;
}
if (cart.romsize <= sram.start) sram.on = 1;
/* Some games with bad header or specific configuration */
if (strstr(rominfo.product,"T-113016") != NULL)
{
/* Pugsy (try accessing unmapped area for copy protection) */
sram.on = 0;
sram.write = 0;
}
else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL)
{
/* Sonic the Hedgehog 2 does not use SRAM */
/* this prevents SRAM activation when using Sonic & Knuckles LOCK-ON feature */
sram.on = 0;
}
else if ((strstr(rominfo.product,"T-26013") != NULL) && (rominfo.checksum == 0xa837))
{
/* Psy-O-Blade (bad header) */
sram.on = 1;
sram.write = 1;
sram.start = 0x200001;
sram.end = 0x203fff;
}
@ -91,7 +92,6 @@ void sram_init()
{
/* Xin Qigai Wangzi, aka Beggar Prince (no header, use uncommon area) */
sram.on = 1;
sram.write = 1;
sram.start = 0x400000;
sram.end = 0x40ffff;
}

View File

@ -27,7 +27,6 @@ typedef struct
{
uint8 detected;
uint8 on;
uint8 write;
uint8 custom;
uint32 start;
uint32 end;