18. Abwärtskompatibilität

^

18.1 Der klassische BASIC Modus

Ältere, nicht objekt-orientierte BASIC Programme besitzen ein "Hauptprogramm", das beim Start des Programms automatisch ausgeführt wird. Außerdem gibt es einen vordefinierten Bildschirm, auf den alle Text- und Grafikausgaben erfolgen. R-BASIC kann dieses Verhalten simulieren, so dass das Übertragen älterer Programme nach R-BASIC vereinfacht wird. Dazu gibt es die Anweisung ClassicCode.
Syntax: ClassicCode
ClassicCode muss vor der ersten ausführbaren Anweisung (z.B. Print) im Quelltext stehen. Fall Sie Include-Anweisungen verwenden, muss ClassicCode nach den Include-Anweisungen stehen.

Die Anweisung ClassicCode bewirkt folgendes:

  • Das Scheiben von Code außerhalb von Routinen (das klassische Hauptprogramm) wird zugelassen.

  • Dieser "klassische" Code wird beim Start des Programms automatisch ausgeführt.

  • R-BASIC legt beim ersten Start des klassischen Programms ein paar Objekte an, damit Text und Grafik-Anweisungen arbeiten können. Konkret sind das ein Primary mit einem View und einem BitmapContent Objekt der Größe 640x400 Pixel mit 256 Farben. Einmal angelegt, können Sie diese UI-Objekte ändern oder ergänzen, wenn Sie wollen.
Hinweis: Auch unter objekt-orientierten Programmen gibt es das Problem, dass beim Start des Programms automatisch Code ausgeführt werden muss. Die Lösung für dieses Problem unter R-BASIC ist, einen OnStartup Handler für das Application-Objekt zu programmieren. Details dazu finden Sie im Objekthandbuch, bei der Beschreibung des Application Objekts (Kapitel 4.1).

^

18.2 Zeilennummern

Viele ältere BASIC-Programme lesen sich etwa so:
10 Print "Bitte geben Sie eine Zahl ein"
20 INPUT Z
30 IF Z < 5 THEN PRINT "Unter Fünf"
40 GOTO 10
Die Zahlen am Beginn jeder Zeile werden als Zeilennummern bezeichnet und sind bei älteren BASIC-Interpretern lebensnotwendig. R-BASIC kommt gänzlich ohne Zeilennummern aus, zur Definition von Sprungzielen gibt es den LABEL Befehl.

Achtung! Verwechseln Sie diese im Code vereinbarten Zeilennummern nicht mit den im Editorfenster angezeigten Zeilennummern!

R-BASIC kann jedoch mit Zeilennummern umgehen (Bei GOTO, GOSUB und RESTORE), so dass ältere Programme einfacher nach R-BASIC zu übertragen sind. Dazu müssen Sie die Zeilennummern aber explizit im Programm vereinbaren. Beispielsweise könnten Sie obiges Programm direkt so eingeben, wie es oben steht. Es geht aber auch folgende Variante:

10 Print "Bitte geben Sie eine Zahl ein"
INPUT  Z
IF Z < 5 THEN PRINT "Unter Fünf"
GOTO  10

Wesentlich besser ist aber diese Form:
Label restart
Print "Bitte geben Sie eine Zahl ein"
INPUT  Z
IF Z < 5 THEN PRINT "Unter Fünf"
GOTO  restart

Hinweis: R-BASIC prüft die Gültigkeit von Zeilennummern nicht! Mehrfach definierte Zeilennummern werden nicht erkannt! Die Verwendung von Zeilennummern, die nicht existieren (also nicht explizit angegeben wurden) führt aber zu einem Compilerfehler

Die Verwendung von Zeilennummern ist mit den Befehlen GOTO, GOSUB und RESTORE möglich.

Tabelle

^

18.3 Kompatibilität mit dem KC-85-BASIC

Das folgende Kapitel ist für Nutzer interessant, die einen KC-85 Homecomputer besitzen oder besessen haben oder aus einem anderen Grund ein KC-85 Programm nach R-BASIC portieren wollen. R-BASIC ist weitgehend abwärts-kompatibel zum BASIC des KC-85/3 und KC-85/4, so dass reine KC-BASIC-Programme ohne größere Probleme laufen sollten.

Hinweise zur Portierung von KC-85 BASIC Programmen

Erforderliche Einstellungen

R-BASIC ist nicht als KC-Emulator konzipiert. Insbesondere steht die Hardware des KC-85 nicht zur Verfügung und wird auch nicht emuliert. Mit der Systemvariablen kc85Features können Sie R-BASIC trotzdem dazu bringen, sich in bestimmten Situationen wie der KC-85 zu verhalten. In diesem Modus können Sie weiterhin alle R-BASIC Befehle verwenden. Ausnahme sind einige Farbbefehle, da auf dem KC-85 nur maximal 16 Farben möglich sind.

Zusätzlich müssen Sie bestimmte Bedingungen einhalten. Dazu gehört, dass Sie als Screen eine 8Bit Bitmap mit aktivierter Palette (idealer Weise 640x512 Pixel) verwenden sowie das Koordinatensystem drehen. Wie man das macht und weitere notwendige Einstellungen finden Sie in der Beispieldatei 'KC 85 Demo' im Ordner 'R-BASIC\Beispiel\Erste Schritte'. Einige Details der Implementation verlassen sich darauf, dass die im Beispiel aufgeführten Initialisierungsschritte ausgeführt wurden.

Farben

Auf dem KC-85 sind nur 8 Hintergrundfarben (Farbcodes 0 bis 7) und 16 Vordergrundfarben (Farbcodes 0 bis 15 und 16 bis 31) möglich. Die Farbtöne von Vordergrund- und Hintergrundfarben unterscheiden sich, so dass insgesamt 24 verschieden Farben möglich sind. Werden die Farbcodes 16 bis 31 für die Vordergrundfarbe verwendet, so werden die entsprechenden Pixel blinkend dargestellt. Intern wird das folgendermaßen so realisiert:
  • R-BASIC konvertiert die KC-Farbindizes intern in einen Farbe aus dem RGB-Würfel der GEOS Standardpalette, die den originalen KC-Farben möglichst nahe kommt. Eine entsprechende Zuordnung finden Sie im Anhang.

  • Als Screen wird eine 8 Bit Bitmap mit Palette verwendet. R-BASIC stellt eine spezielle Palette ein, die diese Farben enthält. Das Blinken der Vordergrundfarben wird über einen Timer realisiert, der im Hintergrund etwa 2 Mal pro Sekunde die Palette der Screen-Bitmap modifiziert und die Bitmap neu dargestellt.

Variablen

Auf dem KC-85 werden Variablen bei ihrer ersten Verwendung definiert. Nur Felder müssen mit DIM angegeben werden. Unter R-BASIC müssen Sie alle Variablen zunächst mit DIM vereinbaren. Beachten Sie, dass auf dem KC nur die ersten beiden Buchstaben einer Variable von Bedeutung sind! WE ist die gleiche Variable wie WELT und AL$ die gleiche wie ALF$.

IRM

Die Grafikausgabe des KC-85 erfolgt über einen Bildwiederholspeicher (IRM: Image Repeat Memory). Er besteht aus dem Pixelspeicher ab Adresse 0, dem Colorspeicher ab Adresse 10240, den Arbeitszellen des KC-Betriebssystems CAOS ab Adresse 12800 und einem freien Bereich ab Adresse 14848.

Im Pixelspeicher ist in jedem Byte für 8 Pixel die Information abgelegt, ob die Vordergrundfarbe oder die Hintergrundfarbe angezeigt werden soll. Der Colorspeicher enthält in jedem Byte für jeweils 4x8 Pixel die zugehörige Vordergrund- und die Hintergrundfarbe. Eine genaue Aufteilung des IRM sowie Informationen dazu, welche der CAOS Arbeitszellen von R-BASIC benutzt werden können, finden Sie im Anhang.

Aus BASIC heraus kann der IRM mit den Befehlen VPEEK und VPOKE (siehe unten) angesprochen werden. R-BASIC stellt dafür einen eigenen Speicherblock bereit. Je nachdem welche Bits in der Systemvariablen kc85Features gesetzt sind löst ein VPOKE Befehl weitere Aktionen aus, die das Verhalten des KC-85 nachahmen.

Sie sollten auf jeden Fall den zu portierenden Code nach Peek, Poke, VPeek, VPoke, Deek und Doke Befehlen durchsuchen um deren Funktion gegebenenfalls anpassen zu können.

Zeilennummern

Klassische BASIC Programme benötigen Zeilennummern, R-BASIC nicht. R-BASIC kann jedoch mit Zeilennummern umgehen, so dass Sie beim Portieren eines Programms die Zeilennummern nicht entfernen müssen.

Im Gegensatz zum KC-BASIC übernimmt R-BASIC reine Kommentarzeilen nicht in den Code. Folgende KC-Sequenz führt unter R-BASIC zu einem Fehler (Zeilennummer existiert nicht) wenn der Befehl 'GOSUB 1100' compiliert wird.

1100 ! Unterprogramm zur Anzeige
1110 Window : COLOR 15, 1: CLS
Ändern Sie den Code dann folgendermaßen:
!  Unterprogramm zur Anzeige
1100 Window : COLOR 15, 1: CLS

Zeichensatz

Der Zeichensatz von KC und PC / R-BASIC unterscheiden sich an einige Stellen. Insbesondere müssen Sie die deutschen Umlaute über ihren Code in einen String einfügen, ein 'ä' z.B. als '\125'. Eine entsprechende Übersicht finden Sie im Anhang, Kapitel H.

Zeichengenerator

Einer der Initialisierungsschritte ist das Einstellen des BlockGrafik Modus. Wenn das Bit 9 in den kc85Features gesetzt ist kann R-BASIC erkennen, ob ein KC-85 Programm der Zeichengenerator des KC-85 ändert (Verwendung der Befehle POKE bzw. VPOKE) und seinen eigenen Zeichengenerator entsprechend anpassen. Wo der KC-Zeichengenerator liegt wird von den Arbeitszellen 14246 bis 14253 im IRM bestimmt, die mit dem Befehl VPOKE geändert werden können. Details dazu finden Sie im Anhang. Der Standard-Zeichengenerator liegt beim KC im ROM auf den Adressen 60928 (&hEE00)bzw. 65024 (&hFE00). R-BASIC erkennt, wenn das Programm den Zeichengenerator in den RAM (Adresse kleiner 49152 bzw. &hC000) verschiebt und überwacht die entsprechenden Adressen dann.

R-BASIC reagiert jedoch nicht adäquat, wenn das Programm die Adresse des Zeichengenerators wieder in den ROM zurück verschiebt. Das kann sinnvoll sein, wenn zwischenzeitlich wieder Buchstaben statt Grafikzeichen ausgegeben werden sollen. Sie müssen diese Programmstellen finden und ändern, indem Sie zwischenzeitlich auf den alternativen Zeichengenerator von R-BASIC wechseln. Im Normalfall müssen Sie dafür an zwei Stellen im Programm VPOKE durch BlockSelect ersetzen. Im eingangs genannten Beispiel ist das demonstriert.

Laufzeit

Läuft ein Programm zu schnell, z.B. in einer Spielschleife, so können Sie den Befehl DELAY verwenden. Wenn Sie während der zu schnell laufenden Schleife Strg-B drücken öffnet sich der R-BASIC Debugger und Sie können im Einzelschrittbetrieb die passende Position für die Delay-Befehle finden. Beachten Sie die Dokumentation zum Delay-Befehl!

Nicht vollständig KC-kompatible Befehle

Einige wenige Befehle sind nicht vollständig KC-kompatibel programmiert, um die Leistungsfähigkeit von R-BASIC nicht unnötig einzuschränken. In anderen Fällen würde der Nutzen im Vergleich zum erforderlichen Aufwand einfach zu gering.
Chr$:
LEN(Chr$(0)) liefert auf dem KC den Wert 1, in R-BASIC Null.

InStr:
Bei der Übergabe von Leerstrings gibt es Unterschiede. INTSR('','X') und INTSR('X','') erzeugen auf dem KC einen Laufzeitfehler, in R-BASIC erhalten wir Null.

INPUT:
Bei der Eingabe von Strings werden führende Leerzeichen vom KC-85-BASIC ignoriert. R-BASIC übernimmt die Leerzeichen in den String.
Im KC-85-BASIC sind als Infotext nur Stringkonstanten zulässig, R-BASIC akzeptiert auch Variablen und String-Ausdrücke.

Left$(),
Right$():
Ist der Längenparameter negativ, erzeugt der KC einen Laufzeitfehler, R-BASIC liefert einen leeren String

Mid$():
Ist der Längenparameter negativ, erzeugt der KC einen Laufzeitfehler, R-BASIC liefert alle Zeichen ab dem Start-Parameter (so als ob kein Längenparameter angegeben wäre)

WINDOW:
Auf dem KC-85 hat der Grafikbildschirm eine feste Größe von 320 x 256 Pixeln. Da der Zeichensatz 8x8 Pixel groß ist, hat das Textfenster maximal 32 Zeilen zu je 40 Spalten. Unter R-BASIC kann der Bildschirm und somit das Textfenster eine beliebige Größe haben.

Der Befehl WINDOW (ohne Parameter) stellt auf dem KC-85 ein Standard-Fenster ein, dass oben und unten eine Zeile frei lässt. Das entspricht dem Befehl WINDOW 1, 38, 0, 39. Unter R-BASIC stellt der Befehl WINDOW (ohne Parameter) das maximal mögliche Fenster ein.

Auf dem KC erzeugen Window-Parameter, die nicht zum Bildschirm passen (z.B. Anfangszeile < 0 ) einen Laufzeitfehler, in R-BASIC wird das Fenster angepasst (abgeschnitten) oder es wird das maximale Fenster eingestellt.

LOCATE:
Der KC erzeugt einen Syntax-Fehler zur Laufzeit, wenn die Koordinaten ungültig sind. R-BASIC begrenzt die Koordinaten auf sinnvolle Werte und arbeitet weiter.

PRINT AT, INK, COLOR, PAPER :
Auf dem KC in jeder Print-Anweisung nur ein AT und eine Farbanweisung zulässig. In R-BASIC kann man diese Anweisungen beliebig kombinieren.

PRINT - Steuercodes
In R-BASIC ist nicht definiert:&H14 (KeyKlick), &H16 (ShiftLock)

Folgende Codes arbeiten in R-BASIC nur innerhalb einer Zeile, während sie beim KC auch zeilenübergreifend arbeiten können: &H16 (Insert), &H17 (Delete) und &H08 (Clear Character)

WIDTH:
Der Befehl wurde in KC_WIDTH umbenannt, damit der Bezeichner width für Variablen verwendet werden kann.

SOUND:
Der Befehl wurde in KCSOUND umbenannt, damit der Bezeichner SOUND für einen leistungsfähigeren Sound-Befehl zur Verfügung steht. Die Länge eines 'Dauertons' ist auf 18 Minuten begrenzt.

LINE, CIRCLE, PSET, PRESET:
Die Grafikbefehle schreiben nicht in den IRM, weder in den Pixel- noch in den Color-RAM. Entsprechend kann es beim Lesen dieser Speicherbereiche mit VPEEK abweichende Ergebnisse geben.

VPOKE und VPEEK
greifen auf einen von R-BASIC bereitgestellten Speicherblock zu. Über die Systemvariable kc85Fetaures (siehe unten) kann eingestellt werden, inwieweit R-BASIC versuchen soll die damit verbundene Hardwareoperation des KC-85 nachzuahmen. In einigen Fällen gelingt das sehr gut, in anderen eher weniger gut.

INP, OUT, WAIT:
Diese hardwarenahen Befehle greifen auf die I/O-Ports des PC zu. Die KC-Hardware wird nicht emuliert.

Nicht unterstützte KC-BASIC Befehle

Einige Befehle sind unter R-BASIC nicht sinnvoll (z.B. die Editorbefehle) oder konzeptionell nicht möglich (z.B. der Aufruf von Z80 Maschinencode).
  • Editor-Befehle und Speicherverwaltung:
    AUTO, BYE, CLEAR, CLOAD, CONT, CSAVE, DELETE, EDIT, FREE(), LINES, LIST, NEW, RENUMBER, RUN, TRON, TROFF

  • Hardware- oder Maschinenprogramm-Zugriffe:
    JOYST, BLOAD, CALL, INPUT#, LIST#, LOAD#, SWITCH, WAIT, USR()

  • Sonstige:
    DEF_FN, KEY, KEYLIST, LET, FRE

    PTEST wird nicht unterstützt. Verwenden Sie stattdessen PGet.


Spezielle Befehle für die KC-Kompatibilität

kc85Features

Die Systemvariable kc85Features bestimmt das Kompatibilitätslevel von R-BASIC gegenüber dem KC-85 BASIC. Die in der Tabelle unten aufgelisteten Funktionen kann man einzeln ein- und ausschalten, da viele von ihnen R-BASIC einschränken oder verlangsamen. Dazu enthält die Variable kc85Features Bitflags, das heißt, jedes Bit hat eine eigene Bedeutung. Die Arbeit mit Bitflags ist im Kapitel 2.3.5.4 des Programmierhandbuchs beschrieben.

Die meisten Bits setzen voraus, dass der Ausgabescreen eine 8 Bit Bitmap mit Palette ist. Ist diese Bedingung nicht erfüllt funktionieren einige Funktionen nicht oder verhalten sich 'seltsam'.

Übersicht über die Bits in kc85Features

Tabelle

Nähere Beschreibung der einzelnen Bits

Bit 0
ermöglicht, dass das grafische Koordinatensystem seinen Ursprung links unten hat, während der PRINT Befehl weiterhin mit der Zeilen- und Spaltenzählung links oben beginnt, ohne dass die Buchstaben gespiegelt werden.

Bit 1
bewirkt, dass den KC-Farbcodes 0 bis 31 Farben aus der GEOS-Standardpalette zugeordnet werden, die denen des KC-85 entsprechen.

Bit 2
bewirkt, dass die Farben 16 bis 31 der Vordergrundfarbe blinkend dargestellt werden. Dazu wird etwa 2 Mal pro Sekunde die Palette der Screen-Bitmap modifiziert und die Bitmap neu dargestellt. Setzt voraus, dass das Bit 1 ebenfalls gesetzt ist. Falls Sie keine blinkenden Zeichen benötigen sollten Sie dieses Bit auch nicht setzen.

Bit 3
bewirkt, dass VPOKE beim Schreiben in den Pixel-RAM auch in die Ausgabebitmap schreibt. Die erzeugten Farben können aber vom Ergebnis auf dem KC abweichen.

Bit 4
bewirkt, dass VPEEK beim Lesen aus dem Pixel-RAM den zu lesenden Wert aus den Pixeldaten der Ausgabebitmap rekonstruiert. Ist das Bit nicht gesetzt wird der Wert direkt aus dem IRM gelesen.

Bit 5
bewirkt, dass VPOKE beim Schreiben in den Color-RAM auch in die Ausgabebitmap schreibt.

Bit 6
bewirkt, dass VPEEK beim Lesen aus dem Color-RAM den zu lesenden Wert aus den Pixeldaten der Ausgabebitmap rekonstruiert. Der gelesene Wert kann vom Ergebnis auf dem KC abweichen. Ist das Bit nicht gesetzt wird der Wert direkt aus dem IRM gelesen.

Bit 7
bewirkt, dass VGet$ den Wert aus dem ASCII-Puffer im IRM liest statt aus dem R-BASIC ASCII-Puffer. Setzt einen 40 Zeilen x 32 Zeichen - Screen voraus.

Bit 8
bewirkt, dass PRINT, INPUT und CLS den ASCII-Puffer im IRM updaten. CLS löscht außerdem den Pixel- und den Color-RAM. Setzt einen 40 Zeilen x 32 Zeichen - Screen voraus.

Bit 9
bewirkt, dass der KC85 Zeichengenerator in den R-BASIC Zeichengenerator gespiegelt und dabei gegebenenfalls skaliert wird, indem die entsprechenden Arbeitszellen im IRM überwacht werden. Setzt einen aktiven Blockgrafik-Modus mit einem 40 Zeilen x 32 Zeichen - Screen voraus. Die Blockgrafikzeichen müssen quadratisch und ihre Größe durch 8 teilbar sein.

Ändert das KC-Programm den Zeichengenerator im RAM so passt R-BASIC seinen eigenen Zeichengenerator automatisch an.

Bit 10
bewirkt, dass die Erstbelegung der Buchstabentasten wie beim KC die Großbuchstaben sind.

Bit 11
bewirkt, dass die ASCII-Codes der Umlaute und Sonderzeichen auf der Tastatur ür INPUT und INKEY$ in die entsprechenden KC-Codes umgewandelt werden. Hinweis: Auf dem KC gibt es bei den Umlauten keine Großbuchstaben.

Bit 12
bewirkt, dass INKEY$ bei den Steuertasten (Pfeiltasten, Einfg usw.) die KC-Codes liefert. INPUT behandelt die Steuertasten immer automatisch korrekt.

Bit 13
bewirkt, dass das Bit 3 der Arbeitszelle 14242 (&HB7A2) im IRM kontrolliert, ob Steuerzeichen (ASCII-Code < 32) 'ausgeführt' oder als druckbare Zeichen ausgegeben werden. Dazu wird das Bit TS_DONT_EXEC_ CONTROLS in printFont.style angepasst.

Bit 14
bewirkt, dass der Befehl Peek(509) des Tastaturcode der aktuell gedrückten Taste liefert. Die Speicherstelle mit der Adresse 509 (=&h1FD) ist eine Arbeitszelle des CAOS Betriebssystem des KC-85.

Hinweis: Die R-BASIC Befehle GetKey bzw. GetKeyLP liefern nicht den KC-Code sondern weiterhin den R-BASIC Code. Diese Codes unterscheiden sich für Steuerzeichen. Will man sie verwenden muss man möglicherweise die Abfrage entsprechend anpassen.

Bit 15
ist immer Null und kann nicht geändert werden.

VPOKE

VPOKE schreibt ein Byte in den IRM. In diesem Bereich liegt der Bildwiederholspeicher des KC-85 und die Arbeitszellen des KC Betriebssystems. Einige Bits in der Systemvariablen kc85Fetaures bestimmen, ob VPOKE weitere Aktionen auslöst oder einfach nur den Speicher beschreibt.

Eine genaue Aufteilung des IRM sowie Informationen dazu, welche der CAOS Arbeitszellen von R-BASIC benutzt werden können, finden Sie im Anhang.


Syntax: VPOKE adr, val
adr: Adresse im IRM. Erlaube Werte sind 0 bis 16383
val: Zu schreibender Wert (Byte).


VPEEK

VPEEK liest ein Byte aus dem IRM. Die Bits 4 und 6 der Systemvariablen kc85Features bestimmen, ob beim Lesen aus dem Pixel- bzw. Color-RAM der IRM selbst gelesen werden soll oder ob VPEEK versuchen soll, den Wert aus den Pixeldaten der Ausgabebitmap zu rekonstruieren.
Syntax: <numVar> = VPEEK adr
adr: Adresse im IRM. Erlaube Werte sind 0 bis 16383


KC_WIDTH

KC_WIDTH (Breite, KC Kompatibilitätsbefehl) bestimmt die maximale Länge einer Ausgabezeile. Dieser Befehl ist ursprünglich zur Arbeit mit Druckern gedacht und wurde deswegen umbenannt. Der Originalbefehl im KC-85 BASIC lautet WIDTH.
Syntax: KC_WIDTH n
n: Länge der Ausgabezeile. Werden mehr als n Zeichen auf einmal ausgegeben, wird nach n Zeichen jeweils ein Zeilenumbruch eingefügt.


Beispiel:
KC_WIDTH 15

KCClear

KCCLEAR löscht den globalen Variablenspeicher, einschließlich String und HUGE Variablen. Der Originalbefehl im KC-85 BASIC lautet CLEAR.
Syntax: KCClear


Beispiel:
KCClear

^

Weiter...