Project:65 EEPROM Programmer, Part 1

As I mentioned last week, the next step for my Project:65 computer is to get it to run a real program. Now, how do we get that program into the computer?

On some of the first microcomputers – I’m talking about machines like the Altair 8800 or the IMSAI 8080 – the operator would load a program into RAM using a series of switches on the front panel of the machine. You’d use the switches to specify the bits of an address and a single data byte, and then latch that value into memory while the CPU was paused. There’s a cool video here of someone starting up an Altair this way. Frankly, it looks like a lot of work – and every time you reset the machine, you have to do it all over again.

If you move forward a generation – to the Apple II and Commodore PET, for example – you get machines with at least a boot loader in ROM – and sometimes a BASIC interpreter, too. That seems a little more my speed, so that’s the route I’m going to pursue for Project:65.

I spent some time prowling through catalogs and reading up on other people’s projects, and found that there are lots of approaches to adding permanent storage to a computer project. For example, I found some flash memory with an SPI interface which might come in handy further down the road, but that’s not quite what I need at this stage. I needed some kind of programmable ROM chip that I could easily connect to the 65c02’s bus.

For my first try, I’m using a 28c65 EEPROM chip that I found online cheap. It’s got 8KB of storage, an 8-bit data bus, and a 13-bit address bus. Now the idea with an EEPROM (that’s “Electrically erasable programmable read-only memory”) is that you can put it in an EEPROM programmer, erase it, and write new data to it. After that, it’s nonvolatile – the data you write to it stays there until you deliberately erase it. So I can write a program to it and then hook it up to my 65c02 as if it were a regular old ROM chip.

There’s just one problem: Programmers for writing data to these chips are expensive – the ones I found online were $300 and up, which is quite a bit of money for a tool I don’t intend to use all that often. There’s a cheaper option, though – I should be able to hook this chip up to a microcontroller and program it that way. It’s just a matter of putting the right signals on the right pins at the right time.

Right?

The first thing I had to decide was which board I was going to use as the base for my homebrew EEPROM programmer – my Arduino or my Raspberry Pi. I’ve been wanting to do more stuff with the Pi, but I decided to start with the Arduino for two reasons: One, that it has more I/O pins, and two, that it runs at 5v instead of the Pi’s 3.3v. The 28c65 is a 5v part, like the 65c02, and while I think I kind of, sort of, know how to deal with the level conversion, it’s one more problem that I’d just as soon not worry about.

Once I’d decided on using the Arduino, two problems jumped out at me. The first was that I still didn’t have enough I/O pins. The EEPROM has 8 data lines, 13 address lines, plus a “chip select”, “output enable”, and “write enable” that I needed to use. That’s 24 pins to the Arduino’s 14. That’s what led me to the 23017 port expander chips I talked about last week. Two of those add 32 I/O pins, and they leave most of the Arduino’s own pins free. After playing with them, I was pretty confident I could use them to do what I needed.

The Arduino Ethernet Shield attaches to the top of an Arduino, and adds an Ethernet port and an SD card slot. The Arduino interfaces with them via the SPI serial protocol.

The second problem was storage. I needed some place to put the 8KB data image while I was writing it to the EEPROM. That actually requires a lot of space, by Arduino standards. With 2 KB of RAM, I wouldn’t be able to keep an entire image in memory. Since the Arduino has 32 KB of Flash memory for storing programs, I could build the data into my program, but that also seemed kind of inflexible.

My solution to the storage problem was the Arduino Ethernet Shield. I got one of these for my last birthday (Thanks Mom!) and hadn’t really had a chance to use it for a project yet. Ironically, I’m still not using the Ethernet connector – so far, I’m just using it for its MicroSD slot. A cheap 8GB MicroSD card will store a lot of ROM images. The Arduino talks to the SD controller by SPI, but there’s a library that sets this up, manages reading the FAT32 filesystem, and provides a straightforward file API.

The actual breadboard circuit to put this together (see below) is conceptually straightforward – you’re basically just hooking up the 28c65’s pins to the two port expanders – but there are a lot of wires to connect. I had two trouble spots trying to get this all assembled correctly. The first tricky bit is that the upper 5 bits of address lines on the EEPROM are kind of scattered all over – pins A8, A9, and A11 are adjacent, but then A10 is out of order, and A12 is on the other side of the chip. The second problem was that I got confused about which side of the 23017s was Port A and which was Port B. In my first attempt, I had the addresses in the software backwards. Oops!

For the record, here’s the mapping I ended up with. In the diagram, 23017 #1 is on the right, and the two Port As are at the top:

23017 #1, Port A: Address bits 8 through 12

23017 #1, Port B: Address bits 0 through 7

23017 #2, Port A: Control Lines (Chip, Write & Output Enable)

23017 #2, Port B: Data bits 0 through 7

Circuit diagram for the EEPROM burner. The ICs are, from left to right, the 28c65 EEPROM, 23017 Port Expander #2, and 23017 Port Expander #1

In the diagram below, the address lines are shown in white and the data lines in blue. The I²C lines from Arduino to the 23017s are in green, and the three control lines are shown in orange.

Once I got the hardware set up the way I wanted, the next step was to write the software – the Arduino sketch that would control all those data lines and actually read and write data to the EEPROM chip. That’s a topic in its own right, so come back next week and we’ll trade in our circuit diagrams for source code and see if this thing really works (Spoiler: it does).

That’s not a bad idea. I started out this way because having two separate circuits felt like the absolute simplest thing to try first, and also because I like the idea of being able to operate without any external microcontrollers attached.

I might revisit the idea once I get the RAM and some IO in place. At that point I’ll need to spend more time with the software, and it’ll be good to be able to rapidly iterate.