For a game project, I was called upon to design the cartridge circuit boards for SMS and Game Gear
presented on this page.
The requirements were established as such:
Must support games larger than 48 kB (in other words: Needs a mapper)
Must allow saving progress or scores
Must fit in original (or compatible) cartridges
Must have reasonable production costs
I decided to use a flash memory chip which can be erased and reprogrammed at will. The chip works
natively at 5 volts so no voltage level translators were required.
The "mapper" function, which allows the console to access more than 64kB of memory, is implemented using
a CPLD. It works as a simpligied Sega-style mapper supporting slot 2 only, with bank selection through address
FFFF.
The traditional approach for saving scores or progress is to use battery-backed RAM in the
cartridge. In order to keep things simple and save cost, my approach is to save directly
into the flash chip. A 64 kB sector must be reserved, leaving 448 kB of space for the game.
On the mechanical side of things, in order to make sure the circuit would fit in original cartridge shells,
I just had to carefully measure.
Master System PCB
Here is what the SMS cartridge PCB looks like. It is available (with or without an enclosure) from
my online store.
SMS PCB (Front)
SMS PCB (Back)
And here are a few pictures of the PCB in use:
Programming with SMSCPROGR
Testing a homebrew game
PCB installed in an cartridge shell
Reprogrammable cartridge built with this PCB
Game Gear PCB
And here is the Game Gear version. This PCB also is available from my
online store.
Game Gear cartridge PCB
Cartridge PCB installed in a cartridge
Here are a few pictures of the Game Gear PCB in action:
Programming with SMSCPROGR
Testing a homebrew game
Testing a homebrew game
Programming a cartridge
Building an SMS cartridge PCB with a soldered flash chip is good, but without a way to
program it in place it is not very useful.
The first 32 kB of FLASH can be programmed with an ordinary EPROM programmer, given an appropriate
adapter and a programmer supporting the flash chip. This is what I did first. The 32 kB limit is
due to the fact that most (if not all) EPROM programmers don't know how to use the mapper to switch
banks.
This was not very convenient, and the 32 kB limit was a problem. So I designed
a dedicated cartridge programmer (and reader), which can program the entirety
of the 512kB flash chip.
The Z80 CPU in the SMS can directly address up to 64 kB of memory. The last 16 kB (slot 3) are reserved
for the console internal 8K RAM. This leaves up to 48 kB for the cartridge ROM.
Still, games larger than 48 kB are possible thanks to an additional chip called "mapper" which
can arrange for some range of memory (from the Z80 point of view) to correspond to a selectable range
located past the 48 kB in ROM. (bank switching)
Memory addresses from $0000 to $7FFF (slots 0 and 1, 16kB each) always correspond directly
to addresses $0000 to $7FFF in flash. However, memory from $8000 to $FFFF (slot 2) can
be pointed to any 16kB bank in flash. The bank is selected by writing to address $FFFF.
Most homebrew games do not "move" slots 0 and 1, so supporting slot 2 should be enough.
Development: Saving scores on Flash
As mentioned in the introduction, saving scores or progress can be done by writing to
the flash chip. This allows for a very simple circuit (Only two chips) without a battery,
but it does complicate the software side. While writing to battery-backed RAM is a simple
matter of doing a normal memory write, writing to flash is not so simple.
Thankfully, at least reading from flash is done perfectly normally, otherwise the program
could not execute from it! Only writes are tricky. First, erasing a single byte
is not possible. The flash chip I used is divided in 64 kB erase blocks. Yes, 64 kB must
be erased even to change a single byte.
Next, the erase and write commands required some time to execute, and during that time,
reading from flash is not possible! This means that if the game code is executing from the flash (i.e
the CPU is reading instructions) then the system will crash/hang.
The solution is to load the code handling the flash erase and write operation in the console
RAM. As the code executes from RAM rather than from flash, the problem is avoided! (Interrupts
should also be disabled)
Yes but, could the game accidentally erase itself?
I think the changes of this happening are extremely low, since erasing a sector
requires a very specific sequence:
Write $AA to address 555
Write $55 to address 2AA
Write $80 to address 555
Write $AA to address 555
Write $30 to sector address to erase.
In order for the erase operation to take place, nothing must happen between the steps above. For instance,
if the console is executing code from the flash, read accessed will be introduced between the steps
above and the operating will be aborted. Writing bytes to flash is done with a sequence similar
to the above, but the sequence is shorter (it ends at step 3).
But what about the non-maskable interrupt? (NMI)
Ah, yes, this is the only defect this approach has. If the player manages to press the PAUSE button
(wired to the NMI) at the wrong time (during the few milliseconds where the code must
run from RAM) the processor will try running code from address $0066 and will hang or reset.
My hope is that one day a great number of new, high quality homebrew games using my PCB design
will be published.
Did you make a game using one of those boards? Please share a few pictures and screenshots and,
with your permission, I will add them here, accompanied by a link to your game's homepage.
DONKEY.SMS
For fun, I created a simple game called DONKEY.SMS. This game has
its own page.