Commodore Basic V2
Commodore BASIC V2 ist der auf den Commodore-Rechnern Commodore 64 (C64), Commodore VC 20 (VC20), CBM 3016 und CBM 3032 (CBM-3000-Serie) primär eingesetzte BASIC-Dialekt. Beim C64 ist ein BASIC-V2-Interpreter fest im ROM enthalten und dient gleichzeitig als Benutzerschnittstelle; diese wird durch einen ebenfalls im ROM enthaltenen Bildschirm-Editor bereitgestellt – Kommandos können auf dem gesamten Bildschirm stehen (bleiben) und (auch nach Modifikation) wiederholt ausgeführt werden (also keine bloße Kommandozeile, sondern eine flächige Zeichenorientierte Benutzerschnittstelle). Als Eingabe akzeptiert der Editor die Angabe einer Programmzeile, was anhand einer vorangestellten Zeilennummer erkannt wird (die Zeile wird dann abgespeichert, aber noch nicht ausgeführt) oder – ohne Zeilennummer – die Angabe eines Befehls oder Systemkommandos (zum Beispiel RUN, LOAD, SYS, PRINT) oder einer durch Doppelpunkte separierten Folge davon (auch innerhalb einer Schleife), was direkt ausgeführt wird.
BASIC V2 basiert auf Microsoft BASIC und wurde für den C64 angepasst.
Zeilen-Orientierung
[Bearbeiten | Quelltext bearbeiten]BASIC V2 arbeitet zeilennummernorientiert, das heißt jeder Zeile muss eine Nummer vorangestellt werden, die auch als Parameter für Sprunganweisungen dient, sowie als Bezug bei Fehlermeldungen. Durch Änderung der Nummer einer Zeile wird diese unter Verwendung der neuen Nummer dupliziert. Das Löschen einer Zeile erfolgt ohne Rückfrage durch Eingabe der entsprechenden Zeilennummer und Drücken der Return-Taste.
Es ist üblich, Zeilennummern im Abstand von 10 (oder höher) zu vergeben; sollen dann später Zeilen eingefügt werden, sind die zunächst übersprungenen Zahlen verwendbar. Einen Befehl zur Neunummerierung gibt es in dieser BASIC-Implementierung nicht, dies ist jedoch mit BASIC-Erweiterungen auf verbreiteten Universal-Modulen wie dem Final Cartridge III und auch mit vielen Cross-Development-Tools möglich.
In jeder Zeile können beliebig viele Befehle stehen, welche durch Doppelpunkte getrennt werden. Eine Programmzeile darf jedoch im Prinzip nicht länger als 255 Zeichen sein; in der Praxis begrenzt der Editor die Länge auf zwei Bildschirmzeilen (80 Zeichen). Der BASIC-Interpreter benötigt keinerlei Leer- oder sonstige Formatierungszeichen.
Strukturierung zur besseren Lesbarkeit ist möglich durch Leerzeichen zwischen Schlüsselwörtern und beliebiges Einrücken der Zeilen nach einem Doppelpunkt am Zeilenanfang.
Befehle
[Bearbeiten | Quelltext bearbeiten]Befehle sind ohne Umschalttaste einzugeben. Dies resultiert im Einschaltzustand (Großbuchstaben und zahlreiche Grafikzeichen) in Großbuchstaben, beim aktivierten zweiten Zeichensatz (Groß- und Kleinbuchstaben, dafür weniger Grafikzeichen) in Kleinbuchstaben.
Neben den üblichen Ein- und Ausgabebefehlen (PRINT, INPUT) kann mittels GET der Wert eines einzelnen Tastendrucks ausgelesen werden.
Zur Verzweigung innerhalb eines Programms unterstützt BASIC V2 die Sprunganweisungen GOTO, GOSUB/RETURN sowie die bedingten Sprunganweisungen ON GOTO, ON GOSUB und IF ... THEN (statt einer Befehlsfolge kann hier auch ein Sprungziel folgen). Außerdem kann mit SYS direkt in ein Maschinenspracheprogramm eingesprungen werden. Die Funktion USR(x) ruft ein Maschinenspracheprogramm als Funktion auf und erhält von diesem einen Rückgabewert.
Als weitergehende Sprachelemente zur strukturierten Programmierung stehen lediglich Zählschleifen (FOR NEXT) zur Verfügung, die jedoch flexibel ausgestaltet sind (die Iterator-Variable ist nicht auf Ganzzahlen beschränkt und deren Änderung im Schleifenkörper ist gestattet).
Nicht enthalten sind Befehle zur komfortablen Erstellung von Sound, HiRes-Grafiken und Sprites: Zum direkten Zugriff auf die Hardware (Speicher und in den Adressraum eingeblendete Prozessor-Register) werden der Befehl POKE und die Funktion PEEK(x) bereitgestellt; so lassen sich dann jedoch wieder Sound- und Grafikprozessor (inklusive Sprites) programmieren, wenn auch nicht trivial und nicht in kompakter Form.
Auf dem C64 wurden jedoch von früheren Commodore-Geräten vielseitige Grafikzeichen (PETSCII) übernommen, die sich mit der entsprechend bedruckten Tastatur eingeben lassen. Auf dem C64 ist dies recht effektiv, da er anders als die ursprünglichen PETSCII-Rechner über Farbe verfügt sowie über eine höhere Textmodus-Auflösung als der Vorgänger VC 20.
Einfache Variablen müssen vor ihrer Verwendung nicht deklariert werden, der Variablentyp wird über deren Suffix definiert („$“ für Zeichenketten (Strings), „%“ für Ganzzahlen, ohne Suffix für Fließkommazahlen). Bei indizierten Variablen (Feldern, Arrays) ist jedoch eine Dimensionierung mit DIM erforderlich, sofern mehr als 11 Elemente (Indizes 0–10) pro Dimension verwendet werden sollen. Komplexere Variablentypen sind nicht implementiert.
Anders als etwa bei C oder C++ gibt es echte Strings, die also nicht wie in diesen Sprachen umständlich als Zeichen-Arrays konstruiert werden müssen.
String-Arrays können auch numerische Strings enthalten, die bei Bedarf mit der Funktion VAL() nach numerisch konvertiert werden können; dies kommt einem komplexen Variablentyp wie struct in C (zusammengesetzt aus numerischen und nichtnumerischen Komponenten) nahe.
Zur Übertragung von Daten von und zu Peripheriegeräten stehen besondere Varianten der Ein- und Ausgabebefehle zur Verfügung (PRINT#, INPUT#, GET#). Dazu kommen OPEN, CLOSE und CMD zur Ansteuerung von Drucker, Datasette und Floppy.
Eine Besonderheit stellen Abkürzungen für die Befehle dar. Statt PRINT kann auch nur kurz ? geschrieben werden, um Tipparbeit zu sparen.
Technische Aspekte
[Bearbeiten | Quelltext bearbeiten]Der Quelltext des momentanen BASIC-Programms (also nicht des BASIC-Interpreters selbst!) steht im Arbeitsspeicher als Default in den Bereichen $0800 bis $9FFF als verkettete Liste. Dies geht mit den auf dem Start-Bildschirm gemeldeten 38611 Bytes einher. Jedes Listenelement besteht dabei aus dem Zeiger (engl. Pointer) zur Adresse des nächsten Listenelements, der Zeilennummer und dem (null-terminierten) Zeileninhalt. Für die letzte Zeile ist der Wert des Zeigers auf das nächste Element 0. Der Programmstart und Einstiegspunkt für den Interpreter ist dabei $0801.
BASIC-Programme werden mit dem Befehl LOAD ohne den Parameter ,1 "relativ" (an den per Zeiger verstellbaren BASIC-Anfang) geladen. Mit diesem Parameter hingegen wird der Inhalt einer Datei "absolut" in den Bereich beginnend mit der Adresse geladen, die durch die ersten beiden Bytes in der Datei definiert ist. Handelt es sich dabei um ein Maschinenprogramm, so kann dieses anschließend durch den Befehl SYS mit der Angabe dieser anfänglichen Speicherstelle gestartet werden. Das erfordert die Kenntnis dieser Adresse. Aus diesem Grund werden meist auch Maschinensprache-Programme an die Speicherstelle $0801 geladen mit einem in BASIC implementierten Start-Programm, welches den entsprechenden Befehlt SYS aufruft („BASIC-Header“)
Die eigentlichen BASIC-Befehle werden dabei nicht im Klartext gespeichert, sondern RAM sparend und eine schnellere Ausführung ermöglichend als 1-Byte-Tokens.
Das ROM des BASIC-Interpreters selbst ist im Einschaltzustand (Default) in den Adressbereich $A000 bis $BFFF eingeblendet. Er kann jedoch über den CPU-Port des C64 an den Adressen 0 und 1 (der intern den Speichercontroller PLA steuert) ausgeblendet werden, um in diesem Bereich für die CPU RAM verfügbar zu machen. Jeder BASIC-Befehl geht mit einem eigenen Maschinen-(Unter-)Programm in diesem Bereich einher. Der BASIC-Interpreter analysiert, welcher Befehl nun vorliegt und verzweigt dann in die entsprechende Einsprung-Adresse des jeweiligen Befehls. Es ist auch möglich, aus eigenen Maschinencode-Programmen heraus entsprechende Implementierungen einzelner BASIC-Befehle zu nutzen. Dies wird zum Beispiel gern für Gleitkomma-Arithmetik genutzt, die sonst hätte selbst implementiert werden müssen, da der Prozessor des Systems (MOS 6510) diese nicht unterstützt.
Trotz der Bezeichnung "BASIC V2" in der Einschaltmeldung des C64 beruht das BASIC auf der Version 4, inklusive Bugfixes, die jedoch auf den Befehlssatz der Version 2 reduziert wurde. Dieses "schlanke" BASIC verbraucht weniger Adressraum und läuft schneller als die umfänglicheren Versionen von Commodore-BASIC.[1]
Wenn auch über BASIC angesprochen, werden die Befehle zur Steuerung des Diskettenlaufwerks von diesem eigenständig ausgeführt und nicht vom BASIC-Interpreter. Die dort (DOS im ROM des Diskettenlaufwerks) auszuführenden Befehle werden dabei als Parameter des Befehls PRINT# übergeben, z. B. PRINT# 15,"R:FILE2=FILE1" für das Umbenennen einer Datei (15 ist der vorher zu öffnende Kommando-Kanal). Fehler im dortigen Befehlssatz wurden mehrfach durch Commodore behoben. Zu beachten ist dabei allerdings, dass seinerzeit Aktualisierungen der Firmware aufwändig waren, sich Aktualisierungen also damals nicht auf die Bestandsgeräte verbreiteten. Deshalb wird um einen in der Literatur bisweilen beschriebenen, in der Praxis jedoch selten auftretenden Fehler in der Replace-Funktion auf BASIC-Ebene herum programmiert: Bei Veränderungen einer Datei wird stattdessen eine neue Datei gespeichert und dann umbenannt, weil das einfache Aktualisieren gemäß Literatur bei frühen DOS-Versionen die Datei zerstören kann.
Die grafische Ausgabe auf Druckern (in den 1980er Jahren in Deutschland meist „Hardcopy“ genannt) ist mittels der meisten einschlägigen Programme auf üblicherweise am C64 betriebenen Druckern unproblematisch. Der BASIC-Befehl PRINT kann auf triviale Weise jedoch nur bei Commodore übliche Zeichen wie Zahlen, Buchstaben, Satz- und Grafikzeichen ausgeben; deutsche Umlaute sind dadurch herausfordernd. Für Grafik muss auf Ebene des BASIC-Programms der entsprechende Drucker in seiner Ansteuerungssprache angesprochen werden. Der insoweit verbreitetste Standard waren Commodore-Drucker. Ein anderes Beispiel ist ESC/P für Modelle des Herstellers Epson und damit kompatible Geräte. Da sich Anfang der 1980er Jahre immer noch verschiedene Ansteuerungssprachen etablierten, bedeutete dies damals, dass entsprechende Ausgabe dann an einem anderen Drucker-Modell eventuell nicht möglich war. Ferner geht diese Ausgabe einher mit der eigenen Implementierung von z. B. Rastering-Funktionen für das Drucken von Linien. Auch Wissen darüber war seinerzeit nicht so einfach und schnell wie heute im Internet verfügbar, und manche Algorithmen waren teilweise erst kurz vor Einführung des Geräts erfunden wurden (z. B. die Methode von Horn) und noch nicht bei Entwicklern verbreitet oder bekannt.
Einordnung
[Bearbeiten | Quelltext bearbeiten]Die Geschwindigkeit der BASIC-Programme ist durch den Interpretations-Ansatz prinzipbedingt langsam. Als Software von Drittherstellern gibt es deshalb auch Compiler, die BASIC-Programme in Maschinensprache umsetzten, was für erheblich mehr Geschwindigkeit sorgt.
Die ineffizienten und langsamen Möglichkeiten für Sound und Grafik verlängern den Programmtext und erschweren dessen Erstellung und dessen Verständnis. Obwohl BASIC anfängerfreundlich sein soll, ist diese Programmierung weiterhin nicht trivial, da hier viel Kenntnis über die Gegebenheiten des Systems und dessen Funktionsweise vonnöten ist.
Erst in BASIC V3.5 der nachfolgenden Plus-4-Reihe wurden beispielsweise einfache Befehle für Sound und Grafik angeboten. Allerdings gib es für den Commodore 64 entsprechende Erweiterungen wie Simons' Basic. Die damit erzeugten Programme sind allerdings nicht portabel, da entsprechende Erweiterung auch bei der Ausführung auf einem anderen Commodore 64 benötigt wird.
Die erwähnten Einschränkungen und Herausforderungen (insbes. die mangelnde Geschwindigkeit) macht die Erstellung von Programmen, die schnell laufen und eine ansprechende Darstellung haben, in reinem, interpretiertem BASIC schwierig. Um das zu erreichen, sind deshalb Ansätze nötig wie der Einsatz beschleunigender Compiler, Hybrid-Programme aus BASIC- und Maschinencode (an zeitkritischen Stellen) oder reine Maschinenprogramme.
Leistungsfähige Programme waren zunächst meist manuell vollständig in Maschinensprache (Assembler) programmiert, als noch keine leistungsfähigen Compiler verfügbar waren – der den schnellsten Code erzeugende Compiler, BASIC BOSS, erschien erst 1988. Es gab durchaus erfolgreiche und sehr gut bewertete Hybrid-Spiele wie wohl am bekanntesten Gunship, Pirates! und andere Titel von Microprose.
Anfang der 1980er Jahre wurde manchmal auch ein damals sogenannter „List-Schutz“ für BASIC-Programme implementiert, insbesondere von Hobby-Programmierern. Es ging hierbei darum, das Anzeigen des Quelltextes durch den Befehl LIST zu unterbinden. Durch Ausnutzung von Fehlern in der BASIC-Implementierung oder durch Veränderung der erwähnten zugehörigen aufzurufenden Einsprung-Adresse dieses Befehls wurde Entsprechendes realisiert. Retrospektiv betrachtet zeigt sich aber, dass entsprechende Ansätze leicht zu umgehen waren und somit keinerlei effektiven Schutz bewirkten. Effektiv ist auch insoweit der Einsatz eines Compilers.
Der Interpreter ist Turing-vollständig. Das BASIC V2, welches ja mit dem Computer ausgeliefert, automatisch und schnell gestartet wurde und nicht separat gekauft werden musste, brachte damit dennoch alles mit, um als Anfänger einen Einstieg in die Prinzipien der Programmierung machen zu können. Für viele Schüler dieser Zeit, die mit dem Gerät nicht nur spielen wollten, war dies der Einstieg in die Programmierung und für einige wegweisend in der beruflichen Laufbahn.
Codebeispiel
[Bearbeiten | Quelltext bearbeiten] 10 input "Geben Sie bitte Ihren Namen ein"; a$
20 print "Guten Tag "; a$
30 input "Wie viele Sterne möchten Sie?"; s
40 for i = 1 to s
50 s$ = s$ + "*"
55 next i
60 print s$
70 input "Möchten Sie noch mehr Sterne?"; q$
80 if len(q$) = 0 goto 70
90 l$ = left$(q$, 1)
100 if (l$ = "J") or (l$ = "j") then goto 30
110 print "Auf Wiedersehen";
120 for i = 1 to 200
130 print a$; " ";
140 next i
150 print
Weblinks
[Bearbeiten | Quelltext bearbeiten]- Das C64-Benutzerhandbuch inklusive BASIC V2-Referenz – bei C64Games.de
- Dokumentation zu BASIC V2 – bei 8-Bit-Nirvana
- CBM BASIC V2 Basic-Interpreter – kompatibel zu Windows 32 Bit und Mac OS X (englisch)