MOSpeed

Aus C64-Wiki
Wechseln zu: Navigation, Suche
MOSPeed
Konsolenausgabe
Entwickler EgonOlsen71
Release 2018
Lizenz Open Source / The Unlicense
Plattform(en) PC, C64
Genre BASIC-Cross-Compiler
Steuerung Icon tastatur.png
Sprache(n) Sprache:englisch

MOSPeed ist ein optimierender BASIC-Cross-Compiler von EgonOlsen71. Er ist Open Source bzw. Public Domain. Als Cross-Compiler läuft er auf dem PC, erzeugt aber 6502-Maschinencode für den Commodore 64.

Beschreibung[Bearbeiten]

MOSPeed ist ein optimierender BASIC-Cross-Compiler, der auf dem PC über die Eingabeaufforderung/Shell gesteuert wird. Er erwartet als Eingabe ein BASIC V2-Programm in Form einer Textdatei, wie sie auch z.B. vom C64 Studio oder CBM prg Studio verwendet wird. Er unterstützt die dort üblichen Platzhalter für Steuerzeichen wie z.B. {clear}. MOSpeed ist in Java geschrieben und benötigt daher eine installierte Java-Runtime-Umgebung, Version 8 oder höher.

MOSpeed lässt sich über diverse Kommandozeilenparameter anpassen. Compilerdirektiven im Quelltext, wie einige andere Compiler für den C64 sie kennen, verwendet er nicht.

MOSpeed ist ein optimierender Compiler. Er kann Konstanten erkennen (auch wenn diese als Variablen deklariert sind) und entsprechend ersetzen. Nicht (mehr) verwendete Variablen oder die Berechnungen zu deren Zuweisung kann er erkennen und entfernen. In der Folge produziert der für andere Compiler gerne verwendete Benchmark-Test aus dem 64'er-Sonderheft 12 hier keine vollständig vergleichbaren Ergebnisse, da MOSpeed Teile der dort laufenden Berechnungen vollständig wegoptimiert.

Die Geschwindigkeit des compilierten Programms liegt im Schnitt 10 bis 20 % über der eines mit Basic-Boss ohne spezielle Variablendeklarationen compilierten Programms, kann im Einzelfall aber auch auch wesentlich höher sein. Im Durchschnitt beschleunigt MOSpeed BASIC V2-Programme etwa um den Faktor 3 bis 5.

Laden, Starten, Bedienung[Bearbeiten]

MOSPeed ist eine Konsolenanwendung für den PC. Da MOSPeed in Java geschrieben wurde, liegt der Compiler selber als JAR-Datei vor. In der Distribution sind zwei Skripte enthalten - einmal für Windows (mospeed.cmd), einmal für Linux (mospeed.sh) - über die der Compiler gestartet werden kann.

Er erwartet mindestens den Dateinamen/-pfad zur zu compilierenden Datei oder alternativ /?, um die integrierte Hilfe anzuzeigen. Nur mit dem Dateinamen gestartet, erzeugt der Compiler nach einem fehlerfreien Durchlauf eine .prg-Datei mit dem Namen der Quelldatei und zwei vorangestellten Pluszeichen, also z.B. example.bas wird zu ++example.prg

Der Compiliervorgang kann über zahlreiche Kommandozeilenparameter beeinflusst werden.

Der Quelltext kann mit Zeilennummern (wie üblich) arbeiten oder aber auch mit, vom Interpreter nicht ausführbaren, Labels. MOSpeed übersetzt die Labels beim Compilieren dann automatisch in Zeilennummern.

Kommandozeilenparameter[Bearbeiten]

Die Kommandozeilenparameter werden direkt an den Aufruf des Compilers angehängt, die Reihenfolge ist dabei egal.
Alle Parameter beginnen mit /, es kann aber alternativ auch ein Minuszeichen verwendet werden.
true|false bedeutet im Folgenden, dass hier entweder true (für aktiv/eingeschaltet) oder false (für nicht-aktiv/ausgeschaltet) angegeben werden kann.

  • /target=<target file>: Setzt den Namen der Zieldatei explizit. Wenn nichts angegeben wird, wird das Name (wie oben kurz beschrieben) aus dem Quellnamen generiert. Hier kann auch ein kompletter gültiger Pfad angegeben werden.
  • /platform=c64: In Zukunft wird man die Programme für verschiedene Zielplattformen compilieren können (min. noch für den VC 20). Momentan geht dies noch nicht, weswegen der einzige gültige Wert hier c64 ist.
  • /generatesrc=true|false: Wenn true, werden zusätzlich zur Zieldatei noch die während des Compilierens generierten Quelltexte für 6502-Assembler und die verwendete Zwischensprache (assemblernah) rausgeschrieben. Default ist false.
  • /constfolding=true|false: Wenn true, werden Konstanten erkannt und im Compilat durch ihren expliziten Werte ersetzt. Beispiele sind hier die oftmals in einer Variablen abgelegten Adressen von VIC oder SID. Default ist true.
  • /constprop=true|false: Wenn true, wird Constant Propagation als Optimierung durchgeführt. D.h. Konstanten werden nicht nur direkt erkannt, sondern es werden auch solche Berechnungen als konstant erkannt, die nur auf letztendlich konstanten Werten basieren. Default ist true.
  • /ilangopt=true|false: Wenn true, wird der erzeugte Zwischencode in einem extra Durchlauf optimiert. Dies beschleunigt und verkleinert das Programm üblicherweise. Default ist true.
  • /nlangopt=true|false: Wenn true, wird der erzeugte 6502-Assemblercode im einem extra Durchlauf optimiert. Die beschleunigt und verkleinert das Programm üblicherweise, der Durchlauf ist allerdings je nach Programmgröße teilweise recht zeitaufwändig. Default ist true.
  • /smartlinker=true|false: Wenn true, werden nur die Teile der Runtime zum Compilat gelinkt, die auch wirklich von diesem verwendet werden. Bei false wird die gesamte Runtime mit dazugelinkt. Default ist true.
  • /deadstoreopt=true|false: Wenn true, werden tote, d.h. ungenutzte Variablenzuweisungen erkannt und entfernt. Dies ist meistens sinnvoll, kann aber in seltenen (z.B. bei zwar ausgeführten, aber nicht weiter genutzten Aufrufen von RND) das Ergebnis des Compilats von dem des Interpreters abweichen lassen. Dieser Parameter wirkt sich nur auf Gleitkomma- und Ganzzahlvariablen aus. Default ist true.
  • /deadstoreoptstr=true|false: Analog zu /deadstoreopt, aber für String-Variablen. Default ist true.
  • /loopopt=true|false: Erkennt und entfernt leere Schleifen aus dem Compilat. Diese Schleifen müssen im Quelltext nicht zwangsläufig leer sein, aber wenn z.B. das in ihnen berechnete Ergebnis für nichts sonst benutzt wird, werden sie trotzdem wegoptimiert. Default ist true.
  • /floatopt=true|false: Wenn true, werden diverse Optimierungen für Gleitkommabrechnungen angewendet. Im Einzelfall kann dies, bedingt durch die Ungenauigkeiten bei Gleitkommabrechnungen, zu kleinen Abweichungen im Ergebnis führen, die aber in den meisten Fällen zu vernachlässigen sein sollten. Default ist true.
  • /intopt=true|false: Wenn true, werden bestimmte Integer-Operationen optimiert. Generell behandelt MOSpeed aus Kompatibilitätsgründen Integer-Variablen im Wesentlichen so wie der Interpreter. Mit diesem Parameter kann dieses Verhalten zu Gunsten der Geschwindigkeit etwas aufgeweicht werden. Default ist true.
  • /compactlevel=[0|3...]: Wenn >= 3, wird der generierte Code auf eine geringere Größe hin optimiert. Dies geht leicht zu Lasten der Geschwindigkeit, allerdings nicht im selben Verhältnis wie die erfolgte Größenreduktion. Je größer der Wert, desto weniger sinkt die erzielte Geschwindigkeit aber desto größer bleibt meistens der optimierte Code. 4 oder 5 sind ein guter Kompromiss, der in vielen Fällen eine 10 bis 15 % geringere Codegröße mit einer 0,5- bis 1-%igen Geschwindigkeitseinbuße verbindet. Default ist 0, was diese Optimierung ausschaltet.
  • /progstart=xxxxx|$yyyy: Legt die Startadresse des compilierten Programms fest. Die Angabe erfolgt entweder Dezimal oder Hexadezimal. Wenn diese Adresse < 2100 ist, wird automatisch ein Basic-Header zum Starten mit eingebunden, ansonsten nicht. Default ist 2072.
  • /varstart=xxxxx|$yyyy: Legt die Startadresse des Variablen- bzw. Konstantenbereichs fest (siehe BASIC-Speicherbelegung). Die Angabe erfolgt entweder Dezimal oder Hexadezimal. Wird nichts angegeben, schließt sich dieser Bereich direkt an den des erzeugten Programms bzw der Runtime an. Dies ist auch der Default.
  • /varend=xxxxx|$yyyy: Legt das Ende des Variablenbereichs fest. Da sich der eigentliche Variablenbereich zur Laufzeit nicht verändert, beschreibt dies faktisch das Ende des Stringspeichers. Zu achten ist darauf, dass der gewählte Bereich lesbar ist und nicht unter einem der ROMs liegt. Default ist 40960.
  • /runtimestart=xxxxx|$yyyy: Legt die Startadresse der Runtime-Routinen fest. Die Angabe erfolgt entweder Dezimal oder Hexadezimal. Wird nichts angegeben, schließen sich diese direkt an das erzeugte Programm an. Dies ist auch der Default.
  • /alloff=true|false: Wenn true, werden alle Optimierungen, die per Default aktiv sind, abgeschaltet. Default ist false.
  • /vice=<path>: Hier kann ein Pfad zum VICE-Emulator (oder einem anderen mit gleichem Verhalten) angegeben werden. Nachdem der Compiliervorgang erfolgreich abgeschlossen wurde, wird das Compilat dann in diesem Emulator direkt gestartet. Per Default passiert das nicht.


Änderungen gegenüber BASIC 2.0[Bearbeiten]

MOSpeed versucht, weitgehend kompatibel zum BASIC V2-Interpreter zu sein. Es gibt aber ein paar wenige Abweichungen.

  • LIST, CONT: Werden ignoriert.
  • NEW, STOP: Funktionieren wie END.
  • DIM mit Variablen: Dies ist generell zwar nicht erlaubt, funktioniert aber teilweise trotzdem, wenn MOSpeed die Variablen als Konstanten erkennt.
  • Eingeschränkter Support von USR: Diese Funktion wird unterstützt, als Eingabeparameter wird aber nur eine einzelne Zahl akzeptiert. Strings oder mehrere Parameter sind nicht möglich.
  • SYS mit Parametern: Diese Option wird nicht unterstützt. Sie ist auch im Interpreter eher ein Hack als ein Feature.
  • INPUT mit Anführungszeichen: MOSpeed ist bei der Eingabe von Anführungszeichen bei INPUT etwas toleranter als der Interpreter.
  • Vereinheitlichte Rundung: Der Interpreter wählt in verschiedenen Situationen verschiedene Rundungsansätze. So wird z.B. innerhalb von Funktionen teilweise anders gerundet. Beispiel: A=145/3*3 setzt A auf 145, aber PEEK(145/3*3) liest aus 144, nicht aus 145. MOSpeed vereinheitlicht dieses Verhalten, so dass in diesem Beispiel immer 145 gilt (wie dies z.B. auch im BASIC 7.0 des C128 der Fall ist).
  • Gleitkommagenauigkeit: Die Ergebnisse von Gleitkommaoperationen können sich, je nach gewählter Optimierung, zwischen MOSpeed und dem Interpreter leicht unterscheiden. Dies sollte in den allermeisten Fällen aber kein Problem sein bzw. gar nicht erst auffallen. MOSpeed versucht ferner, einen Fehler in den Gleitkommaroutinen des ROMs zu umgehen, so dass Ergebnisse unter Umständen in MOSpeed richtiger sein können.

Laufzeitfehler[Bearbeiten]

Laufzeitfehler im Programm (z.B. bei Division durch 0 oder ähnlichem) werden in den meisten Fällen von MOSpeed zwar erkannt und ausgegeben, als Zeilennummer wird allerdings immer 0 ausgegeben.

Weblinks[Bearbeiten]

Programm