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.
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:
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.
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.
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.
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 |
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).
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.
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 |
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.
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.
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.
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.
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.
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.
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
|