This article was published in Commodore Hacking #20.
Update 2001-10-16: Added a new version of the memory test program. Fixed missing parenthesis on line 130 (generated false errors) and testing bank 5 (crashed with an illegal quantity error).
Update 2001-12-16: Corrected typo below (/WE where it should say /OE, in the instructions on how to add bank select switches).
I tried to keep the expansion as simple as possible, requiring no chips besides the two memory chips, and a minimum of soldering. It uses two 6264 SRAM chips (62256 also works) piggy-backed to the Kernal and Basic 2364 ROMs. It's recommended that you do the expansion one chip at a time, as this greatly simplifies troubleshooting. After the first chip checks out OK, do the second one. I'll start out by explaining a few basic principles.
___ ___ 1 =| V |= 8 2 =| |= 7 3 =| |= 6 4 =| |= 5 `-------'As you can see, the pin numbers start at 1, and the first pin is the top left, going down to the bottom left, then from the bottom right to the top right.
6264 RAM ___ ___ 2364 ROM NC 1 =| V |= 28 Vcc ___ ___ A12 2 =| |= 27 /WE A7 1 =| V |= 24 Vcc A7 3 =| |= 26 CS2 A6 2 =| |= 23 A8 A6 4 =| |= 25 A8 A5 3 =| |= 22 A9 A5 5 =| |= 24 A9 A4 4 =| |= 21 A12 A4 6 =| |= 23 A11 A3 5 =| |= 20 /CS A3 7 =| |= 22 /OE A2 6 =| |= 19 A10 A2 8 =| |= 21 A10 A1 7 =| |= 18 A11 A1 9 =| |= 20 /CS1 A0 8 =| |= 17 D7 A0 10 =| |= 19 D7 D0 9 =| |= 16 D6 D0 11 =| |= 18 D6 D1 10 =| |= 15 D5 D1 12 =| |= 17 D5 D2 11 =| |= 14 D4 D2 13 =| |= 16 D4 Vss 12 =| |= 13 D3 Vss 14 =| |= 15 D3 `-------' `-------'I put the pins that don't match in bold, and as you can see there are 8 that don't. However, we don't have to rewire all of them. NC means "No Connection" so we can just ignore that pin. Note that if you're using 62256 chips you'll have to wire this one too, see below. We want to connect CS2 to Vcc, and we'll also swap A11 and A12, leaving 5 pins to solder on each chip. Swapping address bus pins works on RAM chips, as it only affects how bits are stored internally -- when you read them out again, they're swapped back. This also works for the databus.
We'll mount one 6264 on top of the Kernal ROM, and one 6264 on top of the Basic ROM. The ROMs are marked UE11 and UE12 and can be found in the bottom right of the motherboard. The wiring is identical for the two chips, except for the /OE and /CS1 pins. The pins that we want to rewire we carefully bend up so that they don't connect to the ROM. You want to bend them almost all the way up (about 150 degrees) so that you can reach them with the soldering iron. The pins are very sensitive, so make sure you bend the right pins -- bending a pin back again could easily break it.
Sometimes the pins on the RAM are too wide apart to make a good connection when you piggy-back it. In this case, bend all the pins on the RAM slightly inwards. You can do this by putting it on the side on a flat, hard surface and press gently.
The block signals are available on the 74LS138 decoder chip marked UC5 on the left side of the motherboard. Block 1 is on pin 14, block 2 is on pin 13, block 3 is on pin 12 and block 5 is on pin 10. If you look closely you'll see that the signals for block 1 and 2 go out from the chip a few mm to a small pad. It's much easier to connect your wires to these pads than the pins on the decoder chip. Solder a wire from block 1 to pin 20 and 22 on the first RAM chip, and a wire from block 2 to pin 20 and 22 on the second RAM chip.
10 input "test which block";b 20 s = b*8192 : t = s+8191 : e = 0 : o = 0 25 if s>= 32768 then s = s-32768 : t = s+8191 : o = 32768 30 print "testing databus" 40 for a = s to t : poke a+o, 85 : if peek(a+o) <> 85 then gosub 1000 50 poke a+o, 170 : if peek(a+o) <> 170 then gosub 1000 60 next : de = e 70 e=0 : print "testing high address bus" 80 for a = s to t : poke a+o, int(a/256) : next 90 for a = s to t : if peek(a+o) <> int(a/256) then gosub 1000 100 next : he = e 110 e=0 : print "testing low address bus" 120 for a = s to t : poke a+o, a and 255 : next 130 for a = s to t : if peek(a+o) <> (a and 255) then gosub 1000 140 next : print 150 print de;"errors found in databus test" 160 print he;"errors found in high address bus test" 170 print e;"errors found in low address bus test" 999 end 1000 e = e+1 : print "error at";a : return
10 input "test which block";b 20 s = b*8192 : t = s+8191 : e = 0 30 print "testing databus" 40 for a = s to t : poke a, 85 : if peek(a) <> 85 then gosub 1000 50 poke a, 170 : if peek(a) <> 170 then gosub 1000 60 next : de = e 70 e=0 : print "testing high address bus" 80 for a = s to t : poke a, int(a/256) : next 90 for a = s to t : if peek(a) <> int(a/256) then gosub 1000 100 next : he = e 110 e=0 : print "testing low address bus" 120 for a = s to t : poke a, a and 255 : next 130 for a = s to t : if peek(a) <> a and 255 then gosub 1000 140 next : print 150 print de;"errors found in databus test" 160 print he;"errors found in high address bus test" 170 print e;"errors found in low address bus test" 999 end 1000 e = e+1 : print "error at";a : return
Using 62256 chips instead of 6264
You can freely substitute 62256 chips for the 6264. Only two pins
differ:
6264 RAM 62256 RAM ___ ___ ___ ___ NC 1 =| V |= 28 Vcc A14 1 =| V |= 28 Vcc A12 2 =| |= 27 /WE A12 2 =| |= 27 /WE A7 3 =| |= 26 CS2 A7 3 =| |= 26 A13 A6 4 =| |= 25 A8 A6 4 =| |= 25 A8 A5 5 =| |= 24 A9 A5 5 =| |= 24 A9 A4 6 =| |= 23 A11 A4 6 =| |= 23 A11 A3 7 =| |= 22 /OE A3 7 =| |= 22 /OE A2 8 =| |= 21 A10 A2 8 =| |= 21 A10 A1 9 =| |= 20 /CS1 A1 9 =| |= 20 /CS1 A0 10 =| |= 19 D7 A0 10 =| |= 19 D7 D0 11 =| |= 18 D6 D0 11 =| |= 18 D6 D1 12 =| |= 17 D5 D1 12 =| |= 17 D5 D2 13 =| |= 16 D4 D2 13 =| |= 16 D4 Vss 14 =| |= 15 D3 Vss 14 =| |= 15 D3 `-------' `-------'Pin 26 (A13) can be connected to Vcc just like on the 6264, but we need to wire pin 1 (A14) to either Vcc, Vss or another address bus pin. It's probably easiest to wire it to pin 2 (A12). We won't be using the greater capacity of the 62256 using this method (doing so would require some kind of decoder logic) but sometimes 62256 chips are cheaper than 6264, or maybe you just have some lying around.
Adding Block Select and Write Protect Switches
Adding block select switches allows you to chose which blocks should
be populated on the fly. This allows you to chose between a basic
expansion and a "cartridge emulator" that allows you to load cartridge
images into ram and run them. I added one switch for each chip, giving
the first chip the option between block 1 and 3, and the second
between 2 and 5.
block 1 -----o \ o----- to /CS1 and /OE on chip 1 block 3 -----o block 2 -----o \ o----- to /CS1 and /OE on chip 2 block 5 -----oAs a kind of copy protection, some cartridge images try to modify themselves to detect if they're running from RAM. If we add write protect switches we'll be able to run those as well. Switch to write enabled while loading, then switch to write protected and reset.
R/W -----o \ o----- to /WE on chip 1 +5 V -----o R/W -----o \ o----- to /WE on chip 2 +5 V -----o+5 V is the same as Vcc.
This document is Copyright © Per Olofsson in 2001.