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