Anleitung zum Z80 CPU-Tester

Es handelt sich bei diesem Text um eine Übersetzung der Anleitung von Goran Devic, die ich entsprechend ergänzt habe.

Wird der CPU-Tester √ľber die serielle Schnittstelle verbunden, stehen mehrere Befehle zur Verf√ľgung („?“ Oder „h“ in der Konsole eingeben):

l #num       - lade Programm #num in den Speicher (es stehen ein paar Beispiele zur Verf√ľgung)
s            - zeige Simulationsvariablen
s #var value - setzte Simulationsvariablen #var auf den Wert "value"
sc¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† - setzte die Simulationsvariablen auf Standardwerte zur√ľck
r            - Starte die Simulation
:INTEL-HEX   - lade RAM mit dem INTEL-HEX Stream
m            - gib den Inhalt des RAM aus
mc           - lösche den RAM

Es gibt mehrere interne Simulationsvariablen, die ge√§ndert werden k√∂nnen, um die Tests auf dem Z80 auf verschiedene Weisen auszuf√ľhren. Der beste Weg, um einen Z80-Test zu erstellen, geht √ľber einen Z80-Compiler, wie z.B. zmac.¬† Erstelle ein Programm, wie z.B. folgendes:

start:
ei
im 2
ld ix, 80h
srl (ix+20h), b
adc hl, de
ld hl, 30h
ld de, 40h
ld bc, 3h
ldir
ld bc, 1
ldir
halt
org 38h
ei
reti
org 66h
ei
reti
end

Funktionell macht diese Sequenz wenig Sinn, sie lässt uns aber verschiedene Dinge testen: Befehlspräfix IX, ein undokumentierter Opcode, LDIR-Schleife, HALT. Durch einen HALT kann durch einen NMI oder INT an bestimmten Stellen das Verhalten der CPU verfolgen werden.

Der Code wird mit

zmac --od . --oo hex filename.c

assembliert und die erzeugte IntelHex (*.hex) Datei kann in das Arduino-Terminal kopiert werden.

:10000000FBED5EDD218000DDCB2038ED5A21300094
:0E001000114000010300EDB0010100EDB076DB
:03003800FBED4D90
:03006600FBED4D62
:0000000000

Als Antwort gibt der Arduino zur√ľck, dass der Code erfolgreich gespeichert wurde. Mit dem Befehl „m“ kann er angezeigt werden:

    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
   +-----------------------------------------------
00 |FB ED 5E DD 21 80 00 DD CB 20 38 ED 5A 21 30 00
01 |11 40 00 01 03 00 ED B0 01 01 00 ED B0 76 00 00
02 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
03 |00 00 00 00 00 00 00 00 FB ED 4D 00 00 00 00 00
04 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
05 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06 |00 00 00 00 00 00 FB ED 4D 00 00 00 00 00 00 00
07 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
08 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09 |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0A |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0C |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0D |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0E |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0F |00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Durch den Befehl „s“ werden die Simulationsvariablen angezeigt:

------ Simulation variables ------
#0 Trace both clock phases = 0
#1 Trace refresh cycles = 1
#2 Pause for keypress every = -1
#3 Stop after clock # = 40
#4 Stop after # M1 cycles = -1
#5 Stop at HALT = 1
#6 Issue INT at clock # = -1
#7 Issue NMI at clock # = -1
#8 Issue BUSRQ at clock # = -1
#9 Issue RESET at clock # = -1
#10 Issue WAIT at clock # = -1
#11 Clear all at clock # = -1
#12 Push IORQ vector #(hex) = FF
#13 change length of one clock cycle (msec, for H and L cycle each).

W√§hrend der Ausf√ľhrung z√§hlt das Programm die Zyklen und durch Setzen der Variablen k√∂nnen bestimmte Steuersignale zu bestimmten Zeiten erzeugt werden. Wenn beispielsweise bei Taktzyklus 20 ein NMI erzeugt werden soll, einfach „s 6 20“ eingeben. Optional kann auch das Verhalten bei fallender Flanke ausgegeben werden (Variable #0 aus „1“ setzen). Die Variable #1 zeigt oder versteckt die Speicheraktualisierungszyklen, die M1 begleiten.

Mit „r“ wird das Programm gestartet. Der Arduino gibt eine RESET-Sequenz an den Z80, der den Code danach schrittweise ausf√ľhrt. Die Buswerte werden dann f√ľr jeden Zyklus ausgegeben.

Der Tristate wird √ľber einen Spannungsteiler am Adress- und Datenbus erkannt (das Programm gibt f√ľr diesen Zustand ein „-“ aus).¬† Eine etwas gek√ľrzte Ausgabe sieht wie folgt aus

Performing a RESET
Starting the clock
-----------------------------------------------------------+
#001H T1 AB:--- DB:-- RD                                   |
#002H T2 AB:--- DB:--                                      |
-----------------------------------------------------------+
#003H T1 AB:000 DB:-- M1                                   |
#004H T2 AB:000 DB:FB M1 MREQ RD      Opcode read from 000 -> FB
#005H T3 AB:000 DB:-- RFSH                                 |
#006H T4 AB:000 DB:-- RFSH MREQ       Refresh address 000  |
-----------------------------------------------------------+
#007H T1 AB:001 DB:-- M1                                   |
#008H T2 AB:001 DB:ED M1 MREQ RD      Opcode read from 001 -> ED
#009H T3 AB:001 DB:-- RFSH                                 |
#010H T4 AB:001 DB:-- RFSH MREQ       Refresh address 001  |
-----------------------------------------------------------+

Das folgende Video zeigt, wie die CPU ein kleines Programm schrittweise abarbeitet (200msec pro Taktzyklus).

Z80 CPU Tester

Nach einem RESET macht die Z80 CPU f√ľr zwei Taktzyklen nichts. Die T-Zyklen werden ab jedem M1-Zyklus automatisch gez√§hlt. Eingangs- und Ausgangspins, die aktiv sind, werden ebenfalls angezeigt (z.B. RD oder RFSH).

Weiterhin werden alle Lese- und Schreibzugriffe der Z80 CPU auf den Speicher angezeigt. Insgesamt visualisiert die Arduino-Software das gesamte Verhalten der Z80 CPU.

In der aktuellen Version unterst√ľtzt die Software auch ein LCD2004. Dabei wird der Speicher ab 400H (die Adresse wird im Arduino-Sketch durch SCREENBASE definiert) als Bildschirmspeicher verwendet (4 x 20 Bytes). Soll ein ‚A‘ an Position (0/0) ausgegeben werden, geschieht dieses durch ein Schreiben an Adresse 400H <- 41H. Ein Beispiel kann durch „l 3“ geladen werden. Danach Variable s 3 hoch setzen: „s 3 1000“ und das Programm mit „r“ starten.

Z80 CPU Tester mit Display

Der Status der Taster kann durch Lesen von Adresse 4000H bzw. 4001H ermittelt werden. Ein Beispiel kann durch „l 4“ geladen werden. Danach Variable s 3 hoch setzen: „s 3 10000“ und das Programm mit „r“ starten. Durch Dr√ľcken von SELECT erscheint „ON“ auf dem Display, wird OK gedr√ľckt, erscheint „OFF“.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert