SRAM & Bank Switching with the Everdrive Pro, X-series
Contents
- Background
- Traditional SRAM access
- The Sega/SSF mapper
- Controlling the SSF mapper
- Using SRAM with the SSF mapper
- Heads up!
- References
- Footnotes
Background
If you’re intending to use SRAM with the Mega Everdrive Pro or X-series and are using the Sega/SSF mapper, how SRAM is accessed changes. This article explains the approach you need to take.
Traditional SRAM access
Mega Drive games sometimes featured some sort of storage for saving progress when the console is turned off (for example in Sonic The Hedgehog 3). This typically took the form of a static RAM (SRAM) chip with a battery in each cartridge. The SRAM could then be mapped into an area of the memory address space in order to read/write data.
The hardware which facilitated the “mapping” of SRAM into memory and the subsequent approach to read/write data is described
as the mapper. The most common type permitted 32 KB to be used by a game,
mapped in by writing to a specific register (in the 0xA13000
-0xA130FF
range1).
The operations necessary to make use of this mapper are
nicely documented over on Plutiedev’s Saving progress with SRAM
page. If you’ve not used SRAM before, I recommend reading this first before trying
to understand how SRAM access works with the Everdrive X-series and Pro.
The Sega/SSF mapper
The Everdrive range of flash carts use the traditional mapper when ROMs have the standard
SEGA GENESIS
or SEGA MEGA DRIVE
system type in their header. However, when the system
type is SEGA SSF
, the SSF mapper is activated. SSF stands for Super
Street Fighter II. The game’s ROM was 5 MB which meant that not only did it extend into the
0x200000
range typically used for SRAM,
but it stretched beyond the 0x000000
-0x3FFFFF
range for ROMs which would have interfered with
peripherals such as the Sega CD.
In order for the last 1 MB to be accessible, the game had to implement a custom mapper which allowed it to swap (or bank) 512 KB regions of ROM, thus keeping the directly addressible area to under 4 MB but permitting switched access to the upper 1 MB via 2 x 512 KB banks2.
What does this have to do with SRAM though? Well it turns out that if your ROM is over 4 MB, you will
need to employ a mapper, and the SSF mapper is the one typically implemented by flash carts and
emulators. If you wish to use SRAM however, when the SEGA SSF
header is used,
both the Everdrive X-series and Pro change how SRAM should be accessed and the traditional method
will not work.
Controlling the SSF mapper
The SSF mapper has a 16-bit control register at 0xA130F0
(CTRL0). The Everdrive version of
this register has the following implementation:
MSB LSB
[P.WLC... ...RRRRR]
Where:
P
is the protection bit. Every write to this register requires this bit to be set.W
is the write bit. Set it when you want to write to the mapped memory (this will be set if you’re intending to write to SRAM)L
is for LED control. Use this to control the LED light on the Everdrive (bet you wish you’d bought the clear case now, huh?)C
is the#CART
signal control. Just set to0
unless you know what you’re doing.R
represents the bank (0-31) we want to map in.
In addition to CTRL0, there’s also CTRL1-7. Each CTRLx register actually refers to the area of memory we want to ‘swap’ out for another bank of memory. They each refer to a 512 KB region as follows:
Name | Address | Bit Field | Mapped Memory Range |
---|---|---|---|
CTRL0 | 0xA130F0 |
[P.WLC... ...RRRRR] |
0x000000 -0x07FFFF |
CTRL1 | 0xA130F2 |
[........ ...RRRRR] |
0x080000 -0x0FFFFF |
CTRL2 | 0xA130F4 |
[........ ...RRRRR] |
0x100000 -0x17FFFF |
CTRL3 | 0xA130F6 |
[........ ...RRRRR] |
0x180000 -0x1FFFFF |
CTRL4 | 0xA130F8 |
[........ ...RRRRR] |
0x200000 -0x27FFFF |
CTRL5 | 0xA130FA |
[........ ...RRRRR] |
0x280000 -0x2FFFFF |
CTRL6 | 0xA130FC |
[........ ...RRRRR] |
0x300000 -0x37FFFF |
CTRL7 | 0xA130FE |
[........ ...RRRRR] |
0x380000 -0x3FFFFF |
It’s probably best to show with an example how this all works. Let’s say I want
the memory range 0x200000
-0x27FFFF
to actually be 0x500000
-0x57FFFF
of my ROM so I can
access some resources in that upper area which would ordinarily not be accessible. In this case,
the 512 KB starting at 0x500000
would be bank 10 and I would need to use CTRL4 to set it:
#define CTRL0_ADDR 0xA130F0
#define CTRL4_ADDR 0xA130F8
*((vu16*)CTRL0_ADDR) = 0x8000; // unlock the mapper
*((vu16*)CTRL4_ADDR) = 0x000A; // set CTRL4 to bank 10
u16 data = *((vu16*)0x200000); // read data from 0x500000 (mapped at 0x200000)
Now I can access the memory range 0x500000
-0x57FFFF
of my ROM via 0x200000
-0x27FFFF
.
I can reset the mapping as follows:
*((vu16*)CTRL0_ADDR) = 0x8000; // unlock the mapper
*((vu16*)CTRL4_ADDR) = 0x0004; // set CTRL4 to bank 4 (default)
Using SRAM with the SSF mapper
For both the Everdrive X-series and Pro, SRAM is mapped at bank 31. However, there is a subtle difference between the two. The Everdrive X-series requires you to use the upper 256 KB of this region, while the Pro allows you to use the entire 512 KB.
Example: SRAM on the Everdrive X-series
Reading:
#define CTRL0_ADDR 0xA130F0
#define CTRL4_ADDR 0xA130F8
#define SRAM_BASE 0x240000 // upper 256 KB of BANK4
*((vu16*)CTRL0_ADDR) = 0x8000; // unlock the mapper
*((vu16*)CTRL4_ADDR) = 0x001F; // set CTRL4 to bank 31
u16 data = *((vu16*)SRAM_BASE); // read data from first word of SRAM
Now if you want to write to SRAM, you will also need to set the write bit in the CTRL0 register.
*((vu16*)CTRL0_ADDR) = 0xA000; // unlock and set the write bit
*((vu16*)CTRL4_ADDR) = 0x001F; // set CTRL4 to bank 31 (again)
*((vu16*)SRAM_BASE) = 0x1234; // write data to first 16-bit word of SRAM
Example: SRAM on the Everdrive Pro
Reading:
#define CTRL0_ADDR 0xA130F0
#define CTRL4_ADDR 0xA130F8
#define SRAM_BASE 0x200000 // start of BANK4 (whole 512 KB is available)
*((vu16*)CTRL0_ADDR) = 0x8000; // unlock the mapper
*((vu16*)CTRL4_ADDR) = 0x001F; // set CTRL4 to bank 31
u16 data = *((vu16*)SRAM_BASE); // read data from first word of SRAM
Writing:
*((vu16*)CTRL0_ADDR) = 0xA000; // unlock and set the write bit
*((vu16*)CTRL4_ADDR) = 0x001F; // set CTRL4 to bank 31 (again)
*((vu16*)SRAM_BASE) = 0x1234; // write data to first 16-bit word of SRAM
Enhancements over standard SRAM
The Everdrive Pro and X-series offer a few enhancements over standard (non SSF) SRAM:
- Increased capacity: 256 KB of SRAM on the X-series and 512 KB on the Pro
- No need to skip every other byte required with standard SRAM
- No need to skip first byte/last byte of standard SRAM as recommended by Sega
- Whole 16-bit values can be read/written at once
Heads up!
- Be sure to ensure that neither interrupts or the Z80 attempt to access memory you’re mapping in/out for SRAM or other areas. Best way to do this is to disable interrupts and request the Z80 bus from the 68000 before you map.
- Both the Everdrive Pro and X-series will emulate the traditional mapper when the system type is
SEGA GENESIS
orSEGA MEGA DRIVE
. However, when your ROM is < 2MB, they won’t require you to map in SRAM. It seems like it is always mapped. However if your ROM is > 2MB, you will need to map in SRAM using the control register (0xA130F0
) orSRAM_enable()
andSRAM_disable()
if you are using the SGDK. - When loading a ROM over USB with the Everdrive X7, you will be unable to use SRAM (it will not be mapped in correctly). You will need to load the ROM via the SD card slot instead. Loading a ROM over USB with the Everdrive Pro allows you to use SRAM fine.
- The v1 version of the Everdrive works differently to the X-series and Pro. In particular, it requires you to map in bank 28 to access SRAM. I’ve not tested this, but it is mentioned in the documentation.
References
- Everdrive Product Pages
- Everdrive Technical Documentation
- Plutiedev: Saving progress with SRAM
- Plutiedev: Going beyond 4MB
- Plutiedev: Cartridge slot
Footnotes
-
Cartridges had access to all the address & data lines on the bus and so it was feasible for the game to take any action based on the ROM code reading/writing to any area of memory. However, the hardware required to act on any range was relatively complex. Sega therefore added a specific line known as
/TIME
to the cartridge port. This line went high when memory between0xA13000
-0xA130FF
was accessed. As such, a cartridge could listen to this specific line and react according to the last 8-bits of the address line accessed, simplfying the hardware. ↩ -
It should be noted that this is not the same thing as virtual memory swap, or paging. In virtual memory, processes “see” a virtual address space and the operating system will automatically page in physical memory backing these addresses as and when access to them is required. The Mega Drive has no operating system, nor swap file, nor ability to handle page faults such as those which occur with virtual memory. ↩