Sie sind auf Seite 1von 32

ASDIS

Assembler/Disassembler/Reverse Assembler/Einzelschrittbetrieb

(C) Horst Kling, Hermannstr.7, 7000 Stuttgart 1, Tel. 0711/617113

Mit Kommentaren von Kai Fischer, ZX-Team, Mai 1999


Der Originaltext wurde zu 99% übernommen. Das restliche % sind Schönheitskorrekturen, die die
Anleitung für den Einsteiger verständlicher machen.

Allgemeines

ASDIS ist ein Disassembler / Assembler für den ZX81. Bei der Entwicklung wurde besonderer
Wert auf Absturzsicherheit und Einfachheit der Benutzung gelegt. ASDIS ist aber speziell auf den
ZX81 zugeschnitten und unterscheidet sich in einigen Punkten von anderen Assemblern. Deshalb ist
es wichtig, diese Anleitung einmal durchzulesen, bevor man sich an die ersten Programmierschritte
wagt.
Hier in Stichworten die wichtigsten Leistungsmerkmale von ASDIS:
- Ein interaktiver Editor unterstützt das Schreiben eines Assemblerprogramms und verhindert
Syntaxfehler.
- Der Assembler erzeugt daraus den lauffähigen Maschinencode.
- Der Disassembler wandelt Maschinencode in lesbare Mnemoniks um.
- Der Reverse-Assembler wandelt Maschinencode in ein Assemblerlisting um, das dann mit dem
Editor weiterbearbeitet werden kann.
- Mit dem Einzelschrittbetrieb kann ein Maschinenprogramm schrittweise simuliert werden.
- Alle Tasten haben Autorepeat, wenn sie länger als ca. 1/2 sec festgehalten werden.
- Es können beliebig viele Labels und Konstanten definiert werden.

Das Programm wurde vollständig in Maschinencode geschrieben und hat deshalb kurze
Reaktionszeiten. (Im Vergleich zu manchen Basicprogrammen)
ASDIS gibt es als 16K- oder als 64K-Version, je nach Größe Ihres Speichers. Die 16K-Version
belegt den Speicher ab etwa 25000, während die 64K-Version im Bereich von 8192 bis 16384 liegt.
Basic und Assembler beeinflußen sich gegenseitig nicht, können also parallel benutzt werden.
ASDIS legt seinen Quelltext als Variable A$ ab. Es empfiehlt sich daher immer, 64k Speicher zu
nehmen und RAMTOP soweit hoch als möglich zu setzen. Manche Strukturen legt ASDIS recht
speicherintensiv an, sodaß ein 4k-Programm schnell ein A$ von 16k Länge besitzt.

Laden
Die Kassettenversion laden Sie mit dem Namen „ASDIS“ oder einfach „“. Wenn es richtig
eingelesen wurde, meldet das Programm sich mit diesem Namen und zeigt die Adresse an, an der
der Assembler aufgerufen werden kann. Diese Adresse sollten Sie abschreiben, denn sobald man
eine Taste berührt, wird NEW ausgeführt. Je nach RAM wurde der Maschinencode nach 8192(64K)
oder nach ca 25000(16K) verschoben. Zusätzlich wurde bei der 16K-Version der RAMTOP
darunter gelegt, so daß das Programm vor NEW geschützt ist.
Deshalb können auch weitere Programme bzw. ein Assemblerlisting nachgeladen werden, welches
sich dann mit dem Assembler bearbeiten läßt.
Wesentlich einfacher gestaltet sich diese Prozedur, wenn man ASDIS gleich in ein EPROM ab
Adresse 8192 ablegt. Dann reduziert sich das gesamte Prozedere auf ein simples RAND USR 8192!
Noch ein Wort zum Speicher: ASDIS legt unterhalb RAMTOP einen Bereich mit eigenen
Systemvariablen an, der etwa 100 Bytes umfaßt.

Listing:
Das Listing ist der Speicherbereich, in den das Programm alles schreibt, was im Editor eingegeben
wird (also Kommentare, Labels, Befehle, usw.). Wenn das Programm gestartet wird, überprüft es
zuerst, ob sich schon ein Assemblerlisting im Speicher befindet. Wenn das nicht der Fall ist, wird
automatisch eines erzeugt. Der Benutzer braucht sich um das Listing überhaupt nicht kümmern, er
sollte nur wissen, daß es immer in der Basic-Variablen A$ steht. Diese Variable darf also nicht
verändert werden. Ein geschriebenes Listing kann man mit Basic-SAVE auf Kassette speichern und
mit LOAD zur Weiterbearbeitung wieder laden. Mit CLEAR kann man ein Listing komplett
löschen. Diese Anweisung ist für ASDIS dasselbe, wie NEW für das Basic.

Symbole
Symbole können bis zu 5 Zeichen lang sein, müssen immer mit einem Buchstaben beginnen und
dürfen nur aus Buchstaben und Ziffern bestehen. Blanks innerhalb des Symbols sind nicht erlaubt.
Folgende Symbole sollten Sie nicht benutzen, da der Assembler sie mit anderen Mnemonikteilen
verwechselt:
A,B,C,D,E,L,H,L,M,P,R,Z,AF,BC,DE,HL,SP,NC,NZ,PE,PO,IX,IY.
Alle anderen Symbolnamen sind erlaubt.
ASDIS bietet 2 verschiedene Arten von Symbolen an: Marken und Labels. Der Unterschied besteht
darin, daß Labels listingabhängige Symbole sind, deren Wert sich mit dem Listing ändern kann,
während Marken benutzerdefinierte Symbole sind, die nur vom Programmierer geandert werden
können. Gemeinsam ist beiden, daß sie eine 16-Bit-Zahl darstellen. Im Programm können Sie beide
Symbolarten völlig gleich verwenden, um z.B. einen Zahlenwert zu bekommen oder einen Sprung
auszuführen. Solch eine Verwendung ist ein Aufruf.
Beispiel: Der Befehl LD HL,(DFILE) ist erlaubt, unabhängig davon, ob DFILE ein Label oder eine
Marke ist.

Zahlen
Zahlen kann man als Dezimalzahlen, Hexzahlen oder Symbole eingeben.
- Dezimalzahlen werden ohne Zusatz geschrieben.
- Hexzahlen müssen mit einem „$“, beginnen.
- Symbole müssen mit einem Buchstaben beginnen.
Negative Zahlen und Rechenoperatoren sind nicht erlaubt. Wenn ein eingegebenes Symbol nicht
existiert, wird es je nach Situation entweder nicht akzeptiert oder stattdessen der Wert 0
angenommen. Die Tatsache, daß alle 3 Eingabeformen immer völlig gleichwertig sind, sollten Sie
besonders beachten, denn dadurch lassen sich viele Funktionen sehr einfach verwenden. Wenn also
bei irgendeiner Funktion eine Zahl eingegeben werden soll, kann man stattdessen immer auch ein
Symbol eingeben.

Funktionstasten
Immer wenn verschiedene Funktionen gleichzeitig zur Auswahl stehen, können sie durch einen
einzelnen Tastendruck aufgerufen werden. In dieser Zeit reagieren alle gültigen Tasten wie
Funktionstasten. Das ist z.B im Hauptprogramm der Fall, wo man durch einen Tastendruck eine
Funktion aufrufen kann, oder in vielen Funktionen, wo durch Tastendruck Unterfunktionen
erreichbar sind.
Alle Funktionen werden bei längerem Tastendruck automatisch wiederholt.
Es wurde versucht, denselben Tasten - soweit möglich - immer dieselben Funktionen zuzuordnen.
6 - vorwärts
7 - rückwärts
8 - Return
9 - Ausgabe an Drucker
Text- oder Zahleneingaben
Wenn eine Funktion weitere Eingaben erwartet, stellt sie einen entsprechenden Eingaberaum zur
Verfügung, innerhalb dessen man die Eingabe machen kann. (Wenn z.B. eine Zahl oder ein Label
erwartet wird, kann man nur eine 5stellige Eingabe machen, bei der Eingabe einer Befehlszeile
werden maximal 5 Zeichen erwartet, usw.) Diese Eingabe muß normalerweise linksbündig sein.
Bei allen Eingaben haben die Tasten N/L oder Shift und eine der Ziffern 5 bis 9 immer folgende
Bedeutung:
N/L - Eingabe beenden
Shift 5 - Cursor (ein invertiertes Zeichen) nach links
Shift 8 - Cursor nach rechts
Shift 6 - das Zeichen, auf dem der Cursor steht, wird gelöscht und alle folgenden werden
verschoben. (Delete)
Shift 7 - an der Stelle des Cursors wird ein Blank eingefügt, alle folgenden Zeichen werden
verschoben. (Insert)
Shift 9 - Umschaltung in invertierte Schreibweise. Nach N/L oder erneutem Shift wird wieder in
normale Schreibweise geschalten. Die invertierte Schreibweise ist nur für Kommentare und
Textzeilen interessant.
Eine Rubout-Funktion gibt es nicht, dafür kann man alle Zeichen direkt überschreiben. Autorepeat
bei längerem Tastendruck.

Hauptprogramm
Aus dem Hauptprogramm lassen sich 20 Funktionen direkt aufrufen. Die unteren 5 Bildzeilen
zeigen dauernd die Kurzbezeichnungen dieser Funktionen an und die Tasten, mit welchen man sie
starten kann. Wenn eine Funktion aufgerufen ist, steht anstelle der entsprechenden Taste ein
invertiertes „>".
Wenn die Funktion beendet ist, kehrt sie ins Hauptprogramm zurück und der invertierte Winkel
verschwindet wieder.
Funktionen des Hauptprogramms
1. EINGB. Dies ist die Eingabefunktion (Editor), mit der man ein Listing schreiben kann. Da sie
aber viele Unterfunktionen enthält, wird sie am Schluß gesondert beschrieben

2.WERTE. Damit können Hexadezimal- in Dezimalwerte und umgekehrt umgerechnet werden.


Man gibt eine Zahl oder ein Symbol ein und der entsprechende Wert wird dezimal und hexadezimal
angezeigt.

3. SCHIB. (SCHIEBEN) Ein Datenblock kann von beliebiger Stelle im RAM in beliebiger
Entfernung nach vorn oder hinten verschoben werden. Auch Überlappungen sind erlaubt. (z.B.
Verschiebung von 100 Bytes um 10 Adressen nach hinten oder vorn.)
Es erscheint das Wort „VON“ und man gibt ein, von wo ein Datenblock geholt werden soll. Nach
N/L erscheint das Wort „NACH“ und man gibt die Zieladresse ein. Sobald man nach dem Wort
„ZAHL“ die Anzahl der Bytes eingegeben hat, die verschoben werden soll, wird die Funktion
ausgeführt. Nach der Ausführung erscheint „OK“. Sie wird nicht ausgeführt und ins
Hauptprogramm zurückgekehrt, wenn eine der 3 Eingaben ungültig ist.
Wer sich schon mit Assembler auskennt: SCHIB ist dasselbe wie LDIR, nur etwas intelligenter.
Sowas müßte man als Makro im Listing einbauen können!

4.SUCHE. Eine Folge von 1 bis 6 Bytes kann gesucht werden. Es. werden bis zu 32 Hexzeichen
(„0“... „F“) erwartet. Diese Zeichen stellen 1 bis 16 Bytes dar. Sonderzeichen (wie z.B. Blanks)
dürfen deshalb nicht eingegeben werden. Die Zeile wird immer bis zum ersten nichthexadezimalen
Zeichen als eingegeben angesehen. Nach „N/L“ erscheint die Frage „AB WO“ und man gibt die
Adresse ein, ab der gesucht werden soll. Jeweils die Anfangsadresse eines gefundenen Blocks wird
jetzt dezimal und hexadezimal angezeigt. Auf irgendeinen Tastendruck wird der nächste identische
Block gesucht, mit "8" kann die Funktion verlassen werden. Die zu suchende Folge wird auch an
einer bestimmten Stelle im Speicher abgelegt, dort also auch immer gefunden. Irgendwo kurz vor
RAMTOP...

5. INHLT. (INHALT) Diese Funktion verschafft per Tabelle einen Überblick über den Inhalt des
Assemblerlistings, wobei die einzelnen Worte folgendes bedeuten:
LAUFADR: Laufadresse, also die Adresse, an welcher das Programm nach dem Assemblieren
lauffähig ist. (Siehe Funktion A)
ABLEGEN Adresse, wo das Programm nach dem Assemblieren abgelegt werden soll. (Siehe
Funktion A)
M-CODE gibt die Länge des Maschinencodes an, der im Listing enthalten ist, also die Länge (in
Bytes), die das reine Maschinenprogramm bisher hat (wenn man alle Labels, Kommentare, interne
Codierung usw. abrechnet).
LISTING gibt die Länge des Listings (in Bytes) an. Das ist die Länge der Variablen A$ (die durch
Eingabe eines Assemblerprogramms vergrößert wurde) inklusive Labels, Kommentare, usw.
ZEILEN Zahl der Zeilen, die das Listing enthält.
KOMMENT Zahl der Kommentare
BEFEHLE Zahl der Befehlszeilen
VARIABL Zahl der definierten Arbeitspeicher (Frei-, Text-, Datenzeilen)
MARKEN Zahl der definierten Marken.
LABELS Zahl der verwendeten Labels.
AUFRUFE Zeigt an, wieviele Symbole durch das Listing aufgerufen wurden. (Siehe Symbole)
FREI AB Adresse des ersten Bytes, das vom Basic (also auch vom Listing) nicht mehr benötigt
wird.
BYTES Anzahl der freien Bytes zwischen „FREI“ und dem Maschinenstack. Zeigt also die Größe
des Speicherbereiches an, der für Maschinencode frei ist.
(Alle Werte werden dezimal und hexadezimal angezeigt.)

6. RNAM. (RENAME) Ein Symbol kann umbenannt werden. Es erscheint das Wort „ALT:“ und
man gibt die bisherige Schreibweise ein, danach erscheint „NEU:“ und man gibt den neuen Namen
ein. Wenn 2 richtig geschriebene Symbole eingegeben wurden, durchsucht das Programm das
komplette Listing und ersetzt jedes Vorkommen des alten Symbols durch das neue und sagt
anschließend „OK“.
Diese Funktion ist vor allem im Zusammenhang mit dem Reverse Assembler interessant. wenn man
automatisch erzeugte Symbole umbenennen will.

7.SYMBL. (SYMBOL) Sämtliche Symbole werden aufgelistet und deren dezimale und
hexadezimale Werte angezeigt. Zuerst erscheint das Wort „MARKEN“ und nach den Marken das
Wort „LABELS“ und alle Label. Es werden jeweils max. 18 Symbole angezeigt, bei Tastendruck
erscheinen die nächsten. Normalerweise werden die Symbole relativ ungeordnet abgespeichert und
deshalb auch ungeordnet angezeigt. Wenn man aber Shift und 7 drückt statt 7, dann werden die
Symbole vor der Anzeige zuerst alphabetisch geordnet (im Fast-Modus).

8. RETURN Kehrt ins Basic zurück.

9. DRUCK. Ausgabe des oberen Bildschirmteils an den Drucker.


A. ASSMB. Diese Taste startet den Assembler. Da es sich bei ASDIS um einen 2-Paß-Assembler
handelt, dauert dieser Vorgang im allgemeinen nur Sekundenbruchteile. (Längere Listings brauchen
aber schon ein paar Sekunden bis knapp eine Minute.) Im ersten Assembler-Paß werden die Werte
aller Labels berechnet und im 2. Lauf werden diese Werte überall eingesetzt, wo das entsprechende
Symbol aufgerufen wird.
Da der Editor so gestaltet ist, daß Syntaxfehler verhindert werden, können Fehler nur noch im
Zusammenhang mit Symbolen auftreten: Entweder wird durch einen Befehl ein Symbol aufgerufen,
das nicht definiert wurde oder ein relativer Sprung ist so auf ein Label gerichtet, daß die maximale
Sprungweite von +127 oder -128 überschritten wird. Es gibt also keine Fehlermeldungen.
Wenn ein Fehler entdeckt wird, wird der Assemblerlauf abgebrochen und direkt in die
Eingabefunktion gesprungen (dies ist die einzige Funktion, die nicht immer ins Hauptprogramm
zurückkehrt). Der Arbeitszeiger ist jetzt auf die Zeile gerichtet, in der der Fehler entdeckt wurde,
man kann ihn also schnell beheben.
Wenn kein Fehler im Programm ist, wird der reine Maschinencode automatisch an der
Ablegeadresse (nicht Laufadresse) abgelegt und es erscheimt: „OK“. Anfänger im Programmieren
mit Assembler sollten sich nicht durch die Möglichkeit erschrecken lassen, ein Programm an eine
andere Stelle zu legen, als an die, wo das Programm laufen soll. Sie ist für Spezialfälle gedacht.
Im Zweifelsfall gilt immer: Laufadresse=Ablegeadresse.
Um zu zeigen, wie einfach diese Funktion benutzt werden kann ein Beispiel:
Basic-REM-Zeile mit der Zeilennummer 1 und vielen Blanks (oder irgendwelchen anderen
Zeichen) eingeben - Assembler wieder starten - Ablege- und Laufadresse auf 16384 richten.
Wenn man jetzt ein geschriebenes Programm assemblieren läßt, wird es in diese REM-Zeile gelegt
und ist dort lauffähig, kann also an der Adresse 16384 gestartet werden.
Diese Vorgehensweise ist für die meisten Fälle am sinnvollsten. Um bestimmte Programme zu
schreiben, kann es aber wünschenswert sein, Lauf- und Ablegeadresse zu trennen.
Ein Beispiel: Sie wollen ein Programm schreiben, das später oberhalb des RAMTOP laufen soll, wo
jetzt z.B. der Assembler steht. Das ist ganz einfach möglich, indem Sie das Programm für
irgendeinen anderen Speicherbereich im freien RAM schreiben. Und dort testen Sie das Programm
auch aus. Lauf- und Ablegeadresse haben während dieser Zeit den Wert des Test-Speicherbereichs.
Wenn das Programm fehlerfrei ist, geben Sie als Laufadresse die Anfangsadresse an, die Ihr
Programm haben soll, die Ablegeadresse bleibt unverändert. Dann laßen Sie noch einmal
assemblieren. Dadurch wird erreicht, daß das Programm jetzt an der ursprünglich beabsichtigten
Stelle arbeitsfähig ist. Dort wird es aber nicht hingelegt, sondern wieder an die Stelle, an der es
bisher getestet wurde. Es wird also nichts ungewollt überschrieben.
Es geht jetzt nur noch darum, diesen Maschinencode an seine Bestimmungsadresse zu bringen.
Dazu braucht man noch ein Verschiebeprogramm. Aber zuerst empfiehlt es sich, das Listing und
den Maschinencode abzuspeichern. B ist eine Spezialfunktion, die das Abspeichern von
Maschinencode erleichtert.
Wenn man erreichen möchte, daß ein Listing nur überprüft aber nicht abgelegt wird, legt man als
Ablegeadresse 0 fest, denn ins ROM kann bekanntlich nichts geschrieben werden. Vorsicht: es gibt
Hardware, die ein Schreiben in den ROM-Bereich erkennt und für Schaltvorgänge nutzt. Stichwort:
POKE-Karte!
Der Assembler läuft im Fast-Modus und kann mit „8“ angehalten werden.

B. M-CODE. REM-Zeilen haben für das Ablegen von Maschinencode einige Nachteile:
1. Man muß sie erst eintippen, was sehr mühselig sein kann.
2. Man muß immer darauf achten, daß die REM-Zeile mindestens so lang wie der Maschinencode
ist.
3. Je nach Maschinencode kann so etwas wie ein ungewollter „Listschutz“ entstehen, das Basic
zeigt dann einfach große Teile des Basic-Programms nicht mehr an.
4. Wenn REM-Zeilen mit Maschinencode sehr lang werden, hängt sich das Basic beim Listen sehr
oft auf.

Diese Nachteile können durch die Funktion B vermieden werden, wobei man allerdings darauf
verzichten muß, das Maschinenprogramm in eine Basic -Zeile zu schreiben.
Diese Funktion ersetzt das komplette Assemblerlisting durch den entsprechenden Maschinencode,
d.h. die Variable A$, die bisher das Assembler-Listing enthält, wird mit dem entsprechenden
Maschinencode überschrieben. Diese Variable wird außerdem zu B$. A$ existiert dann nicht mehr.
Das funktoniert auch dann, wenn das Listing so groß geworden ist, daß es den gesamten Speicher
belegt.
Wenn man ein Maschinenprogramm so ausgetestet hat, wie in Funktion A beschrieben, dann erzeugt
diese Funktion den direkt abspeicherbaren Maschinencode.
Dieser Maschinencode muß nach dem Laden natürlich jeweils an die Stelle geschoben werden, für
die er berechnet ist, deshalb empfiehlt es sich, an den Anfang eines Maschinenprogramms immer
folgendes kleine Verschiebeprogramm zu schreiben:

LD HL,($4010) Richtet HL auf Variable (B$).


INC HL
LD C,(HL) Lädt in BC die Länge dieser Variablen
INC HL
LD B,(HL)
LD DE,$0012 Richtet HL auf Programmbyte
ADD HL,DE
LD DE,LABEL Richtet DE auf Laufadresse
LDIR Verschiebt das Programm nach „LABEL“
RET Rückkehr ins Basic
LABEL.... Hier fängt das eigentliche Programm an.

Diese Verschiebefunktion läßt sich immer so aufrufen: RAND USR (PEEK 16400+256*PEEK
16401+3) und erspart eine zeitraubende PEEK- und POKE-Schleife. Dieses Programm funktioniert
aber nur, wenn B$ die erste Variable im Variablenteil des Basic ist. Das läßt sich dadurch erreichen,
daß man vor Neubeginn einer Programmeingabe erst CLEAR eingibt und dann ASDIS startet.
Bei der Verwendung von großen Frei-Zeilen ist zu beachten. daß sie möglichst nicht ganz am
Anfang des Listings stehen sollten, sonst könnte die Funktion 6 in Ausnahmesituationen zum
Absturz führen. Im Zweifelsfall kann das immer dadurch verhindert werden, daß man vor einer
Freizeile einen Kommentar einfügt, der so viele Zeichen enthält, wie durch die Frei-Zeile Bytes
freigehalten werden.
Zur Sicherheit wird diese Funktion nicht sofort ausgeführt, sondern zeigt zunächst ein „?“ und
erwartet ein „J“ zur Bestätigung, andernfalls Return ins Hauptprogramm. Nach der Ausführung
wird der Assembler automatisch verlassen.

C. RASS. (REASSEMBLER) Mit dem Reverse-Assembler (umgekehrter Assembler) kann man


Maschinencode, der irgendwo im Speicher steht, in ein Assemblerlisting umwandeln lassen. Man
gibt die Adresse des 1. umzuwandelnden Befehls und die Menge der Befehle (nicht Bytes) an.
Danach wird die entsprechende Zahl Befehle ins Listing aufgenommen. Alle vorkommenden 16-
Bit-Zahlen werden durch Symbole ersetzt und überprüft, ob ein Symbol mit diesem Wert schon
besteht. Wenn es nicht existiert, wird automatisch ein Label oder eine Marke erzeugt.
Der Reverse-Assembler dient dazu, vorhandene Programme entweder an anderer Stelle lauffähig zu
machen oder sie in ein eigenes aufzunehmen.
Datenbereiche werden von dieser Routine nicht erkannt. Der Reverse Assembler erzeugt also keine
Frei-, Daten- oder Text-Zeilen. Sollten solche Bereiche im Programm vorkommen, so muß man sie
anschließend von Hand korrigieren.

D. DISAS. Der Disassembler erwartet zunächst eine Anfangsadresse und zeigt dann 18 Befehle
disassembliert an. Die Anzeige ist 3teilig: links Befehlsadresse, Mitte vollständige Mnemonik und
rechts alle Codes aus denen der Befehl besteht.
Eine Ausnahme machen die relativen Sprünge, denn es nützt ja nicht viel, wenn man die Weite
eines Sprunges sieht, sondern man möchte sehen, wohin gesprungen wird, deshalb wird das
Sprungziel berechnet und angezeigt.
5: Die oberen 18 Zeilen werden fließend nach oben gescrollt und unten jeweils eine neue Zeile
sichtbar.
6: Die nächsten 18 Befehle werden disassembliert.
7: Wenn man beim Disassemblieren etwas zu weit vorgerückt ist, möchte man wieder zurück, ohne
eine neü Adresse einzutippen. Diese Funktion zieht einfach von der laufenden Adresse 70 ab und
disassembliert die folgenden 18 Befehle. Man hat so die Möglichkeit, Maschinenprogramme
bequem zu studieren.
8: Return ins Hauptprogramm.
9: Ausgabe an Drucker.

E. EINZL. Der Einzelschrittbetrieb führt sämtliche Z80-Befehle fast ohne Absturzgefahr aus. Dazu
unterscheidet das Programm intern zwei Befehlsarten:
1. Befehle die den Program Counter (PC) ändern, werden in einer Spezialroutine simuliert (JP, JR,
CALL, RET, usw.).
2. Alle anderen Anweisungen werden ausgeführt, nachdem ein Simulations-Stackpointer sowie alle
Registerinhalte neu geladen wurden. Nach der Ausführung werden die Registerinhalte wieder im
Speicher abgelegt. Der Simulationsstack ist anfangs auf $FF80 (bzw. $7F80 bei 6K RAM)
gerichtet, wo genügend Platz nach oben und unten ist, er kann aber auch an jede andere Stelle im
freien RAM gerichtet werden.

In dieser Funktion sind immer sämtliche Registerinhalte und Flags sichtbar. Bei den Flags bedeutet
„1“ Flag gesetzt und „0“ Flag gelöscht. Es wurden nur der Interrupt Vector (IV) und der Refresh
Counter (RC) weggelassen, weil sie beim Sinclair kaum benutzt werden können, ohne daß die
Hardware durcheinander gebracht wird.
Unterhalb des PC-Registers wird der 2. Registersatz des Z80 aufgelistet, auf den bekanntlich nur
durch die Befehle EXX und EX AF,AF zugegriffen werden kann.
Bevor der Einzelschrittbetrieb beginnt, kann man die Inhalte aller Register festlegen. Um ein
bestimmtes Register auszuwählen, bewegt man den Cursor mit den Tasten 6 und 7 auf und ab. Nach
5 oder Shift 8 (beliebig) kann das Register, neben dem der Cursor steht, verändert werden. Auch
hier können (wie immer) Symbole statt Zahlen eingegeben werden. (Wenn man z.B ein soeben
assembliertes und abgelegtes Programm ab Label soundso testen will.)
Der Inhalt des PC entscheidet darüber, an welcher Stelle der Einzelschrittbetrieb aufgenommen
wird. Sobald man die Registermanipulation (durch „8“ ) verläßt, wird der Befehl disassembliert, auf
den der PC gerichtet ist, aber zur Sicherheit noch nicht ausgeführt.
5: mit dieser Unterfunktion werden alle Befehle mit Ausnahme an CALL und RST Anweisungen im
Einzelschrittbetrieb ausgeführt. CALLs und RSTs werden echt ausgeführt. Diese Funktion hat ihren
Sinn im Testen rechenintensiver Programme, wo es aus Zeitgründen sinnlos wäre, sie im
Einzelschrittbetrieb zu testen.
Unterprogramme, die man schon getestet hat und die mit CALL (oder RST) aufgerufen werden,
kann man also auf einmal ausführen lassen, um schneller zur kritischen Stelle zu kommen, die man
eigentlich testen möchte. Man sollte natürlich vor der Benutzung dieser Taste sicher sein, daß
entsprechende Unterprogramme auch einwandfrei arbeiten.
6: Diese Taste bewirkt den eigentlichen Einzelschrittbetrieb. Sooft man diese Taste drückt, führt
man eine Einzelschritt-Simulation aus. Der Bildschirm wird gelöscht, der ausgeführte und der
nächste auszuführende Befehl werden disassembliert und die neuen Registerinhalte angezeigt.
7: Mit dieser Taste gibt man eine NOP-Anweisung, also die Anweisung den nächsten Befehl zu
überspringen statt auszuführen. Das hat immer dann einen Sinn, wenn man einen normalen
Programmablauf verlaßen möchte, wie er durch Sprünge, CALLs oder RETs erzwungen würde,
oder wenn eine Anweisung nicht ausgeführt werden soll, weil sie z.B. wichtige Speicher (wie Stack
oder System-Variablen) überschreiben würde. Andere Beispiele für nicht ausführbare Befehle sind
HALT, IM 0 und IM. 2.
8: Rückkehr ins Hauptprogramm.
9: Ausgabe an den Drucker.

F. RUN. Maschinenprogramme können sowohl aus dem Basic als auch dem Assembler aufgerufen
werden. Es ist selbstverständlich, daß jedes Maschinenprogramm irgendeine Rückkehranweisung,
also ein RET, enthalten muß. Bei Aufrufen aus dem Basic hat der Assembler keinerlei Einfluß auf
den Programmlauf, d.h. die Registerinhalte zum Programmstart sind unbekannt und Programme
können sowohl im Fast- als auch im Slow-Modus ausgeführt werden.
Der Programmstart aus dem Assembler bietet sich vor allem für das Austesten einzelner Routinen
an, wenn es darum geht, anfangs Registerinhalte festzulegen - wie im Einzelschrittbetrieb - oder zu
wissen, welche Registerinhalte der Prozessor nach Ende des Programmlaufs hat.
Zu Beginn der Funktion wird die Registereingabe gestartet. Der Inhalt des PC entscheidet über die
Startadresse. Die Registereingabe wird durch „8“ beendet, der erste ausführbare Befehl
disassembliert und die Startanweisung R (RUN) erwartet. -Wenn man stattdessen nochmals „8“
eingibt, erfolgt Rückkehr ins Hauptprogramm ohne Ausführung des Maschinencodes.
Sobald ein Maschinenprogramm aufgerufen ist, ist es für jedes Bit verantwortlich, mit dem es der
Prozessor jetzt zu tun bekommt. Weder ROM noch Assembler haben irgendeine Einflußmöglichkeit
bis zum RET. (Es empfiehlt sich also immer, rechtzeitig abzuspeichern).
Zur Programmausführung aus dem Assembler wird automatisch in den Fast-Modus umgeschalten
und der Bildschirm gelöscht. Der Fast-Modus hat den Vorteil, daß alle, auch die Index-Register und
der 2. Akku verwendet werden können (solange man keine Routinen im ROM aufruft, die diese
Register benötigen). Nach Beendigung des Maschinenprogramms werden sämtliche Registerinhalte
und Flags angezeigt, so wie sie vom ausgeführten Programm übergeben wurden

G. VGL. Mit der Vergleichsroutine kann man 2 Speicherblöcke auf Identität überprüfen. Es werden
2 Anfangsadressen erwartet und danach die Blöcke Byte für Byte verglichen, bis ein Unterschied
auftritt (bzw. der 1.Block die Adresse 0 erreicht). Bei einem Unterschied wird die entsprechende
Adresse der beiden Blöcke dezimal und hexadezimal angezeigt und auf einen Tastendruck als
Fortsetzungsanweisung oder Return („8“) gewartet
H. LAUF. Die bisherige Laufadresse wird angezeigt und kann geändert werden.

I. ABLEG. Die bisherige Ablegeadresse wird angezeigt und kann geändert werden. Diese beiden
Adressen brauchen nur einmal für jedes Programm festgelegt werden, wenn man es immer an
derselben Stelle laufen laßen möchte

J. DUMP. Die Speicherinhalte des ZX81 werden als Hex-Dump ausgelistet, indem man eine
Adresse eingibt und N/L drückt. Es werden auf 16 Zeilen 128 Bytes mit den Adressen angezeigt.
6: nächste 128 Bytes auslisten
7: vorhergehende 128 Bytes auslisten
8: Rückkehr ins Hauptprogramm
9: Ausgabe an Drucker

K. MARKN. Alle Marken werden einzeln angezeigt und können gelöscht oder deren Wert geändert
werden.
5: Markenwert ändern und nächste Marke anzeigen
6: keine Änderung und nächste Marke zeigen
7: Marke löschen
8: Rückkehr ins Hauptprogramm

Eingabefunktion
Die Eingabefunktion ist so weit ausgebaut, daß man sie als ein Programm im Programm ansehen
kann. Interaktiv ist sie, weil sie den Programmierer in folgenden Punkten unterstützt:
1. Sofortige Syntax-Prüfung, man kann also wie im Basic nur korrekte Zeilen eingeben.
2. Es ist immer eine Statusinformation sichtbar, die Hinweise darauf gibt, in welchem Zustand
das Programm sich befindet, bzw. welche Eingaben es erwartet.
3. Zeilennummern brauchen nicht eingegeben werden, die laufenden Adressen werden
automatisch berechnet und angezeigt.
4. An beliebiger Stelle kann man beliebig viele Zeilen einfügen oder löschen.
5. Den Arbeitszeiger kann man bequem auf jede Zeile richten.
Bildaufbau
Die Eingabefunktion hat einen speziellen Bildaufbau: der Bildschirm ist in 2 Teile aufgeteilt. Im
oberen Teil von 16 Zeilen ist immer ein Teil des Assemblerlistings sichtbar. Er ist waagerecht
wiederin 3 bis 4 Spalten gegliedert:
1. Die linken 4 Zeichen enthalten die jeweiligen Hex-Adressen der Zeilen.
2. Die nächsten 5 Zeichen rechts daneben sind der Symbolteil, hier werden eingegebene Labels
angezeigt.
3. Bei Sonderzeilen zeigen die restlichen 23 Zeichen den eingegebenen Code an.
4. Bei normalen Assemblerzeilen ist der Codeteil nur 15 Zeichen lang (das genügt für die
Darstellung sämtlicher Z80-Mnemoniks). Die letzten 8 Zeichen zeigen den Hex-Code an, der den
Mnemoniks entspricht.
In der 9. Zeile des oberen Teils sind die ersten 4 Zeichen immer invertiert dargestellt, um die
Adresse der Zeile hervorzuheben. auf die der Arbeitszeiger gerichtet ist.

Der untere Bildteil von 8 Zeilen enthält den Raum für die Statusinformation und die Eingabe von
Zeilen:
1. Das erste Zeichen der 17. Zeile enthält immer die Statusinformation - einen invertierten
Buchstaben.
2. Die nächsten 3 Zeichen sind ein Teil der Adresse, auf die der Arbeitszeiger gerichtet ist.
3. Die nächsten 5 Stellen sind der Symbolteil, in den man entweder ein Label schreibt oder die
Angaben für eine Unterfunktion macht.
4. Der Rest der unteren 8 Zeilen kann für die Eingabe von Zeilen genutzt werden. (Codeteil)

Verkürzte Darstellung
Sonderzeilen können also bis zu 8 Zeilen lang werden. Leider kann der ZX81 pro Bildzeile aber nur
32 Zeichen anzeigen. Um einen ungleichmäßigen Bildaufbau zu verhindern, der dadurch entstehen
würde, daß man auch Sonderzeilen die mehr als 32 Zeichen benötigen, in voller Länge anzeigt,
werden von allen Zeilen nur so viele Zeichen angezeigt, wie in einer Bildzeile Platz haben. Lange
Zeilen werden also verkürzt dargestellt. Aber das Programm vergißt die restlichen Eingaben nicht.
Man kann mit der Korrekturfunktion jede Zeile wieder in den unteren Bildteil holen, wo sie sichtbar
und veränderbar ist.
Statusinformationen
Die möglichen Statusinformationen sind:
B Befehlszeile eingeben
C Codeteil
D Datenzeile eingeben
F Freizeile eingeben
6 Grundzustand
K Kommentar eingeben
L Zeilen löschen
M Marke eingeben
R Arbeitszeiger rückwärts bewegen
S Symbolteil
T Textzeile eingeben
V Arbeitszeiger vorwärts bewegen
Z Arbeitszeiger auf bestimmte Zeile richten

Grundzustand der Eingabefunktion


Solange das invertierte „G" (Grundzustand) als Statusinformation sichtbar ist, hat man die Wahl,
entweder durch einfachen Tastendruck eine Unterfunktion der Eingabefunktion aufzurufen oder in
den Symbol- bzw. Codeteil zu verzweigen. Sobald eine Unterfunktion ausgeführt, eine Zeile
eingegeben oder wenn ein Fehler entdeckt wurde, kehrt das Programm automatisch wieder in diesen
Grundzustand zurück.
Nur wenn eine Zeile eingegeben wurde, wird der Eingabeteil gelöscht. Der obere (Listings-) Teil
wird durch Cursor-, Lösch- und Eingabefunktionen gesteürt Wenn ein Fehler entdeckt wurde, wird
das Bild überhaupt nicht geändert.

Symbolteil
Wenn im Grundzustand weder eine Ziffer noch ein Blank, „N/L“ oder Strichpunkt gedrückt werden,
erwartet das Programm eine Symboleingabe, was es durch die Statusinformation „S“ anzeigt.
Außerdem erscheint das eingegebene Zeichen. Die Symboleingabe muß mit N/L abgeschlossen
werden, worauf das Programm überprüft, ob das Symbol schon existiert und ob die Schreibweise
korrekt ist. Sollte das Symbol schon zuvor definiert oder falsch geschrieben worden sein (siehe
Symbole), dann kehrt das Programm in den Grundzustand zurück, andernfalls springt es in den
Codeteil.
Man muß aber nicht immer Eingaben im Symbolteil machen, sondern kann ihn überspringen, indem
man eine der 3 genannten Tasten drückt.
- „N/L“ hat die Wirkung, daß der Inhalt des Symbolteils überprüft wird.
- Bei einem Druck auf Blank wird der Inhalt des Symbolteils gelöscht.
- Der Strichpunkt ermöglicht die Eingabe einer Kommentarzeile.

Codeteil
Sobald der Codeteil erreicht ist, erscheint die Statusinformation „C“. Jetzt entscheidet der erste
Tastendruck darüber, ob man eine Befehlszeile, Marke oder einen Arbeitsspeicher eingibt.
Mit Blank oder „N/L“ kann man sofort wieder in den Grundzustand zurückkehren, mit dem
Unterschied, daß „N/L“ den Inhalt des Codeteils wie eine normale Befehlszeile betrachtet und
entsprechend reagiert, während ein Blank sonst nichts bewirkt.

Unterfunktionen der Eingabefunktion


Zum Grundzustand sind die Zifferntasten Funktionstasten.
0. Rubout. Die Zeile, auf die der Arbeitszeiger gerichtet ist, wird gelöscht.
1. Korrekturfunktion. Die Zeile, auf die der Arbeitszeiger gerichtet ist, wird im unteren Bildteil
angezeigt und im Listing gelöscht. Man kann sie jetzt ändern oder auch unverändert wieder
eingeben. Das Programm weiß aber nicht mehr, um was für eine Zeilenart es sich handelt. so
daß man z.B. eine Befehlszeile in einen Kommentar umwandeln kann und umgekehrt. Um
zu verhindern, daß durch die Autorepeatfunktion aus Versehen mehrere Zeilen gelöscht
werden, arbeitet die Korrekturfunktion nur, wenn das 1. Zeichen des Codeteils (in der 17.
Zeile) ein Blank ist.
2. Löschen. Wenn die Statusinformation „L“ sichtbar ist, kann man eine beliebige Anzahl
Assemblerzeilen ab der Zeile löschen, auf die der Arbeitszeiger gerichtet ist. Wenn man
keine gültige Zahl oder 0 eingibt, wird nichts gelöscht.
3. Die Statusinformation „Z“ erscheint und man kann den Arbeitszeiger auf eine beliebige
Zeile richten. indem man deren Adresse (Label) angibt.
4. Bei Druck auf diese Taste wird der Arbeitszeiger um eine bestimmte Anzahl Zeilen
vorgerückt. Bei Programmstart ist diese Zahl auf 16 eingestellt. Man kann sie aber beliebig
ändern, indem man Shift und 4 drückt. Es erscheint die Statusinformation „V“ und man
kann angeben, in welcher Schrittweite ab jetzt vor- und rückwärts gerückt werden soll.
5. Die Taste 5 entspricht in ihrer Funktion der Taste 4,nur daß eben rückwärts gegangen wird.
Die Statusinformation bei Shift 5 ist „R“.
6. Der Arbeitszeiger wird um 1 Zeile vorwärts gerückt.
7. Es wird um eine Zeile zurückgegangen.
8. Rückkehr ins Hauptprogramm.
9. Ausgabe an den Drucker und Ausführung der Funktion 4. (Die Schrittweite wird dazu auf 16
eingestellt.)

Kommentar
Gibt man im Grundzustand „;“ ein, verzweigt man damit in die Eingabe einer Kommentarzeile; was
man an der Statusinformation „K“ sieht. Kommentare sind selbständige Zeilen ohne Label, können
bis 250 Zeichen lang sein und invertierte Zeichen enthalten. Sobald man „N/L“ drückt, wird der
untere Bildschirmteil bis zum letzten „Nicht-Blank“ als Kommentar angesehen. Eine
Kommentarzeile kann also nicht mit einem Blank aufhören oder aus lauter Blanks bestehen.
Kommentarzeilen dienen der Übersichtlichkeit des Listings und haben weder Einfluß auf die
Zeilenadressen noch werden sie nach dem Assemblieren irgendwo abgelegt. Im Listing sind
Kommentare maximal bis zum 21. Zeichen sichtbar.

Befehlszeilen
Gibt man im Codeteil weder eine Ziffer noch ein Blank, Dollar-, Pfund-, Gleichheits- oder
Anführungszeichen ein, dann erwartet das Programm eine Befehlszeile, was es durch die
Statusinformation „B“ anzeigt. Außerdem wird das eingegebene Zeichen sichtbar.
Für die Eingabe der Mnemonik stehen die ersten 15 Zeichen hinter dem Symbolteil zur Verfügung.
Dieser Platz reicht für jeden Befehl aus, da Daten und Symbole heechstens 5stellig sein dürfen, alle
Eingaben linksbündig beginnen müßen und keine Rechenoperatoren erlaubt sind.
Die richtige Schreibweise der Befehle (wie sie aus der Zusammenfaßung der Z80-Befehle auf der
letzten Seite entnommen werden kann) muß eingehalten werden sonst wird die Zeile nicht
akzeptiert und das Programm kehrt nach N/L in den Grundzustand zurück.
Jeder Befehl der Z80-Mnemonik besteht aus 1 bis 3 Kürzeln. Das erste bezeichnet immer den
Befehl, die beiden anderen im allgemeinen Operatoren, mit denen gearbeitet wird. Hinter dem 1.
Kürzel muß auf jeden Fall ein Blank kommen. Wenn weitere Angaben erforderlich sind, muß hinter
der letzten ebenfalls ein Blank stehen. Bei Verwendung von 2 Zusätzen müßen diese durch Punkt
oder wahlweise Komma getrennt werden (beliebig).
Der Codeteil wird bei Befehlszeilen immer bis zum 2. Blank ab dem Symbolteil interpretiert.
Mnemonikteile, die eine Zahl darstellen, können immer durch Verwendung eines Symbols ersetzt
werden. Obwohl Symbole immer 16-Bit-Zahlen darstellen, können sie auch für Befehle mit 8-Bit-
Daten verwendet werden. Wenn z.B. das Symbol ZAHL den Wert $643F hat. dann wird der
Assemblerbefehl „LD B,ZAHL“ so assembliert, daß nur das Low-Byte (also hier $3F) eingesetzt
wird.
Bei 8-Bit-Index-Befehlen dürfen in der Klammer keine Symbole vorkommen. (Bsp.:LD
(IX+DIST),34 geht nicht, aber LD (IX+0),ZAHL)

Eine Ausnahme machen die relativen Sprünge. Wenn man ein Symbol angibt (z.B. JR NC,ENDE),
dann wird immer angenommen, daß es sich dabei um das Sprungziel handelt und die notwendige
Sprungweite wird berechnet. (Es wird also nicht - wie bei anderen 8-Bit-Daten - einfach die
niederwertige Hälfte des Symbols eingesetzt.) Ob die Sprungweite mit einem relativen Sprung
möglich ist, oder ob ein absoluter Sprung nötig ist, zeigt sich, wenn man assemblieren läßt.
Hat man einen Befehl richtig eingegeben und die Eingabe mit „N/L“ abgeschlossen, wird er sofort
übersetzt, und ins Listing eingefügt.
Die sofortige Befehlscodierung hat einige Vorteile:
- Syntaxfehler werden sofort erkannt.
- Der eigentliche Assemblerlauf braucht nur noch die Symbole überprüfen und ist daher recht
schnell (es handelt sich also genaugenommen um einen 3-Paß-Assembler),
- Fertig codierte Befehle belegen weniger Speicherplatz als die Mnemoniks (Bsp.: EX (SP),HL = 10
Bytes, E9 = 1 Byte)

Arbeitsspeicher
Die übrigen Sonderzeilen sind im wesentlichen Hilfsmittel um Arbeitsspeicher einzurichten. Da
auch Sonderzeilen Labels haben können, ist es möglich, sie ähnlich zu benutzen wie die Variablen
im Basic. Allerdings muß beim Assembler der Benutzer selbst die Länge der Variablen
kontrollieren.

Frei-Zeile
Wenn man als erstes Zeichen im Codeteil ein „$“ oder eine Ziffer eingibt, erscheint die
Statusinformation „F“ und das Programm erwartet eine Zahl von 1 bis 255. Diese Eingabe ist
vergleichbar mit dem Basic-Befehl DIM, mit dem Unterschied, daß beim DIM-Befehl der
entsprechende Speicherbereich mit Nullen angefüllt wird, während der Assembler nur einen
Speicherbereich freihält, ohne ihn zu verändern. Im Listing steht in der entsprechenden Zeile die
dezimale und hexadezimale Länge des eingerichteten Arbeitsspeichers. Beim Assembler sind
Arbeitsspeicher nicht an einen bestimmten Datentyp (Text oder Zahlen) gebunden, es liegt im
Ermeßen des Programmierers, wie die Speicher benutzt werden.
Im folgenden Anwendungsbeispiel werden so viele Bytes wie VAR2 angibt, von der Stelle, die
VAR1 angibt, in den Arbeitsspeicher VAR3 geschoben. Nach der Ausführung läßt sich das Ergebnis
mit der Dump- oder Disassembler-Funktion ab „VAR3“ betrachten.
5000LABEL LD HL, (VAR1) 2ADF50
5003 LD DE,VAR3 111250
5006 LD A,(VAR2) 3A1150
5009 LD C,A 4F
500A LD B,0 0600
500C LDIR EDB0
500E RET C9
500FVAR1002=$02 (2-Byte-Variable)
5001VAR2001=$01 (1-Byte-Variable)
5012VAR3255=$FF (255-Byte-Arbeitsspeicher)

Daten Zeile
Es ist aber auch möglich, einen Arbeitsspeicher zu definieren und gleichzeitig festzulegen, was
drinstehen soll, indem man entweder das Pfund- (Daten) oder das Anführungszeichen (Text) drückt
Diese Zeilen entsprechen dann den Basic-Statements LET X=... und LET X$= „...“
Nach dem Pfundzeichen erscheint die Statusinformation „D“ (Datenzeile) und es kann eine Zeile
mit bis zu 246 Hexzeichen („0“...„F“) eingegeben werden (also 123 Bytes), die keinerlei
Sonderzeichen wie Blanks oder „$“ enthalten darf. Die Zeile wird nicht akzeptiert, wenn man
andere Zeichen oder eine ungerade Anzahl von Zeichen eingibt
Diese Zeilenart kann man nicht nur als Variablendefinition, sondern auch als Pseudo-Hexmonitor
benutzen, wenn man z.B. einen bestimmten Maschinencode eintippen und an eine bestimmte Stelle
legen möchte. Es ist ja möglich, beliebig viele Datenzeilen aneinander zu hängen und mit der
Ablegeadresse zu entscheiden, wo dieser Code dann hingelegt werden soll. Im Listing sind von
solchen Zeilen jeweils max. 10 Bytes sichtbar.

Text-Zeile
Nach dem Anführungszeichen erscheint die Statusinformation „T“ und man kann eine 246 Zeichen
lange Zeile eingeben, wobei alle Zeichen erlaubt sind, die über die Tastatur erreichbar sind. Wie bei
Kommentaren wird die Zeile bis zum letzten Nicht-Blank als gültig angesehen. Im Listing sind von
Textzeilen max. 21 Zeichen zu sehen.
Folgendes Programm, das eine Text- und eine Datenzeile verwendet, löscht zürst den Bildschirm
(durch Aufruf der CLS-Routine, deren Adresse man mittels einer Marke definieren muß) und
schreibt (mit Hilfe des RST 10) den Text, der im Arbeitsspeicher VAR2 steht auf den Bildschirm, in
der Länge, die in VAR1 angegeben ist.
5000LABEL CALL CLS CD2A0A
5003 LD HL,VAR2 211250
5006 LD BC,(VAR1) ED4B1050
500ALOOP LD A,(HL) 7E
500B RST 10 D7
500C INC HL 23
500D DJNZ LOOP 10FB
500F RET C9
5010VAR1 0012 (Datenzeile)
5012VAR2 DIES IST EIN TEXT. (Textzeile )
5024; KOMMENTAR

Rufen Sie dieses Programm aus dem Basic auf.

Marken
Ein Gleichheitszeichen zu Beginn des Codeteils ermöglicht die Definition einer Marke. Dazu muß
natürlich im Symbolteil eine Eingabe gemacht worden sein. Es erscheint die Statusinformation „M“
und eine Zahl wird erwartet. Wenn man eine Zahl eingibt, ist damit eine Marke definiert, die sich
z.B. als Konstante oder externes Label (wie im obigen Beispiel CLS) benutzen läßt.
Ändern und löschen kann man Marken im Hauptprogramm mit der Funktion K.

Programmentwicklung
Der normale Ablauf einer Programmentwicklung mit ASDIS sieht ungefähr so aus:
1. Laden, lnitialisieren und Starten von ASDIS.
2. Lauf- und Ablegeadresse einstellen.
3. Eingabe des Programms mit der Eingabefunktion.
4. Abspeichern des Listings.
5. Assemblieren lassen.
6. Testlauf aus Basic und/oder ASDIS.
7. Fehlersuche: eventuell Neuladen des Listings (bei Kassettenversion zuerst ASDIS),
assemblieren, Einzelschrittbetrieb.
8. Wiederholung 3. bis 7. bis zur Programmreife, die dann gegeben ist, wenn das Programm
unabhängig von ASDIS läuft.
9. Eventuell Laufadresse neu festlegen.
10.Erzeugung des abspeicherbaren Maschinencodes.
Die Möglichkeiten, die ASDIS Ihnen bietet, sind umfangreicher, als sie hier im Detail beschrieben
werden können. Deshalb muß es Ihrer Phantasie überlassen bleiben, für ihre Zwecke das Beste
daraus zu machen. Auf jeden Fall besitzen Sie mit diesem Programm einen- Assembler, der sich mit
Kollegen größerer Rechner vergleichen kann, ohne rot werden zu müssen. Und die Geschwindigkeit
von Assemblerprogrammen spricht für sich. Das Verhältnis Assembler zu ZX8I-Basic-lnterpreter ist
ca 1:1000 und das kann selbst vom besten Compiler nicht erreicht werden. Machen sie den
Geschwindigkeitsvergleich:
10 FOR I=1 TO 1000 Während es kein Problem ist, schneller zu zählen, als dieses
20 PRINT AT 0,13;I Basic-Programm, werden Sie beim folgenden
30 NEXTI Assemblerprogramm kaum mit den Tausendern mithalten können.

WDHLG CALL ZAEHL Zählt um 1 hoch.


CALL HALT Fragt die Break-Taste ab
JR NZ,WDHLG Wiederholung wenn nicht gedrückt
RET Programmende
ZAEHL LD HL,(DFILE) Richtet HL auf Anfang Bildspeicher.
LD DE,POSIT
ADD HL,DE Richtet HL auf kleinste Ziffer.
ZIFER LD A,(HL) Holt Ziffer in Akku
CP NEUN Kleiner als „9“?
JR C, ENDE Wenn ja, dann letzte Ziffer
LD (HL),NULL Andernfalls „0“ und nächstgrößere.
DEC HL Ziffer hochzählen
JR ZIFER
ENDE INC (HL) Ziffer vergrößern.
CP NULL War sie < „0“ ?
RET NC Return wenn nein.
LD (HL), EINS Andernfalls Ziffer= „1“.
RET
HALT LD A REIHE Tastenreihe in der Break liegt.
IN A,P0RT Break-Taste abfragen
BIT 0,A
Zuvor müsen noch folgende Marken definiert werden
DFILE 400C (Siehe Handbuch Systemvariablen)
POSIT beliebig (z.B.13)
NULL 28 (Sinclaircode für „0“)
EINS 29 (Sinclaircode für „1“)
NEUN 37 (Sinclaircode für „9“)
REIHE $7F andere Werte fragen andere Tastengruppen ab
PORT $FE (Tastatur-Port)
Überblick über alle Programmfunktionen

(Mit den Tasten, durch welche sich die Funktionen aufrufen lassen.)
Hauptprogramm
1. Eingabefunktion
im Grundzustand:
0. Zeile beschen
1. Zeilenkorrektur
2. mehrere Zeilen löschen
3. Cursor auf eine bestimmte Zeile richten
4. Zeiger vorwärts
Shift 4. Zeiger vorwärts mit Zeilenangabe
5. Zeiger rückwärts
Shift 5. Zeiger rückwärts mit Zeilenangabe
6. Cursor eine Zeile vorwärts
7. Cursor eine Zeile rückwärts
8. Rückkehr ins Hauptprogramm
9. Ausdrucken Kommentar
N/L oder Blank: Codeeingabe ohne Symboleingabe
alles andere: Symboleingabe und anschließend Codeeingabe im Codeteil:
Blank : Rückkehr in Grundzustand Eingabe der Zeile
N/L : Eingabe der Zeile
= : Marke definieren
„ : Textzeile
Pfundzeichen : Datenzeile
Dollar oder Ziffer: Freizeile
alles andere : Befehlszeile
2. Dezimale und hexadezimale Darstellung einer Zahl oder eines Symbols.
3. Daten verschieben
4. Daten suchen
5. Inhaltsangabe
6. Symboländerung
7. Symbollisting
Shift 7. Symbollisting mit vorherigem Sortieren
8. Rückkehr ins Basic
9. Ausgabe des Bildschirminhalts an den Drucker
A. Assembler
B. Assemblerlisting in Maschinencode umwandeln
C. Reverse-Assembler
D. Disassembler
5. vorwärts
6. 8 Zeilen vorwärts
7. 70 Bytes rückwärts
8. Rückkehr ins Hauptprogramm
9. Ausdruck
E. Einzelschrittbetrieb

Registermanipulation
5. (oder Shift 8) Register ändern
6. Cursor hoch
7. Cursor runter
8. Ende der Registermanipulation
5. mit echten Calls
6. normal
7. NOPs
8. Rückkehr ins Hauptprogramm
9. Ausdruck
F. Start eines Maschinenprogramms
8. Rückkehr ins Hauotprogramm
R. Start des Maschinenprogramms
G. Blockvergleich
H. Laufadresse
I. Ablegeadresse
J. Dump
6. vorwärts
7. rückwärts
8. Rückkehr ins Hauptprogramn
9. Ausdruck
K. Markenänderung
5. Änderung
6. weiter ohne Änderung
7. Marke löschen
8. Rückkehr ins Hauptprogramm
ASDIS für Anfänger

Diesen Artikel wollte ich eigentlich auf dem Treffen als Vortrag halten, aber irgendwie waren wir da
alle zu sehr beschäftigt. Also, ähem, räusper, ich bitte um Gehör!
Kurz und knapp: ASDIS ist ein Assembler/Disassembler und wurde von Horst Kling (Franke HRG!)
geschrieben/vertrieben. Da er uns leider keine internen Unterlagen zum ASDIS zur Verfügung
stellen konnte, liegt wohl der Verdacht nahe, daß ASDIS von einem anderen System auf den ZX81
portiert wurde. Wenn dem auch so sei, ASDIS ist wirklich gut und deckt 99% aller erdenklichen
Anwendungsfälle ab. Für ASDIS gibt es eine Anleitung, die ich jedoch nicht im Magazin bringen
möchte. Wer sie braucht: gibt es bei mir gegen Rückporto!
Wozu braucht man sowas wie ASDIS? Ein Assembler ist ein Tool, Werkzeug, das
Maschinenprogramme bzw. einen „Quelltext“ in lauffähigen Code übersetzt. Mit
Maschinenprogramm sind die Mnemonics gemeint, dieses ominöse LD A,(HL) und sowas. Code ist
das, was dann im Speicher (RAM/ROM/EPROM) abgelegt wird und direkt von der CPU gefressen
werden kann. Wer sich schon an Willis „Maschinensprachekurs für Anfänger“ versucht hat, kennt
die lästige POKErei in irgendwelche REM-Zeilen. Genau diese Arbeit nimmt uns ASDIS ab, und er
kann freilich noch eine ganze Menge mehr.
Ein Disassembler geht genau den umgekehrten Weg und bastelt aus Zahlenfolgen im Speicher
wieder einen verständlichen Quelltext.
ASDIS selbst kann recht umständlich von Kassette geladen werden. Viel eleganter ist aber ein
ASDIS in einem EPROM. Wir brauchen dazu nur ein EPROM im Bereich 8-16k, ASDIS selbst
belegt etwas mehr als 7kB.
Wie bringe ich dieses EPROM mit dem ZX81 zusammen? Wer den ZX96 oder den Giant hat,
steckt das EPROM einfach dort auf bzw. brennt ASDIS mit hinein. Nur-Floppycontroller-Besitzer
können sich eventuell mit einer Huckepacklösung auf dem FDC behelfen. Schließlich kann man
auch einen Adapter stricken und das ASDIS-EPROM einfach hinten anstecken (Henning kennt
das!). Ich glaube, Bauanleitungen für solche Adapter hatten wir schon. Wer Hilfe braucht, kann
sich aber gerne an mich wenden!
Letztlich ist dann aber alles das gleiche: man startet ASDIS einfach durch RAND USR 8192.
Für einen ersten Versuch nehmen wir gleich mal das Beispiel aus Willis Anfängerkurs (bitte
suchen, denn damit wird alles verständlicher!). Als erstes brauchen wir wieder die REM-Zeile, die
geben wir vorerst noch zu Fuß ein: 1 REM 00000000. Ruhig ein paar Nullen mehr, zuviel macht
hier gar nix! Damit haben wir einen Platz geschaffen, an dem der fertige Code dann abgelegt
werden kann und von wo er sich auch einfach SAVEn läßt. Die erste Null ist unsere „Startadresse“,
bei der ersten REM-Zeile ist diese immer 16514.
Haben wir die REM-Zeile fertig, rufen wir ASDIS mit RAND USR 8192 auf. Die unteren Zeilen des
Bildschirmes sind jetzt das Hauptmenü, von dem wir uns erstmal nicht verwirren lassen. Zuerst
teilen wir ASDIS mit, wo er denn bitte den fertigen Code ablegen soll. Dazu gibt es die Funktion I
(ablegen). Also einmal I drücken, 16514 eingeben und N/L. Dann können wir als nächstes schon
den Eingabeeditor starten und unser Programm eintippen: einfach auf 1 drücken. Das Menü klappt
weg und wir gucken auf die Eingabezeile. Das inverse G signalisiert „Grundzustand“ - alles ok. Wir
drücken einmal N/L, der Cursor springt nach rechts. Jetzt sind wir im Mnemonicteil der
Eingabezeile und dürfen schon unser erstes LD A,85 (Leerzeichen nach LD beachten!) einhacken,
fertig und N/L. ASDIS checkt die Zeile sofort auf richtige Syntax durch und -war alles korrekt- zeigt
die Zeile oben an.
Genauso geht es nun weiter: N/L-Mnemonicteil, LD (49185),A-N/L. N/L-RET-N/L. Damit ist das
Programm schon drin, wir verlassen den Editor mit der Taste 8 und landen wieder im Hauptmenü.
Um das Programm jetzt zu assemblieren (=übersetzen), brauchen wir nur einmal kurz auf A zu
drücken. ASDIS meldet sofort ein OK über dem Menü - solang war unser Programm ja nicht, das
geht fix.
Das war es schon, unser Programm ist fertig und steht als lauffähiger Code in der REM-Zeile.
Glaubt Ihr nicht, ging ZU schnell? Dann verlassen wir ASDIS mit der 8 und gucken auf die REM-
Zeile: da steht was anderes drin als vorher! Zum Testen brauchen wir jetzt natürlich noch das
Spar-Interface, sonst sieht man ja nix. Nach RAND USR 16514 leuchten die 4 LEDs, unser
Programm spielt!
Ein weiteres wichtiges Element sind die Labels. Dazu kramen wir den Teil 3 von Willis Kurs hervor.
Dort ist eine Schleife als „Bremse“ enthalten. Sinn und Wesen einer Schleife sind Rücksprünge.
Wer schonmal Maschinenprogramme von Hand assembliert hat, kennt die Rückwärtszählerei zum
Bestimmen der Sprungweite. Mit ASDIS geht das sehr einfach: man setzt einfach dort, wo der
Sprung landen soll, ein Label. Im Sprungbefehl wird dann einfach das Label angegeben und
ASDIS rechnet sich das dann selbst aus. Wieder schön Schritt für Schritt. Wir gehen mit 1 ins
Listing. Mit den Cursortasten auf die Zeile nach LD (49185),A - denn davor wollen wir die Bremse
einbauen. Jetzt geben wir zunächst die Zeile LD DE,$FFFF ein. Das $-Zeichen bedeutet „hex“,
ASDIS kennt ja beide Schreibweisen. Die nächste Zeile, das DEC DE, ist das Sprungziel. Hier
geben wir als allererstes(!) das Label ein, meinetwegen ZIEL (wichtig: max. 5 Zeichen), dann
landen wir mit N/L im Mnemonicteil und tippen noch DEC DE ein. Schließlich die nächsten Zeilen
wie gehabt, und bei JPNZ geben wir ein: JP NZ,ZIEL. Das Leerzeichen zwischen JP und NZ ist
wichtig, sonst meckert ASDIS! Das war es dann auch schon. Sehen wir uns das Listing nach dem
Assemblieren nochmal an, dann steht die korrekte Adresse des Rücksprunges drin. Dasselbe
funktioniert auch mit Relativsprüngen, man muß nur auf die maximale Sprungweite von 127
achten.

Damit könnt Ihr nun schon einige kleine Listings abtippen. Im zweiten Teil geht es dann um die
Marken, Kommentare und Tabellen. Viel Spaß!
ASDIS für Anfänger - 2.Teil

Das Thema „lange REM-Zeile" berührt eigentlich jeden, der in Maschinensprache am ZX81
programmiert. Zum Ablegen eines Maschinenprogrammes gibt es bekanntlich mehrere
Möglichkeiten: a) REM-Zeile, b) unterhalb RAMTOP, c) irgendwo anders (im RAM).
Die Lage in einer REM-Zeile hat den Vorteil, daß das Programm problemlos über SAVE mit
abgespeichert werden kann (besonders früher: auf Kassette!). Diese Prozedur stellt einen aber
immer vor die Mühe, eine der Programmlänge entsprechend lange oder längere REM-Zeile
anzulegen. Dafür gibt es nun mehrere Routinen, wobei ich als Ergänzung zu Georgs Artikel einmal
exemplarisch eine weitere vorstellen möchte. Es soll ja auch um die Kommentare und die Marken
in ASDIS gehen...

Das Programm steht selbst in der ersten REM-


Zeile und bewirkt eine Verlängerung derselben
um den Wert, der mit RAND übergeben wird. Der
Aufruf lautet daher z.B. RAND 1000 und dann
RAND USR 16514. Wichtig ist noch, daß der
Cursor in einer 2. REM-Zeile stehen muß!
Aus dem ersten Teil wissen wir bereits die
nötigen Schritte bis hierher: REM-Zeile mit 61
Nullen anlegen, ASDIS für Ablegeadresse („I“)
auf 16514 einstellen.
Eine neue Funktion ist nun die Laufadresse.
Diese braucht ASDIS, um auch Absolutsprünge
und CALLs richtig zu berechnen. Für die meisten
Fälle ist Ablegeadresse=Laufadresse. Wir gehen
deshalb im Menü auf „H“ und geben ebenfalls
16514 ein.
Dann nix wie hinein in den Editor! Die erste Zeile
enthält bereits eine Marke: „FAST“. Marken sind
wie Variablennamen und sollen die Lesbarkeit
des Listings erleichtern. Unter FAST kann sich
schließlich jeder etwas vorstellen!

Marken dürfen wie Labels nicht länger als 5 Zeichen sein. Zur Eingabe tippen wir die Zeile
genauso ein: CALL FAST - fertig. Nach N/L steht aber dahinter nur CD0000, da ASDIS den Wert
von FAST noch nicht kennt. Das geht nun wie folgt: FAST nochmal wie ein Label in der ersten
Editorspalte entippen, N/L, und dann „=". Der Cursor wechselt auf ein m („Marke") und wir können
jetzt den Wert eingeben. Wie gehabt in dezimaler Schreibweise oder in hex mit vorangestelltem $.
Die zweite Zeile tippen wir ebenso ein wie sie dasteht und definieren nachher EPPC mit $400A. Es
geht noch anders: man darf auch erst das gesamte Listing einhacken und alle Marken
abschließend definieren! Wurde eine Marke vergessen, moniert das ASDIS beim assemblieren
und springt sofort in den Editor auf die Zeile mit der unbekannten Marke.
Kommentare sind relativ einfach: in der ersten Editorspalte ein Semikolon eintippen und ASDIS

signalisiert mt einem k, daß er dann einen Kommentar erwartet. Als Kommentar ist jedes Zeichen
zulässig.
Eine weitere Funktion brauchen wir für obiges Programm noch: die Datenfelder oder Tabellen. Ein
Beispielprogramm für Tabellen denke ich mir für den 3.Teil aus, hier nur kurz zur Eingabe. Auf den
Adressen $4095 und $40BD stehen Datenfelder, diese haben hier allerdings nur eine Länge von 1
Byte. Um Datenfelder einzugeben, wechselt man mit Shift+Leertaste in den Datenmodus -ASDIS

zeigt ein d- und tippt dann die Werte einfach ein. Weil es sich hier um reine Bytes handelt, muß
folglich eine gerade Anzahl Zeichen eingegeben werden, sonst meckert ASDIS. Desweiteren sind
nur die Zeichen 0...9 und A...F zulässig, alles andere ergibt ja keinen gültigen Hex-Wert. Das „$“
vor den Hex-Werten ist in Datenfeldern nicht mehr erforderlich!
Daten- wie Kommentarzeilen dürfen zwar max. 255 Bytes lang sein, sollten aber besser auf
Bildschirmbreite begrenzt werden.
Zum Löschen von Zeilen im Editor drückt man einfach auf die „0“. Die Zeile, in der der Cursor
steht, wird damit gelöscht.
Zum Ändern einer Zeile drückt man im Editor einfach nur auf die „1“. Leider merkt sich ASDIS nicht
die Funktion der Zeile. Das bedeutet, daß man zunächst z.B. das Semikolon bei Kommentarzeilen
noch einmal drücken muß, bzw. Shift+Leertaste bei Tabellen.
Mitunter etwas bockig wird ASDIS wenn man versucht, ein bereits schon vorhandenes Label (z.B.
von einem Sprung) noch einmal zu vergeben. Die Zeile wird dann einfach nicht akzeptiert. Das
passiert mitunter auch, wenn man eine Zeile mit Label nachträglich editiert hat und dann wieder
N/L drückt. ASDIS meint dann, daß das Label doppelt vergeben werden soll und nimmt das
vermeintlich doppelte Label nicht an. Hier hilft nur, die Zeile zunächst ohne Label abzuspeichern,
dann noch einmal zu editieren und das Label neu einzutragen.
Damit haben wir nun alle Funktionen komplett, um jede Art von Listings mit ASDIS einhacken zu
können. Neben dem Beispielprogramm für größere Tabellen im 3.Teil werde ich dann noch auf die
restlichen Funktionen von ASDIS eingehen und ein paar Tips zum effizienten Programmieren mit
ASDIS geben.
Kai Fischer email: kai@zx81.de
ASDIS intern

ASDIS ist ein (DER!) Assembler/Disassembler für den ZX81. Wir haben nix besseres, und wenn man viel
mit ASDIS arbeitet, kommt man oft an dessen Grenzen. Zum einen wird bei langen Listings der Speicher
knapp, daher sollte man schon sehr sparsam mit Labels und Marken umgehen. Das Drucken von langen
Listings wird ebenfalls zur Qual, da ASDIS immer nur eine Seite druckt. Und könnte man dann auch noch
mit Makros arbeiten...
Leider fehlen uns für das Programm selbst Unterlagen, wie ASDIS intern arbeitet. Aus diesem Grund habe
ich einen Anfang gemacht, und das Gedächtnis von ASDIS analysiert: die Variable A$, in der der gesamte
Quelltext gespeichert wird. Mit diesen Erkenntnissen sollten schon einige Arbeitserleichterungen machbar
sein, dazu abschließend.

Die Variable A$ wird von ASDIS dynamisch verwaltet, d.h. ihre Länge ist veränderlich. Der
Speicherknappheit kann man leicht Abhilfe schaffen, indem man RAMTOP einfach auf 65535 hochsetzt
(durchgängig RAM vorausgesetzt). Lange Listings sind dann kein Problem mehr, sofern man sie auf einen
Datenträger auch sichern kann.
In A$ steht nun alles drin, was ASDIS an Informationen zum Quelltext braucht. ASDIS hat zwar auch noch
ein paar Systemvariablen, aber die brauchen uns vorerst noch nicht zu interessieren.
Der Aufbau von A$ ist nun recht einfach. Zu Anfang steht ein Header mit folgendem Inhalt:

Position 1/2 3/4 5/6 7/8

Inhalt Anzahl d. Marken Anzahl d. Labels Ablegeadresse Laufadresse

Zum Nachmachen: PRINT (CODE A$(5)-28)+256*(CODE A$(6)-28) zeigt uns ganz einfach die
Ablegeadresse des Programmes an. Die Einträge sind also allesamt 16bit-Zahlen im gewohnten Format. Als
nächstes folgt eine Tabelle mit allen Marken im Klartext und ihren Adressen. Jede Marke belegt damit 7
Bytes (5 Bytes Name, 2 Bytes Adresse) im Header. Ein simples PRINT A$ läßt diese Einträge schon sichtbar
werden, da die Codierung im ZX-Format erfolgt. Nach den Marken folgt im selben Muster die Tabelle mit
allen Labels.
ASDIS speichert Marken und Labels nur einmal als Klartext im Header. Im Quelltext wird dann nur noch die
relative Position im Header, bezogen auf den Anfang der jeweiligen Tabelle, eingetragen. Jedes Label und
jede Marke hat also seine Nummer, bei „0“ beginnend. Ist aber der Opcode eines Mnemonics ein Label oder
eine Marke, steht diese auch im Klartext in der jeweiligen Zeile.
Nach dem Header folgt nun der eigentliche Quelltext, wobei jede Zeile ebenfalls im Klartext abgelegt wird.
Der Zeilenaufbau ist sehr unterschiedlich, aber einfach zu lesen:
Position 1 2 3/4 >5

Inhalt Code Zeilenlänge Labelnummer Zeileninhalt

Eine Labelnummer wird nur eingetragen, wenn ein Label vorhanden ist, logisch. Wenn nicht, entfällt der
Eintrag und nach der Zeilenlänge schließt sich sofort der Zeileninhalt an. Eine Zeilenendekennung wie im
ZX (119=“Newline“) gibt es nicht, ASDIS muß also über die Zeilenlängen die nächste Anfangsadresse
berechnen. Als Zeilenlänge wird immer nur die Länge des eigentlichen Codes eingetragen!
Am ersten Byte („Code“) erkennt ASDIS, um welche Art einer Zeile es sich im folgenden handelt. Jede Zeile
hat entsprechend ihrem Inhalt einen speziellen, eigenen Aufbau, der nachfolgend für alle möglichen Fälle
dargestellt wird. Die Beispiele werden so geschrieben, wie sie auch ASDIS selbst anzeigt.

eine einfache Mnemoniczeile ohne Labels/Marken


Länge (Bytes) 1 1 n

Eintrag (dez. / hex.) 24 / $18 Zeilenlänge (n) Code

Bsp.: LD A,B sieht so aus: 24 - 1 - 120

eine einfache Mnemoniczeile mit Label


Länge 1 1 2 n

Eintrag 152 / $98 Zeilenlänge (n) Position d. Labels Code

Bsp.: LABEL LD A,B sieht so aus: 152 - 1 - 0 - 0 - 120 (wenn erstes Label im Header)

eine Kommentarzeile:
Länge 1 1 n

Eintrag 52 / $34 Zeilenlänge (n) ZX-Klartext

Bsp.: ;ANFANG sieht so aus: 52 - 6 - 38 - 51 - 43 - 38 - 51 - 44

ein Freiraum (Platzhalter)


Länge 1 1

Eintrag 40 / $28 n (Größe des Freiraumes)

Damit ist klar, warum man nur maximal 256 Bytes Freiraum in einer Zeile angeben kann!
eine Datenzeile (Tabelle):
Länge 1 1 n

Eintrag 56 / $38 Zeilenlänge (n) Tabelleninhalt

eine Textzeile:
Länge 1 1 n

Eintrag 60 / $3C Zeilenlänge (n) ZX-Klartext

ein Freiraum mit Label (Platzhalter):


Länge 1 1 2 n

Eintrag 168 / $A8 Zeilenlänge (n) Position d. Labels Tabelleninhalt

eine Datenzeile mit Label:


Länge 1 1 2 n

Eintrag 184 / $B8 Zeilenlänge (n) Position d. Labels Tabelleninhalt

der Operand ist ein Label:


Länge 1 1 5 n 2

Eintrag 88 / $58 Zeilenlänge (n) Labelname im Opcode Adresse


Klartext (assembliert)

Bsp.: LD A,(LABEL) : 88 - 3 - 49 - 38 - 39 - 42 - 49 - 58 - (2 Bytes Adresse)

der Operand ist eine Marke:


Länge 1 1 2 5 n 2

Eintrag 216 / $D8 Zeilenlänge Position d. Name der Marke im Opcode Adresse
(n) Marke Klartext (assembliert)

Bsp.: LD HL,(VARS) : 216 - 3 - 0 - 0 - 59 - 38 - 55 - 56 - 0 - 42 - 16 - 64


eine Textzeile mit Label:
Länge 1 1 2 n

Eintrag 188 / $BC Zeilenlänge (n) Position d. Labels Klartext

Es wird klar, daß bestimmte Konstruktionen viel Platz fressen, diese machen aber gerade den Vorteil eines
Assemblers aus. Hier stehen sich also wieder einmal Komfort und Speicherbedarf gegenüber.

Als erste Übung habe ich mir einen Kommentarkiller geschrieben. In einem Rutsch entfernt dieser alle
Kommentarzeilen aus einem Listing und schafft wieder etwas Platz. Ob’s sinnvoll ist, wenn keine
Kommentare mehr drin stehen? Es läßt sich ja erweitern, indem man entbehrliche Kommentare invers
schreibt und nur noch diese entfernt würden.
Die nächste Anwendung wird eine Druckroutine sein, die das Listing übersichtlich formatiert. Später will ich
dann zur Makroverwaltung kommen, mit der definierte Blöcke gelöscht, verschoben, kopiert oder eingefügt
werden können. Die Routinen zur A$-Behandlung habe ich bereits fertig.

Kai Fischer, email: kai@zx81.de