Read Atari game ROM with Arduino
Sun, Nov 22, 2009 at 6:54PMThe 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) } }