2023
HOME

Retro Software in Z80-Asssembler/C/C++
ZX81 - ESP8266 und TFT
Ein Emulator des Klassikers als Sketch der Arduino-IDE auf dem ST7789-240x240-Display

Pro-Dos-Demo Starten
Breadboard-ZX81 im Jahr 2023

Bereits seit 2016 existiert ein Sketch von Joaquim Pereira aka joaquimorg, der es erlaubt einem ESP8266 ein Z80-Prozessor, ein ZX81 nebst 8k-ROM und etwas GFX und TCP/IP einzuhauchen, um das ZX81-BASIC auf einem LCD-Display auszuführen. Die Software liegt auf github, aber die einstige Homepage existiert in der damaligen Form nur noch im Web-Archiv. Heute liegt der Schwerpunkt bei Licht und Uhren bzw. PineTime.

Es erscheint als eine reizvolle Aufgabe diesen Kode für eine ILI9163-Anzeige etwas anzupassen und auch zu verstehen, damit das vorhandene hier oben dargestellte TFT-Display mit 240x240 Pixeln und dessen Treiberbaustein ST7789 funktioniert. Vorhandene Hardware/Software:

Um das ganze, leider undokumentierte Gebilde zu verstehen, erfolgt zunächst eine Analyse der Quelltexte, das Testen der Anzeige am ESP8266 und schließlich die Anpassung und Vorbereitung der Gesamtstruktur. Das klingt kompliziert, aber der Geniestreich steckt m. E. in der Tastatur und deren Einsatz oder Ersatz.


Quelltext Komponenten

Das Archiv ESP8266-Master enthält das Verzeichnis esp8266_zx81 mit allen benötigten Dateien, außer der Bibliothek des verwendeten ILI9163-Displays, welches eine Ebene höher liegt.

Verzeichnis-Inhalt:

  • data, Verzeichnis für den Web-Server des ESP8266!
  • esp8266_z81.ino, der eigentliche Sketch
  • icons.h, Daten des logo.png
  • z80.cpp, z80.h, Emulation des Z80-Prozessors
  • zx81.cpp, zx81.h, Emulation des ZX81
  • zx81_logo.png, das Bild für den Splash-Screen, wie hier rechts abgebildet


Z80


Die Datei z80.cpp ist japanischen Ursprungs aus 2013/10/30 von S.Suwa und enthält den in C geschriebenen Z80-Prozessor mit allen Befehlen und eine entsprechend lange Sprungtabelle.

Ein Z80 Befehl mit dem Byte 7CH ist mit LD A,H mnemonisch festgelegt. Der Akku erhält den Wert des Registers H. In C ist dies dort wie folgt umgesetzt:

void	fnc_0x7c(void)
{
  // LD  A,H
  tstates += 4;
  a = h;
}


ZX81


Die Datei zx81.h enthält das Objekt ZX81 als Klasse und auch das 8k-ROM des ZX81 als Array bzw. static const unsigned char zx81rom[] PROGMEM = {0xd3, 0xfd, 0x01, 0xff, 0x7f, 0xc3, 0xcb, 0x03 ...


Abgleich mit dem Buch Das ZX81 ROM

Auch das ROM des ZX80 ist darin enthalten, allerdings auskommentiert. Das RAM ist hier mit 1kByte definiert: #define Z80_RAM_SIZE 1*1024 // 1K . Der Bildschirm ist ein privates Zeichen-Array des Objekts ZX81 mit unsigned char screen_[25][32]; // Screen.

In zx81.cpp wird eine weitere charakteristische Eigenschaft als Array angegeben. Es handelt sich um die Tasten-/ASCII-Zuordnung.

static unsigned char zx2ascii[128] = {
/*  0- 9 */ ' ', '_', '_', '_', '_', '_', '_', '_', '_', '_', 
/* 10-19 */ '_', '\"','!', '$', ':', '?', '(', ')', '>', '<', 
/* 20-29 */ '=', '+', '-', '*', '/', ';', ',', '.', '0', '1', 
/* 30-39 */ '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 
/* 40-49 */ 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 
/* 50-59 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 
/* 60-63 */ 'W', 'X', 'Y', 'Z'
};

Dabei ist zu erkennen, dass die Zeichen 1 bis 10 nur Unterstriche enthalten. Dies sind die Grafik-Elemente des ZX81, die also in der Emulation nicht funktionieren. Das kann vermutlich durch einen angepassten Zeichensatz für das Ausgabe-Display geändert werden. Weiter unten findet man die Ausgabe-Routine void ZX81::showScreen(void), die eventuell an das verwendete Display angepasst werden muss. Man kann ablesen, dass der Cursor "K" an der Stelle 0, 120 auf dem Schirm erscheint. Die charakteristischen Tasten-Reihen und Spalten werden ebenfalls hier verarbeitet. Der ZX81 startet, wenn alles initialisiert ist mit dem kurzen Aufruf mit der Abarbeitung des ROM.

void ZX81::run( ) {
  execZ80();
}

Mit IN und OUT greift ein Z80 auf die Peripherie über Ports zu. Daran ist beim Original auch die Tastatur angeschlossen, wodurch an dieser Stelle ein ROM-Aufruf entsprechend behandelt bzw. abgefangen werden muss.


ESP8266_ZX81


esp8266_zx81.ino ist der eigentliche Sketch für die Arduino-IDE. Reste zeigen, dass es erst einen ZX80 Emulator gab. Nach dem üblichen Einbinden der zu verwendenden Bibliotheken fallen die beiden Zeilen

ESP8266WebServer server(80);
bool loadFromSpiffs(String path)

auf. Wozu ein Web-Server und ein Dateisystem? Bisher war unklar mit welcher Methode eine Tastatur an den ZX81-Emulator angeschlossen ist. Die Lösung liegt auf der Hand, wenn in 2016 ein ESP8266 als Mikrocontroller verfügbar ist. Die Tastatur erscheint auf einer HTML-Seite mit JavaScript-Unterstützung. Ein Teil des ESP dient als Dateisystem FS und enthält die benötigten Daten, die vom Server ESP8266 benötigt werden, um dem Benutzer in einem Browser auf dem Gerät seiner Wahl die Bedienung mit Maus, Tastatur oder per Touch zu gestatten!


ZX81-Tastatur im Browser bedienbar per Maus, Taste oder Touch

Den größten Platz nimmt die setup-Routine ein. Danach folgt die übliche loop eines Arduino-Sketches. Während der Laufzeit des ZX81 in dieser Schleife wird auch der serielle Kanal überwacht. Liegt ein Zeichen vor, so gibt es bis zu drei Informationen.

  if (Serial.available()) {
    char c = Serial.read();
    if ( c == 'd' ) {          
      //zx81.debug();    
      debug();
    }
    if ( c == 'm' ) {   
      zx81.ShowMEM( Z80_RAM_BASE );      
    }
    if ( c == 'r' ) {   
      zx81.ShowMEM( 0x0 );      
    }
    if ( c == 'a' ) {   
      zx81.GetASM();      
    }

Ein kleines d ruft einen Dump der Z80-Register auf. Mit m kann der ROM-Speicher angezeigt werden, r zeigt den RAM-Speicher ab 4000. Ein frisch gestarteter ZX81 zeigt dann:

CPU :
PC : 0046 SP : 43FB
AF : DD02 BC : 1305
DE : C084 HL : C083
'AF : 0000 'BC : 0000
'DE : 2194 'HL : 0000
IX : 0281 IY : 4000


ZX81-Rom im seriellen Monitor der Arduino IDE zur Laufzeit

Ein auch schon in die Tage gekommener iPod-Touch 2G als ZX81-WiFi-Tastatur und ein 240x240 TFT Bildschirm gesteuert von einem ESP8266 kann dann ZX81-BASIC-Programme erstellen und auch ausführen. Ein herrliches Zusammenspiel!


Die stark vergrößerten Aufnahmen zeigen das Listing und Resultat. PS: Pause 0 stammt vom Spectrum und ist hier wirkungslos.

Wer diesen Emulator mit dem hier verwendeten ST7789-Display verwenden möchte, kann nach folgendem Schema verfahren:

  • Legacy IDE 1.8.19 als Zip-Archiv laden und in ein Verzeichnis entpacken. Serielle Treiber für den ESP downloaden und installieren.
  • ESP8266-Core 3.1.1 installieren und entsprechende ESP8266-Variante wählen, 1 MB FS.
  • Adafruit_GFX und Adafruit_ST7789 installieren, evtl. testen wie hier.
  • ESP8266FS-0.5.0.zip suchen, herunterladen und installieren.
  • Die hier leicht modifizierten Dateien herunterladen und entpacken.
  • Sketch esp8266_zx81.ino laden aus dem Verzeichnis esp8266_zx81 und probehalber kompilieren.
  • Sketch an entsprechender Stelle mit eigener SSID und PASS versehen (Router)
  • Menü Werkzeuge: ESP8266 Sketch Data Upload wählen. Ordner data wird hochgeladen.
  • Sketch hochladen und Daumen drücken.

Wenn alles klappt sollte das Bild ZX Emulator rot auf schwarzem Grund zu sehen sein. Nun verbindet sich der ESP mit dem im Sketch oberhalb von setup() angegebenen Router und Passwort. Bei Erfolg zeigt das Display die IP an. Im einem Browser die IP eingeben und auf die Darstellung der Tastatur warten. Nun lässt sich der ZX81 per Taste, Maus oder Touch in ZX-BASIC programmieren, während die Ausgabe auf dem TFT am ESP erscheint.


Splash-Screen, IP und iPod-Touch 2G mit Schutz-Folien-Tastatur


Pro-DOS-BASIC für den ZX-Spectrum
3D-ZX-Spectrum-Grafik auf Pi-Pico
ZX81 - Das Original 1981
Mehr ZX-Spectrum
Mehr Software

.
Startseite Bücher Software Digital RTV Musik Kontakt

Für Inhalt und weitere Verzweigung externer Links sind die Betreiber der dortigen Seiten verantwortlich - H.-J. Berndt