Zolatron 64: Interfacing the 6502 with the Raspberry Pi

Pretty much every computer needs persistent storage. And these days we’re spoiled for choice – everything from hard drives down to micro SD cards being capable of holding more information than I can comfortably imagine.

With clever interfaces, these options are also open to builders of homebrew computers, like the 6502-based Zolatron 64 (Z64). But it does mean grappling with various protocols and understanding file system structures, which is all good learning material. But it’s not discovery.

I’ve decided to roll my own persistent storage, taking advantage of the Raspberry Pi that’s already attached to the Zolatron. This Pi Zero 2 W is linked via a serial interface and is how I interact with the Zolatron. But a serial interface uses only two GPIO pins on the Pi, and it’s a shame to see all the others being wasted.

Cunning plan

So here’s the plan. I’m going to use a 65C22 Versatile Interface Adapter (VIA) on the Z64 to talk to the Pi. The 65C22 has 16 I/O pins, much like the GPIO of the Pi. They are arranged in two ports. I’m using all eight pins of Port A as a parallel 8-bit data bus. And I’m using some (currently four) pins on Port B as control signals.

I’m not going to get fully into this solution here. For one thing, although working, it’s still a work in process. What I am going to talk about is the first issue I had to face, for which I thought I had a solution – but didn’t.

The 65C22 pins operate at 5V. The Raspberry Pi’s GPIO pins use 3.3V.


Too slow

My immediate instinct was to make use of the handy TXB0108 chip. This is a bidirectional level shifter and I’ve employed it many times in the past (usually in the form of Adafruit’s handy breakout board) to deal with incompatible voltage levels.

But when I hooked up all the wires, and nothing was working, I started to get a sinking feeling. And, as always at this point, out came the oscilloscope.

Signals travelling from the 5V side to the 3.3V side were doing fine. High (logic 1) signals going the other way were also getting through okay. It’s when a pin on the 3.3V side needed to pull a signal to 0V that things were going quack-quack-oops. The signal level never got below around 2.5V.

Note how the blue line never gets to zero. It’s also noisy as hell.

The TXB0108 is known for being somewhat weak at driving lines – it’s inherent in its design. I suspected that something is pulling the lines high and the TXB0108 isn’t capable of overriding it. As we’ll see, that may have turned out to be true.

The control signals are not a problem because they travel in only one direction. I can directly connect signals going from the Pi to the Zolatron because the 65C22 will accept the 3.3V signals as valid highs. And for the (currently two) signals going from the 65C22 to the Pi, I’m using simple resistor-based voltage dividers (with 2.2KΩ and 3.3KΩ resistors).

It’s the data bus that’s a problem, because it needs to be bidirectional.

Divide and conquer

I asked over on 6502.org and got lots of good ideas. Someone pointed out that a resistor divider approach should work in both directions. But it didn’t. I still have the same problem of the Pi being unable to pull the line to 0V.

The level shifter for the data bus. From left-to-right: wires going to the 65C22 port (plus a ground wire); 2K2 resistors; wires going to the Raspberry Pi; header pins for attaching scope or logic analyser probes; 3K3 resistors; plus a row of pins all connected to GND for the scope probe ground leads.

That drove me back to the datasheet for the 65C22. In particular, I wanted to look at different variants. I’d previously encountered a not-dissimilar problem which entailed the addition of a diode (I’ll go into that some other time. EDIT: Actually, I already wrote about it here.).

A smaller resistor divider for four signals going from 65C22 to Raspbbery Pi; plus four direct connections. The Raspberry Pi is in the backgroound. And yes, electronics experiments are meant to look like this.

What I found was interesting.

I had been using the ‘N’ version of the WDC65C22. Here’s the schematic for one of the I/O pins.

Now, imagine we’re using this as an input (which is our problem case). Reading from left to right, the DDR line will be 0, which is flipped to a 1 by the inverter. It doesn’t matter what the DATA line is doing. The output of the NAND gate will be 0, which goes to the gates of two MOSFETs.

The lower MOSFET is N-channel, where the transistor turns on when there is a positive voltage on the Gate relative to the Source (which, in this case is the lower connection, tied to GND). That’s not the case here, so the transistor is off.

The top MOSFET is a P-channel version. With this type, the transistor is turned on when there is a negative voltage on the Gate relative to the Source (here it’s the top-most connection). That is the case in this instance, so the transistor turns on and there will be 5V provided to the pin via the current-limiting resistor. It’s effectively a pullup resistor!

So there’s the root of my problem.

But let’s look at the ‘S’ version of the 65C22.

We still have the totem-pole MOSFETs, but with no power-limiting (or pullup) resistor. Also, the signal path is different. I’ll spare you the blow-by-blow, but the outcome is that, when DDR is 0 (input mode) both transistors are turned off.

I pulled out the 65C22N and replaced it with a 65C22S – still using the simple resistor-based voltage dividers – and lo! It worked!

In spite of the fuzziness, this is actually working.

The downside of this is that the PCB I’m planning will require 24 resistors for the 12 signals lines that need to have level shifting (including two spares).

But wait!

Then I had a thought. (It happens occasionally.)

If my problem was to do with using the wrong version of the 65C22, could I go back to the TXB0108 level shifter chip? That would make life a lot simpler.

I rewired everything, switched on and … nope. Didn’t work. And a few minutes with the oscilloscope provided some evidence as to why this is. Some of the signals are quite brief, and I think the TXB0108 is just too slow.

I also tried out the TXU0104. This is from the same family of chips, but is unidirectional, which I thought might make it faster. But this had the same problem.

This is using the TXU0104. It’s trying to pull the signal low, but it never gets far enough and just gives up. This should be a square wave.

But never fear. I have another cunning plan involving a chip that’s new to me. First, I need to experiment with it, so check back soon.


2 thoughts on “Zolatron 64: Interfacing the 6502 with the Raspberry Pi

  1. John Zybourne

    I came across your build log while searching around for information regarding homebrew computer building. I just wanted to say your write-ups are great and have convinced me to take the plunge. Best of luck with your build.



Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.