Bei jeder guten Basic-Erweiterung ist es notwendig, Parameter
zwischen Basic- und Assemblerprogramm zu übergeben. Die
"Lösung" über POKE und PEEK ist dabei viel zu unkomfortabel.
Besser ist es, die gleichen Routinen wie der C 128-Interpreter
zu verwenden.
Die Routinen zur Parameterübergabe lesen jeweils den nächsten
Wert aus dem Basic-Text und stellen ihn dem Assemblerprogramm
zur Verfügung. Dabei ist es im allgemeinen unerheblich, ob es
sich um eine Konstante oder eine Variable handelt. Werden die
erlaubten Grenzen überschritten, so erhält man einen "ILLEGAL
QUANTITY ERROR", bei einem falschen Variablentyp ergibt sich
ein "TYPE MISMATCH ERROR".
Die Adresse des nächsten zu lesenden Zeichens steht in der
Zeropage in den Speicherstellen $3D/$3E und wird vom
Betriebssystem verwaltet. Für spezielle Effekte(Sprünge im
Basic-Programm, Auswertung von Funktionen, ...) kann man sie
jedoch auch von Hand manipulieren.
Will man die Unterprogramme im Zusammenhang mit SYS-Befehlen
benutzen, muß man daran denken, daß dabei(im Gegensatz zum C 64)
die ersten vier Parameter nach der Startadresse als Byte-Werte
in die Prozessorregister übertragen werden und erst danach die
Kontrolle auf das Assemblerprogramm übergeht. Dies gilt auch für
das Beispielprogramm "DISKNAME.OBJ" auf der
Heftdiskette(Quelltext "DISKNAME.SRC" im Hypra-Ass-Format bzw.
als ASCII-Datei "DISKNAME.TXT"). Nach dem Laden mit
BLOAD"DISKNAME.OBJ" wird es mit
BANK 15:SYS 4864,,,,,GA,A$
gestartet und übergibt den Namen der Disk in Laufwerk GA an den
String A$. Die fünf Kommata sind genau aus dem obigen Grund
erforderlich.
Weitere Beispiele für die Anwendung der Routinen finden sich im
Programm "VDC-POKE" des letzten Teils.
CHRGOT($0386):
Liest das aktuelle Zeichen aus dem Basic-Text und stellt es im
Akku zur Verfügung.
CHRGET($0380):
Liest das nächste Zeichen, indem zuerst der Zeiger in $3D/$3E
um eins erhöht und dann CHRGOT aufgerufen wird.
CHKCHR($795E):
Testet, ob im Basic-Programm das im Akku stehende Zeichen
folgt. Ist dies nicht der Fall, so wird "SYNTAX ERROR"
ausgegeben.
CHKCOM($795C):
Prüft, ob ein Komma folgt.
CHKBRA($7959):
Wie CHKCOM, aber für "(" statt Komma.
CHKKET($7956):
Entsprechend den vorherigen Routinen für ")".
ERROR($4D3C):
Bricht das Programm mit einer Fehlermeldung ab. Die
Fehlernummer(s. Kapitel 8.1 im C 128-Handbuch) wird im X-
Register übergeben. Die wichtigsten Meldungen lassen sich auch
direkt über die folgenden Einsprünge ausgeben.
SYNTAX($796C):
Beendet das Programm mit "SYNTAX ERROR".
ILLEGAL($7D28):
Gibt "ILLEGAL QUANTITY ERROR" aus.
MISMATCH($77E7):
Analog für "TYPE MISMATCH EROOR".
SUBSCRIPT($7D25):
Das Gleiche für "BAD SUBSCRIPT ERROR".
GETBYTE($87F4):
Übergibt einen Byte-Wert(0-255) im X-Register.
GETCOM($8809):
Prüft zuerst auf ein Komma und ruft dann GETBYTE auf.
GETADR($8812):
Liest einen 16-Bit-Wert(0-65535) ein. Das Ergebnis erhält man
in Y/A, $16/$17 und $66/$67.
ADRCOM($880F):
Hierbei handelt es sich um eine Kombination aus CHKCOM und
GETADR.
GETPAR($8803):
Überträgt zuerst eine 16-Bit-Zahl nach $16/$17, prüft dann auf
ein Komma und ruft anschließend GETBYTE auf. Dies entspricht
der Parameterübergabe beim POKE-Befehl.
FRMEVL($AF96):
Liest einen beliebigen Wert aus dem Basic-Text. Handelt es sich
dabei um eine Zahl, so wird sie im FLPT-Format im FAC
gespeichert, die Adresse $0F erhält den Wert 0, und in $10 steht
entweder eine Null für Fließkommawerte oder $80 für Integer. Ist
es jedoch ein String, dann wird dies durch das Byte $FF in $0F
gekennzeichnet und in $66/$67 ein Zeiger auf den
Stringdescriptor, der sich in Bank 1 befindet, abgelegt. Der
Descriptor besteht aus drei Bytes, von denen das erste die Länge
und die beiden folgenden die Adresse des Stringtextes enthalten.
Bei einer Stringkonstanten befinden sie sich immer ab $1B in der
Zeropage(also Länge in $1B, Adresse in $1C/$1D). Für eine noch
nicht angelegte Stringvariable wird hingegen das
Descriptor-Highbyte in $67 auf $03, d. h. außerhalb des
Variablenbereichs(beginnt bei $0400 in Bank 1), gesetzt.
NUMTEST($77DA):
Überprüft, ob in $0F eine Null steht, also ob es sich beim
letzen Parameter um eine Zahl handelte. Falls dies nicht der
Fall ist, erfolgt ein "TYPE MISMATCH ERROR".
STRTEST($77DD):
Hier wird die Speicherstelle $0F auf $FF, d. h. auf den Wert
für Strings, getestet.
FRMNUM($77D7):
Die nächste Zahl wird als Fließkommawert im FAC zur Verfügung
gestellt. FRMNUM ist eine Kombination aus FRMEVL und NUMTEST.
GETPOS($7AAF):
Ermittelt die Adresse einer Variable und setzt die Typangaben
in $0F/$10 analog zu FRMEVL. Falls die Variable noch nicht
existiert, wird sie zuerst angelegt. In $61/$62 erhält man
einen Zeiger auf den Variablenkopf, in $49/$4A auf den -inhalt.
Bei einfachen Variablen beginnt der Kopf immer zwei Bytes vor
dem Inhalt und besteht nur aus dem Namen. Bei Feldern hingegen
erlaubt $61/$62 den Zugriff auf den Array-Header, der daneben
noch Informationen über die Dimensionierung enthält, während
$49/$4A auf das jeweilige Array-Element zeigt. Zudem wird in
$66/$67 der Index des Elementes zur Verfügung gestellt.
Achtung: Nach Ende von GETPOS wird unterhalb $4000 Speicherbank
1 aktiviert(ab $4000 ROM), so daß beim Aufruf der Routine von
Bank 0 aus immer JSRFAR benutzt werden muß, selbst wenn das
Basic-ROM eingeschaltet ist!
Durch die Möglichkeit, mit beliebigen Variablentypen
einschließlich Feldern zu arbeiten und dabei nicht nur lesend,
sondern auch schreibend auf die Inhalte zuzugreifen, kann
GETPOS sehr flexibel angewendet werden.
STRRES($9299):
Reserviert am Beginn des Stringbereichs die im Akku übergebene
Byteanzahl. Reicht der Speicherplatz nicht aus, wird das
Programm mit einem "OUT OF MEMORY ERROR" abgebrochen. Ansonsten
kann man ab der in $35/$36 angegebenen Adresse den Text
abspeichern. STRRES wird meist im Zusammenhang mit GETPOS
benutzt, um einem String einen neuen Inhalt zuzuweisen. Dazu
muß man die Startadresse aus $35/$36 und die Länge in den
Descriptor der Variable kopieren.
Achtung: Auch hier wird wieder nach dem Aufruf Bank 1
unterhalb $4000 eingeschaltet! Bzgl. der JSRFAR-Benutzung gilt
also das Gleiche wie bei GETPOS.
Thomas Klein
Dateien:
DISKNAME.SRC: Quelltext des Bsp.-Programms im Hypra-Ass-Format
DISKNAME.TXT: formatierter Quelltext als ASCII-File
DISKNAME.OBJ: assembliertes Beispielprogramm