ExAss
Inhaltsverzeichnis
ExAss (extended Assembler)
Das Modul ExAss ist ein Werkzeug für den C64. Das Tool unterstützt die Software Entwicklung am C64 in 6502 Assembler Code. Man kann ExAss an die Adresse $8000 laden oder auch als Modul auf ein EPROM schreiben, als 8KB Modul oder als CRT (Vice Cartridge).
ExAss besteht aus zwei Teilen:
- einem 2 Pass Assembler
- einer Befehlserweiterung
- ExAss-02.png
- ExAss-03.png
- ExAss-06.png
Zwei Pass Assembler
Ein Assembler unterstützt den Benutzer bei der Entwicklung und Eingabe von Maschinen Code (6502 Memnonik). Im einfachsten Fall übersetzt ein Assembler die eingegebene Code Zeile direkt um und speichert den Code. Wie es bei allen gängigen Monitor Programmen der Fall ist.
Fortgeschrittene Assembler übersetzen ein ganzes Programm auf einmal. Dabei wird der Assembler Quelltext gelesen und in Maschinen Code übersetzt. Man verwendet Sprungmarken und Symbole (Variable) statt direkter Adressen. Dadurch wird der Quelltext besser lesbar und der Maschinencode kann für jeden Adressraum übersetzt werden.
Zwei Pass Assembler lesen den Quelltext zweimal (Pass 1 und Pass 2). Beim ersten Lauf (Pass 1) werden alle Sprungmarken und Symbole aufgelöst. Dabei baut sich der Assembler intern eine Tabelle aller verwendeten Adressen auf. Im zweiten Lauf sind dann alle Adressen bekannt und der Maschinen Code wird erzeugt.
Bei 2 Pass Assembler gibt es mehrere Ansätze:
- der Quellcode wird beim übersetzen von Floppy Disk geladen
- der Quellcode befindet sich im RAM des Computer
- das übersetzte Maschinen Programm wird auf Floppy Disk gespeichert
- das übersetzte Maschinen Programm wird direkt im Speicher abgelegt
Angesichts der relativ langsamen Floppy Laufwerke beim C64, aber auch wegen des umständlicheren Testverfahren bei Floppy Betrieb habe ich mich damals entschieden, den Assembler Quellcode aus dem RAM zu lesen und auch das assemblierte Programm direkt im RAM zu speichern.
Assembler Quelltext
Der Assembler liest eine Textdatei (Quelltext) und wandelt den Text um in Code. Normalerweise benötigt man für die Erstellung der Textdatei ein Editor Programm (Texteditor). Beim C64 ist bereits ein Texteditor im Standardumfang. Es ist der Editor der normalerweise zur Eingabe eines BASIC Programm dient.
Dem Editor ist es vollkommen egal, was man da eingibt. Es muss nicht zwingend ein BASIC Programm sein, man kann genauso einen Assembler Quelltext eingeben und editieren. Der C64 Benutzer ist zudem den BASIC Editor gewöhnt und kann meist auf Anhieb damit arbeiten. Der Assembler Quelltext kann ganz normal mit SAVE gespeichert, mit LOAD wieder geladen und mit LIST angezeigt werden. Zudem unterstützt ExAss über neue Befehle das arbeiten mit dem Text Editor.
Natürlich kann der Assembler Quelltext nicht mit RUN ausgeführt werden. Der Befehl RUN startet den BASIC Interpreter und der kann mit dem Assembler Quelltext nichts anfangen.
Man startet den zwei Pass Assembler mit dem Kommando ';a'. Dieser liest den Quelltext im Speicher und erzeugt den Maschinencode. Wenn der Quelltext einen Fehler beinhaltet, dann wird der Fehler angezeigt und die Übersetzung abgebrochen. Der Benutzer editiert den Quelltext solange, bis sich das Programm übersetzen lässt und fehlerfrei läuft (Entwicklungszyklus).
Wenn ExAss nicht aktiv ist, dann funktionieren auch keine Kurzbefehle wie ';a'. Man kann aber trotzdem den Quelltext bearbeiten, speichern und laden. Das ist die normale Funktion des C64 BASIC Editor.
Code Generierung
So, nun hat man das Problem, daß der Speicherbereich wo das Programm laufen soll, gerade nicht frei ist.
Beispiel:
Ich habe ein BASIC Programm und dahinter soll ein Maschinen Code kommen, damit man alles auf einmal mit LOAD laden kann.
Sagen wir mal, das BASIC Programm ist sehr kurz und besteht nur aus einem SYS Befehl.
Das BASIC Programm endet am der Adresse $0820. Der Maschinen Code startet ab $0821.
Der Assembler Sourcecode ist etwas größer und reicht bis $6000.
Ich kann das Programm also nicht an der Adresse ablegen wo es später laufen soll.
Also mache ich
- =$0821:&=$C000
Also assembliere für die Adresse $0821, aber lege den Code ab an der Adresse $C000.
Man muss es dann nur noch verschieben an die Ziel Adresse und speichern.
Befehlserweiterung
ExAss bietet eine Erweiterung des Befehlssatz für den Direktmodus. Die neuen Befehle unterteilen sich in neue Befehle für den BASIC Editor und Kurz Befehle zur Steuerung der Floppy Laufwerke.
Floppy Kurzbefehle
Diese Befehle betreffen die Bedienung der angeschlossenen Floppy Laufwerke.
Die Befehle LOAD, BLOAD, SAVE und VERIFY funktionieren auch direkt aus dem Directory Listing am Bildschirm. Also einfach Directory mit $ anzeigen und dann <Cursor up> bis zum gewünschten Eintrag. Dann das erste Zeichen ersetzen mit /, % oder < und dann <RETURN> drücken.
$
Dieser Befehl dient dazu, das Directory einer Diskette anzeigen. Im Gegensatz zu LOAD"$",8 geht hierbei der Inhalt des BASIC Programmspeicher nicht verloren.
@
Dieser Befehl dient dazu, ein Kommando an das Floppy Laufwerk zu senden. Die möglichen Kommandos an die Floppy entnehmen Sie bitte dem Handbuch zum Floppy Laufwerk.
- Beispiele
- @I
- Initialisiert die Diskette im Laufwerk
- @N
- TEST
- Die Diskette wird gelöscht, der neue Name der Diskette ist 'TEST'
- @N
- TEST,UI
- Die Diskette wird formattiert, der neue Name der Diskette ist 'TEST' und die Disk ID ist 'UI'
- @S
- TEST*
- Löscht alle Dateien die mit 'TEST' beginnen
<Pfeil links>
Abkürzung für den Befehl SAVE.
/
Abkürzung für den Befehl LOAD.
%
Das ist der Befehl BLOAD, eine Abkürzung für den Befehl LOAD mit SA=1 (binary LOAD).
<
Abkürzung für den Befehl VERIFY.
#
Dies setzt die Gerätenummer (Floppy Laufwerk Adresse) für die Floppy Kurzbefehle. Der Standard hier ist 8, möglich sind die Werte 8 bis 11.
&
Das ist der Befehl APPEND, eine spezielle Art des Befehl LOAD. Damit kann man an den BASIC Code im Speicher ein weiteres BASIC Programm anhängen.
Zusatz Befehle
Die meisten Zusatzbefehle verbessern die Bedienung des Standard BASIC Texteditor. Diese Befehle funktionieren gleichermaßen für die Erstellung von BASIC Programmen als auch für die Entwicklung von Assembler Sourcecode für den zwei Pass Assembler.
DEL
Dieser Befehl löscht eine oder mehrere Zeilen im BASIC Programmspeicher.
- Beispiele
- DEL 60
- löscht die Zeile 60 im BASIC Code
- DEL 600-
- löscht alle Zeilen im BASIC Code ab der Zeile 600 bis zum Ende
- DEL -500
- löscht alle Zeilen im BASIC Code vom Anfang bis zur Zeile 500
- DEL 200-500
- löscht alle Zeilen im BASIC Code ab der Zeile 200 bis zur Zeile 500
RENUM
Der Befehl RENUM nummeriert Zeilen aus dem BASIC Programm Code. Man muss einen Bereich von Zeilennummern angeben der neu nummeriert werden soll. Optional kann eine Schrittweite angegeben werden. Dabei kann man auch das Ende oder den Anfang des Zeilenbereich offen lassen. Der Befehl kann auch abgekürzt werden.
Das neu nummerieren ist hilfreich, wenn man mitten im Sourcecode Zeilen einfügen möchte und kein Platz mehr dafür vorhanden ist. Also wenn es zu eng geworden ist, weil man bereits zu viele Zeilen eingefügt hat.
Der Befehl ist für den Assembler gedacht. Bei Basic Code funktioniert das schon auch, aber es werden keine Sprungziele (GOTO, GOSUB) angepasst. Beim Assembler Code ist das egal, weil man da ausschließlich mit Sprungmarken adressiert.
- Beispiele
- RENUM 2000-
- nummeriert alle Zeilen von Zeile 2000 bis zum Ende neu (Schrittweite 5)
- RENUM 200-299
- nummeriert alle Zeilen von Zeile 200 bis 299 neu mit der Schrittweite 5
- RENUM -800,10
- nummeriert alle Zeilen bis zur Zeile 800 neu (Schrittweite 10)
FIND
Der Befehl "find" sucht nach dem angegebenen Suchstring in den BASIC Textzeilen und listet alle betroffenen Zeilen. Soll ein Text in Anführungszeichen (") gesucht werden, dann muss auch der Suchstring mit " beginnen. Der Befehl kann auch abgekürzt werden.
Bei großen Quelltexten ist diese Suchfunktion unumgänglich. Der Befehl funktioniert auch einwandfrei in BASIC Programmen. Dabei ist aber zu beachten, dass der C64 alle BASIC Befehle wie PRINT, GOTO etc. umwandelt in Token. Ein Token ist ein einzelnes Sonderzeichen und kann auch nur komplett gefunden werden.
Nach dem Befehl sollte kein Blank eingegeben werden, denn sonst wird es als Bestandteil des Suchstring angesehen.
- Beispiele
- FINDGOSUB
- findet alle GOSUB Befehle (Token) im Code
- FINDGOSU
- findet alle Textstellen wo 'GOSU' enthalten ist, jedoch nicht GOSUB (Token)
- FIND200
- findet alle Textstellen wo '200' vorkommt wie zb. "GOTO 200" oder "LDA #200"
- FIND 200
- findet alle Textstellen wo ' 200' vorkommt wie zb. "GOTO 200" aber nicht "GOTO200"
HELP
Der Befehl HELP listet alle neuen Befehle auf. Der Befehl kann auch mit abgekürzt werden.
MEM
UNNEW
Dieser Befehl stellt ein mit NEW gelöschtes Programm im BASIC Programmspeicher wieder her.
Besonders praktisch ist dieser Befehl nach einem RESET des Computer. Wenn das Programm im Speicher noch in Ordnung ist, kann man es mit UNNEW nach einem Reset wieder herstellen.
Vorsicht: Der Befehl UNNEW setzt den BASIC Ende Pointer (Variablen Beginn) ans Ende des BASIC Code. Wenn sich hinter dem BASIC Code noch Maschinen Code befindet, dann ist dieser nach Ausführung von UNNEW ungeschützt. Sobald Variable angelegt werden, zerstört sich der Speicherinhalt nach dem BASIC Programm Code.
KILL
Dieser Befehl schaltet ExAss ab und deaktiviert das Modul, sofern das die Modul Hardware unterstützt.
Es werden alle Vektoren auf Standard Belegung zurückgesetzt. Der BASIC Programmcode bleibt erhalten. Die Variablen werden alle gelöscht. Der 8K Speicher wo sich ExAss befindet wird freigegeben, wodurch man wieder 38K freien Speicher hat.
Verbesserte Formelauswertung
Der BASIC Interpreter des C64 hat eine Funktion 'Formelauswertung'. Diese Funktion wird immer aufgerufen, wenn der Interpreter eine Zahl erwartet. Die Formelauswertung im BASIC v2 des C64 umfasst dezimale Zahlen, Variable und die Grundrechnungsarten.
ExAss erweitert die Formelauswertung um
- hexadezimale Zahlen
- binäre Zahlen
- low Byte (niederwertiges Byte)
- high Byte (höherwertiges Byte)
- Labels mit bis zu 16 Zeichen Länge (nur im Assembler)
Hexadezimal Zahlen
Das Basic des C64 rechnet normal nur mit dezimalen Zahlen und Variable. Wenn ExAss gestartet ist, dann kann der C64 alle Rechenoperationen auch mit Zahlen zur Basis 16 (hexadezimal) und 2 (binär) ausführen. Dabei können alle Systeme nach belieben gemischt werden. Dh. man kann überall wo man bisher dezimal Zahlen verwendet hat alternativ auch Hex- oder Binärzahlen verwenden. Das funktioniert im Direktmodus und auch in einem BASIC Programm.
Hexadezimale Zahlen beginnen mit einem '$' Zeichen. Es sind die Ziffern '0' bis '9' sowie die Zeichen 'A' bis 'F' zulässig in hexadezimalen Zahlen. Hexadezimale Zahlen müssen die Länge 2 oder 4 haben. Dieses Zahlensystem ist sehr gebräuchlich bei Assembler Programmierung. Der Vorteil ist, dass jedes Zeichen exakt 4 Bit entspricht. Dadurch kann man es auch sehr einfach in binäre Zahlen umrechnen. Ein 8 Bit Wert hat exakt zwei Stellen und eine 16 Bit Zahl exakt 4 Stellen.
- Zum Beispiel
A = $C144 PRINT $80 PRINT A + $40
Binär Zahlen
Das Basic des C64 rechnet normal nur mit dezimalen Zahlen und Variable. Wenn ExAss gestartet ist, dann kann der C64 alle Rechenoperationen auch mit Zahlen zur Basis 16 (hexadezimal) und 2 (binär) ausführen. Dabei können alle Systeme nach belieben gemischt werden. Dh. man kann überall wo man bisher dezimal Zahlen verwendet hat alternativ auch Hex- oder Binärzahlen verwenden. Das funktioniert im Direktmodus und auch in einem BASIC Programm.
Binären Zahlen wird ein '%' Zeichen vorangestellt. Im binären Zahlensystem gibt es nur die Ziffern 0 und 1. Dieses Zahlensystem ist sinnvoll, wenn man Hardware nahe Dinge programmiert, weil man auf den ersten Blick gut sehen kann, welche Bits auf 0 oder 1 sind.
- Zum Beispiel
PRINT $80 + 44 * %0111
In diesem Beispiel enthält die PRINT Anweisung alle drei Zahlensysteme. Hie wird eine Hexzahl zum Produkt eimer dezimalen Zahl und einer Binärezahl addiert. Man kann die Zahlensysteme beliebig mischen.
Niederwertiges Byte
Diese Funktion berechnet das niederwertige Byte (die unteren 8 Bit) einer 16 Bit Zahl (Integer). Die Funktion startet durch das Zeichen '<' (Kleiner Zeichen) gefolgt vom Zahlen Argument. Das Zeichen muss ganz am Anfang der Formel stehen, sonst funktioniert es als Vergleich (kleiner als ...).
- Zum Beispiel
PRINT <$8322 A = $5222 PRINT <A PRINT <(A + 4)
Höherwertiges Byte
Diese Funktion berechnet das höherwertige Byte (die oberen 8 Bit) einer 16 Bit Zahl (Integer). Die Funktion startet durch das Zeichen '>' (Größer Zeichen) gefolgt vom Zahlen Argument. Das Zeichen muss ganz am Anfang der Formel stehen, sonst funktioniert es als Vergleich (größer als ...).
- Zum Beispiel
PRINT >$8322 A = $5222 PRINT >A PRINT >(A + 4)
Labels
Labels funktionieren wie Zahlen Variable im BASIC. Labels können wie Variable aus Buchstaben und Ziffern bestehen und müssen mit einem Buchstaben beginnen. Allerdings können Labels bis zu 16 Zeichen lang sein und es sind alle Zeichen signifikant (Variable können nur zwei Zeichen lang sein, 'A1' ist dieselbe Variable wie 'A12').
Labels symbolisieren immer 16 Bit Zahlen. Im Gegensatz dazu können Variable in BASIC auch Fließkomma Werte (FLOAT) und Zeichenfolgen (STRING) enthalten.
Labels entstehen nur durch den zwei Pass Assembler beim übersetzen des Assembler Quelltext. Nach dem Übersetzungsvorgang kann man Labels im Direkt Modus verwenden wie Variable. Zum Beispiel kann man den Wert anzeigen lassen mit einem PRINT Befehl.
- Beispiel
PRINT LOOP PRINT BSOUT PRINT CBUFFER SYS START
Auf diese Art und Weise kann man herausfinden, an welcher Adresse der Assembler den Code und die Daten gespeichert hat.
Mini Monitor
Sonstige Dinge
Funktionstasten
Die Funktionstasten F1 bis F8 unterstützen die Arbeit im Direktmodus (Eingabe Editor). Mit den Funktionstasten kann man zeilenweise durch den BASIC Text auf und ab scrollen (funktioniert auch für dumps und code listings im Minimonitor), automatische Zeilennummerierung durchführen, Löschfunktionen (Zeilenende/Bildschirmende) auslösen, angezeigte Seite erneuern und mehrere Zeilen blättern.
- F1
- Listing eine Zeile nach unten scrollen
- ExAss sucht von unten nach oben nach einer Zeilennummer oder Adresse.
- F2
- Listing eine Zeile nach oben scrollen
- ExAss sucht von oben nach unten nach einer Zeilennummer oder Adresse.
- F3
- Listing erneuern über die ganze Seite, Startzeile ist erste Zeile am Schirm
- ExAss sucht von unten nach oben nach einer Zeilennummer oder Adresse.
- Tip: Wenn man zB. eine Zeile dupliziert im BASIC Text, ist dieser Befehl besonders nützlich
- F4
- Listing erneuern über die ganze Seite, Startzeile ist aktuelle Zeile (Cursor Zeile)
- ExAss sucht von oben nach unten nach einer Zeilennummer oder Adresse.
- ZB. wenn man immer nur 5 Zeilen weiter gehen möchte
- ZB. wenn eine bestimmte Zeile ganz oben sein soll, damit man einen bestimmten Bereich des Listings sieht
- F5
- Auto Zeilen Nummerierung
- Die aktuelle Zeile wird gespeichert (wie bei Return), und die aktuelle Zeilennummer plus 5 wird vorgeschlagen
- F6
- Bewegt den Cursor an das Ende der Zeile
- F7
- löscht alle Zeichen von der Cursor Position bis zum Ende der Zeile
- F8
- löscht alle Zeilen von der Cursor Position bis zum Ende des Bildschirm
Die List Funktionen (F1,F2,F3,F4) funktionieren mit BASIC Textzeilen aber auch mit Listings des Mini Monitor (Disassembler, Memory Dump).
Beginnt eine Zeile mit einer Zahl, dann handelt es sich um BASIC Textzeile (Zeilennummer). Beginnt eine Zeile mit ';' gefolgt von einer Zahl, dann handelt es sich um einen Speicherdump oder Assembler Listing.
Tastatur Klick
Jeder Tastendruck wird akustisch mit einem Klickgeräusch quittiert.