[stella] Megacart Specs

Subject: [stella] Megacart Specs
From: Chris Wilkson <cwilkson@xxxxxxxxxxxxx>
Date: Sat, 11 Apr 1998 21:39:33 -0700 (PDT)
> Can you send the specs about bankswitching and RAM access to the
> list, please. That way people could see if your cart would be
> usable for any of their games.
> And how about the price of your cart? Wouldn't it be very
> expensive to have that much RAM and ROM?

I thought I'd already done this at some point.  Oh well, here it is.  It is,
of course, somewhat incomprehensible in the spirit of all tech docs...I tried
to model it after the 2600 docs :)  Just kidding.  It still needs some tweaks,
but I think it can be deciphered.

As Glenn mentioned, EPROMs are cheap.  (Not as cheap as DRAM ):
But SRAM is somewhat expensive.  So are batteries.  And the big cost
is the board itself.  Each board run costs $250 for setup plus the actual
per square inch charges.  Plus shipping.

The idea is to make large amounts of ROM available (128KB) with the option
to tack on some RAM and an even more optional battery backup.  I forget the
numbers I quoted way back when, but I think the whole thing was gonna cost
around $15 for a complete cartridge minus labels/docs.  And that was gonna
come down a bit.  I think the cost of a ROM only cart was gonna be about
$8.  But it's been a few months since I was working on costs.

One last thing...
If anyone here has suggestions or requests for the document, or the spec
itself, now is the time to make them...while it's still in development.


Megacart Specification, Rev1.1
(c) 1997 Chris Wilkson


The Megacart is an external memory cartridge for the Atari 2600 and compatible
home video game consoles.  It plugs into the standard cartridge port, and
contains a total of 128K bytes of ROM storage and 32K bytes of battery-backed
RAM storage.

General Operation

The Megacart uses "bank switching" to fit the 160K bytes of physical memory
into the console's available 4K address space.  Physical memory is divided
into 64 RAM blocks of 512 bytes each, and 128 ROM blocks of 1K bytes each.
RAM blocks are numbered $00 through $3F, and ROM blocks are numbered $80
through $FF.

The console's address space is divided into 4 slots of 1K each.  Any physical
memory block can be switched into any memory slot by writing its block number
to the "hot address" for the desired slot.  Memory locations $3C through $3F
serve as "hot addresses" for memory slots 0 through 3, respectively.


To make ROM addresses $1A400-$1A7FF (block $E9) available to the console at
memory locations $F800-$FBFF (slot 2), write $E9 to memory location $3e.


Note that these memory locations are write only.  Trying to read the contents
of memory locations $3C through $3F will not only return invalid data, but
will also corrupt the contents causing the software to crash.  Reading these
addresses should not be attempted.

Special Case - RAM

RAM blocks differ from ROM blocks in that one of the console's address lines,
A9 in this case, must be used as a read/write select.  Because of this, RAM
blocks are limited to 512 bytes each, yet still occupy an entire 1K slot.
To store a value A9 must be low.  To retrieve a value A9 must high.


First, let's set slot 0 (console addresses $F000-$F3FF) to point to RAM
block $9 (RAM $1200-$13ff).  To do this, write $9 to console address $3c.
To store the value $69 in RAM location $1234, write $69 to console address
$F034 (A9=0).  To retrieve the value of RAM location $1234, read from console
address $F234 (A9=1).

Special Case - Powerup

Because the console's memory is randomized at powerup, there is no way to
predict the data initially contained in the "hot addresses".  Therefore,
hardware will force slot 3 to always point to ROM block $FF immediately
after any read or write to the RESET vector at $FFFC-$FFFD.  Block $FF
must contain code to initialize the 4 memory slots to point to the desired
physical memory blocks before any other code can be executed.  After program
execution jumps out of the boot code, the hardware will release slot 3 and
it will function just like any other slot.

Example (the first column is the physical ROM address):

$00C00	JUNK	...		; random code and data
$1F400	START	...		; program starts here
		...		; slot 3 now points to rom block $83
$1FFDD	BOOT	SEI		; disable interrupts
$1FFDE		CLD		; set hexadecimal arithmetic mode
$1FFDF		LDX	#$FF	; 
$1FFE1		TXS		; set stack pointer to $ff
$1FFE2 		LDA	#$00 
$1FFE4	ZERO	STA	00,X	; clear RIOT and TIA -BEFORE- setting
$1FFE6		DEX		; up banks
$1FFE9	BANKS	LDA	#$00	; ram block 0 ($0000-$01ff)
$1FFEB		STA	SLOT0	; slot 0 points to ram block 0
$1FFED		LDA	#$34	; ram block $34 ($6800-$69ff)
$1FFEF		STA	SLOT1	; slot 1 points to ram block $34
$1FFF1		LDA	#$FD	; rom block $fd ($1f400-$1f7ff)
$1FFF3		STA	SLOT2	; slot 2 points to rom block $fd
$1FFF5		LDA	#$83	; rom block $83 ($00C00-$01000)
$1FFF7		STA	SLOT3	; slot 3 points to bootcode (rom block $ff)
				; until jumping out of slot 3
$1FFF9		JMP	$F800	; jump to slot 2
$1FFFC	RESET	.WORD	$FFDD	; powerup reset vector
$1FFFE	SWI	.WORD	$FFDD	; software interrupt vector (BRK)

Current Thread