Skip to main content

What you see here is a Commodore 64 cartridge that I have created by sticking an EPROM and some other components on a breadboard. To connect to the C64 cartridge port I am using a breakout board that was created by Sven Petersen. You can find this design alongside other awesome projects on his GitHub page. In this blog I will try to explain how C64 cartridges work and how you can create one using different configurations. In the end of this article I will test my custom PLA project using the Super Zaxxon cartridge configuration.

Sven had the courtesy to send me one of his boards including all components needed to assemble it. The cartridge header was already pre inserted and the edge pins were soldered. Using sticky tacks I have secured it a bit more and soldered the rest of the pins.

Next I have inserted the pin header into the PCB and soldered it as well.
You can use this connector to attach a flat cable and connect it to a logic analyzer, but in this project we will be sticking jumper wires into it that connect to the breadboard.

We can continue by inserting the connector with the attached jumpers, using sticky tacks to hold them in place and of course soldering the connections.
The jumpers bridge some of the signals between the C64 and the soldered cartridge connector on the PCB. If the connections are interrupted, then the associated signal on the PCB cartridge port is pulled high by the resistor network. So an open jumper means that this pin is HIGH on the PCB cartridge side.

We can  now solder this resistor network.. It is important to note that PIN number 1 must be soldered correctly. This pin can be recognised by a dot on the resistor network, but if you are not sure you can also measure it. Connection from pin 1 to every other pin must give a resistance of 10K ohms.

The resistor network goes behind the jumper header. I might have soldered it before, but it can still be dropped in using tweezers. I can assure you that I am not sponsored by sticky tacks, but for sure they are handy to hold the components in place while soldering. 

The reset-switch is connected to the reset signal. As long as the jumper
labeled RESET is closed, it is effective for the cartridge and the C64. While this jumper is open, it only resets the cartridge.

After finishing soldering we give the board a good rinse with isopropyl alcohol.

Let's test the soldered board by interesting a cartridge. I will use this Final Cartridge III. And it works...

In the previous blog I have created this custom PLA tester so let's take the opportunity and use this breakout board and connect to it. It was much easier to connect it using the breakout board, then connecting to the breadboard using those nasty connector clips. The custom PLA still appears to be working...

After this introduction, let's continue with the real purpose of this blog post which is creating cartridges on a breadboard.

There are many types of cartridges for the Commodore 64, but in this blog post I will focus on 3 variations. 

C64 architecture is natevely designed to run cartridges in the size of 8 or 16 KB, 
It uses 2 pins that are natively inputs to the PLA chip. They are GAME and EXROM. The size of the cartridge is determined according to whether they are pulled-down to the ground. It simply swaps out active memory inside the C64 to the one on the EPROM chip. 

Let's start with the most simple 8 kilobyte version. There are many websites on the internet where you can find images of cartridges that are designed to run on emulators like VICE. The file extension is dot CRT. 

VICE emulator provides a tool called cartconv where you can convert this CRT format to a raw binary file which can be burned on an EPROM.

Let's do that by using a bash terminal.

cartconv -i centipede.crt -o centipede.bin

Now we can burn this converted file onto an electrically programmable EPROM chip. To do that I am using the mini pro command line tool.

minipro -p AT28C256 -w centipede.bin

Apart from the warning that my firmware is out of date, we are getting an error message that the file size that we are trying to burn is not correct. This is due to the fact that I am using a 32 kilobyte chip. Let's fix and fill the file with zeros to the desired length by using this dd command.

dd if=/dev/zero bs=1 count=24576 >> centipede.bin

When we execute the minipro command again, it shows that the EEPROM has been successfully programmed.

This is the schematics of the 8 kilobytes EEPROM that we are going to build.

Let's hook up the breadboard.

First we connect power and ground to pins 24 and 14.
Then the write enable pin which is active low needs to be pulled high as we are not going to write to the chip.
There are 16 address lines that need to be connected on the cartridge breakout board, but to address 64 kilobytes we just need to connect 13 of them.
These wires connect to the pins A0 through A12 of the chip on the breadboard.
Now we need to connect the data lines D0 through D7. And they will of course connect to the related pins on the chip.
The next pin that needs to be connected is ROML. This connection will enable the EEPROM chip by bringing output enable and chip enable pins low.
The EXROM jumper wire is connected to ground and this will let the C64 know that an eight kilobyte cartridge has been inserted.
Before forgetting, let's make sure that both ends of the breadboard will have the power and ground connected.
Because we are using a 32 kilobytes chip, the address lines A13 and A14 need to be pulled low.
And we will also add this 100 nanofarad decoupling capacitor between power and ground.

This should be enough to run the Centipede game. Let's turn the C64 on and see what will happen.

Wait a second... The game is freezing. Why is this happening? After spending some time trying to figure out what was wrong with the EEPROM chip I gave up and decided to try a regular 27C256 EPROM of the same size. 

First the chip needed to be erased, as I was not sure if it  was empty. I knew this EPROM eraser would come in handy someday.. I put the chip in the drawer and let it erase for 10 minutes.

Now we can insert the chip into the EPROM programmer.

To write it we need to specify some other parameters for the minipro command.

minipro -p M27C64A@DIP28 -w centipede.bin

It is a good idea to cover up the EPROM after it has been written. I am using this black electrical tape. Now we should not be worried that our precious data will get erased when the chip is accidently left out in the sunlight.

Ok, it's time to swap the EEPROM chip with this new one.

But before we can test it, some wires need to be swapped as the pinout of the 2 chips differs.

Pin 1 on the 28C256 was A14 and on the new EPROM it is VPP programming voltage. We need to swap it to the 5V rail in order for the chip to operate correctly.

Pin 27 which was Write enable, is now A14, so it will be pulled low.

Let's try again and... Yes! This time the game is running correctly.

We can now proceed with the 16 kilobyte cartridge configuration. To do that we will need an AND gate. Because I do not have one at hand I will chain two NAND gates using this 74LS00 chip. 

If we used two 8 kilobytes chips the AND gate would not be needed as the ROML and ROMH cartridge outputs can both enable 2 separate EPROMS, ROML pin is set when the C64 is reading from the lower memory addresses and ROMH is set when reading from the higher memory address space. They can never be both active at the same time.

Because we are using this 1 chip we have to use the configuration as shown in this schematics.

When the ROML or ROMH signal is LOW then the output of the AND gate will be LOW. That means the chip will be enabled in both cases.

A13 of the EPROM is connected to ROML output. When the signal toggles it will address the lower or the higher 8 kilobytes of the chip. 

First we connect power and ground, then we will take out the wire that pulled A13 to ground in the previous configuration and connect to ROML, that used to connect to the chip and output enable pins. ROML also connects to one of the inputs of the first NAND gate.

And the second input of this gate connects to ROMH on the cartridge port.

Now we connect the output of the first NAND gate to the input of the second one. The second NAND gate also becomes a NOT gate. Output of this gate connects to the chip and "output enable" pins of the EPROM.

And finally the GAME output connects to ground.

It's time to prepare the chip. Like before we convert the CRT file to the binary file.

cartconv -i crystal-castles.crt -o crystal.bin

This time we need to add 16384 bytes to make the file 32 kilobytes in length.

dd if=/dev/zero bs=1 count=16384 >> crystal.bin

We can now insert the EPROM in the programmer and give the minipro command to write it.

minipro -p M27C256B@DIP28 -w crystal.bin

Let's cover the EPROM with the electrical tape and insert back into the breadboard. Finally we can test the 16 kilobytes cartridge.

Yes.. there is the crystal castles game starting up.

Just for fun I have connected the scope to the ROML and ROMH signals that select the memory locations on the EPROM. As you can see there is a pattern. I think that it has something to do with the refresh rate of the blog post. After zooming we can see that the signals are all over the place, but they are never simultaneously low.

The last configuration that I am going to show is for the Super Zaxxon cartridge. 

In my previous blog post I did some tests on my custom PLA using the SR-latch circuit, but I also wanted to test it using the Super Zaxxon cartridge. I came across a blog post on hackup.net that described how to build a replica of this cartridge. I will follow the steps described there and try to build that on a breadboard based on these schematics that are included in this blog post.

This schematics looks a bit like what we have created thus far, but there is a small addition in the form of a D-Flip flop. This circuit is included in the 74LS74 chip and luckily I still had one lying around. 

It latches the output of the A12 address line to the A14 input pin on the EPROM on each clock rise. 

Memory inside the EPROM at locations $8000 and $9000 is mirrored. And when either of them is addressed, bit number 12 toggles and switches between the lower and upper memory bank through the A14 address line.

Using this tick the cartridge can contain a total of 20 kilobytes of data.

Let's extend the circuit that we already have by first adding connections to the 2 new NAND gates. 74LS00 has 4 NAND chips, so we can use the remaining 2. The first one creates a NOT gate.

This jumper wire connects ROML on the cartridge post to the input of the NOT gate. I am making a mistake here by connecting to ROMH, but it will be fixed in a moment.
The output of this NOT gate connects to one of the inputs of the second NAND gate.
Now the clock output on the cartridge port is connected to the other input of the NAND gate.
This is the 74LS74 D-Flip flop chip. We connect power and ground to it.
The output of the second NAND gate connects to the clock input of the D-Flip flop.
This is the reset pin that will connect accordingly to the reset on the cartridge port.
And the D input on the latch connects to the A12 address line which we tap from pin number 2 on the EPROM.
The Q output connects to A14. First we need to get rid of this jumper wire that was pulling it to ground.
The set input connects to 5 volts.
And finally let's fix the mistake that we made in the beginning and switch the connection to the ROML instead of ROMH pin.

Now we can finally prepare the Super Zaxxon cartridge.

First we need to convert the CRT file to the binary format.

cartconv -i Super\ Zaxxon.crt -o zax.bin

The structure of this bin file will be like this:

first $1000 = 4K
$1000 - $3000 8K - bank 0
$3000 - $5000 8k - bank 1

Now we have to split up the binary file like it is described in the hackup.net blog post. 

I will first split the file in 4 kilobytes chunks using the split command.

split -b4k zax.bin zaxxon_split.

will create 4096 bytes files of:

zaxxon_split.aa
zaxxon_split.ab
zaxxon_split.ac
zaxxon_split.ad
zaxxon_split.ae

These chunks need to be concatenated to the final 32 kilobytes binary file using the cat command.

Concatinate to final rom: 4k, 4k, 8k (1), 4k, 4k, 8k (2)

cat zaxxon_split.aa zaxxon_split.aa zaxxon_split.ab zaxxon_split.ac zaxxon_split.aa zaxxon_split.aa zaxxon_split.ad zaxxon_split.ae > zaxxon_32k.bin

We can now write this file to the EPROM using this command:

minipro -p M27C256B@DIP28 -w zaxxon_32k.bin

I have connected the Super Zaxxon cartridge to the C64 with the custom PLA. Now we will find out if this cartridge that we have created works with my custom PLA chip. 

And.. we are getting something. It looks like our Super Zaxxon cartridge and the custom PLA is working correctly.