⚙️Zeichenroutinen in Z80

Sechs Wege, ein Software-Sprite auf den Bildschirm zu bringen – jeder als lauffähiges Programm im Emulator, mit Einzelschritt, „Schritt zurück“, Haltepunkten und gemessener Laufzeit.

🧪
Simulation im Browser. Der Z80 wird Befehl für Befehl emuliert; die CPC-Firmware ist dagegen in TypeScript nachgebildet (HLE) – nach den Ein-/Ausgabebedingungen aus dem Firmware-Handbuch SOFT 968. Es wird kein ROM-Inhalt von Amstrad verwendet, der Zeichensatz ist ein gemeinfreier Ersatz. Emulator, Assembler und Debugger stammen aus VisualZ80.
Sprite:8 × 16 Pixel = 4 Bytes × 16 Zeilen = 64 Bytes

c) Maskiert (AND Maske / OR Sprite)

Zu jedem Byte gehört ein Masken-Byte (1 = Hintergrund bleibt). AND (HL) stanzt die Figur aus, OR (HL) setzt sie ein. Vorher wird der Hintergrund gesichert, beim Bewegen zurückgeschrieben.

✅ saubere Transparenz vor beliebigem Hintergrund
⚠️ doppelter Datenbedarf (Maske + Sprite) und zusätzlich Sichern/Wiederherstellen
Im Emulator gemessen
1511 µs
= 1511 NOPs für einmal Zeichnen (inkl. CALL und RET) · 7.6 % eines Bildes
Bewegen: 2901 µs – wiederherstellen 695 + sichern 695 + zeichnen 1511 µs
Daten/Code: 192 Bytes
bereit
ℹ️ Das Programm stellt Modus 0, die Tinten und ein Karomuster ein und zeichnet das Sprite an zwei Stellen. Zwischen den Labels bench_start und bench_end steht der gemessene Aufruf – „Zeitlupe“ oder Einzelschritt zeigen, wie die Figur Zeile für Zeile entsteht.
Quelltext (editierbar)
Assembler-Liste · Klick auf ● = Haltepunkt
0
1
2
3
Rand
Modus 1 · Basis &C000 · Versatz &0000
Firmware
Firmware jetzt
▶ RESET ENTRY · Details in VisualZ80 ↗
Letzte Falle: –
Letzte Firmware-Aufrufe
noch keine
Register & Flags
AF
&FFFF
BC
&0000
DE
&0000
HL
&0000
IX
&FFFF
IY
&FFFF
SP
&C000
PC
&0000
S
1
Z
1
Y
1
H
1
X
1
P/V
1
N
1
C
1
AF' &0000
BC' &7F8D
DE' &0000
HL' &0000
I &00
R &00
IM 1
IFF1/2 1/1
Z80-Takte: 0 TCPC-Zeit: 0 µsROMs: unten aus, oben ausRAM-Konfig: &C0
Disassembler ab PC
0000HLE ▸ RESET ENTRY
0002RET
0003NOP
0004NOP
0005NOP
0006NOP
0007NOP
0008HLE ▸ LOW JUMP
000ARET
000BHLE ▸ KL LOW PCHL
Stapel (SP)
C0000000← SP
C0020000
C0040000
C0060000
C0080000
C00A0000
C00C0000
C00E0000
Speicher (Hex)
800000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
801000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
802000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
803000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
804000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
805000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
806000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
807000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ················
PCSP(HL)(DE)Leseansicht mit aktueller ROM-/Bank-Einblendung

📊 Wie viele Sprites passen in ein Bild?

Ein Bild dauert bei 50 Hz 19 968 µs (312 Rasterzeilen × 64 µs). Auf dem CPC hält das Gate Array den Z80 so an, dass jeder Befehl ein Vielfaches von 1 µs dauert (4 Takte = 1 „NOP“). Die Zahlen unten sind nicht geschätzt, sondern im Emulator gemessen – mit der gemessenen Befehlstabelle von Kevin Thacker. Rechnung: ⌊19 968 µs × Anteil ÷ Kosten⌋, Interrupts nicht abgezogen.

010203040a · Kopieren (LDI)2814a · Kopieren (LDI): zeichnen 695 µs → 28 Sprites; bewegen 1390 µs → 14 Sprites je Bildb · XOR157b · XOR: zeichnen 1255 µs → 15 Sprites; bewegen 2510 µs → 7 Sprites je Bildc · Maske AND/OR136c · Maske AND/OR: zeichnen 1511 µs → 13 Sprites; bewegen 2901 µs → 6 Sprites je Bildd · Tabelle (Tinte 0)116d · Tabelle (Tinte 0): zeichnen 1722 µs → 11 Sprites; bewegen 3112 µs → 6 Sprites je Bilde · vorverschoben (+1 Pixel)95e · vorverschoben (+1 Pixel): zeichnen 2042 µs → 9 Sprites; bewegen 3592 µs → 5 Sprites je Bildf · kompiliert3510f · kompiliert: zeichnen 565 µs → 35 Sprites; bewegen 1955 µs → 10 Sprites je Bild
nur zeichnenbewegen (löschen/wiederherstellen + sichern + zeichnen)
Routinezeichnen (µs)Sprites/Bildbewegen (µs)Sprites/BildBytesBewegen heißt
a · Kopieren (LDI)6952813901464alte Stelle mit Hintergrund überschreiben + neu zeichnen
b · XOR1255152510764alt wegXORen + neu zeichnen
c · Maske AND/OR15111329016192wiederherstellen 695 + sichern 695 + zeichnen 1511 µs
d · Tabelle (Tinte 0)17221131126384wiederherstellen + sichern + zeichnen
e · vorverschoben (+1 Pixel)2042935925400wie d, aber 5 statt 4 Bytes breit (auch Sichern/Wiederherstellen)
f · kompiliert56535195510466wiederherstellen + sichern + Code ausführen

Bytes: a/b Sprite; c Maske+Sprite verschränkt + Hintergrundpuffer; d/e zusätzlich die 256-Byte-Tabelle (e mit beiden Fassungen); f = Größe des erzeugten Codes. Echte Spiele sparen weiter: INC E statt INC DE bei bekannter Ausrichtung, Zeilenzähler im Code, Sprites über den Stapelzeiger (POP) lesen – die Reihenfolge bleibt aber typisch.