CPU made out of TTL chips only

First the why: Back in the early eighties the emerging microcomputers really caught my attention. First encounter was with the ZX81 and after with the ZX spectrum but at that time the CP/M machines were starting to be the real thing to fight for but unfortunately it was not accessible to the wallet of the teenager's I was so I really had just the ZX81 and later the ZX spectrum to play with. It took a few years more (late eighties/early nineties) for my life to change (computer wise). While the ZX81 was fun I spent many hours drawing circuits and trying to figure if I would be able to design a machine using just the digital circuitry that was available but without using any LSI chips. This was purely a challenge and like many challenges started with the discussion between friends that sounds like "no, it is difficult" versus "yes I can do it".
At that time the TTL chips of the 74 series were becoming affordable and even considering to use a bunch of them (more than 50) it was still not a show stopper. Many design variations were drawn on paper and some simple variations were bread-borded and wire rats-nested. It was undoubtedly a fun learning experience.

One relevant detail is that where I lived TTL availability was driven mainly by industrial control applications therefore not all TTL functions were obtainable and this conditioned the design choices. All logic gates flip-flops, counters and the latches were reasonably easy to obtain however the 74181 (or 74381) ALU was not available at all, however the full adder 7483 (or 74283) was available so the design did not use the usual ALU chip. Also TTL PROMs were not easy to find and I didn't knew anyone with a fuse PROM programmer so decoding operands on a ROM or do micro coding was not really an easy option this is why this design employs only logic for this function. Worth mentioning that EPROMs were slow (200ns) therefore uninteresting to use them as part of the CPU internals.

The actual hardware from those experiments did not survived the years, chips were mostly salvaged into other experiments, but some drawings and sketches survived and about 30 years later I had the idea to resurrect this experiment. I entered the designs (or what I could interpret of them) into a CAD and made some PCBs. During this process (from 2014 to 2017) there was some necessary refinements from the early design but never compromising the original idea and using the TTL chips from that era.

Then the what: It is a 8 bit word (64k address space) CPU using Harvard architecture. However on the memory card I have the RAM or'ed for both program and data.
It has no I/O space therefore peripherals need to be memory mapped.

It has two 8 bit registers A, B and one 16 bit register Y. The architecture allows transfer between any of the registers. Also operations with immediate data can target any of the registers.

The A and B registers are permanently wired to the arithmetic and logic functions. These functions are: ADD, AND, OR, XOR. The A register is wired to zero detection gates therefore the flag 'zero' is persistent and reflects the A register contents. The 'carry' flag is also persistent and reflect the result of A+B since the A and B registers wired to the full-adder. This way any jump if 'carry' or if 'zero' will only depend on the contents of the A and B registers at the time of the jump (and not on the last operation).

The CPU state-machine sequence consists of four states S0 to S3, one per clock cycle. At S0 the CPU fetches and operation from program memory, at S1 depending on the operation fetched it reads program-memory or data-memory or does nothing, at S2 depending on the operation fetched it writes data into the data-memory or does nothing, at S3 it advances the program-counter to the next program location either incrementing the PC or loading the PC with new data (a jump).

The instructions are bitwise direct decoded therefore each bit of the operation-code has a direct hardware meaning. The OP-code contains explicitly the source the destination and the jump control. This way any instruction implies a register transfer that could also trigger a jump. The overall result is a quite compact and efficient assembly code that would result in operations like: "LD A,B" loads A with the contents of B, "LD A,10,JC" load A with 10 and jump if A+B has a carry, or "LD A,ADD,JZ" load A with A+B and jump if the resulting A has zero.

Down to the details / The hardware: The CPU resides in a single board and presents a general bus that has the capability to interface memory boards and I/O boards. Bus has a bidirectional data bus (8bit) an address bus (16bit) and control signals /PGM_RD for reading the program memory, the /MEM_RD for reading the data memory, the /MEM_WR for writing the data memory and a /WR that is an additional signal to tell when the data from CPU is valid (some peripherals and memories may prefer to use this one). Additionally it has a /HOLD and the corresponding /HOLDA that allows any card on the bus to request the bus. When HOLD is acknowledged the data and address buses become high impedance.

This computer in its minimal configuration is composed of a CPU card, a memory card and an I/O card.

The I/O card has a serial interface (RS232) plus an input port (8bit) and an output port (8bit). The I/O card follows the exact same principles all in TTL and with the chips I had available in the eighties and followed quite closely the old sketches namely the RS232 interface made with discrete transistors. The only relevant difference is that the baudrate generator now goes from 1200 bps to 38400 bps instead of 300 to 9600 bps.

The memory card is totally different from the old designs it employs now a 27256 EPROM and a 62256 SRAM. In the early eighties the EPROMs commonly available were the 2716 2732 and the 2764 (27128 or 27256 appeared later and were expensive) while a common static RAM of the era the 2114 (1024x4). It is still in my plans to make a memory card employing a 2732 and two or more 2114.

Diagrams of the CPU board.
Diagrams of the memory board.
Diagrams of the I/O board.

Down to the details / The Operation and Software: The complete set of cards becomes a complete microcomputer when there is some software in it that boots it up and allows user interaction such as entering programs and executing them. The system has no keyboard and display and was designed to rely on a serial terminal such as the VT100 (or similar) for user interaction.

Today I use a video serial terminal that uses a PS2 keyboard and has a VGA output while it emulates a VT100. A vintage serial terminal may be more fun to use if available.

Currently the EPROM has a memory monitor software that allows entering data, display memory contents and receiving code through the serial port. This is enough to allow experimentation. Other system ROM such as BASIC or even a simplistic OS is clearly possible with some effort but not sure if I want to go in that direction.

Doing the software development on modern computer is a very interesting way to move faster creating programs and experimenting with this microcomputer. For this purpose a macro assembler was developed (available for MSDOS and Linux users). This macro assembler implements all the CPU operations and has most of the features available in modern assemblers.

Assembler, misc software and examples.

It works: From a hardware point of view it works flawlessly. Using vintage EPROM and RAM with 100ns to 150ns access time it can be reliably clocked up to 5MHz (I decide to run it a 4.0 MHz). However using faster memories and replacing the few timing critical gates with TTL "S" or "F" it operates past 8MHz. Yet to be tested how it will perform if it all is made with chips from the "74HCT" and "74F" family.

From a software point of view, while using the assembler program on a more modern PC, working with this microcomputer is quite straightforward and pleasant. The few logic and aritmetic functions avaialble are enough to do all the other common logic and arithmetic operations that seem to be missing. Some functions are quite a challenge to discover but in the end they are just clever tricks and result in just a few lines of code such examples are the shift operations and nibble manipulations.

The fact there is only two general purpose registers and one index register to point to memory poses no problems to do any coding. Code written for this CPU needs to do extensive use of storage in RAM as the only two registers are required to do the data manipulations this is why it come handy to have a macro $sto for storing register data into RAM and a macro $rcl to recall the data to a register. Also the CPU does not implement a CALL/RET operation but using memory variables to store program locations and jumps a macro $call can also be made. In summary writing code become quite intuitive and the assembly code results very readable.

Drop me a note if you like to reproduce this design.
I may still have PCB's or may provide gerber files.
Or any other comments: Luis Cupido