Projekt
Hardware
Bedienung
BASIC (1)
BASIC (2)
BASIC (3)
Interna
Beispiele
Erweiterungen
Bibliotheken
Treiber
Programme


Bezugsquellen:
Bausatz
Leerplatine

AVR-ChipBasic2: BASIC-Referenz (1)
Grundlagen
V1.50 (c) 2006-2015 Jörg Wolfram






1 Allgemeines

Jedes Programm besteht aus maximal 95 Programmzeilen (1-95). Für längere Schlüsselwörter existieren teilweise Abkürzungen, diese stehen in rechteckigen Klammern neben der ausgeschriebenen Version. Nach jedem Schlüsselwort muss ein Leerzeichen stehen. Viele Befehle blenden nicht benutzte Bits bei den Parametern aus (z.B. COLOR) oder begrenzen auf den gültigen Wertebereich (z.B. PLOT). Leider werden in der aktuellen Version nicht alle Fehler abgefangen, in so einem Falle (meist wird der ganze Bildschirm mit Nullen oder unsinnigen Zeichen vollgeschrieben) sollte man mit CTRL+ALT+DEL den Computer neu starten und sich den BASIC-Programmtext nocheinmal ansehen.


2 Zahlen, Variablen und Funktionen

AVR-ChipBASIC kennt nur einen Datentyp, und das sind 16 Bit Integerzahlen. Dazu gibt es 26 Variablen (A-Z) und ein Array mit 768 oder 1024 Elementen AR(), dazu aber später mehr. Konstanten können sowohl in Dezimalform als auch in Hexadezimalform eingegeben werden, wobei bei letzterer keine negativen Werte erlaubt sind. Hexadezimalzahlen beginnen mit $. Folgende Operationen sind erlaubt:
  • Addition +
  • Subtraktion -
  • Multiplikation *
  • Division /
  • Modulo %
  • Und-Verknüpfung &
  • Oder-Verknüpfung #
  • Exclusiv-Oder-Verknüpfung ^
  • Vergleiche (=,<>,<,<=,>,>=) liefern 0 für falsch oder 1 für wahr
  • Bit-Shift nach links <<
  • Bit-Shift nach rechts >>
Dazu kommen noch öffnende und schließende Klammern sowie Funktionen. Die Operatoren sind in unterschiedliche Prioritätsgruppen eingeteilt. Soll die Priorität eines Operators erhöht werden, müssen die dazugehörigen Operanden geklammert werden.


Priorität Operatoren
höchste * , / , % , # , ^
... << , >>
... + , - , &
niedrigste = , <> , < , <= , > , >=


Funktionen können im Gegensatz zu Schlüsselwörtern nicht abgekürzt werden. Da die öffnende Klammer Bestandteil des Funktionsnamens ist, darf zwischen Funktionsname und Klammer kein Leerzeichen stehen.


ABS( Berechnet den Absolutwert des eingeklammerten Ausdruckes
SGN( Berechnet das Vorzeichen (-1,0,1) des eingeklammerten Ausdruckes
NOT( invertiert den eingeklammerten Ausdruck
SQR( zieht die Quadratwurzel aus dem eingeklammerten Ausdruck
RND( erzeugt eine Zufallszahl zwischen 0 und dem eingeklammerten Ausdruck
IN( liefert den Pegelwert des angegebenen Portpins (0-7) an der parallelen Schnittstelle, ist der Parameterwert 255 werden die Portpins als Byte eingelesen,
SPI( gibt ein Byte über die SPI-Schnittstelle aus und gibt den eingelesenen Wert zurück
TEMP( liefert den Temperaturwert des angegebenen LM75-Sensors (0-7)
ADC( liefert den Analogwert der Spannung des angegebenen Portpins (0-7) an der parallelen Schnittstelle
XPEEK( liest ein Datenbyte aus dem optionalen Daten-EEPROM, der Klammerausdruck bestimmt die Adresse
EPEEK( liest ein Datenbyte aus dem internen EEPROM, Adresse 0...999
VPEEK( liest ein Datenbyte aus dem Bildwiederholspeicher
LO( liefert das niederwertige Byte des eingeklammerten Ausdruckes
HI( liefert das höherwertige Byte des eingeklammerten Ausdruckes
KEY( liefert verschiedene Tastaturabfragen, siehe Abschnitt Tastatur
AR( Array-Wert (s.u.)
SIN( liefert den Sinus des Winkels (in 1/10 Grad) mal 255
COS( liefert den Cosinus des Winkels (in 1/10 Grad) mal 255
FTYPE( siehe Abschnitt Dateifunktionen
FSIZE( siehe Abschnitt Dateifunktionen
ERR( Fehlerinformationen, siehe Abschnitt Fehlerhandling
XREC( liest einen Datenblock via XModem-Protokoll ein
DBIT( konvertiert Zeichensatzdaten
PSTAT( Sequenzer-Status, siehe Abschnitt Audio


Zusätzlich zu den normalen Variablen gibt es noch die Arrayvariable AR().
  • Die Zellen 0...767 sprechen den internen Bereich byteweise an
  • Die Zellen 768...1023 sprechen die aktive Page des externen Bereiches byteweise an
  • Die Zellen 1024...1407 sprechen den Bereich im wortweise an
  • Die Zellen 1408...1535 sprechen die aktive Page des externen Bereiches wortweise an
Bei den Byte-Zugriffen befindet sich das LOW-Byte an der geraden Adresse und das High-Byte an der darauf folgenden ungeraden Adresse. Wird auf eine Array-Zelle zugegriffen die nicht existiert, wird mit einer Fehlermeldung abgebrochen. Über AR() lässt sich nur vom Array lesen, Schreibzugriffe müssen mit DATA erfolgen.
Um auf das externe Array zuzugreifen, kann mittels des Befehles PAGE nn die aktive Page im externen Speicher eingestellt werden. Einige Dinge wie Datei-I/O funktionieren nur mit dem internen Array-Speicher, um den externen Speicher nutzen zu können, müssen die Daten mittels ACOPY umkopiert werden. Voraussetzung dafür ist, dass auf Programmplatz 8 ein Treiber mit Unterstützung für XMEM geladen wurde.

3 Wertzuweisung

Wertzuweisungen beginnen nicht mit einem Schlüsselwort, sondern mit einem Variablennamen gefolgt von einem Gleichheitszeichen und einem Ausdruck.
01 A=-4
02 B=SQR(8*2)


3.1 ASHIFT v,n

Der Absolutwert der Variable v wird um n Bits verschoben. Für N>0 wird bitweise nach links verschoben, für N<0 nach rechts. Sinnvolle Werte für N liegen zwischen -15 und +15. Im Gegensatz zu den Shift-Operatoren wird nur der Absolutbetrag verschoben, damit liefert dieser Befehl auch bei negativen Werten ein richtiges Ergebnis.
01 A=-39
02 ASHIFT A,-1
03 PRINT A
Da A um 1 Bits nach rechts verschoben wird, wird der Wert -19 ausgegeben. Im Gegensatz dazu ergibt:
01 A=-39 >> 1
02 PRINT A
das Ergebnis 32749, da in die Vorzeichenstelle eine 0 geschoben wurde.

3.2 LIMIT v,min,max [LIM]

Der Wert der Variable v wird auf den Wertebereich min...max begrenzt. Die Funktion ist nur auf Variablen, nicht auf Arrayelemente erlaubt.
01 LIMIT A,1,6
02 LI B,C,C+4
im ersten Beispiel wird die Variable A auf den Bereich 1...6 begrenzt, im zweiten Beispiel die Variable B auf den Wertebereich, der durch den Inhalt der Variable C und die 4 darauffolgenden Zahlen begrenzt ist.

3.3 SCALE Variable,Y0,Y1,X0,X,X1

Dieser Befehl dient dazu, Werte von einem Bereich in einen anderen zu transformieren. X ist dabei der "INPUT"-Bereich, Y liefert das Resultat. Ein Beispiel:
01 V=180
02 SCALE A,0,100,0,V,256
03 ? V
liefert z.B. als Resultat den wert 70. In diesm Falle heißt das, der Wert von V (180) entspricht 70 Prozent vom Maximalwert 256. Man kann sich das so vorstellen, daß das Resultat so zwischen Y0 und Y1 liegt, wie der Wert X zwischen den Grenzen X0 und X1 liegt. Die Formel dafür ist:
 Y = Y0 + ((Y1-Y0) * (X-X0) / (X1-X0))
Damit das Ganze auch hinreichend genau ist, wird intern mit 32 Bit gerechnet. Aufgrund der begrenzten internen Programmspeicherkapazitäten werden aber nicht alle Bedingungen für das Zustandekommen eines gültigen Resultates überprüft. So sollte Y1 betragsmäßig immer größer als Y0 sein, X1 betragsmäßig größer als X0 sein und X sollte zwischen X0 und X1 liegen.

3.4 DATA offset,value1,value2... [DA]

Die Array Elemente werden ab Byte (offset) initialisiert. Als Werte kommen Konstanten, numerische Ausdrücke und Zeichenketten in Frage. Im Word-Bereich des Arrays (ab Offset 1024) werden immer 16 Bit geschrieben, das betrifft insbesondere Zeichenketten wo das HIGH-Byte immer 0 ist. Andersherum wird im Bytebereich des Arrays nur das Low-Byte der Werte geschrieben.
01 DATA 0,"Hallo",0
Das Array wird ab Element 0 mit der nullterminierten Zeichenkette "Hallo" belegt.

3.5 ACOPY source,dest,num... [AC]

Eine Anzahl (num) von Array Elementen wird ab Byte (source) nach Byte (dest) kopiert. Das Kopieren erfolgt elementweise, so kann z.B. auch von 8 auf 16 Bit erweitert werden. Andersherum wird beim Kopieren vom Word- in den Bytebereich des Arrays nur das Low-Byte der Werte geschrieben.
02 ACOPY 0,1029,10
Das Array wird ab Byte-Element 0 in die Word-Elemente 1029...1038 (Byte-Elemente 10...29) kopiert.
Wichtig ist dabei, dass die Arrayzellen nur aufsteigend kopiert werden. Überlappen sich Quell- und Zielbereich und ist die Quelladresse kleiner als die Zieladresse, wird das Ergebnis nicht dem Gewünschten entsprechen, das Teile des Quellbereiches überschrieben werden bevor sie in den Zielbereich kopiert werden.

3.6 TLEN var,ptr

Dieser Befehl bestimmt die "Textlänge" im Array ab Zelle ptr. Es wird die erste Nicht-Text Zelle (alles was kleiner als 0x20 ist) gesucht. Das Ergebnis wird in die Variable var eingetragen.
01 DA 0,"Test",0
02 TLEN A,0
03 ? A
Dieses kurze Programm sollte den Wert 4 ausgeben, da der Text "Test" 4 Zeichen lang ist. Wird bei der Suche nach dem Textende das Ende des Arrays erreicht, bricht der Befehl mit einem Fehler (OUT OF ARRAY) ab.

3.7 TFIND var,ptr1,ptr2

Mit diesem Befehl lässt sich nach einem Text im Array suchen. Dabei zeigt ptr auf den zu durchsuchenden Text und ptr2 auf das zu suchende Textmuster. Beide Zeichenketten müssen mit einem Zeichen kleiner 0x20 abgeschlossen werden. Das Ergebnis wird in die Variable var eingetragen.
01 DA 100," nord ost  sued west"
02 DA 120," end",0
03 INPUT "Richtung:";A
04 DA 0,32:CTEXT 1,20
05 TFIND A,100,0:A=A-100
06 IF A = 20 THEN END
07 IF A < 0 THEN ? "???":GO 3
08 PRINT "R=";A/5: GOTO 3
Wird bei der Suche das Ende des Arrays erreicht, bricht der Befehl mit einem Fehler (OUT OF ARRAY) ab. Konnte das Textmuster nicht gefunden werden, schreibt der Befehl den Wert -1 in die Variable.

3.8 DBIT(N)

Diese Funktion vereinfacht das Erstellen von selbstdefinierten Zeichen im Videomodus 4. Vom Argument N werden nur die 6 unteren Bits berücksichtigt und in ein Bitmuster umgewandelt, welches bei der Darstellung dem Erwarteten entspricht. Grund dafür ist die Organisation des Zeichenspeichers: Hier werden Bit 0+1 nicht benutzt, Bit 7 entspricht dem Pixel ganz links und die nachfolgenden Bits (6...2) ensprechen jeweils der Differenz zum vorherigen Pixel. Sollen zum Beispiel alle 6 Pixel in einer Zeile gesetzt werden, muß 0x80 im Byte stehen. Bit 7 ist "1" und alle nachfolgenden "0", was "keine Änderung" bedeutet. Damit man sich diese Umrechnung ersparen kann, rechnet die Funktion DBIT() das anzuzeigende Bitmuster systemgerecht um. Vom Parameter N werden dabei nur die unteren 6 Bits benutzt.
01 VM 4:? @0,0;%0;:BORDER 4
02 DA 0,"88GG88GG88"
03 WAIT 10
04 FOR K=0 TO 9:C=DBIT(AR(K))
05 VPOKE 1448+K*128,C:NEXT 
Das Programm ändert nach 1 Sekunde das Aussehen von Zeichen 0 welches links oben angezeigt wird, in eine Art "Schachbrettmuster".

4 Programmsteuerung



4.1 BREAK

Setzt einen Breakpoint, ruft den Monitor auf.

4.2 END

Mit dem END-Befehl wird das Programm an der aktuellen Stelle beendet. Das gleiche geschieht auch, wenn die letzte Programmzeile abgearbeitet ist.

4.3 GOTO n [GO]

Mit dem GOTO-Befehl kann die Programmabarbeitung mit einer anderen Zeile fortgesetzt werden. Argument ist ein beliebiger Ausdruck.
01 B=0:GOTO 2
02 GO B+1
Das ist eine Endlosschleife, die nur mit CTRL+C abgebrochen werden kann.

4.4 IF - THEN

Die bedingte Anweisung besteht aus IF gefolgt von einem Ausdruck. Ist das Ergebnis des Ausdrucks Null, wird zum Anfang der nächsten Zeile gesprungen, andernfalls wird die Zeile weiter abgearbeitet. Das THEN kann auch weggelassen werden. Schon wegen der Übersichtlichkeit und Lesbarkeit des Codes sollte dies aber nur dann erfolgen, wenn kein Platz mehr in der Zeile ist. Folgt als erstes eine Wertzuweisung, muss bei fehlenden THEN ein Doppelpunkt zwischen die beiden Anweisungen gesetzt werden.
01 IF A>5 THEN A=5
02 IF A>5:A=5
Beide Ausdrücke bewirken exakt das Gleiche.

4.5 FOR - NEXT

Bei der Zählschleifen-Abarbeitung gibt es nur die Grundform FOR A=B TO C ohne die Angabe der Schrittweite, die konstant 1 ist. Die Schleife wird auf jeden Fall mindestens 1 mal durchlaufen, wenn C keiner als B ist findet ein Überlauf statt und die Anzahl der Schleifendurchläufe ist N=C-B+65536.
01 CLS
02 FOR A=0 TO 9
03 FOR B=0 TO 9
04 PLOT A,B,3
05 NEXT :NEXT
Dieses Programm zeichnet ein Rechteck in die obere linke Ecke des Bildschirmes.

4.6 REPEAT - UNTIL [REP - UNT]

Dies ist eine weitere Schleifenkonstruktion, eine sogenannte Fußgesteuerte oder auch Nichtabweis-Schleife. Das heißt, der Programmteil zwischen REPEAT und UNTIL wird mindestens einmal durchlaufen.
01 A=0
02 REPEAT
03    ? A
04    A=A+3
05 UNTIL A<10
Schreibt die Zahlen 0,3,6 und 9 untereinander auf den Bildschirm.
Systembedingt gibt es kein EXIT, um eine Schleife abzubrechen. Ein einfaches GOTO aus der Schleife heraus ist auch keine gute Lösung, da damit ein Stackeintrag blockiert wird. Eine praktikable Lösung wäre:
01 REPEAT
02    ? "Hallo! ";
03    IF KEY(0)>0 UNT 0: GO 5
04 UNTIL 1
schreibt solange "Hallo!" auf den Bildschirm, bis eine Taste gedrückt wird. Das UNTIL 0 bewirkt in diesem Fall, dass der reservierte Stackeintrag wieder freigegeben wird.

4.7 GOSUB [GOS]

GOSUB Expr ruft das Unterprogramm in der durch den Ausdruck definierten Zeile auf, auf die Zeilennummer können noch bis zu 5 Parameter folgen. Da der Stack auf 10 Einträge begrenzt ist, lassen sich nur insgesamt 10 Schleifen bzw. Unterprogrammaufrufe schachteln.
01 GOSUB 4,2,3
02 ? ~R
03 END
04 RETURN ~(1)+~(2)
Das Unterprogramm in Zeile 4 addiert die beiden Parameter, in diesem Fall 2 + 3 = 5. In der zweiten Zeile wird dann das Resultat ausgegeben.

4.8 RETURN [RET]

Mit RETURN wird aus einem Unterprogramm wieder zurückgesprungen, mit RETURN returnwert kann ein 16 Bit Wert zurückgegeben werden, der dann mit der Systemvariable ~R im aufrufenden Programm verfügbar ist.

4.9 CALL

Eine weitere Anweisung ist CALL prognr,zeile die Unterprogramme in einem der 7 anderen Programme aufrufen kann. Damit ist es möglich, den gesamten Programmspeicherbereich für eine einzige Anwendung zu nutzen. Auf die Programm- und Zeilennummer können noch bis zu 5 Parameter folgen, der Rücksprung erfolgt wie gehabt mit RETURN. Da der Stack auf 10 Einträge begrenzt ist, lassen sich nur 10 Schleifen bzw. Unterprogrammaufrufe schachteln. Weiterhin führt das Verlassen von Schleifen oder Unterprogrammen zu blockierten Stack-Einträgen, die dann nicht mehr genutzt werden können. Wenn das aufgerufene Programm vom Typ Binär ist, gibt es zwei Möglichkeiten:
  • Der zweite Parameter ist eine Zahl und gibt den Offset zum Programmanfang in WORDS an. Möglich sind Werte zwischen 0...1535. Danach können noch bis zu 4 weitere Parameter an das Binärprogramm übergeben werden. Das T-Flag im Statusregister ist bei Übergabe zurückgesetzt
  • Der zweite Parameter ist eine in Gänsefüsschen gesetzte Zeichenkette. Hier wird dann ein Zeiger auf die Zeichenkette im Y-Register übergeben. Einsprungadresse ist Programmanfang+9 WORDS, das T-Flag im Statusregister ist bei Übergabe gesetzt


4.10 LFIND V,n

Mit dieser Anweisung lässt sich feststellen, ob eine bestimmte Binärbibliothek geladen ist. Dazu hat jede dieser Bibliotheken eine (hoffentlich) eindeutige Kennung in Byte 14 und 15. Wenn das LOW-Byte des Suchwertes gleich 0 ist, wird das LOW-Byte der Bibliotheks-ID ignoriert. Die Variable wird auf 1...8 gesetzt, wenn eine entsprechende Bibliothek gefunden wurde.
01 LFIND L,$1200
02 IF L>0 GOTO 4
03 ?"MATLIB1 NICHT GEFUNDEN":END
04 ?"MATLIB1 AUF PLATZ";L:


4.11 VID n

Dieser Befehl ersetzt seit Version 1.00 die Befehle SLOW und FAST um die Bildausgabe ein- und auszuschalten. Mit VID 0 wird die Bidausgabe ausgeschaltet, Synchronsignale werden auch weiterhin erzeugt. VID 1 schaltet die Bildausgabe wieder ein. Mit ausgeschalteter Bildausgabe ist die Geschwindigkeit höher, da ein großer Teil der Rechenleistung normalerweise für die Bilddarstellung verwendet wird. Es sollte dabei beachtet werden, dass damit auch der Aufruf geladener Videotreiber abgeschaltet wird, was z.B. bei einem PWM- oder LED-Multiplex Treiber ungewünschte Folgen haben kann.

4.12 Die System-Variablen

Die Sytem-Variablen (definiert durch vorangestellte Tilde, also die "Schlangenlinie") geben Auskunft über den System-Zustand und können nur gelesen werden. Zwischen das Tilde-Zeichen ~und dem Buchstaben für die Systemvariable darf sich KEIN LEERZEICHEN befinden.

4.12.1 Das Array ~(1) ... ~(5) (Funktionsparameter)

In diesem Array stehen die Parameter, die beim letzen GOSUB bzw. CALL übergeben wurden. Liegt das Argument außerhalb des Bereiches 1...5, wird 0 zurückgegeben.

4.12.2 ~M (Mikrocontroller)

In dieser Variable steht, ob es sich um einen Mega644 (1) oder Mega644P (2) handelt. Dabei wird ein Mega644P mit Input-Pin der ersten seriellen Schnittstelle an PD3 als Mega644 behandelt, da auch hier die zweite serielle Schnittstelle nicht nutzbar ist.

4.12.3 ~L (aktuelle Programmzeile)

Diese Variable liefert als Wert die gerade abgearbeitete Programmzeile. Damit lassen sich z.B. relative Sprünge realisieren. Der Wert liegt zwischen 1 und 95, die folgende Programmzeile ezeugt in jeder Zeile eine Endlosschleife, die einen "bunten" Rand erzeugt:
xx A=(A+1)&15:BORDER A: GOTO ~L


4.12.4 ~N (Parameter-Anzahl)

In dieser Variable steht, wieviele Parameter beim letzten GOSUB bzw. CALL übergeben wurden.

4.12.5 ~P (aktuelles Programm)

Diese Variable liefert als Wert das gerade abgearbeitete Programm. Der Wert liegt zwischen 1 und 8. Wenn mittels CALL P,N ein Unterproramm in einem anderen Programm aufgerufen wurde, wird nicht das aufrufende Programm zurückgegeben, sondern das im Moment aktive.

4.12.6 ~R (Return-Wert)

Diese Variable enthält den zuletzt bei RETURN angegebenen Wert.

4.12.7 ~S (Scanline)

Diese Variable liefert als Wert die aktuelle Bildschirmzeile, die gerade dargestellt wird. Bei NTSC bewegt sich der Wert zwischen 0 und 262, bei PAL zwischen 0 und 312. Anwendungsgebiete sind z.B. genauere Zeitmessungen, bei denen TGET zu grob auflöst. Dabei sollte aber die Videoausgabe abgeschaltet werden.
01 REPEAT :UNTIL ~S<230:BO 4
02 REPEAT :UNTIL ~S>100:BO 0:GO 1
Auf dem Bldschirm sollte jetzt oben und unten ein grüner Rand zu sehen sein, dazwischen ist der Bildschirm schwarz. Allerdings ist dabei ein starkes Zittern der Kanten zu beobachten, was einfach daher rührt, dass die Abarbeitung der Befehle länger dauert als eine Bildschirmzeile.

4.12.8 ~V (Videosystem)

diese Variable liefert als Wert die Anzahl der Bildschirmzeilen je Halbbild. Eine mit ~S ermittelte aktuelle Bildschirmzeile wird immer zwischen 0 und ~V-1 liegen. Bei NTSC ist ~V = 263, bei PAL beträgt der Wert 313.

4.12.9 ~X (X-Ausdehnung)

diese Variable liefert als Wert die Anzahl der Pixel in horizontaler Richtung. Dabei wird die aktuelle Auflösung berücksichtigt. In Video-Mode 0 hat die variable z.B. den wert 60 und im Mode 1 den Wert 168.

4.12.10 ~Y (Y-Ausdehnung)

diese Variable liefert als Wert die Anzahl der Pixel in vertikaler Richtung. Dabei wird die aktuelle Auflösung berücksichtigt. In Video-Mode 0 hat die variable z.B. den wert 46 und im Mode 1 den Wert 116.

4.13 Erweiterungen

Wenn sich auf Programmplatz 6 eine Bibliothek mit Bibliothekscode 0x70...0x7f befindet, können dort zusätzliche Befehle ausgewertet und ausgeführt werden. Diese Befehle beginnen mit einem Unterstrich. Ist der Befehl dort nicht bekannt oder keine passende Bibliothek geladen, wird mit einem UNKNOWN KEYWORD Fehler abgebrochen. Wie bei den eingebauten Befehlen können auch Variablen oder Parameter folgen.

5 Bildschirm-Ausgabe



5.1 COLOR F(,B) [COL]

Mit dem COLOR-Befehl wird die Vorder- sowie die Hintergrundfarbe festgelegt. Diese wird im Gegensatz zu früheren Versionen bei allen Ausgaben bercksichtigt, da jetzt für jedes Zeichen Vorder- und Hintergrundfarbe einzeln festgelegt werden können. Wird nur ein Parameter angegeben, wird nur die Vordergrundfarbe gesetzt. Akzeptiert werden Werte von jeweils 0 bis 15, ohne die "16-Farben Erweiterung" sind die Farben 0...7 und 8...15 identisch:


Wert 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
Farbe schwarz blau rot magenta grün cyan gelb weiss


Wenn die "16-Farben Erweiterung" eingebaut wurde, stehen 8 zusätzliche Farben zur Verfügung, wobei die ersten 8 Farben insgesamt etwas dunkler werden.
Wert 0 1 2 3 4 5 6 7
Farbe schwarz blau rot magenta grün cyan gelb hellgrau
Wert 8 9 10 11 12 13 14 15
Farbe dunkelgrau hellblau hellrot hellmagenta hellgrün hellcyan hellgelb weiss


01 COLOR 4,2
Hier wird die Zeichenfarbe "Grün auf rotem Grund" festgelegt, was allerdings nicht gerade besonders gut lesbar ist.

5.2 CLS

Mit dem CLS-Befehl wird der Bildschirm gelöcht. Beim Programmstart geschieht das automatisch. Es wird die eingestellte Hintergrundfarbe (beim Programmstart schwarz) verwendet.

5.3 BORDER B [BO]

Mit diesem Befehl kann die Randfarbe eingestellt werden, gültige Werte sind 0...15.

5.4 POS Y,X

Mit dem POS-Befehl wird der Schreibcursor an die Stelle Y,X gesetzt. Nach jedem Löschen des Bildschirms wird der Cursor auf die Position 0,0 (links oben) gesetzt.

5.5 WRAP n

Mit dem WRAP-Befehl kann das Verhalten am Bildschirmende im Textmodus eingestellt werden. Mit WRAP 0 wird der Bildschirm beim Erreichen des Bildschirmendes um eine Zeile nach oben gescrollt. Dies ist auch die Standardeinstellung beim Start. Mit WRAP 1 wird beim Erreichen des Bildschirmendes der Cursor auf den Bildschirmanfang zurückgesetzt. BeimProgrammstart ist der Wert mit 0 vorbelegt.

5.6 PRINT [?]

Der PRINT-Befehl dient zur Ausgabe auf den Bildschirm oder auf die serielle/parallele Schnittstelle, in das Array oder auf die I2C-Schnittstelle. Zusätzlich kann die Ausgabe noch formatiert werden. Anstelle des PRINT Befehls kann auch (BASIC-üblich) ein Fragezeichen verwendet werden.


"TEXT" der Text TEXT wird ausgegeben
#Expr Festlegung des Ausgabekanals (s.u.)
!Expr Stellt das Format ein (s.u.)
@Expr1,Expr2 Cursorpositionierung (Y=Expr1, X=Expr2)
%Expr Direkte Ausgabe eines Zeichens mit Zeichencode=Expr
&Expr gibt Arrayelemente als Zeichen aus. Gestoppt wird bei einem Null-Byte oder wenn das Ende des Arrays erreicht ist. Funktioniert nur im Bytezugriff auf das Array.
Expr gibt das Ergebnis des Ausdrucks mit dem eingestellten Format aus
; Trenner zwischen Ausdrücken
, Trenner zwischen Ausdrücken, Leerzeichen bis zur nächsten durch 8 teilbaren Position


Steht am Ende des PRINT-Befehls einer der beiden Trenner, wird kein Zeilenvorschub ausgeführt. Der Ausgabekanal legt fest, wohin die Zeichen ausgegeben werden. Bei Ausgabekanal >3 wird auf die I2C-Schnittstelle mit der Kanalnummer als Devicenummer ausgegeben. Dabei wird das niederwertigste Bit auf 0 gesetzt (Schreibmode).


#0 Ausgabe auf den Bildschirm, Defaulteinstellung
#1 Ausgabe auf die serielle System-Schnittstelle
#2 Ausgabe auf die parallele Schnittstelle
#3 Ausgabe in das Array
#4 Ausgabe auf die zweite serielle Schnittstelle (nur ATMega 644P)
#5... Ausgabe über die I2C-Schnittstelle


Das Format ist ein Wert zwischen 0 und 255, wobei die Bits folgende Bedeutung haben:


Bit 7 0=dezimale Ausgabe, 1=hexadezimale Ausgabe
Bit 6 1 schaltet auf Großdarstellung um
Bit 4/5 Kommaposition (0-3 Nachkommastellen), nur für dezimale Ausgabe
Bit 2/3 Anzahl der ausgegebenen Ziffern (2-5), nur für dezimale Ausgabe
Bit 0/1 0=Kompakt, 1=fhrende Leerzeichen 2=führende Nullen 3=führende Nullen mit Vorzeichen
Bit 0 2/4 Zeichen bei hexadezimaler Ausgabe


Bei Ausgabe auf den Bildschirm wird der Cursor auf die entsprechende Position gesetzt, bei Ausgabe auf die serielle oder parallele Schnittstelle wird die Positionierung ignoriert. Bei Ausgabe in das Array entspricht der erste Wert Array-Byteposition*256 und der zweite Wert der Array-Byteposition, ohne @ ist die Byteposition zu Beginn jedes PRINT-Befehls 0x0000. Wird über die I2C-Schnittstelle ausgegeben, so wird zuerst 0xff und danach xxxxxxxx und yyyyyyyy gesendet. Die Änderung wude notwendig, um Zeichen z.B. auf extern angeschlossenen GLCD's feiner positionieren zu können.

5.7 CBOX Y1,X1,Y2,X2

Mit dem CBOX-Befehl wird ein Rechteck gelöscht (mit der aktuellen Hintergrundfarbe).
01 CBOX 3,3,5,5
löscht oben links ein Quadrat von 3x3 Zeichen.

5.8 FRAME Y1,X1,Y2,X2

Zeichnet einen Textrahmen mit Umrandung.
01 COLOR 7,3:FRAME 0,0,22,29
Zeichnen einen Textrahmen mit voller Bildschirmgröße, violettem Untergrund und weißer Zeichenfarbe.

5.9 HFRAME Y1,X1,Y2,X2

Zeichnet einen Textrahmen mit Umrandung und einem "Kopfbereich", so wie z.B. auch das Hauptmenü aufgebaut ist.
01 COLOR 7,3:HFRAME 0,0,22,29
02 COLOR 3,7:?@1,1;"HFRAME"
Zeichnen einen Textrahmen wie im vorigen Beispiel, allerdings jetzt mit einem Kopfbereich und Text darin.

5.10 IBOX Y1,X1,Y2,X2

Mit dem IBOX-Befehl werden in einem Rechteck Vorder- und Hintergrundfarbe vertauscht. Die Zeichen selbst werden nicht verändert.
01 IBOX 0,0,0,0
invertiert das Zeichen in der linken oberen Ecke.

5.11 SCROLL n

In den Vieomodi 0, 4 und 6 gibt es ein Scrollfenster, in dem in alle 4 Richtungen gescrollt werden kann. Das Fenster beginnt bei Zeichen 2 in Zeile 2 und geht bis Zeichen 27 in Zeile 20. Somit gibt es um das Scrollfenster einen 2 Zeichen breiten Rand in dem z.B. Informationen stehen, die nicht mitgescrollt werden sollen.
Die freiwerdende Zeile wird mit Leerzeichen in der aktuellen Farbeinstellung gefüllt.


n Richtung
0 nach oben
1 nach rechts
2 nach unten
3 nach links


10 SCROLL 2
verschiebt das Scrollfenster um 1 Zeichen nach unten.

5.12 GETCHAR variable,Y,X [GCH]

Ermittelt das Zeichen an der Position y,x und schreibt dieses in die Variable v.
11 GCH F,0,0
Schreibt den Zeichenwert von Position 0,0 in die Variable F.

5.13 GETATTR variable,Y,X [GAT]

Ermittelt das Attributbyte an der Position y,x und schreibt dieses in die Variable v.
12 GAT F,0,0
Schreibt den Attributwert von Position 0,0 in die Variable F. Dabei setzt sich das Attribut folgendermassen zusammen:


Bit Funktion
0 Hintergrundfarbe Bit 0
1 Hintergrundfarbe Bit 1
2 Hintergrundfarbe Bit 2
3 Hintergrundfarbe Bit 3
4 Vordergrundfarbe Bit 0
5 Vordergrundfarbe Bit 1
6 Vordergrundfarbe Bit 2
7 Vordergrundfarbe Bit 2


Dabei ist zu beachten, daß die Bits wegen der Kompatibilität zu früheren Versionen und der 8-Farben Hardware im Bildspeicher physisch anders angeordnet sind:


Bit Funktion
0 Hintergrundfarbe Bit 3
1 Hintergrundfarbe Bit 0
2 Hintergrundfarbe Bit 1
3 Hintergrundfarbe Bit 2
4 Vordergrundfarbe Bit 3
5 Vordergrundfarbe Bit 0
6 Vordergrundfarbe Bit 1
7 Vordergrundfarbe Bit 2




6 Tastatur



6.1 INPUT [INP]

Es können durch Kommata getrennt Zeichenketten und Variablen angegeben werden. Die Zeichenketten werden ausgegeben, die Variablen bewirken einen Eingabecursor. Falsch eingegebene Zeichen können mit der Backspace-Taste korrigiert werden. Es ist auch möglich, Ausdrücke einzugeben die dann berechnet werden. Das folgende Beispiel zeigt einen kleinen Rechner, das letzte Ergebnis ist in der Variable M gespeichert.
01 INPUT "AUFGABE: ",M
02 PRINT "ERGEBNIS:";M
03 GOTO 1
Gibt man als erstes "1+2" ein, erhält man "3". Gibt man danach "M*5" ein, erhält man "15".

6.2 CTEXT adr,anz

Kopiert den zuletzt bei Input eingegebenen Text in das Array byteweise ab Element adr. Als Endemarkierung wird ein Nullbyte angehängt. Mit dem 2.Parameter anz wird die Anzahl der maximal einzulesenden Bytes begrenzt. Dabei ist zu beachten, dass wegen dem angehängten Nullbyte effektiv anz+1 Bytes kopiert werden.
01 INPUT "Text: ",M
02 CTEXT 0,4
03 X=0
04 C=AR(X):IF C=0 THEN END
05 PRINT %C;:X=X+1:GOTO 4
Der nach der Eingabeaufforderung eingegebene Text wird eine Zeile tiefer wiederholt, wobei nur die ersten 4 Zeichen ausgegeben werden.

6.3 Die Keycodes

Neben den "normalen" ASCII-Werten für Ziffern, Zahlen und Satzzeichen liefern RKEY und WKEY auch Codes für Funktionstasten etc.


Code Hexadezimal Code Dezimal Taste
$C0 192 Power
$C1 193 Sleep
$C2 194 Wake
$E0 224 Pos1
$E1 225 End
$E2 226 Pfeiltaste nach links
$E3 227 Pfeiltaste nach rechts
$E4 228 Pfeiltaste nach oben
$E5 229 Pfeiltaste nach unten
$E6 230 Bild hoch
$E7 231 Bild runter
$E8 232 Einfg (Ins)
$E9 233 Entf (Del)
$EA 234 Enter
$EB 235 Tabulator
$EC 236 Backspace
$ED 237 Esc
$F1...$FC 241...252 F1...F12


6.4 Die Funktion KEY

Diese Funktion liefert verschiedene Tastaturabfragen. Als Parameter wird die Art der Abfrage eingetragen. Bei KEY(0) bis KEY(2) zählen Shift, CTRL und ALT nicht als gedrückte Tasten.


KEY(0) Es wird die gedrückte Taste oder 0x00 zurückgegeben
KEY(1) Es wird auf einen Tastendruck gewartet, Resultat ist der Code der gedrückten Taste.
KEY(2) Es wird gewartet, bis keine Taste mehr gedrückt ist, zurückgegeben wird der Code der zuletzt gedrückten Taste.
KEY(3) Es wird der Status der Shift- und CTRL Tasten zurückgeliefert. Belegung s.u.
KEY(4) linke Shift-Taste liefert 1, linke Control-Taste liefert -1, beide zusammen 0
KEY(5) rechte Shift-Taste liefert 1, rechte Control-Taste liefert -1, beide zusammen 0
KEY(6) Taste Cursor links liefert -1, Taste Cursor rechts liefert 1
KEY(7) Taste Cursor nach unten liefert -1 Taste Cursor hoch liefert 1
KEY(8) Es wird der zuletzt gelesene Scancode zurückgeliefert
KEY(9...255) Es wird gewartet, bis die Taste mit dem entsprechenden Keycode gedrückt wird


Belegung der Bits beim Rückgabewert von KEY(3):


Bit Funktion
0 Linke Shift-Taste
1 Rechte Shift-Taste
2 Linke CTRL-Taste
3 Rechte CTRL-Taste
4 ALT-Taste
5-7 Interne Verwendung




7 Zeit



7.1 WAIT n

Mit dem WAIT-Befehl wird N*0,1 Sekunden gewartet. N kann wieder ein beliebiger Ausdruck sein. Im Videomode 7 kann es dabei durchaus sein, dass der Treiber die Zeit nicht weiterzählt und die Funktion nicht wieder zurückkehrt. Das hängt aber von der konkreten Treiberimplementation ab.
10 WA 10
wartet 1 Sekunde, bis das Programm fortgesetzt wird.

7.2 SYNC n

Mit dem SYNC-Befehl wird auf N Bildsynchronimpuse gewartet. N kann wieder ein beliebiger Ausdruck sein. Im Videomode 7 kann es dabei durchaus sein, dass der Treiber die Zeit nicht weiterzählt und die Funktion nicht wieder zurückkehrt. Das hängt aber von der konkreten Treiberimplementation ab.
10 SYNC 300
wartet 6 Sekunden, bis das Programm fortgesetzt wird. Das gilt nur für PAL, bei NTSC wird nur ca. 5 Sekunden gewartet.

7.3 TSET n

Der interne Timer (10Hz) wird auf den Wert n gesetzt.
10 TSET 0
setzt den Timer auf 0.

7.4 TGET V

Der interne Timer (10Hz) wird ausgelesen und in die Varaiable V gespeichert. Im Videomode 7 kann es dabei durchaus sein, dass der Treiber die Zeit nicht weiterzählt und die Funktion die bei TSET gesetzte Zeit zurückliefert. Das hängt aber von der konkreten Treiberimplementation ab.
10 TGET Z
Damit kann z.B. die Laufzeit von Programmen bestimmt werden.

7.5 ONSYNC L,N

Ähnlich dem Timer-Interrupt bei einem Mikrocontroller können mit ONSYNC zeitgesteuerte Unterprogrammaufrufe eingerichtet werden. Dabei ist L die Zeilennummer und N die Anzahl der Bildsynchronimpulse zwischen zwei Aufrufen. Der Wert N für die Wartezeit kann maximal 255 betragen, L sollte eine gültige Zeilennummer sein, bei L=0 werden die automatischen Aufrufe gestoppt. Das aufgerufene Unterprogramm muß mit RETURN enden und darf nicht länger dauern als die Zeit zwischen zwei Aufrufen. Intern wird bei jedem Bildsynchronimpuls ein Zähler mit dem Wert N verglichen und bei Gleichheit ein Flag gesetzt. Im BASIC-Interpreter wird dann vor der Ausführung jedes Statements dieses Flag überprüft und falls es gesetzt ist ein GOSUB zur angegebenen Zeilennummer "eingeschoben". Im Videomode 7 kann es dabei durchaus sein, dass der Treiber die Zeit nicht weiterzählt und angegebene Zeile nie aufgerufen wird. Das hängt aber von der konkreten Treiberimplementation ab.
01 ONSYNC 5,50
02 ? "Border:";A,
03 GOTO 2
04
05 A=A+1:IF A=8 THEN A=0
06 BORDER A:RETURN
Dieses Programm ändert alle Sekunde die Randfarbe, während der aktuelle Border-Wert ständig als Text ausgegeben wird.

8 Fehlermeldungen und Errorhandling



8.1 ONERR N

Liegt N im Bereich der gültigen Zeilen (1...95), wird bei einem Fehler in diese Zeile gesprungen. Andernfalls wird dann (wie gewohnt) mit einer Fehlermeldung abgebrochen. Befinden sich an und hinter der angegebenen Zeile keine Befehle mehr, wird das Programm ohne Fehlermeldung verlassen.
Wenn mittels GOSUB eine Subroutine in einem anderen Programm aufgerufen wird, wird im Fehlerfall dort in die angegebene Zeile gesprungen.
01 ONERR 10
02 A=SQR(-1)
10 DATA 512,7,1,"Error!",0
11 ALERT 512
12 END
Da versucht wird, die Wurzel aus einer negativen Zahl zu ziehen, springt das Programm in Zeile 10 und zeigt dort eine Alertbox an.

8.2 ERR(n)

Über diese Funktion können Informationen über den aufgetretenen Fehler ausgelesen werden. Das funktioniert natürlich nur, wenn vorher mit ONERR eine eigene Fehlerroutine angesprungen wurde. Für n=1 wird die Zeile zurückgegeben, in der der Fehler aufgetreten ist, für n=2 das Statement. Für alle anderen Werte von n wird die Fehlernummer zurückgegeben.
01 ONERR 10
02 A=SQR(-1)
10 DATA 512,7,1,"Error          ",0
11 ? #3@2,8;ERR(0);
12 ALERT 512
13 END
Da versucht wird, die Wurzel aus einer negativen Zahl zu ziehen, gibt es wieder eine Alertbox. In Zeile 11 wird die Fehlernummer in das Array geschrieben und nun mit angezeigt.

8.3 Fehlermeldungen

Insgesamt gibt es 37 verschiedene Fehlermeldungen. Im Editor werden diese oben in der zweiten Zeile mit Programm-, Zeilen- und Statementnummer angezeigt. Im Allgemeinen lässt sich damit der Fehler recht schnell finden, manchmal kann er sich auch am Ende der vorherigen Zeile befinden.


01 BREAK Das Programm wurde mit der Tastenkombination Control (Strg) + C abgebrochen.
02 OVERFLOW Bei einer Rechenoperation liegt das Ergebnis ausserhalb der Grenzen von -32767...32767
03 DIVIDE/0 Es wurde versucht, durch Null zu dividieren
04 SQR FROM <0 Es wurde versucht, die Quadratwurzel aus einer negativen Zahl zu ziehen
05 CONSTANT TOO BIG Die angegebene Zahl liegt das Ergebnis ausserhalb der Grenzen von -32767...32767
06 WRONG EXPRESSION In der Formel befinden sich syntaktische Fehler
07 SYNTAX ERROR Fehlende Parameter, ungültige Zeichen
08 UNKNOWN KEYWORD Unbekanntes Schlüsselwort, der Programmcode enthält ungültige Bytes
09 WRONG FORMAT Die Zahlenformatierung ist ungültig (mehr Nachkommastellen als sichtbare)
10 BAD LINENUMBER Die Zeile mit der angegebenen Zeilennummer existiert nicht
11 NEXT W/O FOR Zu diesem NEXT Statement gibt es kein korrespondierendes FOR
12 RETURN W/O GOSUB Zu diesem RETURN Statement gibt es kein korrespondierendes GOSUB
13 STACK OVERFLOW Insgesamt dürfen nur 16 FOR/GOSUB/REPEAT zu gleichen Zeit "geöffnet" sein, Ursache kann z.B. ein rekursiver Unterprogrammaufruf sein.
14 UNTIL W/O REPEAT Zu diesem UNTIL Statement gibt es kein korrespondierendes REPEAT
15 I2C ERROR An der angegebenen Adresse meldet sich kein Gerät oder es meldet keine Bereitschaft, serielle EEPROMs können z.B. mit dem Schreiben von Daten beschäftigt sein.
16 UNKNOWN ERROR unbekannter Fehler. Leider lassen sich alle möglichen Kombinationen von Befehlen, Funktionen und Parametern nicht so einfach vollständig testen und es wäre schön, wenn Sie den Fehler melden würden.
17 DFLASH ERROR Kein Dataflash angeschlossen oder der Baustein reagiert nicht.
18 OUT OF ARRAY Es wurde versucht auf ein Arrayelement zuzugreifen, welches nicht existiert. Der Fehler tritt auch auf, wenn bei BCOPY der Platz im Array nicht ausreicht.
19 INCOMPLETE PAR Es wurden zuwenige Parameter für den Befehl angegeben
20 KEYWORD IS MISSING Das angegebene Statement beginnt nicht mit einem Schlüsselwort sondern z.B. mit einer Zahl
21 WRONG BCOPY Der Kopiermodus liegt nicht im Bereich (1...6)
22 OUT OF SCREEN Versuch, ausserhalb des Bildschirmbereiches zu zeichnen (nicht implementiert)
23 CANNOT CREATE FILE Das File existiert bereits oder die Filenummer liegt ausserhalb des gültigen Bereiches
24 DFLASH FULL Das File kann nicht erstellt werden, da der Platz auf dem Dataflash nicht ausreicht.
25 FILE NOT FOUND Das File existiert nicht (ist frei)
26 PAGE NOT IN FILE Die zu lesende/schreibende Page existiert nicht in diesem File
27 PAGES NOT IN RANGE Es können nur Files mit 1...128 Pages erzeugt werden
28 NOT IN GRAPHICS MODE Der angegebene Befehl kann nicht im Grafikmode (VMODE 1...3/5) ausgeführt werden
29 NOT IN TEXT MODE Der angegebene Befehl kann nicht im Textmode (VMODE 0) ausgeführt werden
30 NO USR FILE Es können nur Files vom Typ USR gelesen/geschrieben werden (obsolete)
31 SRC OUT OF SCREEN Der Quellblock bei BCOPY befindet sich nicht vollständig im Bildbereich
32 DEST OUT OF SCREEN Der Zielblock bei BCOPY befindet sich nicht vollständig im Bildbereich
33 WRONG SPRITE Die Sprite-Definition hat einen Fehler (z.B. größer als 8x8 Zeichen)
34 WRONG EEPROM ADR Es wurde versucht, auf eine interne EEPROM-Zelle >1999 zuzugreifen
35 NO PRG FILE Es wurde versucht, mit LOADP ein Nicht-Programm-Datei zu laden
36 XMODEM ERROR Beim X-Modem Empfang ist ein (Prüfsummen-) Fehler aufgetreten
37 CANT LOAD THIS Es wurde versucht, das gerade laufende Programm mit LOADP zu überschreiben
38 IO DISABLED Ausgabe auf den Parallelport wurde durch einen Treiber auf Programmplatz 8 deaktiviert
39 SERIAL1 NOT AVAILABLE es wurde versucht, auf die zweite serielle Schnittstelle zuzugreifen, Controllertyp ist aber ein Mega644 oder Input-Pin der seriellen System-Schnittstelle liegt an PD3
40 NO IO DRIVER es wurde versucht, mittels IN/OUT auf eine nicht existierende Adresse ab 0x0800 zuzugreifen




created with latex2web.pl v0.63 © 2006-2013 Joerg Wolfram