Obwohl das Basic V7 des C 128 sehr umfangreich ist, kommt doch manchmal der Wunsch nach weiteren Befehlen auf, z. B. wenn man spezielle Anweisungen für ein Programmprojekt benötigt. Dann hilft nur selber programmieren. Wie den meisten bekannt sein dürfte, werden Basic-Befehle nicht Zeichen für Zeichen abgespeichert, sondern bei der Eingabe in Abkürzungen, sogenannte Token, umgewandelt und beim Listen wieder rückübersetzt. Dies spart Speicherplatz und erhöht die Ausführungsgeschwindigkeit der Programme. Beim C 64 genügt jeweils ein Byte, um jeden Befehl darzustellen, beim C 128 ist dies durch die größere Anzahl jedoch nicht mehr möglich. Deshalb wurden die Sondertoken $FE(für Befehle) und $CE(für Funktionen) eingeführt, auf die jeweils ein weiteres Byte zur Kennzeichnung der entsprechenden Anweisung folgt. An dieser Stelle kann man nun ansetzen, um eigene Befehle und Funktionen zu realisieren, denn die Bytes ab $80 nach den Sondertoken wurden speziell für Erweiterungszwecke reserviert. Den obigen Schritten entsprechend sind folgende Programmteile notwendig: Umwandlung der Befehle in Token, Rückübersetzung beim Listen und, jeweils für Befehle und Funktionen getrennt, Erkennen und Ausführen der neuen Anweisungen. Die Teile werden über die sogenannten ESC-Vektoren in die Interpreterschleife eingebunden. Außerdem müssen Tabellen der neuen Anweisungen und ihrer Adressen angelegt werden. Glücklicherweise wird das Ganze vom Betriebssystem unterstützt, so daß man nicht alles selbst schreiben muß, sondern mit relativ kurzen Routinen auskommt. Zuerst sollte man sich über die einzubindenden Befehle klar sein. Als Beispiel werden wir die Anweisungen VPOKE, VPEEK, RPOKE und RPEEK realisieren. Die beiden ersten funktionieren wie normale POKEs und PEEKs, greifen aber auf den Videospeicher des VDCs zu. Beispielsweise kann man mit "VPOKE 0,1" ein "A" in der linken oberen Ecke des 80-Zeichen-Screens erzeugen. RPOKE und RPEEK dienen zum Beschreiben und Lesen der 37 Register des VDC-Chips. So erhält man mit "PRINT RPEEK(12)" das High-Byte des Video-RAM-Starts. Die entsprechenden Programmteile findet man ab Zeile 93 im Assemblerlisting(Listing 1, als "VDC- POKE.SRC" im Hypra-Ass-Format bzw. "VDC-POKE.TXT" als ASCII- Datei auf der Diskette). Bei den Funktionen muß man wissen, daß der erste in Klammern übergebene Parameter(es sind mehrere möglich) von der FRMEVL-Routine des Betriebssystems ausgewertet wird, die beim nächsten Mal genauer beschrieben wird. Jetzt genügt die Information, daß man für eine Zahl das Ergebnis im Fließkommaakkumulator FAC erhält, wo man auch den Rückgabewert für das Basicprogramm plazieren muß(Übersicht Fließkomma- routinen s. z. B. 64'er 9/96). 1.)Befehls- und Adresstabellen: Damit der Interpreter die neuen Anweisungen erkennen kann, muß man, für Befehle und Funktionen getrennt, Tabellen anlegen, in denen nacheinander alle Wörter aufgeführt sind. Zur Trennung wird jeweils im letzen Zeichen Bit 7 gesetzt, was im Groß- /Kleinschriftzeichensatz der Großschreibung des jeweiligen Buchstabens entspricht. Die Listen selbst werden mit Nullbytes abgeschlossen. Sie stehen im Listing ab Zeile 85. Davor befinden sich die Tabellen mit den Anfangsadressen der Routinen, aufgrund der Art des Aufrufs allerdings um 1 vermindert. 2.)Umwandlung in Token: Der Programmteil TOKEN(ab Zeile 31) benutzt die Betriebssystemroutine TSEARCH($43E2), um in den angelegten Tabellen nach einer Anweisung zu suchen. Dazu wird in Y/A die Adresse der jeweiligen Liste übergeben. War die Suche erfolgreich, ist das C-Flag gesetzt und der Akku und $0D enthalten das zugehörige Token. Bei Befehlen muß jetzt das X- Register auf Null, bei Funktionen auf $FF gesetzt werden und damit TSFIND($43B2) aufgerufen werden. Ist das Wort nicht vorhanden, springt man stattdessen nach einem "JSR CHRGOT"($0386) zur Standardroutine des Basic- Interpreters(TSNFIND, $4326). 3.)Rückwandlung zum Listen: Die Ausgabe der Befehle besorgt die Routine TLIST($516E) im Basic-ROM. Sie verlangt das Token-Byte im X-Register sowie einen Zeiger in $24/$25 auf die Befehls- oder Funktionstabelle. Diese Parameter werden im LIST-Programmteil(ab Zeile 46) vorbereitet. Vom Betriebssystem wird beim Aufruf das Token im Akku übergeben und durch das Z-Flag zwischen Befehl(gesetzt) und Funktion(gelöscht) unterschieden. 4.)Aufrufen der Befehle: Auch beim Aufrufen der Befehle(Zeile 57: BEF) wird das jeweilige Token wieder vom Betriebssystem im Akkumulator zur Verfügung gestellt. Um die Adresse der zugehörigen Routine in der Tabelle zu finden, multipliziert man es durch einen ASL- Befehl mit zwei. Daß die Token nicht bei $00, sondern bei $80 anfangen, kann dabei ignoriert werden, da das Bit 7 durch den Shift-Befehl aus dem Akku hinausgeschoben wird und folglich die Berechnung nicht stört. Der erhaltene Wert wird nun ins X- Register kopiert und als Index für die Adressentabelle BEFADR benutzt. Durch die beiden PHA-Befehle werden Low- und High-Byte (-1) der aufzurufenden Routine auf den Stack gelegt und damit eine Unterprogramm-Rücksprungadresse, wie sie bei einem JSR- Befehl auftritt, simuliert. Trifft das Programm jetzt auf ein RTS, so erfolgt ein Sprung zum darauffolgenden Speicherplatz(deshalb die -1). Das geschieht hier nach Beendigung des CHRGET($0380)-Aufrufs in Zeile 63. Wichtig: Zu diesem Zeitpunkt ist zwar das Basic-ROM, nicht aber der I/O- Bereich ab $D000 aktiviert. Will man in den eigenen Befehlen darauf zugreifen, so muß man dies mit "JSR BANK15"($A845) nachholen. 5.)Aufrufen der Funktionen: Das Aufrufen der Funktionen(ab Zeile 65: FN) funktioniert prinzipiell genauso wie das der Befehle, allerdings kann der vorausgehende CHRGET($0380)-Aufruf entfallen. Stattdessen muß nach der Ausführung noch ein Test auf die schließende Klammer erfolgen(CHKKET, $7956) und dann nach FNEND($77DA) gesprungen werden. 6.)Einbinden der Basic-Erweiterung: Nachdem nun alle notwendigen Routinen fertig sind, müssen sie noch in die Interpreterschleife eingebunden werden. Dies geschieht über die eingangs schon erwähnten ESC-Vektoren: ESCTOKEN($030C/$030D) muß auf TOKEN, ESCLIST($030E/$030F) auf LIST, ESCBEF($0310/$0311) auf BEF und ESCFN($02FC/$02FD) auf (wer hätte es gedacht) FN gerichtet werden. Dies übernimmt INIT(ab Zeile 20) unter Benutzung der VECTAB-Tabelle(Zeile 77). Das fertige Programm kann von Basic aus mit BLOAD"NAME" geladen und mit "BANK 15:SYS Startadresse" aktiviert werden, die Version auf der Diskette("VDC-POKE.OBJ") beginnt bei $1300(dez. 4864). Prinzipiell müssen die vom Betriebssystem angesprungenen Teile von Bank 15 aus erreichbar sein, d. h. in Bank 0 unterhalb von $4000 liegen. Bei Platzmangel könnte man aber statt der Routinen der neuen Befehle selbst dort nur Aufrufe mittels JSRFAR($02CD) unterbringen und die eigentlichen Programmteile in den Speicher überhalb $4000 oder in Bank 1 verlagern. Als Beispiel für die Nutzung der neuen Anweisungen befindet sich das Programm "ASTEROIDEN 4+" auf der Diskette, ein (sehr) einfaches Weltraumspiel für den 80-Zeichen-Bildschirm. Aufgabe ist es, in der vorgegebenen Zeit möglichst häufig und ohne Kollision zur Station in der Mitte des oberen Bildschirmrandes zu fliegen. Beim nächsten Mal wird es dann um die Betriebssystemroutinen gehen, mit denen man Parameter aus dem Basic-Text lesen kann. Thomas Klein
Dateien: VDC-POKE.SRC: Quelltext im Hypra-Ass-Format VDC-POKE.TXT: Quelltext als ASC-Datei VDC-POKE.OBJ: assembliertes Programm ASTEROIDEN 4+: Basic-Demoprogramm