Basic-Boss

Aus C64-Wiki
(Weitergeleitet von bbcompiler)
Zur Navigation springenZur Suche springen
BASIC-BOSS
Startscreen
Entwickler Thilo Herrmann
Verleger Markt & Technik
Release 1988
Lizenz Vollversion
Plattform(en) C64
Genre BASIC-Compiler
Steuerung Icon tastatur.png
Medien Icon disk525 1.png
Sprache(n) Sprache:deutsch Sprache:englisch
Information 64'er Extra Nr.11

BASIC-BOSS ist ein 2-Pass BASIC-Compiler, der von Thilo Herrmann programmiert und 1988 vom Markt & Technik Verlag als 64'er Extra Nr. 11 veröffentlicht wurde. Er ist der schnellste bekannte BASIC-Compiler für den Commodore 64.

Beschreibung[Bearbeiten | Quelltext bearbeiten]

Basic-Boss ist konsequent auf maximale Ausführungs-Geschwindigkeit des erzeugten Programms ausgelegt. Das entstehende Kompilat ist immer 6502-Maschinencode. Die Generierung von speicherplatzsparendem P-Code, der interpretiert wird, ist nicht vorgesehen. Durch die Kompilierung wird ein BASIC-Programm in der Regel um einen zweistelligen Faktor schneller, abhängig von der Art des Programmes. Eine Menüführung besitzt der Compiler nicht. Gesteuert wird er ausschließlich von Direktiven im Quellcode. Diese zeigen ihm an, wie die nachfolgenden BASIC-Anweisungen umgesetzt werden sollen.

Basic-Boss setzt auf der Syntax von BASIC V2 auf, dem Standard-Interpreter des C64. Wird ein Programm ohne Änderungen der Quelldatei kompiliert und treten keine Fehler auf, erreicht man damit einen moderaten Geschwindigkeitsgewinn, der mit dem anderer Compiler vergleichbar ist. Um die Stärken von Basic-Boss zu nutzen, muss man ihn mit Compiler-Direktiven optimiert einsetzen. Ein ausführliches Studium des Handbuches ist dafür empfehlenswert.

Laden, Starten, Bedienung[Bearbeiten | Quelltext bearbeiten]

Das 64'er Extra Nr.11: BASIC-BOSS
64'er Extra Nr.11 Cover Rückseite

Der Basic-Boss wird wie ein BASIC-Programm geladen und gestartet mit

LOAD "BASIC-BOSS",8
RUN

Schließlich erscheint die Startmeldung mit dem Versionshinweis und der Eingabeaufforderung für den Namen des zu kompilierenden Programms. Jetzt muss man die Diskette einlegen, die das Programm enthält. Dies ist am besten eine spezielle Kompilier-Diskette mit einer Kopie des Programms, so dass bei einer Beschädigung der Datei die originale Quelldatei nicht betroffen ist.

  • Gibt man "$" statt eines Programmnamens ein, wird das Directory der Diskette gelistet.
Die Ausgabe des Inhaltsverzeichnisses kann mit Ctrl  verlangsamt, durch Drücken einer beliebigen Taste (außer <CTRL>, <C=>, <SHIFT> und <STOP>) angehalten und mit Stop  abgebrochen werden. Unter der Directory-Anzeige erscheint wieder der Eingabeprompt.
  • Gibt man Return  ohne Name ein, so wird "BASIC" als Default-Name benutzt.
  • Gibt man "*" als erstes Zeichen ein, wird kein Programm kompiliert, sondern der Basic-Boss mit dem Namen hinter dem "*" auf Diskette gespeichert.
  • Gibt man einen Programmnamen ein, so kann dieser - wie hinter dem BASIC-Befehl LOAD - mit einem "*" am Ende abgekürzt werden. Tritt nach der Betätigung durch Return  ein Problem mit dem Laden auf, kann mit Restore  abgebrochen werden. Ist alles in Ordnung, liest der Basic-Boss das Quellprogramm und startet den Kompiliervorgang, der jederzeit mit Stop  oder notfalls mit Stop +Restore  vorzeitig beendet werden kann.

Eine fortlaufende Zeilennummer und Meldungen auf dem Bildschirm dokumentieren den Fortgang der Kompilierung. Bei einer Fehlermeldung stoppt der Compiler, bis der Benutzer Shift  drückt. Mit der Direktive £PROTOCOLL kann die Fehlerausgabe auf einen Drucker oder in eine Datei umgeleitet werden. Ist die Kompilierung erfolgreich, gibt Basic-Boss eine Tabelle mit der Speicherbelegung aus und fordert auf zu
'←' für Neustart des Compilers / 'F1' für Reset / alles andere für Compiler beenden.

Das Kompilat ist nun auf der Diskette gespeichert. Standardmäßig ist sein Name aus dem Quelldateinamen mit einem vorangestellten "+" gebildet. Mit Compiler-Direktiven, z.B. £ROUTFILE, kann der Name des Kompilats beliebig gewählt werden.


Compiler-Direktiven[Bearbeiten | Quelltext bearbeiten]

Der Compiler erkennt Direktiven an dem vorangestellten Zeichen "£".
Mit dem Compiler-Befehl REM@ können Compiler-Direktiven vor dem Interpreter "versteckt" werden, um einen SYNTAX-Error zu vermeiden.

Neue Datentypen[Bearbeiten | Quelltext bearbeiten]

Kernstück der Optimierung sind die neuen Datentypen. Sie werden dem Compiler mit den Direktiven
£BOOLEAN, £BYTE, £INTEGER, £WORD, £REAL und £STRING mitgeteilt.

  • Boolean
  • Byte (8-Bit Ganzzahl ohne Vorzeichen)
  • Integer (16-Bit Ganzzahl mit Vorzeichen)
  • Word (16-Bit Ganzzahl ohne Vorzeichen)
  • Real (entspricht der normalen Fließkommazahl)
  • String (entspricht dem normalen String)

Der Typ der Daten des DATA-Befehls kann mit £DATATYPE festgelegt werden, Standard ist der Typ String. Beispiel:

 10 READ A,B,C
 20 REM@ £DATATYPE BYTE
 20 DATA 10,200,50  

In BASIC wird jede Berechnung mittels Fließkommaarithmetik durchgeführt, was eine Menge Zeit beansprucht und auch unnötige Umwandlungen verursacht. Hier setzten die neuen Datentypen an. Einfache Additionen mit Byte, Integer oder Word lassen sich mit nur wenigen Assemblerbefehlen realisieren, sind dementsprechend auch sehr viel schneller als Fließkomma-Berechnungen. Bei den übrigen Grundrechenarten sieht es ähnlich aus. Wenn man also nur eine Variable zum Hochzählen von 0 bis 100 braucht, so sollte man diese als Byte deklarieren. Der Geschwindigkeitsgewinn gegenüber einer Fließkommavariablen ist enorm.

Das folgende Beispiel zeigt eine optimierte Schleife:

 10 REM@ £BYTE I=FAST:£FASTFOR
 20 FOR I=0 TO 255:POKE 1024+I,I:NEXT I

Erstens ist die Variable I als Byte deklariert, zweiterns wird mit dem Zusatz FAST der Speicherort in die Zeropage verlegt, wodurch noch einmal Bytes und Taktzyklen beim erzeugten Maschinencode im Gegensatz zu Variablen, die im ”normalen” Hauptspeicher liegen, gespart werden. Man kann insgesamt bis zu vier Bytes (oder 2 Word/Integer, oder 1 Word/Integer und 2 Bytes) als FAST deklarieren. Darüber hinaus kann man auch für einzelne Variablen den Speicherort explizit festlegen. Man kann beispielsweise ein Byte-Array der Länge 1000 im Bildschirmspeicher ablegen und hat damit über das Array direkt Zugriff auf den Bildschirm. Das folgende Programm hat den gleichen Effekt wie das vorhergehende, allerdings nur wenn man es kompiliert:

 10 REM@ £BYTE I=FAST,SC(=1024:£FASTFOR
 15 DIM SC(1000)
 20 FOR I=0 TO 255:SC(I)=I:NEXT I

Weitere interessante Compiler-Direktiven:

  • £ALLRAM / £BASICRAM
Zu Beginn des Programms muss festgelegt werden, ob das gesamte RAM oder nur das BASIC-RAM ($0801-$9FFF, die berühmten 38911 Bytes) genutzt werden soll.
  • £ROUTSTART
Hiermit legt man fest, wo der Beginn des Kompilats im Speicher liegen soll, um es später mit SYS bzw JSR/JMP aufzurufen. Syntaktisch macht man dies z.B. in Hexadezimal so '£ROUTSTART $2000'.
  • £HEAPEND
Anders als im normalen BASIC 2.0 kann der Programmierer selbst festlegen, welcher Bereich für den String-Heap reserviert bleiben soll, z.B. '£HEAPEND $7FFF' um eine Bitmap-Grafik von $8000 bis $9FFF davor zu schützen von den String-Daten des Programms überschrieben zu werden. Sollte es Konflikte geben, weil z.B. der Bereich zu klein ist, meldet Basic-Boss dies beim Compilieren, z.B. "HEAPSTART OVER HEAPEND".
  • £FASTFOR
Aktiviert ein ökonomisches und beschleunigtes Kompilieren von FOR-NEXT-Schleifen. Achtung, es gibt Restriktionen: Jedem FOR muss z.B. genau ein NEXT folgen, damit der Compiler eine Schleife mit £FASTFOR bearbeiten kann.
  • £FASTARRAY
Schaltet die Bereichsüberprüfung bei Arrays ab, das heißt man bekommt keine Fehlermeldung wenn das Programm versucht auf einen Index zuzugreifen der außerhalb der Dimensionen des Arrays liegt, sondern der Zugriff wird einfach durchgeführt. Man liest dann irgendwelche Daten die außerhalb des Arrays liegen oder überschreibt sie bei Zuweisungen, was dann natürlich ziemlich sicher im weiteren Programmverlauf zu Problemen führen wird.
  • £SHORTIF
Erlaubt nur einen Befehl hinter THEN. Das spart drei Byte Speicher und beschleunigt den Code etwas. Beliebig viele Befehle hinter THEN sind wieder erlaubt nach £LONGIF.
  • REM@
Bei Ausführung des Codes in BASIC 2.0 wird alles nachfolgende in der Kommandozeile ignoriert, beim Kompilieren werden diese Inhalte aber berücksichtigt. Dies ist hilfreich, wenn man vor dem Kompilieren Funktionstests in BASIC 2.0 machen möchte.
  • £IGNORE / £USE
Zwischen einem £IGNORE und £USE enthaltener Code wird beim Kompilieren ignoriert. Einzig sinnvoller Einsatz sind Tests in BASIC 2.0, es macht also eigentlich nur in Kombination mit REM@ Sinn, z.B. 'REM@ £IGNORE' <beim Compilieren zu ignorierender BASIC 2.0 Code> 'REM@ £USE'
  • £PROTOCOL
Leitet Meldungen beim Kompilieren vom Bildschirm auf den Drucker mit der Geräteadresse 4 um. Als Parameter können auch eine Gerätenummer, eine Sekundärdadresse und ein Dateiname übergeben werden.
£PROTOCOL 8,"MELDUNGEN",S,W sendet die Meldungen in eine sequentielle Datei auf der Diskette.

Basic-Boss enthält über 50 verschiedene Compiler-Direktiven. Um sie alle kennenzulernen ist ein Blick in das Handbuch unerlässlich.

Zusammenarbeit mit Basic-Erweiterungen[Bearbeiten | Quelltext bearbeiten]

Befehle einer BASIC-Erweiterung kann der Basic-Boss nicht beschleunigen. Im besten Fall ist es möglich, sie an den BASIC-Interpreter zu übergeben. Damit der sie bearbeiten kann, ist natürlich Voraussetzung, dass die Erweiterung geladen ist.

  • £OTHERON am Programmbeginn wird bei Erweiterungen mit Token wird benutzt.
  • Bei Erweiterungen mit einer Kennung - wie z.B. "!" - am Anfang der Befehle, ist die Direktive £OTHER gefolgt von der Liste aller Befehle notwendig, z.B.
£OTHER !COL,!PLOT,!HIRES.

Programme mit Befehlen von Basic-Erweiterungen, die etwas tiefer in die Struktur des Interpreters eingreifen, wie z.B. Simons Basic, kann der Basic-Boss in der Regel nicht verarbeiten.

Neue Befehle und Funktionen[Bearbeiten | Quelltext bearbeiten]

Basic-Boss enthält einige gegenüber dem Interpreter neue Befehle und Funktionen. Befehle sind durch ein vorangestelltes , Funktionen durch ein @ gekennzeichnet. Beispiel:

  • ←LOAD
Dieser Befehl führt mit wenigen Parametern eine KERNAL-LOAD Operation durch, was in BASIC 2.0 deutlich komplizierter ist.
Die Syntax ist wie folgt: ←LOAD,"<File-Name>",<Geräte-Nr.>,<Startadresse>.
←LOAD,"MUSIK",8,4096 würde z.B. Musikdaten von einem als Device 8 angeschlossenen Diskettenlaufwerk nach $1000 laden.

Änderungen gegenüber BASIC 2.0[Bearbeiten | Quelltext bearbeiten]

Man möchte in der Regel, dass sich ein kompiliertes Programm, außer das es schneller ausgeführt wird, genau wie die unkompilierte Version verhält. Der Basic-Boss enthält allerdings ein paar Kleinigkeiten, die sich anders verhalten. Da gibt es zum einen Erweiterungen, wie die Möglichkeit ganzzahlige Werte mit einem vorangestellten Dollarzeichen auch hexadezimal anzugeben (z.B. $1337) und zum anderen die zusätzlichen Befehle und Funktionen. Ebenfalls verändert ist die interne Zeichenkettenverwaltung, was sich in einer deutlich schnelleren „Garbage Collection“ niederschlägt, wenn der Speicher aufgeräumt wird, um Platz zu schaffen und alte, nicht mehr benutzte String-Daten zu entsorgen.

Die zusätzlichen Möglichkeiten kann man einfach ignorieren/nicht verwenden, um die Kompatibilität mit BASIC 2.0 zu wahren. Allerdings verhält sich das Kompilat an einigen Stellen auch anders als der interpretierte Code. Beispiele:

  • Arrays müssen in Zeilen, bevor sie verwendet werden, mit DIM angelegt werden und die Dimensionen müssen zur Übersetzungszeit feststehen, dürfen also keine Variablen sein, außer sie wurden mit £CONSTANT als Konstanten deklariert (womit sie dann keine Variablen mehr sind, aber man kann auf diese Weise symbolische Namen vergeben und die Dimension(en) von mehreren zusammengehörenden Arrays an einer Stelle anpassen).
  • Die Funktion ASC() liefert bei einer leeren Zeichenkette 0 statt einen ?ILLEGAL QUANTITY ERROR auszulösen.
  • FRE(X) liefert auch bei einem Wert größer 32767 den korrekten Wert und keine negative Zahl die man erst umrechnen muss.
  • LIST, NEW, und STOP verhalten sich im Kompilat wie der END-Befehl.
  • GOSUBRETURN und FORNEXT können in einer bestimmten Kombination zum Absturz des Kompilats führen, weil RETURN in den Maschinenbefehl RTS übersetzt wird, der die Rücksprungadresse auf dem Stack erwartet, FOR-Schleifen dort aber auch Informationen ablegen. Das bedeutet, eine FOR-Schleife muss komplett abgearbeitet sein, bevor ein RETURN erfolgen darf, denn sonst interpretiert RTS die FOR-Daten als Rücksprungadresse. Diese ”gefährliche” Befehlsabfolge sollte in sauber programmierten BASIC-Programmen aber sowieso nicht vorkommen. Verlassen kann man sich darauf jedoch nicht, da der BASIC-Interpreter sehr gutmütig mit offenen FOR-NEXT- sowie GOSUB-RETURN-Strukturen umgeht und implizit mit einem RETURN oder FOR für eine bestimmte Schleifenvariable alle inneren FOR-NEXT-Schleifen still und ohne Nebenwirkung (hinsichtlich Stapelüberlauf) beseitigt. Im folgenden Beispiel würde der Interpreter mit dem RETURN alle offenen FOR-NEXT des Unterprogramm einfach implizit schließen. Das Programm springt aus der Schleife, bevor sie vollständig abgearbeitet ist und kehrt zum aufrufenden Programmteil "vorzeitig" zurück. Ein Beispiel mit einer logisch ”offen” gelassen Schleife zeigt die Situation, die für den Compiler vermieden werden sollte:
  10 GOSUB 20:END
  20 FOR I=1 TO 10
  30 GOTO 50
  40 NEXT I
  50 RETURN

Versionen[Bearbeiten | Quelltext bearbeiten]


Test[Bearbeiten | Quelltext bearbeiten]

Geschwindigkeit[Bearbeiten | Quelltext bearbeiten]

Die Geschwindigkeit des kompilierten Programms hängt beim Basic-Boss hauptsächlich von der Optimierung ab. Nur Routinen, die viele mathematische Funktionen wie EXP, SIN, TAN usw. benutzen, aber wenige Integer-Variablen, werden weit weniger stark beschleunigt.

Die folgende Tabelle (Zeiten in Sekunden) zeigt den Geschwindigkeitsgewinn durch Kompilieren anhand des Benchmark-Test-Programms aus dem 64'er-Sonderheft 12 (ausgeführt mit VICE) im Vergleich zum BASIC-Interpreter und zum BASIC 64 Compiler.

Anpassungen des Testprogramms für den Basic-Boss:

100 REM *******************************
110 REM     BENCHMARKS FUER COMPILER
120 REM *******************************
130 REM@ £WORD #:£BYTE D:£FASTFOR:£SHORTIF:£FASTARRAY
...
530 RESTORE
532 REM@ £DATATYPE BYTE
535 DATA0
...
Test BASIC V2.0 BASIC 64 Compiler BASIC-BOSS
Interpreter M-Code Opt. 2 M-Code M-Code opt.
B1: 1,37 0,31 0,93 0
B2: 10,23 0,13 1,10 0
B3: 71,00 63,72 63,20 35
B4: 5,40 0,60 0,95 0
B5: 8,82 1,55 3,55 0
B6: 130,17 123,22 120,72 121
B7: 25,80 1,53 3,22 0
B8: 144,10 23,75 47,77 27

Die Geschwindigkeit beim Kompiliervorgang ist im Vergleich zu anderen bekannten Compilern gut. Für die Kompilierung von "Eddi", dem Testprogramm des 64'er-Magazins, benötigt der BASIC-BOSS 1:33 Minuten. Der BASIC 64 Compiler braucht dagegen für die Kompilierung in Maschinensprache 6:22 Minuten.

Platzbedarf auf Diskette[Bearbeiten | Quelltext bearbeiten]

Die folgende Tabelle zeigt an Beispielprogrammen von verschiedenem Umfang die Größe des Compilats (Blöcke auf Diskette) im Vergleich zu BASIC und dem BASIC 64 Compiler.

Programm Basic BASIC 64 M-Code 1 BASIC-BOSS
Benchmark 7 29 22
Eddi 14 41 34
Blockfolge 21 50 44
Diskass 27 46 41
Labyrinth 40 93 80
Diskverw 59 110 93
Sound-Editor+ 92 206 171

Die obigen Programme sind nicht optimiert, sondern nur soweit geändert worden, dass sie mit Basic-Boss kompiliert werden konnten.

Beispiel: Fehlermeldungen und ihre Beseitigung beim Programm "Sound-Editor+":

  • 11/Zu viele Parameter
Grund : SYS mit Parametern
Lösung: £OTHERON
  • 1/Heapend ist unter Heapstart
Grund: Compilat zu lang, Stringspeicher passt nicht mehr rein.
Lösung: £ALLRAM:£VARSTART $CC00

Cross-Compiler[Bearbeiten | Quelltext bearbeiten]

bbcompiler.png

In den Jahren 2007 bis 2009 entwickelte Marco Timm eine Cross-Compiler-Variante des Basic-Boss namens bbcompiler. Damit kann ein BASIC-Programm im PRG-Format direkt auf einem PC kompiliert werden.

bbcompiler startet intern einen einfachen spezialisierten C64-Emulator und führt darin das originale Basic-Boss aus.

Der Emulator-Anteil von bbcompiler ist Freeware. Der C-Quellcode dazu und bbcompiler.exe für Windows sind im Download enthalten.

Die letzte Version ist v0.2.2 vom November 2009.

Weblinks[Bearbeiten | Quelltext bearbeiten]

Literatur[Bearbeiten | Quelltext bearbeiten]

  • "Der schnellste Compiler: Basic-Boss" von Arndt Dettke, 64'er 02/89 S. 100-103
  • "Konkurrenz für den Boss" von Olaf Dwziza, 64'er 08/94 S. 26-27
  • "Power für den Boss" - Effizientes Programmieren mit dem Basic-Boss - von Olaf Dwziza, 64'er 09/94 S. 29

Programm und Handbuch[Bearbeiten | Quelltext bearbeiten]

  • bbcompiler Cross-Compiler und das originale Basic-Boss (im Verzeichnis "anleitung") inkl. überarbeitetem Handbuch bei C64-Online.com
  • CSDb- Release Nr. 103888 Sprache:englisch bbcompiler und Basic-Boss V2.4 mit überarbeitetem Handbuch plus Version 2.42
  • Basic-Boss V2.42 Sprache:englisch bei Commodore.Software mit automatisch erstellter englischer Übersetzung des Handbuchs
  • Basic-Boss 64'er Extra Nr.11 im Internet-Archiv

Quellen[Bearbeiten | Quelltext bearbeiten]

  1. Quelle: BASIC-BOSS Handbuch, Markt & Technik Verlag (1988)
  2. Quelle: 64'er Magazin 08/1994, Artikel "Konkurrenz für den Boss" auf den Seiten 26-27