Go Down

Topic: Reading obsolete ROMs (Read 1 time) previous topic - next topic

W4OLF

Mar 07, 2015, 08:51 pm Last Edit: Mar 10, 2015, 06:05 pm by W4OLF Reason: Simplified read data function
The Mega 2560 works great for reading odd-pinout ROMS. It has enough I/O pins to eliminate the need for additional latch ICs.

I needed to read a 68766 EPROM from my 1980s vintage Radio Shack Color Computer, but my GQ-4X E/EEPROM burner wouldn't handle it. This chip has a 24-pin non-JEDEC-standard pinout. By hooking up the digital I/O pins to the address and data lines as well as Output Enable I was able to use the sketch below to read the data and send it via the serial output in standard Motorola S-Record format which I copied to a text file and then converted to a binary image.

I also used it to make a backup copy of my Digitalker Speech ROMs (same pinout) in another project in case these hard-to-find chips ever fail and are not available in the future. One of each pair of these chips has an inverted Enable pin so a simple software change fixes that without rewiring or adding inverters.

It is easy to change the sketch or add more address lines to accommodate larger ROMs



Code: [Select]
///////////////////////////////////////////////////////////
//                                                       //
//  Arduino Mega 2560                                    //
//                                                       //
//  EEPROM/EPROM/ROM Reader for 24 pin 68766 type        //
//                                                       //
//                                                       //
///////////////////////////////////////////////////////////


// Digital I/O pin assignments
const int romOE = 43;  // ROM /output enable

const int romA0 = 30;  // ROM address lines
const int romA1 = 31;
const int romA2 = 32;
const int romA3 = 33;
const int romA4 = 34;
const int romA5 = 35;
const int romA6 = 36;
const int romA7 = 37;
const int romA8 = 38;
const int romA9 = 39;
const int romA10 = 40;
const int romA11 = 41;
const int romA12 = 42;

const int romD0 = 22;  // ROM data lines
const int romD1 = 23;
const int romD2 = 24;
const int romD3 = 25;
const int romD4 = 26;
const int romD5 = 27;
const int romD6 = 28;
const int romD7 = 29;

// Global variables
word romAddr = 0;     // 13-bit current address
byte romData = 0;     // Eight-bit ROM data
byte romChkSum = 0;   // Eight-bit checksum
char hexBuffer[8];    // Buffer for hex conversion to string

void setup()
{
  Serial.begin(115200);           // Enable serial output

  // Set I/O initial parameters
  pinMode(LED_BUILTIN, OUTPUT);  
  digitalWrite(LED_BUILTIN, LOW); // Turn off activity indicator

  pinMode(romOE, OUTPUT);
  digitalWrite(romOE, HIGH);      // Negate ROM output enable

  for (int i = 0; i < 13; ++i)
  {
    pinMode(romA0 + i, OUTPUT);   // Set direction of ROM address lines
  }

  for (int i = 0; i < 8; ++i)
  {
    pinMode(romD0 + i, INPUT);    // Set direction of ROM data lines
  }

  ResetAddr();                    // Set current ROM address to 0x0000
  delay(8000);                    // Delay for time to open serial window in IDE to capture output
}

void loop()
{
  digitalWrite(LED_BUILTIN, HIGH);        // Turn on activity indicator
  
  // Read ROM and send data to serial port in Motorola S-record format
  for (int records = 0; records < 512; ++records)  
  {                                       // 512 16-byte records in 8k x 8 ROM
    Serial.print("S113");                 // Print record header and count to serial port
    romChkSum = 0x13;                     // Initialize checksum for 16-byte records
    OutputHexWord(romAddr);               // Print ROM address to serial port and update checksum
    for (int i = 0; i < 16; ++i)
    {                                     // Send 16 bytes of data per line
      romData = ReadData();               // Get eight-bit data from ROM at current address
      OutputHexByte(romData);             // Print ROM data byte to serial port and update checksum
      IncrAddr();                         // Increment ROM address lines
    }
    OutputHexByte(~romChkSum);            // Output one's complement of eight-bit checksum
    Serial.println("");                   // Print end-of-line to serial port
  }
  digitalWrite(LED_BUILTIN, LOW);         // Turn off activity indicator
  while(1);                               // Loop continuously until reset
}

void ResetAddr()                          // Reset ROM address bus to 0x0000
{
  romAddr = 0;                            // Reset address variable
  for (int i = 0; i < 13; ++i)
  {                                       // 13 address lines for 8k x 8 ROM
    digitalWrite(romA0 + i, LOW);         // Set all ROM address lines low
  }
}

void IncrAddr()                           // Increment to next address
{
  for (int i = 0; i < 13; ++i)            // Start with A0, check each bit through A12
  {
    if (bitRead(romAddr, i) == 0)         // Check current bit; if zero, increment current ROM address bit
    {                                     //   and equivalent ROM address bit output, then return,
      bitSet(romAddr, i);                 //   since no carry is needed.
      digitalWrite((romA0 + i), HIGH);
      return;
    }
    bitClear(romAddr, i);                 // Otherwise, clear current address bit and equivalent ROM
    digitalWrite((romA0 + i), LOW);       //   address bit output, then loop to increment
  }                                       //   next higher address bit.
}

byte ReadData()                           // Read 8-bit ROM data at current address
{  
  byte result;                            // Eight-bit result
 
  digitalWrite(romOE, LOW);               // Assert ROM output enable
  delayMicroseconds(10);                  // Delay to let data lines settle
  result = 0;                             // Initialize result
  for (int i = 0; i < 8; ++i)
  {                                       // Check D0 through D7 and insert high bits into result
    if (digitalRead(romD0 + i) == HIGH)
      bitSet(result, i);
  }
  digitalWrite(romOE, HIGH);              // Negate ROM output enable
  return result;                          // Return result to caller
}

void OutputHexWord(word WordData)         // Send 16-bit address to serial port and update checksum
{
  byte byteData;                          // Eight-bit temporary variable
  
  byteData = highByte(WordData);          // Get MS byte
  sprintf(hexBuffer, "%02X", byteData);   // Print formatted byte to buffer
  Serial.print(hexBuffer);                // Print buffer to serial port
  romChkSum += byteData;                  // Add to checksum
  byteData = lowByte(WordData);           // Get LS byte
  sprintf(hexBuffer, "%02X", byteData);   // Print formatted byte to buffer
  Serial.print(hexBuffer);                // Print buffer to serial port
  romChkSum += byteData;                  // Add to checksum
}

void OutputHexByte(byte ByteData)         // Send 8-bit data to serial port and update checksum
{
  sprintf(hexBuffer, "%02X", ByteData);   // Print formatted byte to buffer
  Serial.print(hexBuffer);                // Print buffer to serial port
  romChkSum += ByteData;                  // Add to checksum
}

georgedb

You backed up the SSR1/2/5/6 ROM's for the Digitalker. Did you store these dumps somewhere on the internet, I'd be ighly interested to have a copy...

sswcharlie

Would like to contact   W4OLF above poster re this subject.  Are you on board at the moment ?

Charles Harris

Paul_KD7HB

Would like to contact   W4OLF above poster re this subject.  Are you on board at the moment ?

Charles Harris
Sign up for QRZ.com and enter w4olf. Should see his email there.

Paul

Go Up