From e40093793d39eb086dfd18edbc4c7b0d014486eb Mon Sep 17 00:00:00 2001 From: EkeEke Date: Fri, 21 Jun 2013 10:14:58 +0200 Subject: [PATCH] [Core/MD] fixed SRAM incompatibilities between big & little endian platforms (SRAM is now always saved in big endian format like other emulators) --- core/cart_hw/eeprom_i2c.c | 6 +-- core/cart_hw/eeprom_i2c.h | 2 +- core/cart_hw/md_cart.c | 21 ---------- core/cart_hw/sram.c | 80 ++++++++++++++++++++++++++++++++------- 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/core/cart_hw/eeprom_i2c.c b/core/cart_hw/eeprom_i2c.c index 6019d68..f3bce70 100644 --- a/core/cart_hw/eeprom_i2c.c +++ b/core/cart_hw/eeprom_i2c.c @@ -2,7 +2,7 @@ * Genesis Plus * 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 * provided that the following conditions are met: @@ -186,10 +186,10 @@ void eeprom_i2c_init() 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.end - sram.start) < 2) + if ((READ_BYTE(cart.rom,0x1b2) == 0xe8) || ((sram.end - sram.start) < 2)) { /* set SEGA mapper as default */ sram.custom = 1; diff --git a/core/cart_hw/eeprom_i2c.h b/core/cart_hw/eeprom_i2c.h index b47ce02..7ea8d8a 100644 --- a/core/cart_hw/eeprom_i2c.h +++ b/core/cart_hw/eeprom_i2c.h @@ -2,7 +2,7 @@ * Genesis Plus * 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 * provided that the following conditions are met: diff --git a/core/cart_hw/md_cart.c b/core/cart_hw/md_cart.c index 4695425..f09217c 100644 --- a/core/cart_hw/md_cart.c +++ b/core/cart_hw/md_cart.c @@ -42,7 +42,6 @@ ****************************************************************************************/ #include "shared.h" -#include "eeprom_i2c.h" #include "eeprom_spi.h" #include "gamepad.h" @@ -357,27 +356,7 @@ void md_cart_init(void) BACKUP MEMORY ***********************************************/ 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 ***********************************************/ diff --git a/core/cart_hw/sram.c b/core/cart_hw/sram.c index 665a864..835ec15 100644 --- a/core/cart_hw/sram.c +++ b/core/cart_hw/sram.c @@ -37,23 +37,33 @@ ****************************************************************************************/ #include "shared.h" +#include "eeprom_i2c.h" 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 * 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 * 11 if odd address only * 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() { @@ -70,6 +80,10 @@ void sram_init() /* retrieve informations from header */ 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.end = READ_WORD_LONG(cart.rom, 0x1b8); @@ -86,12 +100,9 @@ void sram_init() { sram.end = sram.start + 0xffff; } - sram.start &= 0xfffffe; - sram.end |= 1; /* enable backup RAM */ sram.on = 1; - sram.detected = 1; } else { @@ -151,11 +162,10 @@ void sram_init() } 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) { - /* Sonic 3 & Knuckles combined ROM */ - /* it shows S&K header but should obviously use FRAM from Sonic 3 */ + /* Sonic & Knuckle does not have backup RAM but can access FRAM from Sonic 3 cartridge */ sram.on = 1; sram.start = 0x200001; sram.end = 0x203fff; @@ -165,12 +175,12 @@ void sram_init() /* auto-detect games which need disabled backup RAM */ 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; } 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 */ sram.on = 0; } @@ -178,10 +188,52 @@ void sram_init() /* by default, enable backup RAM for ROM smaller than 2MB */ else if (cart.romsize <= 0x200000) { - /* SRAM mapped to $200000-$20ffff */ + /* 64KB static RAM mapped to $200000-$20ffff */ sram.start = 0x200000; sram.end = 0x20ffff; 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; }