Z80 Rechner mit Terminal


Dieses Projekt begann mit einem Dachbodenfund; Drei Stangen ICs, die ich vor vielen Jahren auf einer Bastelmesse gekauft hatte: 10 x Z80 CPU, 10 x Z80 SIO und 10 x Z80 CTC.
Es fand sich dann auch noch der berühmte Rodnay Zaks - die vermutlich umfassenste Befehlsreferenz zum Z80.
Dazu noch eine Platine, die ich damals selbst geätzt hatte - aber um die soll es hier nicht gehen. Hier wird handverdrahtet.

Bild "Elektronik:Z80-01.jpg"

Z80?

In den späten 70ern ware der Z80 der Firma Zilog einer der dominierenden Prozessoren. Er wurde zunächst in Arcade Games verbaut und später in Homecomputern, wie dem Tandy/Radioshack TRS80, dem Sinclair ZX81 dem Schneider CPC oder meinem eher seltenen Sharp MZ80K. Und sogar für den Apple II gab es eine Z80-Erweiterungskarte.
Meiner Meinung nach unterschied sich der Z80 von seinen anderen Zeitgenossen, wie dem 6502 oder 8080/8085 durch seine sehr gradlinige Architektur und sehr mächtigen Assemblerbefehle.

Das Pin-Diagramm macht das auch auch deutlich:

Bild "Elektronik:Z80-Pinbelegung.png"

Tickt der noch richtig?

Da meine Z80-CPUs ca. 40 Jahre alt sind, war nicht unbedingt davon auszugehen, dass sie noch funktionierten. Mit dem Pin-Diagramm von oben im Blick und dem Rodnay Zaks im Anschlag, kann man einenn einfachen Computer bauen der nur NOP Instruktionen ausführt. NOP ist eine 8-Bit Instruktion, die den Code 0 (Null) hat. Es passiert nichts, wenn die Instruktion ausgeführt wird - nur der Adresszähler wird um eins erhöht.

Man braucht also nur alle Datenpins auf GND zu legen. Der Adressbus bleibt offen und die Steuersignale /HALT, /RESET, /BUSREQ, /INT, /NMI werden auf +5V gelegt. Nun braucht man noch einen 4MHz Takt am CLOCK-Eingang.

Bild "Elektronik:Z80-04.jpg"

Bei meinen CPUs konnte ich dann auf dem Speicheroszilloskop sehen, wie die Adressen hochliefen und beim Überlauf über 65535 wieder auf 0 sprangen.
Also alles im Lot bei meinen CPUs.

Bild "Elektronik:Z80-03.jpg"

Minimalcomputer mit Z80, SRAM, EEPROM und ein paar 74xx

Nun begebe ich mich aufs Lochraster. In meinem Fall eine schöne Variante, bei dem man zwischen den durchkontaktierten Lötpads auch noch durchgehende Leiterbahnen findet, die man verwenden kann um Busse und andere Verbindungen zu machen, ohne, dass man Drähte zu verlegen braucht.

Bild "Elektronik:Z80-05.jpg"

Auf der Unterseite habe ich Vero-Fädeldraht verwendet, was am schnellsten geht und trotzdem noch halbwegs übersichtlich bleibt.
Hier mehr zu den Platinen:
https://hackaday.com/2016/06/16/evaluating-the-unusual-and-innovative-perf-protoboard/

Bild "Elektronik:Z80-06.jpg"

Hier der Schaltplan:
Der Übersichtlichkeit halber, habe ich den Adressbus und den Datenbus nicht gezeichnet. Alle Adress- und Daten-Pins müssen mit den entsprechenden Pins von SRAM und EEPROM-Speicher verdrahtet werden.

Bild "Z80-Schaltplan.png"

Hier ein paar Stichworte zur Schaltung:

Die Toolchain

Wie bekommt man nun ein Programm auf selbstgelöteten Computer? Einen Bootloader, wie beim Arduino, gibt es natürlich nicht. Den könnte man natürlich selbst schreiben, aber am Anfang geht es nur über ein Programmiergerät, das den Code in das EEPROM schreibt.
Dazu muss man das EEPROM aus dem Sockel nehmen, im Programmiersockel beschreiben und wieder in die Schaltung stecken.

Bild "Elektronik:Z80-BX32.jpg"

Im Prinzip könnte man sich so die einzelnen Bytes des Programms aus der Befehlsreferenz heraussuchen und direkt vom Z80 ausführen lassen. Da das aber sehr schnell unübersichtlich wird und viel Nachschlagearbeit erfordern würde, bedient man sich besser eines Assemblerprogramms.
Das gibt jedem Z80-Befehl einen symbolischen Namen anstelle des unleserlichen Byte-Codes.

In Linux-Systemen installiert man den Assembler mit:
sudo apt-get install z80asm

Den Assembler code kann man mit jedem ASCII-Texteditor schreiben also z.B.:
nano myprogram.asm

Übersetzt in die Bytes für die CPU wird es dann mit:
z80asm -i myprogram.asm" -o myprogram.bin

Manche Programmiergeräte erwarten Intel-HEX Format (siehe: https://de.wikipedia.org/wiki/Intel_HEX)
Das muss man noch erzeugen mit:
srec_cat myprogram.bin -binary -offset 0x0000 -output myprogram.hex -intel -address-length=2

Nun nutzt man die GUI oder das Kommandozeileninterface des Programmiergeräts, um den Code in das EEPROM zu schreiben und setzt es dann wieder in die Schaltung ein.

Hier ein Vergleich zum C/C++ Code des Arduinos:

Bild "Elektronik:Z80-Assembler.png"

In meiner Minimalschaltung gibt es keinen UART Baustein für serielle Interfaces. Also habe ich das manuell programmiert und mittels den beiden 74LS373 Registern geschrieben bzw. gelesen. Natürlich hat diese Minimalversion keinen Puffer - man darf also beim Lesen kein Bit verpassen, sonst erhält man nur Datenmüll.
Schneller als 9600Byte/s ist so auch nicht machbar.

Das passende Retro-Terminal

Um den Retro-Image des Z80 gerecht zu werden, habe ich dann auch noch ein Terminal dazu gebaut. Natürlich kann man auch mit einem UART-Interface am USB des Laptops mit dem Z80 kommunizieren. Aber das wäre ja nicht stilecht.

Bild "Elektronik:Z80-11.jpg"

Hierzu habe ich einen Miniröhrenfernseher so modifiziert, dass er ein externes FBAS-Signal anzeigen kann. Das Arduino-Projekt "TVOut" ermöglicht es, auf einem Arduino Zeichen über die serielle Schnittstelle zu lesen und dann auf dem Röhrenmonitor anzuzeigen.
Eine alte PS2-Tastatur aus einem HP-Oszilloskop passt ideal zu diesem Terminal. Die PS2-Arduino-Library dekodiert das PS2-Signal und gibt das entsprechende Zeichen auf der seriellen Schnittstelle aus.

Zunächst habe ich beides auf einem Arduino implementiert, was aber beim Tippen auf der Tastatur zu Bildstörungen führte. Ein separater Arduino Mini für die Tastatur löste das Problem dann.
Der Code zum Download enthält noch alles zusammen für einen Arduino.

Bild "Elektronik:Z80-Terminal-Blockdiagramm.png"

Und so haben wir das dann auf der Maker Faire 2023 in Hannover präsentiert.

Bild "Elektronik:Z80-Makerfaire.jpg"

Bis hierher ist das Ganze eigentlich nur eine Machbarkeitsstudie. Ich plane aber, noch ein kleines BIOS und eine Monitorprogramm zu schreiben, so dass man elementare Funktionen wie Delays, I2C, UART und Servo-Steuerung vorfindet.

Downloads

Z80-TVoutTerminal.zip
Z80-Assembler-Beispiele.zip

Links

Das umfassenste Kompendium von Thomas Scherrer zum Z80 im Web inkusive vieler Beispielprojekte
http://www.z80.info/

Das originale Z80 User-Manual von Zilog
https://www.zilog.com/docs/z80/z80cpu_um.pdf

Die TVOut-Library für den Arduino, die eine FBAS Signal für Videoausgabe auf einem Monitor erzeugt
https://www.arduino.cc/reference/en/libraries/tvout/
https://github.com/Avamander/arduino-tvout/

Die PS2Keyboard Library für den Arduino
https://www.instructables.com/Connect-PS2-Keyboard-to-Arduino/
https://github.com/PaulStoffregen/PS2Keyboard