{{ ---------------------------------------------------------------------------------------------------------

Hive-Computer-Projekt

Name            : TRIOS-Basic
Chip            : Regnatix-Code 
Version         : 2.108
Dateien         :

Beschreibung    : Modifiziertes, stark erweitertes FemtoBasic für den Hive.

Eigenschaften   : -Benutzung externer Ram, Stringverarbeitung, Array-Verwaltung
                  -Gleitkommafuktion, Tile-Grafikunterstützung
                  -SID-Sound-Unterstützung
                  -64-Farb-VGA-Treiber
                  -Maus-Unterstützung, Button-Verwaltung
                  -Fensterverwaltung
                  -durch Tile-Fonts, verschiedene Schriftarten und Fensterstile
                  -bewegte Tile-Sprites

Logbuch         :

02-11-2012      - erste eram Nutzung      ok
                - Load                    ok
                - Save                    ok
                - List                    ok
                - neue Zeilen eingeben    ok
                - Run                     ok
                - aendern von Zeilen      ok
                - Zeilen loeschen         ok
                - nicht vorhandene Zeilen einfuegen ok
                - Fehler-Beep hinzugefuegt
                - Basicspeicher auf 512kb ehoeht (durch die konsequente eRam-Nutzung)
                - 999_999 Basic-Zeilen moeglich

17-11-2012      - 26 Stringvariablen verfuegbar
                - Stringfunktionen:
                - str l         strleft
                - str r         strright
                - str m         midstr
                - LEN           stringlaenge
                - STRCOMP       stringvergleich

08-12-2012      - Tilegrafik-Unterstuetzung
                - TLoad,STile,TPic,TILE,BOX,FONT,SCROLL-Befehl hinzugefuegt
                - cd-Befehl hinzugefuegt

27-12-2012      - Mouse,Button,DButt-Befehl hinzugefuegt(die Buttonverwaltung geschieht in Bella)
                - Buttons mit Tilefonts nutzbar
                - Windows mit Tilefonts nutzbar
                - Hilfesystem mit Tilefonts modifiziert damit mehr Platz fuer Hilfetext vorhanden ist
                - Startbildschirm hinzugefuegt

04-01-2013      - Fehler in Save-Routine behoben (y/n Abfrage bei existierender Datei wurde falsch abgearbeitet)
                - Map-Befehle zum erstellen speichern und laden von Levelmaps hinzugefuegt MAP D, MAP L, MAP S, MAP W (Display,Load,Save,Write)
                - Goto Abfrage optimiert um zu verhindern, das bei Schleifendurchlaeufen immer der gesamte Programmspeicher nach der goto Zeilennummer durchsucht werden muss
                - Load-Befehl mit Autostartfunktion erweitert (Load"Name.bas",1)
                - Mousezeiger kann zur Laufzeit per Tiledatei geaendert werden
                - Dir-Befehl um Extensionssuche erweitert
                - Neuer Befehl GFILE gibt die Anzahl der mit DIR gesuchten Dateien zurueck GFILE,Nummer uebergibt den Dateinamen der entspr.Nummer an #z (Fuer z.Bsp.eine Dateiauswahl)

20-01-2013      - Variablen a...z in den eRam verschoben fuer spaetere Nutzung mit Gleitkomma-Arithmetik
                - CLS Befehl durch interne Verwendung des 2DBox befehls beschleunigt
                - Speicherverwaltung ueberarbeitet und Programmspeicher auf 128 kb begrenzt (ist immer noch mehr als die meisten Retro-Computer hatten)
                - dadurch kann die zweite Rambank fuer andere Sachen benutzt werden

02-02-2013      - eindimensionale Arrays hinzugefuegt a(0...255)-z(0...255) damit sind insgesamt 6656 Variablen moeglich (Verwaltung im eRam ab Adresse $71000)
                - Zeilennummern wieder auf 65535 begrenzt da ja auch der Arbeitsspeicher kleiner ist (128kb) dadurch kleiner Geschwindigkeitsgewinn (statt long wird word als Zeilennummer gelesen->schneller)
                - ASC-Funktion hinzugefuegt
                - CHR-Funktion angepasst
                - STR$-Funktionen jetzt direkt ueber Print-Ausgabe moeglich (print str$ l(#a,2))

16-02-2013      - Fehler in Speicherverwaltung (aendern von Zeilen) offensichtlich behoben -> Hoffentlich
                - PASM-Routinen fuer schnellen Speichertransfer integriert (Bereiche loeschen,fuellen,rdbyte,wrbyte,rdword,wrword,rdlong,wrlong)
                - Load und Save durch die Speicherung der Programmdatei als Binaerdatei erweitert (schnelleres laden und speichern durch Blocktransfer ->Load"Name",1; Save"Name",1
                - Sicherungsdatei (Save & Load ohne Name) wird als Binaerdatei behandelt
                - Str$-Funktion erweitert Option N wandelt eine Zahl in einen String um (funktioniert aber nur mit direkter Zuweisung, nicht ueber Variablennamen (a(0..255))
                - Zeilenlaenge auf 100 Zeichen gekuerzt, spart etwas Platz im Speicher
                - Timerfunktion hinzugefuegt, 8 Timer laufen in einer separaten cog (Funktionen: Timer s, r, c -> setzen, lesen, abfrage ob abgelaufen)
                - Befehl GATTR hinzugefuegt zur abfrage der Dateiattribute einer geoeffneten Datei

03-03-2013      - Befehl MKDIR hinzugefuegt zum Erstellen von Verzeichnissen auf der SD-Card
                - Fehler in DIR-Filter-Funktion behoben
                - STR$ N wieder entfernt, jetzt kann eine Variable direkt in einen String umgewandelt werden mit z.Bsp. #a=g(10)
                - RECLM-Funktion (Reclaim) hinzugefuegt um Programm nach Neustart oder Absturz wieder herzustellen
                - reg-ios-64 rigoros gekuerzt um Speicher frei zu machen, es sind nur noch unbedingt benoetigte Funktionen enthalten (os_error texte entfernt-> spart massig platz)
                - System-und Fehlertexte ausgelagert, werden von SD-Card in den E-Ram geladen (spart Platz und erlaubt umfangreichere Fehlertexte)
                - Hilfesystem ausgelagert, das schafft Platz und ermöglicht zusätzliche Funktionen

19-03-2013      - Gleitkommafunktion hinzugefügt -- Puuh, das war ne harte Nuss
                - diverse mathematische Funktionen und die Zahl PI hinzugefügt (sin, cos, tan, mod, exp, log,asin,acos,atan,floor,ceil)
                - Funktion Val(String) hinzugefügt (String in numerischen Wert umwandeln)
                - noch ein paar Trigonometrische und elektrische Funktionen hinzugefügt, so jetzt reicht es mit Mathe-Funktionen (insgesamt 31 mathematische Funktionen
                - SIN,COS,TAN,LN,DEG,E,FRC,Int,LOG,EXP,ATN,FL,CL,MIN,MAX,ASN,ACS,FAK,PYT,PER,RCL,RAD,SNH,CSH,TNH,CTH,COT,y^x,Modulo,Abs,Neg,Wurzel,PI
                - Tilesetgrösse reduziert auf 256x176 Tiles (spart 1280 longs), ich brauche noch etwas Platz in Bella für Spritefunktionen oder zumindest Bewegung für Tiles

30-03-2013      - Funktion STRING$ hinzugefügt (sich wiederholende Zeichenketten)
                - Stringverarbeitung umgebaut (verbraucht immer noch zu viel Platz)
                - direkte Addition von Strings jetzt möglich (#c=#a+#b)
                - GOTO und GOSUB durch ON erweitert (ON x GOTO GOSUB <expr>,<expr>,<expr>...) Nullwerte werden ignoriert
                - IF THEN durch ELSE erweitert (IF Bedingung THEN Aktion ELSE Aktion) ELSE muss aber in der nächsten Zeile stehen
                - Stringarrays verfügbar #a(0..255)-#z(0...255) Verbraucht ziemlich viel ERam, mal sehen ob ich eine dynamische Array-Verwaltung hinbekomme( vielleicht bis zu 3 Dimensionen)
                - Standard-Arraytiefe wieder auf 10 begrenzt (Zahlen und Strings), bin dabei bis zu dreidimensionale Arrays verfügbar zu machen

02-04-2013      - Stringarrays mit bis zu drei Dimensionen verfügbar maximale Feldgrösse ist 8x8x8 (Dim #a(7,7,7) oder dim #a(16,16,1) oder jede andere Größe die x*y*z=<512 erfüllt)
                - Endlich nach dem dritten oder vierten Anlauf funktionieren jetzt auch die Variablen-Arrays Feldgröße 8x8x8 (beim Dimensionieren einen Wert niedriger eingeben
                  da die Felder bei Null beginnen d.h. das erste Feld ist (0,0,0) und nicht 1,1,1
                - Stringlänge auf 34 Zeichen reduziert da noch keine dynamische Speicherverwaltung vorhanden ist und bei statischer Speicherverwaltung immer die maximale Stringlänge
                  vorgehalten werden muss (verbraucht sehr viel Eram Bsp. 26 Stringnamen (a-z) * 34 Zeichen * 512 (Feldgrösse) = 452 608 Bytes (fast ein ganzer Speicherchip)

06-04-2013      - Array-Verwaltung funktioniert jetzt endlich (das Arbeiten mit dreidimensionalen Feldern hat sich als komplizierter herausgestellt als gedacht)
                - EDIT-Funktion integriert, nun kann man Zeilen auch im Nachhinein editieren ohne immer die ganze Zeile neu einzugeben.
                - serielle Schnittstellen-Unterstützung eingebaut (Befehl COM,COMG,COMR)

03-05-2013      - Parameter Baudrate bei öffnen der seriellen Schnittstelle hinzugefügt (COM 1,57600)
                - Stringverwaltung geändert, alle Stringvariablen dürfen nur noch 33 Zeichen lang sein,macht sich beim Programmieren einfach besser, wenn der Interpreter darauf achtet, die Feldbereiche zu trennen
                - Fehler in der Soundausgabe behoben, beim Spiel Baller.bas kam erst nach dem 2.Run ein Ton (in der Init-Routine Sid-reset und beep(1) eingefügt, jetzt klappts auch beim 1.Run)
                - unsichere RAM-Schreibroutine in PASM mit einigen NOP's ergänzt, da nach ranstöpseln eines neuen Netzteils, die Ram-Routine nicht mehr korrekt arbeitete(Schaltnetzteil Hochfrequenz?)
                - Cursorpromt ala KC87 hinzugefügt, Routine putlinet entfern(überflüssig)
                - Stringlängenbegrenzung in addstring korrigiert (hat über die Feldgrenzen geschrieben)
                - verkettete Stringaddition funktionieren jetzt richtig (Bsp.:str$ l("Teststring",3)+string$(8,"Test")
                - nur die string$-Funktion gibt nicht immer die richtige Anzahl strings zurück

08-05-2013      - mathematische Funktionen modifiziert, jetzt funktioniert das verkettete rechnen richtig (bsp.:FN SIN(FN LN(2.8))
                - verkettete Stringoperationen möglich, string$-Funktion funktioniert jetzt auch korrekt, nachdem noch ein dritter Stringpuffer eingerichtet wurde
                - werde nun versuchen, die Token auszulagern, alle Basicbefehle zusammen belegen ca.200 longs und werden eigentlich nur zur Eingabe, SAVE, LOAD und LIST gebraucht
                - eine funktionierende Variante mit ausgelagerten Token existiert für den Fall, das ich noch 200 Longs brauche
                - Button-Lösch-Befehl in Bellatrix überarbeitet, jetzt optisch besser
                - Spielerfigur mit Bewegung und Positionsbackup-Restore hinzugefügt, funktioniert erstaunlicherweise hervorragend
                - Spritefiguren mit Bewegung und einstellbarer Geschwindigkeit hinzugefügt, fehlt nur noch eine Kollisionserkennung
'#################################################### Version 2.003 ###############################################################################################################
10-05-2013      - Spritekollision funktioniert
                - für die Spielfeldgrenzen bzw. den für den Spieler erlaubten Pfad muss der Shadow-Bildschirmspeicher benutzt werden
                - Map D-schreibt die Map zusätzlich in den Bildschirm-Shadow-Speicher für Pfad-Abtastung der Spielerfigur
                - Player-Spielfeldeingrenzung funktioniert
                - Kollision mit festgelegten Tiles funktioniert, fehlt noch die Item-Verwaltung und die Feuer-Taste Funktion
                - COM-Befehl modifiziert um Befehle frei zu bekommen (COM S(1,57600), COM G, COM R)
                - Map-Speicher und Shadow-Bildschirmspeicher zu einem gemeinsamen MAP-Shadow-Bildschirmspeicher kombiniert (spart Platz im E-Ram und wird für die Item-Verwaltung gebraucht)
                - MAP-Befehl durch die Option C (Clear) erweitert, löscht den MAP-Shadow-Speicher
                - Mathematische Funktion FN PREC hinzugefügt um die Präzision der Nachkommastellen einzustellen (1-7)
                - Spieler-Itemverwaltung funktioniert
                - Sprite-Verfolgungsmodus integriert, fehlt vielleicht noch ein Distanzscanner !?
                - Lade-und Speicher-Prozentanzeige ersetzt die Punkteausgabe beim Laden und Speichern
                - Stringfunktion INSTR hinzugefügt (INSTR(Zeichenkette1,Zeichenkette2) überprüft, ob Zeichenkette1 vollständig in Zeichenkette2 vorhanden ist und gibt die Position des ersten Auftretens zurück
                - Code von überflüssigen Variablen gereinigt, dadurch ca.40 Longs gewonnen (noch frei 1425Longs)

26-05-2013      - Kollisionserkennung Player-Sprite korrigiert, funktioniert jetzt richtig (man konnte manchmal das Sprite überrennen ohne Kollision, das geht jetzt nicht mehr)
                - Für die Feuerfunktion hab ich noch keine Idee :-(
                - Item einsammeln funktioniert momentan nur mit gleichen Hintergrundfarben
                - damit das Item vom Feld verschwindet, muss man ein ersatz-Item definieren mit Player E(I1...I6)
                - momentan 1384 Longs frei

21-07-2013      - Fehler in Line-Funktion behoben (x und y vertauscht)
                - Fehler in Plot-Pixel behoben (x und y vertauscht)
                - Fehler im BYE-Befehl behoben, es konnte passieren, das nach Beendigung von TBasic nicht korrekt ins Root-Verzeichnis gewechselt wurde und die Reg.sys demzufolge
                  nicht gefunden wurde, dies ist jetzt behoben
                - 1361 Longs frei

25-07-2013      - Fehler in der Array-Verarbeitung behoben (bei verschachtelten For-Next Füllschleifen wurde das Arrayfeld falsch errechnet,
                  jetzt ist das Füllen von Arrays über For-Next-Schleifen möglich (durch die Routine get_array_value))
                - 1356 Longs frei

28-07-2013      - Ersatz-Item-Verwaltung wieder entfernt, ist nicht praktikabel, lässt sich im Basic besser und flexibler programmieren
                - 1380 Longs frei

01-08-2013      - Bit-Operationen in FN-Funktion eingefügt Shift-left, Shift-right,  Reverse, ODER, XODER,UND
                - Basic-Verzeichismarker hinzugefügt, jetzt sollte Basic aus jedem Unterverzeichnis funktionieren
                - HEX und BIN zur Ausgabe von Zahlenwerten im Hex-und Binärformat hinzugefügt ->PRINT HEX(92) -> 5C
                - 1262 Longs frei

15-08-2013      - Fehler in Laderoutine des Systemfonts behoben (beim Start aus Plexus heraus wurde der Systemfont nicht korrekt geladen)
                - 1270 Longs frei

16-08-2013      - Code optimiert ->1286 Longs frei

19-08-2013      - Korrektur Cog-Abfrage, es werden die freien und nicht die belegten Cogs angezeigt ->1286 Logs frei

'############################################################ Version 2.100 ######################################################################################################
'#                                           erste Unterstützung für Venatrix-und Sepia-Erweiterungskarte                                                                                  #
'#################################################################################################################################################################################

29-09-2013      - erste Codeimplementierung für Venatrix Erweiterungskarte
                - erster Befehl für Venatrix ist Cogs (Print cogs4 zeigt die freien Cogs in Venatrix an)
                - 1266 Longs frei

20-10-2013      - PCF8574-Portfunktionen für Sepia und Venatrix-Board hinzugefügt, jetzt sind ein oder zwei Joystick's anschliessbar
                - SPI-SRAM-Funktion für Venatrix-Board verfügbar (die 23lv1024-Chips funktionieren nicht mit dem Winbond-Treiber,
                  Austausch durch 23K256-Chips, dadurch 64kb zusätzlicher S-Ram Speicher nutzbar)
                - 1171 Longs frei

23-10-2013      - Portfunktionen in reg-ios als Standardfunktionen eingebaut, Unterstützung für Sepia und Venatrix-Board (Test Sepia steht noch aus)
                - Joystick-Abfrage eingebaut (beide Boards Sepia und Venatrix, Sepia-Test steht noch aus)
                - 1132 Longs frei

01-11-2013      - Venatrix-Port und Joystickfunktionen entfernt (2 IO-Boards macht keinen Sinn)
                - Sepia-Port und Joystickfunktionen eingebaut -> funktioniert
                - 1154 Longs frei

12-11-2013      - Port-Ping-Funktion für Sepia-Card hinzugefügt, damit können die Bausteine der Sepia-Karte auf vorhandensein gescannt werden
                - Venatrix-Portfunktionen entfernt, zwei Port-Erweiterungskarten macht keinen Sinn
                - 1151 Longs frei

21-11-2013      - Venatrix-Scan hinzugefügt um ein Einfrieren bei nicht angeschlossener Venatrix-Karte bei Ausführung des Befehls Cogs zu verhindern
                - 1136 Longs frei

01-12-2013      -Fehler in der Gtime und Gdate-Funktion behoben ->fehlender Rückgabewert
                -Poke und Peek erweitert, jetzt können auch word und long-werte geschrieben und gelesen werden
                -Fehler in der Klammerbehandlung behoben (Befehle mit Klammern erzeugten im Programmteil texec immer Fehler, jetzt nicht mehr)
                -XBUS-Funktion für die direkte Bus-Kommunikation hinzugefügt,
                -XBUS-Funktion kann byte, long und Strings übertragen und byte, longs empfangen (strings empfangen ist noch nicht möglich)
                -COGS-Befehl eingespart, ist jetzt mit dem XBUS-Befehl möglich
                -so ist ein Zugriff auf Systemfunktionen möglich,für zukünftige Projekte
                -1058 Longs frei

02-12-2013      -XBUS-Funktion mit der Rückgabe von Strings erweitert, der String muss an eine Stringvariable übergeben werden,
                -Printausgabe funktioniert nur mit Zahlenwerten, mal sehen, ob mir noch was einfällt
                -Call-Befehl erschaffen, hiermit sind festgelegte Systemaufrufe möglich (z.Zt.9)
                -durch den Call-Befehl wurden die Befehle FREE und VER eingespart ->Aufruf jetzt über Call-Befehl
                -942 Longs frei

04-12-2013      -etwas Codeoptimierung
                -948 Longs frei

05-12-1013      -wieder etwas Codeoptimierung
                -etwas optische Kosmetik
                -964 Longs frei

06-12-2013      -Edit-Funktion erweitert, jetzt ist der Editor solange aktiv, bis mit ESC der Edit-Modus verlassen wird
                -Code etwas kompakter gestaltet und Optikfehler beseitigt
                -Funktion Getline auf Case-Abfrage umgestellt ->10 Longs eingespart
                -Fehler in der DIR-Ausgabe behoben
                -971 Longs frei

07-12-2013      -Fehler in Editfunktion behoben (Programmende-Kennung wurde fälschlicherweise als Zeilennummer angezeigt)
                -I2C_Funktionen (start,stop read und write) hinzugefügt, funktioniert aber noch nicht so richtig ?!
                -927 Longs frei

08-12-2013      -So wie es aussieht, ist die I2C-Funktion warscheinlich zu langsam, um richtig zu funktionieren, mehr als das anpingen eines Bus-Teilnehmers funktioniert nicht :-(
                -I2C-Funktionalität auf Eis gelegt
                -974 Longs frei

14-12-2013      -dev/tty.SLAB_USBtoUART Treiber für billigeren PropPlug in BST aktiviert

'############################################################ Version 2.101 ######################################################################################################

23-12-2013      -Ersatzitem-Verwaltung wieder eingebaut, das Handling ist besser beim Itemsammeln
                -halbwegs funktioniert die Itemsammelei, nur das Ersetzen mit Tiles der richtigen Farbe klappt noch nicht richtig
                -Notenbefehl NT in NOTE umgetauft, damit wird die mathematische Funktion FN INT korrekt dargestellt
                -Momentan noch Probleme mit der Inkey-Funktion, diese muss zum Initialisieren 2 mal aufgerufen werden, sonst befindet sich noch ein Zeichen im Puffer
                -bin noch am knobeln, wie ich das löse.
                -952 Longs frei

25-12-2013      -Lade-und Speicheranzeige für BAS-Dateien ist jetzt ein Fortschrittsbalken am untersten Bildschirmrand (mit Backup und Restore)
                -Call-Befehl wieder entfernt, FREE-Befehl wieder eingebaut ->frisst zuviel Speicher
                -neue Befehle: Backup und Restore für die Sicherung und Restaurierung von Bildschirmbereichen
                -Versionsanzeige mit dem Befehl VER gibt jetzt eine Floatnummer zurück, welche die genaue Revision anzeigt
                -16kB User-Speicher zur freien Verfügung eingerichtet Adressbereich $7A000-$7DFFF (499712-516095)
                -972 Longs frei

27-12-2013      -Window-Befehl zusammengefasst, mit mehr Funktionalität ausgestattet und nach Bellatrix verschoben, dadurch Code und zwei Befehle eingespart
                -Befehle TBAR und TWIN entfernt, wird jetzt durch den Win-Befehl ersetzt
                -MBox-Befehl umgebaut, dadurch Code gespart
                -mit dem Window-Befehl kann auch abgefragt werden, welche Titel- oder Pfeiltasten mit der Maus gedrückt wurden, Rückgabe eines Wertes von 1-4
                -Window-Befehl erweitert mit der Möglichkeit einen Titelzeilentext direkt anzugeben
                -jetzt wird noch der Button-Befehl in der Optik entsprechend geändert
                -1072 Longs frei
'############################################################ Version 2.102 ######################################################################################################

28-12-2013      -Button-Befehl komplett überarbeitet -> Bella ist nur noch für die Maus-Abfrage zuständig
                -Icon-Befehl hinzugefügt, damit ist es möglich Icon-Buttons zu erstellen
                -Abfrage der Buttons erfolgt mit MB 0 (Maus-Tasten-Abfrage), Rückgabe ist die nummer des Buttons
                -968 Longs frei

29-12-2013      -Anzahl der möglichen Button auf 32 erhöht
                -ende-Routine gekürzt, das Laden der reg.sys ist in reg-ios schon drin
                -CLS-Befehl gekürzt, durch die Fensterverwaltung ist es nicht mehr nötig nur bestimmte Bereiche zu löschen
                -SDATE-Befehl durch setday erweitert dadurch ist der Befehl SDOW überflüssig
                -BLOAD-Befehl mit Stringübergabe erweitert
                -XBUS-Routine geschrumpft, muss noch kleiner werden :-(
                -989 Longs frei

30-12-2013      -Adressübergabe für Tileset-Verwaltung optimiert
                -noch etwas Codeoptimierung (ram.spin verkleinert->14 Longs eingespart) :-)
                -1055 Longs frei
                -werde den Buttonbefehl zusammenfassen und als Text,Icon-Button ausführen, dadurch wird ein Befehl eingespart und noch mehr Funktionalität erreicht.
                -aber warscheinlich erst im nächsten Jahr ;-)

31-12-2013      -Doch noch etwas gemacht :-)
                -Buttonbefehl zusammengefasst es sind Text und Icon-Button's möglich
                -so, jetzt ist Silvester !!!!!!
                -1058 Longs frei
'############################################################ Version 2.103 ######################################################################################################

01-01-2014      -Neues Jahr, neues Glück
                -Fenster-und Buttonverwaltung weiter optimiert durch Schrumpfung der Stringeingabe
                -Fenster-,Button-,Xbus-,Map- Routinen mit einheitlicher Stringeingabe versehen, dadurch massiv Platz gespart
                -Fehler in der Fenster und Buttonverarbeitung behoben
                -noch einige Probleme bei der Stringübergabe (z.Bsp.Xbus-Funktion mit str$ l( oder so
                -Fehler liegt in der XBUS-Funktion
                -1107 Longs frei

02-01-2014      -Fehler in der XBUS-Funktion gefunden und behoben
                -Xbus-Funktion funktioniert jetzt auch direkt mit Print (z.Bsp.bei der Rückgabe von Strings)
                -Stringfunktionen weiter zusammengefasst, so ist mehr Funktionalität bei weniger Speicherverbrauch möglich
                -Print-Routine gekürzt, diverse Routinen mit der neuen Stringverarbeitung versehen, dadurch wieder Platz geschaffen
                -1182 Longs frei

03-01-2013      -Möglichkeit der individuellen Windowgestaltung hinzugefügt, es ist nun möglich, die Tiles aus denen die Fenster erstellt werden auszutauschen
                -somit kann jeder Zeichensatz zur Fenstergestaltung benutzt werden und die Kompatibilität zu Plexus (Grafiktreiber) wird möglich
                -einfach eine neue Tilenummer in den E-Ram ab Adresse $7E500 poken und Win r aufrufen, ab sofort sehen die Fenster entsprechend anders aus
                -um zu den Systemfont-Einstellungen zurück zu kommen, muss man nur STILE15 eingeben
                -1133 Longs frei
'############################################################ Version 2.104 ######################################################################################################

04-01-2013      -Ersatz-Item-Tiles funktionieren jetzt korrekt, erreicht wurde dies, indem das Backuptile, auf dem der Player steht durch das Ersatzitem ausgetauscht wird,
                -dadurch ist keine weitere Behandlung im Spielprogramm nötig
                -die Eingabe der Ersatzitems hat sich allerdings geändert, nun wird jedes Ersatzitem als einzelner Befehl eingegeben (Nr,Tilenr,Farbe1,Farbe2,Farbe3)
                -1106 Longs frei

05-01-2014      -Fensterverwaltung in Bella überarbeitet, bei Klick auf ein Fensterbutton wird die Fensternummer*10+Buttonnummer zurückgegeben
                -Beispiel:Schließen Symbol im Fenster 2 gibt 22 zurück (20 für Fenster2 und 2 für Fensterbutton2)
                -dadurch wird es möglich, mehrere Fenster gleichzeitig auf Funktionen abzufragen
                -1106 Longs frei

06-01-2014      -Printfont-Routine nach Bella ausgelagert, dadurch besserer Bezug der Font-Funktion auf die Fenster-Parameter
                -Button-Funktion entsprechend angepasst
                -MBOX-Befehl entfernt, kann mit dem WIN-Befehl erzeugt werden
                -Koordinatenübergabe der Font-Funktion modifiziert,abhängig vom Fenstertyp
                -Fenstertyp 1 und 3 können bis an den Rand schreiben, Fenstertyp 3 hat nur einen y-Offset, alle anderen haben zusätzlich noch einen x-Offset
                -durch die ganzen Optimierungen sind nun wieder 7 Basic-Befehle frei (für Neuerungen)
                -1153 Longs frei

07-01-2014      -Fehler in der Feldberechnung von Arrays entdeckt (verdammt)-> aber gefunden und behoben :-)
                -Wenn der Ram-Speicher noch reicht richte ich für jedes Fenster eine Backup-Area ein kostet 50400 Bytes(möglicher Bereich ab $EE800 ->ca.70kb frei)
                -Backup-Area für Fenster eingerichtet, ist aber nur spartanisch. Funktioniert nur korrekt, wenn überlappte Fenster von oben beginnend gelöscht werden
                -wird zuerst ein verdecktes Fenster gelöscht, entstehen Fehldarstellungen, würde mich mal interessieren, wie die Profi's das machen
                -Restore-Funktion bei Fenstern abschaltbar mit WIN R(Fensternummer,Restore-> 0=Nein 1=Ja)
                -1101 Longs frei

08-01-2014      -Backup und Restore für die Fenster wieder entfernt, verbraucht zuviel Speicher und macht die Fensterfunktion zu langsam, deshalb nur verwenden,
                -wenn man die Funktion auch wirklich braucht
                -Fehler in der Subtraktions-Routine entdeckt, man musste immer ein Freizeichen zwischen den Operatoren lassen, damit die Subtraktion funktionierte
                -rechnet aber immer noch falsch bei z.Bsp. -10 - -5, werden die Zahlen in Variable gepackt funktioniert es !? seltsam :-(
                -Fehler offensichtlich gefunden in Routine PRI FACTOR wurde expr(0) gegen factor ausgetauscht (bei der Vorzeichenabfrage "-" und der Absolutwertabfrage "!")
                -jetzt sind die Ergebnisse korrekt auch bei direkter Eingabe :-)
                -jetzt scheinen die Ergebnisse auch genauer zu sein !?!
                -1152 Longs frei
'############################################################ Version 2.105 ######################################################################################################

09-01-2014      -Funktion MKFILE zum Erzeugen von Dateien hinzugefügt, wird für WRITE benötigt (ist ja doof, wenn man in eine Datei schreiben will, die noch garnicht existiert)
                -1136 Longs frei

10-01-2014      -Sid-Übertragungsprotokoll in Administra zusammengefasst, so müssen die Daten für die zwei Sid-Kanäle nicht doppelt übertragen werden
                -Übertragung erfolgt nur einmal und wird in Administra an beide Sid-Cogs weitergeleitet, das spart wieder Platz
                -sicherheitsabfrage für SDate und STime entfernt -> ist in reg-ios schon drin
                -LoadTileToRam-Routine und Mousetile-Routine zusammengefasst ->10 Longs
                -1273 Longs frei :-)

'############################################################ Version 2.106 ######################################################################################################

11-01-2014      -Beginn des Einbaus einer DATA-Funktion
                -Zahlenwerte lesen funktioniert schon
                -1129 Longs frei

12-01-2014      -DATA-Funktion mit DATA,READ,RESTORE integriert RESTORE-Funktion der Fenster in RECOVER umbenannt, Dateifunktion READ in FREAD umbenannt
                -Funktion muss aber noch kleiner werden,135 Longs ist zuviel :-(
                -Fehler in der INPUT-Routine entdeckt, es war immer ein zweiter Eingabedurchlauf nötig, um die Variable zu übernehmen
                -Fehler umgangen, indem nur einfache Variablen verwendet werden dürfen, damit ist das Array-Feld=0,0,0 ->geht zur Zeit nicht anders :-(
                -Fehler in der CHDIR-Funktion durch die String-Zusammenfassung ->behoben
                -1138 Longs frei

13-01-2014      -Routinen INPUT,WRITE,FREAD überarbeitet, jetzt ist die Verwendung von Arrays möglich, funktioniert auch korrekt
                -WRITE-ROUTINE geschrumpft, wieder etwas eingespart
                -1144 Longs frei

14-01-2014      -Write-Routine zusammengefasst und gekürzt
                -Input-Routine verändert, damit mehrfach-Strings eingegeben werden können
                -dabei ist aber eine bestimmte Reihenfolge nötig, erst Strings, dann Zahlen
                -umgekehrt führt zu Fehlern, mal sehen, ob ich das lösen kann
                -zumindest ist dadurch die INPUT-Routine kleiner geworden, schafft wieder Platz
                -1171 Longs frei

15-01-2014      -INPUT-Routine funktioniert jetzt korrekt, auch mit gemischter Array-Verwendung
                -FREAD-Routine erweitert für gemischte Array-Verwendung
                -weiter zusammengefasst (Array einlesen PRI Get_Input_Read wird jetzt von beiden Befehlen genutzt, das spart wieder Platz)
                -Durch Umbau der INPUT und FREAD-Routine enfällt das Untersuchen der Zeile durch Tokenize->dadurch werden die beiden Routinen erheblich schneller
                -DATA-Verarbeitung zusammengefasst durch Get_Input_Read, wieder etwas gespart
                -WICHTIG !!!! DATA darf nicht in der ersten Programmzeile stehen, das erzeugt Fehler (falsche Restorepointer-Interpretation)
                -1198 Longs frei

16-01-2014      -Neuer Befehl FUNC zur Erstellung eigener Funktionen begonnen,
                -Funktion wird mit FUNC variable(variable)=[Rechenoperation] definiert und im Ram abgelegt ->funktioniert auch schon
                -26 Funktionen (a..z) sind möglich
                -nun muss die Funktion nur noch aus dem Ram gelesen und mit den entsprechenden Variablen interpretiert werden
                -1142 Longs frei

17-01-2014      -Befehl FUNC im Testlauf, bisher funktioniert er sehr gut
                -es sind bis zu 26 Funktionen definierbar (a-z), diese werden im RAM ab Adresse $7E600 abgelegt
                -*************************************************************************************************
                -***** bis auf die neuen Befehle in der Testphase, ist der vorläufige Endstand erreicht :-) ******
                -***** ab jetzt wird nur noch optimiert und kleinere Änderungen vorgenommen,falls nötig.    ******
                -***** Lediglich 2 Befehle sind noch frei für Erweiterungen, ansonsten sollte der Befehlsumfang **
                -***** für einen Einplatinenrechner mehr als ausreichend sein und alle nötigen Funktionen   ******
                -***** vorhanden sein.                                                                      ******
                -*************************************************************************************************
                -1145 Longs frei
                -ich konnte es doch nicht lassen, FUNC jetzt mit bis zu zwei Operatoren möglich, warscheinlich der einzigste Basicinterpreter in der Retro-Ecke, der das kann ;-)
                -dabei ist aber zu beachten, das sich die Operanden nicht gegenseitig überschreiben(durch Doppelverwendung)
                -wenns mich juckt, mach ich bis zu 4 Operanden möglich, in der E-technik braucht man meistens mindestens 3 Variablen, um Berechnungen anzustellen
                -1110 Longs frei
                -sysmode-Variable der RAM-Aufrufe in reg-ios entfernt und im Programm entsprechend geändert, da die Ram-Disk nicht benutzt wird, spart das 40 Longs
                -Fehler in der Klammer-Behandlung behoben, Rechenoperationen erzeugten bei bestimmten Klammerrechnungen Fehler
                -1155 Longs frei
'############################################################ Version 2.107 ######################################################################################################
18-01-2014      -LOAD-Funktion erweitert, es ist jetzt möglich, Programmzeilen nachzuladen (MERGE-Funktion)
                -dabei gibt es zwei Modi, entweder nur nachladen oder (z.Bsp.im Programm) nachladen und Programm fortsetzen
                -LOAD"Dateiname.EXT",2 nur nachladen, LOAD"Dateiname.ext",3 nachladen und Programm fortsetzen
                -jetzt könnte man noch eine SAVE-Möglichkeit schaffen, bei der nur ein bestimmter Programmbereich (Start-Zeile bis End-Zeile) gespeichert wird
                -Fehlerabfang in INPUT-Routine eingebaut, Input kann mit ESC abgebrochen werden
                -Es fehlt aber noch eine Fehlerabfrage, wenn ein Mehrstelliges Input-Feld nicht mit der vorgesehenen Anzahl Daten versorgt wurde, wie mach ich das nun wieder? :-(
                -1152 Longs frei

19-01-2014      -Diverse Sicherheitsabfragen bei INPUT,FREAD,READ eingebaut, jetzt sollte die Dateneingabe bei Fehlern eigentlich sicher abgefangen werden
                -hat aber etwas Platz gekostet
                -1132 Longs frei
                -Array-Befüllung zusammengefasst, dadurch wieder ein wenig Platz gewonnen
                -Home-Befehl entfernt, kann mit POS0,0 genauso erreicht werden, dadurch sind jetzt wieder 3-Befehle frei
                -Befehle MX,MY und MZ zu MGET(1..3) zusammengefasst, 2 Befehle gewonnen, jetzt sind 5 Befehle frei
                -Erweiterung der DIM-Funktion, jetzt können diverse Dimensionierungen durch komma getrennt eingegeben werden und müssen nicht einzeln vorgenommen werden
                -1162 Longs frei

20-01-2014      -Out of DATA Error , wenn das Ende des Datenfeldes erreicht ist eingefügt
                -diverse Fehlerabfragen in den Routinen Window,Button,Playersettings,Port, Map und Spritesettings nachgerüstet
                -FUNC-Routine etwas gestrafft und Fehlerabfragen für zuviel oder zuwenig Operanden eingefügt
                -1157 Longs frei

22-01-2014      -Math-Funktion umgebaut, dadurch Platz gespart, obs jetzt schneller ist, kann ich nicht sagen
                -mathematische Funktion MIN und MAX entfernt, kann man auch mit > oder < lösen, dadurch 19 Longs gewonnen
                -1199 Longs frei

23-01-2014      -Noch etwas Code eingespart
                -Goto-Schleifendurchlauf gestrafft
                -1211 Longs frei

24-01-2014      -Math-Funktion Floor und Ceil entfernt, ich glaube soetwas braucht man eigentlich nicht
                -Speicherschreibroutine für Fenster-Tiles (WIN-Funktion) umgebaut, dadurch viel kleiner geworden :-)
                -Ladebalken-Funktion umgebaut, Ladebalken nur sichtbar bei normaler Ladefunktion, bei Nachladefunktion nicht sichtbar (für Programmablauf besser)
                -Lade-und Save-Balken einen eigenen Backup-Speicher von 256 Bytes zugewiesen $7FD00 '....$7FDFF, verhindert Überschreibungen durch User
                -1248 Longs frei

25-01-2014      -Inkey-Problem mit der doppelt nötigen Abfrage am Anfang behoben, jetzt ist der Tastaturpuffer nach dem Start wirklich leer
                -Print-Routine auf Case umgestellt
                -1253 Longs frei

26-01-2014      -dwdF32.spin auf die im Basic verwendeten Funktionen gekürzt, somit wird wieder etwas Platz geschaffen -> in BasF32.spin umbenannt
                -Division durch 0-Fehler durch entsprechende Abfrage abgefangen, führte zum Hängenbleiben des Hive
                -FUNC-Funktion auf bis zu vier Operanden erweitert :-), das sollte bei Retro-Basic-Interpretern einmalig sein
                -Window-Funktion intern angepasst, um Kompatibilität zu Plexus herzustellen
                -1273 Longs frei - jetzt ist erst mal Schluss!!!

29-01-2014      -Fehler in der Math-Funktion behoben (tok-abfragezähler begann bei -1 statt bei null, dadurch wurden die falschen Funktionen aufgerufen)
                -1272 Longs frei

02-02-2014      -Float.spin gegen FME.spin ausgetauscht, ist zwar langsamer aber genauer und viel kleiner
                -Funktionen Arcus-Sinus und Arcus-Cosinus wieder aufgenommen
                -Pause-Funktion geändert der Wert 1 repräsentiert 1mS ->1000 mS=1sek
                -Befehl FORM für metrische Zahlenausgabe hinzugefügt Bsp.Form"VA" ->Print 12000 ->Ausgabe 12.000 kVA
                -Rückkehr zur Standard-Zahlenausgabe ->FORM"0"
                -getanynumber umgebaut, jetzt ist die Verwendung von Exponenten in Zahlen möglich bsp.2.4e+13
                -gültiger Zahlenbereich 1E+38 bis 1E-38
                -Anpassung der Zahlenausgabe, ab 7-stelliger Zahlen wird mit Exponent ausgegeben, es gibt aber noch Fehler, wenn mehr als 9 Stellen angegeben werden
                -daher müssen ab der 9.Stelle die Zahlen in Exponentialschreibweise eingegeben werden, sonst sind die Ausgaben fehlerhaft!!!
                -Befehl FORM wieder entfernt, kollidiert mit der Exponent-Ausgabe
                -1341  Longs frei

04-02-2014      -mathematische Funktion FRAC entfernt
                -mathematische Funktion EXP entfernt, kann jetzt direkt eingegeben werden
                -Fehlerabfrage in mathfunction korrigiert
                -Fehler in der STRING$-Funktion behoben
                -1355 Longs frei

07-02-2014      -mathematische Funktion DEG und RAD hinzugefügt zur Umrechnung von Bogenmaß in Winkelgrad und umgekehrt
                -Renumber-Funktion zum Neunummerieren der Basic-Zeilen angefangen
                -RENUM Startzeile, Endezeile,Neue Startzeile,Schrittweite
                -oder RENUM ohne Parameter nummeriert alle Basiczeilen, erste neue Zeilennummer lautet 10 mit Schrittweite 10
                -Sprungadressen (Goto,Gosub)werden noch ignoriert, mal sehen, ob das lösbar ist?

08-02-2014      -das Neunummerieren der Sprungadressen ist zu umfangreich, da sie als String gespeichert werden, müsste bei einer anderen Länge des Zeilennummern-Strings
                -die gesamte Basiczeile neu in den Speicher eingepasst werden, das ist einfach zu umständlich und würde bei großen Programmen sehr viel Zeit
                -und die entsprechende Routine zu viel Speicher kosten, Sprungziele müssen also selbst angepasst werden (wie beim C64-Basic)->besser als nichts
                -1314 Longs frei

12-02-2014      -Probleme beim Laden des Basic-Grafiktreibers aus älteren Plexus-Versionen
                -Fehler lag im Administra-Code (behoben), die Sepia-Karten-Abfrage muss beendet werden, bevor ein neuer Administra-Code gebootet wird
                -Verzeichniswechsel noch nicht perfekt, wird noch angepasst
                -1318 Longs frei

16-02-2014      -Routine XBUS geändert lookup durch case-Abfrage ersetzt bei putchar und putlong, Lookup funktionierte nicht immer korrekt
                -Anpassung für die Printausgabe von numerischen Werten aus der XBUS-Funktion
                -1305 Longs frei

21-02-2014      -CHDIR-Befehl mit Dirmarkern geändert, jetzt kann man in jedes Verzeichnis springen
                -dadurch ist das uneingeschränkte Bewegen in den Verzeichnissen möglich
                -überflüssige Variablen entfernt
                -1308 Longs frei  ---> ******* Version veröffentlicht als TRIOS-BASIC 2.1 **********

'############################################################ Version 2.2 ######################################################################################################
22-02-2014      -Note2Freq-Funktion nach Administra ausgelagert, existiert dort schon und muss nicht hier auch noch vorhanden sein
                -dadurch wieder etwas Platz gespart
                -1322 Longs frei

01-03-2014      -Durch die Arbeiten an Plexus, wurde ein neues Feature geschaffen, es ist aus Plexus heraus möglich, Basic mit Startparametern zu versehen
                -d.h. es können gleich beim Start beliebige Basic-Instruktionen übergeben werden
                -zBsp.könnte man automatisch beim Start ein bestimmtes Programm laden oder den Bildschirm löschen und eine eigene Begrüßungs-Meldung ausgeben
                -1291 Longs frei

24-03-2014      -Puffer im Seriell Treiber standardmäßig auf 128 Byte eingestellt
                -1259 Longs frei

08-04-2014      -zwei neue STR$ Funktionen eingefügt str$ d wandelt alle Buchstaben im String in Kleinbuchstaben um
                -str$ u wandelt alle Buchstaben eines Strings in Großbuchstaben um
                -1227 Longs frei

09-04-2014      -Umwandlungs-Funktion Groß-Klein (str$ g, str$ k) zusammengefasst
                -1232 Longs frei

13-04-2014      -Timer-Objekt etwas gestrafft und Timer-Auflösung beim Start auf 1ms geändert
                -so entspricht der Timer-Startwert von 1000 einer Sekunde (Timer s(1,1000)-startet Timer1 mit dem Wert 1000=1Sek)
                -damit ist die Eingabe analog zum Pausen-Wert ->Pause 1000 entspricht ebenfalls einer Sekunde
                -1232 Longs frei

16-04-2014      -Kopierfunktion von Speicherbereichen im E-Ram hinzugefügt, dadurch wird das Einfügen von Zeilen in ein Bestehendes Programm schneller
                -entsprechende Routine im Basic geschrumpft,hat aber trotzdem einige Longs gekostet :-(
                -1216 Longs frei

17-04-2014      -ram.spin wurde weiter geschrumpft
                -LAN-Funktionen wurden in admsid eingebaut, könnten jetzt im Basic eingefügt werden
                -reg-ios mit glob-con zusammengebracht.
                -1220 Longs frei

20-04-2014      -einige kleine Veränderungen im Code um etwas Platz zu schaffen (Abfragen durch Bitmanipulationen ersetzt)
                -READPARAMETER-Aufruf von Doline nach init verschoben, so wird die Abfrage auf Parameter nur einmal beim Start von Basic durchgeführt
                -1233 Longs  frei

22-04-2014      -ram-spin mit neuer Funktion (Zeile überspringen) erweitert und Basic-Code entsprechend angepasst
                -binsave und Map-save mit Block-savebefehl geändert
                -Fehler in der Zeilen-Bearbeitung behoben, durch die PASM-Routinen wurden manche Adressen falsch berechnet (Kopieren von Speicherbereichen)
                -Fehler in der seriell-Übertragung behoben, es wurden bei Zahlenausgaben zuviele Bytes gesendet
                -Fehler in der Dateibehandlung behoben, der Appendbefehl hat in adm-fat keine Wirkung, Funktion in admsid.spin nachgebildet
                -Konvertierung der OPEN-Modes (a/w/r) in Großbuchstaben nach admsid.spin verlagert (braucht man ja öfter :-)), dadurch wieder etwas Platz gewonnen
                -eine case-Abfrage in BUS_Funktionen durch lookup ersetzt
                -mathematische Funktion DEG und RAD wieder entfernt, kann man leicht selbst ausrechnen)
                -1274 Longs frei

29-04-2014      -SID-Soundfunktionen unter einem gemeinsamen Befehl SID +Option zusammengefasst, interne Soundbefehls-Verarbeitung gestrafft
                -dadurch sind 10 Basic-Befehle frei geworden :-)
                -1276 Longs frei

30-04-2014      -Syntax-Hervorhebung kreiert, sieht cool aus, hat aber gekostet
                -1195 Longs frei

01-05-2014      -Syntax-Hervorhebung weiter überarbeitet
                -1218 Longs frei
                -Laden,Speichern und Merge-Funktion geschieht jetzt binär
                -es gibt eine Import/Export-Funktion für Basic-Textdateien, diese wurde extern realisiert
                -gespeichert und geladen wird ab sofort generell in binärer Form, das spart Platz und ist auch erheblich schneller
                -Timerfunktion aufgebohrt, jetzt ist Timer 9-11 jeweils ein Counter
                -Syntaxhervorhebung modifiziert, DATA-Zeilen werden jetzt Orange dargestellt
                -optische Änderung bei Aufruf der Hilfefunktion, es wird der Bildschirm beim Start der Hilfe gesichert und nach Beendigung wieder hergestellt
                -dadurch entsteht der Eindruck, das die Hilfe im Hauptprogramm integriert ist
                -Import-und Export-Funktion sind optisch integriert, es wird der Eindruck vermittelt, das man im Hauptprogramm bleibt
                -1325 Longs frei

02-05-2014      -DIR-Funktion gekürzt, die Parameter x und y entfernt (kann mit POS x,y erfolgen)
                -Hinweiszeile <KEY? / ESC > entfernt, die Ausgabe richtet sich nach der aktuellen x,y-Position
                -dadurch ist die Ausgabe optisch besser, da nicht in den vorhandenen Bildschirm sondern fortlaufend geschrieben wird
                -außerdem wurde dadurch wieder Platz geschaffen ca.50Longs
                -Syntaxhervorhebung um die Klammern [ und ] erweitert
                -1375 Longs frei

08-05-2014      -Load und Save-Teil geschrumpft, Handbuch entsprechend der bisher durchgeführten Änderungen angepasst
                -1377 Longs frei

11-05-2014      -Import.sys durch Abfrage auf gültige Datei ergänzt, da sich sonst der Hive aufhängt, wenn zum bsp. versucht wird eine Binärdatei zu importieren.
                -reg-ios und Seriell-Treiber als spezielle Basic-Varianten gespeichert, da der Seriell-Puffer im Basic kleiner sein soll (Speicherplatz sparen)
                -REM Kommentare haben jetzt ebenfalls eine eigene Farbe
                -Fehler in Import-Routine behoben (PI und Wurzelzeichen wurden als fehlerhafte Zeichen interpretiert)
                -1370 Longs frei

13-05-2014      -Befehl PUT kreiert für die direkte Zeichenausgabe mit x-y Koordinaten, hier wird die aktuelle Zeichen-und Hintergrundfarbe benutzt
                -ist etwas schneller als pos x,y + Print
                -Fehler in der DIR-Routine behoben (im Modus 0 wurde nichts gelesen)
                -DIR-Routine gestrafft
                -1369 Longs frei

16-05-2014      -################### Version 2.2 veröffentlicht ####################

'############################################################ Version 2.3 ######################################################################################################

19-05-2014      -Basic-Runtime-Modul geschaffen, das erlaubt die direkte Ausführung von Basicdateien aus Plexus heraus
                -1369 Longs frei

21-05-2014      -Hilfe zur Onlinehilfe umgebaut, dadurch entfällt der Aufruf als externe Datei und spart die Arbeit an zwei Programmen
                -HELP zeigt alle verfügbaren Befehle auf dem Bildschirm an
                -HELP A zeigt alle mit A beginnenden Befehle an
                -HELP BEFEHL zeigt die Hilfe zum entsprechenden Befehl an
                -Hilfetexte angepasst
                -Hilfetextausgabe farbig (blau) gestaltet
                -1313 Longs frei

23-05-2014      -DIR-Ausgabe etwas angepasst, Verzeichnisse werden jetzt in einer anderen (dynamischen) Farbe angezeigt
                -Ausgabe des HELP Befehls ohne Parameter mit Tastenabfrage ergänzt um ein überscrollen der Ausgabe zu verhindern (alle Befehle passen nicht auf den Bildschirm)
                -ausserdem abfrage auf x-position um zu verhindern, das ein Befehl umgebrochen wird und so schlechter lesbar ist.
                -1304 Longs frei


 --------------------------------------------------------------------------------------------------------- }}

obj
  ios    :"reg-ios-bas"
  Fl     :"FME"
  FS     :"BasFloatString2"
  TMRS   :"timer"
  gc     :"glob-con"

con

_CLKMODE     = XTAL1 + PLL16X
_XINFREQ     = 5_000_000

   version   = 2.303

   fEof      = $FF                     ' dateiende-kennung
   linelen   = 85                      ' Maximum input line length
   quote     = 34                      ' Double quote
   caseBit   = !32                     ' Uppercase/Lowercase bit
   point     = 46                      ' point
   STR_LEN   = 34                      ' Stringlänge von Stringvariablen in Arrays
   FIELD_LEN = 512                     ' Array-Feldgröße (max Feldgröße 8x8x8 -> Dim a(7,7,7)
   DIR_ENTRY = 546                     ' max.Anzahl mit DIR-Befehl gefundener Einträge
   STR_MAX   = 41                      ' maximale Stringlänge für Printausgaben und font
   DPL_CNT   = 1200                    ' Map-und Bildschirm-Shadow-Speicher-Zähler (40Spalten*30Zeilen=1200-Tiles)
'*****************Speicherbereiche**********************************************
   maxstack  = 20                      ' Maximum stack tiefe fuer gosub
   userPtr   = $1FFFF                  ' Ende Programmspeicher  128kb
   TMP_RAM   = $20000 '....$3FFFF      ' Bearbeitungsspeicher   128kb (fuer die Zeileneditierung bzw.Einfuegung von Zeilen)
   TILE_RAM  = $40000 '....$667FF      ' hier beginnt der Tile-Speicher fuer 14 Tiledateien
   SYS_FONT  = $66800 '....$693FF      ' ab hier liegt der System-Font 11kb
   MOUSE_RAM = $69400 '....$6943F      ' User-Mouse-Pointer 64byte
   DIR_RAM   = $69440 '....$6AFFF      ' Puffer fuer Dateinamen 7103Bytes fuer 546 Dateinamen
   VAR_RAM   = $6B000 '....$77FFF      ' Variablen-Speicher fuer Array-Variablen a[0...511]-z[0...511] (13312 moegliche Variablen)
   MAP_RAM   = $78000 '....$79C27      ' Shadow-Display (Pseudo-Kopie des Bildschirmspeichers)
   'FREI_RAM   $79C28 .... $79FFF      ' freier RAM-Bereich 984 Bytes auch für Shadow-Display

   DATA_RAM = $7A000 '.... $7DFFF      ' 16kB DATA-Speicher

   BUTT_RAM = $7E000 '.... $7E4FF      ' ca.1kB Button Puffer
   WTILE_RAM= $7E500 '.... $7E5FF      ' Win-Tile Puffer hier können die Tiles, aus denen die Fenster gebaut werden geändert werden
   FUNC_RAM = $7E600 '.... $7EFFF      ' Funktions-Speicher, hier werden die selbstdefinierten Funktionen gespeichert

   ERROR_RAM = $7F000 '....$7FAFF      ' ERROR-Texte
   DIM_VAR   = $7FB00 '....$7FBFF      ' Variablen-Array-Dimensionstabelle
   DIM_STR   = $7FC00 '....$7FCFF      ' String-Array-Dimensionstabelle
   BACK_RAM  = $7FD00 '....$7FDFF      ' BACKUP RAM-Bereich 256 Bytes für Ladebalken
   'Frei-Ram = $7FE00  ....$7FEFF      ' noch freier Bereich 256 Bytes
   PMARK_RAM = $7FFF0                  ' Flag für Reclaim           Wert= 161
   BMARK_RAM = $7FFF1                  ' Flag für Basic-Warm-Start  Wert= 121
   SMARK_RAM = $7FFF2                  ' Flag für übergebenen Startparameter Wert = 222

   STR_ARRAY = $80000 '....$EE7FF      ' Stringarray-Speicher
   USER_RAM  = $EE800 '....$FFEFF      ' Freier Ram-Bereich, für Anwender, Backup-Funktion usw.
   ADM_SPEC       = gc#A_FAT|gc#A_LDR|gc#A_SID|gc#A_LAN|gc#A_RTC|gc#A_PLX'%00000000_00000000_00000000_11110011
'***************** Button-Anzahl ************************************************
   BUTTON_CNT   = 32                       'Anzahl der möglichen Button
'******************Farben ********************************************************
  #$FC, Light_Grey, #$A8, Grey, #$54, Dark_Grey
  #$C0, Light_Red, #$80, Red, #$40, Dark_Red
  #$30, Light_Green, #$20, Green, #$10, Dark_Green
  #$1F, Light_Blue, #$09, Blue, #$04, Dark_Blue
  #$F0, Light_Orange, #$E6, Orange, #$92, Dark_Orange
  #$CC, Light_Purple, #$88, Purple, #$44, Dark_Purple
  #$3C, Light_Teal, #$28, Teal, #$14, Dark_Teal
  #$FF, White, #$00, Black

'*****************Tastencodes*****************************************************
   ENTF_KEY  = 186
   bspKey    = $C8                     ' PS/2 keyboard backspace key
   breakKey  = $CB                     ' PS/2 keyboard escape key
   fReturn   = 13
   fLinefeed = 10
   KEY_LEFT  = 2
   KEY_RIGHT = 3
   KEY_UP    = 4
   KEY_DOWN  = 5

   MIN_EXP   = -999999
   MAX_EXP   =  999999

var
   long sp, tp, nextlineloc, rv, curlineno, pauseTime                         'Goto,Gosub-Zähler,Kommandozeile,Zeilenadresse,Random-Zahl,aktuelle Zeilennummer, Pausezeit
   long stack[maxstack],speicheranfang,speicherende                           'Gosub,Goto-Puffer,Startadresse-und Endadresse des Basic-Programms
   long forStep[26], forLimit[26], forLoop[26]                                'Puffer für For-Next Schleifen
   long prm[10]                                                               'Befehlszeilen-Parameter-Feld (hier werden die Parameter der einzelnen Befehle eingelesen)
   long gototemp,gotobuffer,gosubtemp,gosubbuffer                             'Gotopuffer um zu verhindern das bei Schleifen immer der Gesamte Programmspeicher nach der Zeilennummer durchsucht werden muss
   long datapointer                                                           'aktueller Datapointer
   long restorepointer                                                        'Zeiger für den Beginn des aktuellen DATA-Bereiches
   long num1,num2                                                             'Puffer für mathematische Funktionen
   long usermarker,basicmarker                                                'Dir-Marker-Puffer für Datei-und Verzeichnis-Operationen
   word tilecounter                                                           'Zaehler fuer Anzahl der Tiles in einer Map
   word filenumber                                                            'Anzahl der mit Dir gefundenen Dateien
   word var_arr[3]                                                            'temp array speicher varis-funktion für direkten Zugriff
   word var_tmp[3]                                                            'temp array speicher varis-funktion für zweite Variable (in pri factor) um Rechenoperationen u.a. auszuführen
   word var_temp[3]                                                           'temp array speicher erst mit dem dritten Speicher funktioniert die Arrayverwaltung korrekt
   byte workdir[12]                                                           'aktuelles Verzeichnis
   byte fileOpened,tline[linelen]                                             'File-Open-Marker,Eingabezeilen-Puffer
   byte debug                                                                 'debugmodus Tron/Troff
   byte cursor                                                                'cursor on/off
   byte win                                                                   'Fensternummer
   byte farbe,hintergr,cursorcolor                                            'vorder,hintergrundfarbe und cursorfarbe
   byte file1[12],dzeilen,xz,yz,buff[8],modus                                 'Dir-Befehl-variablen   extension[12]
   byte volume,play                                                           'sidcog-variablen
   byte xtiles[16]                                                            'xtiles fuer tilenr der Tile-Dateien       '
   byte ytiles[16]                                                            'ytiles fuer tilenr der Tile-Dateien
   byte str0[STR_MAX],strtmp[STR_MAX]                                         'String fuer Fontfunktion in Fenstern
   byte aktuellestileset                                                      'nummer des aktuellen tilesets
   byte font[STR_MAX]                                                         'Stringpuffer fuer Font-Funktion und str$-funktion
   byte mapram                                                                'Map-Schreibmarker
   byte math[8]                                                               'Funktionsstring für mathematische funktionen
   byte ongosub                                                               'on gosub variable
   byte serial                                                                'marker für serielle schnittstelle 1=geöffnet 0=geschlossen
   byte actionkey[5]                                                          'Belegung der Spielertasten -> nach Bella verschoben
   byte item[6]                                                               'von Spielerfigur einsammelbare Gegenstände
   byte block[10]                                                             'tiles, die nicht überquert werden können
   byte collision[6]                                                          'tiles mit denen man kollidieren kann
   byte itemersatz[30]                                                        'Item-Ersatztiles, die das eingesammelte item im Display-Ram und auf dem Bildschirm ersetzen
   byte f0[STR_MAX]                                                           'Hilfsstring
   byte ADDA,PORT                                                             'Puffer der Portadressen der Sepia-Karte
   byte returnmarker                                                          'Abbruchmarker für Zeileneditor
   byte editmarker                                                            'Editmarker für Zeileneditor
   byte actorpos[2]                                                           'Zwischenspeicher für x,y-Position des Spieler-Tiles
   byte button_art[BUTTON_CNT]                                                'Puffer für die Art des Buttons (Text-oder Icon)
   byte sid_command[7]                                                        'SID-Sound-Kommando

dat
   tok0  byte "IF",0                                                                       '128    getestet
   tok1  byte "THEN",0                                                                     '129    getestet
   tok110 byte "ELSE",0                                                                    '238    getestet
   tok2  byte "INPUT",0    ' INPUT {"<prompt>";} <var> {,<var>}                            '130    getestet
   tok3  byte "PRINT",0    ' PRINT                                                         '131    getestet
   tok88 byte "ON",0       ' ON GOSUB GOTO                                                  216    getestet
   tok4  byte "GOTO",0                                                                     '132    getestet
   tok5  byte "GOSUB", 0                                                                   '133    getestet
   tok6  byte "RETURN", 0                                                                  '134    getestet
   tok7  byte "REM", 0                                                                     '135    getestet
   tok8  byte "NEW", 0                                                                     '136    getestet
   tok9  byte "LIST", 0     'list <expr>,<expr> listet von bis zeilennummer                 137    getestet      NICHT AENDERN Funktionstaste!!
   tok10 byte "RUN", 0                                                                     '138    getestet      NICHT AENDERN Funktionstaste!!
   tok26 byte "FOR", 0      ' FOR <var> = <expr> TO <expr>                                  154    getestet
   tok27 byte "TO", 0                                                                      '155    getestet
   tok28 byte "STEP", 0     ' optional STEP <expr>                                          156    getestet
   tok29 byte "NEXT", 0     ' NEXT <var>                                                    157    getestet
   tok52 byte "END", 0      '                                                               180    getestet
   tok53 byte "PAUSE", 0    ' PAUSE <time ms> {,<time us>}                                  181    getestet
   tok58 byte "DUMP", 0     ' DUMP <startadress>,<anzahl zeilen>,<0..1> (0 Hram,1 Eram)     186    getestet
   tok86 byte "BYE",0       ' Basic beenden                                                 214    getestet      NICHT AENDERN Funktionstaste!!
   tok84 byte "INKEY",0     'Auf Tastendruck warten Rueckgabe ascii wert                    212    getestet
   tok85 byte "CLEAR",0     'alle Variablen loeschen                                        213    getestet
   tok87 byte "PEEK",0      'Byte aus Speicher lesen momentan nur eram                      215    getestet
   tok80 byte "POKE",0      'Byte in Speicher schreiben momentan nur eram                   208    getestet
   tok89 byte "BEEP",0      'beep oder beep <expr> piepser in versch.Tonhoehen              217    getestet
   tok92 byte "EDIT",0      'Zeile editieren                                                220    getestet
   tok61 byte "RENUM",0      'Renumberfunktion                                              189    getestet

'************************** Dateioperationen **************************************************************
   tok12 byte "OPEN", 0     ' OPEN " <file> ",<mode>                                        140    getestet
   tok13 byte "FREAD", 0     ' FREAD <var> {,<var>}                                         141    getestet
   tok14 byte "WRITE", 0    ' WRITE <"text"> :                                              142    getestet
   tok15 byte "CLOSE", 0    ' CLOSE                                                         143    getestet
   tok16 byte "DEL", 0      ' DELETE " <file> "                                             144    getestet
   tok17 byte "REN", 0      ' RENAME " <file> "," <file> "                                  145    getestet
   tok102 byte "CHDIR",0    ' Verzeichnis wechseln                                          230    getestet      kann nicht CD heissen, kollidiert sonst mit Hex-Zahlen-Auswertung in getanynumber
   tok18 byte "DIR", 0      ' dir anzeige                                                   146    getestet      NICHT AENDERN Funktionstaste!!
   tok19 byte "SAVE", 0     ' SAVE or SAVE [<expr>] or SAVE "<file>"                        147    getestet      NICHT AENDERN Funktionstaste!!
   tok20 byte "LOAD", 0     ' LOAD or LOAD [<expr>] or LOAD "<file>" ,{<expr>}              148    getestet      NICHT AENDERN Funktionstaste!!
   tok54 byte "FILE", 0     ' FILE wert aus datei lesen oder in Datei schreiben             182    getestet
   tok24  byte "GFILE",0    ' GETFILE rueckgabe der mit Dir gefundenen Dateien ,Dateinamen  152    getestet
   tok78 byte "MKDIR",0     ' Verzeichnis erstellen                                         206    getestet
   tok112 byte "GATTR",0    ' Dateiattribute auslesen                                       240    getestet
   tok90 byte "BLOAD",0      'Bin Datei laden                                               218    getestet
   tok57 byte "MKFILE", 0    'Datei erzeugen                                                185    getestet

'************************* logische Operatoren **********************************************************************
   tok21 byte "NOT" ,0      ' NOT <logical>                                                '139    getestet
   tok22 byte "AND" ,0      ' <logical> AND <logical>                                      '150    getestet
   tok23 byte "OR", 0       ' <logical> OR <logical>                                       '151    getestet
'************************* mathematische Funktionen *****************************************************************
   tok106 byte "FN",0       'Mathematische funktionen                                       234    getestet
                            ' ^,!,//, Sin,Cos,Tan,ArcTan,Ln,e,EXP,Round,Min,Max,Log
                            'Wurzel, Fraction,Int,Floor,Ceil,SHL;SHR;REV;ROR;ROL;ODER;XODER,UND
   tok11 byte "RND", 0      'Zufallszahl von x                                             '139    getestet
   tok83 byte "FUNC",0       'mathematische Benutzerfunktionen                              211    getestet

'******************************** Mouse Befehle *********************************************************************
   tok93 byte "MGET",0      'Mouse-xyz-position                                           ' 221    getestet
   tok97 byte "MB",0        'Mouse-Button                                                 ' 225    getestet
   tok63 byte "MOUSE",0     'Mouse on off  Mouse on,farbe                                 ' 191    getestet
   tok96 byte "MBOUND",0    'Mouse-Bereich definieren                                     ' 224    getestet

'************************* Bildschirmbefehle ***********************************************************************
   tok59 byte "COL",0       'Farbe setzen  1,2,3 Vordergrund,hintergrund,Cursor             187    getestet
   tok60 byte "CLS",0       'Bildschirm loeschen cursor oberste Zeile Pos1                  188    getestet
   tok62 byte "POS",0       'Cursor an Pos x,y setzen -> Locate(x,y)                        190    getestet
   tok64 byte "PLOT",0      'Pixel setzen                                                   192    getestet
   tok66 byte "SCRDN",0     'n Zeilen runterscrollen -> Scrdown(n)                          194    getestet
   tok67 byte "SCRUP",0     'n Zeilen hochscrollen   -> Scrup(n)                            195    getestet
   tok68 byte "CROFF",0     'Cursor ausschalten                                             196    getestet
   tok69 byte "CRON",0      'Cursor einschalten                                             197    getestet
   tok39 byte "WIN", 0      'Fenster C,T,S,R erstellen                                      167    getestet
   tok49 byte "FREE",0      'freien Speicher anzeigen                                       177    getestet
   tok74 byte "BUTTON",0    'Button erzeugen                                                202    getestet
   tok98 byte "FRAME",0     'Rahmen zeichnen                                                226    getestet
   tok99 byte "WSET",0      'in ein zuvor definiertes Fenster springen                      227    getestet
   tok101 byte "SCROLL",0   'Textzeile nach links scrollen                                  229    getestet
   tok81 byte "CIRC",0      'Kreis zeichnen                                                 209    getestet
   tok82 byte "LINE",0      'Linie zeichnen                                                 210    getestet
   tok103 byte "BOX",0      '2dbox zeichnen                                                 231    getestet
   tok118 byte "GETX",0     'Cursor X-Position lesen                                        246    getestet
   tok119 byte "GETY",0     'Cursor Y-Position lesen                                        247    getestet
   tok122 byte "HEX",0      'Ausgabe von Hex-Zahlen mit Print                           '   250    getestet
   tok120 byte "BIN",0      'Ausgabe von Binärzahlen mit Print                          '   248    getestet
   tok125 byte "VER",0      'Versionsanzeige                                            '   253    getestet
   tok123 byte "BACKUP", 0   'Bildschirmbereich sichern                                  '  251    getestet
   tok124 byte "RECOVER",0   'Bildschirmbereich restaurieren                             '  252    getestet

'************************* Datum und Zeit funktionen ***************************************************************
   tok70 byte "STIME",0    'Stunde:Minute:Sekunde setzen ->                                 198    getestet
   tok71 byte "SDATE",0    'Datum setzen                                                    199    getestet
   tok76 byte "GTIME",0    'Zeit   abfragen                                                 204    getestet
   tok77 byte "GDATE",0    'Datum abfragen                                                  205    getestet
   tok65 byte "TIME",0     'Zeit anzeigen                                                   193    getestet
   tok111 byte "TIMER",0   'Timer-Funktionen  set,read,clear?,entry,delete                  239    getestet

'**************************** STRINGFUNKTIONEN ********************************************************************

   tok35 byte "STR$", 0     'l,m,r,g,k left, mid, right ,groß,klein                         163    getestet
   tok36 byte "COMP$", 0    'Stringvergleich                                                164    getestet
   tok37 byte "LEN", 0      'Stringlänge zurueckgeben                                       165    getestet
   tok48 byte "CHR$", 0     'CHR$(expr)                                                     176    getestet
   tok105 byte "ASC",0      'ASCII-Wert einer Stringvariablen zurueckgeben                  233    getestet
   tok56  byte "TAB", 0     'Tabulator setzen                                               184    getestet
   tok113 byte "VAL",0      'String in FLOAT-Zahlenwert umwandeln                           241    getestet
   tok108 byte "STRING$",0   'Zeichenwiederholung                                           236    getestet
   tok109 byte "DIM",0       'Stringarray dimensionieren                                    237    getestet
   tok116 byte "INSTR",0    'Zeichenkette in einer anderen Zeichenkette suchen            ' 244    getestet

'**************************** Grafik-Tile-Befehle *****************************************************************
   tok34  byte "TLOAD", 0    'Tileset in eram laden                                         162    getestet
   tok51  byte "TILE", 0     'Tileblock aus aktuellem Tileset anzeigen                      179    getestet
   tok50  byte "STILE", 0    'tileset in bella laden                                        178    getestet
   tok100 byte "TPIC",0      'komplettes Tileset als Bild anzeigen                          228    getestet
   tok104 byte "FONT",0      'Text mit aktuellem Tileset als Font ausgeben                  232    getestet
   tok25  byte "MAP", 0      'MAP-Befehle L=load,S=Save,D=Display,W=Write in Ram          ' 153    getestet
   tok91 byte "PLAYER",0     'Spielerfigur-Parameter p,k,g(parameter,Keys,collision,get)    219    getestet
   tok114 byte "PLAYXY",0    'Spielerbewegung                                               242    getestet
   tok121 byte "SPRITE",0    'Sprite-Parameter p, m, s(parameter, move,speed,usw)           249    getestet

'**************************** Daten-Befehle *****************************************************************
   tok38 byte "READ", 0      'Data Lesen                                                   '166    getestet
   tok40 byte "DATA", 0      'Data-Anweisung                                               '168    getestet
   tok47 byte "RESTORE", 0   'Data-Zeiger zurücksetzen                                      175    getestet

'**************************** Funktionen der seriellen Schnittstelle **********************************************
   tok115 byte "COM",0      'serielle Schnittstelle öffnen  / schliessen                    243    getestet

'***********************SID-Synth-Befehle**************************************************************************
   tok30 byte "SID", 0       'SID_Soundbefehle                                              158    getestet
   tok31 byte "PLAY", 0      'SID DMP-Player                                               '159
   tok32 byte "GDMP", 0      'SID DMP-Player-Position                                      '160

'************************ Port-Funktionen *************************************************************************
   tok79 byte "PORT",0       ' Port-Funktionen      Port s,i,o,p                            207    getestet
   tok55 byte "JOY",0        ' Joystick abfragen für 2 Joysticks                            183    getestet
   tok117 byte "XBUS",0      ' direkte Bus-Kommunikation zu den Props                       245    getestet
'************************ ende Basic-Befehle **********************************************************************


'************************ Befehle in der Testphase ****************************************************************
   tok33 byte "PUT", 0                                                                     '161
   tok126 byte"HELP",0                                                                     '254

'******************************************************************************************************************

'******************************* freie Befehle für Erweiterungen **************************************************
   tok41 byte "   ",0                                                                     '169
   tok42 byte "   ",0                                                                     '170
   tok43 byte "   ",0                                                                     '171
   tok44 byte "   ",0                                                                     '172
   tok45 byte "   ",0                                                                     '173
   tok46 byte "   ",0                                                                     '174
   tok72 byte "   ",0                                                                     '200
   tok73 byte "   ",0                                                                     '201
   tok75 byte "   ",0                                                                     '203
   tok94 byte "   ",0                                                                     '222
   tok95 byte "   ",0                                                                     '223
   tok107 byte"   ",0                                                                     '235

'        ---------------------------- Mehr Befehle sind nicht möglich --------------------------
'******************************************************************************************************************

   toks  word @tok0, @tok1, @tok2, @tok3, @tok4, @tok5, @tok6, @tok7
         word @tok8, @tok9, @tok10, @tok11, @tok12, @tok13, @tok14, @tok15
         word @tok16, @tok17, @tok18, @tok19, @tok20, @tok21, @tok22, @tok23
         word @tok24, @tok25, @tok26, @tok27, @tok28, @tok29, @tok30, @tok31
         word @tok32, @tok33, @tok34, @tok35, @tok36, @tok37, @tok38, @tok39
         word @tok40, @tok41, @tok42, @tok43, @tok44, @tok45, @tok46, @tok47
         word @tok48, @tok49, @tok50, @tok51, @tok52, @tok53, @tok54, @tok55
         word @tok56, @tok57, @tok58, @tok59, @tok60, @tok61, @tok62, @tok63
         word @tok64, @tok65, @tok66, @tok67, @tok68, @tok69, @tok70, @tok71
         word @tok72, @tok73, @tok74, @tok75, @tok76, @tok77, @tok78, @tok79
         word @tok80, @tok81, @tok82, @tok83, @tok84, @tok85, @tok86, @tok87
         word @tok88, @tok89, @tok90, @tok91, @tok92, @tok93, @tok94, @tok95
         word @tok96, @tok97, @tok98, @tok99, @tok100, @tok101, @tok102,@tok103
         word @tok104, @tok105, @tok106, @tok107, @tok108, @tok109, @tok110
         word @tok111, @tok112, @tok113, @tok114, @tok115, @tok116, @tok117
         word @tok118, @tok119, @tok120, @tok121, @tok122, @tok123, @tok124
         word @tok125, @tok126

   tokx  word

DAT
   '*****************  mathematische Funktionen ************************
   mtok1        byte "SIN",0      'Sinus #
   mtok2        byte "COS",0      'Cosinus #
   mtok3        byte "TAN",0      'Tangens #
   mtok4        byte "LN",0       'natürlicher logarythmus #
   mtok5        byte "E",0        'e-funkt #
   mtok6        byte "INT",0      'Integerwert von x
   mtok7        byte "LOG",0      'Logarythmus zur Basis 10 #
   mtok8        byte "ATAN",0     'Arcustangens #
   mtok9        byte "PREC",0     'Genauigkeit setzen (1-7)
   mtok10       byte "SGN",0      'Signum-Funktion (sgn(8)=1, sgn(0)=0,sgn(-8)=-1)

   '*********** Bit-Operationen ****************************************
   mtok11       byte "SHL",0      'Shift left
   mtok12       byte "SHR",0      'Shift right
   mtok13       byte "REV",0      'Revers
   mtok14       byte "ODER",0     'Bitwise OR
   mtok15       byte "XODER",0    'Bitwise XOR
   mtok16       byte "UND",0      'Bitwise And
   '*********** zusätzliche Funktionen *********************************
   mtok17       byte "ASIN",0     'arcus Sinus
   mtok18       byte "ACOS",0     'arcus Cosinus

   mtoks word @mtok1,@mtok2,@mtok3,@mtok4,@mtok5,@mtok6,@mtok7
         word @mtok8,@mtok9,@mtok10,@mtok11,@mtok12,@mtok13
         word @mtok14,@mtok15,@mtok16,@mtok17,@mtok18

DAT '*************** Sound-Funktionen **********************************

   stok0 byte "NT",0    'Note an/aus
   stok1 byte "VOL",0   'Lautstärke 0-15
   stok2 byte "ADSR",0  'Lautstärke-Hüllkurve
   stok3 byte "WAVE",0  'Wellenform
   stok4 byte "FLT",0   'Filtertyp
   stok5 byte "FMASK",0 'Filtermaske
   stok6 byte "RMOD",0  'Ringmodulator
   stok7 byte "CUTRES",0'Cutoff und Resonanz
   stok8 byte "PWM",0   'PWM-Wert
   stok9 byte "SYNC",0  'Oszillatorsynchronisation

   stoks word @stok0,@stok1,@stok2,@stok3,@stok4,@stok5,@stok6,@stok7,@stok8,@stok9


Dat

   'direkte mathematische Funktionen
   ' ^ - y^x  (entspricht y*y x-mal) #
   ' // - Modulo #
   ' ! - Absolutwert von x
   ' -   Negativwert von x
   ' + - * / Grundrechenarten
   ' √ - Wurzel   #
   ' π - Kreiszahl PI #

DAT
   ext5          byte "*.*",0                                                   'alle Dateien anzeigen
   tile          byte "Tile",0                                                  'tile-Verzeichnis
   help          byte "Help",0                                                  'Hilfeverzeichnis
   tmp           byte "BAS.TMP",0                                               'temporäre Sicherungsdatei
   adm           byte "adm.sys",0                                               'Administra-Treiber
   bel           byte "bel.sys",0                                               'Bella-Grafik-Treiber
   sysfont       byte "sysfontb.dat",0                                          'system-font
   errortxt      byte "errors.txt",0                                            'Error-Texte
   'helpfile      byte "help.sys",0                                              'Hilfesystem
   importfile    byte "import.sys",0
   exportfile    byte "export.sys",0

   windowtile byte 135,137,136,126,141,134,132,130,128,124,129,133,0,131,124,124,124                           'Fenster-Tiles für WIN-Funktion

con'****************************************** Hauptprogramm-Schleife *************************************************************************************************************
PUB main | sa

   init                                                                         'Startinitialisierung

   sa := 0                                                                      'startparameter
   curlineno := -1                                                              'startparameter

   repeat
      \doline(sa)                                                               'eine kommandozeile verarbeiten
      sa  := 0                                                                  'Zeile verwerfen da abgearbeitet

con'****************************************** Initialisierung *********************************************************************************************************************
PRI init |pmark,newmark,x,y,i

  ios.start

'*********************************** Abfrage welche Administra und Bellatrix- Codes geladen sind *************************************************************
          'Diese Funktionen sorgen dafür, das die Treiber nur geladen werden, wenn sie noch nicht vorhanden sind, also nicht bei jedem Start
  basicmarker:= get_dirmarker                                                   'usermarker von administra holen

  if ios.admgetspec<>ADM_SPEC
     ios.admload(@adm)                                                          'administra-code laden, springt nach dem booten ins Root (falls man aus einem Unterverzeichnis startet,

  activate_dirmarker(basicmarker)                                               'usermarker wieder in administra setzen
  usermarker:=basicmarker

  if ios.bel_get<>88                                                            'Grafiktreiber laden (neue Treiberversion)
     ios.belload(@bel)


'**************************************************************************************************************************************************************
  'Fl.start
  FS.SetPrecision(6)                                                            'Präzision der Fliesskomma-Arithmetik setzen

'*********************************** Timer-Cog starten ********************************************************************************************************
  TMRS.start(10)                                                              'Timer-Objekt starten mit 1ms-Aufloesung
'**************************************************************************************************************************************************************
'*********************************** Startparameter ***********************************************************************************************************
  pauseTime := 0                                                                'pause wert auf 0
  fileOpened := 0                                                               'keine datei geoeffnet
  volume:=15                                                                    'sid-cog auf volle lautstaerke
  speicheranfang:=$0                                                            'Programmspeicher beginnt ab adresse 0 im eRam
  speicherende:=$2                                                              'Programmende-marke
  mapram:=0                                                                     'Map-Schreibmarker auf 0
  farbe:=black                                                                  'Schreibfarbe
  hintergr:=white                                                               'Hintergrundfarbe
  cursorcolor:=grey                                                             'Farbe des Cursors
'***************************************************************************************************************************************************************

'******************* Speicher löschen oder wiederherstellen *****************
  pmark:=read_ram(PMARK_RAM)                                                    'Programmarker abfragen, wenn 161 dann reclaim ausführen um Programm im Speicher wieder herzustellen
                                                                                'zum Bsp nach aufruf der Hilfefunktion
  newmark:=read_ram(BMARK_RAM)                                                  'Marker steht auf 121, wenn Basic schonmal gestartet wurde
  write_ram(121,BMARK_RAM)                                                      'Marker setzen,das Basic gestartet wurde

  if pmark==161
     reclaim                                                                    'Programm im Speicher wieder hestellen
     write_ram(0,PMARK_RAM)                                                     'Reclaim-Marker löschen

  else
     ios.ram_fill(ERROR_RAM,$F00,0)                                                'Errortext-Speicher loeschen

     mount
     ios.sdopen("R",@errortxt)
     fileload(ERROR_RAM)                                                           'Error-Text einlesen
     if newmark<>121                                                               'Basic wurde noch nicht gestartet
        ios.ram_fill($0,userPtr,0)                                                 'Basic-Programmspeicher löschen
        ios.ram_fill(TMP_RAM,userPtr,0)                                            'Bearbeitungsspeicher loeschen
        clearall                                                                   'alle Variablen, Strings ,Window-Parameter,Mapdaten usw.löschen,Zeiger zurücksetzen
     else
        clearing                                                                   'nur Variablen,Strings,Mapdaten und Window-Parameter löschen
'************************** Startbildschirm ***********************************************************************************************************************************

  '*************** Bildschirmaufbau ***********************************

     ios.window(0,farbe,hintergr,cursorcolor,0,0,0,0,0,0,0,29,39,1,0)
     ios.printchar(12)                                                             'cls
     LoadTiletoRam(15,@sysfont,16,11)                                              'Logo und Font in eram laden

     loadtile(15)                                                                  'Logo und Font in den Puffer laden

 '*************** Logo anzeigen **************************************
     x:=y:=0
     repeat i from 144 to 151
          ios.displayTile(i,hintergr,farbe,cursorcolor,y,x)
          ios.displayTile(i+8,hintergr,farbe,cursorcolor,y+2,x)
          ios.displayTile(i+16,hintergr,farbe,cursorcolor,y+1,x)
          ios.displayTile(i+16+8,hintergr,farbe,cursorcolor,y+3,x)
          x++

     ios.setpos(y,13)
     errortext(40,0)                                                               'Versionsanzeige
     ios.setpos(y+2,10)

     ios.print(string("* "))
     ios.printdec(userptr-speicherende)                                            'freie bytes anzeigen usrptr-speicherende
     errortext(42,0)                                                               'Basic-Bytes Free

     ios.displaymouse(0,0)                                                         'Maus abschalten, falls an
  win:=0                                                                        'aktuelle fensternummer 0 ist das Hauptfenster
  cursor:=1                                                                     'cursormarker für Cursor on
  ios.printCursorRate(3)
  ios.printwindow(0)

'*******************************************************************************************************************************************************************************
  '******************************************************************************************************************************************************
  ios.sid_resetregisters                                                        'SID Reset
  ios.sid_beep(1)
   '************ startparameter fuer Dir-Befehl *********************************************************************************************************
  dzeilen:=9
  xz     :=2
  yz     :=4
  modus  :=2                                                                    'Modus1=compact, 2=lang 0=unsichtbar
   '*****************************************************************************************************************************************************
  ios.printnl
  serial:=0                                                                     'serielle Schnittstelle geschlossen

  '******************************************************************************************************************************************************
  ios.setactionkey(2,3,4,5,32)                                                  'Cursorsteuerung-Standardbelegung
  actionkey[0]:=2                                                               'links
  actionkey[1]:=3                                                               'rechts
  actionkey[2]:=4                                                               'hoch
  actionkey[3]:=5                                                               'runter
  actionkey[4]:=32                                                              'feuer
  ADDA:=$48                                                                     'Portadressen und AD-Adresse für Sepia-Karte vorbelegen
  PORT:=$20
  ios.set_plxAdr(ADDA,PORT)

  READ_PARAMETER                                                                'eventuelle Startparameter einlesen

obj '************************** Datei-Unterprogramme ******************************************************************************************************************************
con '------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PRI ifexist(dateiname)                                                          'abfrage,ob datei schon vorhanden, wenn ja Überschreiben-Sicherheitsabfrage
   ios.printnl
   mount

   if ios.sdopen("W",dateiname)==0                                              'existiert die dateischon?
      errortext(8,0)                                                            '"File exist! Overwrite? y/n"    'fragen, ob ueberschreiben
      if ios.keywait=="y"
         if ios.sddel(dateiname)                                                'wenn ja, alte Datei loeschen, bei nein ueberspringen
            close
            return 0
         ios.sdnewfile(dateiname)
         ios.sdopen("W",dateiname)
      else
          ios.printnl
          return 2                                                              'datei nicht ueberschreiben
   else                                                                         'wenn die Datei noch nicht existiert
      if ios.sdnewfile(dateiname)
         close
         return 0
      ios.sdopen("W",dateiname)
   ios.printnl
   return 1

PRI close
   ios.sdclose
   ios.sdunmount

PRI mount
     playerstatus
     ios.sdmount
     activate_dirmarker(usermarker)
     if strsize(@workdir)>1
        ios.sdchdir(@workdir)
        usermarker:=get_dirmarker

con '********************************** Speicher und Laderoutinen der Basic-Programme als Binaerdateien, ist erheblich schneller *************************
pri binsave|datadresse,count
   datadresse:= 0
   count:=speicherende-2
   ios.sdxputblk(datadresse,count)
   close

PRI binload(adr)|count
    count:=fileload(adr)
    writeendekennung (adr+count)
    RAM_CLEAR

PRI RAM_CLEAR
    ios.ram_fill(speicherende,$20000-speicherende,0)                            'Programmspeicher hinter dem Programm loeschen

con '********************************** Fehler-und System-Texte in den eRam laden ****************************************************************************************************************
PRI fileload(adr): cont
    cont:=ios.sdfattrib(0)                                                      'Anzahl der in der Datei existierenden Zeichen
    ios.sdxgetblk(adr,cont)
    close

PRI errortext(nummer,ton)|ad                                                    'Fehlertext anzeigen
    ad:=ERROR_RAM
    ram_txt(nummer,ad)
    if ton<2                                                                    'alle fehlertexte mit 0 und 1
       ios.print(@font)                                                         'fehlertext
    if ton==1                                                                   'mit system-beep bei Ton==0 wird nur der Text ausgegeben und kein Beep erzeugt (bei Systemtexten)
       sysbeep
       if curlineno>0                                                           'Ausgabe der Zeilennummer bei Programmmodus (im Kommandomodus wird keine Zeilennummer ausgegeben)
          errortext(10,0)
          ios.printdec(curlineno)
       ios.printnl
       Prg_End_Pos
       close
       abort
    clearstr                                                                    'Stringpuffer löschen


PRI sysbeep
    ios.sid_dmpstop
    'ios.sid_resetregisters
    ios.sid_beep(0)

PRI ram_txt(nummer,ad)|c,i
    i:=0
    repeat nummer
         repeat while (c:=read_ram(ad++))<>10
                if nummer==1 and c>13
                    byte[@font][i++]:=c
         nummer--
    byte[@font][i]:=0

con '********************************** Basic-Programm als TXT-Datei von SD-Card Importieren oder Exportieren ******************************************************************
pri import(mode)|i,adr
    adr:=ios#PARAM
    i:=0
    repeat strsize(@f0)
          ios.ram_wrbyte(f0[i++],adr++)
    ios.ram_wrbyte(0,adr++)

    if mode
       ios.ram_wrlong(speicherende-2,adr++)
    else
       ios.ram_wrlong(0,adr++)

    write_ram(161,PMARK_RAM)                                                    'Programmmarker wird bei rüeckkehr abgefragt und das Programm im Speicher wieder hergestellt
    mount
    activate_dirmarker(basicmarker)                                             'ins Basic Stammverzeichnis
    if mode
       ios.sdopen("r",@exportfile)
       ios.ldbin(@exportfile)
    else
       ios.sdopen("r",@importfile)
       ios.ldbin(@importfile)

    close

con '************************************* Basic beenden **************************************************************************************************************************
PRI ende
   errortext(9,0)
   ios.ram_wrbyte(0,SMARK_RAM)                                                  'Start-Parameter-Flag löschen
   TMRS.stop
   mount
   ios.stop

con'**************************************** Basic-Zeile aus dem Speicher lesen und zur Abarbeitung uebergeben ********************************************************************
PRI doline(s) | c,i,xm
   curlineno := -1                                                              'erste Zeile
   i:=0

   if ios.key == ios#CHAR_ESC                                                   'Wenn escape gedrueck dann?
        ios.printcursorrate(3)
        ios.Sprite_Move(2)                                                      'sprites anhalten
        playerstatus                                                            'stoppe Player falls er laeuft
        errortext(4,0)                                                          'Break in Line ausgeben
        sysbeep                                                                 'Systemsignal
        Prg_End_Pos                                                             'ans Programmende springen, um das Programm abzubrechen
        ios.printdec(xm)                                                        'Ausgabe der Zeilennummer bei der gestoppt wurde
        abort


   if nextlineloc < speicherende-2                                              'programm abarbeiten

      curlineno :=xm:=ios.ram_rdword(nextlineloc)                               'Zeilennummer holen

'**********************TRON-Funktion*************************************************
      if debug == 1                                                             'bei eingeschaltetem Debugmodus wird
         ios.printchar(60)                                                      'die aktuell bearbeitete Zeilennummer
         ios.printdec(curlineno)                                                'ausgegeben
         ios.printchar(62)
'*******************ende TRON-Funktion***********************************************

'*******************Zeile aus eram holen*********************************************
      nextlineloc+=2
               repeat while tline[i++]:=ios.ram_rdbyte(nextlineloc++)

      tline[i]:=0

      tp:= @tline

      texec                                                                     'befehl abarbeiten


   else
      pauseTime := 0                                                            'oder eingabezeile

      if s
         bytemove(tp:=@tline,s,strsize(s))                                      'Zeile s in tp verschieben
      else
         if nextlineloc == speicherende - 2 and returnmarker==0                 'nächste Zeile, wenn Programm zu ende und nicht Return gedrückt wurde (da bei Eingabezeile ebenfalls ein Zeilenvorschub erzeugt wird)
            ios.printnl
         returnmarker:=0
         ios.print(string("OK>"))                                               'Promt ausgeben
         getline(0)                                                             'Zeile lesen und
      c := spaces
      if c=>"1" and c =< "9"                                                    'ueberprüfung auf Zeilennummer
         insertline2                                                            'wenn programmzeile dann in den Speicher schreiben
         Prg_End_Pos                                                            'nächste freie position im speicher hinter der neuen Zeile
      else
         tokenize                                                               'keine Programm sondern eine Kommandozeile
         if spaces
            texec                                                               'dann sofort ausfuehren


con'************************************* Basic-Zeile uebernehmen und Statustasten abfragen ***************************************************************************************
PRI getline(laenge):e | i,f, c                                                  'zeile eingeben
   i := laenge
   f:=laenge
   e:=0
   repeat
'********************* Playerstatus abfragen, wenn er laeuft und am ende des Titels stoppen und SD-Card freigeben********************************
      if play:=1 and ios.sid_dmppos<20                                          'Player nach abgespielten Titel stoppen
         playerstatus
'************************************************************************************************************************************************
      c := ios.keywait
      case c
                       008:if i > 0                                             'bei backspace ein zeichen zurueck 'solange wie ein zeichen da ist
                              ios.printbs                                       'funktion ausfueren backspace
                              i--                                               'nochmal
                           laenge:=i                                            'laenge ist immer die aktuelle laenge der zeile
                       002:if i>0                                               'Pfeiltaste links
                              ios.printleft
                              i--
                       003:ios.printright                                       'Pfeiltaste rechts
                           i++
                       004:repeat while i<laenge                                'Cursor hoch-Taste ans ende der Basiczeile springen
                                ios.printright
                                i++
                       005:repeat i                                             'Cursor runter-Taste an den Anfang der Basic-Zeile springen
                                ios.printleft
                           i:=0
                       027:ios.printnl                                          'Abbruch
                           editmarker:=0
                           e:=1                                                 'Abbruchmarker
                           quit
                      ' 186:'Entf

'******************* Funktionstasten abfragen *************************
                       219:ende                                                 'taste F12 basic beenden
                       214:i := put_command(@tok92,0)                           'F7 edit
                       215:ios.print(string("TRON"))                            'F8 TRON
                           debug:=1
                           return
                       216:ios.print(string("TROFF"))                           'F9 TROFF
                           debug:=0
                           return
                       217:ios.print(string("RECLAIM"))                         'F10 Reclaim
                           reclaim
                           return

                       213:i := put_command(@tok9,1)                            'F6 list in doline
                           tline[i]:=0
                           tp:=@tline
                           return

                       212:i := put_command(@tok10,1)                           'F5 RUN
                           tline[i]:=0
                           tp := @tline
                           return
                       211:
                           h_dir(dzeilen,modus,@ext5)                           'taste F4 DIR aufrufen
                       210:i := put_command(@tok19,0)                           'save  F3
                       209:i := put_command(@tok20,0)                           'Load  F2
                       208:i := put_command(@tok126,0)                          'Help  F1                                                'Hilfe aufrufen
'**********************************************************************
                   fReturn:Returnmarker:=1                                      'wenn return gedrueckt
                           ios.printnl
                           tline[i] := 0
                           tp := @tline                                         'tp bzw tline ist die gerade eingegebene zeile
                           return
                   other:
                         if i < linelen-1
                            ios.printchar(c)
                            tline[i++] :=c
                            if i>laenge
                               laenge:=i                                        'laenge ist immer die aktuelle laenge der zeile


PRI put_command(stradr,mode)                                                    'Kommandostring nach tp senden
    result:=strsize(stradr)
    ios.print(stradr)
    if mode==1
       ios.printnl
    bytemove(@tline[0],stradr,result)

con '****************************** Basic-Token erzeugen **************************************************************************************************************************
PRI tokenize | tok, c, at, put, state, i, j, ntoks
   ntoks :=Get_toks                                                             'anzahl token
   at := tp
   put := tp
   state := 0
   repeat while c := byte[at]                                                   'solange Zeichen da sind schleife ausführen
      if c == quote                                                             'text in Anführungszeichen wird ignoriert
         if state == "Q"                                                        'zweites Anführungszeichen also weiter
            state := 0
         elseif state == 0
            state := "Q"                                                        'erstes Anführungszeichen

      if state == 0                                                             'keine Anführungszeichen mehr, also text untersuchen
         repeat i from 0 to ntoks-1                                             'alle Kommandos abklappern
            tok := @@toks[i] '@token'                                           'Kommandonamen einlesen
            j := 0
            repeat while byte[tok] and ((byte[tok] ^ byte[j+at]) & caseBit) == 0'zeichen werden in Grossbuchstaben konvertiert und verglichen solange 0 dann gleich
               j++
               tok++

            if byte[tok] == 0 and not isvar(byte[j+at])                         'Kommando keine Variable?
               byte[put++] := 128 + i                                           'dann wird der Token erzeugt
               at += j
               if i == 7                                                        'REM Befehl
                  state := "R"
               else
                  repeat while byte[at] == " "
                     at++
                  state := "F"
               quit
         if state == "F"
            state := 0
         else
            byte[put++] := byte[at++]
      else
         byte[put++] := byte[at++]
   byte[put] := 0                                                               'Zeile abschliessen


con '*********************************** Routinen zur Programmzeilenverwaltung im E-Ram********************************************************************************************
PRI writeendekennung(adr)
    ios.ram_wrword($FFFF,adr)                                                   'Programmendekennung schreiben
    speicherende:=adr+2                                                         'neues Speicherende

PRI Prg_End_Pos                                                                 'letztes Zeichen der letzten Zeile (Programmende)
    nextlineloc := speicherende - 2

PRI findline(lineno):at
   at := speicheranfang
   repeat while ios.ram_rdword(at) < lineno and at < speicherende-2             'Zeilennummer
          at:=ios.ram_keep(at+2)'+1                                                     'zur nächsten zeile springen

PRI eram_rw(beginn,adr)|temp,zaehler
'******************** Bereich nach der bearbeiteten Zeile in Bearbeitungsspeicher verschieben **************************
    temp:=TMP_RAM                                        'Anfang Bearbeitungsbereich
    zaehler:=speicherende-2-adr
    if adr<speicherende-2
       ios.ram_copy(adr,TMP_RAM,zaehler)
'******************** Bereich aus dem Bearbeitungsspeicher wieder in den Programmspeicher verschieben ******************
    if zaehler>0                                         'wenn nicht die letzte Zeile
       ios.ram_copy(TMP_RAM,beginn,zaehler)
    writeendekennung(beginn+zaehler)

PRI einfuegen(adr,diff,mode)|anfang
'*********************** aendern und einfuegen von Zeilen funktioniert*************************************************
    anfang:=adr

    if mode>0
       adr:=ios.ram_keep(adr+2)                          'eigentliche Zeile beginnt nach der Adresse
       '****** letzte Zeile? *************
       if ios.ram_rdword(adr)==$FFFF                     'Ueberpruefung, ob es die letzte Zeile ist
          if mode==2                                     'Zeile loeschen
             writeendekennung(anfang)                    'an alte Adresse Speicherendekennung schreiben
             return                                      'und raus
       '*********************************
    eram_rw(anfang+diff,adr)                             'schreibe geaenderten Bereich neu

PRI insertline2 | lineno, fc, loc, locat, newlen, neuesende
   lineno := parseliteral

   neuesende:=0                                                                 'Marker, das Programmende schon geschrieben wurde auf null setzen
   if lineno < 0 or lineno => 65535                                             'Ueberpruefung auf gueltige Zeilennummer
      close
      errortext(2,1)'@ln
   tokenize                                                                     'erstes Zeichen nach der Zeilennummer ist immer ein Token, diesen lesen
   fc := spaces                                                                 'Zeichen nach dem Token lesen

   loc := findline(lineno)                                                      'adresse der basic-zeile im eram, die gesucht wird
   locat := ios.ram_rdword(loc)                                                 'zeilennummer holen
   newlen := strsize(tp)+1                                                      'laenge neue zeile im speicher 1 fuer token + laenge des restes (alles was nach dem befehl steht)

   if locat == lineno                                                           'zeilennummer existiert schon

      if fc == 0                                                                'zeile loeschen
        einfuegen(loc,0,2)                                                      'Zeile hat null-laenge also loeschen
        neuesende:=1                                                            'Marker, das Programmende schon geschrieben wurde

      else                                                                      'zeile aendern
        einfuegen(loc,newlen+2,1)                                               'platz fuer geaenderte Zeile schaffen +2 fuer Zeilennummer wenn es nicht die letzte Zeile ist sonst muss die 2 weg
        neuesende:=1                                                            'Marker, das Programmende schon geschrieben wurde

   if fc                                                                        'zeilennummer existiert noch nicht
      if locat <65535 and locat > lineno                                        'Zeile einfuegen zwischen zwei Zeilen
         einfuegen(loc,newlen+2,0)                                              'Platz fuer neue Zeile schaffen
         neuesende:=1                                                           'Marker, das Programmende schon geschrieben wurde
      ios.ram_wrword(lineno,loc)                                                'Zeilennummer schreiben
      loc+=2

      repeat newlen
             write_ram(byte[tp++],loc++)                                        'neue Zeile schreiben entweder ans ende(neuesende=0) oder in die lücke (neuesende=1)

      if neuesende==0                                                           'Marker, das Programmende noch nicht geschrieben wurde (zBsp.letzte Zeile ist neu)
         writeendekennung(loc)                                                  'Programmendekennung schreiben

   RAM_CLEAR                                                                    'Programmspeicher hinter dem Programm loeschen


PRI writeram | lineno
   lineno := parseliteral
   if lineno < 0 or lineno => 65535
      close
      errortext(2,1)'@ln
   tokenize
   ios.ram_wrword(lineno,nextlineloc)                                           'zeilennummer schreiben
   nextlineloc+=2
   skipspaces                                                                   'leerzeichen nach der Zeilennummer ueberspringen
   repeat strsize(tp)+1
        write_ram(byte[tp++],nextlineloc++)                                     'Zeile in den Programmspeicher uebernehmen

   writeendekennung(nextlineloc)                                                'Programmende setzen

PRI reclaim |a,rc,f                                                             'Programm-Recovery-Funktion
    rc:=0                                                                       'adresszähler
    f:=0                                                                        'fehlermerker
       repeat
                  if rc>$1FFFF                                                  'nur den Programmspeicher durchsuchen
                     errortext(7,1)                                             'Fehler, wenn kein Programm da ist
       until (a:=ios.ram_rdlong(rc++))==$FFFF00                                 'Speicherendekennung suchen $FFFF0000
       speicherende:=rc+2                                                       'Speicherendezaehler neu setzen
       Prg_End_Pos

con '******************************** Variablenspeicher-Routinen ******************************************************************************************************************
PRI clearvars
   clearing
   nextlineloc := speicheranfang                                                'Programmadresse auf Anfang
   sp := 0
   clearstr                                                                     'Stringpuffer löschen


PRI clearing |i
   ios.ram_fill(DIR_RAM,$15BBF,0)'$EBBF,0)                                      'Variablen,Dir-Speicher,Map-Speicher-Shadow-Bildschirmspeicher bis $79C27  loeschen beginnend mit dem Dir-Speicher
   ios.ram_fill(STR_ARRAY,$6E800,0)                                             'Stringarray-Speicher loeschen
   ios.ram_fill(DIM_VAR,$1FF,0)                                                 'DIM-Speicher löschen
   repeat i from 0 to 25                                                        'DIM Speicher vorbelegen
       ios.ram_wrword(10,DIM_STR+(2*i*3))
       ios.ram_wrword(10,DIM_VAR+(2*i*3))

   pauseTime := 0
   gototemp:=gosubtemp  :=0                                                                'goto-Puffer loeschen
   gotobuffer:=gosubbuffer:=0
   restorepointer:=0                                                            'Restore-Zeiger löschen
   datapointer:=0                                                               'Data-Zeiger löschen
   ios.serclose                                                                 'serielle Schnittstelle schliessen
   serial:=0
   DATA_POKE(1,0)                                                               'erste Data-Zeile suchen, falls vorhanden
   if restorepointer                                                            'DATA-Zeilen vorhanden
      DATA_POKE(0,restorepointer)                                               'Datazeilen in den E-Ram schreiben

PRI newprog
   speicherende := speicheranfang + 2
   nextlineloc := speicheranfang
   writeendekennung(speicheranfang)
   sp := 0                                                                      'stack loeschen

PRI clearall
   newprog
   clearvars

PRI pushstack                                                                   'Gosub-Tiefe max. 20
   if sp => constant(maxstack-1)
      errortext(12,1)
   stack[sp++] := nextlineloc                                                   'Zeile merken

PRI varis(var_name,wert,rw,x,y,z)|adress,c                                      'Arrayverwaltung im eRam (Ram_Start_Adresse,Buchstabe, Wert, lesen oder schreiben,Arraytiefenwert 0-255)

    adress:=vari_adr(var_name,x,y,z)
    if rw==0
         c:=ios.ram_rdlong(adress)                                              'Array lesen
            return c
    else
         ios.ram_wrlong(wert,adress)                                            'Array schreiben

pri vari_adr(n,x,y,z):adress|ad                                                 'adresse der numerischen Variablen im Ram
     ad:=DIM_VAR+(2*n*3)
     adress:=scandimension(VAR_RAM,4,n,x,y,z,ios.ram_rdword(ad),ios.ram_rdword(ad+2),ios.ram_rdword(ad+4))

PRI klammers                                                                    'Arraydimensionen lesen (bis zu 3 Dimensionen)
wordfill(@var_arr,0,3)
if spaces=="("
       tp++
       var_arr[0]:=get_array_value
       var_arr[1]:=wennkomma
       var_arr[2]:=wennkomma
       klammerzu

PRI wennkomma:b
    if spaces==","
          tp++
          b:=get_array_value

PRI get_array_value|tok,c                                                       'Array-Koordinaten lesen und zurückgeben
   tok := spaces                                                                'Zeichen lesen
   tp++                                                                         'ein Zeichen weiter

   case tok

      "a".."z","A".."Z":                                                        'Wert von Variablen a-z
          c:=varis(fixvar(tok),0,0,0,0,0)                                       'pos,wert,r/w,x,y,z
          return fl.ftrunc(c)                                                   'und zurueckgeben
      "$","%","0".."9":                                                         'Zahlenwerte
          --tp
          return fl.ftrunc(getAnyNumber)

obj '******************************************STRINGS*****************************************************************************************************************************
con '************************************* Stringverarbeitung *********************************************************************************************************************
Pri Input_String
       tp--
       getstr
       bytemove(@f0,@font,strsize(@font))                                       'string nach f0 kopieren

PRI getarray :adresswert|a,b,c,d,ad                                             'Stringarray-Dimensionen lesen und Adresse im Ram berechnen
    a:=spaces
    tp++
    b:=0
    c:=0
    d:=0
    if spaces=="("
       tp++
       b:=expr(1)
       c:=wennkomma
       d:=wennkomma
       klammerzu

    if isvar(a)
       a:=fixvar(a)
          ad:=DIM_STR+(2*a*3)                                     'x-Dimension       y-Dimension             z-Dimension aus Dimensionsspeicher lesen
          adresswert:=scandimension(STR_ARRAY,STR_LEN,a,b,c,d,ios.ram_rdword(ad),ios.ram_rdword(ad+2),ios.ram_rdword(ad+4))
    else
       errortext(1,1)

PRI scandimension(startpos,laenge,varib,x,y,z,varx,vary,varz) : Position        'Überprüfung auf Dimensionswerte und Feldpositionsberechnung
    if x>varx or y>vary or z>varz
       errortext(16,1)
                  'Feldposition im Ram      y-Position        x-Position       z-Position
    Position:=startpos+(laenge*varib*FIELD_LEN)+(varx*y*laenge)+(x*laenge)+(varx*vary*laenge*z)

PRI clearstr
    bytefill(@font,0,STR_MAX)
    bytefill(@str0,0,STR_MAX)

'***********************************************************************************************************************************************************
PRI getstr:a|nt,b,str                                                           'string in Anführungszeichen oder Array-String einlesen
    a:=0
    skipspaces
    nt:=spaces
    bytefill(@font,0,STR_MAX)
    case nt
         quote:
              scanfilename(@font,0,quote)                                       'Zeichenkette in Anführungszeichen
         "#":                                                                   'String-Array
              skipspaces
              a:=getarray                                                       'Stringarray lesen
              stringlesen(a)
         176: skipspaces                                                        'Chr$-Funktion
              a:=klammer
              byte[@font][0]:=a
              byte[@font][1]:=0
         236: stringwiederholung                                                'String$-Funktion
         245: skipspaces
              Bus_Funktionen                                                    'Stringrückgabe von XBUS-Funktion
         163: skipspaces                                                        'STR$-Funktionen left,mid,right
              stringfunc2
     "a".."z","A".."Z":                                                         'konvertiert eine Variable a(0..255)-z(0..255) in einen String
              skipspaces
              klammers
              b:=varis(fixvar(nt),0,0,var_arr[0],var_arr[1],var_arr[2])         'Arrayvariable aus eRam holen
              str:=zahlenformat(b)

              bytemove(@font,str,strsize(str))


'***********************************************************************************************************************************************************
PRI stringfunc(pr) | a7,identifier                                              'stringfunktion auswaehlen
    identifier:=0

    if pr>0                                                                     'Stringzuweisung
       skipspaces
       a7:=getarray                                                             'String-Array, der mit der Funktion gefüllt werden soll
       if spaces=="="
          getstr                                                                'welche Funktion soll ausgeführt werden?
    else                                                                        'Stringausgabe mit Print
       tp--
       getstr                                                                   'welche Funktion soll ausgeführt werden?

   bytemove(@str0,@font,strsize(@font))
   identifier:=spaces                                                           'welche Funktion kommt jetzt?
   if identifier>0
      stringfunktionen(a7,identifier,pr)
   else                                                                         'keine Funktion dann
      stringschreiben(a7,0,@str0,pr,0)-1                                        'String schreiben

PRI stringfunktionen(a,identifier,pr)                                           'Strings addieren
     repeat while identifier
          if identifier==43
                '************* funktioniert ******************
                                                                                '+ Zeichen Strings addieren
                getstr
                bytemove(@str0[strsize(@str0)],@font,strsize(@font))            'verschiebe den String in den Schreibstring-Puffer
          else
             stringschreiben(a,0,@str0,pr,0)-1                                  'andere Zeichen als "+" zBsp Ausgabe des Strings mit PRINT string,string;variable
             return
          identifier:=spaces                                                    'weitere Zeichen? wenn ja dann von vorn
     stringschreiben(a,0,@str0,pr,0)-1                                          'keine Zeichen mehr String schreiben

PRI stringwiederholung|a,b                                                      'String$-Funktion
    skipspaces
    klammerauf
        a:=expr(1)                                                              'anzahl wiederholungen
        komma
        tp--
        getstr
    klammerzu
    bytefill(@strtmp,0,STR_MAX)                                                 'Stringpuffer löschen
    bytemove(@strtmp,@font,strsize(@font))                                      'String, der wiederholt werden soll merken
    bytefill(@font,0,STR_MAX)                                                   'Stringpuffer löschen
    b:=0
    repeat a
        if b>STR_MAX
           byte [@font][STR_MAX-1]:=0
           quit
        bytemove(@font[b],@strtmp,strsize(@strtmp))                             'Anzahl a Wiederholungen in Stringpuffer schreiben
        b:=strsize(@font)


PRI stringfunc2|a8,b8,c8,function,a,b                                           'die Stringfunktionen (left, right, mid)
    function:=spaces
    skipspaces
    klammerauf
          tp--
          getstr                                                                ' String holen
     case function
         "l","L","m","M","r","R":
                                a8:=strsize(@font)
                                komma
                                b8:=expr(1)                                     'anzahl zeichen fuer stringoperation
                                if function==77 or function==109                'midstr
                                   komma
                                   c8:=expr(1)
    klammerzu

   case function
        "l","L":a:=0
                b:=b8
        "m","M":a:=b8-1
                b:=c8
        "r","R":a:=a8-b8
                b:=b8
        "g","G":charactersUpperLower(@font,0)                               'in Grossbuchstaben umwandeln
                return
        "k","K":charactersUpperLower(@font,1)                               'in Kleinbuchstaben umwandeln
                return

        other:
             errortext(3,1)

   bytemove(@font,@font[a],b)
   byte[@font][b]:=0

PRI charactersUpperLower(characters,mode) '' 4 Stack Longs

'' ┌───────────────────────────────────────────────────────────────────────────┐
'' │ Wandelt die Buchstaben in Groß (mode=0) oder Klein(mode=1) um.            │
'' └───────────────────────────────────────────────────────────────────────────┘

  repeat strsize(characters--)

    result := byte[++characters]
    if mode
       if((result > 64) and (result < 91))    'nur A -Z in Kleinbuchstaben
          byte[characters] := (result + 32)
    else
       if(result > 96)                        'nur a-z in Großbuchstaben
          byte[characters] := (result - 32)


PRI stringlesen(num) | p,i
    i:=0
    repeat while p:=read_ram(num++)                                             'string aus eram lesen und in @font schreiben
          'if p==quote
          '   next
          byte[@font][i++]:=p
    byte[@font][i]:=0
    return num

PRI stringschreiben(adre,chr,strkette,pr,data) | c9,zaehler,laenge
    zaehler:=0
    if data==0                                                                  'keine Data-Zeile
       laenge:=STR_LEN-1
    else                                                                        'Data-Zeile
       laenge:=linelen
    case pr
         0:if chr>0
              ios.printchar(chr)
           else
              ios.print(strkette)

         1:if chr==0
              repeat strsize(strkette)
                    zaehler++
                    c9:= byte[strkette++]
                    if zaehler=<laenge-1
                       write_ram(c9,adre++)
                    else
                       quit
           else
              write_ram(chr,adre++)                                             'chr-Funktion
           write_ram(0,adre++)                                                  'null schreiben fuer ende string
         2:ios.sdputstr(strkette)                                               'auf SD-Card schreiben
    clearstr                                                                    'stringpuffer löschen
    return adre

PUB strpos (searchAddr,strAddr,offset)| searchsize                              'durchsucht strAddr nach auftreten von searchAddr und gibt die Position zurück
  searchsize := strsize(searchAddr)
  repeat until offset  > strsize(strAddr)
    if (strcomp(substr(strAddr, offset++, searchsize), searchAddr))             'if string search found
        return offset
  return 0
PUB substr (strAddr, start, count)                                              'gibt einen Teilstring zurück von start mit der Anzahl Zeichen count
  bytefill(@strtmp, 0, STR_MAX)
  bytemove(@strtmp, strAddr + start, count)                                     'just move the selected section
  return @strtmp
obj '*********************************************** TIMER-FUNKTIONEN ***********************************************************************************************************
con' *********************************************** Verwaltung der acht Timer und 4 Counter ************************************************************************************
PRI timerfunction:b|a,c,function
       function:=spaces
       skipspaces

       case function                                 'Timerfunktionen mit Werterueckgabe
               "c","C":'isclear?                     'Timer abgelaufen?
                       a:=klammer'expr
                       return TMRS.isclr(a-1)
               "r","R":'read                         'Timerstand abfragen
                          a:=klammer'expr
                          return TMRS.read(a-1)      'Timer 1-12 lesen

               "s","S":'timerset                     'Timer 1-12 setzen

                          klammerauf
                          a:=expr(1)
                          komma
                          c:=expr(1)
                          klammerzu
                          TMRS.set(a-1,c)

               other:
                       errortext(3,1)'@syn

con '********************************* Befehle, welche mit Printausgaben arbeiten *************************************************************************************************
PRI factor | tok, a,b,c,d,e,g,f,fnum                                            'Hier werden nur Befehle ohne Parameter behandelt
   tok := spaces
   e:=0
   tp++

   case tok
      "(":
         a := expr(0)
         if spaces <> ")"
            errortext(1,1)
         tp++
         return a

      "a".."z","A".."Z":
          klammers'factor
          wordmove(@var_tmp,@var_arr,3)
          c:=varis(fixvar(tok),0,0,var_tmp[0],var_tmp[1],var_tmp[2])            'pos,wert,r/w,x,y,z
          return c                                                              'und zurueckgeben

      152:'GFile                                                                'Ausgabe Anzahl, mit Dir-Filter gefundener Dateieintraege
          ifnot spaces
                return fl.ffloat(filenumber)

      160:'gdmp playerposition
           return fl.ffloat(ios.sid_dmppos)


      164:'COMP$
          klammerauf
          Input_String
          bytemove(@str0,@f0,strsize(@f0))                                      'in 2.Puffer merken
          komma
          Input_String
          c:=strcomp(@str0,@f0)                                                 'beide vergleichen -1=gleich 0=ungleich
          klammerzu
          return fl.ffloat(c)

      165:'LEN
          klammerauf
          Input_String
          a:=strsize(@f0)
          klammerzu
          return fl.ffloat(a)

      167:'Window
          return fl.ffloat(ios.get_window)

      177:'FREE
          return fl.ffloat(userptr-speicherende)

      182: ' FILE
           return fl.ffloat(ios.sdgetc)

      183:'JOY
          a:=klammer
          'if a<1 or a>2
          '   errortext(1,1)
          return fl.ffloat(ios.Joy(3+a))



      204:'gtime
          a:=klammer
          return fl.ffloat(lookup(a:ios.getHours,ios.getMinutes,ios.getSeconds))

      205:'gdate
          a:=klammer
          return fl.ffloat(lookup(a:ios.getDate,ios.getMonth,ios.getYear,ios.getday))

      207: 'Port
          return fl.ffloat(Port_Funktionen)

      211:'FUNC
           a:=spaces
           if isvar(a)
              a:=fixvar(a)                                                      'Funktionsvariable
              c:=FUNC_RAM+(a*56)                                                'Adresse der Funktion im E-Ram
              skipspaces
              klammerauf
              b:=expr(0)                                                        'Operandenwert der Operandenvariablen
              d:=ios.ram_rdlong(c)                                              'Adresse der Operandenvariablen aus Funktionsram lesen
              ios.ram_wrlong(b,d)                                               'Operandenwert an die Adresse der Operanden-Variablen schreiben
              g:=c
              repeat 3
                 g+=4
                 f:=ios.ram_rdlong(g)                                           'Adresse des nächsten Operanden
                 if spaces==","
                    skipspaces
                    e:=expr(0)                                                  'nächster Variablenwert
                    if f=>VAR_RAM                                               'Variable nicht null, also vorhanden
                       ios.ram_wrlong(e,f)                                      'Variablenwert schreiben, wenn vorhanden
                    else
                       errortext(25,1)                                          'Variable zuviel
                 elseif f=>VAR_RAM                                              'Variable vorhanden aber kein Komma
                       errortext(25,1)                                          'Fehlende Variable
                 else
                    quit
              klammerzu
              stringlesen(c+16)                                                 'Funktionszeile aus dem E-Ram lesen und nach @font schreiben
              tp := @font                                                       'Zeile nach tp übergeben
              d:=expr(0)                                                        'Funktion ausführen
              return d                                                          'berechneter Wert wird zurückgegeben
           else
              errortext(25,1)

      212:'inkey
           return fl.ffloat(ios.inkey)

      215:'PEEK
          a:=expr(1)                                                            'adresse
          komma
          b:=expr(1)                             '1-byte, 2-word, 4-long
          return fl.ffloat(lookup(b:read_ram(a),ios.ram_rdword(a),0,ios.ram_rdlong(a)))

      219:'Player
           c:=expr(1)
           if c==1
              a:=Kollisionserkennung
                 if a==0
                    a:=ios.get_collision
           else
              a:=Item_sammeln

           return fl.ffloat(a)

      221:'MGET
           b:=klammer
           return fl.ffloat(lookup(b:ios.mousex,ios.mousey,ios.mousez))

     ' 222: return fl.ffloat(LAN_Function)

      225:'MB
          a:=klammer
          b:=ios.mouse_button(a)
          if b>0 and b<BUTTON_CNT and a==0
             Buttonpress_on(b)                                                  'Buttonpress-Effekt
          return fl.ffloat(b)

      233:'asc
           klammerauf
           if raute
              a:=getarray
              return fl.ffloat(read_ram(a))
           elseif spaces==quote
                return skipspaces
           klammerzu

      234:'FN
           return mathfunction

      239:'timer
           return fl.ffloat(timerfunction)
      240:'GATTR
           a:=klammer
           return fl.ffloat(ios.sdfattrib(a))
      241:'VAL
           klammerauf
           Input_String
           fnum:=fs.StringToFloat(@f0)
           klammerzu
           return fnum
      243:'COM
          return Comfunktionen
      244:'INSTR
          klammerauf
          Input_String
          bytefill(@str0,0,STR_MAX)
          bytemove(@str0,@f0,strsize(@f0))                                      'in 2.Puffer merken
          komma
          Input_String
          c:=strpos(@str0,@f0,0)                                                'beide vergleichen -1=gleich 0=ungleich
          klammerzu
          return fl.ffloat(c)

      245:'Bus-Funktionen
          return Bus_Funktionen

      246:'GETX                                                                 'Cursorposition x lesen
          a:=klammer
          if a==1
             return fl.ffloat(ios.getx)
          elseif a==2
             return fl.ffloat(ios.get_actor_pos(1))                             'Playerposition
      247:'GEXTY                                                                'Cursorposition y lesen
          a:=klammer
          if a==1
             return fl.ffloat(ios.gety)
          elseif a==2
             return fl.ffloat(ios.get_actor_pos(2))                             'Playerposition
      253:'Ver
           return version

'****************************ende neue befehle********************************

      139: ' RND <factor>
           a:=klammer
           a*=1000
           b:=((rv? >>1)**(a<<1))
           b:=fl.ffloat(b)
           return fl.fmul(fl.fdiv(b,fl.ffloat(10000)),fl.ffloat(10))


      "-":
         return fl.FNeg(factor)                                                 'negativwert ->factor, nicht expr(0) verwenden

      "!":
         return fl.FAbs(factor)                                                 'Absolutwert ->factor, nicht expr(0) verwenden

      "√":
         klammerauf
         a:=expr(0)
         klammerzu
         return fl.fsqr(a)                                                      'Wurzel

      "π":'PI                                                                   'Kreiszahl Pi ausgeben
         return pi

      "$","%", quote,"0".."9":
         --tp
         return getAnyNumber


      other:
           errortext(1,1)

Con '******************************************* Operatoren *********************************************************************************************************************
PRI bitTerm | tok, t
   t := Factor

   repeat
      tok := spaces
      if tok == "^"                                                             'Power  y^x   y hoch x entspricht y*y (x-mal)
         tp++
         t := fl.pow(t,factor)
      else
         return t

PRI term | tok, t,a
   t := bitTerm
   repeat
      tok := spaces
     if tok == "*"
           tp++
           t := fl.FMUL(t,bitTerm)                                              'Multiplikation
     elseif tok == "/"
        if byte[++tp] == "/"
           tp++
           t := fl.FMOD(t,bitTerm)                                              'Modulo
        else
           a:=bitTerm
           if a<>0
              t  :=fl.FDIV(t,a)                                                 'Division
           else
              errortext(35,1)

     else
        return t

PRI arithExpr | tok, t
   t := term
   repeat
      tok := spaces
      if tok == "+"
         tp++
         t := fl.FADD(t,term)                                                   'Addition
      elseif tok == "-"
         tp++
         t := fl.FSUB(t,term)                                                   'Subtraktion
      else
         return t

PRI compare | op,a,c

   a := arithExpr
   op := 0
   spaces
   repeat
      c := byte[tp]
      case c
         "<": op |= 1
              tp++
         ">": op |= 2
              tp++
         "=": op |= 4
              tp++

         other: quit

   case op
      0: return a
      1: return a<arithExpr
      2: return a > arithExpr
      3: return a <> arithExpr
      4: return a == arithExpr
      5: return a =< arithExpr
      6: return a => arithExpr
      8: errortext(13,1)

PRI logicNot | tok
   tok := spaces
   if tok == 149 ' NOT
      tp++
      return not compare
   return compare

PRI logicAnd | t, tok
   t := logicNot
   repeat
      tok := spaces
      if tok == 150 ' AND
         tp++
         t := t and logicNot
      else
         return t

PRI expr(mode) | tok, t
   t := logicAnd
   repeat
      tok := spaces
      if tok == 151 ' OR
         tp++
         t := t or logicAnd
      else
         if mode==1                                                             'Mode1, wenn eine Integerzahl gebraucht wird
            t:=fl.FTrunc(t)
         return t

PRI SID_SOUND|i,err,a,b
    i:=0
    err:=1
    scanfilename(@sid_command,1,40)
    tp--
    klammerauf
    repeat 10
           if strcomp(@sid_command,@@stoks[i++])
              err:=0
              quit

    case i
          1:'NT
             param(1)
             a:=prm[0]
             b:=prm[1]
             if b
                ios.sid1_noteon(a,b)
             else
                ios.sid1_noteOff(a)

          2:a:=expr(1)
            a&=15
            volume:=a
            ios.sid1_setVolume(volume)



          3:'ADSR
             param(4)
             ios.sid1_setADSR(prm[0],prm[1],prm[2],prm[3],prm[4])
             'ios.sid_beep(1)

          4:'WAVE
             a:=expr(1)
             komma
             b:=expr(1)
             b+=3
             b:=1<<b'lookup(b:sid_triangle,sid_saw,sid_square,sid_noise)

             ios.sid1_setWaveform(a,b)

          5:'FILTER
             param(2)
             ios.sid1_setFilterType(prm[0],prm[1],prm[2])

          6:'FMASK
             param(2)
             ios.sid1_setFilterMask(prm[0],prm[1],prm[2])
          7:'RGMOD
             param(2)
             ios.sid1_enableRingmod(prm[0],prm[1],prm[2])
          8:'CUT
             a:=expr(1)
             komma
             b:=expr(1)
             ios.sid1_setCutoff(a)
             ios.sid1_setResonance(a)
          9:'PWM
             param(1)
             ios.sid1_setPWM(prm[0],prm[1])
          10:'SYNC
             param(2)
             ios.sid1_enableSynchronization(prm[0],prm[1],prm[2])


    if err
       ios.print(@sid_command)
       ios.printchar(63) '?
       errortext(25,1)
    klammerzu


PRI mathfunction |i,err                                                         'Liste der verfügbaren mathematischen Funktionen
    i:=0
    err:=1
    scanfilename(@math,1,40)
    tp--
    klammerauf
    repeat 18
           if strcomp(@math,@@mtoks[i++])
              err:=0
              quit

    case i
         1:result := fl.sin(expr(0))                                            'Sinus +
         2:result := fl.cos(expr(0))                                            'Cosinus +
         3:result := fl.tan(expr(0))                                            'Tangens +
         4:result := fl.log(expr(0))                                            'natürlicher Logarithmus +
         5:result := fl.exp(expr(0))                                            'e-funktion e(1)=2.718281 +
         6:result := fl.ffloat(fl.FTRUNC(expr(0)))                              'nächst kleinerer Integerwert von X +
         7:result := fl.Log10(expr(0))                                          'Logarithmus zur Basis 10 +
         8:result := fl.ATan(expr(0))                                           'Arc Tangens +
         9:num1:=expr(1)                                                        'Genauigkeit setzen +
            ifnot num1&7' num1<1 or num1>7
               errortext(25,1)
            FS.SetPrecision(num1)
         10:num1:=expr(0)                                                       'SGN-Funktion +
            if num1>0
               result:=1
            elseif num1==0
                   result:=0
            elseif num1<0
                   result:=-1
            result:=fl.ffloat(result)
         11:Get_term(1)                                                         'shift left +
            result:=fl.ffloat(num1<<num2)
         12:Get_term(1)                                                         'shift right +
            result:=fl.ffloat(num1>>num2)
         13:Get_Term(1)                                                         'reverse
            result:=fl.ffloat(num1><num2)
         14:Get_Term(1)                                                         'bitwise or
            result:=fl.ffloat(num1|num2)
         15:Get_Term(1)                                                         'bitwise xor
            result:=fl.ffloat(num1^num2)
         16:Get_Term(1)                                                         'bitwise and
            result:=fl.ffloat(num1&num2)
         17:result:=fl.asin(expr(0))                                            'arcus sinus +
         18:result:=fl.acos(expr(0))                                            'arcus cosinus +

    if err
       ios.print(@math)
       ios.printchar(63) '?
       errortext(25,1)
    klammerzu

PRI Get_term(wert)
       num1:=expr(wert)
       komma
       num2:=expr(wert)

con '*************************************** Dateinamen extrahieren **************************************************************************************************************
PRI scanFilename(f,mode,kennung):chars| c

   chars := 0
   if kennung==quote
      tp++                                                                      'überspringe erstes Anführungszeichen
   repeat while (c := byte[tp++]) <> kennung
      if chars++ < STR_MAX                                                      'Wert stringlänge ist wegen Stringfunktionen
         if mode==1                                                             'im Modus 1 werden die Buchstaben in Grossbuchstanben umgewandelt
            if c>96
               c^=32
         byte[f++] := c
   byte[f] := 0
con '*************************************** Programmlisting ausgeben **************************************************************************************************************

PRI listout|a,b,c,d,e,f,ntoks,rm,states,fr,qs,ds,rs
               b := 0                                                                                    'Default line range
               c := 65535                                                                                'begrenzt auf 65535 Zeilen
               f :=0                                                                                     'anzahl Zeilen
               qs:=ds:=0
               if spaces <> 0                                                                            'At least one parameter
                  b := c := expr(1)

                  if spaces == ","
                     skipspaces
                     c := expr(1)

               a := speicheranfang
               ntoks := Get_toks                                                                         'anzahl der Basicbefehle
               repeat while a < speicherende-2
                  d := ios.ram_rdword(a)                                                                 'zeilennummer aus eram holen
                  e:=a+2                                                                                 'nach der Zeilennummer adresse der zeile
                  if d => b and d =< c                                                                   'bereich von bis zeile
                     ios.printBoxColor(0,farbe,hintergr,cursorcolor)
                     ios.printdec(d)                                                                     'zeilennummer ausgeben
                     ios.printchar(" ")                                                                  'freizeichen
                     rs:=0
                     repeat while rm:=read_ram(e++)                                                      'gesuchte Zeilen ausgeben

                            if rm => 128
                               if (rm -= 128) < ntoks
                                  ios.printBoxColor(0,dark_green,hintergr,cursorcolor)
                                  ios.print(@@toks[rm])                                                  'token zurueckverwandeln
                                  ios.printchar(" ")

                            '****************************** Farbausgabe *********************************************************************
                                  case rm
                                       25,30,35,39,79,106,111,115: states:="F"                           'Befehlsoptionen haben die gleiche Farbe, wie der Grundbefehl
                                                                   ds:=rs:=0


                                       40                        :'DATA
                                                                   ds:=1
                                                                   fr:=dark_orange
                                       7                         : 'REM
                                                                   rs:=1
                                                                   fr:=Teal
                                       other                     : ds:=rs:=0
                                                                   states:=0
                            else
                               if ds<1 and rs<1
                                     case rm
                                          quote:                    if qs                                     'Texte in Anführungszeichen sind rot
                                                                       qs:=0
                                                                    else
                                                                       qs:=1
                                                                       fr:=red
                                          "#"  :                    fr:=red                                   'Strings sind rot
                                          "0".."9",".":             ifnot qs                                 'numerische Werte sind blau
                                                                          fr:=blue
                                                                          states:=0
                                          "$","%"         :         ifnot qs                                 'numerische Werte sind blau
                                                                          states:="N"
                                                                          fr:=blue
                                          44,58,59,"(",")","[","]": ifnot qs                                 'Befehlstrennzeichen (:) ist dunkelgrau
                                                                          fr:=light_blue
                                                                          states:=0
                                          "a".."z","A".."Z":                                                  'Variablen sind grau
                                                                    ifnot qs
                                                                          fr:=purple
                                                                          ifnot states=="F"
                                                                              if states=="N"
                                                                                 fr:=blue

                                                                              states:=0
                                                                          else                                'Befehlsoprionen sind gruen
                                                                              fr:=dark_green
                                          other            :        ifnot qs                                   'Operatoren sind pink
                                                                          fr:=dark_grey
                                                                          states:=0


                            '****************************** Farbausgabe *********************************************************************

                               ios.printBoxColor(0,fr,hintergr,cursorcolor)
                               ios.printchar(rm)                                                        'alle anderen Zeichen ausgeben

                     ios.printnl                                                                         'naechste Zeile
                     f++                                                                                 'Zeilenanzahl
                     if f==10                                                                            'nach 10 Zeilen Ausgabe pausieren
                        ios.printcursorrate(6)                                                           'Cursor blinkt schneller
                        if ios.keywait==27                                                               ' mit ESC raus
                           ios.printcursorrate(3)
                           quit
                        else
                           f:=0
                           ios.printcursorrate(3)

                  else
                     e:=ios.ram_keep(e)'+1                                                               'zur nächsten zeile springen

                  a := e                                                                                 'adresse der naechsten Zeile

               ios.printBoxColor(0,farbe,hintergr,cursorcolor)

con '************************************ einlesen der Arrays für INPUT und FREAD ************************************************************************************************
pri Get_Input_Read(anz):b |nt                                                   'Eingabe von gemischten Arrays für INPUT und FREAD

                b:=0
                nt:=spaces
                repeat
                  '***************** Zahlen ***************************************
                  if isvar(nt)
                     skipspaces
                     klammers
                     prm[b++]:=vari_adr(fixvar(nt),var_arr[0],var_arr[1],var_arr[2])
                     if spaces==","
                        nt:=skipspaces
                     else
                        quit
                     if anz==b
                        quit
                  '*************** Strings ****************************************
                  elseif nt=="#"
                     skipspaces
                     prm[b++]:=getarray
                     if spaces==","
                        nt:=skipspaces
                     else
                        quit
                  else
                     errortext(19,1)

con '***************************************** Befehlsabarbeitung ****************************************************************************************************************
PRI texec | ht, nt, restart,a,b,c,d,e,f,h,elsa


   bytefill(@f0,0,STR_MAX)
   restart := 1
   a:=0
   b:=0
   c:=0
   repeat while restart
      restart := 0
      ht := spaces
      if ht == 0
         return
      if ht=="#"
         stringfunc(1)
         return
      skipspaces
      if isvar(ht)                                                              'Variable? dann arrayfeld einlesen
         klammers
      wordmove(@var_temp,@var_arr,3)                                            'kopie des Arrayfeldes
      nt := spaces
      if isvar(ht) and nt == "="
         tp++
         varis(fixvar(ht),expr(0),1,var_temp[0],var_temp[1],var_temp[2])
      elseif ht => 128
         case ht
            128: 'IF THEN ELSE
               a := expr(0)
               elsa:=0                                                          'else-marker loeschen -> neue if then zeile
               if spaces <> 129
                  errortext(14,1)
               skipspaces
               if not a                                                         'Bedingung nicht erfuellt dann else marker setzen
                     elsa:=1
                     return
               restart := 1
            238:'ELSE
                if elsa==1
                   elsa:=0
                   restart := 1

            130: ' INPUT {"<prompt>";} <var> {, <var>}
                if is_string
                   input_string
                if spaces <> ";"
                   errortext(18,1)'@syn
                nt := skipspaces
                ios.print(@f0)
                b:=Get_Input_READ(9)
                if getline(0)==0 and strsize(@tline)>0                          'nur weitermachen, wenn nicht esc-gedrückt wurde und die Eingabezeile größer null war
                   FILL_ARRAY(b,0)                                              'Daten in die entsprechenden Arrays schreiben

            131: ' PRINT
               a := 0
               repeat
                  nt := spaces
                  if nt ==0 or nt==":"
                     quit
                  case nt
                      "#",163,176,236,245,quote:stringfunc(0)                   'Strings

                      184:skipspaces                                            'TAB
                          a:=klammer
                          ios.setx(a)
                      250,248:skipspaces
                              a:=klammer
                              d:=a
                              c:=1                                              'Hex-Ausgabe Standard 1 Stelle
                              e:=4                                              'Bin-Ausgabe Standard 4 Stellen
                              repeat while (b:=d/16)>0                          'Anzahl Stellen für Ausgabe berechnen
                                    c++
                                    e+=4
                                    d:=b
                              if nt==250
                                 ios.printhex(a,c)                              'Hex
                              if nt==248
                                 ios.printbin(a,e)                              'Bin
                      233:skipspaces                                            'ASC
                          klammerauf
                          if spaces==quote
                             skipspaces                                         'Anfuehrungszeichen ueberspringen
                             ios.printdec(spaces)                               'ASCII-Wert ausgeben
                             repeat while skipspaces<>quote                     'weiterspringen bis Anfuerungszeichen
                             skipspaces                                         'Anfuehrungszeichen ueberspringen
                          elseif raute
                             a:=getarray
                             ios.printdec(read_ram(a))
                          klammerzu
                      other:
                            ios.print(zahlenformat(expr(0)))

                  nt := spaces
                  case nt
                        ";": tp++
                        ",": a:=ios.getx
                             ios.setx(a+8)
                             tp++
                        ":",0:ios.printchar(fReturn)
                              quit
                        other:ios.printchar(nt)

            216: 'ON Gosub,Goto
                 ongosub:=0
                 ongosub:=expr(1)
                 if spaces < 132 or spaces >133                                 'kein goto oder gosub danach
                    errortext(1,1)
                 if not ongosub                                                 'on 0 gosub wird ignoriert (Nullwerte werden nicht verwendet)
                      return
                 restart := 1

            132, 133: ' GOTO, GOSUB
               e:=0
               a:=expr(1)
               if ongosub>0
                  e:=1
                  repeat while spaces=="," and e<ongosub
                         skipspaces
                         e++
                         a := expr(1)
               ongosub:=0
               if a < 0 or a => 65535
                  errortext(2,1)'@ln
               '*************** diese routine verhindert,das bei gleichen Schleifendurchlaeufen immer der gesammte Speicher nach der Zeilennummer durchsucht werden muss ******
               if gototemp<>a                                                   'sonst zeilennummer merken fuer naechsten durchlauf
                  gotobuffer:=findline(a)                                       'adresse merken fuer naechsten durchlauf
                  gototemp:=a
               if ht==133
                  pushstack
               nextlineloc := gotobuffer

               '***************************************************************************************************************************************************************

            134: ' RETURN
               if sp == 0
                  errortext(15,1)
               nextlineloc := stack[--sp]

            135,168: ' REM,DATA
                   repeat while skipspaces

            136: ' NEW
               ios.ram_fill(0,$20000,0)
               clearall

            137: ' LIST {<expr> {,<expr>}}
                 Listout

            138: ' RUN
                  clearvars                                                     'alle variablen loeschen
                  ios.clearkey                                                  'Tastaturpuffer löschen

            140: ' OPEN " <file> ", R/W/A
                Input_String
                if spaces <> ","
                   Errortext(20,1)'@syn
                d:=skipspaces
                tp++
                mount
                if ios.sdopen(d,@f0)
                   errortext(22,1)
                fileOpened := true

            141: 'FREAD <var> {, <var> }
                b:=Get_Input_Read(9)
                repeat                                                          'Zeile von SD-Karte in tline einlesen
                     c := ios.sdgetc
                     if c < 0
                        errortext(6,1)                                          'Dateifehler
                     elseif c == fReturn or c == ios.sdeof                      'Zeile oder Datei zu ende?
                        tline[a] := 0                                           'tline-String mit Nullbyte abschliessen
                        tp := @tline                                            'tline an tp übergeben
                        quit
                     elseif c == fLinefeed                                      'Linefeed ignorieren
                        next
                     elseif a < linelen-1                                       'Zeile kleiner als maximale Zeilenlänge?
                        tline[a++] := c                                         'Zeichen in tline schreiben
                Fill_Array(b,0)                                                 'Daten in die entsprechenden Arrays schreiben

            142: ' WRITE ...
               b:=0                                                             'Marker zur Zeichenketten-Unterscheidung (String, Zahl)
               repeat
                  nt := spaces                                                  'Zeichen lesen
                  if nt == 0 or nt == ":"                                       'raus, wenn kein Zeichen mehr da ist oder Doppelpunkt auftaucht
                     quit
                  if is_string                                                  'handelt es sich um einen String?
                     input_string                                               'String einlesen
                     b:=1                                                       'es ist ein String
                     stringschreiben(0,0,@font,2,0)                             'Strings schreiben
                  elseif b==0                                                   'kein String, dann eine Zahl
                     stringschreiben(0,0,zahlenformat(expr(0)),2,0)             'Zahlenwerte schreiben
                  nt := spaces
                  case nt
                       ";": tp++                                                'Semikolon bewirkt, das keine Leerzeichen zwischen den Werten geschrieben werden
                       ",":ios.sdputc(",")                                      'Komma schreiben
                           tp++
                       0,":":ios.sdputc(fReturn)                                'ende der Zeile wird mit Doppelpunkt oder kein weiteres Zeichen markiert
                             ios.sdputc(fLinefeed)
                             quit
                       other:errortext(1,1)

            143: ' CLOSE
               fileOpened := false
               close

            144: ' DELETE " <file>
               Input_String
               mount
               if ios.sddel(@f0)
                  errortext(23,1)
               close

            145: ' REN " <file> "," <file> "
               Input_String
               bytemove(@file1, @f0, strsize(@f0))                              'ergebnis vom ersten scanfilename in file1 merken
               komma                                                            'fehler wenn komma fehlt
               Input_String
               mount
               if ios.sdrename(@file1,@f0)                                      'rename durchfuehren
                   errortext(24,1)                                              'fehler wenn rename erfolglos
               close

            146: ' DIR
                if is_String
                   Input_String
                   komma
                   a:=expr(1)
                   h_dir(dzeilen,a,@f0)
                elseifnot spaces
                     h_dir(dzeilen,modus,@ext5)                           'directory ohne parameter nur anzeigen
                else
                     param(1)
                     dzeilen:=prm[0]
                     modus:=prm[1]
                     h_dir(dzeilen,modus,@ext5)


            147: ' SAVE or SAVE "<filename>"
               if is_String                                                     'Dateiname? dann normales Speichern
                  Input_String
                  a:=0
                  if spaces==","                                                'speichern ohne zurueckverwandelte token
                     komma
                     a:=expr(1)
                  d:=ifexist(@f0)
                  if d==1                                                       'datei speichern
                        'binsave
                        if a==4
                           import(1)
                        else
                           binsave
               ios.printnl
               close

            148: ' LOAD or LOAD "<filename>"
                mount
                if is_String
                  Input_String
                  a:=0
                  if spaces==","                                                'Autostartfunktion ? (Load"name.ext",1)
                     komma
                     a:=expr(1)
                  if ios.sdopen("R",@f0)                                        'Open requested file
                     errortext(22,1)

                  case a
                       0:newprog
                         binload(0)
                         Prg_End_Pos

                       1:newprog                                                  'BIN Datei mit Autostart
                         binload(0)
                         clearvars
                       2:                                                         'Append-Funktion
                         binload(speicherende-2)

                       3:   c:=nextlineloc                                        'Replace-Funktion
                            Prg_End_Pos
                            b:=klammer                                            'Zeilen an Zeilenposition schreiben
                            binload(findline(b))
                            nextlineloc := c                                      'Programmadresse zurückschreiben
                            restart:=1                                            'Programm fortsetzen
                       4:Import(0)

                close


            152:'Gfile mit Parameter
                a:=expr(1)
                if a>filenumber
                   errortext(3,1)
                getfilename(a)


            153:'MAP                                                            Map d=Map anzeigen, MAP w=Map in eram schreiben, Map s=Map auf sd-card schreiben, Map l=Map von sd-laden
                 Map_function

            154: ' FOR <var> = <expr> TO <expr> {STEP <expr>}                   For-Next Schleifen funktionieren nicht mit arrays als Operanden
               ht := spaces
               if ht == 0
                  errortext(27,1)
               skipspaces
               nt := spaces
               if not isvar(ht) or nt <> "="
                  errortext(19,1)
               a := fixvar(ht)
               skipspaces

               varis(a,expr(0),1,0,0,0)
               if spaces <> 155                                                 'TO Save FOR limit
                  errortext(28,1)
               skipspaces
               forLimit[a] := expr(0)
               if spaces == 156 ' STEP                                          'Save step size
                  skipspaces
                  forStep[a] := expr(0)
               else
                  forStep[a] := fl.ffloat(1)                                    'Default step is 1
               forLoop[a] := nextlineloc                                        'Save address of line
               c:=varis(a,0,0,0,0,0)
               if forStep[a] < 0                                                'following the FOR
                  b := c=>forLimit[a]
               else                                                             'Initially past the limit?
                  b := c=< forLimit[a]
               if not b                                                         'Search for matching NEXT
                  repeat while nextlineloc < speicherende-2
                     curlineno := ios.ram_rdword(nextlineloc)
                     tp := nextlineloc + 2
                     nextlineloc := tp + strsize(tp) + 1
                     if spaces == 157                                           'NEXT <var>
                        nt := skipspaces                                        'Variable has to agree
                        if not isvar(nt)
                           errortext(19,1)
                        if fixvar(nt) == a                                      'If match, continue after
                           quit                                                 'the matching NEXT
            157: ' NEXT <var>
               nt := spaces
               if not isvar(nt)
                  errortext(19,1)
               a := fixvar(nt)
               tp++
               c:=varis(a,0,0,0,0,0)
               h:=fl.fadd(c,forStep[a])                                         'Increment or decrement the
               varis(a,h,1,0,0,0)                                               'neuen wert fuer vars[a]
               if forStep[a] < 0                                                'FOR variable and check for
                  b := h=> forLimit[a]
               else                                                             'the limit value
                  b := h=< forLimit[a]
               if b                                                             'If continuing loop, go to
                  nextlineloc := forLoop[a]                                     'statement after FOR
               tp++


            158:'SID
                SID_SOUND

            159:'PLAY
                  if is_string
                     input_string
                     mount
                     if ios.sdopen("R",@f0)
                        errortext(22,1)
                     play:=1
                     ios.sid_sdmpplay(@f0)                                      'in stereo
                  elseif spaces == "0"
                         playerstatus'ios.sid_dmpstop
                         play:=0
                         close
                  elseif spaces == "1"
                         ios. sid_dmppause
            161:'PUT
                 param(2)
                 ios.put(prm[0],prm[1],prm[2])

            162:'tload
                a:=expr(1)
                a&=15
                komma
                if is_string                                                    'test auf String
                   Input_String
                komma
                param(1)
                b:=prm[0]
                c:=prm[1]
                if (b*c)>176
                   errortext(16,1)
                if a==15                                                        'Tileset 15 ist die Mauszeigerdatei
                   LoadTiletoRam(16,@f0,1,1)                                    'Mauszeigerdatei
                else
                   LoadTiletoRam(a,@f0,b,c)                                     'Tile-Datei in den Ram schreiben

            166:'READ (DATA)
                 if restorepointer
                    DATA_READ
                 else
                    errortext(5,1)

            167:'Window
                 Window_Function



            175:'RESTORE (DATA)
                ifnot spaces
                      DATA_POKE(1,0)                                            'erste Data-Zeile suchen, falls vorhanden
                      if restorepointer                                         'DATA-Zeilen vorhanden
                         DATA_POKE(0,restorepointer)                            'Datazeilen in den E-Ram schreiben
                         datapointer:=0
                      else
                         errortext(5,1)                                         'kein DATA, dann Fehler
                else
                   SET_RESTORE(expr(1))


            178:'STILE
                a:=expr(1)
                if a and a<16
                   loadtile(a)                                                  'tileset aus eram in bella laden
                else
                   errortext(16,1)

            179:'Tile
                param(5)                                                        'nr,farbe1,farbe2,farbe3,x,y
                                                                                'tileblock-nr aus aktuellem tileset anzeigen
                ios.displayTile(prm[0],prm[1],prm[2],prm[3],prm[5],prm[4])
                if mapram==1
                   tilecounter++
                   ios.ram_wrword(tilecounter,MAP_RAM)                          'tilecounter in ram schreiben
                   a:=MAP_RAM+8+((prm[4]*6)+(prm[5]*40*6))                      'berechnung der speicheradresse
                   repeat b from 0 to 5
                        write_ram(prm[b],a++)

            180: ' END
                Prg_End_Pos
                return

            181: ' PAUSE <expr> {,<expr>}
                  pauseTime := expr(1)
                  waitcnt((clkfreq /1000*pausetime) +cnt)

            182:
             ' FILE = <expr>
                if spaces <> "="
                   errortext(38,1)'@syn
                skipspaces
                if ios.sdputc(expr(1))
                   errortext(30,1)                                              'Dateifehler

            185:'MKFILE    Datei erzeugen
                Input_String
                mount
                if ios.sdnewfile(@f0)
                   Errortext(26,1)'@syn
                close

            186: ' DUMP <adr>,<zeilen> ,ram-typ
                param(2)
                ios.dump(prm[0],prm[1],prm[2])

'******************************** neue Befehle ****************************
            190:'pos <expr>,<expr> cursor an position x,y
                a:=expr(1)
                komma
                b:=expr(1)
                ios.setpos(b,a)

            193:'TIME
                a:=expr(1)      'x
                komma
                b:=expr(1)      'y
                ios.time(a,b)

            187:'Col <vordergr>,<hintergr>,<cursor>
                param(2)
                prm[0]&=255
                prm[1]&=255
                prm[2]&=255

                farbe:=prm[0]
                hintergr:=prm[1]
                cursorcolor:=prm[2]
                ios.printboxcolor(win,prm[0],prm[1],prm[2])


            188: 'CLS
                ios.printchar(12)

            189:'Renum
                ifnot spaces
                      renumber(0,speicherende-2,10,10)
                else
                      param(3)
                      renumber(prm[0],prm[1],prm[2],prm[3])                     'renumber(start,end,step)

            191:'Mouse
                param(1)
                prm[0]&=1
                prm[1]&=255
                ios.displaymouse(prm[0],prm[1])

            192:'Plot
                param(2) 'farbe,x,y
                ios.PlotPixel(prm[0],prm[1],prm[2])


            194:'scrdn
               param(6)
               ios.scrolldown(prm[0],prm[1],prm[3],prm[2],prm[5],prm[4],prm[6])

            195:'scrup                                                          scrollUp(lines, color, startRow, startColumn, endRow, endColumn,rate)
               param(6)   'farbe,x,y,xx,yy
               ios.scrollup(prm[0],prm[1],prm[3],prm[2],prm[5],prm[4],prm[6])

            196:'croff
               cursor:=0
               ios.printCursorRate(0)
            197:'cron
               cursor:=1
               ios.printCursorRate(3)

            198:'stime
               a:=expr(1)
               is_spaces(":",1)
               b:=expr(1)
               is_spaces(":",1)
               c:=expr(1)
                   ios.setHours(a)
                   ios.setMinutes(b)
                   ios.setSeconds(c)

            199:'sdate
                param(3)
                ios.setDate(prm[0])
                ios.setMonth(prm[1])
                ios.setYear(prm[2])
                ios.setDay(prm[3])



            202:'Button
                 Buttons

            206:'MKDIR
                input_string
                mount
                if ios.sdnewdir(@f0)
                   errortext(30,1)
                close

            207:'PORT
                Port_Funktionen

            208:'POKE                                                           Poke(adresse, wert, byte;word;long)
                param(2)
                if prm[2]==1
                   write_ram(prm[1],prm[0])
                elseif prm[2]==2
                   ios.ram_wrword(prm[1],prm[0])
                else
                   ios.ram_wrlong(prm[1],prm[0])

            209:'Circle
                 a:=expr(1) 'farbe
                 komma
                 b:=expr(0) 'x
                 komma
                 c:=expr(0) 'y
                 komma
                 d:=expr(0) 'radius
                 circle(b,c,d,a) 'x,y,r,farbe

            210:'Line
                param(4) 'farbe,x,y,xx,yy
                ios.Plot_Line(prm[1],prm[2],prm[3],prm[4],prm[0])               'x,y,xx,yy,farbe

            211:'FUNC
                nt:=spaces
                f:=0
                e:=0
                if isvar(nt)
                   a:=fixvar(nt)                                                'Funktionsvariablen-name (a..z)
                   skipspaces
                else
                   errortext(25,1)                                              'Fehler, wenn was Anderes als a..z
                klammerauf
                f:=get_input_read(4)                                            'max.4 Variablen
                klammerzu
                is_spaces(61,25)   '=
                is_spaces(91,25)   '[
                scanfilename(@f0,0,93)                                          'Formelstring extrahieren
                d:=FUNC_RAM+(a*56)                                              'Adresse der Function im Ram
                ios.ram_wrlong(prm[0],d)                                        'Variablenadresse in Funktionsram schreiben
                h:=1
                e:=d
                repeat 3
                  e+=4
                  if f>1
                     ios.ram_wrlong(prm[h++],e)                                 'Operandenadressen in den Funktionsram schreiben, wenn vorhanden
                     f--
                  else
                     ios.ram_wrlong(0,e)                                        'nicht benutzte Operanden mit 0 beschreiben

                stringschreiben(d+16,0,@f0,1,0)                                 'Formel in den Funktionsram schreiben

            213:'clear
                clearing

            214:'bye
                ende                                                            'T-Basic beenden

            217:'BEEP
                ifnot spaces                                                    'keine parameter
                   ios.sid_beep(0)
                else
                   a:=expr(1)                                                   'Tonhoehe
                   ios.sid_beep(a)

            218:'BLOAD
                 Input_String
                 mount
                 if ios.sdopen("R",@f0)
                    errortext(22,1)
                 ios.ldbin(@f0)

            219: 'PLAYER
                 Playersettings

            220:'EDIT                                                           'Zeilen editieren bis ESC gedrückt wird
                 editmarker:=1
                 a:=Editline(expr(1))
                 repeat while editmarker
                        a:=Editline(a)
                 return
           ' 222:'LAN
           '      Lan_Function

            224:'MBound
                param(3)
                ios.mousebound(prm[0],prm[1],prm[2],prm[3])

            226:'frame
                param(6)
                ios.display3DFrame(prm[0], prm[1], prm[2], prm[4], prm[3], prm[6], prm[5])

            227:'WSET
                a:=expr(1)
                a&=7
                ios.printwindow(a)
                win:=a

            228:'TPIC                                                           'komplettes Tileset anzeigen
                param(4)                                                        'farbe1,farbe2,farbe3,x,y
                ios.displaypic(prm[0],prm[1],prm[2],prm[4],prm[3],ytiles[aktuellestileset],xtiles[aktuellestileset])

            229:'SCROLL
                Input_String
                komma
                param(5)                                                        'scrollrate,textfarbe,hintergrundfarbe,x,y,xx
                ios.scrollString(@f0,prm[0], prm[1], prm[2], prm[4], prm[3], prm[5])

            230:'CHDIR
                Input_String
                bytefill(@workdir,0,12)
                bytemove(@workdir,@f0,strsize(@f0))
                mount
                close

            231:'box
                param(5)                                                        'farbe,x,y,xx,yy,Schatten ja/nein
                ios.display2dbox(prm[0],prm[2],prm[1],prm[4],prm[3],prm[5])     'farbe,y,x,yy,xx

            232:'Font
                Input_String
                komma
                param(4)                                                        '1.farbe,2.farbe,3.farbe,x,y
                printfont(@f0,prm[0],prm[1],prm[2],prm[3],prm[4])               'Text mit aktuellen Font darstellen

            234:'FN                                                             um ein Setzen der Präzision ohne Werterückgabe zu ermöglichen
                mathfunction

            239:'timer
                timerfunction

            237:'Dim
                repeat
                   b:=0
                   if raute                                                     'String-Felddimensionierung
                      b:=2
                   elseif isvar(spaces)                                         'Zahlen-Felddimensionierung
                      b:=1
                   else
                      errortext(18,1)
                   a:=fixvar(spaces)
                   skipspaces
                   klammers                                                     'Klammerwerte lesen
                   Felddimensionierung(a,b,var_arr[0],var_arr[1],var_arr[2])    'a-x b-y c-z d-variable e-String oder Zahl}
                   if spaces==","
                      skipspaces
                   else
                      quit


            242:'PLAYXY  Spielerfigur bewegen
                a:=expr(1)
                playerposition(a)

            243:'COM
                Comfunktionen

            245:'XBUS-Funktionen
                 BUS_Funktionen

            249:'Sprite-Settings
                 spritesettings

            251:'Backup                                                         Bildschirmbereich sichern
                 param(4)
                 ios.Backup_Area(prm[0],prm[1],prm[2],prm[3],prm[4])            'Backup_Area(x,y,xx,yy,adr)

            252:'Recover                                                        Bildschirmbereich zurückschreiben
                 param(4)
                 ios.Restore_Area(prm[0],prm[1],prm[2],prm[3],prm[4])           'Restore_Area(x,y,xx,yy,adr)

            254:'HELP
                 ifnot spaces
                       Show_help(0)
                 else
                     show_help(1)


'****************************ende neue befehle********************************

      else
          errortext(1,1)'@syn

      if spaces == ":"                                                          'existiert in der selben zeile noch ein befehl, dann von vorn
         restart := 1
         tp++
con'******************************************* Online-Hilfe ****************************************************************************************************************
pri Show_help(len)|a,i
    if len
       a:=spaces                                                                'Anfangsbuchstabe lesen

    if len==0
       repeat i from 65 to 90                                                   'Alle verfügbaren Befehle anzeigen
            if i==82
               ios.keywait                                                      'auf Tastendruck warten
            Put_Help_words(i)
    if a=<122
       Put_Help_words(a)
    if a=>128
       a-=128
       mount
       sdset(@help)                                                             'ins help verzeichnis wechseln
       ios.sdopen("R",@@toks[a])                                                'gesuchte Hilfedatei öffnen
       ios.printBoxColor(0,blue,hintergr,cursorcolor)                           'Hilfetext in anderer Farbe darstellen
       read_txtfile                                                             'Hilfedatei ausgeben
       ios.printBoxColor(0,farbe,hintergr,cursorcolor)                          'Farben zurücksetzen
       activate_dirmarker(basicmarker)                                          'zurück ins Basicverzeichnis
       close
    ios.printnl

pri put_help_words(st)|c,ntok,i,z                                'zeigt alle mit dem, als Suchbegriff eingegebenen Buchstaben vorhandenen Befehle an
    ntok:=Get_toks
    if st>96
       st-=32
    repeat i from 0 to ntok
           bytemove(@tline,@@toks[i],strsize(@@toks[i]))
           c:=tline[0]
           if c==st
              ios.print(@@toks[i])
              ios.print(string("  "))
              if ios.getx>33
                 ios.printnl


pri read_txtfile|c
      repeat
          c:=ios.sdgetc
          if c==10                                            'return oder linefeed nicht als zeichen anzeigen
             next
          ios.printchar(c)                                    'text anzeigen
      until ios.sdeof                                         'ausgabe bis eof
ios.sdclose

pri sdset(str)                                         'Verzeichniswechsel
    ios.sdchdir(str)
    ios.sddmset(str)
con'******************************************* DATA-Funktion ********************************************************************************************************************
PRI DATA_READ|anz                                                               'READ-Anweisungen interpretieren, Data-Werte lesen und an die angegebenen Variablen verteilen
    anz:=0
    anz:=Get_input_read(9)                                                      'Array Adressen berechnen
    FILL_ARRAY(anz,1)                                                           'Arrays mit Daten füllen

pri data_write(adr,art)|adresse,a,c,i,f                                         'schreibt die Data-Anweisungen in die entsprechenden Variablen
    adresse:=DATA_RAM+datapointer
    a:=DATA_LESEN(adresse)
    datapointer:=a-DATA_RAM
    i:=0
    f:=strsize(@font)
    if f<1
       errortext(21,1) 'Out of Data Error
    if art==0
       repeat f                                                                 'String aus Data-Puffer lesen
              c:=byte[@font][i++]
              write_ram(c,adr++)                                                'und nach String-Array schreiben
       write_ram(0,adr++)                                                       'Null-string-Abschluss
    else
       c:=fs.StringToFloat(@font)                                               'String-Zahl in Float-Zahl umwandeln und im Array speichern
       ios.ram_wrlong(c,adr)

PRI DATA_LESEN(num) | p,i                                                       'Data-Wert im Eram lesen
    i:=0
    repeat
          p:=read_ram(num++)                                                    'string aus eram lesen und in @font schreiben egal, ob Zahl oder Zeichenkette
          if p==44 or p==0                                                      'komma oder null
             quit                                                               'dann raus
          byte[@font][i++]:=p
    byte[@font][i]:=0                                                           'String mit Nullbyte abschliessen
    return num                                                                  'Endadresse zurückgeben

PRI SET_RESTORE(lnr)|a                                                          'DATA-Zeiger setzen
    a:=findline(lnr)
    if read_ram(a+2)==168                                                       'erste Data-Anweisung gefunden?
       restorepointer:=a                                                        'Restorepointer setzen
       data_poke(0,restorepointer)                                              'Data-Zeilen in den Data-Speicher schreiben
       datapointer:=0                                                           'Data-Pointer zurücksetzen
    else
       errortext(5,1)

PRI DATA_POKE(mode,pointer)|a,adr,b,c,d,merker                                  'DATA-Zeilen in den Ram schreiben
    a := pointer                                                                'entweder 0 oder Restore-Zeiger
    adr:=DATA_RAM
    repeat while a < speicherende-2
                 d := ios.ram_rdword(a)                                         'zeilennummer aus eram holen
                 a+=2                                                           'nach der Zeilennummer kommt der Befehl
                 c:= read_ram(a)                                                '1.Befehl in der Zeile muss DATA heissen
                 if c==168                                                      'Befehl heisst DATA
                    if merker==1
                       write_ram(44,b-1)                                        'komma setzen nach für nächste Data-Anweisung
                    if mode==1                                                  'Adresse der ersten Data-Zeile
                       restorepointer:=a-2
                       quit
                    merker:=1                                                   'erste DATA-Anweisung schreiben, ab jetzt wird nach jeder weiteren Anweisung ein Komma gesetzt
                    a+=1
                    a:=stringlesen(a)                                           'DATA-Zeile Lesen
                    b:=stringschreiben(adr,0,@font,1,1)                         'DATA-Zeile in den RAM schreiben
                    adr:=b
                 else
                    a:=ios.ram_keep(a)'+1                                         'zur nächsten zeile springen
    ios.ram_wrlong(0,adr)                                                       'abschließende nullen für Ende Databereich

Pri FILL_ARRAY(b,mode)|a,f

    repeat a from 1 to b                                                        'Arraywerte schreiben
          if prm[a-1]>$6AFFF and prm[a-1]<$7FFFF                                'Adresse im Array-Bereich?, dann Zahlenvariable
             if mode
                data_write(prm[a-1],1)
             else
                f:=getanynumber
                ios.ram_wrlong(f,prm[a-1])                                      'zahl im Array speichern
          elseif prm[a-1]>$7FFFF                                                'String
             if mode
                data_write(prm[a-1],0)
             else
                scanFilename(@f0,0,44)                                          'Zeilen-Teil bis Komma abtrennen
                stringschreiben(prm[a-1],0,@f0,1,0)                             'String im Stringarray speichern
          if a<b and mode==0                                                    'weiter, bis kein Komma mehr da ist, aber nicht bei DATA(da werden die Daten ohne Komma ausgelesen, kann also nicht abgefragt werden)
             if spaces==","
                skipspaces
             else
                quit

con'***************************************************** Fensterfunktionen *****************************************************************************************************
PRI Window_Function|w,wnr

    w:=spaces
    skipspaces
    klammerauf
    wnr:=expr(1)
    ifnot wnr&7
       errortext(16,1)'falscher Parameter
    case w
              "c","C":'Create
                      komma
                      param(8) '0-vordergrundfarbe,1-hintergrundfarbe,2-cursorfarbe,3-x,4-y,5-xx,6-yy,7=Art,8=Schatten 0-nein 1-ja
                      komma
                      Input_String
                      prm[8]&=1     'nur 1 und Null gültig
                      ios.window(wnr,prm[0],prm[1],prm[2],prm[2],prm[2],prm[0],prm[2],prm[0],prm[4], prm[3], prm[6], prm[5],prm[7],prm[8])
                      ios.Set_Titel_Status(wnr,1,@f0)
                      win:=wnr                                                  'das aktuelle Fenster
              "t","T":'Titel
                      komma
                      Input_String
                      ios.Set_Titel_Status(wnr,1,@f0)

              "s","S":'Statustext
                      komma
                      Input_String
                      ios.Set_Titel_Status(wnr,2,@f0)
              "r","R":'Reset
                      ios.windel(wnr)
                      win:=0
              other:
                    errortext(1,1)

    klammerzu
con'***************************************************** LAN-Funktionen *********************************************************************************************************
{PRI LAN_Function|a
    a:=spaces
                   case a
                      "c","C":'Connect
                      "l","L":'Listen
                      "w","W":'Wait
                      "r","R":'Read
                      "t","T":'Transmit
                      "g","G":'is_connect?
                      "s","S":'eingabe IP-Adresse in der Form  xxx.xxx.xxx.xxx:xxxx und Start der Verbindung

                      other:
                            errortext(1,1)
                            }
con'***************************************************** MAP-Funktionen *********************************************************************************************************
PRI Map_Function|a
    a:=spaces
                   case a
                      "d","D":
                            mapram:=0                                           'schreibmarker ausschalten
                            tilecounter:=ios.ram_rdword(MAP_RAM)
                            if tilecounter>0
                               DisplayMap                                       'Map anzeigen
                            return
                      "w","W":
                             mapram:=1                                          'schreibmarker fuer ram jeder Tilebefehl wird jetzt zusaetzlich in den Ram geschrieben
                             tilecounter:=0
                             write_ram(farbe,MAP_RAM+2)                         'Header mit farbwerten fuellen
                             write_ram(hintergr,MAP_RAM+3)
                             write_ram(cursorcolor,MAP_RAM+4)
                             write_ram(0,MAP_RAM+5)
                             write_ram(0,MAP_RAM+6)
                             write_ram(0,MAP_RAM+7)                             'Rest des Headers mit nullen fuellen


                      "l","L":                                                  'map von sd-card in eram laden
                             skipspaces
                             Input_String
                             Lmap(@f0)

                      "s","S":                                                  'map aus eram auf sd-card speichern
                             skipspaces
                             Input_String
                             Smap(@f0)

                      "c","C":                                                  'Map-Ram_Shadow-BS-Speicher löschen
                              ios.ram_fill(MAP_RAM,$1C27,0)
                      other:
                            errortext(1,1)

con'***************************************************** XBUS-Funktionen *******************************************************************************************************
PRI BUS_Funktionen |pr,a,b,c,h,r,str,s

    pr:=0                                                                       'pr gibt zurück, ob es sich beim Rückgabewert um einen String oder eine Variable handelt, für die Printausgabe
    klammerauf
    a:=expr(1)                                                                  'Chipnummer (1-Administra,2-Bella,3-Venatrix)
    komma
    r:=expr(1)                                                                  'wird ein Rückgabewert erwartet? 0=nein 1=char 4=long 3=string
    s:=0
                 repeat
                      komma
                      if is_string
                         Input_String
                         s:=1
                      else
                           b:=expr(1)                                           'Kommando bzw Wert
                           if b>255
                              case a
                                   1:ios.bus_putlong1(b)
                                   2:ios.bus_putlong2(b)
                                   3:ios.bus_putlong3(b)
                           else
                              case a
                                   1:ios.bus_putchar1(b)
                                   2:ios.bus_putchar2(b)
                                   3:ios.bus_putchar3(b)

                      if s==1
                         lookup(a:ios.bus_putstr1(@f0),ios.bus_putstr2(@f0),ios.bus_putstr3(@f0))
                         s:=0

                      if spaces==")"
                         quit

                 skipspaces

                 case r
                     0:pr:=0
                       return
                     1:c:=lookup(a:ios.bus_getchar1,ios.bus_getchar2,ios.bus_getchar3)
                     4:c:=lookup(a:ios.bus_getlong1,ios.bus_getlong2,ios.bus_getlong3)
                     3:if a==1
                          str:=ios.bus_getstr1
                       if a==3
                          str:=ios.bus_getstr3
                       bytemove(@font,str,strsize(str))
                       pr:=1
    if r==1 or r==4
       h:=fl.ffloat(c)
       str:=fs.floattostring(h)                                                 'Stringumwandlung für die Printausgabe
       bytemove(@font,str,strsize(str))
       return h


con'******************************************** Port-Funktionen der Sepia-Karte *************************************************************************************************
PRI PORT_Funktionen|function,a,b,c
    function:=spaces
    skipspaces
    klammerauf
    a:=expr(1)                                                                  'Adresse bzw.ADDA Adresse
        case function
            "O","o":komma
                    b:=expr(1)                                                  'Byte-Wert, der gesetzt werden soll
                    klammerzu
                    if a<4 or a>6                                               'nur Digital-Port-Register können für die Ausgabe gesetzt werden
                       errortext(3,1)
                    c:=a-4                                                      'Portadresse generieren
                    a:=c+PORT                                                   'Port 4=Adresse+0 Port5=Adresse+1 usw. da nur Register 4-6 Ausgaberegister sind
                    ios.plxOut(a,b)                                             'wenn a=4 dann 28+4=32 entspricht Adresse$20 von Digital-Port1

            "I","i":'Port I                                                     'Byte von Port a lesen
                    klammerzu
                    return ios.getreg(a)                                        'Registerwert auslesen 0-6

            "S","s":'Port Set                                                   '*Adressen zuweisen
                     komma
                     b:=expr(1)                                                 '*Port-Adresse zuweisen
                     ADDA:=a
                     PORT:=b
                     klammerzu
                     ios.set_plxAdr(ADDA,PORT)

            "P","p":'Port-Ping                                                  'Port-Adresse anpingen
                     klammerzu
                     ios.plxHalt
                     b:=ios.plxping(a)
                     ios.plxrun
                     return b

            other:
                   errortext(3,1)
con'********************************************* serielle Schnittstellen-Funktionen *********************************************************************************************
PRI Comfunktionen|function,a,b
    function:=spaces
    skipspaces
        case function
            "S","s":klammerauf
                    a:=expr(1)                                                  'serielle Schnittstelle öffnen/schliessen
                    if a==1
                       komma                                                    'wenn öffnen, dann Baudrate angeben
                       b:=expr(1)
                       ios.seropen(b)
                       serial:=1
                    elseif a==0                                                 'Schnittstelle schliessen
                       ios.serclose
                       serial:=0
                    else
                       errortext(16,1)
                    klammerzu
            "G","g":'COM G                                                      'Byte von ser.Schnittstelle lesen ohne warten
                    return fl.ffloat(ios.serread)
            "R","r":'COM R                                                      'Byte von ser.Schnittstelle lesen mit warten
                    return fl.ffloat(ios.serget)
            other:
                   errortext(3,1)
con '******************************************* Parameter des Player's und der Sprites *******************************************************************************************
PRI playersettings|f,i,e
    f:=spaces
    skipspaces
    klammerauf
    case f
        "P","p":param(5)                                                        'Spielerparameter
                ios.Actorset(prm[0],prm[1],prm[2],prm[3],prm[4],prm[5])         'Actorset(tnr1,col1,col2,col3,x,y)

        "K","k":param(4)                                                        'Spielertasten belegen
                ios.setactionkey(prm[0],prm[1],prm[2],prm[3],prm[4])            'links,rechts,hoch,runter,feuer
                repeat i from 0 to 4
                       actionkey[i]:=prm[i] 'links
        "B","b":param(9)                                                        'Blockadetiles einlesen (tnr1,....tnr10)
                repeat i from 0 to 9
                     block[i]:=prm[i]
                     ios.send_block(i,prm[i])
        "I","i":param(5)                                                        'Item-Tiles einlesen (tnr1,...tnr6)
                repeat i from 0 to 5
                     item[i]:=prm[i]
        "C","c":param(5)                                                        'Kollisions-Tiles  (tnr1,...tnr6)
                repeat i from 0 to 5
                     collision[i]:=prm[i]
        "E","e":param(4)                                                        'Ersatz-Item-Tiles (nr1-6,tnr,f1,f2,f3)
                e:=(prm[0]-1)*5
                f:=0
                repeat i from e to e+4
                     itemersatz[i]:=prm[f++]
        other:
               errortext(1,1)
    klammerzu


PRI playerposition(a)|b,c,d,i,bl                                                'Hier wird die Playerbewegung auf Blockadetiles überprüft
                bl:=0
                get_position
                b:=actorpos[0]
                c:=actorpos[1]
                if a==actionkey[0]
                   d:=read_ram(MAP_RAM+8+((b-1)*6)+(c*40*6))
                elseif a==actionkey[1]
                   d:=read_ram(MAP_RAM+8+((b+1)*6)+(c*40*6))
                elseif a==actionkey[2]
                   d:=read_ram(MAP_RAM+8+((b*6)+((c-1)*40*6)))
                elseif a==actionkey[3]
                   d:=read_ram(MAP_RAM+8+((b*6)+((c+1)*40*6)))
                elseif a==actionkey[4]
                    'Unterroutine Feuertaste, noch nicht vorhanden
                repeat i from 0 to 9
                   if block[i]==d
                      bl:=1
                if bl==0
                   ios.setactor_xy(a)

PRI Kollisionserkennung:a|d,i
    a:=0
    d:=get_position

    repeat i from 0 to 5
       if collision[i]==d
             a:=2                                                               'Kollision des Spielers mit Kollisionstiles
             quit

PRI get_position:d

    actorpos[0]:=ios.get_actor_pos(1) 'x-pos
    actorpos[1]:=ios.get_actor_pos(2) 'y-pos
    d:=read_ram(MAP_RAM+8+((actorpos[0]*6)+(actorpos[1]*40*6)))                 'Tile an aktueller Position im Map-Speicher lesen

PRI Item_sammeln:a|d,i,e,f
    a:=0
    d:=get_position                                                             'item auf dem der Player gerade steht
    repeat i from 0 to 5
       if item[i]==d
             a:=1+i                                                             'Item-Nr zurückgeben
             e:=MAP_RAM+8+((actorpos[0]*6)+(actorpos[1]*40*6))
             f:=i*5
             write_ram(itemersatz[f+1],e)'gesammeltes Item wird durch Ersatzitem im ERam ersetzt (um Doppeleinsammlung zu verhindern)
             ios.Change_Backuptile(itemersatz[f+1],itemersatz[f+2],itemersatz[f+3],itemersatz[f+4]) 'ersatzitem wird in Backuppuffer des Players geschrieben (ersetzt)
                                                                                                    'damit stimmt jetzt auch die Farbe des Ersatzitems
             quit
PRI spritesettings|f
    f:=spaces
    skipspaces
    klammerauf
    case f
        "S","s":ios.set_sprite_speed(expr(1))                                   'Speed
        "M","m":ios.Sprite_Move(expr(1))                                        'move an aus reset
        "P","p":param(10)                                                       'Spriteparameter
                if prm[0]>8
                   errortext(16,1)
                ios.set_sprite(prm[0],prm[1],prm[2],prm[3],prm[4],prm[5],prm[6],prm[7],prm[8],prm[9],prm[10]) 'Nr,Tnr,Tnr2,f1,f2,f3,dir,strt,end,x,y)
        other:
              errortext(1,1)
    klammerzu

con'*************************************************************** Array-Dimensionierung ****************************************************************************************
PRI Felddimensionierung(variabl,var_str,x_koord,y_koord,z_koord)|grenze,ort

    grenze:=(z_koord+1)*(y_koord+1)*(x_koord+1)
    if grenze>FIELD_LEN
       errortext(18,1)                                                          'Dimensionen dürfen die Grenze von 512 nicht durchbrechen

    if var_str==1                                                               'Zahlenfelddimensionen speichern
       ort:=DIM_VAR+(2*variabl*3)
    else                                                                        'String-Felddimensionen speichern
       ort:=DIM_STR+(2*variabl*3)

    ios.ram_wrword(x_koord+1,ort)
    ios.ram_wrword(y_koord+1,ort+2)
    ios.ram_wrword(z_koord+1,ort+4)

con'*************************************************************** Zeilen-Editor**************************************************************************************************
PRI editline(Zeilennummer):nex|a,ntoks,c,d,f,rm,i,x,y,bn,temp
if Zeilennummer<65535
               x:=0
               y:=0
               temp:=zeilennummer
               bytefill(@tline,0,85)
               a := speicheranfang
               ntoks := Get_toks'(@tokx - @toks) / 2                            'anzahl der Basicbefehle
               bn:=0
               a:=findline(zeilennummer)                                        'Adresse der Zeilennummer feststellen
               d := ios.ram_rdword(a)                                           'Zeilennummer aus dem eram holen
               a+=2
               i := 1_000_000_000
                        repeat 10                                               'zahl zerlegen
                          if d => i
                             tline[x++] := d / i + 48
                             d //= i
                             bn~~
                          elseif bn or i == 1
                                 tline[x++] :=48
                          i /= 10
                        tline[x++] :=32                                         'freizeichen
                        repeat while rm:=read_ram(a++)                          'gesuchte Zeile in tline schreiben
                            if rm => 128
                               if (rm -= 128) < ntoks
                                  f:=strsize(@@toks[rm])
                                  bytemove(@tline[x],@@toks[rm],f)
                                  x+=f
                                  tline[x++]:=32                                'Leerzeichen nach dem Token
                                  y:=0                                          'Tok-Bytezaehler auf null setzen für nächsten Befehl
                            else
                                tline[x++]:=rm                                  'alle anderen Zeichen ausgeben
                        nex:=ios.ram_rdword(a)                                  'Adresse der nächsten Zeile

     ios.print(@tline)                                                          'Zeile auf dem Bildschirm ausgeben

     ifnot getline(strsize(@tline))                                             'wenn die Editierung nicht mit ESC abgebrochen wurde
           tp:=@tline                                                           'tp ist die eigentliche Basic-Arbeitszeile
           c := spaces
           if c=>"1" and c =< "9"                                               'Überprüfung auf gültige Zeilennummer
              insertline2                                                       'wenn programmzeile dann in den Speicher schreiben
              Prg_End_Pos                                                       'neues Speicherende
else
   editmarker:=0

con'********************************************  Renumberfunktion *****************************************************************************************************************
pub renumber(st,ed,nb,stp)|i                                                  'renumber(start,end,neustart,step)
    i:=findline(st)
    if ed<speicherende-2
       ed:=findline(ed)

    repeat while i=<ed
           if nb<65535
              ios.ram_wrword(nb,i)                                              'neue Zeilennummer schreiben
              i+=2
              nb+=stp                                                           'Zeilennummerierung mit Schrittweite addieren
              i:=ios.ram_keep(i)'+1                                                     'zur nächsten zeile springen
           else
              errortext(2,1)                                                    'Abbruch, wenn Zeilennummer >65534

con '******************************************* diverse Unterprogramme ***********************************************************************************************************
pri Get_toks                                                                    'Tokenanzahl ermitteln
    result:=(@tokx - @toks) / 2

PRI spaces | c
   'einzelnes zeichen lesen
   repeat
      c := byte[tp]
      if c==21 or c==17                                                         'Wurzelzeichen und Pi-Zeichen
         return c
      if c == 0 or c > " "
         return c
      tp++

PRI skipspaces
   if byte[tp]
      tp++
   return spaces

PRI parseliteral | r, c                                                         'extrahiere Zahlen aus der Basiczeile
   r := 0
   repeat
      c := byte[tp]
      if c < "0" or c > "9"
         return r
      r := r * 10 + c - "0"
      tp++

PRI fixvar(c)                                                                   'wandelt variablennamen in Zahl um (z.Bsp. a -> 0)
   if c => "a"
      c -= 32
   return c - "A"

PRI isvar(c)                                                                    'Ueberpruefung ob Variable im gueltigen Bereich
   c := fixvar(c)
   return c => 0 and c < 26

PRI circle(x,y,r,frbe)|i,xp,yp,a,b,c,d
    d:=630 '(2*pi*100)
    repeat i from 0 to d step 3
          c:=fl.fdiv(fl.ffloat(i),fl.ffloat(100))
          a:=fl.fadd(x,fl.fmul(fl.cos(c),r))
          b:=fl.fadd(y,fl.fmul(fl.sin(c),r))
          xp:=fl.FRound(a)
          yp:=fl.FRound(b)
          ios.PlotPixel(frbe,xp,yp)

PRI playerstatus
       ios.sid_dmpstop
       ios.sid_resetregisters
       play:=0
       close

PRI param(anzahl)|i
    i:=0
    repeat anzahl
        prm[i++]:=expr(1)                                                       'parameter mit kommatrennung
        komma
    prm[i++]:=expr(1)                                                           'letzter Parameter ohne skipspaces

pri is_string                                                                   'auf String überprüfen
    result:=0
    if spaces==quote or spaces=="#" or spaces==176 or spaces==236 or spaces==163
       result:=1

PRI komma
    is_spaces(",",1)

PRI is_spaces(zeichen,t)
    if spaces <> zeichen
       errortext(t,1)'@syn
    else
       skipspaces

PRI raute
    if spaces=="#"
       skipspaces
       return 1

PRI klammer:b
         if spaces=="("
            skipspaces
            b:=expr(1)
            if spaces<>")"
               errortext(1,1)                                                   '@syn
            skipspaces

PRI klammerauf
    is_spaces(40,1)

PRI klammerzu
    is_spaces(41,1)

PRI getAnyNumber | c, t,i,punktmerker,d,zahl[STR_MAX]

   case c := byte[tp]
      quote:
         if result := byte[++tp]
            if byte[++tp] == quote
              tp++
            else
               errortext(1,1)                                                   '("missing closing quote")
         else
            errortext(31,1)                                                     '("end of line in string")

      "$":
         c := byte[++tp]
         if (t := hexDigit(c)) < 0
            errortext(32,1)                                                     '("invalid hex character")
         result := t
         c := byte[++tp]
         repeat until (t := hexDigit(c)) < 0
            result := result << 4 | t
            c := byte[++tp]
         result:=fl.FFLOAT(result)

      "%":
         c := byte[++tp]
         if not (c == "0" or c == "1")
            errortext(33,1)                                                     '("invalid binary character")
         result := c - "0"
         c := byte[++tp]
         repeat while c == "0" or c == "1"
            result := result << 1 | (c - "0")
            c := byte[++tp]
         result:=fl.FFLOAT(result)

      "0".."9":
          i:=0
          punktmerker:=0
          c:=byte[tp++]
          repeat while c=="." or c=="e" or c=="E" or (c => "0" and c =< "9")    'Zahlen mit oder ohne punkt und Exponent
                 if c==point
                    punktmerker++
                 if punktmerker>1                                               'mehr als ein punkt
                    errortext(1,1)                                              'Syntaxfehler ausgeben
                 if c=="e" or c=="E"
                    d:=byte[tp++]
                    if d=="+" or d=="-"
                       byte[@zahl][i++]:=c
                       byte[@zahl][i++]:=d
                       c:=byte[tp++]
                       next
                 byte[@zahl][i++]:=c
                 c:=byte[tp++]
          byte[@zahl][i]:=0
          result:=fs.StringToFloat(@zahl)
          --tp

      other:
           errortext(34,1)                                                      '("invalid literal value")

PRI hexDigit(c)
'' Convert hexadecimal character to the corresponding value or -1 if invalid.
   if c => "0" and c =< "9"
      return c - "0"
   if c => "A" and c =< "F"
      return c - "A" + 10
   if c => "a" and c =< "f"
      return c - "a" + 10
   return -1

pri zahlenformat(h)|j
    j:=fl.ftrunc(h)
       if (j>MAX_EXP) or (j<MIN_EXP)                                            'Zahlen >999999 oder <-999999  werden in Exponenschreibweise dargestellt
           return FS.FloatToScientific(h)                                       'Zahlenwerte mit Exponent
       else
           return FS.FloatToString(h)                                           'Zahlenwerte ohne Exponent

con '****************************************** Directory-Anzeige-Funktion *******************************************************************************************************
PRI h_dir(z,modes,str) | stradr,n,i,tt,dlen,dd,mm,jj,color,xstart,dr                 'hive: verzeichnis anzeigen
{{h_dir - anzeige verzeichnis}}                                                 'mode 0=keine Anzeige,mode 1=einfache Anzeige, mode 2=erweiterte Anzeige
  ios.printcursorrate(0)                                                        'cursor ausschalten
  mount

  xstart:=ios.getx                                                              'Initial-X-Wert
  if strsize(str)<3
     str:=@ext5                                                                 'wenn kein string uebergeben wird, alle Dateien anzeigen
  else
     repeat 3                                                                   'alle Zeichen von STR in Großbuchstaben umwandeln
        if byte[str][i]>96
           byte[str][i]^=32
        i++

  ios.sddir                                                                     'kommando: verzeichnis öffnen
  n := 0                                                                        'dateizaehler
  i := 0                                                                        'zeilenzaehler
 repeat  while (stradr:=ios.sdnext)<>0                                          'wiederholen solange stradr <> 0


    dlen:=ios.sdfattrib(0)                                                      'dateigroesse
    dd:=ios.sdfattrib(10)                                                       'Aenderungsdatum tag
    mm:=ios.sdfattrib(11)                                                       'Aenderungsdatum monat
    jj:=ios.sdfattrib(12)                                                       'Aenderungsdatum Jahr
    dr:=ios.sdfattrib(19)                                                       'Verzeichnis?

      scanstr(stradr,1)                                                         'dateierweiterung extrahieren

      ifnot ios.sdfattrib(17)                                                   'unsichtbare Dateien ausblenden
        if strcomp(@buff,str) or strcomp(str,@ext5)                             'Filter anwenden
             n++

          '################## Bildschrirmausgabe ##################################
           if modes>0                                                           'wenn Verzeichnis,dann andere Farbe
               if dr
                  ios.printBoxColor(0,farbe+32,hintergr,cursorcolor)
               ios.print(stradr)

               if modes==2
                  erweitert(xstart,dlen,dd,mm,jj)
               ios.printnl
               ios.setx(xstart)
               i++
               ios.printBoxColor(0,farbe,hintergr,cursorcolor)                  'wieder Standardfarben setzen
               if i==z                                                             '**********************************
                  if ios.keywait == ios#CHAR_ESC                                   'auf Taste warten, wenn ESC dann Ausstieg
                     if cursor==1                                                  '**********************************
                        ios.printCursorRate(3)                                     '**********************************
                     close                                                         '**********************************
                     filenumber:=n                                                 'Anzal der Dateien merken
                     abort                                                        '**********************************

                 i := 0                                                           '**********************************
                 ios.setx(xstart)
           if modes==0
              if n<DIR_ENTRY                                                     'Begrenzung der Einträge auf die mit DIR_ENTRY vereinbarte
                 WriteNameToRam(stradr,n)                                        'Dateiname zur spaeteren Verwendung in ERam speichern an adresse n


 if modes                                                                       'sichtbare Ausgabe
    ios.printdec(n)                                                             'Anzahl Dateien
    errortext(43,0)
    ios.printnl
 if cursor==1
    ios.printCursorRate(3)
 filenumber:=n                                                                 'Anzal der Dateien merken
 close                                                                         'ins Root Verzeichnis ,SD-Card schliessen und unmounten
 abort
PRI WriteNameToRam(str,nummer)|adress,position,c                                'Dateiliste in ERam schreiben
    position:=(nummer-1)*13
    adress:=DIR_RAM+position
    repeat strsize(str)
            c:=byte[str++]
            write_ram(c,adress++)

PRI getfilename(nummer)|adress,position,c,num                                   'mit GFile ausgewaehlte Datei in Stringvariable Z schreiben
    position:=(nummer-1)*13
    adress:=DIR_RAM+position                                                    'Adresse Dateiname im eRam
    num:= scandimension(STR_ARRAY,STR_LEN,25,0,0,0,0,0,0)                       'adresse("#Z")
    repeat 12
            c:=read_ram(adress++)                                               'Dateiname aus Dir-Ram lesen
            write_ram(c,num++)                                                  'und in Variablenspeicher an adresse Z schreiben
    write_ram(0,num++)                                                          'null fuer stringende schreiben

PRI erweitert(startx,laenge,tag,monat,jahr)                               'erweiterte Dateianzeige

         ios.setx(startx+14)
         ios.printdec(laenge)
         ios.setx(startx+21)
         ios.printdec(tag)
         ios.setx(startx+24)
         ios.printdec(monat)
         ios.setx(startx+27)
         ios.printdec(jahr)

PRI scanstr(f,mode) | z ,c                                                      'Dateiendung extrahieren
   if mode==1
      repeat while strsize(f)
             if c:=byte[f++] == point                                           'bis punkt springen
                quit
   z:=0
   repeat 3                                                                     'dateiendung lesen
        c:=byte[f++]
        buff[z++] := c
   buff[z++] := 0
   return @buff

PRI activate_dirmarker(mark)                                                    'USER-Marker setzen

     ios.sddmput(ios#DM_USER,mark)                                              'usermarker wieder in administra setzen
     ios.sddmact(ios#DM_USER)                                                   'u-marker aktivieren

PRI get_dirmarker:dm                                                            'USER-Marker lesen

    ios.sddmset(ios#DM_USER)
    dm:=ios.sddmget(ios#DM_USER)

con '********************************* Unterprogramme zur Tile-Verwaltung *********************************************************************************************************
PRI Win_Set_Tiles|i,a                                                           'Tiles, aus denen die Fenster bestehen, in den Ram schreiben
    i:=WTILE_RAM
    a:=0
    repeat 18
           write_ram(windowtile[a++],i++)                                       'Standard-Wintiles in den Ram schreiben
    ios.windel(9)                                                               'alle Fensterparameter löschen und Win Tiles senden

PRI LoadTiletoRam(tilenr,datei,xtile,ytile)|adress ,count                       'tile:=tilenr,dateiname,xtile-zahl,ytilezahl

    xtiles[tilenr]:=xtile                                                       'xtiles fuer tilenr        '
    ytiles[tilenr]:=ytile                                                       'ytiles fuer tilenr
    count:=xtile*ytile*64                                                       'anzahl zu ladender Bytes (16*11*16*4=11264)
    if tilenr<16
       adress:=TILE_RAM+((tilenr-1)*$2C00)                                      'naechster Tilebereich immer 2816 longs (11264 Bytes) 14 Tilesets moeglich Tileset15 ist der Systemfont
    else
       adress:=MOUSE_RAM                                                        'Mouse-Pointer
       count:=64
    mount
    activate_dirmarker(basicmarker)                                             'ins Basic Stammverzeichnis
    ios.sdchdir(@tile)                                                          'ins tile verzeichnis wechseln
    if ios.sdopen("R",datei)                                                    'datei öffnen
       errortext(22,1)
       return
    ios.sdxgetblk(adress,count)                                                 'datei in den Speicher schreiben  (der blockbefehl ist viel schneller als der char-Befehl)
    close
    '####Mouse-Pointer############
    if tilenr==16
       ios.Mousepointer(MOUSE_RAM)                                              'neuen Mauszeiger übernehmen

PRI loadtile(tileset)|anzahl,adress                                             'tileset aus eram in bella laden
    if tileset==15                                                              'bei Systemfont, Fenstertiles wieder herstellen
       Win_Set_Tiles

    adress:=TILE_RAM+((tileset-1)*$2C00)                                        'naechster Tilebereich immer 2816 longs (11264 Bytes) 14 Tilesets moeglich

    anzahl:=ytiles[tileset]*xtiles[tileset]*16                                  'anzahl tilebloecke
    ios.loadtilebuffer(adress,anzahl)                                           'laden
    aktuellestileset:=tileset                                                   'zum aktuellen Tileset machen

PRI printfont(str,a,b,c,d,e)|f,x,adr
    ios.printfont(win,str,a,b,c,e,d,0)
    if mapram==1
       repeat strsize(str)
         f:= byte[str++]
            x:=d*6
            adr:=MAP_RAM+8+(e*40*6)
            write_ram(f,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            write_ram(a,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            write_ram(b,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            write_ram(c,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            write_ram(d,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            write_ram(e,adr+x++)                                                'in Shadow-Bildspeicher schreiben
            tilecounter++
         d++
       ios.ram_wrword(tilecounter,MAP_RAM)                                     'Tile-Zähler in den Ram schreiben
con '************************************* Unterprogramme zur Map-Daten-Behandlung *****************************************************************************************************
PRI lmap(name)|datadresse,counters                                               'Map-datei von SD-Card in eram laden
    datadresse:=MAP_RAM
    mount
    activate_dirmarker(basicmarker)                                             'ins Basic Stammverzeichnis
    if ios.sdopen("R",name)                                                     'datei vorhanden?
       errortext(22,1)
       return
    counters:=DPL_CNT                                                            'anzahl speicherstellen
    counters*=6                                                                  'mit 6 multiplizieren da jedes Tile 6 parameter hat (nr,3xfarbe und x bzw.y)
    counters+=8                                                                  'plus header
    ios.sdxgetblk(datadresse,counters)                                           'Map in den Speicher laden
    close
    tilecounter:=ios.ram_rdword(MAP_RAM)                                        'tilecounter fuer anzeige setzen

PRI smap(name)|datadresse,a,count                                             'MAP-Datei auf SD-Card schreiben
   a:=ifexist(name)
   if a==0 or a==2                                                              'Fehler
      return
   ios.ram_wrword(tilecounter,MAP_RAM)                                          'counter schreiben
   datadresse:= MAP_RAM
   count:=(DPL_CNT*6)+8                                                         'counter mit 6 multiplizieren da jedes Tile 6 parameter hat (nr,farbe1-3,x,y), die ersten 8 stellen sind der Header
   ios.sdxputblk(datadresse,count)                                              'Map auf SD-Card speichern
   close

PRI DisplayMap|datadr,tnr,f1,f2,f3,tx,ty,contr                                  'Map-Datei aus eram lesen und anzeigen
    farbe      :=read_ram(MAP_RAM+2)                                            'Bildschirmfarben lesen
    hintergr   :=read_ram(MAP_RAM+3)
    cursorcolor:=read_ram(MAP_RAM+4)
    ios.printboxcolor(win,farbe,hintergr,cursorcolor)                           'Fenster mit Bildschirmfarben erzeugen
    ios.printcls
    datadr:=MAP_RAM+8                                                           'Start-Position im ERam
    repeat DPL_CNT
               tnr:=read_ram(datadr++)                                          'Tilenr
               f1 :=read_ram(datadr++)                                          'farbe1
               f2 :=read_ram(datadr++)                                          'farbe2
               f3 :=read_ram(datadr++)                                          'farbe3
               tx :=read_ram(datadr++)                                          'x-position
               ty :=read_ram(datadr++)                                          'y-position
               if contr:=tnr+f1+f2+f3                                           'Tile da?
                  ios.displayTile(tnr,f1,f2,f3,ty,tx)                           'einzelnes Tile anzeigen   ('displayTile(tnr,pcol,scol,tcol, row, column))
con'****************************************** Button-Routinen *************************************************************************************************************
Pri Buttons|a,c,bnr,adr
    a:=spaces
    skipspaces
    klammerauf
    bnr:=expr(1)                                                                'Button-Nr
    if bnr>BUTTON_CNT or bnr<1
       errortext(3,1)
    adr:=BUTT_RAM+((bnr-1)*40)
    case a                    '    0        1       2     3
         "t","T":komma
                 param(3)     'vordergr,hintergr,x-pos,y-pos,Buttontext
                 komma
                 Input_String
                 prm[4]:=prm[2]+strsize(@f0)+1
                 ios.Plot_Line(prm[2], prm[3],prm[4],prm[3],prm[1])             'Button darstellen
                 ios.printfont(0,@f0,prm[1],prm[0],0,prm[3],prm[2]+1,0)         'Text mit aktuellen Font darstellen
                 c:=Buttonparameter(5,adr)                                      'Button-Parameter in den Ram schreiben
                 stringschreiben(c++,0,@f0,1,0)                                 'Button-Text in den Ram schreiben
                 button_art[bnr-1]:=1                                           'Art des Buttons 1=Text 2=Icon
                 ios.send_button_param(bnr,prm[2],prm[3],prm[4])                'Button-Koordinaten nach Bella senden zur Maus-Verarbeitung

         "i","I":'Icon-Button    0       1        2        3      4    5
                 komma
                 param(5)     'tilenr,vordergr,hintergr,3.Farbe,x pos,y-pos
                 ios.displayTile(prm[0],prm[1],prm[2],prm[3],prm[5],prm[4])     'einzelnes Tile anzeigen   ('displayTile(tnr,pcol,scol,tcol, row, column))
                 Buttonparameter(6,adr)
                 button_art[bnr-1]:=2                                           'Art des Buttons 1=Text 2=Icon
                 ios.send_button_param(bnr,prm[4],prm[5],prm[4])                'Button-Koordinaten nach Bella senden zur Maus-Verarbeitung
         "r","R":'Reset
                 ios.destroy3dbutton(bnr)                                       'button löschen
                 button_art[bnr-1]:=0                                           'Button-Art löschen
         other:
               errortext(1,1)
    klammerzu

pri Buttonpress_on(h)|adr,a,b,c,d,e,f',g,tnr

  adr:=BUTT_RAM+((h-1)*40)                                                      'Textbutton - Icon
  a:=  read_ram(adr++)                                                          'vordergr - tnr
  b:=  read_ram(adr++)                                                          'hintergrund - f1
  c:=  read_ram(adr++)                                                          'tx - f2
  d:=  read_ram(adr++)                                                          'ty - f3
  e:=  read_ram(adr++)                                                          'txx - x

    if button_art[h-1]==1                                                       'Textbutton
       stringlesen(adr++)                                                       'Button-String holen
       ios.Plot_Line(c,d,e,d,a)                                                 'Button revers zeichnen
       printfont(@font,a,b,0,c+1,d)                                             'Text mit aktuellen revers Font darstellen
       repeat while ios.mouse_button(0)
       ios.Plot_Line(c,d,e,d,b)                                                 'Button normal zeichnen
       printfont(@font,b,a,0,c+1,d)                                             'Text mit aktuellen Font darstellen

    if button_art[h-1]==2                                                       'Icon-Button
       f:=read_ram(adr++)                                                       'y-Position des Icon
       ios.displayTile(a,c,b,d,f,e)                                             'einzelnes Tile revers anzeigen   ('displayTile(tnr,pcol,scol,tcol, row, column))
       repeat while ios.mouse_button(0)
       ios.displayTile(a,b,c,d,f,e)                                             'einzelnes Tile anzeigen   ('displayTile(tnr,pcol,scol,tcol, row, column))

pri buttonparameter(sl,adr):c|i                                                 'Buttonparameter in den Ram schreiben
    i:=0
    repeat sl
        write_ram(prm[i++],adr++)
    c:=adr

pri read_ram(adr)

    result:=ios.ram_rdbyte(adr)

pri write_ram(wert,adr)

    ios.ram_wrbyte(wert,adr)

PRI READ_PARAMETER|a,i                                                          'Parameterabfrage beim Basic-Start
    if ios.ram_rdbyte(SMARK_RAM)<>222                                           'Startparameter-Flag lesen
       a:=ios#PARAM
       i:=0
       repeat while tline[i++]:=ios.ram_rdbyte(a++)                             'Parametertext einlesen
       tline[i]:=0
       if i>0
          tp:= @tline                                                           'Parameterzeile nach tp verschieben
          tokenize                                                              'Befehle in Token konvertieren
          texec                                                                 'Befehle ausführen
          ios.paradel                                                           'Startparameter löschen
       ios.ram_wrbyte(222,SMARK_RAM)                                            'Startparameter-Marker löschen


DAT

{{
                            TERMS OF USE: MIT License

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, exprESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
}}
