[Core/MD] fixed SRAM incompatibilities between big & little endian platforms (SRAM is now always saved in big endian format like other emulators)

This commit is contained in:
EkeEke 2013-06-21 10:14:58 +02:00
parent 15d96065ba
commit e40093793d
4 changed files with 70 additions and 39 deletions

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* I2C Serial EEPROM (24Cxx) support * I2C Serial EEPROM (24Cxx) support
* *
* Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -186,10 +186,10 @@ void eeprom_i2c_init()
i++; i++;
} }
/* Game not found in database but ROM header indicates it uses EEPROM */ /* Game not found in database but ROM header indicates it uses serial EEPROM */
if (!sram.custom && sram.detected) if (!sram.custom && sram.detected)
{ {
if ((sram.end - sram.start) < 2) if ((READ_BYTE(cart.rom,0x1b2) == 0xe8) || ((sram.end - sram.start) < 2))
{ {
/* set SEGA mapper as default */ /* set SEGA mapper as default */
sram.custom = 1; sram.custom = 1;

View File

@ -2,7 +2,7 @@
* Genesis Plus * Genesis Plus
* I2C Serial EEPROM (24Cxx) support * I2C Serial EEPROM (24Cxx) support
* *
* Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:

View File

@ -42,7 +42,6 @@
****************************************************************************************/ ****************************************************************************************/
#include "shared.h" #include "shared.h"
#include "eeprom_i2c.h"
#include "eeprom_spi.h" #include "eeprom_spi.h"
#include "gamepad.h" #include "gamepad.h"
@ -357,27 +356,7 @@ void md_cart_init(void)
BACKUP MEMORY BACKUP MEMORY
***********************************************/ ***********************************************/
sram_init(); sram_init();
eeprom_i2c_init();
if (sram.on)
{
/* static RAM only (64KB max.) */
if (!sram.custom)
{
/* disabled on startup if ROM is mapped in same area */
if (cart.romsize <= sram.start)
{
m68k.memory_map[sram.start >> 16].base = sram.sram;
m68k.memory_map[sram.start >> 16].read8 = NULL;
m68k.memory_map[sram.start >> 16].read16 = NULL;
m68k.memory_map[sram.start >> 16].write8 = NULL;
m68k.memory_map[sram.start >> 16].write16 = NULL;
zbank_memory_map[sram.start >> 16].read = NULL;
zbank_memory_map[sram.start >> 16].write = NULL;
}
}
}
/********************************************** /**********************************************
SVP CHIP SVP CHIP
***********************************************/ ***********************************************/

View File

@ -37,23 +37,33 @@
****************************************************************************************/ ****************************************************************************************/
#include "shared.h" #include "shared.h"
#include "eeprom_i2c.h"
T_SRAM sram; T_SRAM sram;
static unsigned int sram_read_byte(unsigned int address);
static unsigned int sram_read_word(unsigned int address);
static void sram_write_byte(unsigned int address, unsigned int data);
static void sram_write_word(unsigned int address, unsigned int data);
/**************************************************************************** /****************************************************************************
* A quick guide to SRAM on the Genesis * A quick guide to external RAM on the Genesis
* *
* The SRAM definition is held at offset 0x1b0 of the ROM header. * The external RAM definition is held at offset 0x1b0 of the ROM header.
* *
* 1B0h: dc.b 'RA', %1x1yz000, %00100000 * 1B0h: dc.b 'RA', %1x1yz000, %abc00000
* 1B4h: dc.l RAM start address * 1B4h: dc.l RAM start address
* 1B8h: dc.l RAM end address * 1B8h: dc.l RAM end address
* x 1 for BACKUP and 0 If not BACKUP * x 1 for BACKUP (not volatile), 0 for volatile RAM
* yz 10 if even address only * yz 10 if even address only
* 11 if odd address only * 11 if odd address only
* 00 if both even and odd address * 00 if both even and odd address
* 01 others (serial EEPROM, RAM with 4-bit data bus, etc)
* abc 001 if SRAM
* 010 if EEPROM (serial or parallel)
* other values unused
* *
* Assuming max. 64k SRAM / Battery RAM throughout * Assuming max. 64k backup RAM throughout
****************************************************************************/ ****************************************************************************/
void sram_init() void sram_init()
{ {
@ -70,6 +80,10 @@ void sram_init()
/* retrieve informations from header */ /* retrieve informations from header */
if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41)) if ((READ_BYTE(cart.rom,0x1b0) == 0x52) && (READ_BYTE(cart.rom,0x1b1) == 0x41))
{ {
/* backup RAM detected */
sram.detected = 1;
/* retrieve backup RAM start & end addresses */
sram.start = READ_WORD_LONG(cart.rom, 0x1b4); sram.start = READ_WORD_LONG(cart.rom, 0x1b4);
sram.end = READ_WORD_LONG(cart.rom, 0x1b8); sram.end = READ_WORD_LONG(cart.rom, 0x1b8);
@ -86,12 +100,9 @@ void sram_init()
{ {
sram.end = sram.start + 0xffff; sram.end = sram.start + 0xffff;
} }
sram.start &= 0xfffffe;
sram.end |= 1;
/* enable backup RAM */ /* enable backup RAM */
sram.on = 1; sram.on = 1;
sram.detected = 1;
} }
else else
{ {
@ -151,11 +162,10 @@ void sram_init()
} }
else if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL) else if (strstr(rominfo.international,"SONIC & KNUCKLES") != NULL)
{ {
/* standalone Sonic & Knuckle does not use backup RAM */ /* Sonic 3 & Knuckles combined ROM */
if (cart.romsize == 0x400000) if (cart.romsize == 0x400000)
{ {
/* Sonic 3 & Knuckles combined ROM */ /* Sonic & Knuckle does not have backup RAM but can access FRAM from Sonic 3 cartridge */
/* it shows S&K header but should obviously use FRAM from Sonic 3 */
sram.on = 1; sram.on = 1;
sram.start = 0x200001; sram.start = 0x200001;
sram.end = 0x203fff; sram.end = 0x203fff;
@ -165,12 +175,12 @@ void sram_init()
/* auto-detect games which need disabled backup RAM */ /* auto-detect games which need disabled backup RAM */
else if (strstr(rominfo.product,"T-113016") != NULL) else if (strstr(rominfo.product,"T-113016") != NULL)
{ {
/* Pugsy (try writing outside ROM area as copy protection) */ /* Pugsy (does not have backup RAM but tries writing outside ROM area as copy protection) */
sram.on = 0; sram.on = 0;
} }
else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL) else if (strstr(rominfo.international,"SONIC THE HEDGEHOG 2") != NULL)
{ {
/* Sonic the Hedgehog 2 (does not use backup RAM) */ /* Sonic the Hedgehog 2 (does not have backup RAM) */
/* this prevents backup RAM from being mapped in place of mirrored ROM when using S&K LOCK-ON feature */ /* this prevents backup RAM from being mapped in place of mirrored ROM when using S&K LOCK-ON feature */
sram.on = 0; sram.on = 0;
} }
@ -178,10 +188,52 @@ void sram_init()
/* by default, enable backup RAM for ROM smaller than 2MB */ /* by default, enable backup RAM for ROM smaller than 2MB */
else if (cart.romsize <= 0x200000) else if (cart.romsize <= 0x200000)
{ {
/* SRAM mapped to $200000-$20ffff */ /* 64KB static RAM mapped to $200000-$20ffff */
sram.start = 0x200000; sram.start = 0x200000;
sram.end = 0x20ffff; sram.end = 0x20ffff;
sram.on = 1; sram.on = 1;
} }
} }
/* autodetect games with serial EEPROM */
eeprom_i2c_init();
/* initialize m68k bus handlers (if not already done) */
if (sram.on && !sram.custom)
{
/* disabled on startup if ROM is mapped in same area */
if (cart.romsize <= sram.start)
{
m68k.memory_map[sram.start >> 16].base = sram.sram;
m68k.memory_map[sram.start >> 16].read8 = sram_read_byte;
m68k.memory_map[sram.start >> 16].read16 = sram_read_word;
m68k.memory_map[sram.start >> 16].write8 = sram_write_byte;
m68k.memory_map[sram.start >> 16].write16 = sram_write_word;
zbank_memory_map[sram.start >> 16].read = sram_read_byte;
zbank_memory_map[sram.start >> 16].write = sram_write_byte;
}
}
}
static unsigned int sram_read_byte(unsigned int address)
{
return sram.sram[address & 0xffff];
}
static unsigned int sram_read_word(unsigned int address)
{
address &= 0xfffe;
return (sram.sram[address + 1] | (sram.sram[address] << 8));
}
static void sram_write_byte(unsigned int address, unsigned int data)
{
sram.sram[address & 0xffff] = data;
}
static void sram_write_word(unsigned int address, unsigned int data)
{
address &= 0xfffe;
sram.sram[address] = data >> 8;
sram.sram[address + 1] = data & 0xff;
} }