BASIC-BOSS
Basic-Compiler

Quelle: 64'er Extra Nr. 11
(c) 1988 by Markt&Technik Verlag Aktiengesellschaft,
Hans-Pinsel-Strae 2, D-8013 Haar bei Mnchen/West-Germany


Inhaltsverzeichnis

Vorwort

Einleitung

Kapitel 1 - Einfhrung

 1.1      Grundlagen
 1.1.1    Basic und Maschinensprache
 1.1.2    Datentypen

 1.2      Direktiven und Compilerbedienung
 1.2.1    Weitere Compilerdirektiven
 1.2.2    Beispiele

Kapitel 2 - Bedienungshandbuch

 2.1      Die Bedienung des Basic-Boss
 2.1.1    Der Inhalt der Basic-Boss-Diskette
 2.1.2    Bedienung des Compilers
 2.1.3    Automatikmodus
 2.2      Allgemeines
 2.2.1    Compilerdirektiven
 2.2.2    Zahlensysteme
 2.2.3    Inaktivierung von REM-Befehlen
 2.2.4    Das Compilat
 2.3      Datentypen
 2.3.1    Die Wertebereiche der Typen
 2.3.2    Die Deklaration
 2.3.3    FAST-Variablen
 2.3.4    Adrefestlegung bei Variablen	
 2.3.5    Vor- und Nachteile der Datentypen und Verwendung
          des richtigen Typs
 2.3.6    Umwandlungen von Datentypen
 2.3.6.1  Umwandlungen mit Verlust
 2.3.6.2  Umwandlungen ohne Verlust
 2.3.7    Wertigkeit der Typen und deren Verarbeitung
 2.3.8    Der diffuse Wertebereich von Byte, Word und Integer
 2.3.8.1  Byte und Word
 2.3.8.2  Der Integer-Typ und seine hnlichkeit zu Word
 2.3.9    Typen bei Operationen, Funktionen und Befehlen
 2.3.9.1  Typen bei Befehlen
 2.3.9.2  Speicherbefehle
 2.3.9.3  Befehle zur Programmsteuerung
 2.3.9.4  Ein- und Ausgabe (im weiteren Sinne)
 2.3.9.5  Weitere Befehle
 2.3.9.6  Typen bei Funktionen
 2.3.9.7  Typen bei Operationen
 2.3.9.8  Typen der Systemvariablen
 2.3.10   Der Datentyp Constant

 2.4      Beschreibung der Direktiven
 2.4.1    Steuerung der Datentypen
 2.4.2    Optimierungsmglichkeiten
 2.4.3    Festlegung der Startadressen
 2.4.4    Die Dateien
 2.4.5    Protokollierung der Compiler-Ttigkeit
 2.4.6    Speicherverwaltung
 2.4.7    Die SYS-Zeile
 2.4.8    Sonstige Direktiven

 2.5      Neue Befehle und Funktionen
 2.5.1    Ein-/Ausgabe
 2.5.2    Effiziente Ein- und Ausgabe
 2.5.3    Speicherverwaltung
 2.5.4    Verarbeitung von Befehlen aus Basic-Erweiterungen
 2.6      nderungen beim Commodore Basic V2
 2.6.1    Verbesserungen
 2.6.2    Befehle mit Sinnverlust
 2.6.3    nderungen
 2.6.4    Problemflle

 2.7      Speicherplatz und Geschwindigkeit

 2.8      Effiziente Programme
 2.8.1    Datentypen
 2.8.1.1  Der richtige Typ
 2.8.1.2  Umwandlungen
 2.8.2    Konstanten, Operationen, Befehle, Arrays
 2.8.3    Vermeidung berflssiger Befehlsausfhrung
 2.8.4    Tabellen
 2.8.5    Verkrzung von Berechnungen
 2.8.6    EASTFOR, DATATYPE, SHORTIF

 2.9      Anpassung vorhandener Programme

 2.10     Es funktioniert nicht

 2.11     Rechtliches
 2.12     Fehlermeldungen
 2.12.1   Die Meldungen des Basic-Boss
 2.12.2   Die Meldungen des Compilats

Anhang	
 A        bersicht aller Direktiven
 B        Zustzliche Befehle und Funktionen
 C	  Automatikmodus
 D	  Wertebereiche der Variablentypen
 E 	  Der Software-Speeder Ultraload Plus
 F	  Stichwortverzeichnis

Hinweis auf weitere Markt&Technik-Produkte


-----------
- Vorwort -
-----------

Die meisten hatten nicht mehr damit gerechnet, da noch ein Basic-Compiler fr den C64 erscheint, der das bisher Dagewesene in den Schatten stellt. Nun ist es aber doch noch Wirklichkeit geworden: Basic-Boss bersetzt Ihre Programme in reine Maschinensprache. Versehen Sie Ihre Programme noch mit sogenannten Compilerdirektiven, so knnen Sie Ihre Programme noch weiter beschleunigen. Dabei sind Beschleunigungen um den Faktor 100 keine Seltenheit. Sie knnen in Zukunft in vielen Fllen auf die aufwendige Programmierung in Maschinensprache verzichten.
Viele Features erlauben ein komfortables und leistungsgerechtes Arbeiten, denn Basie-Boss enthlt unter anderem neue Befehle und erlaubt das Kompilieren von Programmen, die mit diversen Basic-Erweiterungen erstellt wurden. Auerdem stellt der Basic-Boss dem Programmierer eine Parametertabelle bereit, um hufig gebrauchte Grundeinstellungen abzuspeichern. Wir wnschen Ihnen viel Erfolg mit dem Basic-Boss.
Ihre Software-Extra-Redaktion


--------------
- Einleitung -
--------------

Einst hatte ich die Idee, ein Basic-Programm direkt in Maschinensprache umzuwandeln. Da das Ganze aber etwas eintnig war, wollte ich den Proze automatisieren und setzte mich vor meinen C 64 und programmierte einen Basic-Compiler. Nach ber einem Jahr harter Arbeit und vieler Entbehrungen war es dann soweit: Der Basic-Boss erblickte das Licht der Welt. Er (Quellcode) erstreckt sich inzwischen ber zwei Diskettenseiten (jeweils 41 Tracks) und ein vollstndiger Assemblerlauf bentigt zirka 30 Minuten. Die Assemblierung ist allerdings nur auf einer 512-Kbyte-RAM-Disk mglich (ich benutze Turbo Trans, welches jedoch einige nicht unwesentliche Nachteile besitzt. So lscht es zum Beispiel hin und wieder unmotiviert einzelne Sektoren oder ganze Diskettenseiten). Der Assembler, der ein solches Riesenprojekt berhaupt noch mglich macht, ist der Assi von Dirk Zabel. Einen annhernd gleichwertigen Assembler konnte ich brigens bislang nicht einmal auf den Proficomputern Amiga und Atari ST ausmachen.
Ein solch umfangreicher Compiler bentigt auch eine ausfhrliche Anleitung. Diese besteht aus zwei Kapiteln. Kapitel l vermittelt Grundlagen und fhrt in die Bedienung des Basic-Boss ein. Die meisten von Ihnen werden weite Teile davon berspringen knnen, da dort sicherheitshalber ganz von vorne angefangen wird und der Anwender fast ohne Grundwissen auskommt. Dieses Kapitel erhebt aber keinen Anspruch darauf, genau oder gar vollstndig zu sein, sondern ist als Einfhrung gedacht. Trotzdem kann man nach dessen Lektre bereits mit dem Basic-Boss arbeiten. Im Gegensatz zu Kapitel 1 bietet Kapitel 2 eine genaue und vollstndige Beschreibung aller Befehle und Eigenarten des Basic-Boss. Aber auch dort wird meist nicht viel Grundwissen vorausgesetzt.
Um das Handbuch verstehen und den Compiler benutzen zu knnen sind allerdings gewisse Grundkenntnisse in der Programmiersprache Basic ntig, da nur die Eigenschaften und Befehle des Compilers beschrieben werden, nicht aber die des Commodore-Basic. Darum ist dem Basic-Einsteiger ein gutes Basic-Buch zu empfehlen, da das Standard-Commodore-Handbuch ziemlich mager ist.

Die gesamte Anleitung wurde brigens auf dem C 64 mit VizaWrite verfat. Ich ziehe den C 64 bei der Textverarbeitung dem Amiga und dem Atari ST immer noch vor (die stehen nutzlos daneben) und halte die Behauptung fr unsinnig, der C 64 sei fr vernnftige Textverarbeitung zu klein. Bevor Sie mit dem Compiler arbeiten, sollten Sie sich eine Sicherheitskopie anlegen. Dies stellt kein Problem dar, da der Basic-Boss zum einen keinen Kopierschutz beinhaltet und sich zum anderen sogar selbst kopieren kann. Und das geht so: Stellen Sie sicher, da Sie eine weitgehend leere und formatierte Diskette verfgbar haben und laden Sie dann den Basic-Boss von der Originaldiskette mit

LOAD "BASIC-BOSS",8

Wenn der Computer fertiggeladen hat, geben Sie RUN ein. Jetzt knnen Sie Ihre formatierte Diskette in das Laufwerk schieben. Anschlieend drcken Sie auf die <*>Taste und geben einen Namen ein, unter dem der Basic-Boss dann abgespeichert wird, wenn Sie die Eingabe mit <RETURN> beenden. Auf der Originaldiskette befinden sich noch ein paar Beispielprogramme, die Sie sich ansehen sollten. Ansonsten wnsche ich Ihnen viel Spa beim Lesen der Anleitung und hoffe, da Sie mit dem Basic-Boss keine allzu groen Schwierigkeiten haben.


--------------------------
- Kapitel 1 - Einfhrung -
--------------------------
1.1 Grundlagen

1.1.1 Basic und Maschinensprache

Frisch ab Werk bietet der C 64/C128 dem Benutzer die Programmiersprache Basic. Dies hat seinen Grund. Denn Basic ist eine leicht erlernbare Sprache und darum jedem Anfnger sehr zu empfehlen. Doch nicht nur Anfnger arbeiten mit Basic. Auch Fortgeschrittene und Profis schreiben ihre Programme lieber in Basic als in irgendeiner anderen Sprache, nicht zuletzt weil Basic ber leistungsfhige mathematische Funktionen und eine komfortable Stringverwaltung verfgt und durchaus auch die Entwicklung grerer Programme erlaubt. Damit knnte sich Basic gegen seinen einzigen ernstzunehmenden Konkurrenten problemlos durchsetzen. Dieser Konkurrent ist die Maschinensprache. Sie besitzt keine Stringverwaltung, kann nicht mit Fliekommazahlen rechnen und ist auch sonst uerst primitiv und extrem umstndlich. Darber hinaus dauert es bei greren Programmen recht lange, bis man das Geschriebene berhaupt austesten kann. Bei Basic gengt die Eingabe von RUN. Doch trotz all dieser Nachteile wird die Maschinensprache hufig benutzt, denn sie besitzt einen entscheidenden Vorteil: Sie ist wesentlich schneller als Basic.
Dieser Unterschied ist im verschiedenen Prinzip der beiden Sprachen begrndet. Die Maschinensprache wird vom Computer selbst (der Maschine) interpretiert. Darum ist sie so schnell und auch so primitiv, denn es wre viel zu aufwendig, einen Computer zu bauen, der eine weniger primitive, hhere Programmiersprache versteht. Da man dem Benutzer eine solch primitive Sprache nicht zumuten kann, schreibt man in dieser Maschinensprache ein Programm, das eine hhere Sprache verarbeitet beziehungsweise interpretiert. Dies ist der Interpreter. Nun kann in dieser hheren Sprache programmiert werden, zum Beispiel in Basic. Deren Befehle werden vom Interpreter erkannt und ausgefhrt. Dieser Vorgang bentigt allerdings ziemlich viel Zeit, und eben deshalb ist Basic so langsam.

Es scheint also unmglich, die Vorteile der Programmierung in Basic zu nutzen, wenn man schnelle Programme schreiben will, denn fr die meisten Anwendungen ist Basic unertrglich langsam. Es gibt aber einen Ausweg aus diesem Dilemma: Man kann jemanden die eigenen Basic-Programme in die Maschinensprache bersetzen lassen. Da sich fr diesen langweiligen Job kaum jemand finden lassen wird, liegt es nahe, diesen Vorgang zu automatisieren und ihn dem Computer zu berlassen, denn zur Erledigung monotoner Aufgaben ist er schlielich da. Der einzige Haken an der Sache ist das hierzu ntige bersetzerprogramm (Compiler genannt), das enorm aufwendig und kompliziert ist, denn ganz so monoton ist die Aufgabe eben doch nicht. Darum begngen sich viele Compiler damit, das Basic-Programm in einen etwas effizienteren Spezialcode umzusetzen, der dann aber wieder interpretiert wird, weshalb nur eine mige Beschleunigung erreicht wird.
Der erste echte Compiler war der vor lngerer Zeit in der Zeitschrift 64'er verffentlichte As-Compiler, der tatschlich echten Maschinencode erzeugte. Allerdings verstand er nur ein sehr eingeschrnktes Basic und war darum nur sehr bedingt brauchbar. Der Basic-Boss versteht dagegen alle Basic-Befehle und erzeugt sogar einen noch effizienteren Code. Man sollte sich aber darber im klaren sein, da auch der Basic-Boss die Maschinensprache nicht berflssig macht, denn extrem zeitkritische Programme wird man nach wie vor in Maschinensprache schreiben, da ein Compiler niemals so effiziente Maschinenprogramme erzeugen kann, wie ein Mensch sie schreibt. Doch nun kann man mit Basic zumindest grenordnungsmig die Geschwindigkeit der Maschinensprache erreichen.

1.1.2 Datentypen

Die geringe Geschwindigkeit des Basic-Interpreters resultiert nicht allein aus dem Interpreter-prinzip. Ein weiterer Grund ist die ausschlieliche Verwendung von Fliekommazahlen (zum Beispiel 1.2345 oder 572545.2647254). Solche Zahlen kann der Prozessor des C64 (das ist der fr smtliche Berechnungen und Operationen zustndige Baustein im C64) nur mit grter Mhe verarbeiten, weshalb es auch ziemlich langsam geht. Darum liegt es nahe, einfachere Zahlen zu verwenden, die der Prozessor leichter verarbeiten kann. Dies sind ganze Zahlen, also  vllig  normale  Zahlen   ohne  Nachkommastellen.   Wenn  man  sich  Basic-Programme 

ansieht, so wird man erkennen, da in den meisten Fllen auch keine Nachkommastellen ntig sind und man statt Fliekommavariablen Ganzzahlvariablen bentzen knnte. Solche Varia-blen gibt es tatschlich. Hin und wieder stt man in Basic-Programmen auf Variablen der Form A%. Diese Variablen knnen nur ganze Zahlen von -32768 bis +32767 annehmen. Man knnte folglich vermuten, da diese Zahlen schneller verarbeitet werden. Die Anweisung A% =B%+C% mte also schneller sein als A=B+C. Doch dem ist nicht so. Diese sogenann-ten Integer-Zahlen sind sogar langsamer, was jedoch nicht an den Zahlen selbst, sondern an der fehlenden effizienten Implementierung im Betriebssystern liegt.
Immerhin besitzt das Commodore-Basic damit bereits drei sogenannte Datentypen oder anders ausgedrckt: Basic bietet drei Mglichkeiten, Daten darzustellen. Dies ist zum einen die Dar-stellung als Fliekommazahlen, auch Real genannt (zum Beispiel A=1.2345), zum anderen die Darstellung als Integer-Zahlen (A%=l0000) und auerdem die Darstellung als Zeichenketten, die Strings genannt werden (zum Beispiel A$="Kuckuck"). Somit sind die drei in Basic ver-fgbaren Datentypen Real, Integer und String.
Aber zwei dieser Datentypen sind fr den Prozessor fast vllig ungeeignet (Real und String) und der dritte nur bedingt (Integer). Denn der Integer-Typ ist hufig unbrauchbar, wenn man mit Speicheradressen arbeitet, also mit PEEK und POKE, denn die Speicherzellen des C64 sind bekanntlich von 0 bis 65535 durchnumeriert und nicht von -32768 bis +32767 (in Kapitel 2 wird erklrt, warum beides eigentlich das gleiche ist). Darum liegt es nahe, weitere Daten-typen einzufhren, denen dieser Mangel nicht anhaftet. Diese Typen nenne ich Word und Byte. Eine Variable vom Typ Word kann ganze Zahlen von 0 bis 65535 annehmen und ist damit hervorragend auf den C64 und seinen Prozessor zugeschnitten. Noch besser pat der Typ Byte zum Prozessor, denn mit genau diesem Typ geht der 6510 (der Prozessor des    C64) ausschlielich um und dieser Typ pat exakt in eine der 65536 Speicherstellen des C64. Eine Variable dieses Typs kann ganze Zahlen von 0 bis 255 annehmen. Wenn diese Typen im Basic-Programm benutzt werden, kann man es in ein sehr schnelles Maschinenprogramm bersetzen.


1.2 Direktiven und Compilerbedienung

Es erhebt sich die Frage, wie man diese neuen Datentypen berhaupt verwenden kann, denn der Basic-Interpreter versteht sie ja nicht, und man mu dem Basic-Boss irgendwie mitteilen, da man sie verwenden will. Sie haben zum Beispiel folgendes Programm geschrieben:

10 for i=1024 to 2023
20 poke i,160: next i

Von smtlichen 65536 Speicherstellen, die der C64 besitzt, whlt sich das Programm die aus, die zwischen der 1024sten und der 2023sten liegen und fllt sie mit dem Wert 160. Weil aber genau dort der Bildschirmspeicher liegt, wird der Bildschirm langsam von oben nach unten gefllt (bei einigen C64 fllen sich nur die Textzeilen, doch das soll nicht weiter stren). Da man dies gerne etwas schneller und zackiger htte, wird man das Programm zum Beispiel mit dem Basic-Boss kompilieren.
Und genau das knnen Sie jetzt tun. Schalten Sie also Computer, Monitor und Laufwerk ein und tippen Sie dieses kleine Basic-Programm ab. Wenn Sie es mit RUN starten, knnen Sie sich von der nicht bermig hohen Geschwindigkeit berzeugen. Sodann sollten Sie es auf eine nicht allzu volle Diskette unter dem Namen TEST abspeichern. Anschlieend schieben Sie die Basic-Boss-Diskette in das Laufwerk und laden den Basic-Boss mit

LOAD "BASIC-BOSS",8

+---------------------------------------------------+
!                                                   !
!                                                   !
!                                                   !
!          *** Basic-Boss Compiler ***              !
!              Version 2.40                         !
!             (C) 1988 by Thilo Herrmann            !
!                                                   !
!          Quelldatei:                              !
!          _                                        !
!                                                   !
!                                                   !
!                                                   !
!                                                   !
+---------------------------------------------------+
Bild 1: So meldet sich der Basic-Boss nach dem Start


Nun kann es ohne Floppy-Beschleuniger etwas dauern (weshalb ich einen solchen grundstz-lich anraten wrde. Auf der Basic-Boss-Diskette finden Sie den Software-Speeder Ultraload Plus, der zwar einen Hardware-Speeder nicht ersetzen kann, aber trotzdem eine groe Hilfe darstellt. Bitte beachten Sie dazu Anhang E). Wenn wieder READY. erscheint, geben Sie RUN ein. Falls nun eine Textseite angezeigt wird, so knnen Sie diese mit einer Funktions-taste (<F1>, <F3>, <F5> oder <F7>) verschwinden lassen. Nun werden Sie nach der Quelldatei gefragt, worauf Sie TEST eingeben, nachdem Sie die Diskette eingelegt haben, auf der sich das Testprogramm befindet. Wenn Sie die Eingabe mit <RETURN> abgeschlos-sen haben, beginnt der Basic-Boss mit seiner Arbeit. Er liest das Basic-Programm von der Diskette und erzeugt ein Maschinenprogramm, das er unter dem Namen +TEST abspeichert (dieser Vorgang heit kompilieren). Falls zwischendurch ein Fehler auftaucht, unterbricht er seine Arbeit und wartet auf die Bettigung der <SHIFT>-Taste. Dann mssen Sie den Feh-ler verbessern und von vorne anfangen.

+--------------------------------------------------------+
!                                                        !
!        Datenbereich Schreiben ........                 !
!        Variablen anlegen .......................       !
!        .........                                       !
!                                                        !
!              ***** pass 2 *****                        !
!        Unterroutinen linken ....................       !
!        .........................................       !
!        .........................................       !
!        Datenbereich schreiben .........                !
!        routinen     :2049 -5845  , $0801-$16d5         !       
!        daten        :5845 -5904  , $16d5-$1710         !                            
!        programm     :5904 -11794 , $1710-$2e12         !                            
!        variablen    :11794-17958 , $2e12-$4626         !    
!        hilfsspeicher:17958-17994 , $4626-$464a         !
!        strings      :17994-40960 , $464a-$a000         !                            
!                                                        !
!          '<-' fuer Neustart, 'f1' fuer Reset,          !
!          alles andere fuer ende: _                     !
!                                                        !
+--------------------------------------------------------+
Bild 2: Ein Programm wurde erfolgreich kompiliert

Das fertige Maschinenprogramm (auch Compilat genannt) kann ganz normal mit 

LOAD "+TEST",8

geladen und mit RUN gestartet werden. Was Sie nun sehen, ist zwar um einiges schneller als das Basic-Programm, kann Sie aber vermutlich noch nicht so recht davon berzeugen, da der Basic-Boss sein Geld wert sein soll. Denn wenn Sie jeden beliebigen anderen Compiler verwenden, wird das Ergebnis in etwa genauso schnell sein. Warum? Die Antwort ist einfach: Es wurde wie blich mit Real-Variablen gerechnet und das braucht nun mal seine Zeit. Da aber eigentlich nur ganze Zahlen zwischen 0 und 65535 im Programm verwendet werden, wre der Datentyp Word viel sinnvoller. Doch wie teilt man dies dem Basic-Boss mit? Der Basic-Interpreter unterscheidet seine Datentypen (Real, String, Integer) anhand eines an den zweistelligen Variablennamen angehngten Sonderzeichens. Bei Real-Variablen wird nichts angehngt (zum Beispiel A), bei String-Variablen wird ein $ angehngt (zum Beispiel A$) und bei Integer-Variablen wird ein % angehngt (zum Beispiel A%). Der Basic-Boss macht das im Prinzip genauso. Man kann ihm aber auch auf andere Weise mitteilen, von welchem Typ eine Variable sein soll. Wenn zum Beispiel die Variable I des Beispielprogramms vom Typ Word sein soll, dann mu in der ersten Programmzeile der Befehl WORD I stehen, etwa so:

5 word i

Dieser Befehl ist eine Compilerdirektive. Sie teilt dem Compiler mit, wie er was zu machen hat (er hat die Variable I als Word-Variable zu betrachten). Eine solche Direktive beginnt grundstzlich mit dem -Zeichen. Der Compiler wrde das Programm so akzeptieren. Der Interpreter aber beschwert sich wenn man RUN eingibt. Zu Recht, denn WORD versteht er nicht. Darum ist es sinnvoll, ein REM vor den Befehl zu schreiben. Dann akzeptiert der Interpreter das Programm und fhrt es ordnungsgem aus - der Basic-Boss ignoriert die REM-Zeile allerdings. Damit dieses Dilemma behoben werden kann, gibt es eine Mglichkeit, einen REM-Befehl fr den Basic-Boss unwirksam zu machen. Man hngt ihm einfach einen Klammeraffen an:

5 rem@ word i

Dann ignoriert der Basic-Boss den REM-Befehl und wertet die Zeile wie normal aus. Der Interpreter dagegen erkennt den REM-Befehl und ignoriert darum den Rest. Wenn Sie nun Ihr Testprogramm laden, es um diese Zeile ergnzen, wieder auf Diskette abspeichern und kompilieren, dann werden Sie beim Maschinenprogramm (+TEST) eine starke Geschwindigkeitszunahme feststellen (dies ist nun in etwa die Geschwindigkeit von Petspeed mit Integer-Variablen).

1.2.1 Weitere Compilerdirektiven

Aber es geht noch schneller. Die FOR-NEXT-Schleife des Basic-Boss ist recht umstndlich und langsam gestaltet, weil es leider nicht anders geht, wenn sie genau dasselbe machen soll wie die des Interpreters. Man kann den Basic-Boss jedoch anweisen, es besser zu machen. Dies geschieht mit dem Befehl FASTFOR. Allerdings gibt es dann ein paar Einschrnkungen, die Sie sich in Kapitel 2 unter FASTFOR und SLOWFOR ansehen sollten.

Wenn Sie das Testprogramm folgendermaen umschreiben:

5 rem@ word i: fastfor
10 for i=1024 to 2023
20 poke i,160: next i

und kompilieren, dann lt sich rein optisch kein Unterschied mehr zur Maschinensprache feststellen. Auer FASTFOR sind besonders die Compilerdirektiven ALLRAM und OTHERON wichtig. ALLRAM weist den Basic-Boss an, den gesamten Speicher des C64 fr das Basic-Programm und die Variablen zu benutzen. Wenn OTHERON am Pro-grammanfang steht, dann sind an den SYS-Befehl zum Beispiel per Komma angehngte Para-meter erlaubt. Beide Befehle mssen wie blich am Programmanfang stehen. Fr nhere lnformationen sollten Sie in Kapitel 2 nachschlagen.

1.2.2 Beispiele

Damit Sie einen Eindruck von der Anwendung der neuen Datentypen und der Compiler-direktiven bekommen, zeige ich hier ein paar kleine Beispiele. Sie werden wie beschrieben kompiliert und ausgefhrt.

Beispiel 1:	10 rem@ byte a
		20 a=0
		30 poke 53280,a: a=a+l
		40 if a>15 then a=0
		50 goto 30

Die Bildschirmrandfarbe wird mit allen 16 Farben durchgeschaltet. Weil die Variable A nur Werte von 0 bis 15 annehmen darf, kann sie als Byte-Variable deklariert werden.

Beispiel 2:	10 rem@ byte a(,x: word #
		20 dim a(20)
		30 sum=0: mul=1
		40 for x=1 to 20
		50 input a(x)
		60 sum=sum+a(x): mul=mul*a(x): next x
		70 print sum, mul

In diesem Beispiel werden ber INPUT 20 Byte-Werte in das Array A( eingelesen und deren Summe und Produkt berechnet. Etwas seltsam mutet Zeile 10 an. Hier sieht man, wie Arrays (Felder) definiert werden. Dem Variablennamen wird einfach eine Klammer ange-hngt. Interessant ist auch der Befehl WORD #. Eine Variable # gibt es nicht und kann es nicht geben. Mit diesem Befehl werden vielmehr alle Variablen ohne Zusatz (zum Beispiel A, AB, COL und so weiter nicht aber A%, B$ und so weiter) als Word deklariert, falls sie nicht schon an anderer Stelle mit einem Variablentyp deklariert wurden. Variablen der Form A%, VOL% und so weiter werden mit WORD % als Word deklariert. Nun sind also SUM und MUL vom Typ Word und A( und X vom Typ Byte.

Beispiel 3:	10 rem@ allram: fastfor: word i: byte a(
		20 dim a(62000)
		30 for i=0 to 62000
		40 a(i)=100
		50 next i

Es wird dem Compiler per ALLRAM mitgeteilt, da er den gesamten Speicher benutzen soll. Dann wird ein Byte-Feld mit 62000 Elementen dimensioniert und mit 100 aufgefllt.
Nun sind Sie am Ende des ersten Kapitels angelangt. Sie knnen den Compiler jetzt bedienen und benutzen. Eine genaue Beschreibung des Basic-Boss, seiner Befehle und seiner Eigenschaften finden Sie in Teil 2 des Handbuchs.


---------------------------------- 
- Kapitel 2 - Bedienungshandbuch -
----------------------------------

Hier finden Sie eine genaue, vollstndige und systematische Beschreibung aller Eigenschaften und Befehle des Basic-Boss. Darum ist dieses Kapitel auch zum Nachschlagen sehr gut geeignet .

2.1 Die Bedienung des Basic-Boss

2.1.1 Der Inhalt der Basic-Boss-Diskette

0 38745 basic-boss m&t
193 "basic-boss"        prg  Hauptprogramm
0   "----------------"  del
9   "lies mich"         prg  Hinweise zur Diskette
0   "----------------"  del
4   "other"             prg  Beispiel fr OTHERON und OTHER (Basic)
12  "+other"            prg  Beispiel fr OTHERON und OTHER (Compilat)
0   "----------------"  del
1   "newcom.o "         prg  Basic-Erweiterung fr !COL (Start mit SYS 49152)
3   "newcom.src"	prg  Quellcode zur Basic-Erweiterung (als Textfile)
0   "----------------"  del
3   "errorread"         prg  ASCII-File-Lader Basic (nur als Compilat lauffhig)
13  "+errorread"        prg  ASCII-File-Lader (Compilat)
0   "----------------"  del
5   "preferences"	prg  Beispiel fr Standardeinstellungen
0   "----------------"  del
3   "bossdatei"         prg  Demonstriert die neuen Dateibefehle (Basic)
7   "+bossdatei"	prg  Demonstriert die neuen Dateibefehle (Compilat)
0   "----------------"	del
1   "bossdir"           prg  Zeigt Directory einer Diskette (Basic)
5   "+bossdir"          prg  Zeigt Directory einer Diskette (Compilat)
0   "----------------"  del
3   "ramrom"            prg  Kopiert den Grafikspeicher ins ROM und zurck (Basic)
6   "+ramrom"           prg  Kopiert den Grafikspeicher ins ROM und zurck (Compilat)
0   "----------------"  del
3   "ramload"           prg  Ldt ein File ins RAM (Basic)
13  "+ramload"          prg  Ldt ein File ins RAM (Compilat)
0   "----------------"  del
2   "ramdir"            prg  Quellcode zu r+ramdir und p+ramdir
5   "r+ramdir"          prg  Demonstriert ROUTSTART
1   "p+ramdir"          prg  Demonstriert PROGSTART
0   "----------------"  del
8   "autoboss"          prg  Demonstriert die Automatikfunktion
3   "auto.short"        prg  Kurzversion zum Einbinden in eigene Programme
0   "----------------"  del
8   "forreturn"         prg  Demonstriert FOR und RETURN bei falschem Einsatz (Basic)              
14  "+forreturn"        prg  Demonstriert FOR und RETURN bei falschem Einsatz (Compilat)           
0   "----------------"  del
7   "fastmuldiv"        prg  Schnelle Multiplikation und Division (Basic)
14  "+fastmuldiv"       prg  Schnelle Multiplikation und Division (Conipilat)
0   "----------------"  del
12  "break"             prg  Demonstriert auf fantastische Weise die Geschwindigkeitszunahme (Basic)           
27  "+break"            prg  Demonstriert auf fantastische Weise die Geschwindigkeitszunahme (Compilat) 
0   "----------------"  del
28  "demo"              prg  Demo zur Bildschirmausgabe (Basic)
38  "+demo"             prg  Demo zur Bildschirmausgabe (Compilat)
0   "----------------"  del
27  "labyrinth"         prg  Spiel (Basic)
59  "+labyrinth"        prg  Spiel (Compilat)
0   "----------------"  del
1   "fastdir"           prg  Schnelle Directory-Anzeige (Basic)
11  "+fastdir"          prg  Schnelle Directory-Anzeige (Compilat)
0   "----------------"  del
1   "bigarray"          prg  Demonstriert ALLRAM (Basic, nur kompiliert lauffhig)
4   "+bigarray"         prg  Demonstriert ALLRAM (Compilat)
0   "----------------"  del
37  "wayout"            prg  Spiel
0   "----------------"  del
9   "ultraload plus"    prg  Schnellader
1   "ultraload tool l"  prg
2   "ultraload tool 2"  prg
0   "----------------"  del
74 blocks free.


2.1.2 Bedienung des Compilers

Der Compiler wird ganz normal mit

LOAD "BASIC-BOSS",8

geladen und mit RUN gestartet. Wenn nun eine Textseite auf dem Bildschirm erscheint, knnen Sie diese mit einer Funktionstaste (<F1>, <F3>, <F5>, <F7>) verschwinden lassen (dies ist aber nicht unbedingt notwendig). Dann erscheint die Copyrightmeldung mit Ver-sionsnummer und der Benutzer wird nach der Quelldatei gefragt. Nun knnen Sie sich das Directory mit $ + <RETURN> anzeigen lassen oder sofort den Filenamen eingeben (bei bloem Drcken von <RETURN> wird er mit BASIC angenommen). Dann startet der Kompiliervorgang. Dieser besteht aus zwei Durchgngen (Pass 1 und Pass 2). Whrend Pass 1 wird die Quelldatei gelesen und die Verteilung der Adressen durchgefhrt. In Pass 2 wird das Basic-Programm noch einmal gelesen, damit daraus das Maschinenprogramm erzeugt werden kann, das gleichzeitig auf die Diskette geschrieben wird. Der Name des erzeugten Maschinen-programmes wird standardmig aus dem der Quelldatei gebildet, indem ihm ein + voran-gestellt wird. Wenn whrend des Kompilierens ein Fehler auftritt, dann wird die Nummer der fehlerhaften Zeile angezeigt. Hinter der Nummer ist ein Extrakt des bislang bearbeiteten Teils der aktuellen Zeile zu finden, damit der Fehler leichter lokalisiert werden kann. Dieser Extrakt besteht aus Doppelpunkten, Rechenoperatoren und einem Punkt fr jeden Befehl. Darunter steht die eigentliche Fehlermeldung hinter einer Fehlernummer, die das Auffinden des Fehlers im Fehlerverzeichnis (Kapitel 2.12.1) erleichtern soll. Der Compiler hlt bei jedem Fehler inne, damit dieser nicht ungesehen wieder vom Bildschirm verschwindet (es sei denn, es wurde der PROTOCOL-Befehl verwendet). Ein Drcken auf die <SHIFT>-Taste beendet diesen Starrezustand. Die Fehlermeldungen werden in beiden Durchgngen angezeigt und erscheinen darum hufig doppelt, was aber nicht weiter strt. Am Ende von Pass 1 meldet der Basic-Boss die nicht dimensionierten Arrays, die dann auf 10 dimensioniert werden. Abbrechen kann man den Kompiliervorgang mit <RUN/STOP> oder zur Not mit <RESTORE>. Nach Beendigung des Kompilierens zeigt der Basic-Boss die Adressen der verschiedenen Bereiche an und fordert den Benutzer auf, nun entweder <<->, <F1> oder irgendeine andere Taste zu drcken. Mit <<-> wird der Compiler neu gestartet, <F1> fhrt einen Reset aus. Jede andere Taste beendet den Basic-Boss ohne Reset. Der Basic-Boss bietet auerdem noch eine Speicherfunktion, mit der man ihn abspeichern kann. Wenn man bei der Eingabe der Quelldatei dem Namen einen Stern vorausstellt (*), dann wird der Compiler unter diesem Namen auf Laufwerk 8 geschrieben. Der Klammeraffe kann hier brigens unbedenklich angewandt werden (zum Beispiel *@:NEUER BOSS).


2.1.3 Automatikmodus

Wenn man sehr oft kompiliert, zum Beispiel wenn ein Programm nur als Compilat lauffhig ist, dann wird man sehr oft immer dasselbe eintippen. Es wre also besser, wenn man die Bedienung des Basic-Boss automatisieren knnte. Eine solche Mglichkeit gibt es in der Tat. Man kann dem Compiler verschiedene Informationen bermitteln. Sie stehen im Kassettenpuffer ab Speicherstelle 900. Wenn er gestartet wird, dann untersucht der Basic-Boss zunchst die Speicherstellen 1000 und 1001. Findet er dort die Werte 123 und 234, so nimmt er an, da der Benutzer den Automatikmodus wnscht. Aus 1002 holt er sich dann die Gertenummer fr die Quelldatei, aus 1003 die zugehrige Sekundradresse. In 1004 erwartet er die Lnge des Dateinamens und ab 1005 den Filenamen selbst. Das so beschriebene Programm wird dann kompiliert. Wenn das Kompilieren beendet ist, holt sich der Basic-Boss eine Gertenummer aus 900, eine Sekundradresse aus 901, eine Namenlnge aus 902 und einen Namen ab 903. Dann veranlat er, da das so beschriebene Programm nachgeladen und gestartet wird und beendet sich selbst. Das nachgeladene Programm kann zum Beispiel das Compilat sein, das dann sofort ausgetestet werden kann.
Allerdings ist es nicht etwa einfacher, sondern wesentlich umstndlicher, dem Basic-Boss auf diese Weise den Namen der Quelldatei mitzuteilen, da es viele POKEs erfordert. Darum sollte man fr die POKErei ein kleines Programm einsetzen, das die Speicherstellen ab 900 richtig setzt und anschlieend den Basic-Boss ldt. Man kann sich noch mehr Arbeit sparen, wenn man dieses kleine Programm in das zu kompilierende Basic-Programm integriert, es um ein paar Diskettenbefehle und einen SAVE-Befehl erweitert und mit IGNORE und USE klammert, damit es das Compilat nicht sinnlos verlngert. Dann braucht man es nur noch mit RUN Startzeile aufzurufen, um das Quellprogramm automatisch abspeichern und kompilie-ren zu lassen, wobei das Compilat dann ebenfalls automatisch geladen und gestartet wird. Ein Beispielprogramm, das die Vorgehensweise veranschaulicht, ist auf der Programmdiskette unter dem Namen AUTOBOSS zu finden. Das Programm basiert auf einer kleinen Basic-Routine, die isoliert und gepackt in AUTO.SHORT steht und darum sehr leicht in eigene Programme eingebaut werden kann.



2.2. Allgemeines

2.2.1 Compilerdirektiven

Der Basic-Boss wird fast ausschlielich mittels Compilerdirektiven gesteuert. Dies sind Befehle, die wie andere auch im Basic-Programm stehen. Sie erfllen aber keine normale Funktion wie PRINT oder POKE, sondern teilen dem Compiler mit, was er zu tun hat. Alle Compiterdirektiven beginnen mit dem Pfund-Zeichen (), das auf der C64/C128-Tastatur mit einem einzigen Tastendruck (Taste zwischen <-> und <HOME> erreichbar ist. Dann folgen der Befehlsname und danach eventuell einige Parameter.

2.2.2 Zahlensysteme

Zahlen akzeptiert der Basic-Boss sowohl in dezimaler als auch in hexadezimaler Form, wobei hexadezimale Werte mit einem Dollarzeichen ($) eingeleitet werden. Darber hinaus knnen sie beliebig lang sein und man braucht auf zufllig entstehende Basic-Befehle keine Rcksicht zu nehmen. So ist zum Beispiel folgendes mglich: PRINT $F, $DEF, $123456789ABCDEF oder GOTO $1E. Kommazahlen knnen nur in der dezimalen Form angegeben werden.

2.2.3 Inaktivierung von REM-Befehlen

Der Basic-Boss reagiert bei einem REM-Befehl genauso wie der Interpreter: Er ignoriert den Rest der Zeile. Dies kann man aber verhindern, wenn man direkt hinter den REM-Befehl einen Klammeraffen (@) schreibt. Dann untersucht der Compiler den Zeilenrest als wre das REM nicht vorhanden. Hinter ein solcherart deaktiviertes REM kann man aufgrund einer Eigenart des Interpreters (Tokenisierung) aber nur Compilerdirektiven und Compilerbefehle schreiben - Basic-Befehle werden dort nicht erkannt. Die Deaktivierung von REM-Befehlen ist ntzlich, um Compilerdirektiven vor dem Interpreter zu verbergen, damit sich dieser beim Austesten eines Basic-Progranims nicht mit einer Fehlermeldung beschwert, wenn er auf eine Direktive aufluft.

2.2.4 Das Compilat

Das Compilat wird vom Basic-Boss normalerweise mit einer SYS-Zeile versehen als ganz normales Programm abgespeichert. Es kann dann wie ein Basic-Programm geladen und gestartet werden. Man kann es aber auch in einen bestimmten Speicherbereich legen und aus einem Basic-Programm heraus mit SYS Startadresse aufrufen (siehe unter Kapitel 2.4.3 ROUTSTART). Das Basic-Programm arbeitet nach Ablauf des Compilats einwandfrei weiter, da alle fr Basic wichtigen Speicherstellen nach Beendigung des Compilats wieder restauriert werden.

2.3 Datentypen

Das System der Datentypen ist wohl der bedeutsamste Aspekt des Basic-Boss. Er verfgt ber die Typen Byte, Integer, Word, Real und String. Auerdem gibt es noch den Typ Boolean, der jedoch ziemlich unwichtig ist und in den meisten Fllen wie Byte behandelt wird. Jede Variable im Basic-Programm kann einen dieser Typen annehmen.

2.3.1 Die Wertebereiche der Typen

Real und String sind die in Basic meistbenutzten Datentypen. Ihr Wertebereich drfte Ihnen bekannt sein. Whrend man beim Stringtyp schlecht vom Wertebereich sprechen kann, da er Zeichenketten von (fast) beliebiger Lnge beschreibt, lt sich das beim Realtyp besser ange-ben. Er beschreibt Kommazahlen im Bereich von +-2.93873588 * 10-39 bis +-1.70141183 * 10-38.  Beim Integer-Typ fllt der Wertebereich wesentlich einfacher aus:  Er reicht von  -32768 bis +32767. Word fat Werte von 0 bis 65535 (= 216-1) und Byte von 0 bis 255           (= 28-1). Die Typen Byte, Word, Integer und Real werden aufgrund ihres Wertebereiches numerisch genannt. Boolean kann eigentlich nur die Werte 0 und -1 annehmen. Dieser Typ wird fr Entscheidungen bentigt.


2.3.2 Die Deklaration

Der Interpreter erkennt den Datentyp einer Variablen am Zusatz hinter dem Variablennamen. Wenn kein Zusatz folgt, ist fr ihn die Variable vom Typ Real (Fliekomma). Wenn % folgt, schliet er auf eine Integer-Variable (zum Beispiel A%) und bei $ auf eine String-Variable (zum Beispiel B$). Der Basic-Boss hlt sich standardmig auch an diese Regel. Man kann den Variablen aber auch andere Typen zuweisen. Dies geschieht mit einer Compilerdirektive. Diese sieht allgemein so aus:
Typ Variablenliste
Anstelle von Typ kann jeder der genannten Typen stehen (Boolean, Byte, Integer, Word, Real, String). Die Variablenliste besteht aus einem oder mehreren mittels Komma getrennten Variablennamen. Ein Beispiel:

10 byte a,b%,c
20 word co

Hier werden die Variablen A, B% und C zu Byte-Variablen und die Variable CO zur Word-Variable erklrt. Man kann die Variablen aber auch anhand ihrer Zustze deklarieren. Wenn man zum Beispiel alle Variablen der Form A% als Word-Variablen deklarieren will, dann gengt es, statt der mglicherweise sehr vielen Variablennamen in der Deklaration einfach % zu benutzen. Konsequenterweise kann man auch die Variablen der Form A$ anders deklarieren, indem man $ benutzt. Besonders wichtig ist die Mglichkeit, den Variablen ohne Zusatz einen bestimmten Typ zuzuweisen. Dies ist mit dem Doppelkreuz mglich (#). Die Deklaration von Variablen mittels ihres Namens hat allerdings Vorrang vor der Deklaration anhand des Zusatzes. Man kann folglich zum Beispiel smtliche Variablen mit dem Zusatz % als Word definieren und trotzdem der Variable X% den Typ Byte zuweisen. Die Reihenfolge der Deklarationen ist dabei grundstzlich ohne Bedeutung.

Beispiele:	10 byte #,x%: word a,b,%,c

Es werden die Variablen A, B und C und alle mit dem Zusatz % als Word deklariert. Allen Variablen ohne Zusatz und der Variable X% wird der Typ Byte zugewiesen. Da die ausdrckliche Deklaration Vorrang hat, ist X% vom Typ Byte und nicht vom Typ Word, ebenso wie A, B und C vom Typ Word und nicht vom Typ Byte sind. Die hohe Flexibilitt kann man natrlich auch mibrauchen:

10 rem@ string #,a%: word $: real %
20 x$=2: y$=3
30 a="hallo": a%="lollipop"
40 b%=1.23456
50 print mid$(a,x$,y$),a%,b%

Der Interpreter steigt mit einem Type Mismatch aus, aber der Compiler schluckt das Pro-gramm anstandslos.

2.3.3 FAST-Variablen

In der Programmiersprache C auf dem Amiga oder dem Atari ST gibt es Registervariablen, die der C-Compiler in den Registern des Hauptprozessors abzulegen versucht, damit sie besonders schnell bearbeitet werden knnen. Beim Prozessor des C64/C128 wre dies ein hoffnungsloses Unterfangen, da dieser nur sehr wenige sehr kleine Register besitzt, die er darum andauernd anderweitig bentigt. Aber er besitzt die angenehme Eigenschaft, da er die untersten 256 Byte seines Adrebereichs (die sogenannte Zero-Page) besonders effizient bearbeitet. Darum erlaubt der Basic-Boss, ein paar Variablen vom Typ Byte, Word oder Integer (keine Arrays) in diesem Bereich zu plazieren. Bei normalen Operationen bringen solche Variablen einen Geschwindigkeitsgewinn von zirka 25%. Der Speicherplatzverbrauch schrumpft um etwa ein Drittel. Drastischer wirken sich FAST-Variablen bei PEEK und POKE aus. Wenn fr die Adresse eine solche Variable statt einer normalen Variable verwendet wird, dann werden diese Operationen um den Faktor drei beschleunigt und bentigen nur ein Drittel des Programmspeichers. Darum sollte man FAST-Variablen vor allem hier anwenden. Bei der Deklaration einer FAST-Variablen wird dem Variablennamen einfach ein Gleichheitszeichen angefgt, dem FAST folgt (zum Beispiel WORD A=FAST, B=FAST). Dabei ist allerdings zu beachten, da nur vier Byte fr FAST-Variablen zur Verfgung stehen. Es knnen also nur zwei Word-Variablen mit FAST deklariert werden oder vier Byte-Variablen
 oder eine Word-Variable  und  zwei Byte-Variablen.  Dabei werden die Adressen von 251 bis 254 benutzt.  Achtung: Fast-Variablen werden zu Programmbeginn nicht wie alle anderen auf 0 gesetzt. Darum mssen Sie vom Programmierer selbst initialisiert werden.

+---------------------------------------------------+
!                                                   !
!                                                   !
!          *** Basic-Boss Compiler ***              !
!              Version 2.40                         !
!             (C) 1988 by Thilo Herrmann            !
!                                                   !
!          Quelldatei:                              !
!          test 57                                  !
!                                                   !
!          20 .,,                                   !
!          62/zuviel 'fast'-variablen               !
!                                                   !
!                                                   !
+---------------------------------------------------+
Bild 3: Fehlermeldung 62: Es wurden zu viele FAST-Variablen deklariert

2.3.4 Adrefestlegung bei Variablen

Normalerweise bestimmt der Basic-Boss die Adresse einer jeden Variable selbst. Doch auch Sie knnen die Adresse einer Variable bestimmen, vorausgesetzt, sie ist numerisch. Dies geschieht hnlich wie bei der FAST-Deklaration, nur mu anstelle von FAST eine Adresse angegeben werden, zum Beispiel so: WORD A=49152. Auch Arrays knnen so deklariert werden (BYTE SCREEN=1024). Nun knnen Sie zum Beispiel sehr einfach das Register fr die Hintergrundfarbe ansprechen, wenn Sie COL so deklarieren: BYTE COL=53281. Auerdem kann man irgendwelche Variablen von Maschinenprogrammen ansprechen, indem man eigene Variablen auf die betroffenen Speicherstellen legt. Ein weiterer Anwendungsbereich ist die bergabe von Werten an Programme, die nachgeladen werden und die gleichen Deklarationen beinhalten. Auerdem kann man weitere FAST-Variablen kreieren, indem man normale Variablen auf die Zero-Page-Adressen von $2B bis $2E legt, die vom Compilat sonst nicht angerhrt werden. In der Tat ist die Anweisung WORD A=$FB hinsichtlich A identisch mit WORD A=FAST. Ebenso wie FAST-Variablen werden an eine bestimmte Adresse gelegte Variablen nicht initialisiert und beinhalten am Programmbeginn irgendeinen zuflligen Wert.

2.3.5   Vor- und Nachteile der Datentypen und Verwendung 
	des richtigen Typs

Man kann sich fragen, wozu denn unbedingt fnf Datentypen ntig sind. Die Antwort ist einfach: Die Verwendung der richtigen Datentypen erhht die Effizienz eines Programms. Es wird also schneller und krzer. Wesentlich fr die Entscheidung des richtigen Datentyps ist der gewnschte Wertebereich. Auerdem sollte man vorzugsweise immer den Datentyp benutzen, der am wenigsten Speicherplatz verbraucht und am schnellsten ist. Hierfr gilt:

-  Byte ist am schnellsten und verbraucht am wenigsten Variablenspeicher (genau ein Byte)
    und Programmspeicher. 
-  Word ist etwa halb so schnell und verbraucht genau doppelt so viel Variablenspeicher 
    (zwei	Byte) und meist mehr als doppelt so viel Programmspeicher.
-  Integer ist bei vielen Operationen genauso schnell wie Word und verbraucht genauso
    viel Variablenspeicher. Bei Vergleichsoperationen ist Integer aber um einiges langsamer
   (auer bei = und <>).
-  Real ist wesentlich langsamer als die oben beschriebenen Typen und verbraucht ganze
   fnf Byte Variablenspeicher, aber aufgrund einer speziellen Berechnungsmethode etwas
   weniger Programmspeicher als Word.
-  String ist ein extrem aufwendiger Datentyp und darum auch nicht allzu schnell. Doch
   die Bearbeitung ist dennoch um einiges schneller als beim Basic-Interpreter, nicht nur
   was die Garbage-collection anbetrifft. Der Platzbedarf ist mit dem Realtyp vergleichbar.
   Hinzu kommt noch der Platzbedarf des Stringtextes.

Hieraus geht hervor, da Sie nach Mglichkeit den Bytetyp benutzen sollten, ansonsten Word, sonst Integer und nur wenn es unbedingt ntig ist Real. Wenn Sie zum Beispiel die Variable I ausschlielich zur Stringverarbeitung in der Art A$=LEFT$(B$,I) benutzen, dann sollten Sie I als Byte-Variable deklarieren, da fr I nur Werte zwischen 0 und 255 sinnvoll sind. Wenn eine Variable X aber in der Form POKE X,0 benutzt wird, sollte sie als Word definiert sein. Weitere Informationen zur Steigerung der Effizienz von Programmen finden Sie unter Effiziente Programme (Kapitel 2.8). Die bei den Befehlen und Funktionen erwarteten Typen knnen Sie unter Typen bei Operationen, Funktionen und Befehlen (Kapitel 2.3.9) nachlesen.

2.3.6 Umwandlungen von Datentypen

Da die verschiedenen Datentypen miteinander in Konflikt geraten knnen, mssen sie hin und wieder ineinander umgewandelt werden. Dabei kann man zwei Arten der Umwandlung unterscheiden.

2.3.6.1 Umwandlungen mit Verlust

Sehen Sie sich einmal folgendes Programm an:

10 rem@ real a: byte b
20 a=97.374546
30 b=a
40 print a,b

Unter dem Interpreter luft dieses Programm einwandfrei. Dort wird ja auch nur mit Real-Variablen gerechnet. Beim Compiler mte es aber Probleme geben, denn in Zeile 30 wird eine Real-Variable einer Byte-Variable zugewiesen. Dies ist rein technisch eigentlich vllig unmglich, denn man kann keinen fnf Byte groen und sehr genauen Real-Wert einer primitiven Byte-Variable zuweisen, die doch nur ganze Zahlen zwischen 0 und 255 fat. Aber der Basic-Boss kompiliert dieses Programm ohne Schwierigkeiten. Wenn man es startet, erkennt man das Prinzip: Es werden einfach smtliche Nachkommastellen abgeschnitten und aus 97.374546 wird schlicht 97. Doch Real-Zahlen knnen auch grer sein. Wenn einer Byte-Variable nun zum Beispiel 258.123 zugewiesen wird, reicht das Abschneiden der Nachkommastellen nicht aus. Zustzlich wird die Zahl dann einfach kleiner gemacht, indem grundstzlich nur der Rest einer Division durch 256 genommen wird. Einfacher erklrt: Es wird so oft 256 abgezogen, bis das Ergebnis in die Byte-Variable pat. In diesem Fall wrde die Byte-Variable nach der Zuweisung den Wert 2 enthalten (258-256). hnlich ist es bei den anderen Umwandlungen. Wenn Real nach Word oder Integer gewandelt werden soll, werden ebenfalls die Nachkommastellen abgeschnitten und nur der Rest der Division durch 65536 bernommen. Dies verwundert etwas bei Integer, da dieser Typ einen ganz anderen Wertebereich hat, doch mehr dazu spter. Wenn Word oder Integer nach Byte gewandelt werden, wird wieder nur der Rest einer Division durch 256 bernommen (anders ausgedrckt: Es wird schlicht das Highbyte weggelassen).

2.3.6.2 Umwandlungen ohne Verlust

Bei den bisher beschriebenen Umwandlungen wurde immer etwas verloren beziehungsweise die Genauigkeit nahm ab. Es gibt jedoch noch eine Reihe anderer Umwandlungen, die diesen Nachteil nicht aufweisen. Dies sind Umwandlungen von Byte nach Word, von Byte nach Inte-ger oder von Word nach Real. In diesen Fllen ist der Wertebereich des Quelltyps immer ganz im Wertebereich des Zieltyps enthalten. Die Umwandlung von Boolean ist brigens ebenfalls verlustlos.


2.3.7 Wertigkeit der Typen und deren Verarbeitung

10 rem@ word w: real r
20 r=1.5: w=4
30 print r*w

Wenn dieses Programm unter dem Interpreter mit RUN gestartet wird, dann erscheint das Ergebnis 6 auf dem Bildschirm. Was auch sonst. Bei diesem Beispiel tritt fr den Compiler aber wieder ein Typkonflikt auf. In Zeile 30 soll die Real-Variable R mit der Word-Variable W multipliziert werden. Der Basic-Boss kann aber keine Variablen von unterschiedlichem Typ verknpfen. Die Multiplikation kann folglich erst durchgefhrt werden, wenn eine der beiden Variablen in den Typ der anderen umgewandelt wurde. Der Compiler kann also zum Beispiel den Inhalt von R in den Word-Typ umwandeln, um dann zu multiplizieren. Er wrde den Kommawert 1.5 in einen Word-Wert umwandeln und deshalb die Kommastellen abschneiden. Er erhielte dann 1. Dann wrde er diese l mit 4 multiplizieren. Das Ergebnis wre 4 und offensichtlich falsch. Er sollte also besser den Inhalt der Word-Variablen W in eine Real-Zahl umwandeln. Dann wrde der Word-Wert 4 zum Real-Wert 4 und ergbe mit 1.5 multipliziert das korrekte Ergebnis 6. Genau dies macht der Basic-Boss. Wenn er die Wahl hat, wandelt er immer den Typ mit dem kleineren Wertebereich in den mit dem greren um. Dies entscheidet er anhand der Wertigkeit eines Typs. Am geringsten ist die Wertigkeit von Boolean und Byte. Dann folgt Integer, vor Word und vor Real. Bei einem Typkonflikt entscheidet sich der Basic-Boss bevorzugt fr den Typ mit der hheren Wertigkeit. Dessen sollten Sie sich immer bewut sein, wenn Sie einen Typenkonflikt provozieren. Ein weiteres Problem:

10 rem@ word wl,w2: real r
20 w1=3: w2=2
30 r=w1/w2: print r,w1/w2

In Zeile 30 soll das Ergebnis von W1/W2 der Real-Variable R zugewiesen werden. Wl und W2 sind beide vom Typ Word, weshalb die Division in eben diesem Typ durchgefhrt werden knnte. Doch das Ergebnis von W1 durch W2 wre nicht 1.5, sondern 1, weil nicht mit Real-Zahlen gerechnet wurde. Dieses falsche Ergebnis wrde dann R zugewiesen. Um dies zu verhindern, rechnet der Basic-Boss bei Zuweisungen grundstzlich mindendestens mit dem Zieltyp, in diesem Fall Real. Darum stimmt auch der erste vom PRINT-Befehl in Zeile 30 ausgegebene Wert. Der zweite stimmt beim Compilat aufgrund der aufgezeigten Problematik nicht ganz, da es beim PRINT-Befehl keine Zielvariable gibt (darum kann der Mindesttyp fr PRINT mit PRINTTYPE eingestellt werden).


2.3.8 Der diffuse Wertebereich von Byte, Word und Integer

2.3.8.1 Byte und Word

Es wurde bisher behauptet, eine Byte-Variable knne nur Werte im Bereich von 0 bis 255 annehmen. Doch wie sieht es damit aus:

10 rem@ byte a,b
20 a=5: b=-1
30 a=a+b
40 print a,b

Zum Wert der Variablen A (5) wird der Wert von B (-1) hinzuaddiert. Das Ergebnis mte 4 sein. Und siehe, es funktioniert. A wird auch vom Compilat mit 4 angezeigt. Besonders interessant ist der Inhalt von B, denn -1 kann es nicht sein, weil dies nicht in den Wertebereich pat. B wird in Zeile 40 mit 255 angezeigt. Doch warum 255? -1 ist um 1 kleiner als 0. Also mu man von 0 einen Schritt zurckgehen. Dazu ein anderes Beispiel: Wenn 10 um 1 vermindert wird, so erhlt man 9. Nehmen wir einmal an, jemand sieht nur die hinterste Stelle und kennt darum nur die Zahlen von 0 bis 9. Wenn er die Ziffer 10 beobachtet, sieht er also nur die 0. Man sagt ihm, es werde jetzt 1 abgezogen und pltzlich wird aus der 0 eine 9. Als die Zahl am Ende des ihm bekannten Wertebereichs war (bei 0), sprang sie nach Abzug von 1 wieder auf den hchsten Wert des Wertebereichs (9). Genau so ist es beim Byte-Typ. Wenn man vom kleinsten Wert des Wertebereichs eine 1 abzieht, springt die Zahl auf den hchsten Wert. So erklrt sich die 255. Doch warum wird aus der 5 eine 4. Ganz einfach: Zur 5 wurde 255 addiert (in Zeile 30) und das Ergebnis wre 260. Da dies auerhalb des Wertebereichs von Byte liegt, kann man so oft 256 abziehen, bis man sich wieder im Wertebereich befindet. Und 260-256 ergibt 4, Folglich kann man auch bei Byte in begrenztem Mae mit Vorzeichen rechnen. hnliches gilt fr den Datentyp Word. Fr ihn ist -1 identisch mit 65535. Doch Vorsicht! 
Nicht alle Operationen lassen dies zu. Es funktioniert bei Addition und Subtraktion und sogar bei der Multiplikation, nicht aber bei der Division. Es funktionieren = und <>, nicht aber <, <=, >, >=. Im Typ Byte ist -1 definitionsgem grer als 100, denn -1 ist in diesem Typ identisch mit 255. Darum sollte man in diesen Fllen vorzugsweise mit = und <> arbeiten.

2.3.8.2 Der Integer-Typ und seine hnlichkeit zu Word

Keine solchen Probleme hat man beim Integer-Typ. Er kann Werte zwischen -32768 und +32767 annehmen. In diesem Bereich arbeiten alle Operationen einwandfrei und erwartungs-gem. Dies gilt auch fr <, <=, > , >= (diese Operationen sind im Integer-Typ aber relativ langsam) und die Division. Da dieser Typ ebenfalls wie Word genau zwei Byte an Speicher belegt, liegt die Vermutung nahe, da sie sich irgendwie hneln. Und in der Tat sind sie sich nicht nur hnlich, sondern eigentlich identisch. Denn ob man einer Integer-Variablen den Wert -1 zuweist, oder einer Word-Variablen ist egal. In beiden Fllen steht im Speicher exakt dasselbe. Wodurch unterscheiden sich diese Typen dann berhaupt? Nur durch die Ope-rationen <, <=, >, >=, die Division und die Umwandlung in einen String (bei PRINT oder STR$) oder nach Real. Ansonsten sind diese Typen vllig gleich! Damit ist zum Beispiel auch I=55296: POKE I,1 mit I als Integer-Variable mglich. Da der Datentyp Word der wichtigere ist, wird bei einem Typkonflikt brigens willkrlich nach Word gewandelt. Eine solche Umwandlung von Integer nach Word oder von Word nach Integer verbraucht aber weder Zeit noch Speicher, da letztendlich keinerlei Umwandlung stattfindet.

2.3.9 Typen bei Operationen, Funktionen und Befehlen

Die von Operationen, Funktionen und Befehlen erwarteten und gelieferten Typen sollte man kennen, schon allein deshalb, damit keine unntigen Umwandlungen vorgenommen werden, die Zeit und Speicher verschwenden.


2.3.9.1 Typen bei Befehlen

Viele Befehle des Basic V2 erwarten einen oder mehrere Parameter. Diese Parameter sind beim Interpreter immer vom Typ Real. Der Compiler aber erwartet einen bestimmten zweckmigen Typ. Wenn der Benutzer einen Ausdruck eines anderen Typs angibt, so wird eine Umwandlung vorgenommen. Wenn ein bestimmter Typ erwartet wird, dann ist dieser Typ hier einfach an die Stelle des Parameters gesetzt.

2.3.9.2 Speicherbefehle

POKE		 Word, Byte
SYS		 Word

2.3.9.3 Befehle zur Programmsteuerung

GOTO	Number
GOSUB	Number
ON Byte GOTO	Number
ON Byte GOSUB	Number
Number ist eine Zahl vom Typ Word und keine Variable.

FOR N=A TO B STEP C 
N mu eine Variable des Typs Byte, Word, Integer oder Real sein (also numerisch). A,B, und C sollten vom selben Typ sein.

NEXT N 
N mu dieselbe Variable wie bei FOR sein.

IF A THEN ...	Number
IF A GOTO 	Number
IF A THEN 	Number
A kann ein Ausdruck von jedem beliebigen Typ sein.

2.3.9.4 Ein- und Ausgabe (im weiteren Sinne)

PRINT   A
INPUT   V
GET V und READ V
OPEN    	Byte, Byte, Byte, String
CLOSE   	Byte
PRINT#  	Byte, A
GET#    		Byte, V
INPUT#  	Byte, V
LOAD    	String, Byte, Byte
SAVE    	String, Byte, Byte
CMD     		Byte
A kann ein Ausdruck von jedem Typ sein. 
V ist eine Variable von beliebigen Typ.

2.3.9.5 Weitere Befehle

DIM     V 	(Number,...)
DATA    	D, D, D
RESTORE 	Word
WAIT    	Word, Byte, Byte
Die Daten D sind normale Zeichenketten oder Zahlen

2.3.9.6 Typen bei Funktionen

Funktionen unterscheiden sich von Befehlen dadurch, da sie Ergebnisse liefern. Auch diese Ergebnisse sind von einem bestimmten Typ. SIN, COS, TAN, ATN, LOG, EXP, RND, SQR, USR erwarten jeweils eine Real-Zahl und liefern auch eine solche (zum Beispiel Real=SIN(Real). SGN, INT, ABS lassen sich auf alle numerischen Typen anwenden. Das Ergebnis ist jeweils eine Zahl in diesem Typ.

Byte   = PEEK (Word)
Word = FRE (X)
Byte   = POS (X)
X ist vllig unbedeutend (Dummy-Parameter)

Byte   = ASC (String)
Real   = VAL (String)
String = CHR$ (Byte)
String = STR$ (A)
A ist ein beliebiger numerischer Ausdruck

Byte   = LEN (String)
String = LEFT$ (String, Byte)
String = RIGHT$ (String, Byte)
String = MID$ (String, Byte, Byte)

In diese Sparte passen auch Arrays. Sie erwarten Parameter vom Typ Word und liefern den Typ der Array-Variable. Bei eindimensionalen Arrays vom Typ Byte, Boolean, Word oder Integer wird auch der Parametertyp Byte erwartet, falls die Dimension des Arrays entsprechend klein ist (dann kann eine effizientere Adressierungsart angewandt werden).

2.3.9.7 Typen bei Operationen

Die folgenden Operatoren liefern denselben Typ, mit dem sie versorgt werden: Plus (+), Minus (-), AND und OR verarbeiten smtliche numerischen Typen. Mal (*) und Durch (/) verarbeiten Word, Integer und Real. Potenzieren kann man nur mit Real-Zahlen. Die Negation (-) und NOT verarbeiten alle Typen von Byte bis Real. AND, OR und NOT verarbeiten ebenfalls alle numerischen Typen und zustzlich noch Boolean. Es gibt auch eine Gruppe von Operatoren, die nicht den Typ liefern, den sie erwarten. Dies sind die Vergleichsoperatoren. Sie verarbeiten alle Typen (auch String) und liefern grundstzlich den Typ Boolean.

2.3.9.8 Typen der Systemvariablen

Der C 64 kennt die Systemvariablen TI, Tl$ und ST. TI ist vom Typ Real, TI$ vom Typ String und ST wird als Byte behandelt.

2.3.10 Der Datentyp Constant

Pascal und Modula bieten dem Programmierer die Mglichkeit, schwer interpretierbare Zahlen durch sinnvolle Namen zu ersetzen. Diesen Vorzug besitzt Basic nicht. Hier mu man stattdessen Variablen verwenden, wenn man keine Zahlen schreiben will . Das ist besonders bedauerlich, weil die Effizienz der Compilate bei Verwendung von konstanten Zahlen statt Variablen deutlich zunimmt. Der Code wird schneller und krzer. POKE COL,1 ist kompiliert zum Beispiel drei mal so lang und langsam wie POKE 53281,1. Darum habe ich den Basic-Boss um den Datentyp Constant bereichert. Eine Konstante wird wie jede andere Variable deklariert, wobei als Datentyp CONSTANT anzugeben ist. Es knnen Variablen der Form A, A% und A$ als Konstanten deklariert werden. Wie jeder anderen Variablen kann einer Konstanten im Programm ein Wert zugewiesen werden, indem man hinter den Variablennamen ein Gleichheitszeichen setzt, dem der gewnschte Wert folgt. Auf diese Weise wird die Kompatibilitt zum Interpreter gewahrt. Allerdings darf einer Konstanten nur ein einziges Mal ein Wert zugewiesen werden. Dies mu zudem vor ihrer Benutzung geschehen (also in einer frheren Programmzeile). Darum sollte man den Konstanten am besten am Programmanfang ihren Wert zuweisen. Dann ist die Konstante einsatzbereit. Sie kann im nachfolgenden Programm beliebig oft verwendet werden und wird dann jeweils durch den ihr zugewiesenen Wert ersetzt.

Ein Beispiel: 	10 rem constant col
          	20 col=53281
	        30 poke col,1

Dieses Programm ist aus der Sicht des Compilers exakt identisch mit:

30 poke 53281,1
Im ersten Programm ist die Zeile 30 aber wesentlich besser lesbar. Sie sollten sich bei der Verwendung von Konstanten darber im klaren sein, da diese von Haus aus keinen bestimmten Typ besitzen. Bei der Zuweisung eines Wertes an eine Konstante wird eigentlich nur der Text gelesen und gemerkt. Darum kann man einer Konstante alles mgliche zuweisen (zum Beispiel C="HALLO" oder C=4+1.23*5). Wenn diese Konstante spter im Programmtext auftaucht, dann wird der ihr zugewiesene Text geklammert und eingesetzt. Erst dann wird der Ausdruck ausgewertet. Wenn sich im Konstantentext Fehler befanden, so werden diese folglich erst jetzt gemeldet. Die Klammerung ist brigens notwendig. Man nehme an, C sei eine Konstante und sei so bestimmt worden: C=l+2. Wenn spter der Ausdruck A=C*3 auftaucht, dann wrde sich ohne Klammerung A=1+2*3 ergeben und das Ergebnis wre 7. Gemeint war aber A=(1+2)*3, was 9 ergibt. Konstanten knnen geschachtelt werden. Wenn zum Beispiel VIC und SPR Konstanten sind, dann lassen sich diese auch so belegen: VIC=53248: SPR=VIC+21. Wenn SPR im folgenden Programmtext verwendet wird,   dann wird zunchst SPR ersetzt,   dann VIC und es ergibt sich fr  POKE
SPR,255 der Ersetzungstext POKE((53248)+21),255.

2.4 Beschreibung der Direktiven

Die Einstellungen und Eigenschaften des Compilers werden ausschlielich ber Compiler-direktiven verndert, die im Basic-Text des Quellprogramms stehen. Dies erhht die Flexibili-tt und den Bedienungskomfort des Basic-Boss, da man programmspezifische Parameter nicht wie bei manchen anderen Compilern bei jedem Compilerlauf neu einstellen mu. Bei der Anwendung von Compilerdirektiven sollten Sie sich immer darber im klaren sein, da der Compiler den Basic-Text Zeile fr Zeile von vorne nach hinten durcharbeitet und sich nicht um die tatschliche Abarbeitungsreihenfolge unter dem Interpreter kmmert (die von GOTO und GOSUB bestimmt wird). Die Direktiven sollten darum grundstzlich am Anfang eines Programmes stehen. Eine Reihe von Direktiven kann im Gegensatz dazu beliebig oft innerhalb des Programms verwendet werden. Wenn dies der Fall ist, so wird es in der Beschreibung der Direktive erwhnt. Im folgenden werden die Compilerdirektiven nach ihrer Funktion geordnet erklrt. Sie sind in Grobuchstaben geschrieben und es mu ihnen jeweils noch ein Pfund () vorangestellt werden, damit sie lauffhig sind. Wenn Sie nicht unbedingt alle Mglichkeiten des Basic-Boss bis ins Letzte ausreizen wollen, brauchen Sie sich nur die Befehle anzusehen, die als wichtig bezeichnet werden.

2.4.1 Steuerung der Datentypen

Folgende Befehle sind sehr wichtig:

(BOOLEAN), BYTE, WORD, INTEGER, REAL, STRING

Diesen Befehlen folgt eine Variablenliste der Form A,B%,C,D$ mit beliebig vielen Elementen. Statt der Variablen knnen auch %, $ oder # fr alle Variablen der Form A%, A$ oder A stehen. Die betroffenen Variablen werden zu diesem Typ deklariert. Hinter einer Variable kann ein Gleichheitszeichen, dem wiederum FAST oder eine Adresse folgen mu. Diese Befehle mssen am Anfang des Programms stehen. Mehr hierzu finden Sie unter Kapitel 2.3 Datentypen. Den nchsten Befehl sollte man ebenfalls kennen, wenn man viel mit DATA arbeitet:

DATATYPE Typ

So wird der Typ der Daten des DATA-Befehls festgelegt. Standardmig sind alle Daten vom Typ String und werden auch in diesem Typ im Compilat abgelegt. Denn der Typ String kann vom READ-Befehl in alle anderen Typen umgewandelt werden. Wenn die Daten aber in Wirklichkeit zum Beispiel Zahlen zwischen 0 und 255 sind (was sehr hufig der Fall ist) und einer Variablen vom Typ Byte zugedacht sind, so wre es sicher sinnvoller, die Daten bereits in diesem Typ abzulegen. Dies geschieht, nachdem die Direktive DATATYPE Byte gefunden wurde. Danach sollten die Daten hinter dem DATA-Befehl Zahlen zwischen 0 und 255, sein. Sie werden dann direkt im Typ Byte abgelegt, was sehr viel Speicher spart (zirka 70% bis 80%) und die Ablaufgeschwindigkeit des Compilats drastisch erhht. Man kann statt Byte auch alle anderen Datentypen einsetzen, wobei diese dann entsprechend mehr Speicherplatz bentigen (REAL zum Beispiel bentigt fnf Byte pro Datenwert und spart damit nicht immer Speicher gegenber dem Stringtyp, dafr aber Zeit). Diese Direktive kann beliebig oft im Programm angewandt werden, so wie es die unterschiedlichen Daten erfordern. Dabei ist jedoch zu beachten, da der READ-Befehl die numerischen Typen nicht ineinander umwandeln kann. Darum steigt das Compilat mit einem type mismatch error aus, wenn Sie zum Beispiel Byte-Daten in eine Real-Variable einlesen wollen. Das Problem kann gelst werden, indem man die Byte-Daten zunchst in eine Byte-Variable einliest und diese Byte-Variable anschlieend einer Real-Variablen zuweist, was immer noch schneller und vor allem platzsparender ist als die Benutzung normaler Stringdaten.

Ein Beispiel:	10 rem@ byte a,b,c
          	20 read a,b,c
	        30 read x$,y$,z$
        	40 rem@ datatype byte
	        50 data 10,200,50
       		60 rem@ datatype string
	        70 data dies,sind,strings

Die folgenden Direktiven sind ziemlich unwichtig und werden selten bentigt.

PRINTTYPE Typ

Es wird der Mindesttyp der Berechnung im PRINT-Betehl auf den angegebenen Typ festgelegt. Nach PRINTTYPE Real werden also alle Operationen im PRINT-Befehl mindestens im Real-Typ durchgefhrt. Wenn W1 und W2 vom Typ Word sind und die Werte 5 und 2 enthalten, so liefert der Befehl PRINT W1/W2 nicht mehr das falsche Ergebnis 2, sondern 2.5. Standardmig ist der Typ Boolean.

BOOLEANTYPE Typ

Dieser Befehl legt den Mindesttyp bei der Berechnung von IF-Ausdrcken fest (zum Beispiel IF A+3.5=B THEN ...). Dieser Mindesttyp ist standardmig Boolean.


CALCTYPE Typ

Hiermit wird der Mindesttyp bei Berechnungen allgemein festgelegt. Normalerweise ist er auf Boolean gesetzt. Um die volle Kompatibilitt zu Basic herzustellen, kann man ihn auf Real setzen (mit CALCTYPE real), was die Programme aber unntig verlngert und stark verlangsamt.

2.4.2 Optimierungsmglichkeiten

Die nchsten zwei Befehle sollten Sie kennen, wenn Sie schnelle Programme schreiben wollen:
FASTFOR und SLOWFOR
Die FOR-NEXT-Schleife arbeitet im Compilat sehr umstndlich und langsam, da sie genau so funktionieren soll, wie in Basic. Deshalb bietet der Basic-Boss eine alternative FOR-NEXT-Schleife an, die wesentlich schneller ist, dafr aber ein paar Einschrnkungen aufweist. Dies sind folgende: FOR und NEXT mssen im Programmtext in richtiger Reihenfolge stehen und auf jedes FOR mu genau ein NEXT folgen (hnlich wie in Pascal, Modula oder C). Folgende Konstruktionen lassen den Basic-Boss darum schmollen, wenn er schnelle Schleifen erzeugen soll:

10 goto 30 
20 next i: end 
30 for i=1 to 100 
40 print i: goto 20

oder so etwas:

10 for r=1 to 100 
20 print i; 
30 if i<50 then next i 
40 print "abc" 
50 next i
Eine weitere Einschrnkung besteht beim Typ der Zhlvariable. Sie darf nur vom Typ Byte oder Word sein. Andernfalls benutzt der Basic-Boss die langsame Schleife. Auch beim STEP-Wert ist nicht alles erlaubt: Wenn er angegeben wird, so mu er direkt angegeben werden, das heit als Zahl und nicht als Variable. Er darf allerdings sowohl positiv als auch negativ sein. Auerdem darf sich der Wert der Endvariable nicht verndern. Bei FOR I=A TO E mu der Wert in E whrend der Ausfhrung der Schleife immer gleich bleiben, wenn die Schleife im Compilat dasselbe machen soll wie unter dem Interpreter (es sei denn, E ist ein Ausdruck). Trotz all dieser Einschrnkungen lt sich der FASTFOR-Befehl auf die allermeisten Schleifen anwenden. Normalerweise produziert der Basic-Boss langsame Schleifen (der Kompatibilitt wegen). Wenn er aber die Direktive FASTFOR findet, erzeugt er von da ab schnelle Schleifen. Wenn er dann wieder auf SLOWFOR stt, erzeugt er wieder langsame, aber vollkompatible Schleifen. Wenn man nur eine einzige Schleife schneller machen will, dann kann man also vor diese Schleife FASTFOR und dahinter SLOWFOR schreiben. Man sollte beachten, da bei SLOWFOR alle Schleifen mit NEXT abgeschlossen sind, da der Basic-Boss ansonsten einen Fehler meldet. Man sollte brigens grundstzlich die Schleifenvariable hinter NEXT angeben, da der Compiler dann Fehler besser aufdecken kann. Schachtelungen sind natrlich auch bei schnellen Schleifen erlaubt. Es ist bei FASTFOR-Schleifen im Gegensatz zu langsamen Schleifen auerdem vllig unproblematisch, aus der Schleife mit GOTO herauszuspringen. Die nchsten vier Befehle sind fr die Optimierer unter Ihnen gedacht und nicht von essentieller Bedeutung.


LONGIF und SHORTIF

Es gibt fr den Compiler zwei Mglichkeiten, eine IF-Verzweigung zu konstruieren. Das eine Verfahren erlaubt beliebig viele Befehle hinter dem THEN, das andere nicht. Dafr spart man mit dem zweiten Verfahren aber bei jedem IF-Befehl drei Byte Speicher und der Code wird etwas schneller. Standardmig wendet der Compiler das LONGIF-Verfahren an, das eine beliebig groe IF-Verzweigung erlaubt. Mit SHORTIF schaltet man auf die Sparversion um, die in den allermeisten Fllen aber ausreicht. Darum wrde ich empfehlen, grundstzlich mit SHORTIF zu programmieren. Wenn der Basic-Boss dann doch einmal bei einer IF-Zeile streikt (er meldet einen Fehler), dann kann man vor dieser IF-Zeile mit LONGIF auf die lngere Version umschalten und dahinter mit SHORTIF wieder auf die krzere. Die folgenden zwei Befehle knnen beim Austesten wichtig sein:

SLOWARRAY und FASTARRAY

Wenn ein Feld (Array) zum Beispiel mit DIM A(20) dimensioniert ist, so erlaubt es der Compiler bei einfachen und schnellen Arrays, da das Basic-Programm auch auf nicht existente Array-Elemente zugreift. Die Anweisung X=30: A(X)=1000 wird also anstandslos abgearbeitet, wodurch andere Variablen oder Speicherinhalte zerstrt werden. Zum Ausgleich dafr sind solche Arrays aber extrem schnell. Wenn man dennoch auf Nummer Sicher gehen will, so kann man dies mit SLOWARRAY tun, was das Programm dann stark verlangsamt. FASTARRAY schaltet die schnelle Array-Verwaltung wieder ein. Beide Befehle knnen mehrmals an beliebiger Stelle im Programm stehen, weshalb man die Sicherheit gezielt dosieren kann.

2.4.3 Festlegung der Startadressen

Diese Befehle sollte man nur dann anwenden, wenn man gewisse Grundkenntnisse bezglich der Speicheraufteilung des C64 besitzt. Ansonsten kann man sie ignorieren. Fr gewhnlich wird das Compilat in ein einziges File gespeichert, dessen Name der Basic-Boss aus dem Namen des Quellprogramms erhlt, indem er ihm ein + voranstellt. Das Compilat wird an den normalen Basic-Start (2049) inclusive SYS-Zeile kompiliert, so da man es mit RUN starten kann. Es geht aber auch anders. Man kann das Compilat an einen beliebigen Ort im Speicher legen. Man kann es sogar in seine Bestandteile aufspalten und diese an beliebige Speicheradressen legen und unter beliebigem Namen auf Diskette schreiben. So ist es sogar mglich, mehrere Compilate gleichzeitig im Speicher zu halten, die sich gegenseitig aufrufen, wenn man sie an unterschiedliche Adressen legt. Zu all dem kann noch ein gewhnliches Basic-Programm kommen, das die Compilate mglicherweise als Unterroutinen benutzt und steuert. Die Speicheraufteilung des Compilats sieht normalerweise so aus: Es besteht aus drei Teilen. Dies sind der Programmteil, der Routinenteil und der Datenteil. Der Programmteil stellt das eigentliche Maschinenprogramm dar, das aus dem Basic-Programm erzeugt wurde. Dieser Programmteil bentigt fr seine Arbeit Unterroutinen, die der Basic-Boss einzeln aus seiner Bibliothek holt und hinter den Programmteil schreibt, wobei der Compiler sie an den Adrebereich anpat (insgesamt heit dieser Vorgang Linken). Dann folgt ein Datenbereich, in dem Informationen ber Array-Variablen und eine Tabelle fr den READ-Befehl stehen. Schlielich folgen der Variablenspeicher, der Bereich fr Hilfespeicher und letztendlich der Stringspeicher. Diese Reihenfolge scheint zwar die vernnftigste zu sein, entspricht aber nicht der Realitt. Oder genauer: Sie stimmt nur in Pass 1. In Pass 2 erzeugt der Compiler zunchst Routinen- und Datenbereich und erst danach den Programmbereich. Dies erfordert umfangreiche Umrechnungen, hat dafr aber einen wesentlichen Vorteil: Der Routinenbereich steht im Compilat ganz vorne. Damit ist im Normalfall sichergestellt, da die Routinen im unteren 40-Kbyte-Bereich liegen. Und genau dort mssen sie sein, denn sie mssen unbedingt in einem Speicherbereich stehen, der nicht vom ROM oder von anderem berlagert wird.
Die Lage der Bereiche lt sich mit folgenden Befehlen ndern. Dabei ist zu beachten, da sich die einzelnen Bereiche nicht berschneiden. Wenn die Lage eines Code-Bereichs gendert wird, dann wird er in eine eigene Datei geschrieben. Eine alte Datei gleichen Namens wird standardmig gelscht (mit dem SCRATCH-Befehl).

ROUTSTART Adresse

legt den Anfang fr den Routinenbereich fest. Die Routinen drfen nicht unter das ROM oder unter den I/O-Bereich gelegt werden. Der Dateiname dieses Teils ergibt sich standardmig aus R+ und dem Namen der Quelldatei. Die SYS-Zeile ist Teil dieses Bereichs. Darum schaltet der Befehl auerdem die SYS-Zeile ab, falls sie nicht explizit mit SYSON aktiviert wurde. Dann kann der Routinenbereich direkt mit einem SYS-Befehl angesprungen werden, wenn das Compilat gestartet werden soll. Standardmig liegt der Routinenbereich bei 2049, also am Beginn des Basic-Speichers.

DATASTART Adresse

legt die Startadresse fr den Datenbereich fest. Der Dateiname des Datenbereichs ergibt sich aus D+ und dem Namen der Quelldatei.

PROGSTART Adresse

legt die Startadresse des eigentlichen Programms fest. Es kann berall hingelegt werden, zum Beispiel auch nach $D000, sofern das Compilat im ALLRAM-Modus luft. Der Dateiname ergibt sich aus P+ und dem Namen der Quelldatei.

VARSTART Adresse
bestimmt die Adresse des Variablenspeichers.

HELPSTART Adresse
bestimmt den Anfang des Hilfespeichers.

HEAPSTART Adresse 
und 
HEAPEND Adresse
bestimmen die Lage des Stringspeichers. Die Adresse bei HEAPEND gibt die erste nicht mehr benutzte Speicherstelle an. Wenn bei HEAPEND 0 angegeben wird, so wird berhaupt kein Stringspeicher reserviert, was sinnvoll ist, wenn Sie keine Stringoperationen ausfhren wollen. Variablen-, Hilfs- und Stringspeicher knnen wie der Programmbereich berall hingelegt werden. Normalerweise werden alle Bereiche direkt aneinandergehngt. Falls Sie sich eine eigene Basic-Boss-Version mittels SETPREFERENCES erzeugt haben, die die Bereiche nicht aneinanderhngt, so knnen Sie dies mit der Angabe von 0 als Startadresse eines Bereichs erzwingen.


2.4.4 Die Dateien

Die Filenamen der Ausgabedateien knnen Sie beliebig festlegen, falls Ihnen die Standardnamen nicht zusagen.

ROUTFILE Gert, "Dateiname"

So wird der Name der Datei fr den Routinenteil festgelegt, in die fr gewhnlich auch der Datenteil und der Programmteil geschrieben werden. Das Gert ist sinnvollerweise entweder 8 oder 9, normalerweise wird man es weglassen (ROUTFILE "Dateiname"). Hinter dem Gert knnte man auch noch die Sekundradresse angeben, was aber in den wenigsten Fllen sinnvoll sein drfte (nur bei besonders umstndlichen RAM-Disks oder hnlichem).

PROGFILE Gert, "Dateiname"

und 

DATAFILE Gert, "Dateiname"

funktionieren genauso fr den Programmbereich und den Datenbereich. Dem Namen einer Datei kann unbedenklich ein Klammeraffe (@) gefolgt von einem Doppelpunkt vorangestellt werden. Der Basic-Boss erkennt dies und lscht dann die alte Datei vor dem ffnen der neuen mit dem SCRATCH-Befehl der Floppy. Dies ist notwendig, weil das berschreiben mit dem Klammeraffen aufgrund eines Fehlers in der Floppy nicht funktioniert und normalerweise grundstzlich vermieden werden sollte, da sonst Dateien zerstrt werden knnen. Wenn man dem Dateinamen keinen Klammeraffen voranstellt, dann wird eine alte Datei gleichen Namens nicht gelscht und es tritt eventuell ein Floppy-Fehler auf. Es gibt noch einen weiteren Dateibefehl:


SOURCEFILE Gert, Sekundradresse, "Dateiname"

Dieser Befehl scheint reichlich unsinnig. Er legt Name, Gert und Sekundradresse der Quelldatei fest, nachdem dieselbige bereits geffnet ist (er wird ja aus ihr gelesen). Darum ist er nur vor einem SETPREFERENCES-Befehl sinnvoll. Sekundradresse und/oder Gert knnen wie blich weggelassen werden.

2.4.5 Protokollierung der Compiler-Ttigkeit

Auch die folgende Direktive ist nicht von berragender Bedeutung, sollte aber trotzdem in keinem Compiler oder Assembler fehlen.

PROTOCOL Gert, Sekundradresse, "Dateiname"

Die Fehlermeldungen und sonstige Daten (zum Beispiel die Speicheradressen) erscheinen normalerweise nur auf dem Bildschirm. Wenn man sie auf den Drucker leiten will, so gengt die Direktive PROTOCOL. Wenn der Drucker eine andere Gerteadresse als 4 besitzt (zum Beispiel Plotter 1520), dann sollte man diese mit PROTOCOL Gert angeben. An das Gert kann man noch die Sekundradresse anhngen und eventuell auch einen Dateinamen (Dieser steuert zum Beispiel beim Grlitz-Interface den Zeilenabstand). PROTOCOL 8, "FEHLER",S,W sendet die Fehlermeldungen dagegen in die Datei FEHLER auf Diskette (auch hier kann man unbedenklich den Klammeraffen verwenden). Diese Datei ist eine simple ASCII-Datei und kann zum Beispiel mit dem Programm ERRORREAD (auf der Programmdiskette) wieder gelesen werden. Wenn PROTOCOL verwendet wurde, dann hlt der Compiler beim Auftreten von Fehlern nicht mehr an. Mit PROTOCOL 0 erzeugen Sie diesen Effekt, ohne da irgendeine Ausgabe erfolgt.


2.4.6 Speicherverwaltung

Der Basic-Boss erlaubt es, den gesamten Speicher des C64 zu nutzen. PEEK und POKE werden dabei etwas langsamer. Wenn Sie das nicht strt, dann setzen Sie einfach die Direktive ALLRAM an den Programmanfang und die Sache ist erledigt. Falls Sie aber optimale Geschwindigkeit wnschen, dann sollten Sie sich mit den Befehlen RAM und ROM beschftigen.

ALLRAM

mu am Anfang des Programms stehen und weist den Basic-Boss an, den gesamten Speicher fr das Programm zu nutzen. Zudem wird das Stringspeicherende automatisch an das Speicherende gesetzt, falls kein HEAPEND-Befehl im Programm steht. Im ALLRAM-Modus sind grundstzlich die gesamten 64 Kbyte RAM des C64 eingeschaltet (normalerweise sind nur die untersten 40 Kbyte eingeschaltet und ein kleiner Bereich ab Adresse 49152). Allerdings mu dann bei allen PEEK-, POKE- und SYS-Befehlen zuerst auf das ROM umgeschaltet werden, damit sie in jedem Fall dasselbe Ergebnis erbringen wie beim Interpreter. Dies verlangsamt das Programm nicht unbetrchtlich. Wenn man mit diesen Befehlen aber sowieso nur den RAM-Speicher ansprechen will und nicht das ROM, den I/O-Bereich oder den Farbspeicher, dann kann man die Umschaltung mit RAM unterbinden. Jeder POKE-, PEEK-, oder SYS-Befehl bezieht sich dann auf den RAM-Speicher. Wenn wieder auf das ROM oder die I/O-Bausteine zugegriffen werden soll, mu man die Umschaltung zuvor mit ROM wieder anschalten. Wenn man diesen Befehl vergit, dann wird zum Beispiel nicht die Bildschirmfarbe gesetzt, sondern der Stringspeicher gestrt und die Garbage-collection luft Amok. Diese beiden Befehle sind nur bei ALLRAM sinnvoll. RAM und ROM knnen beliebig oft im Programm verwendet werden. Ein Beispielprogramin (RAMROM) befindet sich auf der Programmdiskette. Auch im Programm RAMLOAD wird von ALLRAM und RAM Gebrauch gemacht. Eine effizientere Mglichkeit des Zugriffs auf das ROM im ALLRAM-Modus bieten die Befehle <-RAM,  <-ROM und <-IOROM, die aber nur der Profi einsetzen sollte (siehe unter 2.5 Neue Befehle und Funktionen).

BASICRAM

ist das Gegenstck zu ALLRAM und bewirkt, da nur der normale Basic-Speicher fr Programme und Variablen benutzt wird. Wenn das Stringende (HEAPEND) noch nicht gesetzt wurde, wird es auf 40960 herabgesetzt (Ende des Basic-Speichers). Dies ist der Normalzustand.
Im ALLRAM-Modus kann das Compilat ber den Basic-Bereich hinausreichen und lnger als 154 Blocks sein. Dann belegt es auch das RAM unter dem ROM. Eine grere Lnge als 201 bis 202 Blocks ist nur deshalb nicht mglich, weil die Lade-Routine des C64 dann den I/O-Bereich berschreibt, was sich optisch an einer drastischen nderung der Bildschirmanzeige erkennen lt. In diesen Bereich kann ein Programm nur mit dem Compilat von RAMLOAD geladen werden. Dabei darf RAMLOAD selbst aber nicht berschrieben werden.


2.4.7 Die SYS-Zeile

SYSON und SYSOFF

Die SYS-Zeile ermglicht es, das Compilat wie ein normales Basic-Programm zu laden und zu starten. Sie kann mit SYSOFF unterbunden werden. Dies ist jedoch meist nicht notwendig, da der ROUTSTART-Befehl die SYS-Zeile selbstttig abschaltet, so da das Programm mit SYS Startadresse vom Direktmodus aus oder von einem anderen Programm gestartet werden kann. Mit SYSON kann man die SYS-Zeile erzwingen. Folgende Befehle haben nur rein kosmetische Bedeutung:

SYSNUMBER Nummer
bestimmt die Zeilennummer der SYS-Zeile.

SYSTEXT "Text"
legt den Text in der SYS-Zeile fest.

2.4.8 Sonstige Direktiven

LINEON und LINEOFF

schalten die Zeilenaktualisierung an und aus. Normalerweise ist sie abgeschaltet, da sie Speicherplatz verbraucht und das Programm verlangsamt. Wenn sie angeschaltet ist, werden die whrend des Programmlaufs auftretenden Fehler mit der richtigen Zeilennummer angezeigt, sonst nicht. Die nun folgenden Befehle sind fr den gelegentlichen Benutzer von geringerer Bedeutung:

LONGNAME und SHORTNAME

In Basic sind bei Variablen beliebig lange Namen erlaubt. Trotzdem unterscheidet der Interpreter nur die ersten zwei Stellen. KUCKUCK und KUHFLADEN sind fr den Interpreter also genau dasselbe. Der Compiler ist aber auf beliebig lange Variablen ausgelegt. Aus Kompatibilittsgrnden unterscheidet er trotzdem nur zwei Stellen. Mit LONGNAME kann man diesen Mangel beheben, wenn man in Kauf nimmt, da das Programm unter dem Interpreter dann nicht mehr einwandfrei luft. SHORTNAME schaltet wieder auf zweistellige Namen.
Beim Benutzen langer Namen sollte man darauf achten, da kein Basic-Befehl in diesen Namen enthalten ist, da dies zwangslufig zu einem Fehler fhrt.

IGNORE und USE
IGNORE weist den Compiter an, alles nachfolgende zu ignorieren. Erst wenn er auf USE trifft, untersucht er das Basic-Programm wieder. Diese Funktion ist sinnvoll, wenn man einige Teile des Basic-Progranims vor dem Compiler verstecken will. Das kann sehr ntzlich sein, wenn die Lauffhigkeit unter dem Interpreter erhalten bleiben soll und man trotzdem spezielle Compilerfunktionen ausnutzen will.

Ein Beispiel:	10 print "fuer compiler und interpreter"
	        20 rem@ ignore
        	30 print "nur fuer interpreter"
		40 goto 70
	        50 rem@ use
        	60 print "nur fuer compiler"
	        70 print "wieder fuer beide"

SETPREFERENCES

Wenn man seine Lieblingseinstellungen nicht in jedem Programm per Compilerdirektive neu setzen will (zum Beispiel Programmstart, Standarddatentyp und so weiter), dann kann man ein kleines Programm schreiben, das die erwnschten Einstellungen setzt und anschlieend den SETPREFERENCES-Befehl einsetzt. Die momentanen Einstellungen des Basic-Boss werden dann in die Standardeinstellungen kopiert und der Compiliervorgang wird abgebrochen. Wenn man den Basie-Boss jetzt mit <<-> neu startet, kann man einen Stern (*) gefolgt von einem Namen eingeben, unter dem Ihr individueller Basic-Boss anschlieend gespeichert wird (nicht auf die Originaldiskette!). In Zukunft knnen Sie dann diese Basic-Boss-Version statt der Standardversion benutzen und mssen die am hufigsten gebrauchten Einstellungen nicht jedesmal neu setzen. Ein Beispielprogramm hierzu finden Sie unter dem Namen PREFERENCES auf der Diskette.

CODE Wert, Wert, ...

Dieser Befehl ist nur fr Kenner der Maschinensprache gedacht. Dem Befehlswort folgen beliebig viele mittels Komma getrennte Werte. Dies knnen Byte-Werte sein. Es knnen auch Word-Werte sein, wenn man dem Zahlenwert ein w vorausstellt. Auch Zeichenketten sind mglich, wenn man diese in " einschliet. Diese Bytes oder Words oder Zeichenketten werden an der aktuellen Position in das Compilat eingefgt. Auf diese Weise kann man smtliche Maschinensprachebefehle des 6510 erzeugen. Man braucht dabei nicht auf den Erhalt der Register-Werte (A,X,Y) zu achten, da der Basic-Boss dies nicht verlangt. Wenn man den CODE-Befehl unvorsichtig einsetzt, dann ist das Compilat anschlieend aber nicht lauffhig. Ein paar Beispiele: CODE 234,234 fgt zwei NOP-Befehle ein, was eine kleine Zeitverzgerung bewirkt. CODE 0 setzt einen Breakpoint. CODE 96 ist identisch mit RETURN. CODE 108,w40962 fhrt JMP($A002) aus und CODE 2 erzeugt einen sicheren Systemabsturz.

INITOFF und INITON

Smtliche Variablen werden bekanntlich zu Beginn eines Programms auf 0 gesetzt (FAST- und Adrevariablen ausgenommen). Dies kann man mit INITOFF verhindern. Dieser Befehl mu unbedingt am Anfang eines Programms stehen. Wenn er vor Beginn der Code-Erzeugung gefunden wird, dann werden keine Variablen initialisiert und haben beim Start des Compilats einen zuflligen Wert. Wenn dieser Befehl verwendet wird, sollte man auf Strings verzichten, da diese eine Initialisierung unbedingt bentigen. INITON schaltet die Initialisierung wieder ein.


2.5 Neue Befehle und Funktionen

Der Basic-Boss versteht einige neue Befehle und Funktionen. Die Befehle werden mit einem <- eingeleitet und die Funktionen mit dem Klammeraffen (@). Da der Basic-Interpreter beides nicht verarbeitet, kann man IGNORE und USE hierbei nutzbringend einsetzen und fr Interpreter und Compiler stellenweise verschiedene Befehlsfolgen vorsehen, damit das Programm nach wie vor einwandfrei unter dem Interpreter ausgetestet werden kann.

2.5.1 Ein-/Ausgabe

<-LOAD "DATEINAME", GERT, ADRESSE

Dieser Befehl ldt vom angegebenen Gert eine Datei an die angegebene Adresse. Falls die Adresse fehlt, dann wird die Datei an die von ihr gewnschte Adresse geladen. Wenn man auch das Gert weglt, wird die Gerteadresse 8 angenommen. Das Programm wird nach Ausfhrung dieses Befehls im Gegegensatz zum normalen LOAD-Befehl regulr beim nchsten Befehl weiterbearbeitet.

Beispiel:  10 print "jetzt wird geladen"
	   20 <-load "sprite",8,832
           30 print "fertig mit laden"

2.5.2 Effiziente Ein- und Ausgabe

Das Commodore-Basic bietet dem Programmierer die Eingabebefehle GET# und INPUT# und den Ausgabebefehl PRINT#. Das reicht fr die allermeisten Anwendungen aus. Allerdings weisen diese Befehle auch einige Nachteile auf: Zahlen werden bei PRINT# erst zu Strings umgewandelt und dann als Text abgespeichert, was viel Zeit und Platz verbraucht. Ebenso wird die Eingabe bei INPUT# verlangsamt. Bei jeder einzelnen Befehlsausfhrung wird zwischen den Ein- beziehungsweise Ausgabekanlen umgeschaltet. Dies wirkt sich besonders bei GET# sehr ungnstig auf die Geschwindigkeit aus. Es mu hufig mit den verhltnismig langsamen Strings gearbeitet werden, obwohl dies berhaupt nicht ntig wre.

@BYTE, @INTEGER, @REAL, @WORD

<-BYTE, <-INTEGER, <-REAL, <-WORD

Die Lsung bieten ein paar neue Befehle und Funktionen zur Ein-/Ausgabe. Die Befehle zur Ausgabe bestehen aus dem blichen <- und dem Namen eines numerischen Datentyps. Dem folgen dann eine oder mehrere mit Komma getrennte Ausdrcke (meist einzelne Variablen oder Zahlen). Das Ergebnis dieser Ausdrcke wird dann in den angegebenen Typ umgewandelt (falls ntig) und in den momentan aktiven Ausgabekanal geschrieben. <-BYTE 3 gibt zum Beispiel ein einzelnes Byte aus, das den Wert 3 hat. <-REAL 1.2345 gibt fnf Byte aus, die dem Speicherformat von 1.2345 entsprechen. Genau so arbeiten auch <-WORD X und <-INTEGER X, die genau zwei Byte schreiben. 
Die Eingabe wird im Gegensatz zur Ausgabe nicht ber Befehle, sondern ber Funktionen realisiert, da sie flexibler und effizienter angewandt werden knnen. Diese Funktionen beginnen grundstzlich mit einem Klammeraffen, dem hnlich wie bei den Befehlen ein numerischer Datentyp folgt. Es werden keine Parameter bentigt, weshalb man die Funktionen wie Variablen behandeln kann. Bei A=@BYTE wird ein Byte vom Eingabekanal geholt und der Variablen A zugewiesen. Bei PRINT @REAL werden fnf Byte gelesen und als Fliekommazahl auf den Bildschirm ausgegeben. POKE 1, @BYTE holt ein Byte und schreibt es nach Adresse 1. Diese neuen Befehle und Funktionen sind in der Form allerdings nicht sonderlich ntzlich, da sie nur auf das Standardausgabegert Bildschirm schreiben und vom Standardeingabegert Tastatur lesen knnen. Diesem Mistand helfen folgende Befehle ab:

<-OUT, <-IN, <-RESET

<-OUT n richtet den Ausgabekanal auf die Datei n (genauso wie CMD n).
<-IN n richtet den Eingabekanal auf die Datei n. 
<-RESET n schaltet die Kanle wieder auf die Standardgerte Bildschirm und Tastatur.	
Wenn man zum Beispiel die 1000 Elemente des Real-Arrays R( in die Datei TEST,S schreiben will, so kann das folgendermaen aussehen:

1000 open 1,8,2,"test,s,w"
1010 <-out 1
1020 for i=0 to 999: <-real r(i): next i 
1050 <-reset 
1060 close 1 

Wenn eine Schreib- oder Leseoperation abgechlossen ist, so mu unbedingt der <-RESET-Befehl ausgefhrt werden, damit man wieder Bildschirm oder Tastatur ansteuern kann. Denn auch die Befehle GET, INPUT und PRINT beziehen sich jeweils auf den aktuellen Ein-/Ausgabekanal. Trotzdem sollte man aus Zeitgrnden mglichst selten umschalten. Das Betriebssystem lt es nicht zu, da Ein- und Ausgabekanal umgelenkt werden. Wenn der Eingabekanal umgelenkt wurde, mu also immer erst ein <-RESET erfolgen, bevor der Ausgabekanal umgelenkt werden kann (oder umgekehrt). Man kann auch Daten von verschiedenem Typ in dieselbe Datei schreiben, wenn man peinlich genau darauf achtet, da die Daten in exakt derselben Reihenfolge gelesen werden, wie sie geschrieben wurden . Auf der Programmdiskette finden Sie zwei Beispiele zu diesem Thema namens BOSSDIR und RAMLOAD.
2.5.3 Speicherverwaltung

<-RAM, <-ROM und <-IOROM
Diese drei Befehle sind nur fr den Spezialisten gedacht. Es ist am sinnvollsten, sie zusammen mit ALLRAM zu verwenden. <-ROM schaltet das ROM und den Input/Output-Bereich (Videoprozessor, SID, Farb-RAM und so weiter) ein, so da darauf sehr schnell zugegriffen werden kann (mit POKE oder PEEK in Verbindung mit der Compilerdirektive <-RAM, der ein  vorangeht). Dabei kann auf das RAM von $A000 bis $BFFF und $D000 bis $FFFF nicht mehr zugegriffen werden. Darum drfen weder Programm noch Variablen in diesem Bereich liegen. <-ROM schaltet nur den Input/Output-Bereich und das Betriebssystern ein, nicht aber den Basic-Interpreter. Dann kann auf das RAM von $D000 bis $FFFF nicht mehr zugegriffen werden. <-RAM schaltet wieder alle 64 Kbyte ein. Nach <-ROM oder <-IOROM sollten nur einfache Operationen mit Word oder Byte-Typen durchgefhrt werden. Jede komplexere Operation ruft eine Unterroutine auf, die im allgemeinen wieder auf den RAM-Modus schaltet. Statt mit diesen Befehlen knnen Sie die Umschaltung brigens auch gefahrlos selbst mit POKE 1,X durchfhren (allerdings ebenfalls nur im ALLRAM-Modus).

<-SEI und <-CLI
Auch diese Befehle sind eher fr den professionelleren Programmierer gedacht. Sie sind mit den gleichnamigen Maschinensprachebefehlen identisch. Mit <-SEI kann man den System-Interrupt sperren. Das ist sinnvoll, wenn man besonders zeitkritische Anwendungen programmiert, die keine kurzen Unterbrechungen vertragen. Allerdings wird nach <-SEI die Tastatur nicht mehr abgefragt und die Zeit nicht hochgezhlt. Darum sollte man den lnterrupt mit <-CLI sobald als mglich wieder einschalten. Auerdem kann man mit Hilfe dieser Befehle <-RAM, <-ROM und <-IOROM auch dann sinnvoll einsetzen, wenn das Programm nicht im ALLRAM-Modus luft. Man sollte dann komplexere Operationen vermeiden. Sonst schalten eventuell aufgerufene Unterroutinen wieder auf den ROM-Modus zurck. Man sollte diese Befehle sehr sorgfltig handhaben und nach <-SEI keine Ein-/Ausgabeoperationen durchfhren.

2.5.4 Verarbeitung von Befehlen aus Basic-Erweiterungen

Das Commodore Basic V2 ist bekanntlicherweise recht spartanisch ausgestattet und sicher nicht fr seinen Befehlsumfang berhmt. Dessen wird man sich sehr schnell bewut, wenn man versucht, Grafik oder Tne zu programmieren. So ist es nicht verwunderlich, da es eine Vielzahl von Erweiterungen und Zusatzroutinen gibt, die diesem Mangel begegnen. Aus der Sicht des Basic-Boss gibt es grundstzlich drei verschiedene Sorten solcher Erweiterungen: Die simpelsten werden mit SYS Adresse aufgerufen. Eventuelle Parameter werden zuvor per POKE in bestimmte Speicherzellen gebracht (z.B. POKE 900,A: SYS 49152). Etwas benutzerfreundlicher ist die zweite Sorte, die ebenfalls per SYS aufgerufen wird, ihre Parameter aber an den SYS-Befehl angehngt erwartet (z.B. SYS 49152, A, B$, C). Die letzte Sorte ist die komfortabelste, denn sie arbeitet mit vllig neuen Befehlen (z.B. LINE X1, Y1, X2, Y2). Die simplen Erweiterungen machen dem Compiler keine Schwierigkeiten, da nur vllig normale Basic-Befehle verwendet werden. Genauso bereitwillig verarbeitet er die USR-Funktion. In beiden Fllen sind keine besonderen Vorkehrungen notwendig, vorausgesetzt, die Erweiterung benutzt keine wichtigen Teile des Speichers (dann mu man mglicherweise mit HEAPEND arbeiten).

OTHERON und OTHEROFF

Schwierig wird es fr den Compiler bei zustzlichen SYS-Parametern oder gar vllig neuen Befehlen. Dann mssen spezielle Vorkehrungen getroffen werden, wozu man den Boss mit OTHERON am Programmanfang veranlat. Wenn der Compiler nun einen unbekannten Befehl (genauer Token oder Token-Folge) findet, so nimmt er an, da es sich um den Befehl einer Erweiterung handelt. Der Basic-Boss wertet den unbekannten Befehl samt Parameter und Trennzeichen aus und schreibt alles zusammen in einem Spezialformat ins Compilat. Die an den Befehl angehngten Parameter knnen voneinander mittels Komma oder irgendeinem anderen Sonderzeichen (z.B. mit einem Basic-Befehl) getrennt sein (z.B. LINE Xl,Y1 TO X2,Y2). Auch mehrere Trennzeichen oder gar keines werden akzeptiert. Die Reihenfolge und die Art der Trennzeichen mu aber von der Erweiterung erwartet werden, ebenso der Befehl selbst, da beim Compilat sonst ein SYNTAX ERROR auftritt. Denn das Compilat fhrt den Befehl nicht selbst aus, sondern bergibt ihn dem Basic-Interpreter. Wenn sich eine Erweiterung im Speicher befindet, die sich ordnungsgem in den Interpreter eingebunden hat, dann wird sie den Befehl verarbeiten. Der Erweiterung knnen nur Strings und Real-Zahlen bergeben werden, da der Interpreter nur diese Typen kennt. Andere Datentypen werden daher nach Real umgewandelt. Vor allem ist zu beachten, da die Erweiterung nur lesend auf die Variablen zugreifen darf. Eine Maschinenroutine zum Sortieren von Strings kann z.B. schon allein wegen der vllig neuen Stringverwaltung des Basic-Boss nicht verwendet werden. OTHERON arbeitet brigens auch im ALLRAM-Modus. Allerdings knnen dann die bergebenen Strings nicht lnger als 80 Zeichen sein und man sollte beachten, da die Erweiterung auch ihren Speicherplatz bentigt, den man ihr z.B. mit HEAPEND sichern sollte. OTHEROFF schaltet die Verwaltung von SYS-Parametern und Erweiterungsbefehlen ab. Dies ist der Normalzustand. Fr Interessierte noch ein Wort zum Prinzip: Die bergabe von SYS-Parametern ist eigentlich nicht ohne weiteres mglich, da die Variablenstruktur des Basic-Boss sich von der des Interpreters zu stark unterscheidet. Doch glcklicherweise bietet der Interpreter einen Vektor zum Holen eines arithmetischen Elements. Dieser Vektor wird bei OTHERON vom Compilat auf eine eigene Routine gerichtet. Sie bereitet die Basic-Boss-Variablen auf und verfttert sie an den Interpreter, der sie wiederum an das Maschinenprogramm der Erweiterung weitergibt. Die Trennzeichen liest die Erweiterung selbst. Bei neuen Befehlen kommt noch ein weiterer Vektor ins Spiel ($308/$309), ber den das Compilat die Erweiterung anspringt.

OTHER

Manche Erweiterungen arbeiten trotz OTHERON mit dem Compilat nicht zusammen und erzeugen nur SYNTAX ERROR. Dies trifft auf eine bestimmte Klasse von Erweiterungen zu, die man oft daran erkennt, da ihre Befehle mit einem Sonderzeichen eingeleitet werden, z.B. Pfeil links, Ausrufezeichen oder eckige Klammern oder hnliches (es werden keine echten Tokens benutzt). Wenn dies nicht der Fall ist, dann sollten Sie ihr Basic-Programm einmal laden, ohne da die Erweiterung im Speicher ist. Wenn die Erweiterungsbefehle nun immer noch vllig einwandfrei zu lesen sind, dann gehrt Ihre Erweiterung auch zu dieser Gruppe. Deren Befehle kann der Basic-Boss nicht ohne weitere Hilfe verarbeiten, da er nicht wei, wo der Befehl aufhrt und die Parameter anfangen. Wenn der Befehl z.B. !COLA lautet, dann kann das entweder ein einziger Befehl namens !COLA sein, oder auch !COL A meinen, mit A als Variable. Die OTHER-Direktive schafft dem Abhilfe. Ihr sollte eine Liste aller im Progamm verwendeter Befehle folgen, die voneinander per Komma getrennt sind, z.B. OTHER !COL,!PLOT,!HIRES. Wenn eine Programmzeile nicht ausreicht, dann knnen auch mehrere Other-Direktiven eingesetzt werden. Sie sollten allerdings sicherheitshalber nicht in REM-Zeilen stehen, sondern per GOTO vom Interpreter ferngehalten werden (z.B. 10 GOTOll: OTHER !COL). Dann drfen die Erweiterungsbefehle auch normale Basic Befehle enthalten (z.B. !TEXTON enthlt ON). OTHER mu vor dem ersten Erweiterungsbefehl stehen (ansonsten ist der 7/CODE VERSCHOBEN-Fehler mglich). Bei den moderneren Erweiterungen wird der OTHER-Befehl nicht bentigt (z.B. HiRes-Master aus The Best of Grafik 3).


BOSSOFF und BOSSON

In seltenen Fllen kann es vorkommen, da ein Erweiterungsbefehl mit einem Basic-Boss-Befehl in Konflikt gert. Wenn ein Erweiterungsbefehl z.B.  <-LOAD lautet, so wird der Basic-Boss flschlicherweise annehmen, da dies fr ihn bestimmt ist. Darum kann man mit BOSSOFF alle Direktiven und Befehle des Basic-Boss abschalten. Mit Ausnahme von BOSSON, denn so schaltet man die Befehle wieder ein. Beide Direktiven knnen beliebig
oft im Programm gebraucht werden. Welche Erweiterungen funktionieren?
Meinen Erfahrungen nach arbeiten umfassende Basic-Erweiterungen wie Simons' Basic und G-Basic nicht mit dem Basic-Boss zusammen, da sie zu tief in die innere Struktur des Basic eingreifen. Die typischen Grafikerweiterungen wie Grafik 2000 (The Best of Grafik 2) oder der recht schnelle HiRes-Master (The Best of Grafik 3) arbeiten dagegen sehr gut mit dem Compilat zusammen. Bei HiRes-Master ist darauf zu achten, da man die Strings mit HEAPEND $8000 in Sicherheit bringt. Beide Erweiterungen bentigen keinen Other-Befehl (nur OTHERON). Sogar die Scroll-Machine (The Best of Grafik 2) kooperiert mit dem Boss. Allerdings wird hier die Other-Direktive bentigt. Andere Erweiterungen setzen teilweise den Basic-Start herauf, um so Platz fr Sprites oder Grafik zu schaffen. Auch dies ist kein greres Problem. Man mu dem Basic-Boss nur mit ROUTSTART Adresse 
mitteilen, wo der Basic-Start liegt (da Compilate, also Maschinenprogramme im Gegensatz zu Basic-Programmen nicht relokatibel sind). Bei geladener Erweiterung kann man die Startadresse mit PRINT PEEK(43)+256*PEEK(44) erfahren (die Endadresse fr HEAPEND mit PRINT PEEK(55)+256*PEEK(56)). Ansonsten ist noch darauf zu achten, da die Erweiterung Werte von den Variablen holt und nicht in sie hineinschreibt. Man sollte beim Arbeiten mit Fremderweiterungen auch keine Fast-Variablen benutzen oder sicherstellen, da die Speicherstellen $FB bis $FE ungeschoren bleiben. Wenn die Erweiterung Interrupts benutzt (z.B. Raster-Interrupts zum Bildschirmsplitting), dann sollte man keinesfalls ALLRAM verwenden. Im Zweifelsfall hilft jedoch nur probieren. Das Compilat wird wie ein normales Basic-Programm geladen und gestartet. Natrlich mu die Erweiterung im Speicher sein. Ein Demoprogramm mit einer kleinen Beispielerweiterung befindet sich nebst Quellcode auf der Diskette unter dem Namen OTHER.


2.6 nderungen beim Commodore Basic V2

Aufgrund des verschiedenen Arbeitsprinzips von Interpreter und Compiler ergeben sich bei einigen der normalen Befehle Unterschiede oder neue Eigenschaften. Auerdem habe ich ein paar Befehle verbessert. All das ist im folgenden aufgefhrt.


2.6.1 Verbesserungen

An ein paar Stellen habe ich Verbesserungen oder Korrekturen vorgenommen. Diese erweitern die Mglichkeiten, fhren aber nicht dazu, da Inkompatibilitten des Compilers entstehen. Allerdings funktioniert ein Basic-Programm teilweise nicht mehr ordnungsgem unter dem Interpreter, wenn diese Mglichkeiten genutzt werden.


Hexadezimale Zahlen

Es ist nun erlaubt, Zahlen auch in hexadezimaler Schreibweise anzugeben. Eine hexadezimale Zahl beginnt mit $, dem dann beliebig viele Ziffern (0-9 und A-F) folgen knnen. Auf diese Weise knnen aber nur ganze Zahlen angegeben werden.

A=ASC(A$)

Die ASC-Funktion wurde leicht gendert. Wenn A$ leer ist, dann liefert ASC den (Byte-)Wert 0 und es erfolgt kein illegal quantity error. Dies ist sinnvoll, weil bei GET A$ ein Nullbyte zu einem Leerstring gemacht wird.

A=FRE(X)

Diese Funktion lieferte beim Interpreter die Gre des noch freien Speicherbereichs. Das Ergebnis war gelegentlich negativ (wenn der Bereich grer als 32 Kbyte war). Nun liefert sie grundstzlich die Gre des noch freien Stringspeicher, und zwar positiv.

RESTORE

kann nun auch eine Zeilennummer als Parameter haben. Wenn sich der nchste READ-Befehl zum Beispiel auf die Zeile 150 beziehen soll, so kann man nun RESTORE 150 schreiben. Damit mu man die Daten nicht mehr unbedingt von vorne nach hinten lesen und braucht nicht mehr so peinlich genau auf die Reihenfolge zu achten.

READ und DATA

An der Syntax ndert sich nichts. Trotzdem sind diese Befehle ein gutes Stck leistungsfhiger geworden. Die Compilerdirektive DATATYPE Typ ermglicht es, die Daten bei DATA bereits in ihrem Bestimmungstyp abzulegen, was Speicher spart und die Verarbeitung wesentlich beschleunigt. Nheres knnen Sie unter 2.4.1 Steuerung der Datentypen bei DATATYPE nachlesen.

FOR und NEXT

Es existiert eine zweite Version der FOR-NEXT-Schleife, die mit FASTFOR aktiviert werden kann. Nheres hierzu unter 2.4.2 Optimierungsmglichkeiten bei FASTFOR.

2.6.2 Befehle mit Sinnverlust

Einige Basic-Befehle sind hauptschlich fr den Direktmodus gedacht, weshalb gewisse Schwierigkeiten bei deren Realisierung im Compilat auftreten.

LIST, NEW, STOP

Alle drei Befehle sind fr den Basic-Boss vollkommen identisch mit END. Denn der LIST-Befehl macht im Compilat wenig Sinn, da er bestenfalls die SYS-Zeile zeigen und das Programm anschlieend sowieso beenden wrde. NEW ist im Programm ziemlich bedeutungslos und eine richtige Implementation von STOP scheint mir auch nicht sinnvoll.

CONT

ist im Programm eigentlich vllig sinnlos. Meinen Erfahrungen nach wirkt es im Basic-Programm wie eine Endlosschleife. Darum produziert auch der Basic-Boss beim Auftreten von CONT eine solche.

LOAD, SAVE, VERIFY

Sie funktionieren genauso wie unter dem Interpreter. LOAD ldt Daten in den Speicher und springt an den Programmanfang. SAVE speichert das aktuelle Programm im Basic-Speicher ab und VERIFY vergleicht es mit einem anderen Programm auf Diskette (und erzeugt gegebenenfalls einen verify error). SAVE und VERIFY wurden nur der Vollstndigkeit halber implementiert.

2.6.3 nderungen

Hier sind die Befehle aufgefhrt, die im Compilat nicht ganz so reagieren, wie unter dem Interpreter.

INPUT

Beim Konzept des INPUT-Befehls ist eine Kleinigkeit verndert: Bei INPUT A,B,C kann wie sonst auch ein redo from start-Hinweis auftauchen, wenn die Eingabe unsinnig ist. Beim Interpreter mu der Benutzer dann alle drei Werte von neuem eingeben. Beim Basic-Boss mu er die Werte ab dem Parameter eingeben, bei dem der Fehler auftrat. Die vollkommene Kompatibilitt erschien mir ziemlich sinnlos.

IF A$ THEN

Die Bedingung wird im Compilat als erfllt betrachtet, wenn A$ nicht leer ist. Der Interpreter reagiert hier scheinbar nach Lust und Laune (hin und wieder auch mit einem formula too complex error) was mich vermuten lt, da hier ein Fehler im lnterpreter vorliegt. Das einst in der Zeitschrift 64'er verffentlichte Programm TURBODIR arbeitet als Compilat nicht, da es den Betriebssystemfehler ausnutzt. Es wird dort die falsche Variable auf die Lnge 0 berprft. Da der Interpreter nicht die angegebene Variable prft, sondern die andere, funktioniert es unter dem Interpreter trotzdem.

2.6.4 Problemflle

GOSUB ... RETURN und FOR ... NEXT
Sie funktionieren im Normalfall wie erwartet, doch in einer bestimmten Situation strzt RETURN ab:

10 gosub 20: end
20 for i=1 to 10
30 goto 50
40 next i
50 return

Diese Befehlsfolge funktioniert beim Interpreter einwandfrei. Das Compilat dagegen strzt ab. Der Grund dafr ist darin zu suchen, da der Basic-Boss GOSUB und RETURN in die Maschinensprachebefehle JSR X und RTS bersetzt, was auch als das einzig sinnvolle erscheint. Diese Befehle beanspruchen aber den Stack. Da jedoch FOR seine Parameter auch auf den Stack legt, verarbeitet RETURN die Werte, die eigentlich fr NEXT gedacht waren und springt irgendwo hin. Dies knnte man mit einer speziellen Kennung der Stack-Inhalte vermeiden, hnlich wie der Interpreter das macht. Das wrde die Geschwindigkeit aber drastisch verringern. Eine solche Stack-Verwaltung ist dennoch in Planung (zuschaltbar). Es gibt brigens keinen return without gosub error, da ein berflssiges RTS aus dem Maschinenprogramm wieder ins Basic zurckspringt. Auch dies wre mit einer Kennung nicht der Fall.

DIM

Beim Gebrauch des DIM-Befehls gibt es nur wenig Einschrnkungen. Allerdings mu man sich darber im klaren sein, da der DIM-Befehl eigentlich eine Compilerdirektive ist, weshalb er bereits whrend des Kompilierens ausgewertet wird. Darum ist es nicht erlaubt, Variablen beim Dimensionieren von Feldern zu benutzen (zum Beispiel DIM A(B)). Auerdem sollte eine Variable vor ihrer Benutzung mit DIM dimensioniert sein (auch wenn sie nur elf Elemente enthalten soll), da dann teilweise ein effizienterer Code erzeugt werden kann (X-indizierte Adressierungsart). Aus der Direktiven-Natur von DIM resultiert auch das Verbot folgender Konstruktion, da sich der Compiler nicht an der tatschlichen Abarbeitungsreihenfolge orientiert, sondern die Programme von vorne nach hinten durchgeht:

10 dim a(10)
20 goto 40
30 dim a(20)
40 :
DEF FN

Da der Compiler im Gegensatz zum Interpreter die Ausdrcke nicht whrend der Programmausfhrung auswertet, ergeben sich auch hier Probleme. Eine Funktion mu vor ihrer Benutzung definiert werden (das heit in einer Zeile mit kleinerer Nummer). Eine FN-Funktion darf darber hinaus nicht mehrmals definiert werden, wie das in Basic mglich ist. Eine Schachtelung von FN-Ausdrcken ist erlaubt, ebenso eine Mischung mit Variablen des Typs Constant. Man sollte dennoch sehr sparsam mit DEF FN umgehen, da es das Compilat stark verlngern kann, denn beim Auftreten einer FN-Funktion wird sie jedesmal neu ausgewertet. Dies ist in der Natur von FN begrndet: Es handelt sich um ein Makro und nicht um ein Unterprogramm.

LOAD

Unter dem Interpreter kann ein Basic-Programm andere Basic-Programme nachladen. Das nachgeladene Programm belegt dann den Speicher seines Vorgngers und kann auf seine Variablen zugreifen. Dies funktioniert aber nur, wenn das nachgeladene Programm kleiner als sein Vorgnger ist und die Variablen keine String-Variablen sind, die in der Form A$ = "..." gesetzt wurden. Ein Basic-Boss-Compilat kann auch ein beliebiges anderes Programm nachladen. Der Nachfolger kann aber nicht auf die Variablen seines Vorgngers zugreifen. Zur Not kann man Werte mit POKE, PEEK oder mit Adrevariablen bergeben (zu empfehlen ist der Bereich von 828 bis 1023).

PRINT A, IF A THEN und STR$(A)

Bei allen drei Befehlen kann es in seltenen Fllen zu Problemen mit den Datentypen des Basic-Boss kommen. Denn bei diesen drei Befehlen ist der Mindesttyp Boolean, also der niedrigste Typ berhaupt. Wenn A ein Ausdruck ist, dann wird dieser Ausdruck in seinem Typ berechnet. Die Befehlsfolge W1=5: W2=2: PRINT W1/W2 wird zum Beispiel nicht 2.5, sondern 2 ausgeben, falls W1 und W2 Word-Variablen sind. Dessen sollte man sich bewut sein, wenn man diese Befehle benutzt. ndern kann man das mit den Direktiven PRINTTYPE und BOOLEANTYPE,
2.7 Speicherplatz und Geschwindigkeit

Die Lnge des Programms schwankt etwa zwischen 80% und 170% der Lnge des ursprnglichen Programms. Man kann sicher auch Faktoren von 10% oder 1000% erreichen, wenn man es darauf anlegt. Normalerweise wird dies jedoch nie der Fall sein. Wenn man effizient programmiert, schwankt der Faktor zwischen 80% und 120%. Dazu kommen noch die angelinkten Routinen (Stringverwaltung und all das, was normalerweise im ROM steht). Der Variablenbereich wird immer krzer. Eine als Byte deklarierte Variable bentigt nur ein Byte. Der Interpreter bentigt dagegen grundstzlich sieben Byte pro Variable. Der Geschwindigkeitsfaktor schwankt zwischen drei und 1000. Bei Verwendung von Word und Byte betrgt er etwa 50 bis 300. Bei Real liegt er zwischen zwei und acht und bei String zwischen fnf und zehn. Grenordnungsmig entspricht die Geschwindigkeit der des vor einiger Zeit im 64er-Magazin verffentlichten As-Compilers, wobei das Compilat des Basic-Boss aber noch etwas effizienter ist.



2.8 Effiziente Programme

Hier wird beschrieben, wie sie kurze und schnelle Compilate erhalten knnen. Das macht der Basic-Boss zwar ziemlich einfach, doch man mu auch selbst seinen Teil dazu tun. Wenn man kurze und schnelle Compilate erhalten will, sollte man folgende Grundregeln beachten:

2.8.1 Datentypen

2.8.1.1 Der richtige Typ

Soweit es irgendwie mglich ist, mu der Datentyp Byte verwendet werden, denn er ist der eigentliche Datentyp des C64 und darum der schnellste und krzeste. Der Wertebereich von 0 bis 255 reicht fr viele Anwendungen aus (zum Beispiel Stringverarbeitung). Falls ein grerer Wertebereich wnschenswert ist, sollte man Word-Variablen verwenden. Sie sind halb so schnell und verbrauchen doppelt so viel Platz im Programm- und im Variablenspeicher. Nach Mglichkeit sollte man auerdem FAST-Variablen benutzen (vor allem bei Adressen bei POKE- und PEEK-Adressen). Wenn man unbedingt mit vorzeichenbehafteten Zahlen rechnen will, weil man auf die Operatoren >, <, >= und <= nicht verzichten kann, dann sollte man den Integer-Typ dem Real-Typ in jedem Falle vorziehen, soweit das mglich ist, denn Integer ist in den meisten Fllen so schnell wie Word, auer bei >, <, >= und <=. Wenn diese Operatoren nicht bentigt werden, kann man auch bei Byte und Word mit vorzeichenbehafteten Zahlen rechnen, wobei man aber bei Umwandlungen und der Division aufpassen mu. Nur wenn es unvermeidbar ist, sollten Sie Real-Variablen oder -Funktionen verwenden. Ebenso sollte man Strings so weit als mglich vermeiden. Allerdings bentigen Operationen mit Strings oder Real-Zahlen aufgrund eines uerst sparsamen Parameterbergabe-Prinzips weniger Programmspeicher als die meisten Operationen mit Word und Integer (zum Beispiel Addition: 17 bis 19 Byte bei Word, 9 Byte bei Real).

2.8.1.2 Umwandlungen

Es ist uerst wichtig, unntige Umwandlungen zu vermeiden. Man sollte bei Befehlen oder Operationen grundstzlich die Typen benutzen, die erwartet werden. Welche das sind, lt sich bei 2.3 Datentypen unter Typen bei Funktionen und Befehlen nachlesen. Der Befehl POKE A,B ist zum Beispiel grauenhaft ineffizient, wenn A und B vom Typ Real sind.
Dann wird eine Operation (POKE) zu drei Operationen gemacht (A<-Word, B<-Byte, POKE) und die Geschwindigkeit stark reduziert. hnlich ist es bei den anderen Befehlen. Es gibt aber auch ein paar Umwandlungen, die beliebig verwendet werden drfen, weil sie weder Speicherplatz noch Zeit bentigen. Dies sind: Boolean<-->Byte, Word<-->Integer, Integer<-->Byte und Word<-->Byte. Nur wenig Platz und Zeit bentigen folgende Umwandlungen: Byte<-->Word, Byte<-->Integer. Vor allem sind Umwandlungen von und nach Real zu vermeiden. Man sollte den Datentyp fr eine Variable auch anhand deren Verwendung entscheiden. Wenn zum Beispiel die Variable A nur die Werte 0 und 1 annimmt, sollte man sie trotzdem nicht als Byte definieren, sondern als Real, falls sie ausschlielich mit Real-Variablen verrechnet werden soll.

2.8.2 Konstanten, Operationen, Befehle, Arrays

Konstanten

Die Verwendung von konstanten Zahlen anstatt von Variablen beschleunigt die Verarbeitung bei Byte, Word und Integer und spart Speicherplatz. Vor allem bei Adressen fr POKE und PEEK sollte man Konstanten verwenden (oder FAST-Variablen). Wenn Sie aber keine nichtsagenden Zahlen verwenden wollen, so hilft Ihnen der Datentyp Constant.

Operationen

Wenn Sie mit Word, Integer und Byte arbeiten, sollten Sie mglichst nur einfache Operationen verwenden (Addition, Subtraktion, Zuweisung, Vergleiche, AND, OR). Operationen wie die Multiplikation, Division oder gar Potenzierung sollten vermieden werden, wobei aber fr Multiplikation und Division spezielle Routinen fr Word und Integer benutzt werden, die noch relativ schnell sind. Unbedingt zu vermeiden sind folgende Funktionen: SIN, COS, TAN, ATN, EXP, LOG, SQR, RND und vor allem Potenzierung. Wie das hufig realisiert werden kann, wird spter bei 2.8.4 Tabellen beschrieben.

Befehle

Die Befehle wurden grtenteils stark beschleunigt. Dies gilt in besonderem Mae fr:
POKE, PEEK, GOTO, GOSUB, RETURN, FOR ... NEXT (FASTFOR), LET, ON, WAIT.

Sogar der PRINT-Befehl ist bei Word, Integer und Byte um einiges schneller, da spezielle Ausgaberoutinen fr diese Typen bestehen.

Arrays

Vermeiden Sie mehrdimensionale Arrays, denn diese sind sehr langsam, da zu deren Berechnung Multiplikationen notwendig sind und zwar genau (Dimensionen-1) Stck. Vermeiden Sie auch Arrays vom Typ Real und String und verwenden Sie SLOWARRAY nur zum Austesten. Bei eindimensionalen Arrays brauchen Sie sich bei den Datentypen Integer, Word oder Byte keine Sorgen hinsichtlich der Geschwindigkeit zu machen, da der Zugriff auf diese Arrays aufgrund spezieller Algorithmen sehr schnell erfolgt. Dimensionieren Sie Ihre Felder immer ganz am Anfang des Programms, auch wenn Sie nicht mehr als elf Elemente bentigen (DIM A(10)). Denn um eine besonders effiziente Adressierungsart des Prozessors 6510 anwenden zu knnen, mu der Basic-Boss von Anfang an wissen, wie gro ein Array ist. Dies gilt aber nur fr eindimensionale Arrays vom Typ Word, Integer oder Byte, die weniger als 128 oder 256 Elemente beherbergen. Falls Sie mehrdimensionale Arrays verwenden, sollten Sie bei den hinteren Dimensionen Konstanten verwenden, soweit das mglich ist. Sie sollten Ihre Arrays also so anlegen, da Sie statt A (10,I) die Form           A (I,10) verwenden. Damit sparen Sie eine Multiplikation und viel Zeit, weil der Basic-Boss das Array teilweise selbst berechnet und das Compilat nur den Rest berechnen mu. Bei A (I,10,15) werden so zwei Multiplikationen gespart.


2.8.3 Vermeidung berflssiger Befehlsausfhrung

Sie sollten Ihre Programme so schreiben, da nur die Befehle ausgefhrt werden, die ntig sind. Insbesondere sollte man die unntige Verarbeitung von Realzahlen oder Strings vermeiden. Folgendes Programm kann man zum Beispiel wesentlich beschleunigen:

10 get a$ 
20 if a$="a" then ... 
30 if a$="b" then ... 
40 ... 
50 rem hier gehts weiter 

indem man folgende Zeile ndert:

10 get a$:if a$="" then 50

Noch einmal wesentlich schneller geht es so:

5 if peek(198)=0 then 50
10 get a$

Hier wird berprft, ob der Tastaturpuffer leer ist. Wenn ja, wird berhaupt keine Stringoperation durchgefhrt. Dies ist die optimale Lsung.

2.8.4 Tabellen

Stark beschleunigen kann man seine Programme mit Hilfe von Tabellen. Betrachten Sie zum Beispiel einmal folgende Routine zum Setzen eines Punktes auf den Bildschirm. X (0 bis 39) und Y (0 bis 24) enthalten die Position und die Routine wird mit GOSUB 1000 aufgerufen. Alle Variablen seien vom Typ Word (weil sie mit Word verrechnet werden).

1000 poke 1024+40*y+x,160: return

Wenn diese kleine Routine hufig aufgerufen wird, dann wird das Programm ziemlich lang-sam, da die Multiplikation verwendet wurde. Die Additionen fallen kaum ins Gewicht. Es geht aber auch besser. Man kann sich die Multiplikation sparen, wenn man alle mglichen Multi-plikationen schon vorher ausfhrt und dann nur noch die Ergebnisse benutzt. Das geht so:

10 dim sc(24)
20 gosub 2000
30 ...
1000 poke sc(y)+x,160: return
2000 for y=0 to 24: sc(y)=1024+y*40: next y: return

Nun werden die Multiplikationsergebnisse am Programmbeginn in ein Array eingelesen, weshalb im Programm direkt auf sie zugegriffen werden kann. hnliches kann man zum Beispiel auch bei Sinuswerten oder bei den oft bentigten Zweierpotenzen machen, denn Sinusberechnung und Potenzierung sind noch langsamer.
2.8.5 Verkrzung von Berechnungen

Sehen Sie sich folgende Programmzeile an:

10 a=10+20

Wenn man den Interpreter mit RUN startet, so fhrt dieser eine unntige Addition aus. Denn statt 10+20 wre es doch sinnvoller, einfach 30 zu schreiben. Wenn man die Zeile kompiliert und das Comnpilat untersucht, wird man feststellen, da dieses keine Addition durchfhrt. Der Basic-Boss hat also erkannt, da er hier selbst etwas vereinfachen kann und bereits whrend dem Kompilieren 10 und 20 zusammengezhlt, weshalb das Compilat fr A=10+20 oder A=30 exakt dasselbe ist. Diese Sofort-Berechnungen kann der Compiler mit den Grundrechenarten +, -, * und / durchfhren. Auerdem kann er potenzieren oder negieren (zum Beispiel -(l+2) ). Alle diese Berechnungen werden grundstzlich im Real-Typ durchgefhrt. Auch beim Ausdruck 1+2+A kann der Compiler vereinfachen. Bei A+1+2 hat er aber Schwierigkeiten. Darum sollte man A+(1+2) schreiben, wenn man effizienten Code haben will.

2.8.6 FASTFOR, DATATYPE, SHORTIF

Soweit es mglich ist, sollte FASTFOR verwendet werden (siehe unter 2.4.2 Optimierungs-mglichkeiten und FASTFOR). Bei Verwendung von DATA und READ sollten Sie mit DATATYPE Typ unbedingt den Typ der Daten spezifizieren (nheres bei DATATYPE). Auerdem ist SHORTIF zu empfehlen.


2.9 Anpassung vorhandener Programme

Vermutlich besitzen Sie Basic-Programme, die Sie zu einer Zeit schrieben, als Sie vom Basic-Boss noch nichts wuten. Wenn Sie ein solches Programm an den Basic-Boss anpassen wollen, dann ergeben sich eine Reihe charakteristischer Probleme. Wenn Sie diese meistern wollen, dann sollten Sie folgende Schritte beachten: Achten Sie auf DIM und DEF FN und stellen Sie fest, ob diese Befehle in unzulssiger Weise benutzt werden. DEF FN mu am Programmanfang stehen (vor der Verwendung der Funktion) und bei DIM drfen keine Variablen zur Definition von Arrays verwendet werden (siehe nderungen beim Commodore-Basic V2 unter 2.4.6 Problemflle).
Stellen Sie dann fest, ob das Programm irgendeinen Speicher belegt, zum Beispiel fr nachzuladende Maschinenprogramme oder fr einen vernderten Zeichensatz oder hnliches. Ein sicheres Merkmal hierfr ist ein POKE-Befehl, der die Adresse 56 (Basic-Speicherende) zum Ziel hat. Meist folgt diesem Befehl der CLR-Befehl. Den POKE-Befehl sollten Sie dann entfernen und stattdessen die Compilerdirektive HEAPEND Adresse benutzen, die dem Basic-Boss das Basic-Speicherende direkt angibt. Mit ihr knnen Sie sicherstellen, da das Compilat den reservierten Bereich unangetastet lt. Sie sollten auch alle anderen POKE-Befehle entfernen, die die Adressen 43 bis 56 betreffen. Falls der dem Compilat verbleibende Speicherbereich nicht ausreicht (der Compiler meldet heapend unter heapstart), dann mssen Sie entweder den reservierten Bereich verlegen oder einen Teil des Compilats (Programmbereich, Variablenbereich oder Stringbereich) an einen anderen Ort legen (mglicherweise wird ALLRAM ntig). Auf jeden Fall sollten Sie sicherstellen, da kein POKE-Befehl im Programm auf einen der Bereiche des Compilats zugreift.
Wenn das Basic-Programm sehr lang ist, knnen Sie vorsorglich ALLRAM verwenden. Dabei ist allerdings darauf zu achten, da dann der gesamte Speicher benutzt wird. Wenn zum Beispiel ein Maschinenprogramm ab $C000 (49152) liegt, dann sollten Sie das Basic-Speicherende mit HEAPEND $C000 vor diesen Bereich legen. Wenn sich SYS-Befehle mit angehngten Parametern im Programm befinden, dann wird OTHERON ntig. Dabei ist allerdings sicherzustellen, da die Maschinenroutinen nicht versuchen, die bergebenen Variablen zu verndern, sondern nur deren Wert verarbeiten. Auch vertragen sich nicht alle Maschinenprogramme mit dem Basic-Boss. Hier hilft am besten Ausprobieren. Im Gegensatz zu anderen Sprachen gibt Basic nicht gerade Hilfestellung zum strukturiertem Programmieren, dies wird eher von den unbequemen Zeilennummern und dem Konzept der globalen, zweistelligen Variablen noch erschwert. Darber hinaus halten es viele Basic-Programmierer mit der Ordnung nicht allzu genau, weshalb ein Basic-Programm leicht in ein unkontrollierbares Chaos ausarten kann. Darum ist bei der Anpassung im besonderen folgendes zu beachten:
Ein Basic-Programm arbeitet im Normalfall ausschlielich im Realtyp. Da aber das Compilat bei Berechnungen in diesem Typ nicht bermig schnell ist, wrden Sie sicher gerne auch die restlichen Typen des Basic-Boss nutzen. Dies sollte man aber sehr sparsam tun, da bei einem Basic-Programm nicht so leicht festzustellen ist, wo welche Variablen benutzt werden. Darum ist es anzuraten, nur einige wenige Variablen umzudefinieren, die an zentralen und fr die Geschwindigkeit besonders bedeutsamen Orten benutzt werden. Man mu genau wissen, wo diese Variablen berall gebraucht werden, damit sichergestellt ist, da sie nicht andernorts vom Typ Real sein mssen, whrend man sie als Word, Integer oder Byte deklariert. Der Code wird auf diese Weise zwar recht lang, doch das lt sich meist verkraften (ALLRAM). Fr diese Arbeit kann ein Crossreference-Programm sehr ntzlich sein, das genau anzeigt, wo welche Variablen benutzt werden.
Hin und wieder stellt auch die FOR-NEXT-Schleife ein Problem dar. Wenn in einem Unterprogramm aus einer Schleife mit GOTO herausgesprungen wird, dann riskieren Sie in Basic nur einen Stackberlauf, das Compilat strzt dagegen beim nchsten RETURN ab (siehe unter nderungen beim Commodore Basic V2 unter 2.6.4 Problemflle). Verhindern knnen Sie dies, indem Sie nicht mit einem bloen GOTO aus der Schleife springen, sondern die Schleifenvariable zunchst auf den Endwert setzen, einen NEXT-Befehl ausfhren, der dann nicht wieder zum Anfang der Schleife fhrt, weshalb Sie nun unbehindert mit GOTO arbeiten knnen. Zu diesem Thema finden Sie ein Beispielprogramm namens FORRETURN auf der Basic-Boss-Diskette.

2.10 Es funktioniert nicht

Wenn Ihr Programm Schwierigkeiten macht, dann sind folgende Grnde denkbar:

-  Das Programm ist in sich fehlerhaft
-  Die Datentypen werden falsch angewandt
-  Das Programm vertrgt die Eigenheiten des Compilers nicht

Wenn die erste Mglichkeit zutrifft, kann ich Ihnen nicht weiterhelfen. Dann mssen Sie nach den allgemeinen Regeln fr das Ausmerzen von Fehlern verfahren. Wenn Sie aber den Verdacht haben, die Datentypen falsch anzuwenden, knnen Sie versuchsweise alle Variablen auf Real setzen, indem Sie smtliche Deklarationen unwirksam machen (mit IGNORE und USE) oder indem Sie den @ hinter den REM-Befehlen entfernen. Das Compilat wird dann zwar ziemlich lang und ineffizient, wenn aber der Speicher ausreicht (zur Not kann man ALLRAM zu Hilfe nehmen) und das Programm dann luft, so ist dies ein Hinweis darauf, da irgendeine Variable vom Typ Real sein sollte, dies aber nicht ist. Nun knnen Sie den Fehler suchen, indem Sie entweder aus den Reaktionen des Programms schlufolgern oder die Variablen grppchenweise wieder auf den Wunschtyp umdefinieren. Wenn das Programm dann auch nicht luft, drfte wohl eine Eigenheit des Compilers daran schuld sein. Wahrscheinlich wird aus einer FOR-NEXT-Schleife gesprungen, weshalb das Compilat beim darauffolgenden RETURN abstrzt. Mglich ist auch, da das Basic-Programm Maschinenroutinen aufruft, die sich mit dem Compilat nicht vertragen. Dabei ist eine berlappung von Speicherbereichen denkbar, da das Compilat hufig lnger ist als das Original. Dazu sollten Sie sich die 2.6.4-Problemflle unter nderungen beim Commodore-Basic V2 ansehen. Schlielich kommt noch ein Fehler im Basic-Boss in Betracht. Ein solcher ist durchaus mglich, weil der Basic-Boss noch sehr jung ist. In einem solchen Falle sollten Sie sicherstellen, da tatschlich ein Compilerfehler vorliegt. Das Programm sollte also unter dem Interpreter einwandfrei laufen und die oben beschriebenen Fehler sollten weitgehend ausgeschlossen sein. Dann wre ich Ihnen beraus dankbar, wenn Sie den Fehler so weit als mglich isolieren knnten, das heit, das fehlerhafte Programm sollte mglichst kleingemacht werden, ohne da der Fehler verschwindet. Anschlieend sollten Sie mir das fehlerhafte Programm mit mglichst genauer Fehlerbeschreibung (Auswirkungen des Fehlers) zuschicken; sehr, sehr kleine Programme als Ausdruck und alles, was darber hinausgeht, auf Diskette. Dabei drfen Sie die Versionsnummer Ihres Compilers auf keinen Fall vergessen.

2.11 Rechtliches

Das Compilat enthlt von mir verfate Routinen und Algorithmen, vor allem im Routinenbereich. Trotzdem beanspruche ich kein Urheberrecht auf das Compilat, sofern diese Routinen nicht ausgebaut und fr andere Zwecke verwendet werden. Das Compilat kann also uneingeschrnkt kopiert Oder verkauft werden, soweit der Autor des kompilierten Basic-Programms dies zult. Bei ihm allein liegt das Urheberrecht fr das kompilierte Programm. Allerdings halte ich es fr fair, wenn im Programm oder der Anleitung erwhnt wird, da es mit dem Basic-Boss kompiliert wurde. Fr den Compiler selbst gilt das volle Urheberrecht. Ebenso gilt es fr die Compileranleitung. Beides darf nicht (auch nicht teilweise) ohne schriftliche Genehmigung kopiert oder in irgendeiner Weise vervielfltigt werden. Fr vom Compiler verursachte Schden wird brigens keine Haftung oder juristische Verantwortung bernommen.


2.12 Fehlermeldungen

Es gibt zwei Sorten von Fehlermeldungen. Die einen meldet der Basic-Boss bereits whrend des Kompilierens und die anderen erscheinen erst bei der Ausfhrung des Compilats.

2.12.1 Die Meldungen des Basic-Boss

Diese Meldungen erscheinen whrend des Kompiliervorganges. Da es sich bei dem Basic-Boss um einen Zwei-Pass-Compiler handelt, tauchen die meisten Fehlermeldungen doppelt auf (einmal in Pass 1 und einmal in Pass 2). Die Fehlermeldung besteht aus mindestens zwei Zeilen. In der ersten Zeile werden Zeilennummer und dahinter eine Art Extrakt der Zeile dargestellt. Dieser Extrakt besteht aus den verwendeten Rechenoperatoren, einem Punkt fr jeden Befehl und den Doppelpunkten, die die Befehle trennen. Der Extrakt erlaubt eine genauere Lokalisation des Fehlers. Zumindest die Doppelpunkte geben einen genauen Aufschlu ber die Position des Fehlers und auch die Operatoren knnen ntzlich sein. Wenn gelegentlich unbekannte Operatoren auftauchen (z . B. k,g,v,u ....), so sollten Sie sich nicht weiter darum kmmern, da dies einer internen Darstellung im Basic-Boss entspringt. Die Zeile darunter enthlt die Fehlernummer gefolgt von der eigentlichen Fehlermeldung. Die Fehlernummer erleichtert das Auffinden in der Fehlerliste. Es gibt auch einige Fehler, die nie erscheinen drfen und deren Text nur fr mich einen Sinn ergibt. Falls nmlich keine Fehlernummer angezeigt wird und der Fehler mit einem Pfund-Zeichen beginnt, dann zeigt das ein Problem im Basic-Boss an, das eigentlich nicht existieren drfte. In solchen Fllen kann eine Aufteilung eines komplizierten Ausdrucks in mehrere kleinere Ausdrcke das Problem beheben. Ein Pfund-Fehler kann auch auftauchen, wenn bestimmte Fehler vorausgegangen sind, die den Basic-Boss unvermittelt aus der Befehlsbearbeitung herausgerissen haben. In diesen Fllen lst sich das Problem mit der Behebung der anderen Fehler von selbst. Man sollte sich beim Auftreten eines Fehlers nicht auf die angegebene Fehlerursache versteifen, da hufig verschiedenartige Schreibfehler zum gleichen Fehler fhren. Darum sollte man bei unauffindbaren Schwierigkeiten die allgemeine Syntax an der Fehlerstelle berprfen. Insbesonders den vorangehenden Ausdruck sollte man genau untersuchen, da in ihm ein Fehler stecken kann, der den Compiler veranlat, das Ausdrucksende zu frh zu vermuten, was zu einer Vielzahl von Fehlermeldungen fhren kann. Bei lngeren Variablennamen sollte man sich davon vergewissern, da sie keine Basic-Befehle enthalten, da auch dies vielfltige Auswirkungen haben kann. Wenn ein Fehler angezeigt wurde, kann ich fr die Funktionstchtigkeit des Compilats nicht mehr garantieren. Einige Fehler sind so schwerwiegend, da der Compiliervorgang bei ihrem Auftreten sowieso abgebrochen wird. Wenn als Fehlerzeile 65535 angezeigt wird, dann trat der Fehler nach Bearbeitung der letzten Programmzeile auf.

Die Fehlerliste

Die Fehler sind nach ihrer Nummer geordnet. Diese Ordnung erhebt keinen Anspruch darauf, sinnvoll zu sein, da die Liste nur zum Nachschlagen gedacht ist. Dem Fehler folgen eine nhere Beschreibung des Problems und eventuell Vorschlge zu dessen Behebung.

1/HEAPEND IST UNTER HEAPSTART
Das Ende des Stringspeichers liegt unter dessen Anfang. Das ist typischerweise dann der Fall, wenn das Compilat zu lang wird und nicht mehr in den Basic-Speicher pat, weshalb es ber das Stringspeicherende (normalerweise 40960 bzw. $A000) hinausragt. Abhilfe schafft hier z.B. der ALLRAM-Befehl und/oder das Verlegen des Stringspeichers mit HEAPSTART und HEAPEND. Der Fehler tritt auch dann auf, wenn Sie das Compilat in einen anderen Speicherbereich legen, z.B. nach $C000. Dann mu ebenfalls HEAPEND angewandt werden.
2/DIVISION DURCH NULL

Es wird eine Berechnung mit direkten Zahlen ausgefhrt, die eine Teilung durch 0 verlangt (z.B. PRINT 2/0).

3/BEREICHSUEBERSCHREITUNG

Der Zahlenbereich von Real wird bei einer direkten Berechnung berschritten (z.B. PRINT 10 ^ 50).

4/FEHLER BEI DER BERECHNUNG

Es ist bei einer direkten Berechnung irgendein Rechenfehler aufgetreten, der nicht genauer bekannt ist.

5/ABBRUCH MIT RESTORE

Whrend der Kompilierung wurde <RESTORE> gedrckt.

7/CODE VERSCHOBEN

Der erzeugte Code der vorangegangenen Zeile in Pass 2 ist gegenber dem in Pass 1 erzeugten Code krzer oder lnger. Dieser Fehler darf nur dann auftreten, wenn andere Fehler vorausgegangen sind (z.B. Konstante nicht definiert). Er verschwindet, wenn die anderen Fehler behoben sind. Wenn er allein auftritt, dann wurde einer Variablen zweimal der gleiche Wert zugeordnet.

8/FALSCHER IF-ZWEIG

Wenn dem Ausdruck nach IF weder GOTO noch THEN folgt, dann erscheint dieser Fehler. Es kann aber auch der Ausdruck nach IF in einer Art und Weise fehlerhaft sein, da der Compiler das Ausdrucksende zu frh vermutet.
9/UNBEKANNTER TOKEN

Diese Meldung erscheint dann, wenn der Basic-Boss einen Token (ein codierter Basic-Befehl) findet, den er nicht kennt. Das ist meist bei der Kompilierung von Programmen der Fall, die mit Hilfe einer Basic-Erweiterung erstellt wurden und Befehle dieser Erweiterung enthalten.


10/ES IST LONGIF NOTWENDIG

Dieser Fehler kann nur im SHORTIF-Modus auftauchen und zeigt an, da die IF-Zeile fr diesen Modus zu viel Speicher bentigt. Abhilfe schafft der LONGIF-Befehl entweder am Programmanfang oder kurz vor der bemngelten Zeile. Hinter dieser Zeile kann man wieder auf SHORTIF umschalten (fr eine automatische Umschaltung bruchte man einen dritten Pass).


11/ZU VIELE PARAMETER

Hier vermutet der Basic-Boss einen Befehl mit zu vielen Parametern. Der Fehler kommt dann zustande, wenn der Basic-Boss am Befehlsende angekommen zu sein glaubt, dann aber weder einen Doppelpunkt noch ein Zeilenende findet. Eine typische Ursache sind z.B. an den SYS-Befehl angehngte Parameter. Dann ist der OTHERON-Befehl zu empfehlen.


12/UNZULAESSIGE ZUWEISUNG

Es wurde z.B. versucht, einer Systemvariablen etwas zuzuweisen, obwohl dies nicht erlaubt ist. Dies ist z.B. bei TI der Fall. ST kann man dagegen etwas zuweisen.


13/UNBEKANNTER BEFEHL (=)

Der Compiler glaubt, eine Variablenzuweisung zu bearbeiten, findet aber hinter der vermuteten Variable kein Gleichheitszeichen. Dann liegt meist ein Befehl vor, der falsch geschrieben wurde und den der Editor des Interpreters darum nicht als Token erkannt hat. Es kann sich aber auch um einen langen Variablennamen handeln, der Basic-Befehlsworte enthlt, was nicht erlaubt ist.

14/UNBEKANNTER ZUSATZBEFEHL

Der Compiler hat den Zusatzbefehl hinter dem Linkspfeil nicht erkannt. Vermutlich wurde er falsch geschrieben oder es handelt sich um den Befehl einer Basic-Erweiterung.

15/ADRESSBEFEHL ZU SPAET

Ein Befehl wie ROUTSTART, PROGSTART usw. steht nicht am Anfang des Programms, wie es eigentlich sein sollte und kann daher nicht verwertet werden.

16/COMPILERDIREKTIVE UNBEKANNT

Der Compiler hat eine mit einem Pfundzeichen eingeleitete Compilerdirektive nicht verstanden. Es liegt vermutlich ein Schreibfehler vor.

17/DATENTYP ERWARTET

Der Compiler hat an dieser Stelle einen Datentyp wie Byte oder Word erwartet. Vermutlich liegt ein Schreibfehler vor.

18/ZU LANGER NAME

Der angegebene Dateiname ist zu lang und wurde auf 20 Zeichen gekrzt. Dieser Fehler tritt auch bei SYSTEXT auf.
19/DATEINAME ERWARTET

Der Compiler hat an dieser Stelle einen in Anfhrungszeichen gesetzten Dateinamen erwartet. Vermutlich fehlt das Anfhrungszeichen. Dieser Fehler kann auch bei SYSTEXT auftreten,


20/ES WURDE BEREITS CODE ERZEUGT

Der Basic-Boss hat eine Direktive gefunden, die nicht am Anfang eines Programms steht, dort aber stehen sollte, da sie sonst nicht einwandfrei funktioniert (z.B. SETPREFERENCES).


21/FOR OHNE NEXT (FASTFOR)

Der Fehler tritt nur im FASTFOR-Modus auf und dann auch nur am Ende des Programms oder beim SLOWFOR-Befehl. In beiden Fllen mssen nmlich smtliche FOR-Schleifen abgeschlossen sein. Sind sie dies nicht, so erfolgt dieser Fehler. Man sollte also nach einem FOR-Befehl suchen, fr den noch kein NEXT-Befehl existiert.


22/GO OHNE TO

Statt GOTO kann man auch GO TO schreiben. Wenn man jedoch GO ohne TO schreibt, beschwert sich der Basic-Boss.


23/UNBEKANNTE ZEILE

Es wurde eine Zeilennummer verwendet, fr die keine Zeile existiert. Man sollte also untersuchen, wohin man eigentlich springen will, um dann entweder die vorangehende oder die nachfolgende Zeile anzusprechen.
24/',' ODER ')' ERWARTET

Beim DIM-Befehl wird hinter jeder Dimensionsangabe entweder ein Komma oder eine schlieende Klammer erwartet. Vermutlich wurde das Ausdrucksende zu frh vermutet, wofr irgendein Schreibfehler verantwortlich sein drfte.

25/FALSCHE DIMENSIONSANZAHL

Beim DIM-Befehl wurde ein Array dimensioniert, das bereits im vorangegangenen Programmtext verwendet wurde. Dabei mssen jeweils gleich viele Dimensionen benutzt werden. Wenn dies nicht beachtet wird, dann erscheint dieser Fehler.

26/'=' ERWARTET

Hinter der bei FOR angegebenen Schleifenvariablen mu ein = stehen, das der Basic-Boss hier nicht finden kann. Mglich ist auch ein langer Variablenname, in dem sich Basic-Befehle befinden, was nicht erlaubt ist.


27/'TO'ERWARTET

Beim FOR-Befehl wurde an der Stelle von TO etwas anderes gefunden. Mglich ist ein Schreibfehler oder ein Fehler in der Zuweisung hinter FOR, so da dessen Ende zu frh vermutet wird.

28/NEXT OHNE FOR (FASTFOR)

Es wurde im FASTFOR-Modus versucht, eine Schleife mit NEXT abzuschlieen, die es gar nicht gibt. Ursache hierfr knnte z.B. sein, da der FASTFOR-Befehl im Programm hinter dem angepeilten FOR-Befehl steht statt davor. In jedem Fall sollte man das FOR-NEXT-Gefge untersuchen.

30/UNERLAUBTER ZAEHLERTYP

Bei FOR drfen als Zhlervariable nur numerische Variablen verwendet werden und keine String-Variablen. Auch Arrays sind verboten.


31/KOMMA ERWARTET

Der Basic-Boss erwartet an dieser Stelle ein Komma. Es kann allerdings auch sein, da das Ende des vorangegangenen Ausdrucks zu frh vermutet wird. Man sollte hier im Zweifelsfall den gesamten Ausdruck berprfen.


32/NACH DEM INPUTSTRING MUSS ';' FOLGEN

Wenn nach dem INPUT-Befehl ein in Anfhrungszeichen geklammerter String steht, mu nach diesem String ein ; folgen. Danach folgt die einzulesende Variable.


33/NACH ON MUSS GOSUB ODER GOTO FOLGEN

Nach dem ON-Befehl folgt ein Ausdruck, dem wiederum GOTO oder GOSUB folgen. Wenn diese Reihenfolge nicht eingehalten wird, erfolgt dieser Fehler. Mglich ist auch ein Fehler im Ausdruck hinter ON, der dazu fhrt, da das Ausdrucksende zu frh vermutet wurde.


34/DAS ARRAY WURDE BEREITS DIMENSIONIERT

Es wurde versucht, ein Array zweimal mit DIM zu dimensionieren. Man sollte die andere DIM-Anweisung suchen und eliminieren.


35/FALSCHE NEXT-VARIABLE (FASTFOR)

Dieser Fehler tritt nur im FASTFOR-Modus auf. Es wird versucht, eine FOR-Schleife mit NEXT X abzuschlieen, wobei aber die bei NEXT angegebene Variable nicht mit der bei FOR angegebenen identisch ist. Entweder wurde die Variable falsch geschrieben oder das FOR-NEXT-Gefge ist durcheinander.

36/BEI DER FELDDIMENSIONIERUNG DUERFEN KEINE VARIABLEN 
VERWANDT WERDEN

Wenn Sie ein Array mit DIM A(B) dimensionieren, dann erhalten Sie diesen Fehler, weil der Basic-Boss keine variable Dimensionierung verarbeiten kann. Man mu also konstante Zahlen verwenden wie z.B. DIM A(1000). Falls die Feldgre vor dem Programmstart nicht bekannt ist, mu man das Feld wohl oder bel auf die grtmgliche Gre dimensionieren und dabei Speicherplatzverluste in Kauf nehmen. (Siehe auch unter nderungen beim Commodore-Basic V2 in Kapitel 2.6.4 Problemflle.)

38/NUMMER ERWARTET

Es wurde eine Zahl zwischen 0 und 65535 erwartet. Es darf an dieser Stelle keine Variable verwendet werden.

39/KLAMMER ZU FEHLT

Es fehlt eine schlieende Klammer im Ausdruck, oder das Ausdrucksende wird zu frh vermutet. Mglich ist auch eine berzhlige ffnende Klammer.

40/ZAHL ERWARTET

Es wurde eine Zahl erwartet. Ein String, eine Variable oder ein arithmetischer Ausdruck an dieser Stelle lsen den Fehler aus. Dieser Fehler kann z.B. bei DATA auftauchen, wenn der Datentyp numerisch gewhlt wurde (z.B. mit DATATYPE Byte).
41/KLAMMER AUF FEHLT

Es fehlt eine ffnende Klammer im Ausdruck, oder eine schlieende Klammer ist berzhlig.

42/ZU VIELE FUNKTIONSPARAMETER

Es wurde versucht, einer Funktion zu viele Parameter mitzugeben. Mglich ist auch eine fehlende schlieende Funktionsklammer bei verschachtelten Funktionen und Arrays.

43/DAS KOMMA MUSS INNERHALB EINER 
FUNKTIONS/ARRAY-KLAMMERUNG STEHEN

Der Basic-Boss kann mit einem im Ausdruck auftretenden Komma nichts anfangen. Dieser Fehler kann nur innerhalb einer Klammerung auftreten.

44/STRING HIER NICHT ERLAUBT

Der Fehler wird ausgelst, wenn in einer Funktion ein Stringausdruck verwendet wird, obwohl ein numerischer Ausdruck verlangt ist (z.B. PRINT ABS(A$)).

45/ZUWENIG FUNKTIONSPARAMETER

Einer Funktion wurden zuwenig Parameter mitgegeben. Denkbar ist auch eine berflssige schlieende Klammer.

46/ZUVIEL ARRAYPARAMETER

Es wurde versucht, bei einem Array mehr Dimensionen anzusprechen, als dieses laut seiner Definition mit DIM besitzt (die erstmalige Verwendung eines Arrays betrachtet der Basic-Boss auch als Definition). Mglich ist aber auch eine fehlende schlieende Klammer bei verschachtelten Funktionen und Arrays.

47/ZUWENIG ARRAYPARAMETER

Es wurden bei der Verwendung von Arrays weniger Dimensionen angegeben, als diese laut ihrer Definition mit DIM besitzen (die erstmalige Verwendung eines Arrays betrachtet der Basic-Boss auch als Definition). Mglich ist aber auch eine berzhlige schlieende Klammer bei verschachtelten Funktionen und Arrays.


48/DAS ARRAY MUSS MINDESTENS EINDIMENSIONAL SEIN

Wenn bei der erstmaligen Benutzung eines Arrays weniger als ein Parameter angegeben wird, dann erscheint dieser Fehler.


49/UNERWARTETES AUSDRUCKENDE

Wenn ein Ausdruck unvermittelt abbricht, dann erhalten Sie diese Meldung. Der Basic-Boss erwartete hier mglicherweise noch eine Zahl.


50/DEKLARATION ZU SPAET

Die Deklaration einer Variablen mittels einer Compilerdirektive (z.B. WORD A,B)
erfolgte erst, nachdem bereits der Code erzeugt wurde. Darum kann die Deklaration dieser Variablen nicht bercksichtigt werden. Sie sollte deshalb mglichst am Anfang des Programms stehen.


51/EIN STRING KANN NICHT IN EINE ZAHL UMGEWANDELT WERDEN

Es wurde ein Stringausdruck an einer Stelle benutzt, an der ein numerischer Ausdruck htte stehen sollen.
52/EINE ZAHL KANN NICHT IN EINEN STRING UMGEWANDELT WERDEN

Es wurde ein numerischer Ausdruck an einer Stelle benutzt, an der ein Stringausdruck htte stehen sollen. Mglicherweise wurde versucht, einen numerischen Ausdruck mit einem String zu verknpfen.


53/FUNKTIONSPARAMETER MUESSEN IN 
KLAMMERN EINGESCHLOSSEN SEIN

Hinter einer Funktion fehlt die ffnende Klammer, die dort unbedingt stehen mu (A = SIN 10 ist nicht mglich). Man kann auf die Umklammerung also grundstzlich nicht verzichten.


54/DEKLARATION EINER SYSTEMVARIABLEN

Es wurde versucht, eine Systemvariable (wie TI, TI$, ST) zu deklarieren, was aber sinnlos ist, weil diese bereits von vornherein deklariert sind.


55/VARIABLE ERWARTET

An dieser Stelle wurde eine Variable oder gegebenenfalls auch eine Zahl erwartet, aber nicht gefunden.


57/DER SPEICHER IST ZU KNAPP

Dem Basic-Boss ist sein interner Speicher fr Variablen, Zeilennummern, Konstanten usw. ausgegangen. Dies drfte recht selten der Fall sein, da der Basic-Boss ab Version 2.2 sehr sparsam mit seinem Hauptspeicher umgeht.

58/DIMENSION UEBERSCHRITTEN

Bei der Verwendung von Konstanten als Parameter bei Array-Variablen kann der Basic-Boss sofort feststellen, ob diese Parameter den dimensionierten Bereich berschreiten. Wenn also  z. B. DIM A(15) im Programm steht und an anderer Stelle PRINT A(20) verwendet wird, dann erscheint dieser Fehler.

60/DISKFEHLER:...

Das Floppy-Laufwerk hat dem Compiler einen Fehler signalisiert. Hinter DISKFEHLER: erhalten Sie dann die Meldung, die aus der Floppy ausgelesen wurde. Deren Bedeutung knnen Sie im Floppy-Handbuch nachschlagen. Nachdem ein Diskfehler aufgetreten ist, wird der Kompiliervorgang abgebrochen.

61/'FAST'ERWARTET

Wenn bei der Deklaration hinter einer Variablen ein Gleichheitszeichen folgt, dann mu diesem entweder eine Zahl oder FAST folgen. Ansonsten erscheint dieser Fehler (siehe unter Datentypen bei 2.3.2 Die Deklaration).

62/ZUVIEL'FAST'-VARIABLEN

Es knnen maximal vier Byte mit FAST-Variablen belegt werden. Dies entspricht zwei Word/Integer-Variablen oder vier Byte-Variablen. Wenn diese vier Byte verbraucht sind, dann erscheint dieser Fehler.

63/VERBOTENER DATENTYP

Es knnen nur Variablen vom Typ Byte, Word und Integer als FAST-Variablen deklariert werden. Diese knnen auerdem keine Arrays sein. Der Fehler kann auch auftreten, wenn versucht wird, einer String-Variablen eine Adresse zuzuweisen, was ebenfalls verboten ist. mglicherweise sollte auch ein Array als Konstante deklariert werden.
64/FUNKTIONSDEFINITION FALSCH

Es wurde ein Fehler bei der Definition einer FN-Funktion mit DEF gemacht. Mglicherweise sollten Sie sich die Syntax der Funktionsdefinition noch einmal im Basic-Handbuch ansehen.

65/FUNKTION MEHRFACH DEFINIERT

Dieselbe FN-Funktion wurde mehrfach im Programm mit DEF definiert. Der Interpreter lt dies zu, der Basic-Boss nicht.

66/FUNKTION NICHT DEFINIERT

Es wurde versucht, eine FN-Funktion anzuwenden, die zu diesem Zeitpunkt noch nicht mit DEF definiert war. Eine solche Funktion mu in einer kleineren Zeilennummer und vor ihrer Anwendung definiert sein.

67/VERBOTENER TYP BEI FN

Wenn eine FN-Funktion gefunden wurde, deren Parameter ein String ist, dann erscheint diese Meldung - z.B. bei FN("abc").

68/KONSTANTE BEREITS DEFINIERT

Es wurde versucht, einer Variablen vom Typ Constant zweimal einen Wert zuzuweisen. Das ist jedoch nur ein einziges Mal im gesamten Programm erlaubt.

69/KONSTANTE NICHT DEFINIERT

Es wurde eine Variable des Datentyps Constant benutzt, obwohl sie noch nicht in einer vorausgehenden Zeile definiert wurde. Siehe hierzu unter Datentypen Kapitel 2.3.10 Der Datentyp Constant.
70/FUNKTION/KONSTANTE ERWARTET

Es wird versucht, eine FN-Funktion oder eine Konstante zu definieren, wobei allerdings der Funktionstext bzw. der Konstantentext fehlt. Es liegt also ein schwerer syntaktischer Fehler bei DEF FN oder der Konstantenzuweisung vor.

71/COMPILERFUNKTION UNBEKANNT

Der Compiler hat eine mit  eingeleitete Funktion gefunden, die er nicht kennt. Meist ist ein Schreibfehler die Ursache. Siehe auch Kapitel 2.5 Neue Befehle und Funktionen.


2.12.2 Die Meldungen des Compilats

Dies sind die Fehlermeldungen, die whrend der Ausfhrung des kompilierten Programms ausgegeben werden. Die Nummer der betroffenen Zeile wird normalerweise nicht angezeigt. Dieses Manko kann man beheben, wenn man LINEON benutzt (siehe unter LINEON in Kapitel 2.4.8 Sonstige Direktiven. Die Fehler sind nicht numeriert, was nicht weiter schlimm ist, da es nicht sehr viele gibt, denn die meisten Fehler werden bereits vom Compiler abgefangen. Es werden die normalen englischen Fehlermeldungen des Interpreters benutzt. Sie haben meist auch dieselbe Bedeutung wie beim Interpreter.


Die Fehlerliste

NEXT WITHOUT FOR ERROR
Das Programm ist bei einem NEXT-Befehl angelangt, ohne da zuvor ein FOR-Befehl abgearbeitet wurde. Man sollte den Programmlauf also genau berprfen, um festzustellen, wann dieses NEXT angesprungen wird. Dieser Fehler kann bei einer FASTFOR-Schleife nicht auftreten.


OUT OF DATA ERROR

Dem READ-Befehl sind die Daten ausgegangen. Man sollte also berprfen, wann und wo dieser READ-Befehl ausgefhrt wird und auf welche Daten er normalerweise zugreifen sollte.


TYPE MISMATCH ERROR

Dieser Fehler hat beim Compilat normalerweise eine andere Bedeutung als beim Interpreter. Er zeigt an, da die einzulesenden Daten beim READ-Befehl von einem anderen Typ sind als die Variable, in die sie eingelesen werden sollen. Wenn man z.B. alle Daten mit DATATYPE Byte als Byte-Daten erklrt hat und spter der Befehl READ R ausgefhrt wird (R sei eine Fliekommavariable), dann erscheint dieser Fehler. Wenn man die Daten trotzdem in eine Fliekommavariable einlesen will, mu man sie zunchst in eine Byte-Variable einlesen, um sie anschlieend einer Real-Variablen zuzuweisen (z.B. READ B: R=B, wobei B eine ByteVariable sein soll). Wenn die Daten vom Typ String sind, tritt dieser Fehler normalerweise nicht auf, da der READ-Befehl Strings in jeden anderen Typ umwandeln kann. Er erscheint aber trotzdem, wenn die Umwandlung unmglich ist (man kann keinen Buchstabenstring in eine Zahl umwandeln).


BAD SUBSCRIPT ERROR

Es wurde versucht, ein Array-Elernent anzusprechen, das nicht existiert. Die Feldgrenzen wurden also berschritten. Wenn man z.B. mit DIM A(100) ein Feld dimensioniert und dieses anschlieend mit I=101: A(I)=1 anspricht, dann erhlt man diesen Fehler. Standardmig tritt dieser Fehler aber nicht bei allen Feldern auf. Bei eindimensionalen Word-, Integer- oder Byte-Feldern wird eine Feldberschreitung nicht bemerkt, es sei denn, man benutzt SLOWARRAY.


OUT OF MEMORY ERROR

Wenn der Stringspeicher nicht mehr ausreicht, dann erscheint dieser Fehler. Man mu dann entweder den Stringspeicher vergrern (mit HEAPSTART und HEAPEND oder mit ALLRAM, siehe Kapitel 2.4 Beschreibung der Direktiven) oder mit den Strings etwas sparsamer umgehen.


CAN'T CONTINUE ERROR

Der Fehler hat nichts mehr mit seiner ursprnglichen Bedeutung gemein (er kann ja normalerweise nur im Direktmodus auftauchen). Das Compilat (genauer: die Garbage-collection) zeigt mit ihm an, da der Stringspeicher defekt ist. Grund hierfr kann entweder ein unvorsichtiger POKE in den Stringspeicher sein oder schlimmstenfalls ein Fehler in der Stringverwaltung des Compilers.


STRING TOO LONG ERROR

Der Fehler kann nur beim Addieren von Strings auftreten (z.B. A$=B$+C$). Die zu addierenden Strings haben eine Gesamtlnge von mehr als 255 Zeichen, was auch meine Stringverwaltung nicht verarbeitet.


ILLEGAL QUANTITY ERROR

Dieser Fehler kann bei der MID$-Funktion ausgelst werden, wenn der zweite Parameter 0 ist (z.B. MID$ (A$, 0, 2)). Er mu mindestens 1 sein.


SYNTAX ERROR

Wenn mit OTHERON erweiterte SYS-Befehle erlaubt sind, dann kann auch dieser Fehler auftreten. Er wird vom Compilat ausgelst, wenn die Parameterbergabe an das aufgerufene Maschinenprogramm durcheinandergekommen ist. Bei OTHERON sind weitere Fehler denkbar, die das aufgerufene Maschinenprogramm auslst.
Es sind auch noch andere Meldungen mglich, die vom Basic-Interpreter des C64/C128 stammen. Diese Meldungen haben im allgemeinen dieselbe Bedeutung wie sonst auch (z.B. division by zero error oderoverflow error). Sie knnen auftreten, weil die arithmetischen Routinen des Basic-ROM vom Compilat teilweise genutzt werden (fr Realzahlen).


-----------------------------------------
- Anhang A - bersicht aller Direktiven -
-----------------------------------------

ALLRAM         Schaltet die Nutzung des Gesamtspeichers (62 Kbyte) ein
BASICRAM       Schaltet die Nutzung des Gesamtspeichers (62 Kbyte) aus
BOOLEAN        Legt den Variablentyp BOOLEAN (zwei Zustnde) fest
BOOLEANTYPE    Bestimmt den Erwartungstyp bei IF-THEN
BOSSOFF        Schaltet Basic-Boss-Direktiven aus
BOSSON         Schaltet Basic-Boss-Direktiven ein
BYTE           Legt den Variablentyp Byte (256 Zustnde) fest
CALCTYPE       Bestimmt den Mindesttyp aller Berechnungen
CODE           Fgt Codes in das Compilat ein
DATAFILE       Bestimmt Gert und Name des Daten-Files
DATASTART      Legt die Startadresse des Datencodeteils fest
DATATYPE       Legt den Typ der DATA-Daten fest
FASTARRAY      Schaltet die schnellen, aber gefhrlichen Feldzugriffe ein
FASTFOR        Schaltet die schnelle FOR-NEXT-Schleife ein
HEAPEND        Bestimmt die Endadresse des Stringspeichers
HEAPSTART      Bestimmt die Anfangsadresse des Stringspeichers
HELPSTART      Bestimmt die Anfangsadresse des Hilfespeichers
IGNORE         Ignoriert alle nachfolgenden Befehle
INITOFF        Schaltet die Initialisierung der Variablen auf 0 aus
INITON         Schaltet die Initialisierung der Variablen auf 0 ein
INTEGER        Legt als Variablentyp Integer fest
LINEOFF        Zeilenaktualisierung ausschalten
LINEON         Zeilenaktualisierung einschalten
LONGIF         Normale IF-Anweisung verwenden
LONGNAME       Schaltet auf Basic-Boss-Variablen-Erkennung
OTHER          Erlaubt unbekannte Befehle aus Basic-Erweiterungen
OTHEROFF       Verbietet zustzliche Parameter des SYS-Befehls
OTHERON        Erlaubt zustzliche Parameter des SYS-Befehls
PRINTTYPE      Legt den Mindest-Variablen-Typ bei PRINT-Anweisungen fest
PROGFILE       Legt Gert und Name der Programm-Datei fest
PROGSTART      Legt die Anfangsadresse des Programms fest
PROTOCOL       Veranlat die Ausgabe von Fehlermeldungen und sonstigen Daten 
                an den Drucker oder in eine Datei
RAM            Schaltet im ALLRAM-Modus den schnellen RAM-Zugriff fr POKE 
                und PEEK ein
REAL           Legt als Variablentyp Real fest
ROM            Schaltet im ALLRAM-Modus den schnellen RAM-Zugriff fr POKE
                und PEEK aus
ROUTFILE       Bestimmt Gert und Name der Routinen-Datei
ROUTSTART      Legt Startadresse des Routinen-Teils fest
SETPREFERENCES Erhebt die momentanen Einstellungen zu den dauerhaften Standard-
                einstellungen
SHORTIF        Schnelle IF-Anweisung verwenden
SHORTNAME      Schaltet auf zweistellige Variablenerkennung
SLOWARRAY      Schaltet auf normale Feldzugriffe zurck
SLOWFOR        Normale FOR-NEXT-Schleife verwenden
SOURCEFILE     Legt Name, Gert und Sekundradresse der Quelldatei fest
STRING         Legt als Variablentyp String fest
SYSNUMBER      Regelt die Zeilennummer der SYS-Zeile
SYSOFF         Schaltet die SYS-Zeile des Compilats aus
SYSON          Schaltet die SYS-Zeile des Compilats ein
SYSTEXT        Legt den Text in der SYS-Zeile fest
USE            Deaktivierung von IGNORE
VARSTART       Legt Startadresse des Variablenspeichers fest
WORD           Legt als Variablentyp Word fest


-------------------------------------------------
- Anhang B - Zustzliche Befehle und Funktionen -
-------------------------------------------------

<--BYTE         Schreibt ein Byte in den aktuellen Ausgabekanal
<--CLI          Erlaubt Interrupts	
<--IN           Legt den Eingabekanal in die angegebene Datei
<--INTEGER      Schreibt zwei Byte in den aktuellen Ausgabekanal
<--IOROM        Schaltet I/O-Bereich und Basic-ROM ab
<--LOAD         Ldt eine Datei in den Speicher und arbeitet den nchsten Befehl ab
<--OUT          Legt den Ausgabekanal in die angegebene Datei
<--RAM          Schaltet das ROM ab
<--REAL         Schreibt fnf Byte in den aktuellen Ausgabekanal
<--RESET        Legt den Ausgabekanal auf den Bildschirm und den Eingabekanal auf
                die Tastatur
<--ROM          Schaltet das ROM ein
<--SEI          Verbietet Interrupts
<--WORD         Schreibt zwei Byte in den aktuellen Ausgabekanal

  @BYTE         Liest ein Byte aus dem aktuellen Ausgabekanal
  @INTEGER      Liest zwei Byte aus dem aktuellen Ausgabekanal
  @REAL         Liest fnf Byte aus dem aktuellen Ausgabekanal
  @WORD         Liest zwei Byte aus dem aktuellen Ausgabekanal


-----------------------------
- Anhang C - Automatikmodus -
-----------------------------

Bedeutung der Speicheradressen:

1000,1001        Enthalten sie die Werte 123 und 234, so wird der Automatikmodus
                 aktiviert
1002             Gertenummer Quelldatei
1003             Sekundradresse
1004             Lnge Dateiname
1005-1020        Filename

900              Gertenummer Zieldatei
901              Sekundradresse
902              Lnge Dateinarne
903-918          Filename


-----------------------------------------------
- Anhang D - Wertebereiche der Variablentypen -
-----------------------------------------------

+----------------------------------------------------------------------------------------+
! Typ		! Wertebereich Minimum 	      ! Wertebereich Maximum 	 ! Speicherplatz !
!---------------+-----------------------------+--------------------------+---------------+
! Real		! +-2.93873588*10(exp)-39 bis ! +-1.70141183*10(exp)38   ! 5 Byte	 !
! Integer	! -32768 bis		      ! +32767		 	 ! 2 Byte	 !
! Word		! 0 bis			      ! 65535			 ! 2 Byte	 !
! Byte		! 0 bis			      ! 255			 ! 1 Byte	 !
! Boolean	! 0 und			      ! -1			 ! 1 Byte	 !
+----------------------------------------------------------------------------------------+


--------------------------------------------------
- Anhang E - Der Software-Speeder Ultraload Plus -
--------------------------------------------------

Das Laden des Basic-Boss dauert ohne Floppy-Speeder zirka zwei Minuten. Sollten Sie mehrere Programme kompilieren, so ergibt sich eine betrchtliche Ladezeit. Mit dem hier beschriebenen Programm Ultraload Plus knnen Sie die Ladezeit um ein Vielfaches verkrzen. Der Basic-Boss, Ihre Basic-Programme und Ihre Compilate werden dann in siebenfacher Geschwindigkeit geladen. Bitte laden Sie das Programm mit:

load 'ultraload plus",8
run

Jetzt steht Ihnen die erhhte Ladegeschwindigkeit zur Verfgung. Ihre Programme laden Sie wie gewohnt. Die nachfolgende Beschreibung von Ultraload Plus ist in zwei Teile gegliedert: Der erste Teil beschreibt das Programm fr den Anwender (die Vorteile und Mglichkeiten), whrend sich der zweite Teil an interessierte Programmierer wendet, die mehr ber dieses System wissen wollen. Doch zuerst zu einer einfachen Beschreibung dieses Programms. Auch wenn Sie Ihre Floppy fr den C 64 (C 128) vielleicht noch nicht lange haben, so werden Sie sicher schon die berchtigt langen Wartezeiten der 1541/1570/1571 kennengelernt haben. Es gibt nun mehrere Lsungen, die langsame Geschwindigkeit der Diskettenstation zu umgehen, sei es hardware- oder softwaremig. Ultraload Plus ist eine der Softwarelsungen und noch dazu eine sehr gute. Im folgenden sind die Vorteile fr Sie als Benutzer aufgefhrt:

- Programme werden 6,8mal schneller geladen als normal.
- Directory-Eintrge werden sehr viel schneller gefunden.
- Auch der Befehl VERIFY wird sehr viel schneller ausgefhrt.
- Da der Schreib-Lese-Kopf der Floppy mehr als dreimal so schnell bewegt wird wie normal,
  wird somit einer Dejustierung vorgebeugt.
- Sie knnen das Laden jederzeit mit <RESTORE> unterbrechen.

Vielleicht kennen Sie bereits das Programm Hypra-Load. Aber Ultraload Plus ist auch noch besser als Hypra-Load, wie die folgende Zusammenstellung beweist.

- Das Laden erfolgt noch schneller als bei Hypra-Load (6,8mal anstelle von 6,2mal). 
- Hypra-Load beschleunigt nicht die Suche von Directory-Eintrgen.
- Die Wahrscheinlichkeit eines Absturzes ist bei Ultraload Plus noch geringer als bei Hypra-Load.
- Mit Hilfe mehrerer Parameter lt sich Ultraload Plus einfacher an Programme anpassen,
  die zuerst nicht mit Floppy-Speedern (die Bezeichnung fr solche Beschleunigungs-
  programme) zusammenarbeiteten.
- Ultraload Plus gibt bei einem Schreib-Lese-Fehler eine dementsprechende Meldung aus,
  ohne - wie Hypra-Load - abzustrzen.
- Bei Ultraload Plus wird der Bildschirm nicht abgeschaltet.

Sie sehen also, da Ultraload Plus einige Vorteile mit sich bringt. Vor allem werden Ihnen aber die wesentlich krzeren Ladezeiten auffallen. Vorbei sind die Kaffeepausen beim Laden des 193 Block langen Basic-Boss. Um mit Ultraload Plus zusammenzuarbeiten, brauchen Sie es nur mit den oben genannten Befehlen zu starten. Danach stehen Ihnen die schnelleren Laderoutinen sofort zur Verfgung. In der letzten Zeile der Einschaltmeldung sehen Sie einen SYS-Befehl (SYS 336). Sie knnen ihn verwenden, sollten Sie <RUN-STOP/RESTORE> gedrckt oder einen Reset ausgelst haben. Auch dann knnen Sie die schnelleren Laderoutinen sofort weiterverwenden, ohne das Programm neu laden zu mssen.
Sollte es ein Programm geben, das nicht problemlos mit dem Floppy-Speeder luft, mchte ich Sie auf den folgenden Teil verweisen; lassen Sie sich nicht durch etwaige Spezialausdrcke abschrecken. Zwischendurch werden Sie immer wieder wertvolle Hinweise fr die Arbeit mit diesem Programm finden, wie z.B. die Steigerung der Geschwindigkeit auf das bis zu 8fache! Des weiteren werden noch zwei Hilfsmittel (Tools) mitgeliefert, die auch im folgenden beschrieben werden. Die schnelle Datenbertragung vom Diskettenlaufwerk zum Computer beruht auf der gleichzeitigen bertragung von zwei Bit, auf dem eingeschrnkten Handshake-Betrieb sowie auf der zeitsparenden Verwendung einer Tabelle. Bei der Suche nach den Directory-Eintrgen wird eine eigene GCR-Codierung verwendet (Group-Code-Recording, so heit das Aufzeichnungsverfahren der 1541). Die rasante Datenbertragung zum Laufwerk ist fr das um Sekundenbruchteile verzgerte Starten des Motors zustndig und beruht auf einer uerst kurzen Transfer-Routine. Das Laden des Directorys (LOAD "$",8 ...) wird nicht beschleunigt. Dafr wird der VERIFY-Betehl - wie oben bereits erwhnt - schneller abgearbeitet. Im Gegensatz zur Original-Verify-Routine bricht das Programm beim Auftreten eines Fehlers sofort ab. Mit der Befehlsfolge PRINT PEEK(174) + 256 * PEEK(175) knnen Sie das erste unterschiedliche Byte feststellen.
Wenn Sie das Programm direkt nach dem Laden listen, sehen Sie folgende Zeile:

1985 sys 2080,00288,192,214,n,3

Im folgenden werden wir die einzelnen Parameter nher erlutern. Dazu werden wir sie aber zuerst durch Buchstaben ersetzen, um sie einfacher beschreiben zu knnen. Demnach ist die Startzeile folgendermaen aufgebaut:

1985 sys 2080, a, b, c, d, e

A: Startadresse des Bootprogramms
B: Highbyte der Anfangsadresse des Arbeitsbereichs; mu bei der zweiteiligen Version gleich
   der nachfolgenden Zahl sein und zwischen 16 und 200 liegen
C: Highbyte der Anfangsadresse des Hauptteils; mu bei der zweiteiligen Version zwischen 16 und 200, bei der dreiteiligen      zwischen 16 und 246 liegen
D: Transfergeschwindigkeit (N fr normal, H fr hoch)
E: Speicherbelegungsart (2 fr zweiteilig, 3 fr dreiteilig)

Prinzipiell mu die Lnge der Basic-Zeile immer gleich sein. Daher mssen eventuelle Vernderungen mit fhrenden Nullen versehen werden (beispielsweise 00288 statt 288).
Kommen wir jetzt aber endlich zu den Parametern: Ultraload Plus kann entweder als zweiteilige oder dreiteilige Version im Speicher liegen. Fr jeden Teil existiert genau eine Startadresse (A-C). Da bei zwei Teilen die Adresse fr den dritten Programmblock entfllt, mu in dem Fall die Angabe B mit Angabe C bereinstimmen (E mu 2 sein).
A wird einfach als Dezimalzahl angegeben, kann also Werte zwischen 0 und 65535 annehmen (das sind alle im C64 mglichen Adressen). Hier empfiehlt es sich aber, bei der Adresse 288 zu bleiben. Die folgenden Ausfhrungen ber die Angaben B und C werden nur Assemblerprogrammierer unter Ihnen verstehen. Das ist aber kein Grund zur Verzweiflung, da weiter unten noch eine Lsung fr alle anderen Leser geboten wird. Die Bootroutine (ab 288) ruft das eigentliche Hauptprogramm (ca. 2 Kbyte) auf. Die Angaben fr C (Hauptteil) ermitteln Sie, indem Sie jeweils die Highbytes der Adressen angeben (dezimal). Das heit also, da die Zahl 88 fr die Startadresse 22528 (=$5800) steht. Wie bereits erwhnt, mssen bei der zweiteiligen Version B und C unbedingt bereinstimmen.
Dieser zweite Teil enthlt alle Laderoutinen und einen kleinen Arbeitsspeicher. Er ist vor berschreiben durch sich selbst geschtzt, das heit, er kann beim Laden nicht zerstrt werden. Diesen Programmteil knnen Sie beispielsweise in das RAM unter dem Kernel oder in das RAM unter den I/O-Bausteinen legen. Der dritte und letzte Teil ist der sogenannte Arbeitsbereich (wird durch B festgelegt!). Auch dieser Bereich ist vor berschreiben geschtzt. Zunchst mchte ich dieses Prinzip der Speichereinteilung an einem Beispiel verdeutlichen: 

1985 sys 2080, 00288, 192, 214, n, 3

Der Bootteil liegt demzufolge ab Adresse 288, der Arbeitsbereich ab 49152 (=$C000), der Hauptteil liegt ab 54784 (=$D600), und die 3 am Ende verdeutlicht noch einmal, da es sich um eine dreiteilige Version handelt. Der fnfte Parameter gibt die Transfergeschwindigkeit an, mit der geladen und gespeichert werden soll. Dabei steht N fr normal und H fr hoch. Mchten Sie die Ladegeschwindigkeit um den Faktor 8 erhhen, geben Sie bitte die folgenden Zeilen ein:

open 1,8,15 
print# 1, "m-w"+chr$(105)+chr$(0)+chr$(1)+chr$(7); 
closel

Mit dieser kurzen Befehlssequenz wird der Blockabstand auf Diskette von normalerweise zehn auf sieben umgestellt. Dadurch kann Ultraload Plus noch schneller auf die Diskette zugreifen. Alle Programme, die so gespeichert wurden, werden spter auch wieder schneller geladen. Allerdings funktioniert dieser Mechanismus nur, wenn Sie den bertragungsmodus auf H
gestellt haben. Zum Schlu mchte ich noch auf den Fall eingehen, da ein Programm nicht mit Ultraload zusammenarbeitet. Laden Sie dazu das Programm ULTRALOAD TOOL 1, und starten Sie es. Es fllt den Speicher mit einem bestimmten Code und fhrt danach einen Reset aus. Laden Sie daraufhin Ihr Problemkind, und lsen Sie wieder einen Reset aus (SYS 64738 oder notfalls mit einem Resetschalter). Laden Sie jetzt noch ULTRALOAD TOOL 2, und starten Sie auch dieses Hilfsmittel. Daraufhin werden Ihnen alle mglichen Startadressen fr die einzelnen Programmteile von Ultraload Plus angezeigt. Diese Werte knnen Sie dann unmittelbar in den SYS-Befehl von Ultraload Plus bernehmen.


(Thilo Herrmann/wb/ti)
