8-bit breadboard computer – eeprom programmer

Part of the output display of the 8-bit computer relies on an eeprom to drive the 7-segment displays. In order to program the eeprom, I needed to build a programmer.

In Ben Eater’s youtube series, he builds a programmer with an arduino nano and a couple of shift registers because the nano doesn’t have enough digtal pins to program the parallel eeprom.

I had an arduino mega with plenty of digital pins, so I used it instead.

I essentially made up a shield for the arduino with a 40 pin zif socket and soldered each pin of the socket to a digital pin on the arduino.

Well, not quite every pin. That is a lot of wires.

I will eventually solder every pin, but for now, I’ve got enough to cover the 28C16 eeproms.

/images/eeprom_programmer_web.jpg

The idea was to manipulate the pins in the sketch to fit any similar eeprom up to 40 pins. To do that, I have to define the VCC and GND pins as OUTPUT pins in the sketch and set them to HIGH and LOW respectively.

Unfortunately, it seems that the eeprom draws too much current from the digital pins, so the voltage topped out at ~2 volts.

I soldered on the orange wire above to the 5v rail and connected it to VCC and that seemed to fix the problem.

The code I am using is below. It is mostly modified from Ben’s code.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// define pin mapping for ZIF socket

#define ZPIN3 53
#define ZPIN4 52 
#define ZPIN5 51
#define ZPIN6 50
#define ZPIN7 49
#define ZPIN8 48
#define ZPIN9 47
#define ZPIN10 46
#define ZPIN11 45
#define ZPIN12 44
#define ZPIN13 43
#define ZPIN14 42
#define ZPIN15 41
#define ZPIN16 40
#define ZPIN17 39
#define ZPIN18 38
#define ZPIN19 37
#define ZPIN20 36
#define ZPIN21 35
#define ZPIN22 34
#define ZPIN23 33
#define ZPIN24 32
#define ZPIN25 31
#define ZPIN26 30
#define ZPIN27 29
#define ZPIN28 28
#define ZPIN29 27
#define ZPIN30 26
#define ZPIN31 25
#define ZPIN32 24
#define ZPIN33 23
#define ZPIN34 22



// define pin map for 28C16 EEPROMs

#define GND ZPIN20
#define VCC ZPIN32

#define WRITE_ENABLE ZPIN29  // E PIN 21 - Active LOW
#define OUTPUT_ENABLE ZPIN28 // E PIN 20 - Active LOW
#define CHIP_ENABLE ZPIN26    // E PIN 18 - Active LOW

#define ADDRESS_0 ZPIN16  // E PIN 8
#define ADDRESS_1 ZPIN15  // E PIN 7
#define ADDRESS_2 ZPIN14  // E PIN 6
#define ADDRESS_3 ZPIN13  // E PIN 5
#define ADDRESS_4 ZPIN12  // E PIN 4
#define ADDRESS_5 ZPIN11  // E PIN 3
#define ADDRESS_6 ZPIN10  // E PIN 2
#define ADDRESS_7 ZPIN9   // E PIN 1
#define ADDRESS_8 ZPIN31  // E PIN 23
#define ADDRESS_9 ZPIN30  // E PIN 22
#define ADDRESS_10 ZPIN27 // E PIN 19

#define IO_0 ZPIN17 // E PIN 9
#define IO_1 ZPIN18 // E PIN 10
#define IO_2 ZPIN19 // E PIN 11
#define IO_3 ZPIN21 // E PIN 13
#define IO_4 ZPIN22 // E PIN 14
#define IO_5 ZPIN23 // E PIN 15
#define IO_6 ZPIN24 // E PIN 16
#define IO_7 ZPIN25 // E PIN 17


const int ADDRESS_PINS[] = { ADDRESS_0, ADDRESS_1, ADDRESS_2, ADDRESS_3, ADDRESS_4, ADDRESS_5, ADDRESS_6, ADDRESS_7, ADDRESS_8, ADDRESS_9, ADDRESS_10 };
const int IO_PINS[] = { IO_0, IO_1, IO_2, IO_3, IO_4, IO_5, IO_6, IO_7 };

void setAddress(int address) {   
    for (int i = 0; i < (sizeof(ADDRESS_PINS)/sizeof(int)); i++ ) {
        digitalWrite(ADDRESS_PINS[i], address >> i & 1);
    }
}


byte readByte(int address) {
    for ( int i = 0; i < (sizeof(IO_PINS)/sizeof(int)); i++ ) {
        pinMode(IO_PINS[i], INPUT);
    }
    
    setAddress(address);
    
    digitalWrite(OUTPUT_ENABLE, LOW); // output byte from eeprom

    byte data = 0;
    for ( int i = (sizeof(IO_PINS)/sizeof(int)); i >= 0; i-- ) {
        data = (data << 1) + digitalRead(IO_PINS[i]);
    }
    digitalWrite(OUTPUT_ENABLE, HIGH); // stop eeprom outputting byte
  
    return data;
}


void writeByte(int address, byte data) {
    setAddress(address); 
    for (int i = 0; i < (sizeof(IO_PINS)/sizeof(int)); i += 1) {
        pinMode(IO_PINS[i], OUTPUT);
        delayMicroseconds(10);
        digitalWrite(IO_PINS[i], data & 1);
        data = data >> 1;  
    }
    delay(10);
  
    digitalWrite(WRITE_ENABLE, LOW);
    delayMicroseconds(1);
    digitalWrite(WRITE_ENABLE, HIGH);
  
    delay(10);

}

void printContents(int start, int length) {
    for (int base = start; base < length; base += 16) {
        byte data[16];
        for (int offset = 0; offset <= 15; offset += 1) {
            data[offset] = readByte(base + offset);
        }

        char buf[80];
        sprintf(buf, "%03x:  %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x      %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x",
            base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
            data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);

        Serial.println(buf);
    }
}




void eraseEEPROM() {
    // Erase entire EEPROM
    Serial.print("Erasing EEPROM");
    for (int address = 0; address < 2048; address += 1) {
        writeByte(address, 0xff);

        if (address % 64 == 0) {
            Serial.print(".");
        }
    }
    Serial.print(" done.");
    Serial.println();
    printContents(0, 2048);
}



void setup() {
 
    Serial.begin(57600);

    // SETUP CHIP

    // power chip
    pinMode(VCC, OUTPUT);
    digitalWrite(VCC, HIGH);
  
    pinMode(GND, OUTPUT);
    digitalWrite(GND, LOW);
  
    // write disabled
    pinMode(WRITE_ENABLE, OUTPUT);
    digitalWrite(WRITE_ENABLE, HIGH);

    // output disabled
    pinMode(OUTPUT_ENABLE, OUTPUT);
    digitalWrite(OUTPUT_ENABLE, HIGH);
  
  
    // chip enabled
    pinMode(CHIP_ENABLE, OUTPUT);
    digitalWrite(CHIP_ENABLE, LOW);

    // set address pins as OUTPUTs
    for (int i = 0; i <= 10; i += 1) {
        pinMode(ADDRESS_PINS[i], OUTPUT);
    }
  
    delay(1000);


    // END SETUP

    
 
    //eraseEEPROM();

    
    /*
    byte data[] = { 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47 };

    Serial.print("Programming EEPROM");
    for (int address = 0; address < sizeof(data); address += 1) {
        writeByte(address, data[address]);

        if (address % 64 == 0) {
            Serial.print(".");
        }
        delay(10);
    }
    Serial.println(" done");
    */
    
    printContents(0, 2048);
}


void loop() {}