🧩Z80-Architektur
Der Zilog Z80 (1976) ist das Herz des CPC: ein 8-Bit-Prozessor mit 16-Bit-Adressbus (64 KB), 4 MHz Takt im CPC, einem doppelten Registersatz und über 700 dokumentierten Befehlsformen.
🗃️Die Register
Hauptregistersatz Schattenregister (EX AF,AF' / EXX)
┌─────────┬─────────┐ ┌─────────┬─────────┐
AF │ A │ F │ AF' │ A' │ F' │ A = Akkumulator, F = Flags
├─────────┼─────────┤ ├─────────┼─────────┤
BC │ B │ C │ BC' │ B' │ C' │ B oft Zähler (DJNZ), BC Port/Länge
├─────────┼─────────┤ ├─────────┼─────────┤
DE │ D │ E │ DE' │ D' │ E' │ DE Ziel (LDIR)
├─────────┼─────────┤ ├─────────┼─────────┤
HL │ H │ L │ HL' │ H' │ L' │ HL Zeiger, 16-Bit-Akku
└─────────┴─────────┘ └─────────┴─────────┘
┌───────────────────┐ ┌───────────────────┐
IX │ IXH │ IXL │ │ IY │ Indexregister (IXH/IXL undokumentiert)
├───────────────────┤ ├───────────────────┤
SP │ Stapelzeiger │ │ PC Befehlszähler │
└───────────────────┘ └───────────────────┘
┌─────────┬─────────┐
│ I Vektor│ R Refr. │ I: High-Byte der IM-2-Tabelle, R: zählt je Befehlsholung (7 Bit)
└─────────┴─────────┘🚩Flags zum Ausprobieren
- S: Bit 7 des Ergebnisses – bei Zweierkomplement-Zahlen „negativ“.
- Z: gesetzt, wenn das Ergebnis 0 ist (bei BIT: wenn das getestete Bit 0 ist).
- H: Übertrag von Bit 3 nach Bit 4 (bzw. Borgen) – braucht DAA für BCD.
- P/V: bei Arithmetik: Überlauf im Zweierkomplement (V); bei Logik/Rotation: gerade Anzahl Einsen (P).
- N: 1 nach einer Subtraktion – damit DAA weiß, wie es korrigieren muss.
- C: Übertrag aus Bit 7 (Addition), Borgen (Subtraktion) oder herausgeschobenes Bit.
- X/Y: undokumentierte Bits 3 und 5 – meist Kopien der Ergebnisbits (Sean Young).
Berechnet vom Z80-Emulator dieser Seite (derselbe wie im Debugger).
🧭Adressierungsarten
| Art | Beispiel | Bytes | Wirkung | Erklärung |
|---|---|---|---|---|
| Unmittelbar | LD A,&41 | 3E 41 | A ← &41 | Der Wert steht im Befehl selbst. |
| Unmittelbar, 16 Bit | LD HL,&C000 | 21 00 C0 | HL ← &C000 | Zwei Bytes Wert, niederwertiges zuerst (Little Endian). |
| Register | LD B,A | 47 | B ← A | Quelle und Ziel sind Register – 1 Byte, 1 µs auf dem CPC. |
| Register indirekt | LD A,(HL) | 7E | A ← Speicher[HL] | Das Registerpaar enthält die Speicheradresse. |
| Direkt (absolut) | LD A,(&BE80) | 3A 80 BE | A ← Speicher[&BE80] | Die Adresse steht im Befehl. |
| Indiziert | LD A,(IX+5) | DD 7E 05 | A ← Speicher[IX+5] | IX/IY plus vorzeichenbehafteter Versatz −128…+127. |
| Relativ | JR &4010 | 18 0E | PC ← PC + e | Sprungweite relativ zum nächsten Befehl (−128…+127). |
| Seite 0 (Restart) | RST &38 | FF | CALL &0038 | Ein-Byte-Aufruf fester Adressen &00…&38. |
| Implizit | CPL | 2F | A ← NOT A | Der Operand (hier A) steckt im Befehl. |
| Bit-Adressierung | SET 3,(HL) | CB DE | Bit 3 von (HL) ← 1 | Einzelnes Bit eines Registers oder Speicherbytes. |
| Ein-/Ausgabe | OUT (C),C | ED 49 | Port[BC] ← C | Port-Adresse in BC (CPC: B wählt den Baustein, z. B. &7F = Gate Array). |
⚡Interrupt-Modi IM 0, IM 1, IM 2
IM 0
Das Gerät legt einen Befehl (meist ein RST) auf den Datenbus, die CPU führt ihn aus – kompatibel zum Intel 8080.
Auf dem CPC liefert der Bus &FF = RST &38, wirkt also wie IM 1.
IM 1
Jeder Interrupt ist ein RST &38: Rücksprungadresse auf den Stapel, Sprung nach &0038. 13 T.
Das benutzt die CPC-Firmware: INTERRUPT ENTRY bei &0038 (SOFT 968, Abschnitt 11.2).
IM 2
Die CPU bildet aus I (High-Byte) und dem Datenbus-Byte (Low-Byte) eine Tabellenadresse und springt an die dort stehende Adresse. 19 T.
Auf dem CPC für eigene Routinen üblich: 257-Byte-Tabelle mit gleichem Wert, weil das Bus-Byte nicht festgelegt ist.
CPC: Gate Array fordert alle 52 Rasterzeilen (3,328 ms) einen Interrupt an → 300 pro Sekunde, 6 pro Bild (50 Hz) Bild n Bild n+1 │VSYNC │VSYNC ▼ ▼ ├──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬────────── INT INT INT INT INT INT INT │ Fast Ticker (300 Hz) bei jedem INT · Ton (100 Hz) bei jedem 3. · Frame Flyback, Ticker, Tastatur (50 Hz) bei jedem 6. └─ Firmware: RST &38 → INTERRUPT ENTRY → Ereignisse „anstoßen“ (KL EVENT) → EI, RET
⏱️Takte (T) und die 1-µs-Uhr des CPC
| Befehl | Z80 (T) | T ÷ 4 | CPC gemessen (µs) |
|---|---|---|---|
| NOP | 4 | 1,00 | 1 |
| LD A,B | 4 | 1,00 | 1 |
| LD A,n | 7 | 1,75 | 2 |
| LD A,(HL) | 7 | 1,75 | 2 |
| LD A,(IX+d) | 19 | 4,75 | 5 |
| PUSH HL | 11 | 2,75 | 4 |
| POP HL | 10 | 2,50 | 3 |
| CALL nn | 17 | 4,25 | 5 |
| RET | 10 | 2,50 | 3 |
| JR e | 12 | 3,00 | 3 |
| JR NZ,e | 12/7 | 3,00 / 1,75 | 3/2 |
| DJNZ e | 13/8 | 3,25 / 2,00 | 4/3 |
| LDIR | 21/16 | 5,25 / 4,00 | 6/5 |
| OUT (C),A | 12 | 3,00 | 4 |
| EX (SP),HL | 19 | 4,75 | 6 |
| ADD HL,DE | 11 | 2,75 | 3 |
Quellen: Zilog Z80 CPU User Manual (UM0080); Sean Young „The Undocumented Z80 Documented“ (Flags X/Y, SLL, IXH/IXL); SOFT 968 Abschnitt 11 und Appendix XI; CPC-Zeiten: K. Thacker „Instruction timings“ (cpctech.cpcwiki.de), Erklärung des Wartezyklus nach T. Harte „Amstrad CPC Timing“.