Floppyspielereien Teil 1: Mut zur Lücke

Wie der ST seine Disketten verwaltet, und wie man ihm dabei gehörig auf die Sprünge helfen kann, soll hier am Beispiel eines Programmes gezeigt werden, das Träume erfüllt: Der HYPERFORMATTER bläst Disketten bis auf schwindelerregende 927000 Bytes auf und beschleunigt dazu noch den Zugriff um bis zu 30 %

927000 Bytes?! Wie macht man das? Um das zu erklären, muß ich weiter ausholen, weil mein Programm viele Finessen verwendet, die erst mal erklärt werden wollen. Ich möchte Ihnen dazu in einem Blitzkurs in zwei Folgen Grundlegendes und Raffiniertes über Disketten und Laufwerke erzählen. Sie sollten auch schon mal eine Diskette in der Hand gehabt haben — das sid diese kleinen viereckigen Dinger, die immer dem Bürostuhl unter die Rolle kommen (knirsch) — und Bits von Bytes unterscheiden können, sonst wird dieser Kurs Ihnen wohl nicht so viel bringen. Aber zumindest können Sie die Programmbeispiele abtippen und sich an den Ergebnissen delektieren.

Spuren, Sektoren und Lücken

Beginnen wir zur Abwechslung mal am Anfang: TOS, das Betriebssystem des ST (also nicht dieser Grafikaufsatz namens GEM), hält sich in der Diskettenverwaltung recht sklavisch an Vorgaben des großen Bruders MS-DOS. Grundsätzlich: Eine Disk teilt sich ein in Spuren (Tracks) und Sektoren. Bei der SF354 sind es 80 Tracks, bei der SF314 sogar 2 x 80 Tracks, weil da die Disketten beidseitig beschrieben werden. Jeder Track besteht wiederum aus 9 Sektoren:

(Bild 1: So sieht der Lesekopf eine typische ST-Diskette)

Spur 79 liegt innen, Spur 0 außen. Zwischen den Sektoren gibt es kleine Lücken, auf die ich noch zu sprechen komme. In den Sektoren werden die eigentlichen Daten abgespeichert, beim ST 12 Bytes pro Sektor.

Information durch Rotation

Über der rotierenden Diskette schwebt ein Schreib-Lesekopf. Beim Schreiben fließt Strom durch den Schreibkopf und erzeugt eine magnetische Fährte auf der Diskette. Beim Lesen ist es umgekehrt: Die magnetisierten Partikel auf der Disk induzieren einen Stromfluß im Lesekopf, den er als logisch T oder ’0‘ versteht. Aber keine Angst: So tief in die Physik brauchen wir nicht einzusteigen, der ST verfügt über einen Baustein (nämlich einen Diskcontroller), der sich um diese Dinge kümmert. Dieser Baustein im ST ist auch der Grund, warum die Programme dieses Kurses auch auf Fremdlaufwerken laufen: Die Floppystationen am ST sind nicht wie die anderen Rechner (C64) intelligent, sondern bestehen fast nur aus Mechanik.

Das bedeutet, die Ansteuerung hängt nur vom Controller ab, und der ist ja bei allen ST-Rechnern gleich.

Platz da!

Nun sieht man schon auf der Zeichnung, daß nach dem neunten Sektor noch viiiiel Platz ist, so viel Platz, daß viele Formatierprogramme (zum Beispiel) auch FAT-DISK aus der ST/86) dort einen zehnten Sektor unterbringen und so die Kapazität erhöhen. Das macht pr Spur immerhin 312 Bytes aus, bei 80 Spuren und 2 Seiten sind das 80 Kilobyte!

Bei vielen Laufwerken kann man auch den Schreib-Lesekopf bis über Track 79 hinaus bewegen. Einer eigenen Blitzumfrage bei Händlern und ST-Besitzern zufolge gibt es allerdings bei etwa der Hälfte aller Laufwerke Probleme ab Track 82, weil der Lesekopf anschlägt. Um herauszufinden, ob Ihr Laufwerk auch Track 82 noch mitmacht, sollten Sie mal eine freie Disk mit FATDISK formatieren. Legen Sie das Ohr aufs Laufwerk (ja, ich weiß, es klingt lächerlich, aber es lohnt sich) — wenn es bei Track 82 (FATDISK zeigt den aktuellen Track an) anders klingt als bei den vorherigen Trackwechseln (es hört sich etwa so an, als ob ein kleines Männchen in der Floppy den Lesekopf mit einem Hämmerchen bearbeitet), haben Sie Pech: Tyrannisieren Sie irgendjemanden, der Ihnen Ihre Floppy einstellen kann. Vielleicht kann der ja noch was machen. Andererseits können einige Leute aber auch ihren Kopf (quatsch, den ihrer Floppystation) bis Spur 85 bewegen!

Ein wenig Arithmetik: 83 Spuren (also Spur 0 bis Spur 82) mal 10 Sektoren mal 2 Seiten macht 1660 Sektoren = 849920 Bytes. Von dieser Summe geht aber noch einiges für Bürokratie weg, bei FATDISK bleiben nur 828416 Bytes übrig.

Verwaltungskram auf Disketten

Da ist zum ersten der geheimnisumwitterte Bootsektor (Track 0, Sektor 1, Seite 0), der 512 Bytes frißt. Nach dem Einschalten prüft der ST den Bootsektor der Diskette in Laufwerk A. Wenn dieser Bootsektor ausführbar ist, versucht der ST von dieser Diskette ein TOS zu laden. Außerdem stehen noch viele andere Informationen im Bootsektor, die ich genauer in der zweiten Folge behandeln werde.

Ab dem zweiten Sektor steht die sogenannte FAT (File Alloction Table). Auf ihr ist die Belegung der Diskette mit Dateien vermekrt. Das Format ist allerdings a bisserl kompliziert. Vorweg: TOS verwaltet seine Disketten nicht in logischen Sektoren, sondern in Clustern. Das sind jeweils 2 aufeinanderfolgende Sektoren. Eine neue Datei belegt mindestens einen ganzen Cluster — selbst bei einer Datei mit nur einem Byte! Diese Verschwendungssucht schmiert aber den Verwaltungsmechanismus und beschleunigt die Bürokratie (Parallelen mit der ,wirklichen“ Welt sind rein zufällig). Eine typische FAT fängt nun so an:

Jeder Cluster erhält in der FAT 12 Bit (!) zugewiesen, das sind drei Flexadezimalzt/ fern. Die ersten 5 Nullen sind Flags, deren Bedeutung ich noch nicht vollständig entschlüsselt habe. Bei MS-DOS, dem großen Bruder, steht im ersten Byte ein Format-kennzeichen, im zweiten ist die Kapazität der Floppy eingetragen. Seltsamerweise beeindrucken Änderungen der ersten beiden Bytes TOS nicht sonderlich.

Vielleicht hat sich ja schon ein Leser damit befaßt und scheibt mir oder der ST. Das :bere Nibble des 3.Bytes bedeutet offenbar auch nichts Besonderes (wie gesagt, ich bin für Tips zugänglich). Aber dann folgt cer Eintrag des Clusters mit der Nummer 2 (TOS speichert Daten erst ab Cluster 2 ab). Hier sehen wir ’003‘, das heißt: Die Datei, die im Cluster 2 beginnt, wird im Cluster 3 fortgesetzt. Im Eintrag für Cluster 3 steht ’400‘, also ein umgedrehtes ’004‘ (warum auch immer), die Datei setzt sich folglich bei Cluster 4 fort undsoweiter.

Am Schluß der Datei steht ein Endekennzeichen (FFO). In MS-DOS zumindest gibt es noch die Kennzeichen FF7 (Sektor beschädigt) und FF8—FFF (Dateiende). Für jeden Cluster sind 12 Bit reserviert, macht (bei normalen Format) 8640 Bit = 1080 Byte, also knapp 3 Sektoren. Trotzdem reserviert ATARI großzügig 5 Sektoren für die FAT.

Tanz auf dem Vulkan

Direkt auf die erste FAT folgt eine identische Kopie der FAT, aus Sicherheitsgründen. Nett gedacht, nur: beide FATs liegen in der Regel auf der gleichen Spur, und da viele Programme gleich eine ganze Spur schreiben, segelt bei einem Fehlgriff auch die Kopie ins Nirwana. Traurig, traurig, denn nur mit diesem roten Faden (oder besser: FATen) kann man feststellen, welche Bereiche eine Datei belegt. Gerade bei zerstörten Dateien ist das sehr wichtig — und ohne FAT gleicht der Versuch, die Datei wieder zusammenzuklauben, einer stecknadelsuche im Vesuv.

Ein Tip für diejenigen, die es trotzdem versuchen wollen (oder müssen, mein Beileid): TOS versucht grundsätzlich, aufeinanderfolgende Sektoren für neue Dateien zu verwenden. Erst wenn es auf einen breits belegten Sektor stößt, weicht das Betriebssystem aus. Auf einer einigermaßen leeren Diskette hat man also noch relativ gute Chancen, seine Dateisektoren wiederzufinden.

Nach den FATs steht in 7 Sektoren die Directory, beim normalen Format ab dem 12. Sektor, vom Anfang der Diskette an gezählt (dabei zählt man zuerst die Sektoren der Vorderseite, dsann die der Rückseite, so vorhanden, und geht dann weiter zum nächsten Track). Jeweils 32 Bytes pro Datei beinhalten deren Namen und Kenndaten unter anderem auch einen Verweis auf den ersten Dateicluster. Damit gerüstet, schaut TOS an der betreffenden stelle der FAT nach und kann den Verlauf einer Datei verfolgen. Genaueres zur Directory im Teil 2 der Reise durchs wilde Floppy-stan (in der nächsten ST).

Kurze Überschlagsrechnung: Für die Verwaltung einer Diskette gehen summa summarum 18 Sektoren für Bootsektor, FATs und Direcotry hops, also 9216 Bytes.

Nochmal in der Zusammenfassung der Anfang einer ST-Diskette:

1. Sektor: Bootsektor (Track 0, Seite 0, Sektor 1)

2. Sektor: FAT1 (Track 0, Seite 0, Sektor 2)

7. Sektor: FAT2 (Track 0, Seite 0, Sektor 7)

12. Sektor: Directory (bei SF314: Track 0, Seite 1, Sektor 3? bei SF 354: Track 1, Seite 0, Sektor 3)

Danach: Daten und Programme

Manche Formatierprogramme kürzen die beiden FATs noch auf jeweils 3 Sektoren (was völlig ausreicht) und die Directory auf 64 Einträge (also 4 Sektoren) und gewinnen so 7 Sektoren = 2584 Bytes.

Der Clou: HYPERFORMAT

Trotzdem, das alles kann noch nicht das Wahre sein: der AMIGA hat doch auch diseiben Laufwerke und formatiert auf 880K. Warum kann das der ST nicht, fragt man sich. Er kann. Aber dazu mußte ich erst mal einiges umbiegen.

Glücklicher AMIGA, du hast es leichter. Das Betriebssystem des AMIGA formatiert nämlich eine Diskette mit 11 Sektoren pro Spur! Macht zusammen — bei 80 Spuren — über 900000 Bytes! Et voila, dachte ich mir, ds müßte der ST doch auch können, setzte mich fröhlich pfeifend an meinen ATARI-Ferrari, um die Sache auszuprobieren, und verlor schon nach kurzer Zeit die Lust: Ein schnell zusammengehacktes Formatierprogramm für 11 Sektoren formatierte zwar, doch überschrieb der elfte Sektor immer den ersten: Zuwenig Platz auf der Spur. Was tun? Irgendwo im Betriebssystem entdeckte ich schließlich die Formatierroute des XBIOS, die man auch über den internen XBIOS-Aufruf 10 erreicht. Wenn man analysiert, was TOS da so auf die Diskette schreibt, kommt man schließlich auf folgendes Track-Format: (siehe Tabelle 1)

Der lange Weg zum Glück

Das Problem: Es paßt zuwenig auf eine Spur, um einen elften Sektor schreiben zu können. Die Beobachtung: Zwischen den einzelnen Informationen auf der Spur liegen immer wieder Lückenbytes (Gapbytes). Schlußfolgerung: Wenn man die Lücken auf ein Minimum kürzt, bringt das vielleicht so viel Platz auf der Spur, daß noch ein elfter Sektor draufpaßt.

Vorspann (Index, Trackheader; "PoST Index Mark")

(*) Lückenbytes (Pre Adress Mark)
    Synchronisationsbytes 
    Adressmarke + Sektorinfo 
    Checksumme 
    Lückenbytes (PoST Adress Mark)
    Synchronisationsbytes 
    Datenmarke + DATEN 
    Checksumme
    Lückenbytes (PoST Data Mark)
zurück zu (*). bis alle Sektoren geschrieben sind, danach:

Lückenbytes bis zum Trackende.

(Tabelle 1: Einer Spur auf der Spur)

Und in der Tat: Man kann die Lückenbytes kürzen (durch Änderungen in der Formatierroutine des TOS), wenn man sich nur daran hält, daß mindestens 30 Lückenbytes zwischen Adreßmarke und Daten geschrieben werden. Das erste HYPERFORMAT modifiziert also zuerst mein RAM-TOS so, daß 11 Sektoren auf eine Spur passten, rief dann ganz normal das XBIOS auf, um zu formatieren, und gab dabei an, 11 Sektoren formatieren zu wollen.

Hexerei bringt Geschwindigkeit

HYPERFORMATiert man eine Diskette nach diesem Verfahren, gibt es allerdings bald lange Gesichter:

1. Nicht jedes Laufwerk vertrug offenbar die Roßkur fürs XBIOS. Auf Laufwerken von Freunden ließen sich HYPERFORMATierte Disketten zunächst nicht lesen, später zwar lesen, aber nicht HYPER-FORMATieren. Nach kniefieslingster Probiererei mit den Lückengrößen scheinen auch andere Laufwerke mein HYPERFORMAT zu verstehen, so daß ich damit an die Öffentlichkeit treten kann, ohne sofortige Enthauptung zu fürchten. Sollte es doch nicht laufen, liegt das an physikalischen Toleranzen der Laufwerke.

2. Die Schreib-Lesegeschwindigkeit zwar zunächst ein Graus (3mal langsamer, als die sowieso nicht sehr schnelle SF314 sonst liest). Ein Freund kam auf die rettende Idee — Stichwort Interleave (dafür bekam er auch eine Widmung im Programm).

Normalerweise werden die Sektoren so auf die Spur geschrieben wie in Bild 1 angegeben, also erst Sektor 1, dann Sektor 2 und sofort. Beim normalen Format liest die Floppy zuerst den Sektor 1, der Floppycontroller (das ist der Baustein, der die Ansteüerung des Laufwerks übernimmt) werkelt jetzt ein bißchen, und wenn er wieder bereit ist, hat sich die Lücke zwischen den Sektoren gerade unterm Lesekopf vorbeigedreht, so daß gleich der nächste Sektor gelesen werden kann. Bei den gekürzten Lücken stimmt nun dieses Timing nicht mehr, und der Controller muß immer wieder Pausen einlegen und warten, bis der passende Sektor wieder unter dem Lesekopf vorbeirotiert. Nun kann man eine Spur aber auch so formatieren:

(Bild 2: Mehr Speed durch noch mehr Mut zur Lücke)

Damit hat der Controller zwischen zwei aufeinanderfolgenden Sektoren (etwa zwischen Sl und S2) immer genug Zeit! Diese Taktik nennt man Interleaving, der Interleavefaktor ist in diesem Falle — und auch per Voreinstellung in meinem Programm — sechs (weil auf die aktuelle Sektornummer immer sechs addiert wird; wenn das Ergebnis größer als die Anzahl der Sektoren pro Spur ist, wird diese Anzahl abgezogen). So modifiziert, bringt HYPERFORMAT eine Diskette auf beachtliche Geschwindigkeit: Im Durchschnitt ist sie im gemischten Schreib-Lesezugriff 20 bis 35 % schneller als normal formatierte Disketten, in Einzelfällen liegt dieser Wert sogar noch weit besser.

Dieser Geschwindigkeitsvorteil rührt auch daher, daß man beim Diskzugriff nicht mehr so oft den Track wechseln muß, weil mehr Daten auf eine Spur passen. Und der Trackwechsel ist auch eine zeitaufwendige Sace (normalerweise werden jeweils 3ms dafür verbraten).

3. In der bisherigen Version lief HYPERFORMAT nur auf RAM-TOS, da ja Passagen aus dem TOS geändert, gepatcht werden mußten. In der jetzigen Version ist auch das gelöst.

HYPERFORMAT prüft nach, ob ein ROM-TOS vorliegt, wenn nein, erwartet es ein RAM-TOS in der Version vom 6.2.86 im Speicher (es müßte auch mit der Version vom 18.7.85 laufen), wenn ja, benutzt es eine modifizierte ROM-Routine mit Einsprüngen ins ROM. Eine wichtige Anmerkung: Booten Sie ein FASTLOAD mit, wenn Sie den Geschwindigkeitsvorteil von HYPERFORMAT-Disketten nutzen wollen. Beim Umschreiben des Programmes auf ROM-Rechner habe ich bemerkt, daß das Timing beim Lesen und Schreiben nur mit FASTLOAD optimal ist. Deswegen installiert HYPERFORMAT bei gebootetem RAM-TOS gleich FASTLOAD und FASTFORMAT mit.

ROM-Beisitzer haben zwei Möglichkeiten: Ein FASTLOAD-Programm booten (in den AUTO-Ordner kopieren), das auch auf ROM-Rechnem läuft, oder die ROMs in Eproms kopieren und dabei auf den FASTLOAD-Modus umbrennen. Dazu ändert man im Eprom U7 den Inhalt der Eprom-Adresse $0DC7 von $14 auf $10 (modifizierte EPROMS gibt es auch für 30 Mark zu kaufen). Eine von diesen Möglichkeiten sollten Sie nutzen, um alle Vorteile von HYPERFORMAT genießen zu können. Die FASTLOAD-Modifikation läuft übrigens schon seit einem Jahr bei mir und bei vielen Bekannten ohne Kompliaktionen, also keine falsche Vorsicht.

Und ein kleines Trostpflaster für ST-Besitzer ohne FASTLOAD: Das Formatieren läuft bei HYPERFORMAT auch bei ROM-Rechnern mit derselben Geschwindigkeit, als wäre ein FASTLOAD mitgebootet worden! Und wenn Sie den Interleavefaktor auf 3 einstellen, ergibt sich sogar doch noch ein kleiner Geschwindigkeitsvorteil gegenüber normalen Disketten.

Allerdings werden Disketten mit Interleavefaktor 3 wieder langsam, wenn man sie mit FASTLOAD liest. Deswegen empfehle ich dringend (um auch vom Speed her die Kompatibilität zu wahren), den Interleave nicht zu verstellen, sondern ein FASTLOAD ins TOS zu integrieren.

Die Anleitung zu HYPERFORMAT

Das Programm ist vollständig in Assembler geschrieben und relokatibel; es wurde mit dem AS68 aus dem Entwicklungspaket assembliert. Andere Assembler brauchen eventuell andere Pseudo-Ops; bitte halten Sie sich an die Anleitung Ihres Assemblers. Das Programm an sich ist recht lang zum Abtippen, seien Sie vorsichtig. Die Kommentare müssen Sie ja nicht treudoof runterhacken, aber lesen Sie die Hinweise, man kann dabei sicher was für die eigene Programmierung lernen. Nicht zuletzt deswegen ist HYPERFORMAT heavily documented, wie der Angelsachse so schön sagt.

Wenn Sie das Programm fertig eingetippt ich beneide Sie nicht), assembliert (fluch!) und gelingt (bibber!) haben, dann starten und keine Bomben oder ATARI-Gardinen entdecken, haben Sie es geschafft, Sie sind im Menü angekommen.

Im Menü können Sie einige Parameter einstellen, zum Beispiel, wieviel Spuren Sie formatieren wollen (wichtig für Leute mit dem Knackatakatak bei der 82. Spur), wieviel Seiten Ihr Laufwerk hat (auf der einseitigen Floppy hat man dank HYPERFORMAT 459000 Bytes frei), wieviel Directoryeinträge Sie zulassen wollen, und welcher Interleavefaktor gewählt wird.

Voreingestellt sind 2 Seiten, 83 Tracks (also Spur 0 bis Spur 82 einschließlich), 64 Directoryeinträge und ein Interleavefaktor 6, und damit ergeben sich mehr als 927000 freie Bytes auf Ihrer Diskette (AMIGA go home!). HYPERFORMAT kürzt die FATs dabei auf völlig ausreichende drei Sektoren. CTRL-C im Menü bricht das Programm ab, RETURN startet das Formatieren, ’B‘ überspringt das Formatieren und schreibt nur Bootsektor, FAT und Directory neu. ROM-Besitzer ohne FASTLOAD können den Interleave auf 3 einstellen (siehe oben).

Zusätzlich sind im Listing noch folgende Parameter änderbar:

virgin (Daten, mit denen die Sektoren beim Formatieren initalisiert werden) spt (Sektoren pro Track) res (Reservierte Sektoren) fat (Anzahl der FATs) secsperfat (Länge der FAT)

Von allen anderen Parametern im Listing sollten Sie zunächst mal die Finger lassen.

Sollte Ihr Laufwerk doch mal bocken und Lesefehler melden, können Sie in den Routinen change_tos und rom_fmt die gekennzeichneten „Lücken“ von 3 auf 4 vergrößern, das hilft meistens.

Diesmal haben Sie erfahren, wie eine Diskette aufgebaut ist, wie die Aufzeichnung funktioniert, was FATs, Cluster und Diskcontroller sind, wie man mit kleinen Tricks den Verwaltungsaufwand reduzeirt und mehr Platz gewinnt, und Sie haben jetzt mit HYPERFORMAT die ultimate Waffe gegen den Knetefraß durch Diskettenkauf. In der nächsten ST lesen Sie, wie man auf den Diskettencontroller des ST zugreift, was der für Finessen beherrscht, wie man BIOS, XBIOS und GEMDOS für die Arbeit mit der Floppy nutzen kann, wie gängige Kopierschutzmechanismen funktionieren und einiges mehr.

(Tabelle 2: Hier noch eine Liste der Routinen von HYPERFORMAT:

maln Hauptschleife

change_tos modifiziert RAM-TOS und inSTa11iert FASTLOAD+FASTFORMAT repair_tos macht Änderungen am RAM-TOS rückgängig, nicht aber FASTLOAD und FASTFORMAT formatdisk ganze Diskette formatieren formattrack eine Spur formatieren

rom Vorbereitungen für die romfmt-Routine romfmt Modifzierte Formatierroutine aus dem ROM

writeboot Bootsektor und FATs initialisieren

writesector einen Sektor schreiben

printmsg STring ausgeben

waitforkey Auf TaSTe warten

mallocerror,freeerror,fatal-error Fehlermeldungen

Parameters Eingabeschleife fürs Menü

op_exe Exe-Flag ändern

op_tracks Anzahl der Tracks ändern

op_side Anzahl der Seiten einSTellen

op_dir Wieviele Directoryeinträge?

op_inter Interleavefaktor ändern

calc_secs Zahl der Sektoren auf der Disk ausrechnen

*********************************************************
* HYPERFORMATTER                                        *
* Written 1987 by Claus Brod                            *
* Am Felaenkeller 2                                     *
* 8772 Marktheidenfeld                                  *
* (C) 1987 and for all eternity by Claus Brod           *
*                                                       *
* 1. Formatiert Diskette in Laufwerk A                  *
* auf über 905K (>927000 Bytes frei)                    *
* 2. Beschleunigt Diskzugriff bei Laden                 *
* und Speichern um 20-35%                               *
*                                                       *
* Version für RAM- und ROM-TOS                          *
* Revision 2.0, Last update 4.4.87                      *
* Assembliert mit AS68 aus dem Entwicklungspaket        *
*********************************************************

virgin      .equ $cbcb      * Virgin data
spt         .equ 11         * Sektoren pro Track
laufwerk    .equ 0          * Laufwerk A
secsperfat  .equ 3          * Sektoren pro FAT
spc         .equ 2          * Sectors per Cluster
res         .equ 1          * Reservierte Sektoren
fat         .equ 2          * Anzahl der FATs
bufflength  .equ 10000      * Länge des Trackpuffers

******************
* Routine zum Reservieren von Speicherplatz
******************

    move.l  a7,a5           * Stackpointer retten
    move.l  4(a5),a5        * Basepage—Start vom Stack nach a5
    move.l  $c(a5),d0       * Länge von .text
    add.l   $14(a5),d0      * Länge von .data addieren
    add.l   $1c(a5),d0      * Länge von .bss addieren
    add.l   #$500,d0        * Platz für den Stack muß auch sein
    move.l  d0,d1           * Ergebnis nach d1
    add.l   a5,d1           * Ergebnis + Adresse der Basepage
    and.l   #-2,d1          * Adresse gerade machen
    move.l  d1,a7           * Stackpointer = errechnete Adresse
    move.l  d0,-(sp)        * Größe des Bereiches
    move.l  a5,-(sp)        * Startadresse. ab der reserviert wir
    clr.w   -(sp)           * Dummy (reserviert)
    move.w  #$4a,-(sp)      * SETBLOCK
    trap    #1              * im GEMDOS
    add.l   #12,sp

    clr.l   -(sp)           * Userstack wird Supervisorstack
    move.w  #$20,-(sp)      * SUPER
    trap    #1              * im GEMDOS
    add.l   #6,sp           * ab jetzt alles im Supervisormode
    lea     save_ssp(pc),a2
    move.l  d0,(a2)         * Supervisorstackpointer retten
    cmpi.l  #$00FC0000,$4F2 * von ROM gebootet?
    beq     rom_ist_da      * ja. weiter
    bsr     change_tos      * RAM-TOS patchen
    lea     romflag(pc),a2
    move.b  #-1,(a2)        * Flag für 'kein ROM' setzen
rom_ist_da:
    bsr     main            * Ab ins Hauptprogramm

exitus:
    lea     romflag(pc),a2
    cmpi.b  #-1,(a2)        * ROM drin?
    bne     rom_sweet_rom   * jawoll, weiter
    bsr     repair_tos      * Heileheilegänschen fürs RAM-TOS
rom_sweet_rom:
    move.l  save_ssp(pc),-(sp) * zurück
    move.w  #$20,-(sp)      * in den Usermode
    trap    #1 
    add.l   #6,sp

    clr.w   -(sp)           * Raus in die boese Welt
    trap #1

**************************
* main: Holt Parameter, formatiert
* und gibt Gelegenheit zur Wiederholung 
**************************

main:
    lea     msg1(pc),a5     * Intromeldung
    bsr     printmsg        * ausgeben

    bsr     parameters      * Parameter einsteilen
    lea     diskmsg(pc),a5
    bsr     printmsg        * 'Diskette einlegen'
    bsr     waitforkey      * auf Taste warten
    bsr     calc_secs       * Sektoren ausrechnen

    lea     fmtflag(pc),a2
    cmpi.b  #13,(a2)        * Formatieren oder nur Bootsektor?
    bne     nurboot
    bsr     formatdisk      * eigentliche Formatierroutine
nurboot:
    lea     againmsg(pc),a5 * Noch'ne Message
    bsr     printmsg

    bsr     writeboot       * Bootsektor etc. schreiben
    bsr     getkey          * auf Taste warten
    cmpi.b  #'y',d0         * nochmal?
    beg     main            * 'y' für ja, zurück
    cmpi.b  #'Y',d0
    beq     main            * 'Y' für ja, zurück
    rts

**************************
* change_tos: ändert TOS ab 
**************************
change_tos:
    lea     $000075c2,a5    * a5 auf Anfang der fmt-Routine
    move.b  #3,$81(a5)      * Post Index Mark, evt. auf 4
    move.b  #3,$8f(a5)      * Pre Adress Mark. evt auf 4
    move.b  #21,$bf(a5)     * Post Adress Mark 1
    move.b  #11,$cb(a5)     * Post Adress Mark 2 C2)
    move.b  #3,$f9(a5)      * Post Data Mark, evt auf
    move.w  #600,$118(a5)   * Nachspann
    move.l  #$6000034c,$58fa5) * FASTFORMAT
    suba.1  a5,a5           * a5 löschen
    move.b  #$10,$7a1d(a5)  * FASTLOAD
    rts

**********************
* repairtos: siehe oben, nur retour 
**********************

repair_tos:
    lea     $000075c2,a5 
    move.b  #$3b,$81(a5) 
    move.b  #$b,$8f(a5) 
    move.b  #$15,$bf(a5)
    move.b  *$b,$cb(a5) 
    move.b  #$27,$f9(a5) 
    move.w  #$578,$118(a5) 
    rts

***********************
* formatdisk: von Track 0-endtrack formatieren 
***********************

formatdisk:
    move.l  #bufflength,-(sp) * bufflength Bytes
    move.w  #$48,-(sp)  * per MALLOC
    trap    #1          * (GEMDOS)
    addq.l  #6,sp       * reservieren
    tst.l   d0          * Fehler?
    bmi     mallocerror * Rumpel...

    move.l  d0,a6       * Trackpufferadresse nach a6
    move.w  #0,d4       * ab Track 0 formatieren
floop:
    move.w  #0,d5       * Seite 0 formatieren
    bsr     formattrack 
    lea     side(pc),a2
    cmpi.b  #2,(a2)     * 1 oder 2 Seiten?
    bne     nureine     * eine Seite, nächster Track
    move.w  #1,d5       * Seite 1 formatieren
    bsr     formattrack 
nureine:
    addq.w  #1,d4       * Nächster Track
    cmp.b   endtrack(pc),d4 * alle Tracks formatiert?
    bls     floop       * Nein, weiter

    move.l  a6,-(sp)    * Reservierten Bereich per
    move.w  #$49,-(sp)  * MFREE im GEMDOS
    trap    #1          * wieder freigeben
    addq.l  #6,sp
    tst.l   d0          * Fehler?
    bne     freeerror   * Da soll doch...
    rts

************************
* formattrack: Einen Track formatieren
* d5:Seite, dd:Track, a6:Puffer
***********************

formattrack:
    move.w  #virgin,-(sp)   * Virgin
    move.l  #$87654321(sp)  * Magic Number
    move.w  ileave(pc),-(sp) * Interleave
    move.w  d5,-(sp)        * Seite
    move.w  d4,-(sp)        * Track
    move.w  #spt,-(sp)      * Sektoren pro Track
    move.w  #1aufwerk,-(sp) * Laufwerk (A)
    clr.l   -(sp)
    move.l  a6,-(sp)        * Pufferadresse
    lea     romflag(pc),a2 
    move.b  (a2),d0
    cmp.w   #-1,d0          * ROMs eingebaut?
    bne     rom             * ja, in ROM-Routine
    move.w  #10,-(sp)       * Und ab ins XBIOS: flopfmt
    trap    #14 
    add.l   #2,sp 
redo_stk:
    add.l   #24,sp
    tst     d0              * Fehler passiert?
    bmi     fatalerror      * Oje oje
    rts

rom:
    move.l  $4a2,a1
    movem.l d3-d7/a3-a7,-(a1)   * Register retten
    move.l  a1,$4a2
    clr.l   a5 * a5 löschen
    lea     $FC0000,a0          * Offset-Register für ROM-Calls
    bsr     romfmt 
    move.l  $4a2,al
    movem.l (a1)+,d3-d7/a3-a7   * Register holen
    move.l  a1,$4a2 
    bra     redo_stk

**************************
* romfmt-, modifzierte Formatierroutine des ROM
**************************

romfmt:
    jsr     $1CBE(a0)       * Disketten gewechselt?
    moveq.l #$FF,d0
    jsr     $1A34(a0)       * Parameter setzen
    lea     $fc0000,a0
    jsr     $1014(a0)       * select drive and side
    move.w  $E(a7),$9D4(a5) * Sektoren pro Track
    move.w  $14(a7),$9D6(a5) * Interleave
    move.w  $1A(a7),$9D8(a5) * Virgin
    moveq.l #2,d0
    lea     $fc0000,a0
    jsr     $1CF6(a0)       * Diskette gewechselt
    lea     $fc0000.a0
    jsr     $1B28(a0)       * Track anfahren
    bne     fatalerror      * Fehler beim Tracksuchen
    move.w  $9C4(a5),$0(a1) * aktueller Track
    move.w  #$FFFF.$9E0(a5)
    bsr     machhin         * Track formatieren
    bne     fatalerror      * Fehler passiert

    move.w  $9D4(a5),$9CA(a5) * Sektoren/Track als Zähler
    move.w  #1,$9C6(a5)     * mit Sektor X anfangen
    lea     $fc0000,a0
    jmp     $lada(a0)       * flopok (verify überspringen)

machhin:
    move.w  #$FFF6.$9DE(a5)
    move.w  #1,d3           * mit Sektor X anfangen
    move.l  $9cc(a5),a2     * Adresse des Puffers

    move.w  #3,d1           * 4 Lückenbytes (evt. auf
    move.b  #$4E,d0         * move.w #4,d1 ändern)
    bsr     wmult           * in Puffer schreiben
nsect2:
    move.w  d3,d4           * Sektornummer retten

nsect:
    move.w  #3,d1           * 4 Lückenbytes (evt. auf
    clr.b   d0              * move.w #4,d1 ändern)
    bsr     wmult
    move.w  #2,d1           * 3 Syncbytes (nicht ändern!)
    move.b  #$F5,d0         * $F5 schreiben
    bsr     wmult

    move.b  #$FE,(a2)+      * $FE, Adreßmarke schreiben
    move.b  $9C5,(a2)+      * Tracknr. schreiben
    move.b  $9C9,(a2)+      * Seite
    move.b  d4,(a2)+        * Sektor
    move.b  #2,(a2)+        * Bytes pro Sektor. Hibyte
    move.b  #$F7,(a2)+      * Checksumme schreiben
    move.w  #$15,d1         * 22 Lückenbytes (nicht ändern!)
    move.b  #$4E,d0         * $4E schreiben
    bsr     wmult
    move.w  #$b,d1          * 12 Lückenbytes (nicht ändern!)
    clr.b   d0              * 0 schreiben
    bsr     wmult
    move.w  #2,d1           * 3 Syncbytes (nicht ändern!)
    move.b  #$F5,d0         * $F5 schreiben
    bsr     wmult
    move.b  #$FB,(a2)+      * $FB- Datenblockmarke
    move.w  #$FF,d1         * 256 Worte

wrvirgin:
    move.b  $9D0(a5),(a2)+  * Virgin data
    move.b  $9D9{a5),(a2)+ 
    dbra    d1,wrvirgin

    move.b  #$F7,(a2)+      * Checksum schreiben
    move.w  #3,d1           * 4 Lückenbytes (evt. auf
    move.b  #$4E,d0         * move.w #4,d1 ändern)
    bsr     wmult

**************************
* writeboot: Bootsektor etc. schreiben
**************************

writeboot:
    lea     bootsector(pc),a5   * Bootsektor-Adresse
    move.w  executable(pc),-(sp) * Ausfuhrbarkeitsflag
    move.w  #-1,-(sp)           * Disktyp nicht andern
    move.l  #$11000000,-(sp)    * Serial number zufällig erzeugen
    move 1  a5,-(3p)            * Adresse des Puffers übergeben
    move.w  #18,-(sp)           * PROTOBT
    trap    #14                 * im XBIOS
    add.l   #14,sp

    move.w  #0,d5               * Track 0
    move.w  #1,d6               * Sektor 1
    move.w  #0,d4               * Seite 0
    bsr     writesector         * Bootsektor schreiben

    move.w  #2,d6               * Ab Sektor 2
    move.w  #0,d4               * Beite 0
    move.w  #0,d5               * Track 0
    lea     cleansector(pc),a5  * cleansector schreiben
cnochma1:
    bsr     writesector 
    addq.w  #1,d6 
    cmp.w   #12,d6 
    bne     cnochma1 
    rts

*******************
* writesector: Einen Sektor schreiben
* Seite in d4, Track in d5, Sektor in d6, Pufferadresse in a5 *******************

writesector:
    move.w  #1,-(sp)            * Count
    move.w  d4,-(sp)            * Seite
    move.w  d5,-(sp)            * Track
    move.w  d6,-(sp)            * Sektor
    move.w  #laufwerk,-(sp)     * Laufwerk
    clr.l   -(sp)               * Füllsel
    move.l  a5,-(sp)            * Pufferadresse
    move.w  #9,-(sp)            * FLOPWR
    trap    #14                 * Xbios
    add.l   #20,sp 
    rts

********************
* printmsg: String ausgeben
* Adresse in a5 
********************

printmsg:
    move.l  a5,-(sp)            * Message ausgeben
    move.w  #9,-(sp)
    trap    #1                  * GEMDOS
    addq.l  #6,sp 
    rts

    add.w   $9D6(ab),d4         * Interleave draufzählen
    cmp.w   $9D4(a5),d4         * mit größter Sektornummer^v
    ble     nsect               * vergleichen

    addq.w  #1,d3               * Startsektor plus eins
    cmp.w   $9d6(a5),d3         * Interleave
    ble     nsect2

    move.w  #600,d1             * 601 Lückenbytes (Änderung
    move.b  #$4E,d0             * zwecklos)
    bsr     wmult

    move.b  $9CF(a5),$FFFF860D  * DMA—Lowbyte
    move.b  $9CE(a5),SFFFF860B  * DMA-Midbyte
    move.b  $9CD(a5),SFFFF8609  * DMA-Highbyte
    move.w  #$190,(a6)          * DMA-Status säubern
    move.w  #$90,(a6)
    move.w  #$190,(a6)          * Datenrichtung
    move.w  #$1F,d7 
    lea     $fc0000,a0
    jsr     $1C90(a0)           * d7 an Controller schicken

    move.w  #$180,(a6)
    move.w  #$F0,d7             * format_track-Befehl
    lea     $fc0000.a0
    jsr     $1C90(a0)           * d7 an Controller

    move.l  #$40000,d7          * timeout-Zähler

mfploop:
    btst    #5,$fffffa01        * Controller fertig?
    beq     dmastatus           * ja. weiter
    subq.l  #1,d7               * nein, warten
    bne     mfploop

    lea     $fc0000,a0
    jsr     $1BFA(a0)           * abbrechen
kaputt:
    moveq.l #1.d7               * Fehler
rts

dmastatus:
    move.w  #$190,(a6)          * DMA-Status
    move.w  (a6),d0             * lesen
    btst    #0,d0               * Fehler?
    beq     kaputt              * ja, Fehler

    move.w  #$180,(a6) 
    lea     $fc0000,a0
    jsr     $1CA4(a0)           * Register lesen
    lea     $fc0000,a0
    jsr     $165A(a0)           * Fehlernummer
    and.b   #$44,d0
    rts

wmult:                          * Bytes in Puffer schreiben
    move.b  d0,(a2)+ 
    dbra    d1,wmu1t 
    rts


**********************
* waitforkey: 'Taste drücken' ausgeben
* und auf Taste warten
***********************

waitforkey:
    lea     keymsg(pc).a5       * ‘Taste drücken'
    bsr     printmsg

getkey:                         * Einsprungpunkt ohne Message
    move.w  #7,-(sp)            * Auf Taste warten
    trap    #1                  * GEMDOS Conin without echo
    addq.l  #2,sp 
    rts

*************************
* Error-Routine mit Einsprungpunkten für verschiedene
* Fehlermeldungen. Gibt Fehler aus und verabschiedet sich 
*************************

mallocerror:
    lea     ma1locmsg(pc),a5    * Fehler beim Reservieren von Speicher
    bra     error

freeerror:
    lea     freemsg(pc),a5      * Fehler bei der Freigabe von Speicher
    bra     error

fata1error:
    lea     errormsg(pc),a5     * Fehler beim Formatieren

error:
    bsr     printmsg            * Error-Routine. Textadresse in a5
    bsr     waitforkey          * Gibt Message aus, wartet auf Taste
    bra     exitus              * und terminiert

*************************
* Parameters: Gibt Menue aus
* und erlaubt Änderungen 
*************************

parameters:
    lea     msg_parms(pc),a5
    bsr     printmsg            * Menue ausgeben

    bsr     getkey              * Auf Taste warten
    cmpi.b  #3,d0               * ^C?
    beq     exitus              * ja, raus
    cmpi.b  #13,d0              * RETURN?
    beq     end_parms           * ja, fertig
    cmpi.b  #'b',d0             * 'b' für boot
    beq     end_parms
    cmpi.b  #'B',d0
    beq     end_parms

    cmpi.b  #'d',d0             * 'd' gedrückt
    beq     op_dir              * Dir—Einträge ändern
    cmpi.b  #'D',d0 
    beq     op_dir
    cmpi.b  #'s’,d0             * 's' gedrückt
    beq     op_side             * Seitenzahl ändern
    cmpi.b  #'S',d0 
    beq     op_side
    cmpi.b  #'t',d0             * 't' gedrückt
    beq     op_tracks           * letzten Track andern
    cmpi.b  #'T',d0
    beq     op_tracks
    cmpi.b  #'e',d0             * 'e' gedrückt
    beq     op_exe              * Ausführbarkeit andern
    cmpi.b  #'E',d0
    beq     op_exe
    cmpi.b  #'i',d0             * 'i' gedrückt
    beq     op_inter            * Interleave ändern
    cmpi.b  #'I',d0
    beq     op_inter
    bra     parameters

end_parms:
    lea     fmtflag(pc),a2      * fmt oder nur boot
    move.b  d0,(a2)
    rts

op_exe:                         * Ausführbarkeitsflag ändern
    lea     s_exe(pc),a2        * Stringadresse
    lea     executable(pc),a3   * Adresse der Variablen
    move.w  (a3),d0
    move.b  #’Y',d1             * Yes als Default
    eor.w   #1,d0               * Flag invertieren
    bne     wr_exe              * nicht ausführbar?
    move.b  #'n',d1             * auf 'No' ändern
wr_exe :
    move.b  d1,(a2)             * String und
    move.w  d0,(a3)             * Flag ändern
    bra     parameters

op_tracks:                      * Tracks ändern
    lea     s_tracks(pc),a2     * Stringadresse
    lea     endtrack(pc),a3     * Adresse der Variablen
    move.b  $1(a2),d0           * Low-Nibble des Strings
    move.b  (a3),d1             * Wert
    addq.b  #1,d1               * um eins erhöhen
    addq.b  #1,d0
    cmpi.b  #'7',d0             * mehr als 86 Tracks läuft nicht
    bne     wr_tracks 
    move.b  #'0',d0
    move.b  #79,d1              * letzter Track 79

wr_tracks:
    move.b  d0,$1(a2)           * String und
    move.b  d1,(a3)             * Flag ändern
    bra     parameters

op_side:                        * Seiten ändern
    lea     s_sides(pc),a2      * Stringadresse
    lea     side(pc),a3         * Adresse im Bootsektor
    move.b  (a3),d0             * Seitenzahl nach d0 holen
    move.b  $1(a2),d1
    eor.b   #3,d0               * Seitenzahl ändern
    eor.b   #3,d1
    move.b  d0,(a3)             * in Bootsektor schreiben
    move.b  d1,$1(a2)           * für String aufbereiten
    bra     parameters 
op_dir:
    lea     s_dir(pc),a2        * Stringadresse
    lea     entries(pc),a3      * Adresse der Einträge
    move.b  (a3),d0 
    move.b  (a2),d1
    addq.b  #1,d1
    add.b   #16,d0              * 16 aufaddieren
    cmpi.b  #143,d0             * schon mehr als erlaubt?
    bne     wr_dir              * nein, fertig
    move.b  #15,d0              * wieder von vorne
    move.b  #'1',d1 
wr_dir:
    move.b  d0,(a3)             * Bootsektor aktualisieren
    move.b  d1,(a2)             * String aktualisieren
    bra     parameters

op_inter:
    lea     s_inter(pc),a2      * Stringadresse
    lea     ileave(pc),a3       * Inter1eave-Adresse
    move.w  (a3),d0             * Wert holen
    move.b  1(a2),d1            * String holen
    addq.b  #1,d1 
    addq.b  #1,d0
    cmpi.b  #10,d0              * schon 10?
    bne     wr_inter 
    move.w  #1,d0 
    move.b  #'1',d1 
wr_inter:
    move.b  d1,1(a2) 
    move.w  d0,(a3) 
    bra     parameters

***************************
* calc_secs: Anzahl der Sektoren ausrechnen
* Formel: (endtrack+1)*11*side
****************************
calc_secs: 
    clr.l   d1 
    clr.l   d0
    lea     sectors(pc),a3
    move.b  endtrack(pc),d0     * Letzter Track
    addq.b  #1,d0               * plus eins
    mulu    #11,d0              * mal 11
    move.b  side(pc),d1
    mulu    d1,d0               * mal side
    move.b  d0,(a3)             * Lowbyte schreiben
    asr.l   #8,d0               * Highbyte holen
    move.b  d0,$1(a3)           * und schreiben
    rts

************************
* Der Text 
************************
.even 
msg1:
.dc.b 27,'E',27,'P                                 ',13,10
.dc.b 'THE HYPER FORMATTER V2.0',13,10
.dc.b '========================',13,10
.dc.b ' Written 1987 by Claus Brod ',13,10
.dc.b ' (Thanks to CD and Anton) ',27,'q',13,
.dc.b ' 927000 Bytes free & 30% faster',0

msg_parms:
.dc.b 27,'Y',32+7,32+0 
.dc.b 27,'pT’,27,'q Tracks             '
s_tracks:
.dc.b '83',13,10
.dc.b 27,'pE',27,'q Ausführbar (executable):'
s_exe:
.dc.b 'n',13,10
.dc.b 27,'pD',27,'q Directoryeinträge      :$'
s_dir:
.dc.b '40',13,10
.dc.b 27,'pS',27,'q Seiten (sides)         :'
s_sides:
.dc.b '02',13,10
.dc.b 27,'pl',27,'q interleave             :'
s_inter:
.dc.b '06',13,10
.dc.b 13,10,27,'pCR',27,'q HYPERFORMAT ',13,10 
.dc.b 27,'p^C',27,'q Quit',13,10
.dc.b 27,'pB ',27,'q Bootsektor etc. schreiben',13,10,0

.even 
againmsg:
.dc.b 13,10,13,10,'Again (Y/N)? ',0 
diskmsg:
.dc.b 13,10,'Bitte Disk in Laufwerk ',65+laufwerk,' einlegen.',13,10,0 
keymsg:
.dc.b 'Taste drücken.',13,10,0 
errormsg:
.dc.b 13,10,'Fehler beim Formatieren!',13,10,0 
mallocmsg:
.dc.b 13,10,'MALLOC Error!',13,10,0 
freemsg:
.dc.b 13,10,'MFREE Error!',13,10,0

.even
bootsector:
.dc.b 96,56,76,111,97,100,101,114 
.dc.b 203,31,238,0,2,spc,res,0,fat 
entries:
.dc.b 63,0 
sectors:
.dc.b 34,7,249,secsperfat,0,spt,0 
side:
.dc.b 2,0,0,0,0,0,0,0,0,0,0,0,0,4 
.dc.b 0,0,0,0,128,0,84,79 
.dc.b 83,32,32,32,32,32,73,77 
.dc.b 71,0,51,250,255,226,0,0 
.dc.b 4,130,63,57,0,0,4,70 
.dc.b 63,60,0,7,78,77,88,79 
.dc.b 74,128,103,0,0,246,42,64 
.dc.b 65,250,255,208,74,144,102,6 
.dc.b 32,185,0,0,4,50,48,45 
.dc.b 0,8,225,72,208,128,56,64 
.dc.b 217,250,255,184,48,58,255,170 
.dc.b 103,16,60,58,255,166,56,58 
.dc.b 255,164,38,122,255,162,96,0 
.dc.b 0,180,60,45,0,10,56,45 
.dc.b 0,8,216,109,0,6,38,122 
.dc.b 255,146,97,0,0,178,102,0 
.dc.b 0,170,32,76,48,45,0,6 
.dc.b 225,72,227,72,65,240,0,0 
.dc.b 67,250,255,124,144,252,0,32 
.dc.b 177,204,109,0,0,142,112,10 
.dc.b 18,48,0,0,178,49,0,0 
.dc.b 102,234,81,200,255,244,126,0 
.dc.b 30,40,0,27,225,79,30,40 
.dc.b 0,26,44,122,255,78,38,122 
.dc.b 255,70,66,132,190,124,15,240
.dc.b 108,82,54,7,85,67,198,237 
.dc.b 0,2,214,109,0,12,184,124 
.dc.b 0,64,108,8,74,68,103,14 
.dc.b 182,69,103,16,97,72,102,66 
.dc.b 225,140,227,140,215,196,60,3 
.dc.b 58,3,66,132,216,109,0,2 
.dc.b 218,109,0,2,52,7,226,74 
.dc.b 212,71,18,54,32,1,225,73 
.dc.b 18,54,32,0,8,7,0,0 
.dc.b 103,2,232,73,194,124,15,255 
.dc.b 62,1,96,368,74,68,103,4 
.dc.b 97,12,102,6,47,58,254,224 
.dc.b 78,117,66,128,78,117,63,57 
.dc.b 0,0,4,70,63,6,63,4 
.dc.b 47,11,66,103,63,60,0,4 
.dc.b 78,77,222,252,0,14,74,64 
.dc.b 78,117,78,101,117,116,101,114 
.dc.b 32,66,111,111,116,101,114,13 
.dc.b 10,40,67,41,49,57,56,53 
.dc.b 32,65,116,97,114,105,32,67 
.dc.b 111,114,112,46,13,10,0,0 
.dc.l 0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0

cleansector:
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 * Je 16 Nuller
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
.dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

ileave:
.dc.w 6 
endtrack:
.dc.b 82 
executable:
.dc.w 0 
fmtflag:
.dc.b 0 
romflag:
.dc.b 0 
.even 
save_ssp:
.dc.l 0
.end


Aus: ST-Computer 06 / 1987, Seite 20

Links

Copyright-Bestimmungen: siehe Über diese Seite