← Zurück zur Übersicht

AtariAssembler1

Veröffentlicht am


AtariAssembler1

Am Beispiel lerne ich AtariAssemblerprogrammierung

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

  1. Initialisierung lea control(pc), a0 Zeiger auf den GEM-Control-Array laden

  2. 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

  1. Parameter-Zeiger

lea pb_struct(pc), a1

move.l a0, (a1) ... Zeigerblöcke (control, global, intin, intout, addrin, addrout) in die Parameter-Struktur eintragen

  1. 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

  1. 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?

  1. 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.

  2. 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.

  3. 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.

  4. 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.

Info

Diese Seite wurde dynamisch aus Groovy-DSLs generiert.


User: