Skip to content

Replacement ROM for the Z80MC

September 29, 2015

It just feels too hard to figure out what’s going on with Josh’s monitor program so i’m going to figure out how to run my own code instead.  I have a 28C64 EEPROM which is close in pinout to the 27C256.  In fact, I have one that I previously used to replace a 27C64 in an old 1802 terminal.  It’s beat up but resocketed and has pin 27(/write enable) rewired to pin 1 and pin 26(not connected) rewired to pin 22.  I can’t remember why the pin 26 rewire was done but i don’t think it hurts anything.

In the ZMC CPU board, pin 1 of the ROM is tied to VCC so that’s fine and pin 22 is /Output Enable which shouldn’t matter.

To program it, I just have to move the whole mess to a breadboard where pin 1 will be /Write Enable.  I even have programmer code from the original project which was from 2008.  I don’t fully understand the comments about /WE in the code but I’ll figure it out:

//_13bit_prom_monitor.pde
/* PROM Monitor - 28c64 with active high enable and write lines
* designed to read/write a 28C64 eeprom or the prom from the msi/88e, 8kX8
* for experimenting with the MSI/88e 1802 handheld
* uses arduino pins 2-9 for Data 
* Uses arduino pins 12-18  for 7 bits of address 
* with 19 controlling a latch for the high bits (latches on high-low transition).
* this keeps pins 0 & 1 free for serial data 
* uses pin 10 for Write enable with inverter
* for reading the original ROM this pin has to be held low at the chip, high in the arduino
* and uses 11 for MRD
* this version implements 3 commands via serial from the PC:
*  d means display the source data
*  r means read the prom
*  w means write the prom from the source data
*/
#include <avr/pgmspace.h>
int datapins[] = {2,3,4,5,6,7,8,9};  //pins used for data connection to the ROM (D0-7)
int addrpins[] ={12,13,14,15,16,17,18}; //pins used for MA0-6, 7-13
int addrlen=7; //length of addresses in bits
int notlatchpin=19; //high to low transition latches the high address bits
int notreadpin=11; // used to toggle the -MRD line
int writepin=10; //used to toggle -WE (active high)
int count=0;
byte bitmasks[]={B00000001,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B10000000}; //masks for isolating bits in bytes
byte stepper=0;
#include <idiot4.h>
unsigned int addr; byte data; unsigned int addr0;
unsigned int progbegin; unsigned int progend;
int cksum=0;
void setup() {
  progbegin=msibgn; progend=msicnt-1;
//  progbegin=0; progend=1023;
  pinMode(notreadpin,OUTPUT);
  digitalWrite(notreadpin,HIGH);
  pinMode(writepin,OUTPUT);
  digitalWrite(writepin,LOW);
  pinMode (notlatchpin,OUTPUT);
  setaddrpins(addrlen,addrpins);
  pinMode(2,INPUT); pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(7,INPUT); pinMode(8,INPUT); pinMode(9,INPUT);
  Serial.begin(9600);
  Serial.println(" "); Serial.print(">");  //initial prompt
}

void loop(){
  char cmd=' ';
    if (Serial.available()>0){
        cmd=Serial.read(); Serial.print(cmd,BYTE);
        switch(cmd){
          case 'r': {Serial.println("ead");readprom(); break;}
          case 'w': {Serial.println("rite");writeprom(); break;}
          case 'd': {Serial.println("isplay");displaysource(); break;}
          default: {beep(); break;}
        }
        Serial.print(">");
    }
}

void beep(){
  Serial.print("?"); Serial.println(7,BYTE);
}

void displaysource(){
  cksum=0;
  for (addr=progbegin;addr<(progend+1);addr=addr+8){
    p3hex(addr); Serial.print(":");    
    for (addr0=addr;addr0<min(addr+8,(progend+1));addr0++){
      data = pgm_read_byte_near(msipgm+addr0);    //was      data=msipgm[addr0]; 
      cksum=cksum+data;
      Serial.print(" ");p2hex(data);
    } 
    Serial.println(" ");
    if (Serial.available()>0) {char dmmy=Serial.read(); break;}
  }
  Serial.print("checksum"); Serial.println(cksum,HEX);
}

void readprom(){
  cksum=0;
  for (addr=progbegin;addr<(progend+1);addr=addr+8){
    p3hex(addr); Serial.print(":");    
    for (addr0=addr;addr0<min(addr+8,(progend+1));addr0++){
      data=readone(addr0); cksum=cksum+data;
      Serial.print(" ");p2hex(data);
    } 
    Serial.println(" ");
    if (Serial.available()>0) {char dmmy=Serial.read(); break;}
  }
  Serial.print("checksum"); Serial.println(cksum,HEX);
}

void writeprom(){
  cksum=0;
  for (addr=progbegin;addr<(progend+1);addr=addr+8){
    p3hex(addr); Serial.print(":");    
    for (addr0=addr;addr0<min(addr+8,(progend+1));addr0++){
      data = pgm_read_byte_near(msipgm+addr0);    //was      data=msipgm[addr0];
      cksum=cksum+data;
      Serial.print(" ");p2hex(data);
      progone(data,addr0);
    } 
    Serial.println(" ");
    if (Serial.available()>0) {char dmmy=Serial.read(); break;}
  }
  Serial.print("checksum"); Serial.println(cksum,HEX);
}

void p2hex (byte toprnt){
  if (toprnt<16) Serial.print("0");
  Serial.print(toprnt,HEX);
}

void p3hex (unsigned int toprnt){
  if (toprnt<256) Serial.print("0");
  if (toprnt<16) Serial.print("0");
  Serial.print(toprnt,HEX);
}




void progone(byte data, unsigned int addr){
  byte databits[]={0,0,0,0,0,0,0,0}; //individual bits to be written
  splitbits(data,databits);
  pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(7,OUTPUT); pinMode(8,OUTPUT); pinMode(9,OUTPUT);
  writebits(8,datapins,databits);
  writeaddress(addr);
  commitwrite();  //toggle the write enable line
  pinMode(2,INPUT); pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(7,INPUT); pinMode(8,INPUT); pinMode(9,INPUT);
}
void setaddrpins(int addrlen, int addrpins[]){
//  pinMode(12,OUTPUT); pinMode(13,OUTPUT); pinMode(14,OUTPUT);  pinMode(15,OUTPUT);  pinMode(16,OUTPUT);  pinMode(17,OUTPUT); pinMode(18,OUTPUT); 
int indx;
  for (indx=0;indx<addrlen;indx++){
    pinMode(addrpins[indx],OUTPUT);
  }
}

void writeaddress(unsigned int addr){
  byte addrbits[]={0,0,0,0,0,0,0,0}; //individual address bits to be written
  byte halfaddr; //7 of 12 address bits 0-6 or 7-13 (only 12 used by rom)
  halfaddr=addr/128;  //isolate the top address bits
  splitbits(halfaddr,addrbits);
  digitalWrite(notlatchpin,HIGH); //prep the address latch
  writebits(7,addrpins,addrbits);  //write high address bits
  digitalWrite(notlatchpin,LOW); //latch the address
  halfaddr=addr%128; //low address bits
  splitbits(halfaddr,addrbits);
  writebits(7,addrpins,addrbits); //write low address bits
}

void commitwrite(){
  digitalWrite(writepin,HIGH);
  delay(100); //required delay is really only 100 NS
  digitalWrite(writepin,LOW);
  delay(50); //required delay is really < 10 MS
}

byte readone(unsigned int addr){
  byte byteread;
  byte databits[]={0,0,0,0,0,0,0,0}; //individual bits read in
  pinMode(2,INPUT); pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(7,INPUT); pinMode(8,INPUT); pinMode(9,INPUT);
  writeaddress(addr);
  digitalWrite(notreadpin,LOW);  //set the output enable line 
  delay(100);
  readbits(datapins,databits);
  digitalWrite(notreadpin,HIGH);  //reset the output enable line 
  byteread=assemblebits(databits); 
  return byteread;
}
byte assemblebits(byte inbits[]){
int indx=0; byte outbyte=0;
  for (indx=0;indx<=7;indx++){
    if((inbits[indx]==HIGH)) {
       outbyte=outbyte | bitmasks[indx];
    }
  }
return outbyte;
}

  
void splitbits(byte inbits, byte outbits[]){
int indx=0;
  for (indx=0;indx<=7;indx++){
    if((inbits & bitmasks[indx])!=0) {outbits[indx]=1;} else {outbits[indx]=0;}
  }
}

void writebits(int pincount, int pins[], byte bits[]){
  int indx;
  for (indx=0; indx<pincount;indx++) {
    digitalWrite(pins[indx],bits[indx]);
  }
}

void readbits(int pins[], byte bits[]){
  int indx;
  for (indx=0; indx<=7;indx++) {
    bits[indx]=digitalRead(pins[indx]);
  }
}
void stall(){
int countdown;
  Serial.print("Stalling.."); 
  for (countdown=10;countdown>=0;countdown--){
    Serial.print(countdown); Serial.print("...");
    delay(500);
  }
  Serial.println(""); 
  Serial.println("Done!"); 
}

15-09-29 eeprom 2 15-09-29 eeprom1
UPDATE: OOPS now – I see that pin 22 is actually lifted and depends on 26 for input. Looking back at old old notes, it was not a 27c64 being replaced, it was a CM6400-3C presumably the pinout is a bit different. Still, the idea survives, lift the W/E pin and top solder to pin 1. Leave 26/22 alone. I don’t think I can reuse that butchered chip because pin 12 looks wonky too. I have several others similarly butchered but i won’t trust them because i have a feeling they might be blown.

Advertisements

From → Olduino/Z

2 Comments
  1. Josh’s code isn’t too hard to understand once you remove the keypad and LED scanning stuff. I’m in the process of adapting it as a serial/console monitor for the RC2014, another cool Z80 kit.

    • well yeah! If you can figure out how to decruft those routines I’ll be very interested. Are you planning to stick with 9600 baud? My goal was to get to 19,200.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: