Building a PIO

A project log for Melba I

Melba I is an implementation of the Apple I from parts in my collection.

Christian BjelleChristian Bjelle 06/19/2020 at 19:060 Comments

I was preparing to plopp-in the big ICs when I realised that the PIO had mostly internal connections. Very few of the IO-pins were to connect to anything outside the CPLD, making a real chip unnecessary tedious to wire up.

As I had expected to write a 6821 in Verilog sooner or later, I immediately started hacking.

The ports A and B are almost identical, and only differs in their behaviour when reading from an output port, where port A reads from the pin and port B reads from the output register.

To avoid writing two nearly identical modules, I used the ifdef-statement to get two instances of the same module with slightly different behaviours. If someone can suggest a more elegant solution, please comment below.

	      // Port A behaviour
	      // Read output pins directly (i.e. only input-pins)
	      busOutputRegister_next = portInputRegister;
	      // Port B behaviour
	      // Splice output data with input data
	      busOutputRegister_next = (portOutputRegister & ~dataDirectionRegister) |
				       (portInputRegister & dataDirectionRegister);

All signals in a 6821/6520/65C21 are relative to the trailing edge of the E-clock, with one notable exception. I was happy to use E as clock for my c6821 until I started implementing interrupt control for CA and CB IO.

Interrupts are by their nature asynchronous, and 6821 can be programmed to react to either positive edges or negative edges, and I was searching for the most verilogish way to detect either when I came across this article. 

I realised that I had to synchronise the inputs with a clock, but the E-clock was so darn slow that  most short interrupts would likely be lost, and even worse was the fact that this module instantiated in my CPLD would live by a clock that was different from all other clocks on the "SOC".

I went back and added a fast clock and synchronised all my inputs, E, CA1, CB1 and even the ports PA and PB. (which is why the input pins in the code above is portInputRegister; it is registered at that point.)

All in all, I'm pretty happy with my little PIO.

I've also started looking at a suitable keyboard and a case-design, but that is a story all by itself.