Das Agon Light und andere Revisionen der Agon-Plattform basieren auf dem Zilog eZ80-Prozessor. Der eZ80 verfügt über einen 24-Bit-Adressraum, der 16 Megabyte Speicher unterstützt, verglichen mit 64 Kilobyte beim ursprünglichen Z80. Der eZ80 verfügt über zwei Betriebsmodi: den Standard-Z80-Modus, der über 16-Bit-Register verfügt, was die Adressierung von 64 KB Speicher erleichtert, für den Zugriff auf mehr als 64 KB Speicher jedoch die Verwendung von „Banking“ erfordert; und der ADL-Betriebsmodus (Address Data Long), der die Register auf 24 Bit erweitert und so den gesamten Adressraum leicht zugänglich macht.
Wenn wir über höhere Programmiersprachen nachdenken, gibt es für den Z80 eine Reihe davon, diese sind jedoch auf 64 KB Speicher begrenzt oder verfügen über umständliche Methoden zum Bankwechsel, um auf größeren Speicher zuzugreifen.
Im Hinblick auf die C-Programmiersprachen stehen eine Reihe von Z80-C-Compilern zur Verfügung. Bisher hat sich die Agon-Community auf zwei konzentriert:
Zilog ZDS II-Entwicklungsumgebung , die eZ80 ADL-Code erstellen kann. Dabei handelte es sich um die ursprünglichen Tools, die von den Entwicklern von Agon verwendet wurden. Es handelt sich jedoch um Closed Source, läuft nur unter Windows und unterstützt nur den Datenstandard C89
SDCC (Small Devices C-Compiler) , eine beliebte Wahl für 8-Bit-Computer, und dessen Anpassung für Agon war ein Schwerpunkt einer Reihe von Leuten im Agon-Computer. Dies ist ein guter Compiler für Z80, aber er unterstützt nur Z80 und nicht den ADL-Modus.
Alternativ dazu ist die CEdev C/C++-Toolchain ein Open-Source-Compiler, der ADL-Code erzeugen kann. Es zielt auf den Taschenrechner TI-84 Plus CE (basierend auf dem eZ80-Prozessor) ab und verfügt über eine recht große Community. CEdev basiert auf eZ80-Versionen des LLVM-Compilers und des Fasmg-Assemblers. Es erzeugt ADL-Code mit 24-Bit-Zeigern, 24-Bit-Ganzzahlen, 32-Bit-Long-Werten, 16-Bit-Short-Werten und 32-Bit-Float-Werten. Es gibt auch eine recht umfangreiche Bibliothek für C- und C++-Programme (obwohl sie noch nicht ISO-konform ist ...).
AgDev ist das Ergebnis eines Versuchs, CEdev zu modifizieren, um es an den Funktionsumfang und das Hardware-Design der Agon-Plattform anzupassen. Das Ergebnis ist eine leistungsfähigere und C++-fähigere Toolchain im Vergleich zu anderen Optionen für den Agon.
Laden Sie einen Release-Build herunter oder bauen Sie selbst aus dem Quellcode. Platzieren Sie den Build in einem Verzeichnis Ihrer Wahl.
Stellen Sie anschließend sicher, dass der Ordner /bin
in PATH
zu finden ist. Wenn Sie Windows verwenden, befolgen Sie diese Anleitung, oder Sie können stattdessen cedev.bat ausführen und von dort aus Befehle ausführen. Führen Sie unter Linux export PATH=/<insert path here>/bin:$PATH
in einem Terminalfenster aus.
Dies folgt dem gleichen Ansatz wie die ursprüngliche CE-Toolchain (siehe unten auf der Seite „Erste Schritte“ von CEdev). Der Build-Prozess wurde so geändert, dass er bei der Generierung der .bin
Datei stoppt. Dies ist die ausführbare Datei von Agon Light.
Ich empfehle die Verwendung von:
sauber machen mache V=1
Mit dem Befehl make clean
können Sie die Ergebnisse früherer Kompilierungen löschen und so eine Neukompilierung erzwingen.
Der Build-Prozess durchläuft die folgenden Schritte:
Kompilierung von .c-Quelldateien in LLVM-Bitcode (.bc) mit ez80-clang
Verknüpfung von LLVM-Bitcode mit ez80-link
. Dazu gehört auch die Optimierung der Linkzeit
Generierung von eZ80-Assemblercode (.src) für die Quellprogramme mit ez80-clang
Zusammenstellen und Verknüpfen des generierten Assemblercodes (aus Schritt 3) mit den Bibliotheken und der Compiler-Laufzeit mithilfe von fasmg
– dazu gehört auch das Erstellen der ausführbaren Datei, die an einem bestimmten Speicherort ausgerichtet ist. Dies ist der Hauptteil des Build-Prozesses, der angepasst werden muss.
Siehe Zilog-Anwendungshinweis „Calling C from asm.pdf“.
Nur IX-Register und Stapel müssen von aufgerufenen Funktionen beibehalten werden.
Argumente werden entsprechend dem C-Prototyp vom letzten zum ersten verschoben. In eZ80 werden unabhängig von der tatsächlichen Größe immer 3 Bytes auf den Stapel geschoben. Allerdings muss die Assembly-Funktion darauf achten, nur die gültigen Bytes zu verwenden, die gepusht werden. Wenn beispielsweise ein kurzer Typ verwendet wird, enthält das obere Byte des auf den Stapel verschobenen Werts beliebige Daten. Diese Tabelle listet die Positionen relativ zu sp innerhalb der aufgerufenen Funktion auf. Beachten Sie, dass sp + [0,2]
die Rücksprungadresse enthält.
C/C++-Typ | Größe | Stapelstandort |
---|---|---|
verkohlen | 1 Byte | sp + [3] |
kurz | 2 Bytes | sp + [3,4] |
int | 3 Bytes | sp + [3,5] |
lang | 4 Bytes | sp + [3,6] |
lang lang | 8 Byte | sp + [3,10] |
schweben | 4 Bytes | sp + [3,6] |
doppelt | 4 Bytes | sp + [3,6] |
Zeiger | 3 Bytes | sp + [3,5] |
Beachten Sie, dass eZ80 Little Endian ist, dh das niedrigstwertige Byte wird zuerst gespeichert.
In dieser Tabelle ist aufgeführt, welche Register für Rückgabewerte einer Funktion verwendet werden. Das Vorzeichen des Typs hat keinen Einfluss auf die verwendeten Register, kann sich jedoch auf den zurückgegebenen Wert auswirken. Das LSB befindet sich im Register ganz rechts im Ausdruck, z. B. zeigt E:UHL
an, dass Register L
das LSB speichert.
C/C++-Typ | Rückgaberegister |
---|---|
verkohlen | A |
kurz | HL |
int | UHL |
lang | E:UHL |
lang lang | BC:UDE:UHL |
schweben | E:UHL |
doppelt | E:UHL |
Zeiger | UHL |
Nicht ISO-konform!
Besteht aus Folgendem:
Datei-IO:
fopen()
, freopen(),
fclose()
fputc()
, fputs()
fgetc()
, ungetc()
, fgets()
feof()
, ferror()
, fflush()
fread()
, fwrite()
fseek()
, rewind()
, ftell()
clearerr()
remove()
Stdin / stdout IO:
putchar()
, puts()
getchar()
, gets_s()
Formatierte Ausgabe
printf()
(und vprintf()
)
sprintf()
(und vsprintf()
)
snprintf()
(und vsnprintf()
)
Formatierte Eingabe
scanf()
sscanf()
Es gibt noch einige andere Dinge hier – wie stdint
und so – aber es sollte größtenteils den Erwartungen an die normale Standardbibliothek entsprechen. Meistens.
stdio
Umleitung Kann die Ausgabe umleiten, indem freopen()
auf stdout
oder stderr
verwendet wird:
putchar()
– Ausgabe an outchar()
, es sei denn, die Ausgabe wird umgeleitet. In diesem Fall erfolgt die Ausgabe an fputc()
puts()
– ruft putchar()
auf
printf()
(und vprintf()
) – ruft npf_putc_std()
auf, das putchar()
in nanoprintf.c
aufruft
fputc()
– ruft mos_fputc()
auf, es sei denn, es wird auf stdout
aufgerufen, wenn outchar()
aufgerufen wird – vermeidet den Aufruf von putchar()
sodass keine Gefahr von Funktionsaufrufschleifen besteht
Kann Eingaben umleiten, indem freopen()
auf stdin
verwendet wird:
getchar()
– ruft inchar()
auf, um das Zeichen abzurufen, und outchar()
um das Zeichen wiederzugeben (auch wenn die Ausgabe umgeleitet wurde). Wenn die Ausgabe nicht umgeleitet wurde, wird fgetc()
aufgerufen und das Zeichen wird nicht zurückgegeben.
gets_s()
– ruft getchar()
auf, wenn die Eingabe nicht umgeleitet wurde (Zeilen werden mit CR beendet). Aufrufe fgets()
der Eingabe wurden umgeleitet (Zeilen werden mit CR/LF-Paar abgeschlossen).
scanf()
– ruft getchar()
in uscan.c
auf (muss nicht aktualisiert werden)
fgetc()
– ruft mos_fgetc()
auf, es sei denn, es wird auf stdin aufgerufen, wenn inchar()
aufgerufen wird, und echot mit outchar()
– vermeidet den Aufruf von getchar()
, sodass keine Gefahr von Funktionsaufrufschleifen besteht
Erfordert FILE *
, einen Zeiger auf ein Dateihandle, das von fopen
zurückgegeben und an die Datei-E/A-Routinen übergeben wird, um die Datei anzugeben, für die die Aktion ausgeführt werden soll.
Andere verwandte Dateien:
stdio.h
– normale Header-Dateien, die die verschiedenen Funktionen und die Typdefinition für FILE
definieren
files.c
– instanziiert den Speicher für Dateihandles, einschließlich: stdout, stderr, stdin.
Die folgenden Standard-Dateihandles sind definiert:
stdout
– Standardausgabe
stderr
– Standardausgabe für Fehlermeldung
stdin
– Standardeingabe
MOS implementiert keine Eingabe-/Ausgabeumleitung, daher verwenden diese standardmäßig alle die Konsole.
Für die Befehlszeilenverarbeitung stehen zwei Optionen zur Verfügung.
Dies ist automatisch enthalten, wenn die Hauptfunktion als definiert ist
int main( int argc, char* argv[] )
Das teilt die Befehlszeile mit Leerzeichen als Trennzeichen auf. Die Befehlszeilenoptionen sind wie gewohnt im Array argv[]
verfügbar.
Dies ist optional enthalten, wenn das Anwendungs-Makefile Folgendes enthält:
LDHAS_ARG_PROCESSING = 1
Das unterstützt
Zitieren mit doppelten Anführungszeichen
Eingabe-/Ausgabeumleitung
>out_file.txt
– leitet stdout zu out_file.txt
um und erstellt eine neue Datei
>>out_file.txt
– leitet stdout zu out_file.txt
um und hängt es an das Ende der Datei an
<in_file.txt
– leitet stdin so um, dass es von in_file.txt
stammt
Die aktuelle Dokumentation zu MOS-Befehlen finden Sie in der Agon Console8-Dokumentation.
Das MOS (Machine Operating System) bietet eine Schnittstelle zum Agon-Dateisystem und einigen Hardware-Peripheriegeräten, wie der Maus. Es speichert Informationen zu Systemvariablen in einer großen SYSVAR
Struktur, auf die auf der Z80-Seite zugegriffen werden kann. Im Allgemeinen deklariert Ihr C-Code einen Zeiger auf diese Struktur, der wie folgt initialisiert wird:
static volatile SYSVAR* sv; sv = vdp_vdu_init();
Weitere Informationen finden Sie unter <mos_api.h>
.
Die aktuelle Dokumentation zu VDU-Befehlen finden Sie in der Agon Console8-Dokumentation.
Der VDP (Video Display Processor) akzeptiert einen Textstream vom MOS und verhält sich wie ein Text-/Grafikterminal. Der Textstream kann enthalten:
Normaler Text
Escape-Sequenzen/Befehle zur Steuerung der Anzeige und zum Senden von Grafik-/Sound-/usw.-Befehlen
Wenn MOS als Ergebnis des Sendens eines Befehls Ergebnisse zurückgibt, werden diese in den SYSVAR
gespeichert und nicht direkt als Antwort auf den Befehl zurückgegeben. Die Antwort ist asynchron – um zu überprüfen, ob ein Ergebnis zurückgegeben wurde:
Setzen Sie vdp_pflags
in SYSVAR
auf Null
Geben Sie den VDU-Befehl aus
Warten Sie, bis das entsprechende Bit in vdp_pflags
gesetzt ist – siehe <mos_api.h>
für die Bitmasken
Befehle können gesendet werden von:
putch()
– einzelnes Zeichen (dies ist nicht Teil der C-Standardbibliothek)
mos_puts()
– Zeichenfolge mit mehreren Zeichen
Beide geben direkt an MOS/VDP aus. Beachten Sie, dass sie nicht Teil der STDIO-Bibliothek sind und keiner CR/LF-Übersetzung oder -Umleitung unterliegen.
Komfortfunktionen für viele Bildschirmbefehle werden in AgDev bereitgestellt. Um beispielsweise den Bildschirmmodus auf 3 zu ändern, muss der C-Aufruf vdp_mode(3);
sendet 22,3
als einzelne Bytes an die Ausgabe, äquivalent zu putch(22); putch(3);
Eine Liste dieser Funktionen finden Sie unter <vdp_vdu.h>
. Weitere Funktionen im Zusammenhang mit der Tastaturbedienung finden Sie in <vdp_key.h>
.