I always wanted to build a single board “trainer style” computer:
When I was first getting started with electronics, wanted a Heathkit ET-3400 Microproccessor trainer, but could never afford one at the time. Eventually both I and the world moved on, to fancier more capable computers. However, I’ve still always wished I had an iconic trainer, complete with LED displays and a hexadecimal keypad. So I decided to build something of my own.
A brief feature list
- Z80 CPU
- RC-2014 Compatible Expansion Connector
- Eight TIL311 Displays, or a 2×16 LCD/VFD Module
- 20-Key Keypad for cherry MX Blue Keyswitches
- Two serial ports (Z80 SIO/2)
- 24-bit Parallel IO Connector (Z80 PIO)
- Counter/Timer chip, optionally usable as a baud rate generator for the SIO/2
- 512 KB of banked RAM
- 512 KB of banked ROM
- Single stepper, with automated slow stepping feature
- Flexible IO address decoding using programmable logic devices
The schematic is too big to inline into this blog post, it’s a solid 6 pages long. As such I’ve included a PDF link:
The schematic is divided into pages, each page serving a logic block of functionality
Sheet 1: Display and Keypad
There are two display options, TIL311 LED displays or a 2xz16 LCD/VFD. I really like the TIL311 display and have used it in several of my projects. It features a built-in 4-bit hex digit decoded, so you can simply write four bits to the display and the appropriate character shows up. There is an optional blanking input that lets you turn off the display, and inputs for decimal points. The problem with the TIL311 is that it is not currently manufactured — you have to find them on eBay. It’s also a bit of a power hog.
Data bus to the TIL311 is buffered via a 74HCT244, otherwise eight of these displays would quickly load down the Z80 Bus. Blanking inputs are latched by a 74HCT374. The left-hand decimal points are also latched by another 74HCT374. I chose not to implement the right-handle decimal points.
As an alternative to the TIL311, I provided a header to connect a parallel 2×16 LCD (or VFD) display.
The keypad uses Cherry MX Blue keyswitches. There are 20 keyswitches, and they are served by a set of three 74HCT244. There are ways to implement a keypad with fewer chips using strobing approaches, but using the 244 ICs allows for a simple one key = one data bit approach. Three 74HCT244 provide 24 bits of digital IO and we only have 20 keys, so I ran the remaining 4 bits to a dip switch.
Sheet 2: CPU and Expansion Header
This sheet is pretty straightforward, it’s just the Z80 CPU and the RC2014 expansion header, which features most of the pins of the Z80 CPU. Several of the pins on the RC2014 are “optional” and are brought out to jumpers. These include TX and RX from the SIO/2. bus control signals like BUSRQ, BUSAK, HALT, and WAIT.
There’s an RC power-on reset circuit, a crystal oscillator (connect the jumper JP3 to enable it), a 3-terminal regulator (I suggest using an EZSBC drop-in switching replacement for the 7805), and some blinky LEDs tied to some of the bus signals.
Sheet 3: Memory
Both the FLASH and the RAM are on this sheet. Memory paging is implemented using some 74HCT670 register files, see my paged memory board for the RC2014 for a description of how the memory paging works. The paging design is borrowed from Sergey Kiselev’s Zeta-2 single board computer.
The FLASH chip is brought out to an extra large footprint that allows installation of a ZIF socket. The ZIF socket is useful if you plan on reprogramming the FLASH more than a handful of times, such as if you wish to develop a custom CP/M distribution.
You’ll need to program the FLASH chip, a 39SF040. I recommend using one of the TL866 variant of USB Eprom programmers widely available on eBay.
Sheet 4: IO Address Decoding
I went a different route than my usual design here. Typically I would use some 74HCT138 3-8 decoders and headers to select which addresses to assign the onboard peripherals. However, we’re talking a lot of peripherals. I really wanted the peripheral addresses to be configurable, but without taking a lot of board space. My choice was to use ATF16V8 programmable logic devices.
The ATF16V8 can be configured with 10 inputs and 8 outputs and internally is implemented with a bunch of fuses that let you program logic between the inputs and outputs. Implementing address decoding is a relative piece of cake. I was able to squeeze in seven address bits and a write line into one of the ATF16V8 and seven address bits and a read line into the second ATF16V8. This lets us put write-only peripherals on the first chip and read-only peripherals on the second. Read/write peripherals can be placed on either.
The programming for the ATF16V8s is located in my github repo. For those wanting the standard board, you should be able to use my fuse maps directly. For those wanting to assign different addresses, for whatever reason, you can write your own fuse maps. I have some helper utilities to build the fuse maps. Most people will just use my fuse maps. You can often use the same EPROM/FLASH programmer that you’d use for the 39SF040 FLASH chip in the memory sheet to program the ATF16V8 chips.
Sheet 5: Serial, Parallel, and Counter/Timer
In this sheet, we have our input/output peripherals. The SIO/2 chip is our serial chip and gives you two serial ports. For running CP/M, you’ll end up using one of these ports as your console. The other port you can use for whatever you want (I connected a serial GPS for my Z80 Nixie Clock project). The first serial port is brought out to both a DB9 via a MAX232 serial driver chip and to a header that’s set of typical FTDI TTL-serial-USB cables. Personally I think the DB9 is cool, because that’s what a retro computer would have used.
The PIO chip provides 24 bits of parallel IO all brought out to a header. You can use it to drive LEDs (with an appropriate dropping resistor), read switches, interface with external peripherals, whatever.
The CTC is a counter-timer chip. It has several internally counters/timers that can be used to pulse its outputs at a specific rate. The primary use of the CTC would be as a baud rate generator for the SIO/2, if for example you wanted to be able to support both a 115200 baud console and a 9600 baud GPS.
Sheet 6: Single-Stepper
Sheet 6 is my single stepper, copied verbatim from my RC2014 single-stepper page. Check smbaker.com or my videos for a detailed description [TODO: dig up the links].
The single-stepper allows you to step through a program one instruction at a time. Why would you want to do this? If you were using this as an actual trainer, programming directly in assembly language, then it could be handy. In addition to single-stepping, it also supports a mode that I called “slow-stepping” where a 555 timer automatically pushes the “step” button for you. This makes a program run really slow. Like in the tens or hundreds of instructions per second rather than millions.
Here’s where I’m going to talk about the 4-layer PCB. Yes, it’s a 4-layer board!
- https://github.com/sbelectronics/z80sbc, Scott’s Z80SBC repository containing schematics, code for the
- https://github.com/sbelectronics/RomWBW, my fork of the RomWBW CP/M distribution.