Atari ST Assemblerprorammierung mit Beispielen
GEM-Programmierung (Graphics Environment Manager) auf dem Atari ST in Motorola 68000 Assembler erfordert die Kommunikation mit den Betriebssystem-Schichten AES (Application Environment Services) und VDI (Virtual Device Interface) über Software-Interrupts (Traps) sowie die Bereitstellung von Parameter-Blöcken (z. B. cntrl, global, intin, intout, addrin, addrout).
Architektur des GEM-Aufrufs in Assembler
Im Gegensatz zu reinen GEMDOS-Aufrufen (wie trap #1 für Textausgabe) läuft ein AES- oder VDI-Aufruf über einen speziellen Parameterblock.
• AES-Traps: Erfolgen typischerweise über trap #2 (oder Bibliotheken wie AESBIND, die den Aufruf kapseln). • VDI-Traps: Erfolgen ebenfalls über trap #2 mit einem Zeiger auf den VDI-Parameterblock in Register d0.
Grundlegendes Schema für einen GEM/AES-Aufruf (Prinzipieller Ablauf)
In Assembler (z. B. mit HiSoft DevPac oder vasm) sieht ein AES-Funktionsaufruf (wie appl_init zu Beginn eines Programms) strukturell so aus:
Schritt Aktion in Assembler Beschreibung
-
Initialisierung lea control(pc), a0 Zeiger auf den GEM-Control-Array laden
-
Funktion eintragen
move.w #10, (a0)
move.w #0, 2(a0)
move.w #1, 4(a0) ... Opcode für appl_init (Funktion 10) in den Control-Block schreiben
- Parameter-Zeiger
lea pb_struct(pc), a1
move.l a0, (a1) ... Zeigerblöcke (control, global, intin, intout, addrin, addrout) in die Parameter-Struktur eintragen
- Trap auslösen
move.w #200, d0
lea pb_struct(pc), a1
move.l a1, d1
trap #2 GEM-AES-Trap über trap #2 aufrufen
-
Auswertung
move.w intout(pc), d0 Rückgabewert (z. B. Application ID) auslesen
Minimaler Programm-Strukturvergleich (Assembler vs. C/GEM)
Da direkte GEM-Programmierung in purem 68k-Assembler sehr mühsam ist, nutzen viele Entwickler entweder Makros (wie bei DevPac oder angepasste .s-Include-Dateien) oder greifen auf C-Compiler zurück. Komplette Open-Source-Beispiele für Atari-ST-Assemblerprojekte finden sich im Simple Atari ST Project Template auf GitHub sowie in umfangreichen Archiven wie den Atari ST Sources auf GitHub.
Ausführliche Dokumentationen und Handbücher zur klassischen GEM-Struktur bietet unter anderem das Atari ST GEM Programming 1986 Manual auf dem Internet Archive.
Um den Namen eines Programms und den Inhalt des aktuellen Verzeichnisses auf dem Atari ST zu ermitteln, nutzt man am einfachsten die GEMDOS-Aufrufe (Trap #1). Reines GEM (AES/VDI) für Fenster und Dialoge wäre für diese Aufgabe extrem lang und unübersichtlich, da GEMDOS bereits perfekte Funktionen für die Dateisuche mitbringt (Fsetdta, Fsfirst, Fsnext). Hier ist ein vollständiges, lauffähiges Beispielprogramm in Motorola 68000 Assembler (kompatibel mit Devpac / GenST), das genau das tut. Es nutzt die Standard-Konsole des TOS für die Textausgabe.
Assembler-Quelltext (TOS/GEMDOS)
assembly
; =============================================================================
; ATARI ST - Verzeichnisinhalt auflisten in Assembler
; =============================================================================
OUTPUT .TOS ; Erzeugt ein ausführbares TOS-Programm
; --- GEMDOS Funktions-Opcodes ---
Cconws EQU 9 ; String auf Konsole ausgeben
Cconin EQU 1 ; Auf Tastendruck warten
Fsetdta EQU 26 ; DTA (Disk Transfer Address) setzen
Fsfirst EQU 78 ; Erste Datei suchen
Fsnext EQU 79 ; Nächste Datei suchen
Pterm0 EQU 0 ; Programm normal beenden
SECTION TEXT
START:
; 1. DTA-Puffer für die Dateisuche registrieren
pea dta_buffer(pc) ; Adresse des DTA-Puffers auf den Stack
move.w #Fsetdta,-(sp) ; GEMDOS Funktion 26
trap #1 ; Aufruf
addq.l #6,sp ; Stack aufräumen
; 2. Begrüßungstext ausgeben
pea msg_title(pc) ; Adresse des Titels auf den Stack
move.w #Cconws,-(sp) ; GEMDOS Funktion 9
trap #1
addq.l #6,sp
; 3. Erste Datei im Verzeichnis suchen (*.*)
move.w #$07,-(sp) ; Attribute: Normale Dateien, Verzeichnisse, etc.
pea search_mask(pc) ; Suchen nach "*.*"
move.w #Fsfirst,-(sp) ; GEMDOS Funktion 78
trap #1
addq.l #8,sp ; Stack aufräumen
tst.w d0 ; d0 < 0 bedeutet Fehler oder keine Datei gefunden
bmi exit ; Wenn Fehler, direkt zum Ende springen
print_file:
; 4. Gefundenen Dateinamen aus dem DTA-Puffer ausgeben
; Der Dateiname liegt im DTA-Puffer ab Offset 30
pea dta_buffer+30(pc)
move.w #Cconws,-(sp)
trap #1
addq.l #6,sp
; Einen Zeilenumbruch (CR/LF) ausgeben
pea msg_crlf(pc)
move.w #Cconws,-(sp)
trap #1
addq.l #6,sp
; 5. Nächste Datei suchen
move.w #Fsnext,-(sp) ; GEMDOS Funktion 79
trap #1
addq.l #2,sp
tst.w d0 ; d0 == 0 bedeutet: Weitere Datei gefunden
beq print_file ; Schleife wiederholen
exit:
; Am Ende auf einen Tastendruck warten, damit das Fenster nicht schließt
pea msg_end(pc)
move.w #Cconws,-(sp)
trap #1
addq.l #6,sp
move.w #Cconin,-(sp) ; Auf Taste warten
trap #1
addq.l #2,sp
; Programm ordnungsgemäß beenden
move.w #Pterm0,-(sp) ; GEMDOS Funktion 0
trap #1
; =============================================================================
SECTION DATA
; =============================================================================
search_mask:
dc.b "*.*",0 ; Suchmaske für alle Dateien
msg_title:
dc.b 27,"E" ; VT52-Steuercode: Bildschirm löschen
dc.b "=========================================",13,10
dc.b "Programm: DIRLIST.TOS",13,10
dc.b "Inhalt des aktuellen Verzeichnisses:",13,10
dc.b "=========================================",13,10,0
msg_crlf:
dc.b 13,10,0 ; Wagenrücklauf und Zeilenvorschub
msg_end:
dc.b 13,10,"Fertig. Bitte eine Taste druecken...",13,10,0
; =============================================================================
SECTION BSS
; =============================================================================
; Der DTA-Puffer muss laut Atari-Spezifikation mindestens 44 Bytes groß sein.
; Offset 30 bis 43 enthält den gefundenen Dateinamen als Null-terminierten String.
dta_buffer:
ds.b 44
END
Wie funktioniert das Programm?
-
Fsetdta (Zuweisung des Puffers): Bevor der Atari ST nach Dateien suchen kann, braucht er einen Speicherbereich (die Disk Transfer Address oder DTA), in den er die Metadaten der gefundenen Datei (Größe, Datum, Name) schreibt.
-
Fsfirst (Die erste Datei): Wir übergeben dem Betriebssystem die Suchmaske .. TOS sucht die erste passende Datei und füllt die DTA. Ab Offset 30 der DTA steht der Name der Datei.
-
Cconws (Textausgabe): Gibt den Namen auf dem Bildschirm aus. Da das TOS standardmäßig den VT52-Terminal-Standard nutzt, löscht 27,"E" (ESC E) zu Beginn den Bildschirm.
-
Fsnext (Die Schleife): Das Programm ruft so lange Fsnext auf, bis das Register d0 einen negativen Wert zurückgibt. Das signalisiert dem Programm: "Keine weiteren Dateien mehr vorhanden".
Auf der Linuxconsole läßt sich das mit
vasmm68k_mot -Ftos -o dirlist.tos dirlist.s
assemblieren. Zum Testen benutzt man dann am besten hatari und kopiert sich das TOS-File vorher auf die Harddisk. Das sieht dann z.b. so aus:
hatari --harddrive ~/atarihdd/
oder wenn man mit einer virtuellen Disketten arbeiten will:
hatari --disk-a /mnt/chromeos/removable/chromeb/atarifiles/$1.st --harddrive ~/atarihdd/
wobei $1 der Platzhalter für die Diskette,z.b. signum ist.
