Outils pour utilisateurs

Outils du site


Pac-Man Atari 2600

This is a simple, solderless, project using our PTL-ino to read out the Pac-Man Atari 2600 cartridge.

Status

Status du project
Date de début 12/2015
Status Done
Initiateur Magnus

"Shield" description

Well, it's not a shield but rather jumper wire spaghetti: All you need is an old floppy drive cable with 5-1/4“ floppy connector and a bunch of jumper wires.

The trick is that the floppy cable has a slot connector which mates well with the cartridge. There is only one small alignment problem: the cable is keyed and the PCB on the cartridge has some margin. I had to use the next-to-first pin after the key to connect to pin 1 of the cartridge.

This is the view of the opened cartridge (you need to insert some pin to make the dust protection open): The edge connector should mate with the floppy cable: If you look closely you can see that the floppy connector is keyed and that the edge connector is a bit too wide as that the first pin would match the first slot spring on the connector. If one tries to align it by pressing the cartridge towards the key, many pins are shorted to each other. For a proper connection, one needs to offset it by one (which require some trying). This offset can also be seen by the position of the jumper wires. Finally, this is how it looks like:

The Atari 2600 catridge of Pac-Man is essentially an asynchronous 4K memory. That means you set the address to 12 address pins and it will put out the data byte to 8 data pins. This totals to 20 I/Os. The PTL-ino would have them (14 digital + 6 analog), but then there wouldn't be anything left for communicating the reading results to the PC. For simplicity the following approach is followed: digital pins 0 and 1 are used for serial communication with the PC as usual, and only 10 out of the 12 address lines are driven from the PTL-ino – the other two are driven by you the user (see below).

While trying if everything is wired up properly, I measured the supply current to the cartridge: Yes, let's have a close look: This is 50 mA static power consumption. I googled it a bit and apperently it is not too far of from what one should (have) expect(ed)… no warranties, but see below, it worked!

Sketch

This should be quite self-explanatory:

#define BAUD 9600
 
#define PIN_D0  2
#define PIN_D1  3
#define PIN_D2  4
#define PIN_D3  5
#define PIN_D4  6
#define PIN_D5  7
#define PIN_D6  8
#define PIN_D7  9
 
#define PIN_A0 10
#define PIN_A1 11
#define PIN_A2 12
#define PIN_A3 13
#define PIN_A4 A0
#define PIN_A5 A1
#define PIN_A6 A2
#define PIN_A7 A3
#define PIN_A8 A4
#define PIN_A9 A5
 
void setup() {
 Serial.begin(BAUD);
 pinMode(PIN_D0,INPUT );
 pinMode(PIN_D1,INPUT );
 pinMode(PIN_D2,INPUT );
 pinMode(PIN_D3,INPUT );
 pinMode(PIN_D4,INPUT );
 pinMode(PIN_D5,INPUT );
 pinMode(PIN_D6,INPUT );
 pinMode(PIN_D7,INPUT );
 pinMode(PIN_A0,OUTPUT);
 pinMode(PIN_A1,OUTPUT);
 pinMode(PIN_A2,OUTPUT);
 pinMode(PIN_A3,OUTPUT);
 pinMode(PIN_A4,OUTPUT);
 pinMode(PIN_A5,OUTPUT);
 pinMode(PIN_A6,OUTPUT);
 pinMode(PIN_A7,OUTPUT);
 pinMode(PIN_A8,OUTPUT);
 pinMode(PIN_A9,OUTPUT);
}
 
void loop() {
 for (uint16_t addr=0;addr!=1024;++addr) {
   digitalWrite(PIN_A0,addr&1<<0?HIGH:LOW); 
   digitalWrite(PIN_A1,addr&1<<1?HIGH:LOW); 
   digitalWrite(PIN_A2,addr&1<<2?HIGH:LOW); 
   digitalWrite(PIN_A3,addr&1<<3?HIGH:LOW); 
   digitalWrite(PIN_A4,addr&1<<4?HIGH:LOW); 
   digitalWrite(PIN_A5,addr&1<<5?HIGH:LOW); 
   digitalWrite(PIN_A6,addr&1<<6?HIGH:LOW); 
   digitalWrite(PIN_A7,addr&1<<7?HIGH:LOW); 
   digitalWrite(PIN_A8,addr&1<<8?HIGH:LOW); 
   digitalWrite(PIN_A9,addr&1<<9?HIGH:LOW); 
   uint8_t b=0;
   if (digitalRead(PIN_D0)==HIGH) b|=1<<0;
   if (digitalRead(PIN_D1)==HIGH) b|=1<<1;
   if (digitalRead(PIN_D2)==HIGH) b|=1<<2;
   if (digitalRead(PIN_D3)==HIGH) b|=1<<3;
   if (digitalRead(PIN_D4)==HIGH) b|=1<<4;
   if (digitalRead(PIN_D5)==HIGH) b|=1<<5;
   if (digitalRead(PIN_D6)==HIGH) b|=1<<6;
   if (digitalRead(PIN_D7)==HIGH) b|=1<<7;
   char tmp[4];
   sprintf(tmp,"%02X",b);
   Serial.print(tmp);
   if (addr%16==15)
     Serial.println();
   else
     Serial.print(' ');
 }
 while (!Serial.available());
 Serial.read();
}

Only remark: as you can see only 1K is read out by this sketch, the address bits 10 and 11 are not steered.

Reading procedure

Once all is wired, the user has to do 4 reads of 1K each. This can be done as follows:

  1. program the sketch and open the serial console
  2. connect A10 and A11 to GND
  3. clear the console
  4. enter any character
  5. now the first 1K is dumped in hex into the console
  6. connect A10 to +5V
  7. enter any character
  8. now the second 1K is dumped (appended) to the console
  9. repeat with A11,A10=+5V,GND and A11,A10=+5V,+5V
  10. copy the whole console content into a text file pacman.hex

Post processing

Only thing left is converting the hex into a binary file (well, the sketch could have sent binary directly, but this would IHMO be more awkward to save to file).

$ xxd -r -p pacman.hex > pacman.bin

Let's hash this!

$ md5 pacman.bin
MD5 (pacman.bin) = fc2233fc116faef0d3c31541717ca2db

Search the web for the MD5!

Game play

Long story short: it was fun to read the cartridge, but it seems that the emulator for Pac-Man still needs to be developed. The flickering ghosts (one ghost per frame) seems to be too much for all phosphor emulators I have tried (they seem to blend two frames max). Any hint welcome!

Epilog

This project works explicitly with a 4K cartridge. There are other sizes out there and a lot of tricks were employed to reach larger values (makes a very interesting read, see links below). For these this sketch will not work.

projects/electronics/ptl-ino/pacman-atari2600.txt · Dernière modification: 2016/03/27 23:54 par magnustron