3. Geänderte oder neue BASIC-Anweisungen

Aus CBMPET.DE

Wechseln zu: Navigation, Suche
3.1 LOAD

Zweck

LOAD lädt eine PRG-Datei von Diskette in den
Arbeitsspeicher an die Adresse, die in den ersten beiden
Bytes der Datei vermerkt ist, bzw. die im Kommando
angegeben wird.

Aufgrund der Diskrepanz zwischen logischen und
physikalischen Adressen mußte LOAD einige optionale
Zusatzparameter erhalten, um auch Sonderfällen gerecht zu
werden.


Format

LOAD , ; ¶ % adresse , "laufwerk:name" , gerätenummer

Anmerkungen

load "namell

Im Normalfall werden die Parameter zwischen LOAD und dem
Namen nicht angegeben. Dann wird angenommen, ein Programm
soll in den Programmbereich geladen werden. Deshalb wird
in diesem Fall immer die Programm-Page eingeschaltet. Die
Adresse, an die geladen wird, wird den ersten beiden
Bytes der PRG-Datei entnommen. Die Adresse kann in der
Praxis von etwas unter 32K bis zu 64K reichen, je
nachdem, wie der Programmbereich eingestellt war, als das
Programm abgespeichert (SAVE) wurde. Standardeinstellung
des Programmbereichs ist Anfang der Programm-Page
(32768).

Wird ', gerätenummer' nicht angegeben, gilt die
Voreinstellung 8.

Kommt hinter dem Namen der Datei noch irgendein Wert, der
nicht durch Komma abgetrennt ist, so wird er ignoriert.
Dies ermöglicht das Laden aus dem Bildschirm-Listing des
Directory.


load , "name"

Komma nach LOAD bewirkt, daß das Programm automatisch an
den derzeit eingestellten Programmbereich-Anfang geladen
wird (40/41). Da dabei ein Link-Lauf nötig ist, dürfen
Maschinenprogramme nicht mit Komma geladen werden.

Diese Option ist u.a. für das Laden von BASIC-4-
Programmen nötig.


load ¶ adresse , "name"

Wird hinter ¶ oder @ eine Adresse angegeben, so wird ab
dieser Adresse in den Speicher geladen. Diese Adresse
kann aus dem gesamten logischen Adressraum von 128K
genommen werden. Bei Werten über 32K wird die richtige
von den drei möglichen 32K-Pages eingeschaltet. Bei
Werten unter 32K wird für den Fall der Überlappung die
Programm-Page eingeschaltet. Dies ist von der logischen
Adresse her verwirrend, da nach logisch 32767 in 65536
weitergeladen wird. Da aber wegen der möglichen
Verlängerung des Programmspeichers in den Adressraum
unter 32K ein Programm ab einer Adresse unterhalb 32K
ladbar sein muß, ist diese Abweichung von der logischen
Adressfolge nötig. Andererseits macht es wenig Sinn, mit
dem Laden einer Datei unterhalb des Bildschirms zu
beginnen und dann im Bildschirm fortzusetzen.
  __________________________________________________________________________
load ¶ % adresse , "name"

Da theoretisch durch SAVE auch ein nach unten
veriängerter Variablenbereich abgespeichert werden kann
(physikalisch z.B. 30000 - 60000), wurde für LOAD eine
entsprechende Option vorgesehen: Durch '%' nach dem
Klammeraffen wird nicht der PRG-, sondern der VAR-Bereich
eingeschaltet. Dadurch werden physikalische Adressen
oberhalb von 32K in den Variablenbereich geladen.

Für den Bildschirmbereich existiert keine derartige
Möglichkeit. Der Bildschirm wird also nur eingeschaltet,
wenn die hinter ¶ angegebene Anfangsadresse im Bereich
2^15 - 2^16 liegt.


load ; "name"

Beim Laden von Programmen in den Programmbereich wird der
Programmende-Zeiger (248/249) hinter das zuletzt geladene
Byte gesetzt. Dies ist für Overlay wichtig, wenn ein so
nachgeladenes Programm abgepeichert oder geändert werden
soll.

Da für Sonderanwendungen aber auch Maschinenprogramme in
den PRG-Bereich geladen werden können, kann durch ';'
zwischen LOAD und NAME verhindert werden, daß der
Programm-Ende-Zeiger verändert wird.

Beachten Sie, daß in BASIC-4 der Programm-Ende-Zeiger
(42/43) bei LOAD im Direktmodus geändert wurde, bei LOAD
aus dem Programm aber nicht!


LOAD im Programm:

Durch LOAD im Programm können sowohl BASIC-Programme
nachgeladen werden (Overlay), als auch Maschinenprogramme
bzw. beliebige Speicherinhalte auf bestimmte Adressen
gelegt werden.

Nach LOAD von BASIC-Programmen läuft das Programm mit der
ersten Anweisung des neuen Programms weiter (s. Overlay-
Erläuterungen im 8032-Handbuch).

Im Gegensatz zu BASIC-4 wird aber das Programm hinter der
LOAD-Anweisung fortgesetzt, wenn


· nicht in den PRG-Bereich geladen wird (load ¶ adr)
· ';' zwischen LOAD und NAME steht
· das Ende des geladenen Programms vor (40/41) liegt

In diesen Fällen kann also der bisher nötige ON-Verteiler
am Anfang des Programms entfallen.
  __________________________________________________________________________
Beispiele

load "programm"        'programm' ab der abgespeicherten
                       Adresse laden
load , "programm"      'programm' ab PRG-Speicher-Anfang
                       (40/41) laden
load "programm",9      'programm' von Gerät 9 laden

load "programm" prg    'prg' vom directory-listing stört
                       nicht
load ; "masch"         laden ohne Zeiger verändern und
                       weiter nach LOAD
load ¶ 32768 , "bild"  'bild' ab Bildschirm-Anfang laden

load ¶ 100000 , "block"'block' ab 100000 (Variablen-
                       Page) laden
load ¶ 25000, "system" 'system' ab 25000 (BS-Bereich)
                       laden (falls 32768 überschritten
                       wird, weiter in PRG)
load ¶ % 30000 "variab"in VAR-Bereich laden, falls 32768
                       überschritten wird
  __________________________________________________________________________
3.2 SAVE

Zweck

SAVE speichert ein BASIC-Programm bzw. einen beliebigen
Speicherbereich in eine PRG-Datei auf Floppy ab. Dabei
wird die Startadresse in den ersten beiden Bytes
vermerkt.


Format

SAVE ¶ vonadresse , bisadresse , "laufwerk-name" ,
gerätenummer

Anmerkungen

Im Normalfall wird ¶ vonadresse,bisadresse,' nicht
angegeben. Dann wird das derzeit im Speicher stehende
BASIC-Programm auf Diskette abgelegt.

Wird zwischen SAVE und dem Namen ein Komma angegeben, so
wird automatisch nach dem Abspeichern VERIFY
durchgeführt.

Die Gerätenummer wird als 8 angenommen, wenn sie nicht
angegeben wird.

Folgt auf den Namen ein Ausdruck, der nicht durch Komma
getrennt ist, so wird er ignoriert. Dies ermöglicht die
problemlose Entnahme des Namens aus dem Directory-Listing
auf dem Bildschirm.

Wird ¶ vonadresse , bisadresse , ' angegeben, so wird der
Speicherbereich von einschließlich 'vonadresse' bis
ausschließlich 'bisadresse' abgelegt.

Wenn Anfangs- und Endadresse im selben 32K-Bereich liegt,
wird die betreffende Page eingeschaltet und unter der
jeweils zutreffenden physikalischen Anfangsadresse
abgelegt.

Liegen dagegen Anfangs- und Endadresse in verschiedenen
Pages, so muß die Anfangsadresse kleiner als 32K sein,
also im gemeinsamen Bereich liegen. Je nachdem, ob die
Endadresse im Bereich 32-64 K oder 64-96 K oder 96-128 K
liegt, wird beim Abspeichern der ROM oder PRG oder VAR -
Bereich eingeschaltet.

Überlappen über 64K bzw. 96K ist also nicht möglich.

Bitte beachten Sie, daß ein so abgespeicherter Bereich
(Anfangsadresse unter 32K) durch LOAD ohne Adressangabe
immer in den PRG-Bereich geladen wird!

Beispiele

save "0:programm"          'programm' auf Gerät 8 ablegen

save , "0:programm"        abspeichern und sofort verifizieren

save "0:programm",9        auf Gerät 9 ablegen

save "0:programm" prg      'prg' stört nicht

save ¶                     Bildschirminhalt unter 'bild'
32768,34768,"0:bild"       ablegen

save ¶                     Gesamten Variablenbereich
98304,131056,"0:varia"     abspeichern (Dump)

save ¶                     Nach unten verlängerten
30000,100000,"0:varia"     Variablenbereich abspeichern
  __________________________________________________________________________
3.3 VERIFY


Drei Eigenschaften von VERFIY wurden gegenüber 8032
geändert:

Die Ersatzadresse ist 8, wenn nichts angegeben wird.

Wie bei LOAD und SAVE stören Ausdrücke nach dem Namen
nicht, wenn sie nicht durch Komma getrennt sind.

VERIFY ERROR wird bereits bei der ersten Nicht-
Übereinstimmung gemeldet und der Zeiger auf die
physikalische RAM-Adresse in 201/202 übergeben.

VERIFY übernimmt die Einstellung auf ROM PRG bzw. VAR
ohne sie zu verändern. Diese Einstellung wird durch LOAD
/ SAVE POKE / PEEK / SYS / WAIT definiert. Wenn also nach
dem zugehörigen SAVE oder LOAD einer der aufgeführten
Befehle einen anderen Bereich eingestellt hat, wird
VERIFY den falschen Bereich vergleichen, sofern die
Adressen über 32768 liegen.
  __________________________________________________________________________
3.4 LIST


Zweck

LIST gibt ein BASIC-Programm auf Bildschirm aus. Dabei
werden Blanks zwischen Anweisungen und bestimmten Zeichen
eingefügt, um das Listing lesbarer zu machen. Eine
besondere Art von LIST druckt jede Anweisung in eine neue
Zeile.


Format

LIST von - bis   normales Listing
LIST , von - bis Komma hinter LIST bewirkt, daß jede
                 Anweisung in eine eigene Zeile gedruckt
                 wird

Anmerkungen

Die Blanks im Listing werden bei Übergabe einer Zeile
durch RETURN wieder entfernt.

Bei Verwendung von LIST mit Komma auf dem Bildschirm
müssen Sie bedenken, daß Zeilen mit mehr als 25
Anweisungen (durch Doppelpunkt getrennt) nicht mehr durch
RETURN übernommen werden können, da sie nur zum Teil auf
dem Bildschirm stehen.

Im Gegensatz zu BASIC-4 bricht LIST im Programm nicht den
Programmlauf ab; das Programm läuft also nach LIST
weiter.

Durch folgende Anweisungen können Sie ein Programm-
Listing auf Drucker ausgeben:

open 4,4 : cmd 4 :    (Mit oder ohne Komma hinter
list,                 LIST)

print#4 : close 4

Ähnlich können Sie auch ein Listing in eine Floppy-Datei
schreiben. Anstatt 'open 4,4' benötigen Sie nur 'open
2,8,2,"0:listing,s,w'"(z.B.).
  __________________________________________________________________________
3.5 DELETE

Zweck

Durch DELETE kann ein Programm-Zeilen-Block gelöscht
werden. Die Angabe des Zeilenbereichs erfolgt wie bei
LIST.


Format

DELETE zeilenbereich

Abkürzung: deL


Anmerkungen

DELETE ist zwar im Programm nicht gesperrt, darf aber
nicht verwendet werden. Der Name kann in künftigen
Versionen geändert werden, bzw. das Token aus der Liste
entfernt werden.


Beispiele

delete 100-200     Zeilen 100 bis 200 löschen

deL100-200         Abkürzung

deL 100-           Zeilen 100 bis letzte Zeile löschen

deL -200           Erste Zeile bis Zeile 200 löschen

deL                Alle Zeilen löschen (wie NEW, aber
                   ohne CLR!)
  __________________________________________________________________________
3.6 FRE:

Zweck

FRE übergibt die Anzahl der freien Bytes im Variablen-
bzw. im Programmspeicher. Beim Variablenspeicher wird
vorher Garbage Collect durchgeführt.


Format

A = FRE(M)

m gleich 0           Programm
m ungleich 0         Variabie

FRE ist eine Funktion, die an beliebiger Stelle eines
numerischen Ausdrucks vorkommen kann.

Anmerkungen:

Bei FRE(0) wird die Differenz zwischen Programmabergrenze
und Stackuntergrenze ausgegeben, also (239/240) -
(248/249).

Bei FRE(1) wird zuerst Garbage Collect durchgeführt und
dann die Differenz zwischen Untergrenze
Stringarbeitsbereich (48/49) und Obergrenze Felder
(46/47) berechnet.

Beachten Sie, daß FRE(I) wegen Garbage Collect sehr
zeitintensiv sein kann (bis zu einigen Sekunden).


Beipiele:

?fre (0)      freie Bytes im Programmspeicher drucken

?fre (1)      freie Bytes im Variablenspeicher drucken
  __________________________________________________________________________
3.7 CLR

Zweck

Hinter CLR können im Gegensatz zu BASIC-4 Variabien-Namen
angegeben werden. Diese Variablen werden dann aus dem
Speicher gelöscht. Dies gilt auch für Felder.


Format

CLR variablenliste

Die 'variablenliste' enthält durch Komma getrennt
Variablennamen. Felder müssen durch '(' gekennzeichnet
werden.


Beispiel

clr a , b( , c$ , d$(, die einfachen Variablen a,c$ und
f%(                    e%, sowie die Felder b(, d$( und
                       f%( aus dem Variablenspeicher
                       löschen

clr                    ohne Variable: ganzen
                       Variablenspeicher löschen, sowie
                       den BASIC-Stack und den DATA-Zeiger


Anmerkungen

CLR ohne Variable wirkt wie CLR im BASIC-4. Zusätzlich
wird ON-ERROR gelöscht.

CLR mit Variablen löscht nur die angegebenen Variablen.
Alle anderen bleiben erhalten. Bei Stringvariablen wird
der Inhalt und die Verwaltungs-Information gelöscht.

Vor allem bei Feldern wird dies einen beträchtlichen
Speicherplatzgewinn im Variablenbereich bringen.

Da beim Löschen von Variablen Felder verschoben werden
müssen, entspricht der Zeitbedarf dem beim Einfügen von
Variablen. (Bei sehr vielen Variablen und Strings ist mit
Zeiten im Sekundenbereich zu rechnen.)
  __________________________________________________________________________
3.8 REDIM: Felder verlängern oder verkürzen

Zweck

Eindimensionale (nicht mehrdimensionale) Felder können
durch REDIM verlängert oder verkürzt werden. Die Inhalte
bleiben dabei erhalten, soweit sie nicht in zu löschenden
Elementen stehen.


Format

wie DIM

Anmerkungen

Bei Angabe eines mehrdimensionalen Feldes erfolgt BAD
SUBSCRIPT ERROR.

Bei eindimensionalen Feldern kann REDIM die Anweisung DIM
ersetzen, noch nicht definierte Felder dürfen also durch
REDIM dimensioniert werden.

Der Zeitbedarf für die Änderung der Feldgröße liegt bei
dem von DIM oder etwas höher.

Wird ein Feld durch REDIM verkleinert, so wird sowohl bei
numerischen als auch bei String-Feldern der gewonnene
Platz völlig freigegeben.
  __________________________________________________________________________
3.9 RESTORE

Zweck

RESTORE setzt den DATA-Zeiger für READ auf eine bestimmte
BASIC-Zeile bzw. ein bestimmtes Element ab einer Zeile
zurück. Dadurch können DATA's wesentlich differenzierter
behandelt werden, als bei BASIC-4.


Format

RESTORE zeile , element

zeile:          BASIC-Zeilennummer als Konstante

element:        1 ... 255; kann entfallen, Ersatzwert
                ist 1


Anmerkungen

Wird eine Zeilennummer angegeben, muß die Zeile
existieren, sonst erfolgt UNDEF'D STATEMENT ERROR. Die
angegebene Zeile muß aber nicht unbedingt eine DATA-
Anweisung enthalten. Wenn nicht, wird einfach die nächste
Zeile mit DATA-Anweisung gesucht.

Das gewünschte Element muß nicht in der angegebenen Zeile
stehen. Das Element kann ab einer beliebigen Zeile
gesucht werden. Lediglich die Begrenzung von 255
Elementen ist zu beachten.

Wird ein nicht vorhandenes Element verlangt, erfolgt OUT
OF DATA ERROR.

Beispiele

restore 100      DATA-Zeiger auf Zeile 100 setzen

restore 100,20   auf das 20-te DATA-Element ab Zeile
                 100
restore 20       nicht zulässig: SYNTAX ERROR
  __________________________________________________________________________
3.10 Maschinen-Adressen (POKE, PEEK, SYS, WAIT)

Der 8096 verfügt über insgesamt 128K Speicher. Der
Prozessor 6502 kann aber nur 64K gleichzeitig
adressieren. Deshalb muß das Betriebssystem die jeweils
benötigten Speicherbänke einschalten. Um auf BASIC-Ebene
dennoch eine eindeutige Zuordnung von Speicherzellen zu
Adressen zu haben, wurde für die Befehle POKE, PEEK, SYS
und WAIT der zulässige Adressbereich erweitert und
folgende Zuordnung von logischen (BASIC) Adressen zu
Speicherbänken gewählt:

12SK--------------------------------
       Variablenspeicher       (VAR)
96K --------------------------------
       Programmspeicher        (PRG)
64K --------------------------------
       ROM-Bereich             (ROM)
32K --------------------------------
       Betriebssystem          (LOS)
0K  --------------------------------

Dieses Speicherschema ist an anderer Stelle ausführlicher
dargestellt.

Bitte beachten Sie, daß für die Funktion USR( ) diese
Konvention nicht gelten kann, da ihre Zieladresse in den
Zellen 1 und 2 enthalten ist, also nur 64K adressieren
kann!
  __________________________________________________________________________
3.11 Getstring (GET$)

Zweck

GETSTRING liest von einem Peripheriegerät maximal 255
beliebige Kodes (Zeichen) in eine Stringvariable.

Dabei ist die Anzahl der zu lesenden Bytes oder ein
beliebiges Endezeichen (z.B. Carriage Return) vorzugeben.
Ein spezieller Aufruf holt sich die Anzahl der zu
lesenden Bytes automatisch aus dem ersten gelesenen
Bytes, wodurch verzeigerte Dateien sehr einfach und
schnell gelesen werden können.

Durch diese Eigenschaften wird GET$ in vielen Fällen
INPUT# vorzuziehen sein.

Format

GET$ logische adresse , stringvariable , max , ende ,
ignor

logische adresse; Byteausdruck

Durch OPEN bzw. DOPEN muß einer logischen Adresse die
Datei zugeordnet worden sein, aus der gelesen werden
soll. Falls die Datei nicht geöffnet wurde, wird FILE NOT
OPEN ERROR gemeldet.


stringvariable : Einfache oder indizierte Stringvariable

Einfache oder indizierte Stringvariable. In diese
Variable wird der eingelesene String ohne die
Beschränkungen des INPUT übernommen. Maximal sind 255
Zeichen möglich. Prinzipiell wird jeder Code, also auch
0, 13, Komma, Doppelpunkt übernommen, es sei denn er ist
bei 'ende' als Ende-Code definiert.


Logische Adresse und Stringvariabie müssen angegeben
werden. Falls keine weiteren Angaben hinter der Variablen
folgen, wird angenommen, daß 255 Zeichen gelesen werden
sollen, und nur bei Dateiende (st = 64) oder
Zeitüberschreitung (st = 2) abgebrochen werden soll.
Endezeichen ist nicht definiert, also wird jeder der 256
möglichen Codes von 0 - 255 eingelesen.

max : Maximale Anzahl Bytes; Byteausdruck; Ersatzwert ist
255

'max' gibt an, wieviele Zeichen maximal übernommen werden
sollen.

Angabe kann entfallen; 'max' ist dann 255 (Ersatzwert).
Entfallen heißt, daß entweder kein weiterer Parameter
mehr kommt, oder daß zwei Kommas unmittelbar aufeinander
folgen.

Bei max = 0 wird das erste gelesene Byte als Längenzeiger
interpretiert und soviele Bytes eingelesen, wie der ASC-
Wert des ersten Bytes ausmacht. Bei der Anzahl der zu
lesenden Bytes wird das Längen-Byte nicht mitgerechnet.

Bitte beachten Sie, daß bei Algorithmen, die die Länge
aus anderen Quellen nehmen, und dann diese Länge bei
'max' angeben, für Länge 0 eine Abfrage erforderlich ist,
die verhindert, daß in diesem Fall GET$ gerufen wird.

Abbruch wegen Empfang der maximalen Zeichenanzahl wird
durch Bit 3 im Status vermerkt (8 and st ist wahr).
  __________________________________________________________________________
ende : Ende - Code; Byteausdruck; Ersatzwert ist 'kein
Abbruchcode'

'ende' definiert einen Abbruch-Code. Wird dieser Code
empfangen, so wird die Übertragung abgebrochen. Der
Abbruch-Code selbst wird nicht mehr in den String
übemommen. Abbruch wegen Empfang des Ende-Codes wird
durch Bit 4 im Status vermerkt (16 and st ist wahr).

Wenn 'ende' nicht angegeben wird, kann jeder Code von 0
bis 255 eingelesen werden.

ignor: zu ignorierender Anfangscode; Byteausdruck;
Ersatzwert ist 'kein Code'

Dieser Code wird ignoriert, wenn er als erster Code
empfangen wird. (Z.B. 34 für Anführungszeichen
unterdrücken).

Das ignorierte Zeichen zählt nicht zur Anzahl der
eingelesenen Zeichen (max). 'ignor' darf nicht
gleichzeitig mit max=0 auftreten (ILLEGAL QUANTITY).

Abbruchkriterien

Die Übertragung in den String wird grundsätzlich nur dann
abgebrochen, wenn der Status (st) von 0 verschieden ist.

Insgesamt existieren 4 verschiedene Abbruchgründe. Zwei
werden vom Betriebssystem geliefert und zwei von
GETSTRING selbst:


Betriebssystem-Abbruchkriterien

 2 and st        Zeitüberschreitung beim
                 Lesen
64 and st        Ende der Datei

GETSTRING-Abbruchkriterien

 8 and st        Maximallänge erreicht
16 and st        Endecode empfangen

(2 and st ist wahr) kommt vor, wenn entweder das
Dateiende (64 and st) übersehen wurde, oder die Datei
nicht ordnungsgemäß geöffnet wurde, oder ein Lesefehler
bei der Floppy auftritt oder die Floppy aus sonstigen
Gründen keine Daten liefert.

Wenn dieser Wert auftritt, enthält die Stringvariabie
normalerweise den Code 13 (Carriage Return). Dieser Code
wird vom Betriebssystem als Ersatzwert übergeben. Wenn
allerdings gleichzeitig 13 als Abbruchkriterium
eingestellt ist, ist die Stringvariable leer.

Bei (64 and st ist wahr) steht das letzte gültige Zeichen
in der Variablen, falls es nicht das voreingestellte
Ende-Zeichen ist.

Bitte beachten Sie, daß mehrere Statuswerte gleichzeitig
auftreten können. Z.B. kann am Dateiende gleichzeitig der
Wert 64 und 16 auftreten. 'print st' würde dann 80
melden!
  __________________________________________________________________________
Anwendung

GETSTRING ist INPUT immer dann vorzuziehen , wenn die
Delimiter Komma, Doppelpunkt und CR nicht wirken sollen
oder wenn der Code 0 eingelesen werden soll.

Spezialanwendungen ergeben sich, wenn Datenfelder
bekannter Länge ohne Abschlußode gelesen werden sollen,
oder ein beliebiger Ende-Code vorgegeben werden soll.

Durch max=0 können durch Zeiger verkettete Bytefelder
gelesen werden, sofern die einzelnen Elemente nicht 255
Bytes überschreiten.


Syntax-Möglichkeiten:

get$ la  ,str-var , max , ende , ignor
get$ la  ,str-var ,     , ende , ignor
get$ la  ,str-var , max ,      , ignor
get$ la  ,str-var ,     ,      , ignor
get$ la  ,str-var , max
get$ la  ,str-var

Beispiele

open               bzw dopen ¶5,"lesedatei"
5,8,2,"lesedatei"
get$ 5,a$"13,34    liest einen String wie INPUT, d.h. 13
                   ist Endezeichen (CR) und 34 am Anfang
                   wird ignoriert (Anführungszeichen). Die
                   Endezeichen Komma und
                   Doppelpunkt, sowie Code 0 bewirken aber
                   nicht Abbruch der Übernahme in a$.

get$ 5,a$255       Bytes werden bedingungslos in a$
                   übernommen

get$ 5,a$,16       genau 16 Bytes werden in a$ übernommen

for i = 1 to    10 10 Elemente des Stringfeldes a$( ) werden
get$ 5,a$(i),0     übernommen. Die Länge der einzelnen
                   Elemente wird
next               aus dem Byte vor dem jeweiligen 'Satz'
                   genommen. Eine derartige Struktur wird
                   durch das folgende Programm aufgebaut:

open 5,8,2,"0:lesedatei,s,w"
for i = 1 to 10
print#5, chr$(len(a$(i@» a$(i);
next
  __________________________________________________________________________
3.12 lnstring (INSTR)

Zweck

Instring sucht den Inhalt einer Stringvariable nach einer
vorgegebenen Zeichenkette ab. Dabei ist die Suchrichtung,
der Suchanfang, sowie Suche auf Ubereinstimmung oder
Abweichung wählbar.


Forrnat

INSTR( zeichenkette , stringvariabte, spalte ,
betriebsart )


Zeichenkette : Zeichenkette, nach der im String gesucht
wird.

Einfache oder indizierte Stringvariable; Konstante;
Stringausdruck


stringvariable : Zu durchsuchender String.

Einfache oder indizierte Stringvariable; Stringausdruck


spalte : Nummer des Zeichens in stringvariable, ab dem
gesucht werden soll.

Byteausdruck (0 - 255)     1. Zeichen = 1

Angabe kann entfallen, 'spalte' ist dann 0

'spalte' = 0 : Automatisch je nach Betriebsart 1 oder
Länge von 'string-variable'

Wenn 'spalte' grösser als len(stringvariable) ist, so
wird 'spalte' gleich der Länge von 'stringvariable'.

Betriebsart : Byteausdruck: p (Angabe kann entfallen, p
ist dann 0)

p=0       von links nach rechts auf Übereinstimmung
          suchen
p=l       von links nach rechts auf Abweichung suchen
p=2       von rechts nach links auf Übereinstimmung
          suchen
P=3       von rechts nach links auf Abweichung suchen
  __________________________________________________________________________
Beispiele

a=instr(s$,q$)

Übergibt in a die Spalte, in der s$ in q$ gefunden wurde.

a=instr(s$,q$,0,0)

Wie oben

print instr(s$(s),q$,10)

Druckt die Spalte aus, in der s$(s) in q$ ab Spalte 10
gefunden wurde.

s=instr(s$,q$(j),s-1,2)

Übergibt in s die Spalte, ab der s$ in q$(j) ab s-1 (von
rechts nach links) gefunden wurde. (Sinvoll in Schleifen,
wenn nach allen Übereinstimmungen gesucht werden soll.)

s=instr(" ",q$,0,3):q$=left$(q$,s)

Übergibt in s die Spalte, ab der in q$ von rechts nicht
mehr gefunden wurde und schneidet anschließend alle
nachfolgenden Blanks in q$ ab.

if instr(s$,q$,s)=0 then print"nicht gefunden"

Druckt 'nicht gefunden' aus, wenn INSTR(...) gleich 0
ist.

Fehlermeidungen

illegal quantity error     Spalte muss Wert zwischen 0
                           und
z.B. instr(n$,q$,300,0)    255 haben

Keine Fehlermeidung        aber falsche Ausgabewerte
z.B. instr(n$,q$,0,5)      Betriebsart muss Wert zwischen
                           0 und 3 haben

syntax error               leere Parameter sind nicht er-
z.B. instr(n$,q$"3)        laubt.

type mismatch error        erster und zweiter Parameter
z.B. instr(n$,q)           müssen String sein.
  __________________________________________________________________________
3.13 Midstring (MIDSTR)

Zweck

Midstring setzt eine Zeichenkette (String) in einen
anderen String ab einer frei wählbaren Stelle ein. Dabei
wird der alte Inhalt des Strings ab dieser Stelle
überschrieben.

Format

MIDSTR(strvar , spalte ) = zeiket

strvar:    Stringvariable, in die die Zeichenkette
           eingefügt werden soll;Einfache oder
           indizierte Stringvariabie

zeiket:    Zeichenkette, die in die Stringvariabie
           eingefügt werden soll; Stringausdruck

spalte:    Nummer des Zeichens in 'strvar', ab dem
           'strvar' durch 'zeiket' überschrieben werden
           soll; Byteausdruck.

Wenn der Wert von 'spalte' größer ist als die Länge von
'strvar', wird die Länge entsprechend vergrößert. Im
Zwischenraum zwischen 'strvar' und 'zeiket' stehen dann
im neuen String irgendwelche Zufallszeichen.

Bei spalte=0 wird nichts ersetzt (Abbruch).


Beispiele

a$="0123456789-
11
midstr                 Ersetzt in a$ ab Spalte 3
(a$,3)="xyz"           die Zeichen durch 'xyz'
print a$
0xyz56789

midstr                 Ersetzt in b$ das Zeichen an
(b$,w)=chr$(q)         Spalte w durch das Zeichen,
                       das sich aus chr$(q) ergibt.

a$="123"
midstr(a$,8)="-
89"
?a$
123xxxx89              Die Stellen x enthalten
                       undefinierte Codes



Fehlermeidungen

illegal quantity    spalte' kleiner als 0 oder größer als
error               255
string too long     Neuer String 'str-var' wäre länger
error               als 255 Zeichen
  __________________________________________________________________________
3.14 ASC / CHR$

Zweck

CHR$ wandelt einen Zahlenwert in einen 1-5 Byte-String
um, ASC wandelt einen so erzeugten String wieder in einen
Zahlenwert um.

Zusätzlich zu den alten Möglichkeiten von ASC und CHR$,
die auf 1 Byte be-
schränkt waren, können nun also alle vorkommenden
Zahlenwerte mit minimalem Platzbedarf abgespeichert
werden.


Format

A = ASC(string , spalte , länge)

A$ = CHR$(zahl , länge)

string       Stringausdruck
zahl         numerischer Ausdruck
spalte       1...255; kann entfallen (mit 'länge'),
             Ersatzwert ist 1
Länge        1...5; kann entfallen, Ersatzwert ist 1


Anmerkungen:

CHR$ packt eine beliebige Zahl in einen String mit der in
'länge' angegebenen Länge.

Folgende Wertebereiche sind abhängig von der Länge
eindeutig wandelbar:


Länge        Wertebereich

1            0...255            (2 hoch 8 - 1)
2            0...65535          (2 hoch 16 - 1)
3            0...16777215       (2 hoch 24 - 1)
4            0...4294967275     (2 hoch 32 - 1)
5            Gleitkommabereich

Länge 5 überträgt eine Zahl im Speicherformat (5 Bytes)
in den String. Dadurch kann jede Gleitkommazahl gepackt
werden.

Bei den anderen vier Längen ist darauf zu achten, daß der
Wertebereich nicht überschritten wird, sonst wird die
Funktion durch ILLEGAL QUANTITY ERROR abgebrochen.

ASC wandelt die oben angegebenen Wertebereiche eindeutig
vom gepackten Format in Zahlen zurück. Voraussetzung ist
natürlich, daß die angegebenen Längen bei CHR$ und ASC
übereinstimmen.

Bei Gleitkomma wird durch CHR$ die Zahl nicht
normalisiert. Deshalb können beliebige Bitmuster in
beiden Richtungen gewandelt werden.

Die Reihenfolge der Bytes bei Länge (2-4) ist high - low.

Bei Länge 1-4 können bei CHR$ auch negative Zahlen
eingegeben werden. Diese werden aber durch ASC in ihr
Komplement überführt:

z:     -2 hoch (länge * 8 - 1)   ...    -1
wird durch     z$ = chr$(z,länge) : x = asc (z$,1,länge)
abgebildet in
x:      2 hoch (länge * 8 ) + z
  __________________________________________________________________________
spalte

ASC hat gegenüber der 8032-Version noch den Parameter
'spalte' bekommen. Dadurch wird das früher immer
benötigte MID$ überflüssig. Der Hauptvorteil davon liegt
in einer Zeitersparnis, da nun kein Zwischenstring mehr
angelegt werden muß:

     ASC(string,spalte) ersetzt ASC(MID$(string,spalte))

CHR$ hat keinen entsprechenden Parameter. Hier müssen Sie
durch

     MIDSTR(A$,spalte) = CHR$(string,länge)

den Einbau an eine bestimmte Spalte in einem String
erzielen.

Beipiele:

? asc(a$,5)         Byte an 5-ter Spalte von A$ in Zahl
                    umwandeln

print#2,chr$(a,5);  Inhalt von a als 5 Bytes in Datei
                    schreiben

get$2,a$,5:         5 Bytes aus Datei holen
a=asc(a$,G,5)       und in Zahl zurückwandeln


Weiterführende Hinweise

Im Handbuch des 8032 ist nach den Stringfunktionen ASC
und CHR$ angedeutet, daß damit in Zusammenhang mit
Stringfeldern sogenannte Bytefelder aufgebaut werden
können.

Durch die neuen Eigenschaften von ASC und CHR$ können nun
nicht nur Strukturen mit Basis 1 Byte, sondern mit bis zu
4 Bytes aufgebaut werden.

Das gleiche Beispiel soll nochmal etwas abgewandelt
gebracht werden:

Sie haben 1000 Elemente (Kunden), für jedes Element
maximal 85 Ereignisse (Rechnungen) und jedes Ereignis
benötigt 3 Bytes zu seiner Darstellung (7-stellige
Rechnungsnummer). Im Mittel haben Sie 5 Ereignisse pro
Kunde.

Zur Darstellung dieser Daten mit Hilfe eines Stringfeldes
benötigen Sie 1000 Elemente * 5 Ereignisse/Element * 3
Bytes/Ereignis = 15 000 Bytes zuzüglich 5000 Bytes für
die Verwaltung des Stringfeldes.

Würden Sie ein zweidimensionales Gleitkommafeld mit
1000*85 Elementen verwenden, bräuchten Sie 425 000 Bytes.
(Was selbst bei diesem Rechner noch nicht möglich ist.)
  __________________________________________________________________________
3.15 CATALOG$

Zweck

Übernimmt das Directory der Floppy in ein Stringfeld.

Format

CATALOG$ string, gn , lw , muster , mode

string: Stringfeld mit Anfangsindex

Pro Element des angegebenen Stringfeldes wird ein
Directory-Eintrag abgelegt. Das Format wird weiter unten
beschrieben. Der angegebene Index bezeichnet das erste zu
verwendende Element. In diesem ersten Element wird der
Name der Diskette usw. abgelegt.

gn: Gerätenummer; Byteausdruck; Ersatz = 8

lw: Laufwerk; 0 oder 1; Ersatz = 0

muster: Gemäß bekanntem DOS-Kommandostring; Ersatz = leer
- Ans Floppy wird nur '$ lw' ohne Doppelpunkt gesendet,
wodurch ganzes Directory gelesen wird.

mode: Ersatz = 0

     0:Nur Name übernehmen und nicht auf 16 Bytes
auffüllen
     1:Nur Name und Typ übernehmen
     2:Name, Typ und belegte Blöcke übernehmen

Format des String-Inhaltes:

Name,     Typ,     Blockanzahl
16        1        5

namenamenamenameT65000
1234567890123456789012

Der Name wird linksbündig eingetragen und bei mode =1,2
rechts mit Blanks auf 16 Zeichen aufgefüllt.

Der Typ wird als 'p s r' oder 'u' angegeben. Ist im
Directory das Ungültigkeitsmerkmal '*' gesetzt, so wird
der entsprechende Buchstabe geshiftet (Bit 7 gesetzt).
Dies kann durch 'AND 128' abgefragt werden.

Die erste Zeile (Anfangsindex) enthält

Name , id , dos , freie Blöcke
namenamenamenameid2c65000
1234567890123456789012345
  __________________________________________________________________________
Anmerkungen

Jeder Directory-Eintrag benötigt maximal 22 Bytes + 5
Bytes Stringverwaltung, das ergibt bei 224 Einträgen
(8050) 6075 Bytes (225*(5+22)). Wegen dieses relativ
hohen Betrages wurden die drei Optionen vorgesehen. Bei
mode = 0 beträgt der Platzbedarf bei lauter 16-Byte-Namen
4725 Bytes (225*(5+16)). Hier lohnt also der Einsatz von
CLR bzw. REDIM.

Bei mode=1,2 wird der Name mit Blanks rechtsbündig
aufgefüllt. Bitte beachten Sie, da_ die Blanks z.B. mit
Hilfe von INSTR abgeschnitten werden müssen, ehe Sie über
einen solchen Namen auf die Datei zugreifen können.

Sollen mehr Directory-Einträge gelesen werden, als
Elemente im String-Feld zur Verfügung stehen, wird
abgebrochen. Durch Bit 3 (Wert 8) in ST wird der Abbruch
mitgeteilt. In diesem Fall wird im ersten Element die
Anzahl der freien Blöcke nicht mitgeteilt, da sie noch
nicht gelesen wurde.

Wenn während des Einlesens des Directory timeout auftritt
(Status 2), wird mit FILE DATA ERROR abgebrochen.


Beispiel

dim a$(100)    maximal 100 Directory-Einträge vom
               Laufwerk 0, Gerät 8
catalog$ a$(0) lesen; nur die Namen übernehmen, kein
               einschränkendes Muster
  __________________________________________________________________________
3.16 IF THEN ELSE

Zweck

Die IF THEN Anweisung von BASIC-4 mit der nur eine
einseitige Verzweigung möglich war, ist durch ELSE zur
beidseitigen Verzweigung erweitert worden.

Format

IF logischer Ausdruck THEN Ja-Zweig : ELSE Nein-Zweig


Anmerkungen

Der Nein-Zweig kann mit ELSE entfallen (kompatibel mit
BASIC-4)

10 if a=b then a=0
20 ...

Der Ja- bzw Nein-Zweig kann eine beliebige
Anweisungsfolge oder eine Zeilennummer sein.

10 if a=b then a=0 : b=b+l : else a=a+l : c=l

20 if a=b then 100 : else 200

Der Ja-Zweig darf leer sein, aber THEN muß immer
vorhanden sein.

10 if a=b then : else a=a+l

20 if a=b : eise a=a+l                     SYNTAX ERROR

THEN darf durch GOTO ersetzt werden, ELSE nicht.

20 if a=b goto 100 : else 200     richtig

20 if a=b goto 100 : goto 200     das zweite goto wird nie
                                  erreicht

20 if a=b goto 100 : else goto 200funktioniert

Die beiden Zweige laufen in der nächsten Zeile zusammen,
sofern kein Sprung in den Zweigen vorkommt.

20 if a=b then a=b : goto 100 : else a=a+l  im ja-Fall wird zu
30 ...                                      Zeile 100 gesprungen

IF THEN und ELSE müssen in einer BASIC-Zeile stehen.
Durch die langen BASIC-Zeilen ist dies aber kaum ein
Nachteil.

ELSE ohne IF THEN wird wie REM mit allen folgenden
Anweisungen ignoriert, es erfolgt aber keine
Fehlermeldung.

10 a=3 : ELSE a=5             a=5 wird ignoriert
  __________________________________________________________________________
Schachteln von IF THEN ELSE Anweisungen ist möglich.

10 if a=b then a=0 :
        if c=d then c=0 :
               else c=c+l :
        else a=a+l :
               if e=f then e=0 :
               else e=e+l :

Diese Einrückungen sollen die Struktur verdeutlichen,
sind aber im Programm nicht möglich. Wenn Sie eine
derartige Struktur eingeben, erhalten Sie durch LIST,10
folgendes Bild:

10 if a=b then a=0
 : if c=d then c=0
 : else c=c+l
 : else a=a+I
 : if e=f then e=0
 : else e=e+l

Durch LIST 10 (ohne Komma) erhalten Sie folgendes Bild:

10 if a=b then a=0 : if c=d then c=0 - else c=c+l : eise
a=a+l if e=f then e= 0 : eise e=e+l

Falls Sie bei sehr langen IF THEN ELSE Zeilen mit einigen
Schachtelebenen die Übersicht verlieren sollten, machen
Sie es wie der Interpreter: Zählen Sie von links nach
rechts für jedes IF ab 0 eins dazu und ziehen Sie für
jedes ELSE wieder eins ab. Sobald Sie bei einem
bestimmten ELSE denselben Zählerstand haben wie bei einem
bestimmten IF, gehören diese beiden zusammen.
  __________________________________________________________________________
3.17 ON ERROR GOTO / EL, EC, EO / RESUME

Nach Abarbeitung von ON ERROR ... springt der Rechner bei
Auftreten eines ERRORs nicht in den Direktmodus und
meldet den Fehler auf dem Bildschirm, sondern springt auf
die angegebene Zeile, wo der Fehler vom Programm aus
behandelt werden kann.

Die reservierten Variablen EL, EC und EO geben Auskunft
über Fehler-Ort und Art. Nach der Fehlerbehandlung kann
durch RESUME die fehlerhafte Anweisung wiederholt oder
die nächste Anweisung oder ein Sprung zu einer beliebigen
Zeile ausgeführt oder eine Direktmodus-Fehlermeldung
gebracht werden.


3.17.1 ON ERROR

Format

ON ERROR GOTO zeilennummer

GOTO ist optional

zeilennummer muß wie bei GOTO eine Konstante sein.

Anmerkungen

Die Variablen EL, EC und EO werden durch ON ERROR
initialisiert.

CLR löscht auch die ON ERROR Definition und die RESUME-
Adresse.

ON ERROR ohne Zeilennummer löscht eine vorangegangene ON
ERROR - Definition.

ON ERROR kann beliebig oft definiert werden - es gilt die
jeweils letzte Definition.

Ist die hinter ON ERROR angegebene Zeilennummer nicht
vorhanden, wird UNDEF'D STATEMENT ERROR gemeldet.


3.17.2    ERROR-LINE, ERROR-CODE, ERROR-OFFSET

Drei reservierte Variable enthalten alle Informationen,
die nötig sind, um einen Fehler identifizieren zu können.
Nach einem Fehler werden die aktuellen Werte vor dem
Sprung auf die Fehlerbehandlungsroutine, die durch ON
ERROR definiert wurde, in diese Variablen geschrieben.

EL (ERROR-LINE) enthält die BASIC-Zeilennummer, in der
der Fehler aufgetreten ist.

EC (ERROR-CODE) enthält die Fehlernummer. Die beiden
Fehlertabellen (Interpreter bzw. Betriebssystem) sind
durchnummeriert. Die Interpreterfehler werden positiv ab
1 gezählt, die Betriebssystemfehler negativ ab -1. (s.
Tabelle)

EO (ERROR-OFFSET) enthält den Offset, der im X-Register
an die Fehlermeldungsroutine übergeben wird. Dieser Wert
kann zwischen 0 und 255 liegen.

ERROR (E0) übergibt als String die Klartextmeidung, die
sonst im Direktmodus erscheinen würde, allerdings ohne
das nachfolgende 'error'.
  __________________________________________________________________________
3.17.3 RESUME

Nach der Fehlererkennung und Behandlung wird durch RESUME
bestimmt, wie das Programm fortgesetzt werden soll.

Format:

RESUME                  fehlerauslösende Anweisung wiederholen
RESUME NEXT             auf die f.A. folgende Anweisung
                        ausführen
RESUME zeilennummer     entspricht GOTO zeilennummer (s.
                        Anmerkung)
RESUME ERROR            Direkt-Modus-Fehlermeldung auslösen

Durch RESUME wird der Interpreterzeiger auf den Anfang
der Anweisung gesetzt, die den Fehler produzierte, bei
RESUME NEXT auf den Anfang der darauf folgenden Anwe
isung.

RESUME zeilennummer springt auf die Zeile mit dieser
Nummer.

RESUME ERROR löst die Direktmodus-Fehlermeldung aus, die
durch ON ERROR verhindert wurde. Dies ist für Fälle
gedacht, wo für die Fehlerbehandlungsrautine
unvorhergesehene Fehler auftreten, was normalerweise
immer möglich ist.

RESUME ERROR ohne vorangegangene Fehlersituation führt zu
einer Endlos-Schleife, die durch STOP unterbrochen werden
kann.

Der STACK-LEVEL bleibt durch RESUME erhalten, sofern er
nicht durch die Fehler-Behandlung verändert wurde.
Erläuterung: Der ON ERROR-Sprung entspricht einem GOTO
von der Fehlerstelte zur Fehlerbehandlung, also verändert
er den Stack-Level nicht. RESUME entspricht ebenfalls
einem GOTO von der Fehterbehardlung zurück zur
Fehlerstelle - mit dem Unterschied, daß nicht die Zeile,
sondern die Anweisung angesprungen wird.

Wenn aber in der Fehlerbehandlung z.B. durch DISPOSE der
Stack manipuliert wurde, wird durch RESUME nicht wieder
der alte Zustand hergestellt.

Tritt während der Fehlerbehandlung ein Fehler auf, so
wird dieser immer im Direktmodus gemeldet, da
anderenfalls Verklemmungen auftreten würden, die eine
Endlasschleife zur Folge haben könnten. Exakt ist der
Zusammenhang folgender: Durch ON ERROR wird ein Flag
gesetzt, weiches die Fehlermeidungsroutine des
Betriebssystems veranlaßt, den Fehler nicht zu meiden,
sondern den ERROR-Sprung durchzuführen. Im selben Moment
wird dieses Flag aber gelöscht, so daß ab nun auftretende
Fehler normal gemeldet werden. Durch RESUME wird dieses
Flag wieder auf 'Nicht-Melden' geschaltet.

Deshalb ist unbedingt erforderlich, daß die letzte
Anweisung der Fehlerbehand-
lung immer RESUME enthält.

Achten Sie darauf, daß ihr Programm nicht von sich aus in
die Fehlerbehandlungsroutine läuft; z.B. RESUME ERROR
läuft dann in eine Endlosschleife.

Läuft Sie in der Fehlerbehandlung auf ein STOP oder END,
gelangt es also in den Direktmodus, so wird wie bei
RESUME das ON-ERROR-Flag wieder gesetzt. Tritt dann nach
einem CONT oder GOTO ein Fehler auf, so wird wieder die
Fehlerbehandlungsroutine gerufen.
  __________________________________________________________________________
3.17.4 ON ERROR Beispiel-Programm

10 REM ON ERROR DEMO
20 ON ERROR 900
100 INPUT "TEILERl";TL
110 PRINT "QUOTIENT=";
 : Q = 10/TL
 : PRINT Q
115 INPUT "TEILER2-1;TL
120 PRINT "QUOTIENT=";
 : Q = 10/TL
 : PRINT Q
125 INPUT "TEILER3";TL
130 Q = 0
 :PRINT "QUOTIENT=tl
 :G = 10/TL
 :PRINT Q
140 INPUT "TEILER4";TL
150 G = 0
 :PRINT "QUOTIENT
 :Q = 10/TL
 :PRINT Q
160 INPUT "TEILER5";TL
170 Q = 0
:PRINT "QUOTIENT=tt
:Q = 10/TL
:PRINT Q
190 GO RO100
899 STOP
900 IF EC 11 THEN RESUME ERROR
910 IF EL = 110 THEN TL = lE-34
 : RESUME
920 IF EL = 120 THEN PRINT "NICHT 0 EINGEBEN!"
 : RESUME 115
930 IF EL = 130 THEN RESUME NEXT
940 IF EL = 150 THEN OPEN 4,4
 :PRINT#4,EL;EC;EO; ERROR (E0)
 :CLOSE 4
 :RESUME NEXT
950 IF EL = 170 THEN PRINT
 :PRINT "DIVISION DURCH 0 IST NICHT MOEGLICH! FEHLER IN
ZEILE"EL
 :PRINT "LIST"EL
 :END
990 RESUME ERROR
READY
  __________________________________________________________________________
Anmerkungen zum Beispiel:

Im Beispiel soll der Fehler DIVISION BY ZERO abgefangen
werden. Insgesamt 6 verschiedene Möglichkeiten der
Fehler-Behandlung sollen damit aufgezeigt werden.

900: Die folgende Fehlerbehandlung kann nur den
Fehlercode 11 (DIVISION BY ZERO) behandeln. Deshalb soll
bei allen anderen Fehlern die Fehlermeidung im Direkt-
modus gebracht werden.

910: Tritt der Fehler in Zeile 110 auf, so wird der
fehlerhafte Teiler auf einen von Null verschiedenen, sehr
kleinen Wert gebracht und die Division mit diesem Wert
wiederholt. Dieses Beispiel steht dafür, daß durch eine
Änderung der Eingangswerte bzw. Umgebungsbedingungen eine
fehlerhafte Anweisung zu einer richtigen Anweisungen
werden kann, also RESUME sinnvoll ist.

920: In diesem Fall wird angenommen, daß der Fehler nur
in Zusammenarbeit mit dem Bediener behoben werden kann.
Er wird aufgefordert, einen anderen Wert einzugeben.
Durch RESUME zeile wird hier ab der auch sonst benötigten
Eingabe wiederholt.

930: Hier wird angenommen, auf die fehlerhafte Anweisung
kann auch verzichtet werden. Deshalb wird einfach mit der
nächsten Anweisung weitergemacht. Denkbar wäre hier auch
die Anweisung 'q=1e34' als Fehlerkorrektur.

940: Dies ist ein Beispiel für eine Fehlerprotokollierung
auf Drucker. Selbstverständlich kann dies auch zusätzlich
zu anderen Maßnahmen gemacht werden.

950: Als Alternative zur englischen Fehlermeidung kann
versucht werden,denFehler ausführlicher und in anderer
Sprache zu meiden. Dazu könnte man auch
alleFehlermeidungen übersetzen, aus DATA in ein
Stringfeld lesen und über EC als Index zugreifen.

990: Für den Fall, daß DIVISION BY ZERO noch in einer
anderen Zeile auftritt, die hier nicht vorgesehen ist,
soll der Fehler analog zu 900 gemeldet werden.


Die Möglichkeiten der ERROR-Behandlung können hier nur
angedeutet werden. Genauso wie Erfahrung dazugehört,
Fehler zu finden und präventiv zu verhindern, so ist es
nicht einfach, denkbare Fehler zu korrigieren, nachdem
sie aufgetreten sind.
  __________________________________________________________________________
3.17.5 Liste der Fehlermeldungen

Einige der Meldungen mit negativem Code sind keine
Fehlermeldungen im laufenden Programm; sie werden also in
Zusammenhang mit ON ERROR nicht auftreten.'*' steht
ersatzweise für CHR$(13) (CR).



   EC        EO        ERROR(E0)

   -1        0         TOO MANY FILES
   -2        14        FILE OPEN
   -3        23        FILE NOT OPEN
   -4        36        FILE NOT FOUND
   -5        50        *SEARCHING
   -6        61        FOR
   -7        65        *LOAD
   -8        70        *VERIFY
   -9        77        DEVICE NOT PRESENT
   -10       95        *FOUND
   -11       102       *OK*
   -12       106       *READY
   -13       114       *ARE YOU SURE?
   -14       129       *? BAD DISK *
   +1        0         NEXT WITHOUT F'OR
   +2        16        SYNTAX
   +3        22        RETURN WITHOUT GOSUB
   +4        42        OUT OF DATA
   +5        53        ILLEGAL QUANTITY
   +6        69        BASIC STACK OVERFLOW
   +7        89        OUT OF MEMORY
   +8        102       UNDEFID STATEMENT
   +9        119       BAD SUBSCRIPT
   +10       132       REDIM'D ARRAY
   +11       145       DIVISION BY ZERO
   +12       161       ILLEGAL DIRECT
   +13       175       TYPE MISMATCH
   +14       188       STRING TOO LONG
   +15       203       FILE DATA
   +16       212       FORMULA TOO COMPLEX
   +17       231       CAN'T CONTINUE
   +18       245       UNDEF'D FUNCTION
  __________________________________________________________________________
3.18 DISPOSE

Zweck

Durch DISPOSE kann der BASIC-Stack manipuliert werden.
Folgende 4 Möglichkeiten sind gegeben:

Format

DISPOSE NEXT
DISPOSE RETURN
DISPOSE level
DISPOSE NEXT,RETURN,NEXT usw


DISPOSE NEXT

Entfernt die Schleife, in der sich das Programm gerade
befindet, vom Stack. Die Laufvariable behält dabei ihren
aktuellen Wert.

Durch diesen Befehl können Schleifen, deren Laufvariable
den Endwert noch nicht überschritten hat, konfliktfrei
verlassen werden.

Wenn im Stack an erster Stelle keine Schleife, sondern
ein Unterprogramm liegt, wird Fehler gemeldet (RETURN
WITHOUT GOSUB ERROR).


DISPOSE RETURN

Entfernt das Unterprogramm, in dem sich das Programm
gerade befindet, vom Stack. Dabei wird der entsprechende
Rücksprung nicht ausgeführt und die Adresse vergessen.

Speziell für Fehlermeidungs-Verfahren nützlich.

Wenn im Stack an erster Stelle kein Unterprogramm,
sondern eine Schleife liegt, wird Fehler gemeldet (NEXT
WITHOUT FOR ERROR).


DISPOSE level

level: Ebene zwischen 1 und n

Der Stack wird auf die durch 'level' angegebene Ebene
gesetzt. Es ist gleichgültig, ob diese Ebene ein
Unterprogramm oder eine Schleife enthält.

DISPOSE 1 leert den Stack vollständig aus, bringt ihn
also in den Zustand, den er nach RUN hat.

Für Fehlermeidungs-Verfahren nützlich.

Wenn level negativ oder größer als 255 oder größer als
der aktuelle Stack-Level ist, wird ILLEGAL QUANTITY
gemeldet.
  __________________________________________________________________________
Beispiele

10 for i = 1 to 1000
 :if a$(i) = "" then dispose next
 :print "erstes leeres eiement hat den index" i
 :else next
 :print "kein leeres element"
30


10 on error 20 : goto 50
20 if el
.
.
.
40 print "unerwartete fehlermeidung:" error (eo) " error
in zeile "ei
42 input "warmstart (j/n)";i$
 :if i$ = "i" then resume 44 : else resume error
44  dispose 1 : goto 1000 : rem warmstart-punkt
  __________________________________________________________________________
3.19 INPUT / PRINT - ¶(zeilespalte)

Zweck

Die Sonderanweisung '¶ (zeile,spalte)1 hinter PRINT bzw.
INPUT bewirkt, daß der Cursor auf diese absolute
Bildschirmpositii)n gesetzt wird.

Format

PRINT ¶ (zeile,spalte) variablenliste

INPUT ¶ (zeile,spalte) variable

zeige:0...24
spalte:0...79

( ¶ ist der Klammeraffe / CHR$(64)

Anmerkungen

Die Angabe von Spalte kann entfallen; Ersatzwert ist 0.

Hinter INPUT ¶ ()  darf im Gegensatz zum normalen INPUT
nur eine einzige Variable kommen. Das sonst übliche
Fragezeichen erscheint dabei nicht auf dem Bildschirm und
der Cursor kann nur ab dem Aufsetzpunkt bis ans Ende der
Zeile bewegt werden. Weitere Einzelheiten sind bei INPUT
bzw INPUT USING zu finden.

Hinter PRINT können mehrere (zeilen,spalten) Angaben
kommen.

Bei Verwendung dieser Anweisung zusammen mit
Bildschirmfenstern können Schwierigkeiten auftreten, wenn
der Cursor außerhalb des Bildschirmfensters aufgesetzt
wird!


Beispiele

print 5 (10,20) "text"          'text' ab Zeile 10, Spalte 20
                                drucken

print ¶ (10) "text"             Zeile 10, Spalte 0

print ¶                         Itextl' ab Zeile 10, Spalte
(10,20)"textl"¶(10,25)"text2"   20,
                                'text2' ab Spalte 25 drucken

print ¶ (10,20);                nur Cursor positionieren

input ¶ (10,40) I$              Eingabe bei Zeile 10, Spalte
                                40 beginnen
  __________________________________________________________________________
3.20 USING

Zweck

USING ist eine Stringfunktion, die mehrere
Variableninhalte gemäß einer Formatvorschrift in einen
String einbaut. Im Gegensatz zu anderen Dialekten ist
USING unabhängig von PRINT realisiert, kann aber
insbesondere auch hinter PRINT verwendet werden.

In Zusammenhang mit INPUT vom Bildschirm hat USING
Sonderbedeutung.


Format:

A$ = USING ( format , var-liste )


USING ist im Direktmodus nicht erlaubt, weil es den
INPUT-Puffer verwendet. (ILLEGAL DIRECT ERROR). Aus
demselben Grund darf ein USING als Argument kein weiteres
USING haben.


format:

Die Format-Angabe ist ein Stringausdruck. In der Praxis
wird es entweder eine Stringvariabie oder eine
Stringkonstante sein. format kann nicht wie manchmal
üblich auf eine BASIC-Zeile verweisen, die die
Formatangabe enthält.

format enthält in Form von Sonderzeichen die
Formatierungsvorschrift für die Inhalte der var-liste.
Diese Zeichen sind nachfolgend beschrieben.


Textfeld:

Apostroph leitet ein Textfeld ein und Schrägstrich setzt
es fort. Apostroph und Schrägstrich bilden jeweils ein
Zeichen eines Textfeldes.

"'////////'/////``/" definiert 4 Textfelder mit den
Längen 9, 6, 1, 2
 123456789123456112

Text wird linksbündig ins Feld gedruckt und rechts mit
Blanks aufgefüllt bzw. abgeschnitten.

Apostroph ist absolut reserviert. Will man ihn drucken,
so wird dies folgendermaßen erreicht:

A$ = USING ("SM's BASIC-96","'")          ergibt   SM's
BASIC-96

Schrägstrich ist nur hinter Apostroph bzw. Schrägstrich
hinter Apostroph reser-
viert. Nach einem beliebigen anderen Zeichen wird er als
normales Zeichen inter-
pretiert.

Ein Operator für variabel lange Felder wird nicht
vorgesehen, da dies durch Kettung von USING, String,
USING leicht erreicht werden kann.
  __________________________________________________________________________
Zahlen:

Doppelkreuz repräsentiert genau eine Ziffer, Punkt den
Dezimalpunkt, Komma Tausenderkomma, Schrägstrich
Tausender-Blank:

('Doppelkreuz, ist das SHIFT-Zeichen über der '3'-Taste)

Die Anzahl von Vor- und Nachkommastellen sollte zusammen
nicht 9 übersteigen.

Mehr als 9 Stellen bewirken folgendes: Muß eine Zahl mit
9 Stellen rechts mit Nullen aufgefüllt werden, um die
Formatierungsvorschrift zu erfüllen, so findet Überlauf
in Exponentialdarstellung statt. Dies ist nötig, da sonst
optisch eine nicht vorhandene Rechengenauigkeit
vorgetäuscht werden würde.

Im Fall von definierten Nachkommastellen ist der Exponent
um die Anzahl Nachkommastellen zu groß, es wird also ein
fehlerhafter Exponent ausgegeben.

Dagegen kann linksbündig mit Blanks oder '*' beliebig
aufgefüllt werden.

Beipiele und Sonderfälle der Zahlenformatierung

A$ = USING("###.##  ###,###,##  ###/###/###", 123.456,
123456789,

123456789)
ergibt: 123.46 123,456,789.00 123 456 789

Trenn-Komma wird nur gedruckt, wenn links weitere Ziffern
kommen:

A$ = USING("###,###,###.## ###,###,###", 123456789,
123456)
ergibt: 123,456,789.00 123,456

Grenzfall 0 Vorkommastellen:

A$ = USING("###.##   ##",.123,.123)
ergibt:             0.12 .12

Führende Vorkommanullen werden durch Blanks ersetzt mit
Ausnahme der ersten. Dies gilt nicht, wenn im Format
keine Vorkommastelle vorgesehen ist.

Überlauf wird durch ein & in der letzten Stelle
signalisiert, sofern die Zahl nicht durchVerschieben zu
'retten' ist.

A$=USING("###.##   ###.## ###.##",
1234.567,12345.67,123456.7,1234567)
ergibt  1234.6 12346. 123457 12345&

Dadurch wird der Wert der Zahl gerundet richtig
wiedergegeben, solange sie nur um soviele Vorkommastellen
größer ist, wie Nachkommastellen vorgesehen sind.

Daß die Zahl in diesem Fall nicht mit der richtigen
Nachkommaanzahl gedruckt wird, ist bei Tabellen eindeutig
erkennbar; in anderen Fällen nur, wenn das Format bekannt
ist.

Vorzeichen:

Der Platz für ein Vorzeichen ist immer explizit anzugeben

   ###.##       kein Vorzeichen möglich, sonst
                Überlauf-Reaktion
   +###.##      + oder - vor der Zahl ausgeben
                (explizites Plus)
   -###.##      nur - vor der Zahl ausgeben
                (implizites Plus = Blank)
   ###.##+      + oder - nach der Zahl ausgeben
                (explizites Plus)
   ###.##-      nur - nach der Zahl ausgeben
                (implizites Plus = Blank)
  __________________________________________________________________________
Scheckschutz:

Durch einen führenden Stern im format werden beim
Ausdruck führende Blanks durch Sterne ersetzt:

A$ = USING("*##,###,###.##       *##,###,###",123456,)
ergibt:****123,456.00 **********0

Der Stern repräsentiert ebenso wie Doppelkreuz eine
Ziffer!

Die erste Vorkommastelle wird durch Null anstatt Stern
dargestellt.

Wurde eine Vorzeichenstelle reserviert, so wird in die
linke Spalte Blank statt Stern gedruckt.

Unmittelbar nach '*' darf kein 'Tausender-Komma' stehen;
dies führt zu Fehlformatierungen.


Exponentialdarstellung:

Vier &-Zeichen reservieren Platz für den Exponenten und
schalten auf Exponentialdarstellung. Die Mantisse wird
immer mit einer Vorkommastelle ausgegeben.

Der Exponent hat immer die Form 'E', Vorzeichen, zwei
Ziffern Exponent. Bei einstelligem Exponent ist die
führende Ziffer eine 0.


Wiederholung:

Ein Format kann von mehreren Variablen 'benützt' werden.
Das ganze Format wird automatisch wiederholt:

A$ = USING ("###.## ",123.45,234.56,345.67)
ergibt: 123.45 234.56 345.67

A$ = USING("'//////// ### : ",mueller,25,maier,36)
ergibt:        mueller    25 : maier      36 :


Wenn USNG alleine oder in Zusammenhang mit PRINT
verwendet wird, verhält es sich wie eine Stringfunktion,
übergibt also genau einen String.

Dagegen hatUSING in Zusammenhang mit INPUT vom Bildschirm
eine Doppelfunktion: Einmal wird genauso wie bei PRINT
der Inhalt der E/A-Variabie formatiert auf den Bildschirm
geschrieben und zwar genau an der Eingabeposition. Zum
zweiten sind bei numerischer Eingabe nur Zifferntasten
usw. erlaubt und der Cursor kann nicht aus dem durch das
Format definierte Eingabefenster entfernt werden. Diese
Eigenschaften sind im Kapitel INPUT beschrieben.
  __________________________________________________________________________
3.21 INPUT USING

Zweck

INPUT USING ermöglicht eine für Programmierer und
Anwender komfortable Eingabe, die weit über die
Möglichkeiten des normalen INPUT hinausgeht. Zusammen mit
der Cursorpositionierung durch '¶(zeile,spalte)' ergeben
sich Möglichkeiten, mit geringem Aufwand einen
übersichtlichen und abgesicherten Bildschirm-Dialog
aufzubauen.


Forrnat

INPUT ¶ (ze,sp) eingabe-variable
INPUT USING (format) eingabe-variable
INPUT ¶ (ze,sp) USING (format) eingabe-variable


eingabe-variable: numerische oder String-Variable,
einfach oder indiziert

Der Inhalt der Variablen wird ab (ze,sp) linksbündig auf
den Bildschirm geschrieben (Vorgabe) und der Cursor auf
die erste (linke) Spalte gesetzt.


format: wie bei USING beschrieben, aber mit folgenden
Einschränkungen:

Nur 1 Eingabeformat (//// oder####) ist möglich. Vor dem
Eingabeformat können beliebige konstante Zeichen stehen
("Alter: ###"). Nach dem ersten Eingabeformat werden alle
weiteren Angaben im Formatstring ignoriert.

Typ von Eingabeformat und Variable müssen übereinstimmen,
sonst erfolgt TYPE-MISMATCH-Meldung.


Verhalten des Bildschirm-Editurs bei der Eingabe:

Der Cursor kann aus dieser Bildschirmzeile nicht entfernt
werden:

Cursor-Vertikal-Tasten sind wirkungslos.

DEL wirkt nur rechts vom Aufsetzpunkt.

HOME stellt alten Inhalt nochmal her, solange nicht durch
RETURN übernommen wurde.

CLR löscht rechte Zeilenhälfte ab Aufsetzpunkt.

RETURN übernimmt Fenster-Inhalt in Variable.

Leere Eingabe bei String erzeugt leeren String. Bei
numerischer Variable ist die leere Eingabe nicht
zugelassen, d.h. aus leerem Zahlenfenster kommt man nicht
raus. Die Reaktion ist wie bei HOME.

STOP bewirkt die Rückkehr ins BASIC-Programm und von dort
BREAK, sofern dies nicht verhindert wurde.

Bei numerischer Eingabe (numerische Variable) sind nur
die Zifferntasten sowie Punkt, Komma, E, +, - und Blank
zugelassen.
  __________________________________________________________________________
USING hinter INPUT hat zusätzlich zu den bisher genannten
noch die folgenden
Wirkungen:

Das Eingabefenster ist nicht nur nach links, sondern auch
nach rechts begrenzt (entsprechend der Länge des
Eingabeformats).

Die Vorgabe wird entsprechend der Formatvorschrift
gemacht.

Vorzeicheneingabe ist entsprechend der Formatangabe
erlaubt oder nicht.

'E' ist nur zugelassen, wenn im Format ein Exponent
definiert ist.

Vor Übergabe einer Zahl durch RETURN wird sie
entsprechend der Formatvorschrift gerundet und formatiert
ins Fenster gedruckt. Der übergebene Wert ist gerundet.


Beispiel

input ß(10,20) using ("Menge (kg): ######.### mk

Persönliche Werkzeuge