Cookies and Capacitors

Read Atari game ROM with Arduino

Sun, Nov 22, 2009 at 6:54PM

The purpose of this project was to see if it would be possible to read the contents of a ROM chip (from the Atari 2600 game, Laserblast) and broadcast the data over a serial line, using nothing more than an Arduino. The breadboard I used, as seen above, could certainly be neater without the debugging LEDs set up, however, I saw them to be crucial in understanding how ROM chips work.

Before starting this project, I knew absolutely nothing about the internal structure of memory chips. After hours of Web searching, I only had a pinout of some EEPROMs and a childlike sense of wonder, speculating how they work. After I spent the better part of a night trying to read the memory values of the ROM, I finally had success after removing the Arduino from the project entirely, and gave the ROM chip direct wiring to the positive and ground planes of my breadboard. How did I know that I was successful? Well, earlier I downloaded the ROM file of the game I was trying to read. After opening this ROM file in a hex editor, the values of each memory location were shown, allowing me to compare the value in the memory location I was reading on my breadboard to that of which the hex editor displayed.

Once I spent a few hours figuring out how ROM can be read, I was able to whip up a quick Arduino program that would enable the chip, set the address lines to the correct binary location, and read the state of the data lines.

For your viewing pleasure, here are some images of my project.

Lastly, here’s the code I used, it should be simple enough to find out how it’s wired (there are comments). EDIT: It’s been a while since I wrote this, and I’m too lazy to draw up a schematic.

EDIT 2: After switching CMSs a few times, this code’s spacing has been screwed up. I’m not going to fix this, since it’s so old.

//**************************************************************//
// Name  : Arduino ROM Reader                 //
// Author : Davis Remmel (davisr)               //
// Date  : 20 Oct, 2009                    //
// Version : 1.0                        //
// Notes  : Used for reading Atari 2600 ROM to         //
//     : serial port                    //
//**************************************************************// 

#include "pins_arduino.h" 

#define myDigitalRead(pin) ((*portInputRegister(digitalPinToPort(pin)) \
              & digitalPinToBitMask(pin)) ? HIGH : LOW) 

#define ROM_SIZE 2048 // In bytes 

//Pin connected to ST_CP of 74HC595
int latchPin = 10;
//Pin connected to SH_CP of 74HC595
int clockPin = 11;
//Pin connected to DS of 74HC595
int dataPin = 12;

int data = 0; // Used in counting up to the ROM's maximum byte 

byte myByte = 0x00; // Used later as D[0..7] byte 

void **setup**() {
 Serial.begin(9600); // Begin serial mode 

 pinMode(latchPin, OUTPUT); // Set pin status for shift registers
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
}

void **loop**() {
 digitalWrite(latchPin, LOW); // Make shift register listen for data 

 if(data < ROM_SIZE) { // Collect data for every byte in the ROM
 shiftOut(dataPin, clockPin, MSBFIRST, (data >> 8)); // Send data for two shift registers
 shiftOut(dataPin, clockPin, MSBFIRST, data);

 //shiftOut(dataPin, clockPin, MSBFIRST, 0x00); 
 //shiftOut(dataPin, clockPin, MSBFIRST, 0x02);
 digitalWrite(latchPin, HIGH); // Shift register no longer listens for data
 delay(5); // Delay a bit so the shift registers have enough time to output data before being read by the Arduino again
 myByte = myDigitalRead (9) // Read the byte using Arduino pins [2..9] for each digit
      | myDigitalRead (8) << 1 
      | myDigitalRead (7) << 2
      | myDigitalRead (6) << 3
      | myDigitalRead (5) << 4
      | myDigitalRead (4) << 5
      | myDigitalRead (3) << 6
      | myDigitalRead (2) << 7;
 Serial.write(myByte); // Write the collected data byte to the serial port
 data++; // Increase byte read by one
 delay(5); // Delay a bit before reading (may not be necessary)
 }
}