Magic Disk 64

home to index to html: KURS-BASICKURS.html
     BASIC-Kurs : "Von Adam und Eva..." (Teil 1)     
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾     
Sehr geehrter Leser,                                 
pünktlich zum Anfang des  neuen  Jahres  möchten  wir
uns  gleich an unsere guten Vorsätze für 1989 halten,
und unser Versprechen einlösen,  die  Anfänger  unter
Ihnen  nicht zu kurz kommen zu lassen. Sie lesen näm-
lich im Moment gerade die ersten einleitenden  Zeilen
unseres  neuen  BASIC-Kurses  für Einsteiger. Wie der
Name dieses Kurses schon vermuten  läßt,  wollen  wir
ganz  am  Anfang  beginnen, so daß auch der, der noch
überhaupt keine Ahnung von der  Programmierung  eines
Computers  hat, von Adam und Eva an  alles schön mit-
verfolgen kann.                                      
Beginnen wir nun mit der Frage nach dem WARUM.  Warum
BASIC?  Nun,  BASIC  ist die Abkürzung für "Beginners
Allpurpose Symbolic Instruction Code", was frei über-
setzt  etwa  "Universeller Befehlscode mit Symbolwör-
tern für Anfänger" bedeutet. Und dies sagt uns  schon
fast  alles  über den Grund und die Aufgabe von BASIC
aus, denn man wollte mit BASIC  eine  Computersprache
erschaffen,  mit  der jeder normale Mensch, der etwas
Englisch versteht und logisch denken kann, einen Com-
puter  programmieren  kann.  Zu  früheren Zeiten, als
das, was heute in einem zündholzkopfgroßen  Mikrochip
untergebracht   ist  noch  ganze  Räume  und  Gebäude
ausfüllte, war die Programmierung von Computern  noch
äußerst kompliziert, und bestand meist darin, nichts-
aussagende,  trockene  Zahlenreihen   von   der   Art
0101000110101...  in die sage und schreibe 1 KiloByte
großen Hauptspeicher der damaligen Rechner regelrecht
"hineinzumorsen". Da dies eine sehr mühsame und lang-
wierige Arbeit war entwickelte man mit der Zeit immer
mehr  Computersprachen, die auf Grund der immer höher
werdenden Leistungsfähigkeit der Computer  immer kom-
fortabler und benutzerfreundlicher wurden, so daß das
Programmieren  eine leichte Sache wurde. BASIC stellt
wohl so eine Art Endstufe dieser Entwicklung dar, was
zumindest  die  Einfachheit  der  Programmierung  be-
trifft. Heutzutage ist ehrlich gesagt fast jede Spra-
che leistungsfähiger als BASIC, doch die meisten noch
lange nicht so einfach  zu  erlernen.  Diese  Sprache
eignet  sich  außerdem  hervorragend für Anfänger die
Funktionsweise und den Bau eines Computers zu  erler-
nen  und gibt eine unverzichtbare Grundlage für ande-
re, schnellere  Programmiersprachen.  Deshalb  wollen
wir  nun  endlich beginnen und einmal einen Blick auf
die einfachsten, trotzdem aber häufig  benutzten  BA-
SIC-Befehle werfen...                                
Leider ist es nicht so einfach einen Kurs mit kleinen
Beispielen zu gestalten, wenn Sie selbigen gerade auf
Ihrem C64 lesen. Deshalb werde  ich  bei  praktischen
Beispielen  in  Zukunft  so tun, als säßen Sie gerade
nicht vor der MAGIC DISK 64, sondern  nur  vor  einem
eingeschalteten  Computer,  der auf eine Eingabe war-
tet. Ich werde grundsätzlich das  Ergebnis,  das  auf
Grund  einer Anweisung, die wir dem Computer eingege-
ben haben auf dem Bildschirm erscheinen  sollte  hier
im  Kurs  aufzeigen, doch sollten Sie nicht davon Ab-
schrecken, die  aufgeführten  Beispiele  auch  selbst
einmal  auszuprobieren  (wenn Sie fertig sind mit der
MAGIC DISK 64), indem Sie sie sich ganz einfach  auf-
schreiben,  oder wenn ein Drucker vorhanden ist, ein-
fach ausdrucken können.                              
Also:  Bitte geben Sie einmal folgende Zeile in Ihren
angeschalteten, auf eine Eingabe wartenden 64er ein: 
PRINT "DAS IST MEIN ERSTER AUSDRUCK !"               
Drücken  Sie nun die RETURN-Taste. Auf dem Bildschirm
erscheint nun folgendes :                            
DAS IST MEIN ERSTER AUSDRUCK !                       
READY.                                               
Das  war  doch  schon mal ein Erfolgserlebnis! Fassen
wir doch einmal zusammen, was passiert ist:          
Sie  haben eine Zeile eingegeben, an deren Anfang der
Befehl "PRINT" stand. Anschließend gaben Sie in "Gän-
sefüßchen"  oder  "Anführungsstrichen"  einen    Text
ein und haben die RETURN-Taste gedrückt. Nun ist  un-
ter  Ihrer  eingegebenen  Zeile  der Text, den Sie in
Anführung hatten, ausgedruckt worden, und der  Compu-
ter hat sich mit "READY." wieder zurückgemeldet.     
Was ist genau geschehen? Nun, der PRINT-Befehl  wird,
wie Sie schon richtig erkannt haben,   dafür  benutzt
um  Texte  auf  dem  Bildschirm auszugeben. Sie gaben
also Ihre Zeile ein und signalisierten  mit  der  RE-
TURN-Taste  dem  Computer,  daß Sie mit Ihrer Eingabe
fertig sind und daß er Ihre  Zeile  bearbeiten  soll.
Dieser  erkannte  die  ersten  5 Buchstaben als einen
PRINT-Befehl, druckte  den  anschließenden  Text  und
meldete  ordnungsgemäß mit "READY." seine Betriebsbe-
reitschaft für weitere Befehle.                      
Sollte das oben beschriebene in Ihrem Fall nicht ein-
getreten sein, dann kann es nur sein, daß  Sie  einen
Fehler  bei  der  Eingabe  gemacht haben. Sollte also
jetzt anstatt unseres Textes die Zeilen:             
?SYNTAX  ERROR                                       
READY.                                               
bei  Ihnen  auf  dem  Bildschirm stehen, so haben Sie
sich wahrscheinlich beim Eingeben  unseres  Beispiels
vertippt.  Der  Computer  ist  da sehr genau, denn er
versteht nur  einen  bestimmten  Befehlssatz,  bezie-
hungsweise  kann  er  mit einigen Formulierungen oder
Eingaben nichts anfangen, da er seine vorprogrammier-
ten Befehlswörter zu erkennen versucht. Wenn man obi-
ge Fehlermeldung einmal in deutsche  Übersetzt,  wird
einem  das  sogar  noch  etwas klarer:  Syntaktischer
Fehler. Zur Erläuterung, die Syntax einer Sprache ist
die Art und Weise, wie diese grammatikalisch und  vo-
kabular  aufgebaut ist. Sie haben sich also im Dialog
mit Ihrem C64 sozusagen "versprochen", weshalb dieser
Sie auch nicht verstand. Und wir möchten ja, daß  Sie
die Sprache BASIC "akzentfrei" sprechen können.      
Keine Panik also, wenn der Computer bei Ihren  ersten
Gehversuchen Ihnen ein paar Errormeldungen in den Weg
wirft. Sehen Sie sich Ihre Eingaben dann nochmal ganz
genau an und Sie werden bestimmt die Ursache des Feh-
lers finden. Manchmal ist dies etwas schwieriger,  da
bei  bestimmten Dingen die der Computer für Sie erle-
digen soll auch ganz spezielle Fehler auftreten  kön-
nen.  Doch  nicht verzagen, im C64 Bedienungshanbuch,
Anhang L sind alle möglichen Fehlermeldungen zusammen
mit Ihren Ursachen aufgelistet. Hier können  Sie  bei
Bedarf Hilfe suchen.                                 
Nun wieder zurück zu  unserem  PRINT-Befehl.  Sollten
Sie  ein  wenig Englisch können, werden Sie erkennen,
daß dieser Befehl nicht umsonst so heißt.  PRINT  ist
die  Übersetzung für DRUCKE und sagt somit eigentlich
alles aus, was dieser Befehl tut. Dies ist,  wie  Sie
bald  merken  werden, bei allen BASIC-Befehlen so, so
daß man sich diese sehr leicht merken  kann,  was  ja
auch der Sinn der Sache sein soll, damit ein leichtes
Programmieren ohne lange Suche nach Befehlen  gewähr-
leistet ist.                                         
Gehen wir nun aber etwas  weiter.  Langweilige  Texte
ausdrucken macht eh nicht soviel Spaß, zumal man gan-
ze 7 Zeichen (PRINT und 2 Mal ") mehr  eingeben  muß,
will man einen Text ausdrucken. Doch der PRINT-Befehl
ist noch zu viel mehr gut, denn immerhin hat man hier
einen dicken Computer stehen, der solche kleinen Din-
ge, wie sie zum Beispiel ein Taschenrechner  erledigt
doch mit dem "kleinen Finger" bringt. Ja,  mit  PRINT
können Sie rechnen, sei es, daß es Ihnen  einen  Text
ausdruckt, oder das Ergebnis einer Addition. Die Syn-
Syntax hierzu ist denkbar einfach:                   
PRINT 101+35                                         
Dieser Befehl addiert  die  Zahlen  101  und  35  und
druckt anschließend das Ergebnis auf  dem  Bildschirm
aus:                                                 
 136                                                 
READY.                                               
Sie  sehen,  die  Eingabe erfolgt genau wie bei Text-
ausdrücken, nur daß Sie  hier  die  Zahlen  nicht  in
Anführungsstriche  zu  setzen brauchen, ja sie MÜSSEN
Sie sogar weglassen, denn sonst meint  der  Computer,
Sie möchten eine Zeichenkette ausdrucken, weshalb bei
dem  folgendem  Befehl auch die folgende Reaktion des
Computers zu erwarten ist:                           
PRINT "101+35"                                       
101+35                                               
READY.                                               
Ich  hoffe,  daß  Ihnen hiermit etwas klarer geworden
ist, wie Sie zu unterscheiden haben :                
             ⌈––––––––––––––––––––––––––⌉            
             |MIT  "" wird Text gedruckt|            
             |OHNE "" wird gerechnet.   |            
             ⌊––––––––––––––––––––––––––⌋            
Doch weiter mit der Rechnerei. Sie können  ohne  wei-
teres auch andere Rechenfunktionen verwenden.  Die  4
Grundrechenarten möchte ich hier jetzt erwähnen,  ob-
wohl  auch  Wurzeln  oder trigonometrische Funktionen
für unseren C64 kein Problem darstellen,  doch  werde
ich  diesen  Rechenfunktionen später noch ein eigenes
Kapitel widmen. Im Moment reichen die folgenden voll-
kommen aus. Genau so, wie Sie bei "101+35" einen "+"-
Operator  eingestzt  hatten, so ist dies auch bei der
Subtraktion,  Multiplikation  und  Division  möglich,
hierfür  müssen  Sie allerdings folgende Zeichen ver-
wenden, um dem Computer klar zu machen, was  Sie  von
Ihm wollen:                                          
"+" - zum addieren                                   
"-" - zum subtrahieren                               
"*" - zum multiplizieren                             
"/" - zum dividieren                                 
Somit sind folgende Zeilen auch leicht denkbar :     
PRINT 222*67                                         
PRINT 1000-100                                       
PRINT 81/9                                           
Probieren Sie es einmal aus, und experimentieren  Sie
mal  ein  wenig.  Grundsätzlich  gilt auch für andere
Beispiele die ich geben werde,  daß  Sie  ruhig  auch
einmal eigene Versuche machen können, um sich mit den
neu erlenten Dingen in allererster Linie vertraut  zu
machen,  denn wie heißt es so schön:  "Probieren geht
über studieren." zumal Sie mit Ihren Eingaben  grund-
nichts an Ihrem Computer kaputt machen können, es sei
denn, Sie versuchen die Tasten mit  einem  Hammer  zu
betätigen...                                         
Bei Ihrer Rechnerei dürfen Sie sogar auch Kommazahlen
verwenden.  Hierbei  müssen  wir  uns allerdings auch
wieder ein wenig ans  Englische  anpassen,  denn  der
Computer  versteht auch Kommazahlen nur in englischer
Schreibweise. Das normale Komma ist für einen anderen
Zweck reserviert. Das heißt im Klartext, daß die Zahl
"3,14" für unseren kleinen Siliziumfreund so aussehen
muß:  "3.14". Die Amerikaner  benutzen  grundsätzlich
den  Punkt  als  Dezimalkomma,  und hieran müssen Sie
sich gewöhnen. Richten Sie sich danach,  dann  machen
Rechnungen wie die Folgende keine Probleme mehr :    
PRINT 2*20*3.14                                      
Vielleicht  haben Sie ja bemerkt, daß der Kreisumfang
für einen Kreis mit dem Radius 20 cm (oder m oder km)
berechnet wurde. Denn gemäß der Kreisumfangsformel  2
mal  Radius  mal  die  Zahl Pi (π) haben wir hier die
Zahl π mit der Dezimalzahl 3,14 dargestellt, nur  mit
einem Dezimalpunkt. Wie Sie sehen, können auch mehre-
re Rechenoperationen aneinander gehängt werden, wobei
der   Computer   die   allgemeingültige   "Punkt-vor-
Strich"-Regel  natürlich  ordnungsgemäß  einhält. Das
heißt, daß bei der Rechnung 20+3*100 das Ergebnis 320
herauskommt (und nicht etwa 2300), da auf Grund  die-
ser Regel die Multiplikation (und auch die  Division)
Vorrang vor der Addition (oder Subtraktion) hat.     
Es wurde also folgendermaßen gerechnet:              
1.) 3*100 (=300) 2.) 20+300 (=320)                   
Möchte man den anderen Weg benutzen, nämlich daß  ge-
rechnet wird:                                        
1.) 20+3   (=23)                                     
2.) 23*100 (=2300)                                   
so  muß man mit Klammern arbeiten, denn genau wie bei
den allgemeinen algebraischen Rechenregeln auch, kann
man mit Klammern die Prioritäten der einzelnen  Rech-
nungen  verändern.  Wollen wir also 2300 herausbekom-
men, so müssen wir folgenden Befehl benutzen:        
PRINT (20+3)*100                                     
Anstelle  von "PRINT 20+3*100", wobei nämlich 320 he-
rauskäme.                                            
Dies zum Rechnen mit PRINT.  Doch  müssen  Sie  schon
zugeben,  daß  das,  was wir hier taten, alles nichts
"handfestes" war, zumal wir mit den  errechneten  Er-
gebnissen  nicht  weiterarbeiten  konnten. Natürlich,
Sie hatten diese nach Ihrer  Rechnung  dann  auf  dem
Bildschirm stehen und konnten sie dann in einer neuen
PRINT-Zeile  weiterverarbeiten,  doch  dies wird sehr
umständlich mit der Zeit. Angenommen Sie erhalten bei
einer Rechnung folgendes Ergebnis: 2.75399753.  Jetzt
müßten Sie diese Zahl nochmal  gänzlich  abtippen  um
Ihre  Rechnung  durchführen  zu  können. Doch wie Sie
vielleicht bemerkten, beutzte ich soeben den Irrealis
("müssten"), das heißt, daß es noch eine  andere  Art
der  Rechnung  gibt,  eine bequemere Art, bei der das
nochmalige Abtippen nicht mehr nötig ist. Ich spreche
von dem Rechnen mit Variablen. Ich  möchte  mich  nun
ein  klein  wenig  von  der Rechnerei lösen, um Ihnen
dieses äußerst wichtige Kapitel  besonders  verständ-
lich  darlegen  zu  können. Denn das Verständnis über
Variablen ist die Vorraussetzung für BASIC (und  auch
für  die  meisten anderen Hochsprachen). Um Variablen
dreht sich alles in BASIC, denn sie sind ein  äußerst
einfaches  und  praktisches  Hilfsmittel.  Wollen wir
beginnen:                                            
Falls  Sie  sich  vielleicht  noch  ein  wenig an die
Schulzeit errinnern, oder vielleicht sogar noch Schü-
ler  sind, dann werden Sie sich bestimmt auch noch an
Rechnungen mit Unbekannten und  Variablen  errinnern.
Gleichungen  von  der Art "y = 2x" dürften Ihnen dann
nicht unbekannt sein. Genauso  wie hier  die  Zeichen
"x" und "y" Platzhalter für eine beliebige Zahl sind,
so  sind  die Variablen gewissermaßen Platzhalter für
unsere drei Datentypen. "Gewissermaßen" deshalb, weil
sie allgemein tatsächlich Platzhalter für Zahlen oder
Texte  sind, mit dem Unterschied, daß mit  Ihrem  In-
halt  allerdings sofort gerechnet werden kann, dieser
also nicht eher imaginär ist, so wie bei  den  mathe-
matschen Variablen.                                  
Um Ihnen dies noch ein wenig besser erläutern zu kön-
nen, kann man Variablen auch mit Schubladen  verglei-
chen  (wobei  jede  Schublade ihren eigenen Namen be-
sitzt, mit dem man sie ansprechen kann)  und  in  der
jeweils  bestimmte  Dinge, beziehungsweise Daten ent-
halten sind. Möchte ich zum Beispiel  einmal  in  die
Schublade PI hineinschauen, so öffne ich sie und kann
mir dann bei Bedarf den Zahlwert 3.14159 dort heraus-
holen.                                               
Sie sehen also, daß das Ganze eigentlich äußerst ein-
fach  ist.  Sie  geben einer Variable einen Namen und
sagen, was in Ihr enthalten ist.  Wir  sprechen  hier
von  einer sogenannten Variablendefinition. Ab sofort
brauchen Sie solche Werte dann nicht  mehr  von  Hand
hinzuschreiben, sondern brauchen nur noch anstatt der
getippten  Zahl  in  Ihrer  Rechnung die entspechende
Variable zu verwenden. Als  kleines  Beispiel  möchte
ich Ihnen einmal eine kleine Rechnung zeigen, bei der
dies durchaus von Nutzen sein kann.                  
Angenommen, wir wollen die Oberfläche eines Zylinders
berechnen. Die Formel, die man hierfür allgemein  be-
nutzt sieht folgendermaßen aus:                      
o=2rπ(r+h),                                          
wobei die Platzhalter (oder neuerdings  für  uns  die
Variablen) folgende Bedeutung haben:                 
r = Radius der Zylindergrundfläche, h = Höhe des  Zy-
linders, π nimmt hier eine  Sonderstellung  ein.  Die
Zahl PI müssen wir nämlich nicht mehr  eingeben,  Sie
ist in Ihrem C64 schon  fest  gespeichert  und  immer
greifbar. Sogar bis auf 8 Stellen hinter dem Komma!  
Ihre Taste befindet sich rechts  oben,  direkt  neben
der RESTORE- Taste Ihres 64ers, und  Sie  können  Sie
mit nur mit gleichzetigem drücken der SHIFT  und  der
↑-Taste erreichen.                                   
Nehmen wir nun einmal an,  wir  wollen  in  etwa  die
Oberfläche  einer  Coladose  berechnen,  also wieviel
Quadratzentimeter  Weißblech  zur  Herstellung  einer
solchen  Dose verbraucht werden. Eine normale Geträn-
kedose ist allgemein  11.5  cm  hoch  und  hat  einen
Durchmesser  von  6.5 cm. Um den Radius nun zu erhal-
ten, den wir ja brauchen, dividieren wir einfach noch
durch 2, also 6.5/2 = 3.25. Ich habe hier absichtlich
einmal die Operatoren und die Schreibweise des Compu-
ters gewählt, damit Sie sich ein wenig  daran  gewöh-
nen.                                                 
So,  eine  Höhe  und einen Radius haben wir ja jetzt,
wollen wir nun einmal rechnen. Wie wir ja vorhin  ge-
lernt haben, können wir unsere Formel o=2rπ(r+h) ganz
normal  übernehmen, nur müssen wir darauf achten, daß
wir dem Computer noch die  in  der  Formel  fehlenden
Multiplikationsoperanden  "unterschieben"  können, da
diese in der Mathematik  im  allgemeinen  weggelassen
werden (um eine kompaktere Schreibform zu erreichen),
unser  C64  sie  allerdings unbedingt benötigt, da er
sonst nicht von  Varablen  und  Zahlen  unterscheiden
könnte.  Dies liegt einfach daran, daß Variablennamen
auch Zahlen beinhalten können. Doch  zur  Nomenklatur
von  Variablen  später etwas mehr. Widmen wir uns nun
wieder unserem Problem, und lassen  wir  die  in  der
Formel  verwendeten  Variablen stehen. Geben Sie doch
dem  Computer  nun  einmal  unsere   Beispielrechnung
direkt  ein,  indem Sie die Werte für Höhe und Radius
der Dose ganz einfach schon einsetzen. Dann kämen Sie
zu folgender Zeile :                                 
PRINT 2*3.25*π*(3.25+11.5)                           
Mal  abgesehen  davon,  daß  Sie  hiermit auch zu dem
richtigen Ergebnis kommen,  nämlich  301.200196  qcm,
hätte  man  hier  ein  wenig sparen können, zumal man
zweimal den selben Wert eingeben mußte, nämlich  3.25
für  den Radius. Machen wir es uns also einfacher und
benutzen wir Variablen. Eine  Wertzuweisung  an  eine
Variable  ist  denkbar einfach. Sie schreiben einfach
den Namen der Variable hin, setzen  ein  Gleichheits-
zeichen  "=" dahinter und schreiben dann den Zahlwert
hinter dieses Zeichen.                               
a=1  wäre  also die Zuweisung des Wertes 1 an die Va-
riable "a". Geben Sie nun "PRINT a"  ein,  dann  wird
der  Computer  Ihnen die Zahl 1 ausdrucken, Sie haben
also gerade eben in die Schublade  "a"  geschaut  und
ihren Inhalt auf dem Bildschirm dargestellt.         
In unserem Beispiel müßten Sie also  folgende  Zeilen
eingeben:                                            
r=3.25                                               
h=11.5                                               
Hiermit  haben  Sie  nun den Beiden Variablen "r" und
"h" ihren Wert zugewiesen. Jetzt geht es um die  For-
mulierung  der  Rechnung, die genial einfach ist. Sie
müssen nur alle vorher  eingesetzten  Werte  mit  den
Variablennamen austauschen.                          
Statt:                                               
PRINT 2*3.25*π*(3.25+11.5)                           
heißt es jetzt nur noch:                             
PRINT 2*r*π*(r+h)                                    
womit wir der Ursprungsform der mathematischen Formel
schon etwas näher wären. Das tolle daran ist, daß Sie
nun für alle Werte, die  Sie    einsetzen    möchten,
ein  und  dieselbe Zeile weiterverwenden können, näm-
lich die oben angezeigte. Sie müssen vorher  nur  den
Variablen andere Werte zuweisen, z.B.:               
r=2.8                                                
h=5.4                                                
Das ganze mit den Variablen hat natürlich einen Sinn:
Später,  wenn  Sie  Programme  schreiben, sind solche
Universalanweiungen unerläßlich, zumal Sie einem  das
Programmieren  erleichtern  und  zusätzlich auch noch
unwahrscheinlich flexibel sind...                    
Wollen wir uns nun einmal ein wenig um die Variablen-
namen kümmern, zumal hierbei bestimmte Regeln  einge-
halten  werden müssen, da sonst BASIC nicht mehr mit-
spielt, oder falsche Ergebnisse liefert.             
Zusammenfassend  möchte  ich  Ihnen diese Regeln hier
einmal Auflisten :                                   
1.) Eine  Variable darf aus Buchstaben (also a-z) und
    aus Zahlen  (0-9)  bestehen.  Sonderzeichen,  wie
    z.B.:  ".,;:"  oder ähnliches sind NICHT erlaubt.
    Das erste Zeichen einer Variable  MUSS  immer ein
    Buchstabe  sein,  Sie  dürfen  also hierfür keine
    Zahlen verwenden.                                
2.) Eine Variable darf höchstens 2 Zeichen lang sein.
    Sie  können zwar soviel Zeichen verwenden wie Sie
    wollen, doch sind grundsätzlich die ersten 2  nur
    von  Bedeutung.  Das heißt, daß Sie eine Variable
    zwar "RADIUS" nennen dürfen, doch ist  diese  Va-
    riable  z.B.  mit der Variable "RADIESCHEN", oder
    "RAMBOCK" absolut identisch, weil unser 64er halt
    nur mit Hilfe der ersten 2 Zeichen  die  Variable
    unterscheidet.  In diesem Fall heißen also alle 3
    Variablen für unsern kleinen Freund "ra".  Gewöh-
    nen  Sie  sich  also  auf keinen Fall eine solche
    Namensgebung an, da es so leicht zu  Mißverständ-
    nissen  kommen kann und damit zu Programmfehlern,
    nach denen man ewig sucht                        
3.) Ansonten  gilt natürlich, daß nur in Kleinschrift
    geschriebene Variablen erlaubt sind,  beziehungs-
    weise,  falls Sie den Grafikzeichensatz des 64ers
    benutzen sollten - er ist direkt  nach  dem  Ein-
    schalten vorhanden -  keine Grafikzeichen. Zusam-
    mengefaßt heißt das, daß Sie  niemals  geSHIFTete
    Zeichen verwenden dürfen, sondern nur solche, die
    Sie  ohne  SHIFT-Taste  erreichen können, und die
    unter den in 1. aufgezeigeten Zeichen sind.      
Erlaubte Variablennamen wären also :                 
a                                                    
b                                                    
xx                                                   
ja                                                   
pi                                                   
c1                                                   
c2                                                   
Nicht erlaubt sind z.B.:                             
s.                                                   
%r                                                   
&g                                                   
i/                                                   
Bb                                                   
aB                                                   
1c                                                   
2c                                                   
Kommen wir nun zu den Variablentypen. Falls Sie  ein-
mal  ausprobiert haben sollten, folgende Anweisung zu
geben :                                              
a=Das ist ein Text                                   
dann werden Sie vielleicht  festgestellt  haben,  daß
der Computer dann nach dem anschließenden  "PRINT  a"
ganz und garnicht den Text -"Das ist ein  Text"  aus-
druckte, sondern entweder  einen  SYNTAX  ERROR  oder
eine 0.                                              
Wie Sie nun vielleicht bemerkt haben, haben  wir  bei
unseren  PRINT-Anweisungen  3  verschiedene Arten von
Ausgabedaten verwendet. Fassen wir einmal zusammen : 
1.) Wir hatten Texte ausgegeben. Diese bestanden aus-
    mehreren  beliebigen  Zeichen,  die wir in Anfüh-
    rungszeichen eingeschlossen hatten.              
2.) Wir hatten dann mit Zahlen gearbeitet,  indem wir
    mit ihnen rechneten und die  Gesamtergenisse  uns
    ausgeben ließen. Hierbei handelte es sich anfäng-
    lich  wohlgemerkt um ganzzahlige Zahlen. Es wurde
    kein Dezimalpunkt benutzt.                       
3.) Anschließend haben wir dann die sogenannten reel-
    len  Zahlen  hinzugenommen. Diese sind Zahlen mit
    Dezimalkomma  (beziehungsweise  Dezimalpunkt,  in
    BASIC - Beispiel: pi = 3.14159...).              
Grundsätzlich  kann  man nun sagen, daß es drei Arten
von Datentypen gibt:  Zeichenketten, ganze Zahlen und
Kommazahlen.                                         
Genauso müssen wir bei den  Variablen  unterscheiden.
Es  gibt  damit  also  3 Variablentypen, in denen nur
jeweils eine bestimmte Art von Daten gespeichert wer-
den darf:                                            
1.) Texte, bestehend aus Zeichenfolgen.  Diese  Texte
    nennt    man   allgemeinhin   im   Computerjargon
    "Strings".                                       
2.) Ganze Zahlen, sogenannte Integers.               
3.) Dezimalzahlen, sogennannte "Floats",  oder  Floa-
    tingpoint-Variablen     (deutsch:     Fließkomma-
    Variablen).                                      
Ich möchte hier noch bemerken, daß ich diese Begriffe
von nun an immer benutzen werde. Prägen Sie sie  sich
also  gut  ein,  da man mit Ihnen am besten die Typen
unterscheiden kann, ohne noch langwierige Umschrebun-
gen liefern zu müssen.                               
Wie bringen wir also nun unserem C64 bei, welche  der
3  Arten  wir nun wünschen, zumal er sie nicht selbst
unterscheiden kann? Nun das  ist  sehr  einfach,  wir
hängen  einfach  noch  ein  bestimmtes Zeichen an den
Variablennamen an, mit dem diese  Unterscheidung  mö-
glich  wird,  und  das typisch für seine Variablenart
ist.                                                 
Für die einzelnen Variablen gibt es folgende Zeichen:
1.) Strings wird ein "$" angehängt, so daß ein Varia-
    blenname  für einen String beispielsweise anstatt
    "a" nun "a$" heißt.                              
2.) Integers  bekommen ein "%"-Zeichen dahinter. Also
    "a%" anstatt "a".                                
3.) Floats  sind am einfachsten zu bilden, sie bekom-
    men keinen Anhang. Sie sehen also, daß die Varia-
    blen,  die wir in unsrem obigen Beispiel gebildet
    hatten, alles Floatvariablen waren, was auch not-
    wendig war.                                      
    Floatvariablen heißen also wirklich "a".         
Wie Sie einer Floatvariable einen Wert zuweisen, wis-
sen  Sie ja mittlerweile aus unserem Beispiel mit der
Coladose (nämlich mit "x=Zahl")                      
Die  Wertzuweisung  von  Integern  verläuft analog zu
dieser Methode, da es sich hier  ja  auch  um  Zahlen
handelt. Also "x%=10".                               
Bei Strings verhält sich dies  allerdings  ein  wenig
anders.  Zwar  wird die Zuweisung mit "a$=" kenntlich
gemacht, doch muß der  zuzuweisende  Text  unbedingt,
wie auch bei PRINT, noch in Anführungsstriche gesetzt
werden,  da  sonst  ja  nicht von Programmtext unter-
schieden werden könnte.  Also  muß  unsere  Zuweisung
dann lauten:                                         
a$="Das ist ein Text"                                
Nun  wäre  diese Zeichenfolge auch gespeichert. Jetzt
können Sie sie auch ruhig einmal mit "PRINT a$" abru-
fen.  Der  Computer  wird  Ihnen nun wie erwartet den
String "Das ist ein Text" ausdrucken. Sie sehen also,
daß Sie sich hierdurch sehr viel Tipparbeit (und  au-
ßerdem  auch  Speicherplatz)  sparen können, wenn Sie
für einen häufig in einem Programm vorkommenden  Satz
Strings  benutzen.  Natürlich  sind Variablen zu noch
viel  mehr  nutze,  obwohl  eine  Wertzuweisung  auch
eine  Menge  Tipparbeit  mehr  bedeutet,  doch um sie
dreht sich wie gesagt alles in BASIC,  und  ohne  sie
wäre  es kaum möglich, sinnvolle Programme zu schrei-
ben. Diese Wertzuweisung hat natürlich  auch  nur  im
Programm  einen Sinn, doch dazu wollen wir allerdings
in der nächsten Ausgabe kommen.                      
Hier  trotzdem noch eine kleine Anmerkung. Vielleicht
ist Ihnen ja aufgefallen, daß die  Integers  irgendwo
überflüssig sind, da Floatzahlen ja auch ganze Zahlen
darstellen können. Eine Zuweisung von der Art "y=100"
ist also nicht nur möglich, sondern meist auch die am
häufigsten  verwendete Methode. Sie als Anfänger dür-
fen ruhig so arbeiten, doch sei hier gesagt, daß  das
Rechnen mit Integern sehr viel schneller vom Computer
ausgeführt  werden  kann, als das Rechnen mit Floats.
Dies liegt darin begründet, daß die Darstellungsweise
von Floats im Computer intern sehr  kompliziert  ist,
und  viel  internes  hin- und hergerechne verursacht,
wohingegen die Integers dem Computer wieder einfacher
erscheinen, da er selbst diese  nur  benutzt.  Floats
sind  eher  umständlich  simulierte Dezimalzahlen, da
ein Computer diese Zahlenmenge nicht  kennt,  sondern
halt nur die natürlichen Zahlen.                     
Außerdem ist die Verwendung von  Integern  auch  noch
speicherplatzsparend,  da  die  Darstellungsweise wie
gesagt nicht so komliziert ist. Sollten Sie also spä-
ter  einmal  größere  Programme  schreiben, bei denen
dann auf einmal die 37911 Bytes, die BASIC als Haupt-
speicher  frei  hat (siehe auch Einschaltmeldung), zu
knapp werden, dann können Sie häufig mit der  geziel-
ten Benutzung von Integern wieder ein paar Bytes "he-
rausschinden".                                       
Wohlgemerkt  ist  die Benutzung von Integern nur dann
angebracht, wenn wirklich nur mit ganzen  Zahlen  ge-
rechnet wird, bzw. wenn eine Integervariable für eine
Rechnung  eine  ganze  Zahl darstellen soll. Hier sei
auch noch gesagt, daß bei Integerwerten mit  Nachkom-
mastellen  diese  grundsätzlich abgeschnitten werden.
Das heißt, das bei der Zuweisung "a%=5.78" die Varia-
ble  dann  den Wert 5 enthält. Oder daß bei der Divi-
sion 3/2 (=1.5) das Ergebnis 1 ausgegeben wird.      
Wir werden  trotz  allem  wahrscheinlich  doch  immer
Floats  benutzen,  weil  es so einfacher zu schreiben
ist (da wir ja kein Prozentzeichen  anzuhängen  brau-
chen)  und  es  außerdem schwieriger ist das Ganze zu
verstehen, wenn z.B.  in  einer  Formel  verschiedene
Variablentypen  vorkommen.  Doch  ist es grundsätlich
besser, Integers zu verwenden, wobei ich Ihnen  frei-
stelle,  wie  Sie dies handhaben möchten. Sie könnten
ja zum Beispiel auch die  hier  im  Kurs  behandelten
Programme  einmal  umschreiben,  wobei Sie allerdings
sehr weit voraus denken müssen, um prüfen zu  können,
ob  eine  Variable nicht doch irgendwann einmal einen
Dezimalwert annimmt, wegen dem dann die  ganze  Rech-
nung  zunichte wird, da falsche Ergebnisse herauskom-
men, zumal der Computer sich bei solchen  Operationen
ja nicht beschwert, sondern ganz einfach die Nachkom-
mastellen abschneidet.                               
Ich hoffe, daß Sie bis  jetzt  meinen  Gedankengängen
und  vor allem denen des Computers folgen konnten und
möchte mich nun verabschieden bis nächsten Monat,  wo
wir  dann  endlich  zur  Sache  gehen werden, was das
Schreiben von Programmen angeht.                     
Hiermit  möchte  ich  nun schließen und wünsche Ihnen
viel Erfolg beim experimentieren,                    
                                     Ihr Uli Basters.
                  Basic-Kurs Teil 2                  
                  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                  
Lieber  Leser. Nachdem wir uns das letzte Mal ja aus-
giebig um die Variablen und den  PRINT-Befehl  geküm-
mert  haben, möchten wir uns diesen Monat nun endlich
dem Programmeschreiben, also der wirklichen  Program-
merung, von BASIC befassen.                          
Letzte  Ausgabe  hatten wir unsere Befehle und Anwei-
sungen ja immer direkt auf den Bildschrirm  geschrie-
ben,  und der Computer hat sie dann auch immer, nach-
dem wir die Taste RETURN gedrückt hatten, sofort aus-
geführt,  insofern  er nichts an der Syntax der Zeile
auszusetzen hatte. Nun müssen Sie allerdings zugeben,
daß unsere kleinen PRINT-Anweisungen sich als relativ
umständlich und sinnlos erwiesen, zumal man, um einen
Text auf den Bildschirm zu drucken, ja mehr  Schreib-
arbeit   hatte,  als  wenn man ihn einfach "von Hand"
auf den Bildschirm geschrieben hätte.  Man  hatte  ja
noch zusätzlich den PRINT-Befehl zu schreiben und die
Anführungszeichen, die den Text einschlossen.        
Nun,  all  dies  hat  natürlich  einen Sinn, denn der
PRINT-Befehl ist, ebenso wie die meisten anderen  BA-
SIC-Befehle,  nicht  dafür  geschaffen worden, direkt
Texte auszugeben, sondern um in Programmen zu  arbei-
ten,  wo  die  Textausgabe zur Kommentierung des Pro-
gramms absolut unerläßlich ist, zumal dann ein völlig
ahnungsloser Benutzer auch dann mit dem Programm  et-
was  anfangen  kann,  wenn er es sich  zum ersten Mal
ansieht. Doch wie sag ichs meinem Computer?  Wie  ma-
chen wir denn unserem C64  klar, daß wir die eingege-
ben Zeile nicht jetzt, sondern irgendwann später aus-
geführt haben wollen, und daß er sich diese Zeile für
jenen späteren Zeitpunkt merken soll?  Nun, geben Sie
doch einfach einmal folgende Zeile ein :             
10 print"Das ist ein Programm !"                     
Sie sehen, daß Sie nichts sehen. Denn sobald Sie  die
RETURN-Taste drücken, druckt Ihnen Ihr 64er nicht den
Text "Das ist ein Programm !" aus sondern springt mit
dem Cursor (das ist das kleine hellblaue Viereck, das
immer  so  blinkt, und Ihnen Ihre Schreibposition an-
gibt) einfach in die nächste Bildschirmzeile und war-
tet  nun  wiederum  auf  eine Eingabe. Noch nicht mal
eine Fehlermeldung ist zu  sehen.  Eine   Riesensaue-
rei!!!                                               
Doch  keine Panik ! Ihr C64 ist nicht etwa beleidigt,
oder kaputt, sondern er hat sich soeben  gerade  eine
Programmzeile gemerkt. Doch was heißt das eigentlich?
Nun,  wie  Ihnen  bestimmt aufgefallen ist, haben wir
vor unsre PRINT-Anweisung noch eine Zahl geschrieben.
Dies ist die sogenannte  Zeilennummer.  Ihr  Computer
merkt  sich Ihre Eingaben intern nämlich mit Nummern,
die er nach ihrer Größe ordnet. Das  heißt,  daß  Sie
mit dieser Zahl auch immer wieder auf eben jene Zeile
zurückgreifen  können.  Sie ist sozusagen das "Erken-
nungszeichen" einer Programmzeile. Was das genau  be-
deutet,  möchte  ich Ihnen mit einem kleinen Beispiel
noch ein wenig näher bringen. Geben Sie  doch  einmal
ein:                                                 
list                                                 
Sie sehen nun folgendes:                             
10 print"Das ist ein Programm !"                     
ready.                                               
Nach Eingabe des BASIC-Befehls LIST hat uns  der  C64
die  eben  eingegebene  Programmzeile wieder aufgeLI-
STet; so, wie wir sie eingegeben hatten, nämlich  mit
ihrer  Zeilennummer  vorangestellt. Er hat sich diese
Zeile also gemerkt. Sie können gerne einmal probieren
ob es  auch  funktioniert  wenn  Sie  den  Bildschirm
gelöscht  haben  (dies tun Sie mit der Tastenkombina-
tion SHIFT und CLR/HOME), auch  nun  wird  Ihnen  der
Text  noch  haargenauso angezeigt, wie Sie ihn einga-
ben, es hat also nichts damit zu tun, daß unsere Zei-
le  noch  auf  dem Bildschirm stand. Das ist auch gut
so, denn der C64  merkt sich solche Programmzeilen in
seinem Programmspeicher (ebenso  wie  die  Variablen)
von wo er sie auch wieder auf dem Bildschirm anzeigen
kann, halt mit eben jenem Befehl LIST.               
Auch für Zeilennummern müssen  Sie  bestimmte  Regeln
einhalten, damit Ihnen keine Fehler angezeigt werden.
Hier eine Zusammenfassung dieser Regeln :            
1.) Sie können alle Zahlen von 0 bis 63999  für  eine
    Zeilennummer  benutzen.  Dabei sollten Sie jedoch
    die Zeilennummern immer in 10er-Schritten   (also
    10,20,30,40,etc.)  vergeben,  warum dies von Vor-
    teil ist, werde ich Ihnen später erklären.       
2.) Egal in welcher Reihenfolge Sie die Zeilen einge-
    ben, der C64 ordnet diese immmer wieder neu  nach
    der Größe ihrer Zahlen ein. Sollten Sie also ein-
    mal folgende Zeilen  in  der  hier  dargestellten
    Reihenfolge eingeben:                            
    30 print"Zeile 30"                               
    10 print"Zeile 10"                               
    20 print"Zeile 20"                               
    40 print"Zeile 40"                               
    So wird Ihnen Ihr C64  nach der Eingabe von  LIST
    immer wieder folgendes Bild liefern :            
    10 print"Zeile 10"                               
    20 print"Zeile 20"                               
    30 print"Zeile 30"                               
    40 print"Zeile 40"                               
3.) Sollten Sie eine Zeile eingeben, die eine Zeilen-
    nummer hat, die schon im Speicher existiert, dann
    wird  die  alte  Zeile im Speicher durch die neue
    ersetzt. Sollten Sie also bei obigem Programm (so
    können wir es jetzt nennen) die Zeile:           
    30 print"Aetsch! Das is jetzt anders."           
    eingeben, dann wird das  Programm  beim  nächsten
    Listen so aussehen :                             
    10 print"Zeile 10"                               
    20 print"Zeile 20"                               
    30 print"Aetsch! Das is jetzt anders."           
    40 print"Zeile 40"                               
4.) Sollten Sie eine Zeile eingeben, die nur aus  ei-
    ner  Zeilennummer besteht OHNE darauffolgende Be-
    fehle, so wird die entspechende Zeile mit  dieser
    Nummer,  sollte  sie im Speicher stehen, gelöscht
    werden. Würden Sie also:                         
    30                                               
    eingeben, dann würde Zeile 30  aus  unserem  Pro-
    gramm oben gelöscht werden.                      
Jetzt  möchte  ich  Ihnen die Syntax des LIST-Befehls
erst einmal noch etwas genauer  erklären,  bevor  ich
weitergehe  und  Ihnen  zeige,  wie Sie unser kleines
Progrämmchen zum Ablauf bringen.                     
Sie  können dem LIST-Befehl nämlich sogar noch spezi-
fischer sagen, in  welche  Programmzeilen  Sie  einen
Einblick  wünschen. Hierzu müssen Sie dem Befehlswort
LIST ganz einfach die Zeilenummer der Zeile, die  Sie
sich ansehen wollen hinterherstellen. Der Befehl:    
list 20                                              
bewirkt also, daß Ihnen anstatt des ganzen  Programms
nur  die  Zeile  20  angezeigt wird. Ich glaube jetzt
wird es Ihnen hoffentlich auch etwas deutlicher,  wa-
rum  eine  Zeile  eine Nummer braucht. Durch sie kann
man jede einzelne Zeile ansprechen  wie  man  möchte,
der  Computer  versteht also sofort, welche Zeile Sie
von ihm sehen wollen.                                
Doch  die  Anwendung  von  LIST geht noch weiter. Sie
können sich ebenso auch einen ganz bestimmten Bereich
aus Ihrem Programm ansehen, geben Sie etwa  folgendes
ein:                                                 
list 20-30                                           
so werden die Zeilen 20 und  30  auf  dem  Bildschirm
gelistet.  Sie geben also einfach eine obere und eine
untere Grenze an, und LIST wird seine Arbeit auf die-
se Zeilengrenzen beschränken. Ebenso können Sie diese
Schranke  nach oben und unten offen lassen. Dann wird
dementsprechend einfach von der ersten Zeile  bis  zu
der  angegebenen Zeile, beziehungsweise von der ange-
gebenen Zeile bis zur letzten Zeile gelistet. Probie-
ren  Sie  doch  einfach  einmal folgendes mit unserem
kleinen Beispielprogramm im Speicher. Geben Sie ein: 
list -30                                             
Nun werden die Zeilen 10,20 und 30 gelistet, weil das
Programm ab Zeile 10 anfängt.                        
Bei dem Befehl:                                      
list 20-                                             
werden  die  Zeilen  20,30  und 40 gelistet. Der  C64
fängt bei der von Ihnen angegebenen Zeile an und hört
erst am Ende des Programms auf.                      
Wie der LIST-Befehl funktioniert wissen Sie jetzt ja,
klären  wir also schnell noch die Frage, warum man im
Allgemeinen besser  Zeilennummern  in  10er-Schritten
verteilt.  Nun,  dies  liegt einfach darin begründet,
daß Sie, wie jeder Mensch auch, nicht unfehlbar sind,
und daß es Ihnen durchaus einmal passieren kann,  daß
Sie,  aufgrund  eines  Fehlers im Programm, noch eine
Zeile einfügen müssen. Würden  Sie  in  1er-Schritten
die  Programmzeilen eingeben, so müßten Sie erst ein-
mal Platz schaffen, indem Sie alle der  einzufügenden
Zeile  folgenden Zeilen nochmals neu einzutippen hät-
ten, da diese ja im Speicher stehen bleiben  sollten,
aber  zwischen  den  Zeilen 33 und 34 kein Platz mehr
für eine weitere Zeile  wäre.  Deshalb  benutzen  Sie
besser  10er  Zahlen, so, daß Sie bequem zwischen die
Zeilen 20 und 30 beispielsweise eine  weitere  Zeile,
vielleicht mit der Zeilennummer 25, einfügen könnten.
Gewöhnen  Sie sich diese Programmierweise also gleich
an, Sie werden sehen, es lohnt sich ganz bestimmt.   
Doch  widmen  wir uns nun unserem Problem, unser Pro-
gramm auch zum Ablaufen zu bringen. Auch hierfür gibt
es einen Befehl: den RUN-Befehl  (von engl.: to run =
laufen). Haben Sie unser  kleines  Programm  noch  im
Speicher? Gut. Dann geben Sie doch einmal ein:       
run                                                  
Und  nun,  siehe  da,  werden unsere ersehnten PRINT-
Zeilen endlich aktiv, denn Sie  sehen  nun  folgendes
auf dem Bildschirm :                                 
Zeile 10                                             
Zeile 20                                             
Aetsch! Das is jetzt anders.                         
Zeile 40                                             
ready.                                               
Und nun sehen Sie auch den Vorteil des PRINT-Befehls.
Sie können nämlich so auf einfache Art und Weise lan-
ge, lange Texte eingeben, die dann dem Benutzer  wäh-
rend  des Ablaufs eines Programms wertvolle Meldungen
und Hinweise geben können.                           
Der  RUN-Befehl  kann übrigens ähnlich wie LIST ange-
wandt werden. Sie können Ihm nämlich auch  sagen,  wo
genau  er  beginnen  soll, ein Programm abzuarbeiten.
Nämlich indem Sie ihm, wie bei LIST, eine  Zeilennum-
mer nachstellen, ab der er beginnen wird das Programm
abzuarbeiten. Gäben Sie also :                       
run 30                                               
ein, so würde Sie folgendes Bild auf  dem  Bildschirm
anstrahlen :                                         
Aetsch! Das is jetzt anders.                         
Zeile 40                                             
ready.                                               
Eines  sollte  noch gesagt sein:  sollten sich Varia-
blen im Speicher befinden, wenn Sie  eine  neue  Pro-
grammzeile eingegeben haben, so werden diese nach dem
drücken  der RETURN-Taste restlos gelöscht. Das liegt
daran, daß der 64er zum Eingliedern der  neuen  Zeile
in  die  richtige Zahlenreihenfolge den gesamten Pro-
grammspeicher hin- und herschieben muß  und  daß  bei
dieser Schieberei sehr leicht der Inhalt einer Varia-
blen zerstört werden kann. Deshalb werden alle Varia-
blen  vorher gelöscht, damit später kein Mist im Pro-
grammtext stehen kann, und falsche Variablenwerte  zu
falschen Programmreaktionen führen können.           
Ebenfalls aus letztem Grund heraus  werden grundsätz-
lich vor der Ausführung eines RUN-Befehls alle Varia-
blen vom Computer gelöscht, da so ebenfalls ungewoll-
te Veränderungen der Variablen entstehen könnten.    
Außerdem  kann  für  die  beiden Befehle LIST und RUN
gesagt werden, daß sie durch  das  Drücken  der  RUN/
STOP-Taste wieder angehalten werden können.          
Das heißt also, wenn LIST Ihnen gerade  ein  Programm
auflisten  sollte,  und Sie sich einen Teil etwas ge-
nauer ansehen wollten, Sie dadurch  den  Vorgang  des
Listens unterbrechen könnten.                        
Ebenso bei RUN. Möchten Sie aus irgendeinem Grund Ihr
Programm anhalten, vielleicht weil es nicht das  tut,
was  Sie von Ihm wollen, dann können Sie es ebenfalls
auf diese Weise unterbrechen.  Sollten  Sie  es  dann
allerdings  doch  an der Stelle fortsetzen wollen, an
der Sie es angehalten haben, allerdings ohne den  In-
halt  aller  Variablen zu zuerstören, dann können Sie
den Befehl CONT benutzen.  Er  hat  haargenau  selben
Effekt  wie RUN, nur, daß er zum einen die Variablen-
werte nicht vorher löscht, und zum anderen genau hin-
ter  dem  Befehl weiterarbeitet, bei dem das Programm
vorher abgebrochen  wurde,  vorrausgesetzt  es  wurde
zwischendurch  nicht  verändert.  Am besten zeige ich
Ihnen noch einen weiteren Befehl, damit Sie hier auch
ein wenig experimenieren können: der GOTO-Befehl.    
Übersetzen  wir  GOTO  aus dem Englischen, wissen wir
auch schon gleich, was wir mit diesem Befehl anfangen
können.  GEHE  ZU  einer Zeilennummer und arbeite das
Programm von dort aus weiter ab. Hinter GOTO muß also
noch eine Zeilennummer  folgen.  Probieren  wir  also
wieder an unserem kleinen Progrämmchen etwas aus.    
Geben Sie doch zusätzlich noch folgende Zeile ein:   
50 goto 10                                           
Starten  Sie  nun das Programm mit RUN. Sie sehen nun
immer wieder  unseren  Demotext  auf  dem  Bildschirm
"runterlaufen", also etwa folgendes Bild :           
...                                                  
Zeile 40                                             
Zeile 10                                             
Zeile 20                                             
Aetsch! Das ist jetzt anders.                        
Zeile 40                                             
Zeile 10                                             
...                                                  
Verfolgen  wir  einmal  unseren C64, wie er sein Pro-
gramm abarbeitet. Zuerst werden die Zeilen 10-40  wie
gewohnt  durchlaufen.  Der  Text  in den PRINT-Zeilen
erscheint  also  auf  dem  Bildschirm.   Anschließend
trifft  der Computer in Zeile 50 auf den GOTO Befehl,
der besagt, daß er bei Zeile 10 weiterarbeiten  soll.
Er  führt  diesen  Befehl aus, und beginnt wieder von
vorne bei 10. Dies wiederholt sich nun bis ins Unend-
liche. Pausenlos wird der Text ausgedruckt, und unser
64er  würde  dies Jahre lang machen, vorrausgestzt es
gäbe keinen Stromausfall. Er befindet sich  in  einer
sogenannten "Endlosschleife" eine Schleife, die immer
wieder  durchlaufen  wird, ohne daß Sie zu einem Ende
kommt. Eine Schleife ist  also  ein  bestimmter  Pro-
grammabschnitt, der mindestens  zweimal   durchlaufen
wird. Um nicht den ganzen Programmteil nochmals  ein-
geben und somit das Programm  unnötig  verlängern  zu
müssen verwendet man also den GOTO-Befehl. Nun  kommt
der Auftritt für die RUN/STOP-Taste. Drücken Sie  sie
einmal. Es erscheint nun:                            
break in  xx                                         
ready.                                               
Der  Computer  meldet  Ihnen also, daß Sie soeben das
laufende Programm in Zeile xx abgebrochen haben.  Für
"xx"  können alle Zeilennummern des Programms stehen,
da es Zufall ist, in welcher Zeile Sie  gerade  abge-
brochen  haben.  Auf  alle Fälle sind Sie nun unserer
Endlosschleife entkommen und können wieder  an  Ihrem
Programm  weiterarbeiten. Sollten Sie allerdings wie-
der den Wunsch hegen, schöne  Zeichenketten  auf  dem
Bildschirm  "runterlaufen"  zu sehen, dann können Sie
jetzt ganz einfach wieder mit CONT das Programm fort-
fahren lassen (CONT von engl.: to continue = fortset-
zen, fortfahren).                                    
Fassen wir doch einmal zusammen, wie weit  wir  schon
fortgeschritten  sind. Wir können mittlerweile kleine
Programme schreiben, die  etwas  auf  dem  Bildschirm
ausgeben, wir können rechnen, Programme mit Hilfe von
LIST editieren und kennen auch RUN, um diese zum lau-
fen zu bringen. Außerdem kennen wir uns mit den Namen
und Typen von Variablen aus. Nunja,  auf  den  ersten
Blick  erscheint dies ja sehr viel, doch direkt welt-
bewegende Programme können wir  noch  nicht  so  ganz
schreiben,  da  wir eigentlich nur einen einzigen Be-
fehl kennengelernt haben, mit dem sich innerhalb  von
Programmen etwas anfangen läßt, den PRINT-Befehl. Die
anderen  sind mehr oder weniger ausschließlich außer-
halb von  Programmen,  im  sogenannten  "Direktmodus"
nützlich, obwohl sie ebenso in Programmen funktionie-
ren würden. Wollen wir also nun unser  Befehlsspektum
noch  ein wenig mehr erweitern und wenden wir uns ei-
nem sehr mächtigen Befehl zu,  mit  dem  schon  etwas
mehr zu machen ist.                                  
Erinnern wir uns doch einmal an  unser  Beispiel  vom
letzten  Monat mit der Coladose. Wir hatten mit Hilfe
von Variablen die Oberfläche einer  Coladose  berech-
net. Diese Dose hatte eine Höhe von 11.5 cm und einen
Deckelradius  von  3.25  cm.  Mit  Hilfe  der  Formel
o=2*r*π*(r+h) sind wir dann zu dem Ergebnis 301.2 qcm
gekommen. Bedenkt man nun, daß durch  den  Trend  zum
Umweltschutz  es  heutzutage  durchaus  möglich  sein
könnte, daß man ein anderes Material für  Einwegdosen
erfinden  wird,  und  daß  man deshalb vielleicht ein
anderes Dosenformat wählen muß, so wäre unsere schöne
mühselige Rechnung nur noch Müll, da unbrauchbar. Man
müßte die ganze Prozedur nochmals mit den Werten  der
neuen   Dosen   durchführen.  Eine  mehr  oder  wenig
umständliche Sache also. Doch wozu können  wir  jetzt
Programme  schreiben,  wir hatten ja gelernt, daß die
Formel für die Zylinderoberfläche, wie ich  sie  oben
schon  aufgeführt  hatte,  ja allgemeingültig ist und
somit mit allen nur erdenklichen Werten für r  und  h
einen  richtigen  Wert liefert. Im Prinzip könnte man
nun ein Programm schreiben, daß diese Formel benutzt,
und würde dann hierfür die Variablen in einer  voran-
gehenden  Zeile  mit den entspechenden Werten versor-
gen. Doch wir machen es uns  noch  komfortabler,  wir
benutzen  den  INPUT-Befehl, der für Eingaben vom Be-
nutzer aus sehr empfänglich ist  (im  wahrsten  Sinne
des Wortes, denn INPUT bedeutet  nichts  anderes  als
"EINGABE"). Mit ihm wird es uns gestattet,  eine  Ab-
frage zu machen, auf die der Benutzer mit einer  Ein-
gabe antworten kann, und dies alles sogar  mitten  im
im Programm!!!                                       
Wir benötigen also Werte für  Radius  und  Höhe.  Wie
beim  letzten Mal wollen wir hierfür die Variablenna-
men r und h wählen. Sehen wir uns nun doch einmal die
ersten Zeilen unseres Programms an :                 
10 print chr$(14);                                   
20 print"[CLR,4 SPACE]Zylinderoberflaechenberechnung"
30 input"[2 DOWN]Radius ";r                          
40 input"Hoehe ";h                                   
Da haben wir ja schon eine ganze Menge neue Anweisun-
gen. Fangen wir einmal in Zeile 10 an. Sie sehen hier
einen PRINT-Befehl, doch was dieser Befehl ausdruckt,
können Sie nicht wissen. Eine String-Variable ist das
nicht (obwohl es fast so aussieht),  ich  kann  Ihnen
allerdings  versichern,  daß  es etwas ähnliches dar-
stellt. Dies ist die CHR$-Funktion. ACHTUNG! Ich  be-
tone das Wort FUNKTION! Es handelt sich hierbei wohl-
gemerkt NICHT um einen Befehl,  das  dürfen  Sie  nie
verwechseln.  Eine Funktion wird zwar ebenfalls durch
ein BASIC-Schlüsselwort  dargestellt,  doch  sie  ist
ohne einen verknüpfenden Befehl, oder eine Variablen-
zuweisung nicht ausführbar, da der Computer in diesem
Fall  nicht  spezifisch weiß, was er mit ihr anfangen
soll. Das heißt also, daß Sie  Funktionen  immer  mit
PRINT ausgeben, oder einer Variablen zuweisen können.
Zum Beispiel so:                                     
a$=chr$(65)                                          
print a$                                             
Es gibt übrigens  noch  mehr  Anwendungsmöglichkeiten
für Funktionen, doch werden wir hierzu später kommen,
da  Sie  die  entprechenden Befehle hierzu noch nicht
kennen.                                              
Was  bewirkt  die CHR$-Funktion?  Nun, CHR$, wird be-
nutzt um einzelne Zeichen  spezifiziert  aufrufen  zu
können.  Jedes Zeichen auf Ihrer Tastatur besitzt ei-
nen eigenen Zahlencode. Geben Sie  der  CHR$-Funktion
nun  diesen  Zahlcode  eines  Zeichen in Klammern an,
dann steht die ganze Funktion für  eben  dieses  Zei-
chen. In unserem  Beispiel von eben haben wir der Va-
riable a$ den Zeichencode 65 zugeordnet. Anschließend
wurde die Variable a$, in der ja nun dieser  Zeichen-
code  als  Buchstabe  dargestellt  war, auf dem Bild-
schirm ausgegeben. Dieses Zeichen, das zu dem Code 65
gehört, ist das kleine "a". Somit ist unsere  Variab-
lendefinition gleich der Definition:                 
a$="a"                                               
mit  der  ja auch der Buchstabe "a" dem String a$ zu-
geordet wird. Ich hoffe Sie  haben  dies  verstanden.
Somit  hat der folgende PRINT-Befehl auch das "a" auf
dem Bildschirm ausgedruckt. Genauso hätten  Sie  auch
schreiben können:                                    
print chr$(65)                                       
womit  Sie  das selbe Ergebnis erzielt hätten, aller-
dings nicht mehr über den Umweg mit der  Stringvaria-
ble.  Hier sei auch noch gesagt, daß das Ergebnis der
CHR$-Funktion immer einer Stringvariablen  zugeordnet
wird,  nicht  also einer Float- oder Integervariable,
da diese Variablentypen ja keine  Zeichen  darstellen
können.  Allerdings können Sie problemlos auch Anwei-
sungen von dieser Art vergeben:                      
a=65                                                 
a$=chr$(a)                                           
Hier  haben  wir  nicht den Zeichencode 65 in "a" ge-
speichert, sondern einfach nur den Zahlwert  65  (bei
"PRINT a" kriegen Sie wie  erwartet  "nur"  die  Zahl
65  auf  den  Bildschirm  gedruckt).  Sie dürfen also
Floats und Intergers benutzen,  um  den  Zahlwert  in
Klammern (von CHR$) anzugeben, dies führt also zu dem
selben  Ergebnis,  CHR$  holt sich den Wert von a aus
dem Speicher und ordnet dann dem String a$  den  Zei-
chencode  des  Zahlwerts  von a zu. Auf der Rückseite
dieser Magic Disk  finden  Sie diesmal auch ein klei-
nes  Programm  namens ASCII-Code. Es zeigt Ihnen alle
möglichen ASCII-Codes (das sind eben jene  Codes  der
Zeichen) des C64 an.                                 
Wollen wir in diesem  Zusammenhang  gerade  noch  die
Umkehrfunktion von CHR$ betrachten, die ASC-Funktion,
mit  der  Sie  sich beispielsweise den ASCII-Wert (so
nenne ich ab jetzt diesen Zeichencode, ASCII ist  ein
internationaler  Standard,  an  den  sich die meisten
Computerhersteller halten, die Zeichen haben also auf
den meisten Computern die selben  Codes.  Leider  ist
dies  beim  C64  aus unerfindlichen Gründen nicht der
Fall, trozdem wird auch hier  von  ASCII  gesprochen)
eines  Zeichens ausgeben lassen können. Hier geht al-
les genau umgekehrt, hier geben Sie ein  Zeichen  an,
und  es  kommt  ein  Zahlwert heraus. Dies müssen Sie
also  auch  bei  Variablenzuweisungen  beachten.  Die
ASC-Funktion sieht so aus:                           
print asc("a")                                       
Wie chr$, nur daß Sie jetzt das zu untersuchende Zei-
chen in Anführungsstrichen in die  Klammer  einsetzen
müssen.  Die Anführungsstriche deshalb, weil Sie hier
auch Strings als sogenanntes  Funktionsargument  ver-
wenden dürfen, diese dann allerdings OHNE Anführungs-
striche. Also:                                       
a$="a"                                               
print asc(a$)                                        
hätte die selbe Wirkung wie die oben aufgezeigte Zei-
le. Sie können sich so  also  alle  CHR$-Codes,  bzw.
ASCII-Codes ausgeben lassen, und dann bei Bedarf ver-
wenden. Auch ASC-Funktionswerte  kann  man  Variablen
zuweisen :                                           
a$="x"                                               
a=asc("x")                                           
a%=asc(a$)                                           
Die beiden letzten Zeilen führen zum selben Ergebnis,
nur daß der eine Wert in der  Floatvariable  "a"  ge-
speichert ist  und der andere in der Integervariablen
"a%".  Außerdem  ist  der  Weg, mit dem die Ergebnise
erreicht werden jeweils ein anderer, doch das dürften
Sie mittlerweile ja kennen.                          
Doch wollen wir uns nun, nach  unsrem  langen  langen
Ausflug zu den ASCII-Codes wieder unserer Zylinderbe-
rechnung widmen. Wir sind ja gerade dadurch auf  die-
ses Thema gekommen...                                
In Zeile 10 stand der Befehl PRINT CHR$(14).  Es wur-
de also ein ASCII-Zeichen ausgegeben,  mit  dem  Zei-
chencode  14.  Dieser  Code steht für eine sogenannte
"Steuerfunktion". Mit einer Steuerfunktion können Sie
ein Zeichen ausgeben, das nicht direkt als  Buchstabe
auf  dem Bildschirm sichtbar wird,  sondern eher eine
"unsichtbare" Funktion ausübt, wie zum  Beispiel  den
Bildschirm  zu  löschen,  den Cursor eine Zeile höher
oder tiefer rücken zu lassen, oder  die  Zeichenfarbe
zu verändern. Unser Code 14 bewirkt, daß der Zeichen-
satz von Groß- auf Kleinschrift umgeschaltet wird. Er
hat also die  selbe  Wirkung  wie  das  gleichzeitige
Drücken  der  SHIFT- und der Commodoretaste. Dies ist
deshalb notwendig, damit beim späteren  Ausdruck  von
"Zylinderoberflächenberechnung"   in  Zeile  20,  der
Großbuchstabe "Z" nicht etwa als Grafikzeichen ausge-
geben  wird,  was  leicht  passieren  kann, zumal die
Großschrift doch  direkt  nach  dem  Einschalten  des
64ers vorhanden ist.                                 
Sicher ist Ihnen der Text in den    eckigen  Klammern
- [ ] - aufgefallen, dies ist  kein  Programmtext  im
allgemeinen,  hiermit  habe  ich ebenfalls angegeben,
welche Steuerzeichen an dieser Stelle eingefügt  wer-
den  müssen. Sie wissen ja, unsere Zeichen, die keine
sind, sondern etwas bestimmtes  ausführen.  Man  kann
Sie  nämlich  auch  direkt  in  die   PRINT-Anweisung
einfügen, zumal das auch einfacher und platzsparender
ist. Ich tat dies bei CHR$(14) bewußt  nicht, da  Sie
so  bei  der  Gelegenheit  einmal  die CHR$- und ASC-
Funktion kennenlernen konnten, und weil außerdem die-
ses  Steuerzeichen  nicht als solches in einer PRINT-
Anweisung darstellbar ist (es gibt zwar  schon  einen
Weg,  doch das wäre jetzt hier zuviel). Doch wie sol-
len Sie denn überhaupt  diese  Steuerzeichen  in  die
PRINT-Anweisung  hereibringen?  Die Lösung ist ebenso
einfach wie genial. Sie müssen lediglich, NACHDEM Sie
den auszugebenden Text  mit  einem  Anführungszeichen
schon angekündigt haben, die entspechende Taste drük-
ken, und schon wird unser  Steuerzeichen   mit  einem
inversgedruckten Zeichen dargestellt. Von nun an wis-
sen Sie, daß an dieser Stelle dann ein  Steuerzeichen
gedruckt  wird.  Die  Steuerzeichen können Sie ebenso
wie normale Buchstaben überall innerhalb  der  Anfüh-
rungsstriche  einfügen.  Mit der Zeit werden Sie dann
auch lernen, diese an Ihren Reverszeichen  zu  erken-
nen.                                                 
Inverszeichen  wurden deshalb gewählt, da man sie in-
nerhalb einer PRINT-Klammer nicht verwenden kann, man
kann trotzdem aber inverse Texte ausgeben, indem  man
einfach  die Steuerzeichen für RVS ON und RVS OFF be-
nutzt. Die Zeichen zwischen diesen Steuerzeichen wer-
den dann auch invers gedruckt.                       
In  unserem  Fall  müssten  Sie  also  ein CLR (CLEAR
(dtsch.: lösche) =  SHIFT +  CLR/HOME-Taste)   einfü-
gen.  Ich  werde in Zukunft bei solchen Steuerzeichen
bestimmte  Ausdrücke  in  eckigen  Klammern  angeben.
Damit Sie wissen welche Zeichen nun gemeint sind. Die
Programme, die sich ja auf der  Rückseite  der  Magic
Disk befinden, werden dann natürlich immer schon  die
entspechenenden  Steuerzeichen  in  Reversdarstellung
enthalten, da wir ja keine "geschweiften" Texte nach-
her auf dem Bildschirm haben wollen. Diese Ausdrücke,
die ich verwenden werde,  werde  ich  Ihnen  dann  im
nachfolgenden Text immer noch  erläutern,  damit  Sie
wissen, was gemeint war.                             
Nachdem wir uns jetzt wohl zur Genüge in den ersten 2
Zeilen  unseres  Programms verrannt haben, wollen wir
uns nun endlich dem Befehl widmen, von  dem  ich  an-
fangs  gesprochen  hatte. Sie werden ihn schon in den
Zeilen 30 und 40 bemerkt haben.  Es  ist  der  INPUT-
Befehl. Übersetzen wir doch einmal:                  
INPUT = engl. EINGEBEN, EINGABE                      
Na wunderar, wir können also etwas eingeben. Und  das
auch noch wahnsinnig komfortabel, denn  Sie  brauchen
lediglich dem INPUT-Befehl eine Variable zu geben, in
der  er die Eingabe ablegen soll und schon weiß unser
Programm genauer, was sein  Benutzer  von  ihm  will.
Sehen wir uns die Syntax einmal genauer an:          
30 INPUT"Radius ";r                                  
Ich muß hier noch anmerken, daß ich bei  diesem  Bei-
spiel,  die  im  Programm  vorkommenden Steuerzeichen
weggelassen habe. Es ist dort von [2 DOWN] die  Rede,
womit  Sie aufgefordert sind, 2 mal die Taste "Cursor
runter" zu drücken.                                  
Wie  Sie  an den Steuerzeichen und auch an den Anfüh-
rungsstrichen erkennen können, kann man auch bei  IN-
PUT  einen  Text  angeben, der vor Ausführung der ei-
gentlichen Eingabe  ausgegeben  werden  soll.  Hinter
einem  Semikolon  (oder  Strichpunkt  -  ;) wird dann
noch der Name einer Variablen angehängt,  in  unserem
Fall  "r"  für  den Radius. Probieren Sie doch einmal
obige Zeile als Programm aus.                        
Sie  MÜSSEN  übrigens  unbedingt  den INPUT-Befehl im
Programm verwenden, da es vom Direktmodus aus zu Feh-
lern  kommen kann, da der INPUT-Befehl im Direktmodus
keinen Sinn hat. Deshalb haben die Programmierer  von
BASIC  2.0  sich gesagt, daß die Benutzung dieses Be-
fehls im Direktmodus nicht erlaubt sein darf und des-
halb mit einer Fehlermeldung quittiert wird.         
Sie  sehen,  wenn Sie alles richtig eingegeben haben,
nun folgendes auf dem Bildschirm :                   
Radius ?                                             
und einem blinkenden Cursor hinter dem  Fragezeichen.
Sie  sind  nun  dazu  aufgefordert einen Wert für den
Radius einzugeben. Tun Sie dies also. Geben Sie  doch
beispielsweise einmal 3.25 ein:                      
Radius ? 3.25                                        
und  drücken Sie die Return-Taste. Das Programm endet
nun, vorausgesetzt, Sie hatten auch wirklich nur die-
se  eine  Zeile  im  Speicher  stehen. Geben Sie doch
jetzt einmal im Direktmodus:                         
print r                                              
ein. Was sehen Sie?  Es erscheint der  Zahlwert  3.25
auf  dem Bildschirm! Genau Ihre Eingabe, die Sie soe-
ben taten. Na ist ja entzückend - würde Kojak, lolli-
lutschend, jetzt sagen. Merken Sie was INPUT tat?  Es
hat  Ihre  Eingabe  gleich  einer Variablenwertzuwei-
sung, der Variable "r" zugeordnet und in ihr  gespei-
chert!  Dies geht sogar noch weiter! Sie dürfen sogar
Strings  und Integers benutzen, um Eingaben in Varia-
blen ablegen zu können.  Ein  solches  Programm  wäre
also auch denkbar:                                   
10 input"Wie heissen Sie bitte ";n$                  
20 input"Und wie alt sind Sie ";a%                   
30 print"Sie heissen ";n$;"und sind "a%" Jahre alt." 
Sie  sehen,  hier  benutzen  wir einen String n$ (für
Name) und eine Integervariable a%  (für  Alter).  Den
Integer  können wir bedenkenlos anwenden, da ja Alter
im allgemeinen  mit  ganzen  Zahlen  angegeben  wird.
Vielleicht ist Ihnen allerdings etwas aufgefallen:   
Obwohl wir KEIN Fragezeichen in unserem  Text  stehen
hatten,  erschien  doch  eins auf dem Bildschirm. Wie
denn das?  Nun, INPUT druckt grundsätzlich immer  ein
Fragezeichen  am  Ende  seines Textes aus, da ja nach
etwas gefragt wird,  und  somit  dieses  Fragezeichen
auch  berechtigt ist. Es wird vielleicht Fälle geben,
in denen es Sie stören wird, da es nicht in den  Kon-
text  der  Frage passt, doch werden wir später einmal
behandeln, wie man es abschalten kann.               
Im  Übrigen  brauchen  Sie auch nicht unbedingt einen
Text mit INPUT auszugeben, Sie können dies  auch  un-
terdrücken, indem  Sie  die Anführungsstriche und das
Semikolon einfach weglassen  und  den  Variablennamen
einfach anhängen. Also so beispielsweise:            
10 input a$                                          
20 input a                                           
30 input xx%                                         
Ebenfalls ist es möglich, mehrere Eingaben gleichzei-
tig aufzunehmen. Ich finde diese  Methode  allerdings
sehr  unbequem,  und außerdem gefällt es mir getrennt
besser, doch möglich wäre auch dies:                 
10 input "Koordinaten (X/Y) ";x,y                    
Sie können hier also gleich mehrere  Werte  abfragen,
die  allerdings  mit einem Komma voneinander getrennt
sein sollten. Jetzt wissen Sie auch, wofür das  Komma
reserviert  ist, da wir ja gesagt hatten, daß das De-
zimalkomma bei Floatvariablen immer einem Punkt  ent-
spricht. Die Eingabe müßte dann so aussehen:         
Koordinaten (X/Y) ? 22.3,10                          
Den  Variablen  x und y wären dann folgende Werte zu-
geordnet worden:                                     
x=22.3                                               
y=10                                                 
Leider  muß  ich  nun  an dieser Stelle abbrechen, um
keinen Informationsstau bei Ihnen hervorzurufen. Ver-
suchen  Sie  erst einmal die eben erkannten neuen Be-
fehle kennenzulernen. Sie können sich ja auch  einmal
das gesamte Zylinderberechnungsprogramm auf der Rück-
seite dieser Magic Disk 64  ansehen.  Nächsten  Monat
werde  ich  es dann auf jeden Fall zu Ende kommentie-
ren. Des weiteren wollen wir uns dann mit der Schlei-
fenprogrammierung  und den Entscheidungsbefehlen (und
-operatoren) widmen.                                 
Bis  dahin  wünsche  ich  Ihnen weiterhin ein allzeit
"Gut Hack",                                          
                                      Ihr Uli Basters
G                                                    
     BASIC-Kurs : "Von Adam und Eva..." (Teil 3)     
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾     
Auf in die dritte Runde in unserem Basickurs.  Diesen
Monat  wollen  wir endlich unser Zylinderberechnungs-
programm  zu Ende abhandeln, um uns anschließend noch
ein paar  kleine,  nichtsdestotrotz  ebenso  wichtige
Befehle anzuschauen.                                 
So. Nun also weiter. Nachdem Sie die Fülle an  Infor-
mationen  letzten  Monats hoffentlich verarbeitet ha-
ben, möchten wir uns nun gleich frisch ans  Werk  ma-
chen  und  den  Rest  unseres Zylinderberechnungspro-
gramms abhandeln. Erinnern wir uns:                  
Wir hatten uns die ersten 40  Zeilen  angeschaut  und
dabei den INPUT-Befehl kennengelernt, sowie die CHR$-
und  die  ASC-Funktion. Außerdem  hatten wir uns noch
ein wenig mit den Steuercodes befaßt,  und ich hoffe,
daß Sie mit dem ASCII-Druck-Programm auf der Rücksei-
te  ebenfalls  etwas  anzufangen  wußten, hier gab es
nämlich auch noch eine Menge weiterer  Steuerfunktio-
nen zu finden, die wir im einzelnen im Laufe des Kur-
ses noch kennenlernen werden.                        
Doch  nun weiter im Text, sprich im Listing (so nennt
man die vom Computer geordnete  Liste  der  einzelnen
Programmzeilen) unseres kleinen Programms, machen wir
weiter  ab  Zeile  50, also LIST 50- (Sie wissen doch
wohl hoffentlich noch, was dies bewirkt ?!?):        
50 o=2*r*π*(r+h)                                     
60 print"[2 DOWN]Die Oberflaeche eines Zylinders mit"
70 print"der Hoehe"h"und dem Radius"r                
80 print"betraegt";o                                 
90 input"[2 DOWN]Noch eine Berechnung (J/N)";a$      
100 if a$="j"then run                                
110 end                                              
Zeile  50 kennen wir ja noch von unseren Versuchen im
Direktmodus. Mit ihr können wir die Berechnung  unse-
res  Zylinders  durchführen, und das allgemeingültig,
denn wir können für Radius (r) und Höhe (h) beliebige
Werte angeben. Diese müssen halt nur  vorher  festge-
legt  werden.  Wie Sie sich erinnern, hatten wir dies
in den Zeilen 30 und 40 erledigt,  wo  wir  die  zwei
INPUT-Befehle  untergebracht hatten, die diese beiden
Variablen einlesen sollten. Also wird in dieser Zeile
nun  die  eigentliche  Berechnung  durchgeführt,  an-
schließend  steht  dann  in  der  Variablen  "o"  die
Oberfläche des verlangten Zylinders.  Bitte  verwech-
seln Sie nie den Buchstaben o mit der Zahl 0!        
Die  Zeilen 60-80 sind jetzt nur noch für die korrek-
te, beziehungsweise formatierte  Ausgabe  des  Ergeb-
nisses  der  Rechnung verantwortlich. Damit das alles
ein weing besser aussieht (denn darauf sollte man als
Programmierer ebenfalls achten, daß die  Nachrichten,
die ein solches Programm ausgibt auch leichtverständ-
lich und ansprechend lebendig  sind),  habe  ich  das
Ergebnis  in einen kleinen Satz eingebunden. Zunächst
wird einmal Platz geschaffen, indem die Textausgabe 2
Zeilen tiefer geschoben wird (das Steuerzeichen  DOWN
dürften  Sie ja noch aus der letzten Ausgabe kennen),
jetzt haben wir das ganze  schön  abgesetzt  von  den
anderen  Buchstaben  auf dem Bildschirm plaziert. Nun
druckt Zeile 60 den Text "Die Oberflaeche  eines  Zy-
linders  mit" aus. In der nächsten Zeile geht es dann
weiter mit "der Hoehe" und nun  sehen  Sie  nach  den
Anführungsstrichen  den  Buchstaben "h" eingefügt. Da
sich dieser außerhalb  der  "Gänsefüßchen"  befindet,
wird  er auch nicht als Text, sondern, wie wir es bei
vorherigen PRINT-Anweisungen ja schon gesehen  haben,
als  Variablenname  interpretiert. Deshalb wird jetzt
nicht ein "h" ausgedrucht sondern  ganz  einfach  der
Wert  der  Variablen  h.  Ebenso geht es dann bei dem
anschliessenden Text, der direkt nach unserer  Varia-
blen  wieder  in  Anführungszeichen  folgt. Auch hier
wird am Ende dann der Wert der Variablen  "r"  ausge-
druckt.                                              
Interessant wird es dann wieder in Zeile 80, hier ist
eine weitere Funktion  des  PRINT-Befehls  enthalten,
die Ihnen vielleicht aufgefallen ist:                
Nach  dem  Text  "betraegt" folgt ein Semikolon (oder
Strichpunkt)  wie  bei  INPUT  und  anschließend  der
Name  der  Variablen, die hier folgen soll ("o"). Ich
muß gleich zugeben, daß  der  Strichpunkt  an  dieser
Stelle  eigentlich total überflüssig ist  und daß man
ihn auch genausogut weglassen  könnte,  nur  paßt  er
gerade  gut  in  den  Stoff,  weshalb ich Ihnen seine
Funktion nicht vorenthalten möchte.                  
Wie  Ihnen vielleicht aufgefallen ist, arbeitet jeder
PRINT-Befehl so, daß er nachdem er einen Text  ausge-
geben  hat in eine neue Zeile springt, wo der nächste
PRINT-Befehl dann wieder seine Arbeit fortseten kann.
Ersichtlich wird das in folgendem kleinen Programm:  
10 PRINT"DAS IST IN EINER "                          
20 PRINT"ZEILE !!!"                                  
Starten Sie es, so sehen Sie folgendes auf dem  Bild-
schirm :                                             
DAS IST IN EINER                                     
ZEILE !!!                                            
Was zum ausgegebenen Text  wohl  total  im  Gegensatz
steht.  Doch  PRINT  hat hier genau das getan, was er
sollte. Nach Zeile 10 hat er den Cursor an den Anfang
der nächsten Zeile gesetzt und dann den Text aus Zei-
le   20  ausgedruckt  (durch  einen  erneuten  PRINT-
Aufruf).                                             
Doch was hat das alles mit unserem Semikolon zu tun ?
Nun,  das  Semikolon  am Ende eines PRINT-Befehls be-
wirkt, daß das  eben  beschriebene  Springen  in  die
nächste  Zeile unterdrückt wird. Ändern Sie doch ein-
mal unser Programm folgendermaßen ab:                
10 PRINT"DAS IST IN EINER ";                         
20 PRINT"ZEILE !!!"                                  
Starten Sie es jetzt so sehen Sie:                   
DAS IST IN EINER ZEILE !!!                           
Womit diesmal tatsächlich alles "in einer Zeile ist".
In  unserem  Zylinderberechnungsprogramm  hat das ei-
gentlich keinen Zweck, denn das, was nach dem Semiko-
lon ausgedruckt wird, würde sowieso schon direkt fol-
gen, da das Drucken der Variablen  "o"  ja  noch  zum
selben  PRINT-Befehl  gehört. Doch wäre durchaus auch
so etwas denkbar:                                    
80 PRINT "betraegt";                                 
85 PRINT o                                           
Würden  Sie  diese  beiden  Zeilen  in unser Programm
einfügen, so kämen Sie ebenfalls zum selben Ergebnis.
Nun weiter in den folgenden Zeilen, von 90-110.  Hier
gibt es nämlich wieder etwas  neues  zu  lernen:  der
IF-THEN-Befehl.  Ich  liste  Ihnen  diese Zeilen hier
noch einmal auf, damit Sie sich das ein wenig genauer
ansehen können:                                      
90 input"[2 DOWN]Noch eine Berechnung (J/N)";a$      
100 if a$="j"then run                                
110 end                                              
Zunächst einmal Zeile 90. Hier  fragen  wir,  nachdem
wir  die  Augabe um 2 Zeilen nach unten geschoben ha-
ben, um dem ganzen einen besseren Eindruck zu verlei-
hen zunächst einmal, ob der Benutzer noch eine weite-
re Zylinderberechnung verlangt. Das heißt, ob er  den
Rechenvorgang   eventuell   wiederholen  möchte  oder
nicht.                                               
Hier  kann  er, wie vom Text vorgeschlagen, mit J für
JA, oder mit N für NEIN antworten.  Die  Antwort,  zu
der  er  sich  entscheidet,  wird dann in der String-
Variablen "a$" abgespeichert.                        
Nun das neue:  in Zeile 100 sehen wir die  sogenannte
IF-THEN-Klammer.  Übersetzen wir doch erst eimal wie-
der aus dem Englischen :  WENN-DANN.  Wie  Sie  viel-
leicht  erraten,  ist  dieser Befehl dazu gedacht be-
stimmte Abrfragen auf ihren Wahrheitsgehalt  zu  prü-
fen,  um  anschliessend  entsprechend  im Programm zu
verzweigen. Ich kann gleich anmerken, daß  dies  wohl
einer  der  wichtigsten Befehle für Programme ist, da
Sie ohne ihn kaum komplexere Dinge schreiben könnten,
als unsere einfache Zylinderberechnung. Hier  benutze
ich  ihn  eigentlich  nur,  um das Programm ein klein
wenig komfortabler zu machen, und um außerdem  diesen
äußerst  wichtigen  Befehl einzuführen. Was geschieht
nun in Zeile 100?                                    
Ganz einfach :                                       
1.) Der IF-Befehl prüft, ob die ihm  folgende  Bedin-
    gung  erfüllt ist, das heißt, ob in der Variablen
    "a$" der Buchstabe "j" enthalten ist.            
2.) Sollte  diese  Bedingung "wahr" sein, so wird der
    Computer ganau  das  ausführen,  was  hinter  dem
    THEN-Wort  folgt.  In  unserem  Fall würde er den
    RUN-Befehl aufrufen, der unser  kleines  Programm
    wieder  von  vorne  ablaufen  lassen  würde. Aber
    jetzt kommt der Clou:                            
3.) Sollte  die  Bedingungen "unwahr" sein, oder ganz
    einfach "falsch", dann wird der Teil hinter  THEN
    ignoriert  und  einfach  in  der Zeile hinter der
    IF-THEN-Klammer weitergemacht.  In  unserem  Fall
    steht  hier  der  Basic-Befehl  END, den wir noch
    nicht kennen, den ich Ihnen später jedoch genauer
    erläutern werde. Erst einmal zu IF-THEN :        
Sie sehen also, hier wurde ganz einwandfrei eine Ent-
scheidung vom Computer getroffen. Aufgrund einer Ein-
gabe des Benutzers wurde eine bestimmte Reaktion ver-
anlasst. Wenn Sie  "j"  eingaben, dann  startete  das
Programm  wieder von vorne, wie es ja auch sein soll-
te, wenn man "noch eine Berechnung" wünscht,  andern-
falls  wurde das Programm beENDet (nichts anderes tut
der END-Befehl, doch ist trotzdem noch mehr zu ihm zu
sagen).                                              
Um  den  IF-THEN-Befehl  (es ist nur  ein  Befehl, da
die beiden Teilworte alleine keinen Sinn ergeben  und
vom  Computer  auch mit einem ERROR quittiert werden)
zu benutzen brauchen wir also zum einen  eine  Bedin-
gung,  nach der unterschieden werden soll und zum an-
deren einen oder mehrere Befehle, die beim  Zutreffen
der gestellten Bedingung ausgeführt werden sollen.   
Als Bedingungen können Sie hier mit  allen  Variablen
"spielen"  die  unser Computer kennt, oder Sie können
auch einfach nur Argumente angeben, wobei dies  nicht
unbedingt sinnvoll ist, da eine folgende Bedingung ja
immer  wahr wäre, und man somit sich die Abfrage spa-
ren könnte:                                          
IF 3=3 THEN PRINT"3 ist gleich 3."                   
Dies  allerdings nur einmal als kleines Beispiel, da-
mit Sie auch verstehen, was mit  "Bedingung"  gemeint
ist.  Weitaus  sinnvoller als Abfrage wäre schon eher
so etwas:                                            
IF A=B THEN PRINT"A und B sind gleich."              
Hier könnten die beiden Variablen tatsächlich  einmal
verschieden von einander und einmal gleich sein.     
Bei den Bedingungen, die Sie angeben  können,  müssen
Sie,  wie Ihnen vielleicht aufgefallen ist, immer ei-
nen sogenannten  "Vergleichsoperator"  angeben.  Dies
ist  ein  Operator, mit dem wir dem Computer klar ma-
chen, in welcher Weise nun  verglichen  werden  soll,
denn  man kann die einzelnen Vergleichsargumente auch
relativ aufeinander beziehen. So wären  zum  Beispiel
die folgenden Ausdrücke vollkommen identisch :       
IF A>B THEN PRINT"A ist groesser B."                 
IF B<A THEN PRINT"A ist groesser B."                 
Zumal ja automatisch mit der Bedingung, daß "A" klei-
ner  als "B" ist, auch gesagt ist, daß "B" größer als
"A" ist. Hier  werden  natürlich  die  Variablenwerte
verglichen.  Wie  wir ja gelernt haben  müßte das bei
Strings ja dann in Gänsefüßchen  stehen.  Sie  können
übrigens problemlos auch ganze Wörter vergleichen:   
IF a$="BASIC" THEN PRINT "BASIC find ich auch super!"
Doch  nun  wieder  zu  den Vergleichsoperatoren. Hier
können Sie mehrere Arten  verwenden,  die  ich  Ihnen
hier einmal auflisten möchte:                        
a=b   A gleich B                                     
a<>b  A ungleich B (entweder größer oder kleiner)    
a>b   A größer B                                     
a<b   A kleiner B                                    
a>=b  A größer oder gleich B                         
a<=b  A kleiner oder gleich B                        
Zu den beiden letzten Punkten sei noch zu sagen,  daß
sie ebenso auch folgendermaßen lauten könnten :      
a=>b  A gleich oder größer B                         
a=<b  A gleich oder kleiner B                        
Hierbei bewirken beide Schreibarten dasselbe.        
Es gibt übrigens noch 3 weitere Vergleichsoperatoren,
die wir aber hier vorläufig übergehen wollen,  da  zu
deren  Verständnis  weitere Grundkenntnisse vorausge-
setzt sein müssen. Nun noch zu END:                  
Wie bereits erwähnt  sorgt dieser Befehl  dafür,  daß
ein  Basicprogramm  beENDet wird. Der Computer bricht
an dieser Stelle ganz einfach ab und meldet sich   im
Direktmodus  mit  "READY." wieder zurück. Auch dieser
Befehl ist an der Stelle im Programm eigentlich  ganz
überflüssig, denn sollte Ihr C64 irgendwann einmal am
Ende  eines  Listings,  also in der letzten Zeile des
Programms, daß er zu diesem Zeitpunkt gerade abarbei-
tet angelangt sein, so wird er es sowieso beenden und
in  den  Direktmodus  zurückspringen. Ich habe diesen
Befehl eigentlich auch nur deshalb benutzt, weil  ich
ihn  Ihnen halt vorstellen wollte. Ich hätte Ihn bes-
ser anders benutzt, dann wäre er sinnvoller  gewesen.
Sie  können  ja  die  Zeilen 100 und 110 unseres Pro-
gramms einmal folgendermaßen abändern:               
100 IF a$="n" THEN END                               
110 RUN                                              
Dies  hat den selben Effekt, nur daß Sie nun den Sinn
des END-Befehls sehen. Hier ist  es  unbedingt  nötig
das  Programm  abzubrechen,  und da es dies nicht von
selbst tut, da es ja  noch  eine  Zeile  hat  die  es
ausführen könnte, müssen wir dieses Beenden sozusagen
"künstlich" erzwingen...                             
Wie Ihnen womöglich auffiel, hatte ich  vorhin  übri-
gens  von mehreren Befehlen (also Plural) gesprochen,
die nach dem THEN ausgeführt werden können.          
Doch wie?  Hierzu kennt BASIC das Befehlstrennzeichen
":".  Ja,  ein  ganz  schlichter Doppelpunkt, mit ihm
können Sie dann 2 Befehle in einer Zeile  voneinander
trennen,  ohne  einen  SYNTAX  ERROR zu erhalten, bei
IF-THEN sähe das so aus :                            
IF a$="n" THEN PRINT"Tschuess dann, bis zum naechsten
Mal...":END                                          
Sie sehen, hier haben wir  zunächst  einen PRINT- und
dann  den END-Befehl, beide getrennt durch einen Dop-
pelpunkt. Diesen Trick können Sie auch  so  in  einer
normalen  Zeile  (also  in einer solchen, in der KEIN
IF-THEN steht) anwenden. Etwa so:                    
10 PRINT"Das ist eine Endlosschleife mit viel Gedruk-
ke!!!";:GOTO 10                                      
Probieren Sie es, nun haben wir unsere Endlosschleife
vom  letzten  Mal  in nur EINE Zeile gepackt, und sie
funktioniert genauso zuverlässig. Wie man  sie  jetzt
auch wieder "endlich" macht wissen Sie ja mittlerwei-
le - einfach RUN/STOP drücken.                       
Die  einzige  Grenze  für  Zeilen  mit  Doppelpunkten
stellt die maximale Länge einer  BASIC-Programm-Zeile
dar.  Grundsätzlich  darf  eine Programmzeile nämlich
nie mehr als 80 Zeichen lang sein (also 2 Bildschirm-
zeilen).  Dies  ist  eine  computerinterne Regel, die
etwas mit der Art und Weise zu tun hat, mit der  eine
Zeile  im  Speicher des Computers abgespeichert wird.
Alles, was Sie mehr eingeben, wird radikal vom Compu-
ter  abgeschnitten, er akzeptiert also nur maximal 80
Zeichen.                                             
Ich kann Ihnen übrigens gleich verraten, daß der Dop-
pelpunkt auch seine Nachteile hat.                   
Vorteilhaft ist, daß der Computer Programme mit  vie-
len  Doppelpunkten,  wo die einzelnen Befehle also in
lange  Zeilen  zusammengefasst  sind,   grundsätzlich
schneller abarbeitet, als die gleiche Befehlsfolge in
mehreren  Zeilen. Dies hat ebenfalls etwas mit inter-
nen Vorgängen zu tun, nämlich ganz einfach damit, daß
der Computer einen Doppelpunkt schneller erkennt, als
eine neue Programmzeile, beziehungsweise ist  er  ge-
zwungen, beim  Abarbeiten einer jeden neuen Zeile ein
paar Arbeitsvorgänge mehr ablaufen zu lassen. Deshalb
also ein (ganz,ganz) geringer Zeitgewinn bei der  Be-
nutzung des Doppelpunkts.                            
Ebenso vorteilhaft ist auch, daß durch die  Benutzung
des  Doppelpunkts  Speicherplatz  gespart  wird.  Die
Speicherung einer  neuen  Programmzeile  kostet  mehr
Platz im Hauptspeicher des C64 als ein einzelner Dop-
pelpunkt.                                            
Doch  nun  der große Nachteil, weshalb ich Ihnen auch
sehr von der Benutzung des Doppelpunkts außerhalb von
IF-THEN-Klammern abrate. Dadurch, daß alles  so  dur-
cheinander  über  2  Bildschirmzeilen verteilt steht,
entsteht ein wahres Chaos auf  dem  Bildschirm,  wenn
Sie Ihr Programm einmal listen sollten. Es wird durch
den  Doppelpunkt sehr, sehr unübersichtlich, was eine
Tücke von BASIC ist, die einem  als  Anfänger  häufig
Schwierigkeiten  macht.  Ich empfehle Ihnen also, den
Doppelpunkt nur dann zu  benutzen,  wenn  nicht  sehr
viel  Unheil durch ihn im Gesamtbild des Listings auf
dem Bildschirm entsteht (also nur,  wenn  alle  durch
ihn getrennten Befehle noch in EINE Bildschirmzeile -
das  sind  40  Zeichen  -  passen).  Und  in IF-THEN-
Klammern, wo es manchmal unerläßlich ist, mehrere Be-
fehle  auszuführen,  bevor  BASIC dann in der IF-THEN
folgendenden Zeile mit seiner Arbeit fortfährt.      
Hier gibt es übrigens auch eine Alternative  mit  der
Sie auch bei IF-THEN keine Probleme bekommen sollten,
was  die Formatierung des Programmtextes angeht, denn
nichtsdestotrotz   wird   eine  "Doppelpunkt-IF-THEN-
Zeile"  ebenso  unübersichtlich  wie eine normale 80-
Zeichen-Zeile. Hierbei hilft uns eine kleine Eigenart
des THEN-Befehls. Sie könnten  nämlich  eine  längere
Befehlsfolge ebensogut auch in mehreren Zeilen unter-
bringen, die Sie, von ihren Zahlennummern  her  gese-
hen,  ein wenig vom Hauptprogramm absetzen, und diese
dann mit ihrer Zeilennummer DIREKT anspringen.  Denk-
bar wäre folgendes :                                 
10 INPUT"[CLR]WOLLEN SIE TEXT SEHEN (J/N) ";a$       
20 IF a$="J" THEN 200                                
30 PRINT"DANN NICHT...":END                          
40 :                                                 
200 PRINT"DAS IST IHR GEWUENSCHTER TEXT..."          
210 PRINT"UND HIER NOCH EINE KLEINE ZUGABE AN"       
220 PRINT"TEXT, DAMIT SIE SICH NICHT VERAEPPELT"     
230 PRINT"FUEHLEN, UND DAMIT HIER AUCH NOCH MEHR"    
240 PRINT"ZEILEN GEFUELLT WERDEN."                   
Zuerst haben wir in Zeile 10 die Abfrage, ob die Ein-
sicht vom Benutzer in den  Text  überhaupt  erwünscht
ist.  Die  Antwort,  wieder ein J oder ein N, wird in
der Variablen a$ gespeichert.  Dann  folgt  eine  IF-
THEN-Abfrage,  ob die Anwort ein "J" war. Wenn nicht,
dann wird der Text "DANN  NICHT..."  ausgedruckt  und
das Programm wird beendet.                           
Sollte die Antwort allerdings tatsächlich "J" gewesen
sein, traf unsere Bedingung also zu, so  springt  der
Computer  gleich  weiter zu Zeile 200, wo er dann den
gewünschten Text ausdruckt, der hier  getrennt  in  5
eigenen  Zeilen  abgelegt  wurde.  Bestimmt ist Ihnen
aufgefallen, daß merkwürdigerweise nur die Zeilennum-
mer unserer gewünschten Zeile hinter dem THEN folgt. 
Dies ist eben jene Eigenart des THEN-Befehls, von der
ich  eben sprach. Er interpretiert Zahlen, die direkt
nach ihm folgen grundsätzlich immer als eine  Zeilen-
nummer,  auf die er springen soll. Er führt sozusagen
den Befehl GOTO 200 (oder GOTO xxxx) aus. Ändern  Sie
Zeile 20 doch einmal folgendermaßen um:              
20 IF a$="J" THEN GOTO 200                           
Sie werden feststellen, daß Sie hiermit genau dassel-
be  erreichen  wie  vorher, allerdings mit dem Unter-
schied, daß diese Zeile langsamer abgearbeitet  wird,
da  der  GOTO-Befehl  ja noch erkannt werden muß, und
daß sie außerdem auch noch  mehr  Speicherplatz  ver-
braucht.  Die  Kurzschreibweise ist also nur von Vor-
teil und sollte eigentlich immer verwandt werden.    
Auf diese Weise können Sie übrigens auch Programmzei-
len überspringen, etwa so:                           
10 INPUT"[CLR]WUENSCHEN SIE TEXT (J/N) ";a$          
20 IF a$="N" THEN 40                                 
30 PRINT"HIER IST TEXT FUER SIE..."                  
35 END                                               
40 PRINT"NIX TEXT!"                                  
Die ersten 2 Zeilen sind ja mittlerweile  ein  "alter
Hut" für uns. In Zeile 20 sehen Sie, daß bei der Ant-
wort "N" ganz einfach der Teil, der bei "J"  gekommen
wäre  (bzw.  auch  bei jedem anderen Zeichen, das un-
gleich "N" gewesen wäre, wie auch in  den  Beispielen
zuvor,  ich hatte es dort allerdings nie erwähnt, die
Zeilen 30 und 35 ausgeführt  werden.  Sie  können  es
gerne  einmal  ausprobieren und mit "Y" oder "Z" ant-
worten...) übersprungen wird. Wenn nicht,  dann  wird
der  folgende  Teil  ausgeführt.  Von hier können Sie
entweder gleich mit END aufhören, oder  Sie  springen
dann  von dort wieder mit GOTO hinter die Zeilen, die
bei "N" ausgeführt worden wären. Dies  sähe  dann  so
aus:                                                 
10 INPUT"[CLR]WUENSCHEN SIE TEXT (J/N) ";a$          
20 IF a$="N" THEN 40                                 
30 PRINT"HIER IST TEXT FUER SIE..."                  
35 GOTO 50                                           
40 PRINT"NIX TEXT!"                                  
50 END                                               
Ich hoffe Ihnen nun klar und deutlichst die Benutzung
und vor allen Dingen den Sinn von  IF-THEN  dargelegt
zu haben  und möchte mich nun einmal der übersichtli-
chen Programmierung zuwenden. In diesem  Zusammenhang
wollen  wir  dann auch noch 2 neue Befehle kennenler-
nen.                                                 
Doch  zunächst  möchte ich schnell noch etwas nachho-
len. Ich habe nämlich - ich muß es gestehen  -  einen
äußerst  wichtigen  Befehl  vergessen,  als ich Ihnen
letzten   Monat   erläuterte,   wie   man   Programme
schreibt: den NEW-Befehl.                            
Dieser  Befehl  braucht  keinerlei Parameter, und ist
daher auch ganz schnell und einfach  abgehandelt.  Er
dient  dazu,  ein  Programm  aus dem Programmspeicher
Ihres C64 wieder zu löschen. Dies ist insofern  wich-
tig,  da Sie ab jetzt wohl häufiger Programme schrei-
ben werden, und Sie diese nun ganz  einfach  mit  NEW
wieder  löschen  können, falls Sie ein neues eingeben
möchten, und nicht mehr immer gleich den ganzen  Com-
puter  ausschalten  müssen, beziehungsweise alle vor-
kommenden Zeilennummern eines Programms einzeln  ein-
tippen müssen, um diesen Effekt zu erzielen.         
Außer  den  gesamten  Programmspeicher  zu   löschen,
löscht NEW auch alle sich zu diesem Zeitpunkt sich im
Speicher  befindlichen  Variablen!   Wundern Sie sich
also nicht, wenn manche vorher von  Ihnen  definierte
Variablen plötzlich leer sind.                       
Den gleichen Effekt, nämlich daß  alle  Variablen  im
Speicher  gelöscht  werden  können Sie ebenso mit dem
Befehl CLR (für CLEAR = löschen)  erzielen.  Mit  dem
einzigen  Unterschied  zu  NEW, daß Ihr geschriebenes
Programm noch im Speicher steht, die Variablen aller-
dings  gelöscht  sind.  Dieser Befehl wird eigentlich
kaum benutzt, allerdings ist es gut, ihn  zu  kennen,
da  es auch hier und da mal Gelegenheiten geben wird,
wo er ganz angebracht ist. Sie werden schon sehen... 
Dies also zu NEW und CLR, die  übrigens  beide  keine
Parameter  brauchen - leider, da es manchmal ganz an-
gebracht wäre, wenn man einfach nur einen  bestimmten
Bereich  eines  Programms löschen könnte, doch leider
ist dies nicht möglich und wirklich nur so zu  reali-
sieren, indem man halt sämtliche Zeilennummern dieses
Bereichs durch einzelnes Eintippen löscht.           
Wenden wir uns nun einmal  dem  übersichtlichen,  der
formatierten  Programmierung  zu,  wie  ich es weiter
oben schon angekündigt hatte.                        
Vielleicht  haben Sie sich unser kleines Textausgabe-
programm von vorhin einmal  genauer  angeschaut   und
sicher  sind  Ihnen daran auch mindestens eine Sache,
wenn nicht sogar 2, aufgefallen. Wie?  Nein?  Na dann
schauen Sie doch einfach nochmal rein:               
10 INPUT"[CLR]WOLLEN SIE TEXT SEHEN (J/N) ";a$       
20 IF a$="J" THEN 200                                
30 PRINT"DANN NICHT...":END                          
40 :                                                 
200 PRINT"DAS IST IHR GEWUENSCHTER TEXT..."          
210 PRINT"UND HIER NOCH EINE KLEINE ZUGABE AN"       
220 PRINT"TEXT, DAMIT SIE SICH NICHT VERAEPPELT"     
230 PRINT"FUEHLEN, UND DAMIT HIER AUCH NOCH MEHR"    
240 PRINT"ZEILEN GEFUELLT WERDEN."                   
Na? Klingelt es bei Ihnen? Genau  -  die  eine  Sache
liegt ja wohl auf der Hand. Zeile 40 ist ja wohl  to-
tal  überflüssig!  Nicht nur, daß sie niemals abgear-
beitet wird, da das Programm ja vorher  in  Zeile  40
schon  mit  END  beendet wurde, sie ist außerdem auch
von ihrem Aussehen etwas merkwürdig, zumal KEINE  An-
weisungen  in  ihr vorkommen, und sie einfach nur aus
einem Doppelpunkt besteht. Warum also überhaupt  eine
solche  Zeile?  Na  wie Sie sich schon denken können,
da es hier ja um die Formatierung des  Programmtextes
geht, hat das ganze etwas mit eben jenem zu tun.     
Ich habe diese Zeile ganz einfach deshalb  eingefügt,
um  die vorherige Abfrage und den anschließenden Text
ein wenig voneinander abzusetzen. Damit  man,  sollte
man  sich  dieses Listing zu einem späteren Zeitpunkt
nocheinmal ansehen, sofort erkennt,  daß  die  beiden
Programmteile  verschiedene  Aufgaben haben und nicht
zusammengehören und hintereinander abgearbeitet  wer-
den. Zugegeben - bei einem solch kleinen Programm wie
diesem  hätte  ich  diese Feststellung wahrscheinlich
auch so noch hingekriegt, doch stellen Sie sich  ein-
mal  vor,  Sie  hätten ein etwas längeres Listing vor
sich mit ca. 10000 Zeilen (natürlich in 10er  Schrit-
ten  gerechnet)  -  Sie  müssen  zugeben, daß es hier
nicht mehr ganz so einfach wäre das  Ganze  zu  über-
schauen.                                             
Benutzen Sie also, um einzelne  Programmteile,  soge-
nannte  Module,  optisch voneinander abzusetzen immer
eine oder mehr Doppelpunktzeilen, damit Sie sich spä-
ter wieder in Ihrem eigenen Programm zurechtfinden.  
"Wieso soll ich mich denn nicht mehr in meinem  eige-
nen Programm zurechtfinden können, zumal ich es  doch
selbst  geschrieben  habe?"  werden  Sie  sich  jetzt
vielleicht fragen, doch glauben  Sie  mir,  denn  ich
speche  aus Erfahrung, wenn Sie nach einiger Zeit mal
wieder in ein altes Programm reinschauen, um es viel-
leicht zu verbessern, dann wissen Sie manchmal selbst
nicht  mehr,  was  Sie da eigentlich bewirken wollten
und es passiert dann schnell, daß  man  dann  einfach
die  Lust  verliert, an so einem Anweisungschaos wei-
terzuarbeiten. Das ist wohl auch eine der Hauptschwä-
chen von BASIC, die dem Anfänger anfangs das Program-
mieren sehr erschwert.  Also immer die einzelnen  Mo-
dule  eines Programms gut sichtbar voneinander abset-
zen, das kostet zwar ein  kleines  bißchen  Speicher-
platz, aber es lohnt sich wirklich !                 
Übrigens:  wir hatten zwar festgestellt, daß die Dop-
pelpunktzeile 40 in unserem Programm nicht abgearbei-
tet wird, da dieses vorher ja mit END  beendet  wird,
aber  es  sei hier auch noch gesagt, daß der Computer
sie auch ruhig hätte ausführen  können  -  sie  hätte
keine  Fehlermeldung  bewirkt, sondern wäre sozusagen
ganz einfach "übergangen" worden, obwohl  dies  nicht
der  richtige Ausdruck hierfür ist. Sie wird nämlich 
wie eine normale Programmzeile behandelt.            
Der  Grund,  warum nichts passiert, wenn der Computer
eine solche Zeile durchläuft ist  ganz  einfach  der,
daß  der  Doppelpunkt,  wie wir ja gelernt haben, als
Trennzeichen zweier Befehle dient. In  unserer  Zeile
trennt  er  ganz  einfach den "Befehl" NICHTS von dem
"Befehl" NICHTS, wird also als  gültiges Trennzeichen
erkannt; daß diesem gar kein Befehl folgt, steht  auf
einem  anderen  Blatt.  Der  Computer "übersieht" das
sozusagen. Er erkennt nur, daß dann die Programmzeile
endet, und daß er die nächste abzuarbeiten  hat,  was
er auch prompt tut. Daß wir ihm  soeben  eine  völlig
hirn- und sinnlose Zeile vorgesetzt  hatten  ist  ihm
egal, solange er nichts an dieser auszusetzen  hatte,
was ja nicht der Fall war. Sie  könnten  also  ebenso
einzelne Funktionsmodule im Programmfluß  voneinander
trennen:                                             
10 input"Bitte geben Sie einen Text ein ";a$         
20 a$="Das ist Ihr Text : "+a$                       
30 :                                                 
40 PRINT                                             
50 PRINT a$                                          
Sie sehen, in Zeile 10 wird ein Text in die  Variable
a$  eingelesen,  und in Zeile 20 wird vor diesen Text
noch der Prefix "Das ist Ihr Text :  "  gehängt.  Die
Variablenzuweisung dürfte Ihnen ja bekannt sein, hier
wird  a$  ganz  einfach  das  zugeordnet, was auf der
rechten Seite steht. Hierbei gilt natürlich noch  der
alte Inhalt der Variablen a$ - genau also wie bei dem
Ausdruck  I=I+1.  Sie müßten das noch von dem letzten
Kurs her kennen...                                   
Hier  sieht  man  übrigens  auch  sehr schön, wie man
Strings aneinanderhängen kann, nämlich ganz  einfach,
indem  man sie wie Zahlen mit dem Pluszeichen addiert
(ACHTUNG! In umgekehrter Richtung, also mit Minus ist
nichts zu machen! Wie das geht kommt später...)      
In Zeile 30 wird nun das Modul, das für die Vorberei-
tung  des  auszudruckenden  Textes zuständig ist, mit
einem Doppelpunkt von einem  zweiten  Modul,  nämlich
das,  das den Text dann ausgibt, getrennt. Der Compu-
ter arbeitet also auch diese Zeile ab, sie hat aller-
dings  keinerlei  Einwirkung  auf  den Programmablauf
ansich, außer daß dieser vielleicht um wenige  Mikro-
sekunden verlangsamt wird.                           
Vielleicht ist Ihnen in Zeile  40  auch  das  einsame
PRINT  aufgefallen, das, ganz im Gegensatz zu unseren
PRINTs, keinen Text oder  gar  eine  Variable  hinter
sich  stehen  hat. Dieses PRINT, ohne Parameter also,
tut nichts anderes, als den Cursor an den Anfang  der
nächsten Zeile zu setzen. Hiermit haben wir also wie-
der ein absetzen der Ausgabe vom bisherigen Text  er-
reicht.  Genausogut  hätte  ich in Zeile 40 schreiben
können :                                             
40 PRINT "[DOWN]";                                   
Also einfach einmal "Cursor runter", allerdings  dür-
fen  Sie  hier  das Semikolon (;) nicht vergessen, da
sonst 2 (!) Zeilen freigelassen werden. Da  PRINT  ja
nach  jeder  Ausgabe  den Cursor in die nächste Zeile
vorschiebt, und wir dies mit dem Semikolon  unterbin-
den  können.  Hier sehen Sie auch warum PRINT alleine
einfach nur eine Zeile weitergeht -  nachdem  es  den
Text ausdruckte, den es ja leider bei dieser alleini-
gen Anweisung nicht gibt, warum auch nichts  ausgege-
ben wird, rückt es eine Zeile weiter...              
Als  letztes  möchte  ich  jetzt  noch den REM-Befehl
einführen. REM steht für REMark, was  so  viel  heißt
wie "Anmerkung", womit schon wieder alles gesagt ist.
REM  wird nämlich dazu benutzt, kleine Anmerkungen in
Programmen unterzubringen, die später dem Programmie-
rer  erklärend  wieder Anzeigen sollen, was dieser an
bestimmten Stellen mit seinen Programmierkünsten  be-
wirken wollte.                                       
REM wird folgendermaßen angewandt :                  
10 REM DAS IST EIN KOMMENTAR                         
Hinter dem eigentlich Befehlswort REM folgt ganz ein-
fach ein beliebiger Text, der Hinweise auf etwas  ge-
ben  kann. Hier können Sie grundsätzlich alle Zeichen
verwenden, die auf Ihrer Tastatur  vorkommen,  aller-
dings  sollten  Sie von den Grafikzeichen absehen, da
diese interne Probleme verursachen könnten. Im allge-
meinen  sollte  man allerdings mit den Buchstaben und
Zahlen auskommen.                                    
Was  genau  passiert  jetzt bei REM im innern unseres
64ers?  Nun, sobald dieser erkannt hat, daß  er  hier
einen  REM-Befehl  vor sich hat, springt er sofort in
die nächste Programmzeile, um diese abzuarbeiten, und
ignoriert ganz einfach den Text der hinter REM kommt.
Somit kann dann natürlich  auch  keine  Fehlermeldung
entstehen,  von  dem  was da steht, zumal die meisten
Computersprachen mehr auf  Englisch  ansprechen  (wie
wir  ja mittlerweile oft genug gemerkt haben) als auf
Deutsch, und somit unser C64 wohl nicht mehr als  ei-
nen  SYNTAX  ERROR in solchen Fällen auf Lager hätte.
Versuchen Sie es doch einmal so :                    
10 DAS IST EIN KOMMENTAR                             
Sie werden sich denken können, was passiert...       
Was jetzt noch erwähnenswert wäre, ist, daß  bei  REM
grundsätzlich  ALLES, was in dieser Zeile noch folgt,
übersprungen wird. Also auch Befehle, oder  Anweisun-
gen,  die hier stehen könnten. Eine solche Zeile wäre
also ein fataler Fehler:                             
10 PRINT"ERST DAS.":REM AUSDRUCK 1:PRINT"DANN DAS."  
Der Ausdruck, den Sie jetzt sähen, wäre folgender:   
ERST DAS.                                            
Die zweite PRINT-Anweisung, wäre  übergangen  worden,
da  grundsätzlich alles ignoriert wird, also auch die
PRINT-Anweisung,  was  hinter  dem  Befehlswort   REM
steht. Dies sollten Sie sich einprägen !             
Der  Vorteil  von REM liegt mittlerweile ja dann auch
auf der Hand. Mit diesem Befehl kann man  seine  Pro-
gramme  auf  sehr  einfache Art und Weise  sehr über-
sichtlich gestalten. Natürlich gibt es auch  Nachtei-
le, nämlich wieder die selben, wie beim Doppelpunkt -
REM verbraucht Speicherplatz und verlangsamt das Pro-
gramm um wenige Mikrosekunden, doch ist es immer bes-
ser  ein gut formatiertes Listing zu haben, als einen
Haufen Spaghetti-Code durch den man selbst nicht mehr
durchsteigt. Wen es wurmt, daß sein Programm  dadurch
langsamer  und  Speicherintensiver wird, der kann ja,
nachdem er eine Kopie von der  kommentierten  Version
angefertigt hat, die überflüssigen Zeilen löschen und
es in dieser endgültigen Version  dann  benutzen,  so
hat man dann immer noch eine kommentierte  Kopie,  an
der man leicht  wieder  kleine  Veränderungen  machen
kann.                                                
Hiermit möchte ich dann  wieder  schließen  und  mich
bis  April  von  Ihnen verabschieden, wo wir uns dann
noch zwei  wichtige  Befehle  zur  formatierten  Pro-
grammierung ansehen werden, und anschließend  endlich
die schon letzten Monat versprochenen  Schleifen  an-
schauen werden. Bis dahin Servus,                    
                           Ihr Uli Basters           
     BASIC-Kurs:  "Von Adam und Eva..." (Teil 4)     
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾     
Hiermit möchte ich Sie zum vierten Teil  unseres  Ba-
sickurses  herzlichst  begrüßen.  Diesen Monat werden
wir uns noch ein wenig mit der formatierten  Program-
mierung  befassen und werden uns anschließend endlich
den lang versprochenen Schleifenbefehlen zuwenden.   
Letzten Monat hatten Sie ja  gelernt,  wie  man,  mit
Hilfe von REM und sogenannten "Doppelpunktzeilen" ein
wenig  Ordnung  in  einen  Programmtext  bringt. Eine
richtige "Programmierung" war das ja noch nicht,  zu-
mal  die von uns eingefügten Zeilen und Kommentare ja
nichts mit dem  eigentlichen  Programmablauf  zu  tun
hatten,  und wir sie genausogut auch hätten weglassen
können, wie ich zum Schluß andeutete.                
Deshalb kommen wir heute  zum  GOSUB-Befehl,  der  in
zusammenhang mit dem RETURN-Befehl uns ungeheuerliche
Weiten zur platzsparenden, einfachen und formatierten
Programmierung öffnet.                               
GOSUB steht für GO to SUBroutine, was  soviel  heißt,
wie GEHE zu UNTERprogramm, und ist in etwa vergleich-
bar mit GOTO. Hinter GOSUB wird ebenfalls  eine  Zei-
lennummer  angegeben,  zu  der  der Computer springen
soll. Bis hierhin tut GOSUB genau dasselbe, was  auch
GOTO  tut,  nämlich  ganz einfach zu einer bestimmten
Zeile im Programm springen. Die  Programmzeilen,  die
dort  stehen und folgen werden ganz normal abgearbei-
tet. Doch nun kommt der Clou:  nachdem  diese  Zeilen
abgearbeitet wurden, können Sie mit dem RETURN-Befehl
wieder  an die Stelle im Programm zurückspringen, von
wo der GOSUB-Befehl in das Untersprogramm  (so  nennt
sich  das  nämlich)  eingesprungen  ist. Dies hat den
Vorteil, daß Sie beliebige Programmsequenzen, die Sie
innerhalb eines  Programms  benötigen,  beliebig  oft
benutzen  können,  aber  nur EINMAL schreiben müssen.
Der Computer merkt sich jedesmal die Stelle, von wel-
cher Sie in das Unterprogramm eingesprungen sind, und
wird  jedesmal  auch  wieder dorthin zurückkehren. In
der Praxis sieht das so aus:                         
5 REM *****************                              
6 REM * hauptprogramm *                              
7 REM *****************                              
8 :                                                  
10 GOSUB 200                                         
20 PRINT"Hallo Leute..."                             
30 GOSUB 200                                         
40 PRINT"Unn weils so schön war, grad nochmal...";   
50 GOSUB 200                                         
60 END                                               
90 :                                                 
195 REM ************                                 
196 REM * demotext *                                 
197 REM ************                                 
198 :                                                
200 PRINT                                            
205 PRINT"Das ist ein Text, der hier zur Demon-"     
210 PRINT"stration insgesamt 3 Mal ausgedruckt"      
220 PRINT"wird."                                     
230 PRINT                                            
240 RETURN                                           
Genau  so  sollte ein gut formatiertes Programm übri-
gens aussehen. Vor jedem  Modul  (=Programmabschnitt,
das  hatten  wir  letzten  Monat  ja schon einmal...)
steht ein unübersehbarer Kommentar. Zuerst haben  wir
das  "HAUPTPROGAMM".  Der  Programmteil  also, der am
Anfang auch mit RUN  gestartet  wird,  und  der  alle
benötigten  Unterprogramme,  so  wie zum Beispiel das
Programm "DEMOTEXT", zu dem Zeitpunkt aufruft, zu dem
sie benötigt werden.                                 
Schauen wir uns doch einmal unser Programm ein  wenig
näher  an.  Gleich am Anfang, in Zeile 10, wird unser
kleines Unterprogramm schon beansprucht und  aufgeru-
fen.  Dann wird in Zeile 20 der Text "Hallo Leute..."
ausgegeben. Anschließend kommt wieder  das  Unterpro-
gramm  dran.  Dann kommt etwas aus dem Hauptprogramm,
nämlich der Text "Unn weils so schoen war, grad noch-
mal...".  Schließlich  und endlich wird DEMOTEXT noch
ein letztes Mal aufgerufen und das Hauptprogramm  mit
END  beendet.  Der  Ausdruck, den Sie somit erhalten,
sieht im Endeffekt dann so aus:                      
Das ist ein Text, der hier zur Demon-                
stration insgesamt 3 Mal ausgedruckt                 
wird.                                                
Hallo Leute...                                       
Das ist ein Text, der hier zur Demon-                
stration insgesamt 3 Mal ausgedruckt                 
wird.                                                
Unn weils so schoen war, grad nochmal...             
Das ist ein Text, der hier zur Demon-                
stration insgesamt 3 Mal ausgedruckt                 
wird.                                                
Sie sehen, obwohl Sie den Text, der hier, wie so  oft
angezeigt,  "insgesamt  3  Mal ausgedruckt wird", nur
einmal eingegeben  haben,  erscheint  er  tatsächlich
drei  Mal auf dem Bildschirm. Sie haben sich also er-
steinmal ein wenig Tipparbeit gespart, und dann  auch
noch Speicherplatz, da drei mal mehr Platz verbraucht
worden wäre, hätten Sie jedesmal unseren Text nochmal
eingegeben.  Außerdem  sieht  unser Programm so jetzt
schön sauber und ordentlich aus - Unterprogramm schön
vom Hauptprogramm getrennt...                        
Und es gibt da noch einen kleinen Vorteil:   angenom-
men, Sie sind gerade dabei ein Programm zu schreiben,
zu  dem  Sie  ein bestimmtes Unterprogramm benötigen,
das eine ganz bestimmte Aufgabe erfüllen soll. Welche
Aufgabe im Einzelnen, sei jetzt einmal dahingestellt.
Dieses Unterprogramm haben Sie vor längerer Zeit  al-
lerdings  schon  einmal in einem anderen Programm be-
nutzt, und haben es  dort  noch  voll  funktionsfähig
drin  stehen. Das einzigste, was Sie jetzt zu tun ha-
ben, ist das Unterprogramm aus Ihrem  alten  Programm
herauszuisolieren, und es dann in Ihr neues einzubin-
den. Also ein weiterer Vorteil  von  Unterprogrammen,
da  Sie  sie jederzeit wiederverwenden können, können
Sie sich Ihre Programme sozusagen aus vielen  kleinen
Modulen  (also  Unterprogrammen) "zusammenbauen", wie
als wenn Sie mit Bauklötzen einen  Turm  konstruieren
würden.                                              
Ich muß Ihnen allerdings gestehen, daß dies gar nicht
so  einfach ist, wie es sich anhört, da man beim  BA-
SIC V2.0 des C64 nicht so einfach riesige Programmab-
schnitte  löschen kann, geschweige denn, daß man ein-
zelne Module so  einfach  aneinander  hängen  könnte.
Doch  nicht verzagen, in einer der nächsten Ausgaben,
wird wahrscheinlich ein kleines Hilfsprogramm  hierzu
erscheinen, daß diese Aufgaben bewältigen wird.      
Wie oben schon erwähnt, kann man GOSUB auch zum  "he-
rumspringen" genauso  wie GOTO verwenden, doch möchte
ich  Ihnen  DRINGENDST  davon abraten. Denn wie eben-
falls schon gesagt, merkt sich der  GOSUB-Befehl  (im
Gegensatz zu GOTO) eben jene Stelle, von wo aus er in
ein  Unterprogramm eingesprungen ist. Da der Computer
allerdings nur  einen  begrenzten  Speicherplatz  für
solche  Rücksprünge  bereithält,  kann es Ihnen somit
passieren, daß Ihr Programm irgendwann aus  Speicher-
mangel  einen Fehler ausspuckt. Benutzen Sie also im-
mer GOTO, wenn Sie "nur" springen möchten.  Dies  ist
auch  ein  kleiner Hinweis für Sie, falls Sie mal ein
Programm haben sollten, das nicht so  laufen  sollte,
wie  Sie  es  wünschen. Eine häufige Fehlerquelle ist
nämlich auch die Tatsache, daß  vergessen  wurde, das
Unterprogramm  mit RETURN abzuschließen.  Sollte näm-
lich jetzt zufällig wieder der  Programmteil  folgen,
von  dem aus das Unterprogramm aufgerufen wurde, dann
wiederholt sich dieser Aufruf solange, bis der Compu-
ter  abbrechen  muß, da sein Merkspeicher "überläuft"
(so nennt man das, wenn bei einer internen  Operation
der  Computer  über  die  Speichergrenze hinaus einen
Zugriff machen muß). Das soll jetzt  natürlich  NICHT
heißen,  daß Sie ein Unterprogramm nicht wiederum von
einem weiteren Unterprogramm  aus  aufrufen  könnten.
Natürlich  geht  das,  Sie müssen nur jedes Unterpro-
gramm immer wieder ornungsgemäß mit dem RETURN-Befehl
abschließen, um keinen Ärger zu bekommen. Theoretisch
könnten Sie  sogar  24  Unterprogramme  untereinander
verschachteln,  doch werden Sie diese Grenze wohl nie
erreichen...                                         
Wollen wir uns nun endlich den  Scheifenbefehlen  zu-
wenden.  Zuerst  einmal,  was ist eine Schleife?  Wie
Sie sich vielleicht erinnern, hatten wir, beim Abhan-
deln  des GOTO-Befehls eine sogenannte "Endlosschlei-
fe" geschrieben. Deshalb Endloschleife, weil ein ganz
bestimmter Programmteil immer und  immer  wieder  ab-
gearbeitet  wurde,  so, daß das Programm endlos lange
weitergelaufen wäre, hätten wir es nicht mit RUN/STOP
angehalten. Hier nochmals ein solches Programm:      
10 PRINT"Das ist eine Endlosschleife...";            
20 GOTO 10                                           
Hier  wird  der Text "Das ist eine Endlosschleife..."
also immer wieder ausgegeben, da in Zeile 20 ja immer
wieder zu Zeile 10 verzweigt wird, womit  sich  unser
Programm  also  immer  wieder  selbst aufruft. Klarer
wird es, wenn Sie Zeile 20 wie folgt abändern:       
10 PRINT"Das ist eine Endlosschleife...";            
20 RUN                                               
Jetzt startet sich das  Programm  also  immer  wieder
selbst, ohne  daß es jemals zu einem Ende kommen wür-
de.                                                  
Sie  müssen  allerdings  zugeben,  daß solche Endlos-
schleifen, so  wie sie hier dargestellt  sind  zumin-
dest,  wenig  Sinn ergeben. Es wäre doch viel besser,
wenn man eine solche Schleife unter Kontrolle  hätte,
und  sie endlich machen könnte, so also, daß sie nach
eine bestimmten Anzahl von Durchläufen beendet wird. 
Zum Einen könnte man das, wenn wir uns auf unser bis-
heriges Wissen stützen, sehr  gut  mit  der  IF-THEN-
Klammer lösen. Nämlich so:                           
5 i=0                                                
10 i=i+1                                             
20 PRINT"DAS IST EIN TEXT"                           
30 IF i<>5 THEN 10                                   
40 END                                               
Zuerst  wird in Zeile 5 die Variable I auf 0 gesetzt.
Anschließend wird diese Laufvariable (so  wollen  wir
es einmal nennen), ihres Zeichens eine Floatvariable,
um  eins  erhöht.  Dann drucken wir den Text "DAS IST
EIN TEXT" aus. In Zeile 30 vergleichen wir nun, ob  I
den  Wert  5 enthält. Wenn nicht, dann wird wieder zu
Zeile 10 gesprungen  und  der  Vorgang  des  Um-Eins-
Erhöhens und des Ausdruckens wiederholt sich. Andern-
falls wird das Programm beENDet. Sie sehen, daß diese
Schleife nur 5 Mal durchlaufen werden kann,  da  sich
nämlich  bei  jedem  Durchlauf die Variable I um eins
erhöht,  hat  sie  nach  5  Durchgängen  den  Wert  5
tatsächlich erreicht. Also wird die Schleife abgebro-
chen, und es geht in Zeile  40  weiter  im  Programm.
Hiermit hätten wir also eine Endlichschleife geschaf-
fen,  doch dies geht auch einfacher und  übersichtli-
cher,  denn  BASIC stellt uns extra zur Schleifenpro-
grammierung zwei Befehle zur Verfügung, FOR und NEXT,
die die FOR-NEXT-Schleife bilden.                    
FOR-NEXT   arbeitet   ähnlich,  wie  unsere  IF-THEN-
Schleife. Auch hier benötigen wir eine  Laufvariable,
nur, daß wir hier gleich in einem Zug angeben können,
von welchem Wert zu welchem Wert gezählt werden soll.
Also  haben  wir hier die Zeilen 5 und 30 unseres er-
sten Schleifenprogramms in EINEM zusammengefaßt.  Se-
hen  Sie  sich doch einfach einmal dieses kleine Pro-
gramm an, das die selbe Arbeit verrichtet, wie  unser
letztes Programm, allerdings mit Hilfe von FOR-NEXT: 
10 FOR I=1 to 5                                      
20 PRINT"DAS IST EIN TEXT"                           
30 NEXT                                              
Das  war  alles!  Auf den ersten Blick sieht das zwar
genauso lang aus, wie unser erstes Schleifenprogramm,
doch der FOR-Befehl hat noch einige  Eigenarten,  die
ihn  zum  einen  komfortabler machen, und zum anderen
ÜBERSICHTLICHER, was ja außerordentlich wichtig  ist,
wie  wir  festgestellt  hatten. Nicht umsonst nämlich
hatte ich ein ganzes Kapitel der  formatiertien  Pro-
grammierung gewidmet!                                
Das  Übersichtliche  an FOR-NEXT ist, daß der gesamte
Schleifenrumpf, der Teil also, der immer  wieder  ab-
gearbeitet  werden  soll,  durch  FOR und NEXT einge-
grenzt wird. Sehen wir uns nun einmal an, was im  In-
nern  unsers  Computers  abläuft, wenn er eine solche
Schleife abarbeitet:                                 
In  Zeile  10  erkennt der 64er erst einmal (an FOR),
daß hier gleich eine Schleife  folgt.  Direkt  hinter
dem  FOR-Befehl  wird dann die Laufvariable mit einem
Grundwert "initialisiert", das  heißt,  daß  ein  be-
stimmter  Wert  als  Ausgangswert  für diese Variable
festgelegt  wird.  Diese  Initialisierung  entspricht
Zeile  5 unseres ersten Programms, hier wurde die Va-
riable 'I' auf 0 gesetzt. Daß wir  sie  nicht  mit  1
initialisierten,  wie  bei  FOR, liegt einfach daran,
daß sie  anschließend,  in  Zeile  10,  schon  auf  1
gezählt  wurde. Womit sie den selben Anfangswert hat,
wie in unserem zweiten Programmbeispiel.             
Wie  gesagt  haben  wir  nun die untere und die obere
Grenze festgelegt, innerhalb der der Computer  zählen
soll. In unserem Beispiel ist das von 1 bis 5.       
In Zeile 20 geht's jetzt weiter  mit  dem  Schleifen-
rumpf,  der hier nur diese eine Zeile, mit Nummer 20,
lang ist. Natürlich könnten  Sie  hier  auch  mehrere
Zeilen  stehen  haben,  Hauptsache ist, daß Sie diese
dann auch zwischen FOR und NEXT  sozusagen  "einklam-
mern".  Unser Schleifenrumpf besteht also aus der An-
weisung, den Text "DAS IST EIN TEXT" auszudrucken.   
In  Zeile  30  nun  trifft der Computer auf die NEXT-
Anweisung. Jetzt zählt er die Schleifen- oder Laufva-
riable  erst  einmal um 1 hoch. Entsprechend also der
Zeile 10 unseres ersten Programms:                   
10 I=I+1                                             
Anschließend prüft er, ob der Inhalt dieser  Variable
mittlerweile  größer ist, als der obere Grenzwert, ob
dieser also schon überschritten wurde. Ist  dies  der
Fall,  so  wird die Schleife beendet und der Computer
fährt in Programm fort. Ist die  Laufvariable  aller-
dings  noch  kleiner  oder  gleich  dem Grenzwert, so
wird wieder an den Befehl im Programm verzweigt,  der
nach  der  FOR-Anweisung  kommt. Dies wiederholt sich
dann halt solange, bis  der  Grenzwert  dann  endlich
überschritten wurde. Ich möchte hier auch noch darauf
aufmerksam  machen, daß die Laufvariable VOR dem Ver-
gleich hochgezählt wird. Deshalb  hat  Sie  nach  dem
Aussprung  aus der Schleife immer den Inhalt des obe-
ren Grenzwertes plus 1!!!  Dies zu  wissen  kann  äu-
ßerst  wichtig  sein, da hier manchmal Fehler gemacht
werden:                                              
FOR i=0 TO 3:PRINT"TEXT":NEXT                        
Diese Schleife zum Beispiel wird insgesamt 4 (!)  mal
durchlaufen,  da  von  0  nach 3 gezählt wird (also 3
Ziffern  plus  die  Null...).  Nicht  also,  wie  man
fälschlicherweise annehmen könnte, nur 3 mal!        
Hier sehen Sie übrigens auch, daß man  FOR  und  NEXT
nicht  unbedingt  in  eigene Programmzeilen schreiben
muß, es ist nämlich auch durchaus möglich sie in  EI-
NER   Zeile   zusammenzufassen,  vorrausgesetzt,  der
Schleifenrumpf ist nicht zu lang.                    
Grundsätzlich gilt:  alle  Befehle,  Anweisungen  und
Funktionen,  die  zwischen FOR und NEXT stehen bilden
alle gemeinsam den Schleifenrumpf, den Teil also, der
immer  wieder  von  der  Schleife  durchlaufen  wird,
unabhängig davon, wie die einzelnen Befehle innerhalb
von Programmzeilen verteilt sind.                    
Doch kann man mit FOR noch viel mehr anfangen!  Ange-
nommen Sie wollten nicht immer um 1 erhöhen,  sondern
immer um 2, weil Sie, aus welchen Gründen auch immer,
alle  2er  Zahlen, oder alle geraden Zahlen, benutzen
möchten. Hierzu kann man die STEP-Anweisung benutzen,
die an den FOR-Befehl angehängt wird, ohne diesen sie
nicht  existieren  kann, sprich nicht verwendbar ist.
Geben Sie doch einfach einmal folgendes ein:         
FOR I=0 to 10 STEP 2:PRINT I:NEXT                    
Die Ausgabe dieser Schleife sieht so aus:            
0                                                    
2                                                    
4                                                    
6                                                    
8                                                    
10                                                   
Eigentlich nichts neues mehr für uns. Hier wurde ganz
einfach  von  0  bis  10  gezählt,  allerdings in 2er
Schritten, wie man an der Ausgabe erkennen kann - der
Inhalt von 'i' war  immer  um  2  erhöht.  Auch  hier
galt:  erst als NACH einem Hochzählen um den Zählwert
(oder  die  sogenannte Schrittweite) der obere Grenz-
wert überschritten wurde, wurde die Schleife  verlas-
sen.                                                 
Es  mag  sein,  daß dieses Ihnen noch nicht ganz ein-
leuchtet, deshalb also  ein  weiteres  Beispiel.  Wir
hatten  bis  jetzt immer von einem kleineren Wert bis
zu einem größeren gezählt. Manchmal  könnte  es  aber
auch ganz nützlich für uns sein, rückwärts zu zählen,
beispielsweise von 5 bis 0 in 1er-Schritten, oder gar
in halben Zahlen, also in  0.5er-Schritten.  Das  ist
absolut kein Problem mit STEP. Der Wert hinter diesem
Anweisungswort  muß  ganz  einfach negativ sein, also
mit einem Minuszeichen (-) davor. Etwa so:           
FOR I=5 to 0 STEP -1:PRINT I:NEXT                    
Hier haben wir  dann  eine  "Rückwärtsschleife".  Sie
zählt  rückwärts  von  5 bis 0. Auch hier gilt:  erst
wenn der zweite Grenzwert, diesmal ist er  allerdings
kleiner als der erste, UNTERSCHRITTEN wurde, wird die
Schleife  verlassen.  Diesmal also erst, wenn der In-
halt der Zählvariable kleiner ist, als der Grenzwert,
zu  dem gezählt werden soll. Dies ist ein kleiner Un-
terschied, der bei Schleifen mit negativen Zählwerten
auftritt, an den man sich jedoch leicht  gewöhnt,  da
er im Grunde ja ganz logisch ist, oder?              
Das zum Thema Schleifen. Ich hoffe, Ihnen dieses Pro-
blem verständlich dargelegt zu haben. Nun möchte  ich
mich,  quasi zur Entspannung, einem etwas  leichteren
Themen zuwenden, sozusagen ein paar  kleine  Häppchen
als "Hors d'oevre" vorschicken, auf das was  nächsten
Monat auf sie zu kommt...                            
Beginnen wir mit einem  kleinen  Rechenoperator,  den
ich Ihnen bei unserer Rechnerei am Anfang dieses Kur-
ses verschwiegen habe. Es handelt sich hierbei um den
Exponentialoperator, der durch den 'Pfeil nach  oben'
('↑')  ausgedrückt  wird. Mit ihm können Sie die n-te
Potenz einer Zahl berechnen. Etwa 2 hoch  8,  oder  5
zum Quadrat. Geschrieben wird das so:                
PRINT 2↑8                                            
PRINT 5↑2                                            
Sie  können  diesem Operator natürlich genauso benut-
zen, wie die anderen Operatoren auch, also  ebenfalls
auch bei Variablenzuweisungen benutzen.              
Sollten Sie übrigens darauf bedacht sein,  Ihre  Pro-
gramme so zu programmieren, daß sie mit einem Minimum
an  Zeit  ablaufen, dann gebe ich Ihnen den Tip, Ihre
Quadrat-Potenzen (also die Potenzen, die  die  2  als
Exponenten, oder als 'Hochzahl' haben) mit dem Multi-
plikationsoperator '*' auszudrücken. Dies rechnet der
64er nämlich bedeutend schneller aus,  als  wenn  Sie
den Potenz-Operator verwenden würden. Also anstatt:  
PRINT X↑2 schreiben Sie besser:                      
PRINT X*X                                            
Dieses  führt  zum selben Ergebnis, verbraucht aller-
dings bedeutend weniger Zeit. Sie selbst dürften  das
vielleicht  nicht  direkt  merken, da es der Computer
für uns normal Sterbliche immer noch sehr schnell be-
rechnet,  aber  schreiben Sie doch vielleicht einfach
einmal eine Schleife, die eine solche Potenzoperation
vielleicht 1000 oder 2000 Mal durchführt, und stoppen
Sie dann doch mal die Sekunden, ich  denke,  daß  Sie
einen Unterschied feststellen müßten...              
Das nächste, was ich Ihnen nicht vorenthalten möchte,
ist die "DEF-FN"-Anweisung. Mit dieser Anweisung kön-
nen Sie ganze Funktionen in einem  Ausdruck  definie-
ren,  so  daß  sie diesen Ausdruck nur noch durch ein
kleines Namenskürzel aufrufen müssen. Angenommen, Sie
haben eine Formel, mit der Sie  durch  Eingabe  einer
Unbekannten eine gewisse Größe berechnen können.  Als
praktisches  Beispiel  will ich mich mal ein wenig an
der Kreisberechnung auslassen.  Nehmen  wir  an,  Sie
wollten  ein Programm schreiben, das Ihnen den Kreis-
umfang sowie den Kreisinhalt berechnet. Die dazugehö-
rigen Formeln lauten, wie wir wissen, wenn  wir  alle
schön in der Schule aufgepaßt haben:                 
Kreisumfang:  2rπ  (= 2*r*π)                         
Kreisinhalt:  r↑2π (= r↑2*π)                         
Da wir hier in unserem Kurs leider  keine  Sonderzei-
chen  haben,  habe  ich, um das Quadrat auszudrücken,
wie unser C64 auch, den Exponentenpfeil (↑)  benutzt.
Sie kennen Ihn ja mittlerweile. In Klammern sehen Sie
dann  die endgültige Computerschreibweise (da ja noch
die Multiplikations-Zeichen '*' eingefügt werden muß-
ten.                                                 
Die  Formel für den Kreisinhalt werden wir allerdings
gleich nochmal ein wenig abändern. Da wir ja die Qua-
drate  etwas  schneller  berechnen  wollen,  heißt es
jetzt also:  r*r*π (was ja dasselbe ist wie r↑2*π).  
Nun  müssen  diese  beiden  Funktionen  nur  noch mit
DEF FN in einem  Namen  definiert  werden.  Dies  ge-
schieht folgendermaßen:                              
10 def fnu(r)=2*r*π                                  
20 def fni(r)=r*r*π                                  
Mit DEF zeigen Sie dem Computer also an, daß Sie hier
eine Funktion definieren wollen. Dann geben  Sie  den
Namen  der  Funktion  an,  der sich immer aus dem FN-
Prefix, einem oder zwei  Buchstaben  und  dem ' (R)'-
Suffix  zusammensetzt. Das Prefix ist bei jeder Defi-
nition gleich, der eigentliche Name der Funktion wird
durch die beiden Buchstaben in  der  Mitte  bestimmt,
bei denen Sie nach den selben Regeln arbeiten  müssen
wie  bei  den  Variablennamen. Diese Regeln hatte ich
Ihnen, als wir die  Variablennamensgebung hatten,  ja
schon  einmal  aufgezählt. Zum Suffix sei nur noch zu
sagen, daß hier in Klammern immer die Unbekannte ste-
hen  muß,  die in der zu definierenden Funktionsglei-
chung (oder Formel) eingesetzt werden soll.          
Warum, werden Sie beim Aufruf  erkennen.  Ich  möchte
hier  jedoch  erst  einmal  wieder ein weiteres Stück
unseres Programmes einfügen:                         
30 print chr$(14)chr$(8)                             
40 print"[CLS]Programm zur Berechnung von Kreisum-   
fang"                                                
50 print"und -inhalt."                               
60 input"[2 DOWN]Radius ";r                          
70 u=fnu(r)                                          
80 i=fni(r)                                          
Die Zeilen 30-50 drucken die Titelzeile des Programms
aus. In Zeile 30 wird übrigens  wieder  mit  CHR$(14)
die  Kleinschrift  eingeschaltet  und mit CHR$(8) die
Umschaltmöglichkeit durch Drücken der SHIFT- und  der
COMMODORE-Tasten  blockiert. Wir hatten dies ja schon
einmal bei unserem Zylinderberechnungsprogramm...    
In Zeile 60 fragt das Programm jetzt nach dem Radius,
der nach Eingabe eines beliebigen Wertes in  der  Va-
riablen 'r' gespeichert wird.                        
Jetzt folgt endlich unser  langerwarteter  Funktions-
aufruf.  Sie sehen, daß in Zeile 70  das Ergebnis der
Funktion  erst  einmal  der  Variablen ' u' zugeornet
wird. Der Aufruf ansich gestaltet sich höchst einfach
und schmerzlos. Sie schreiben ganz einfach wieder den
Prefix 'FN' gefolgt vom Funktionsnamen und  dem  Suf-
fix, mit der unbekannten Variablen in runden Klammern
eingeschlossen - das wars schon. Jetzt müssen wir das
Ergebnis  nur noch ausdrucken, und das geschieht fol-
gendermaßen:                                         
90 print"Der Kreisumfang ist: "u                     
100 print"Der Kreisinhalt ist: "i                    
Was ja hoffentlich keinerlei Erklärung bedarf...     
Der  Clou  an den vordefinierten Funktionen ist also,
daß man eine Unbekannte gleich  in  den  Klammern  am
Ende  angeben  kann.  Sie  hätten die Funktion ebenso
auch so aufrufen können:                             
print fnu(1.5)                                       
Hier haben wir den Wert der Funktion also gleich  nu-
merisch angegeben, nicht also in einer Variablen. Der
Vorteil  von  solchen Funktionsdefinitionen liegt auf
der Hand. Angenommen, Sie haben eine  bestimmte  For-
mel,  die Sie in einem Programm wahnsinnig oft benut-
zen müssen. Mit DEF-FN können Sie  diese  also  immer
abkürzen, und haben Ihre Funktion immer sofort parat.
Mit  FN  haben Sie also eine Art Variable für Formeln
(oder Funktionen), weshalb FN als ' normaler'  Varia-
blenname  nicht zulässig ist. Sie können gerne einmal
versuchen der Variable 'fn'  einen  Wert  zuzuweisen,
doch  wird  Sie  der C64 dann nur mit einem lapidaren
SYNTAX ERROR belohnen...                             
Außerdem  sei  noch  hinzuzufügen, daß Sie eine Funk-
tionsdefinition ausschließlich NUR innerhalb von Pro-
grammen  durchführen  können.  Versuchen  Sie dies im
Direktmodus, so quittiert Ihnen das der Computer  mit
einem  "ILLEGAL DIRECT ERROR", einem "UNERLAUBTEN DI-
REKTANWEISUNGS FEHLER" also. Ebenso  wie  INPUT  bei-
spielsweise  ist  DEF außerhalb von Programmen unsin-
nig, weshalb dieser Fehler auftritt. Einmal definiert
allerdings, können Sie jede Funktion aus dem  Direkt-
modus aus aufrufen - andersherum geht es also...     
Beschäftigen wir uns nun noch ein wenig mit  der  be-
nutzerfreundlichen Programmierung. Das heißt, daß wir
unsere  Programme  so  schreiben wollen, daß sie auch
jeder Computeranfänger problemlos bedienen kann.  Ge-
nauergesagt möchte ich Ihnen die komfortable Program-
mierung von sogenannten "Menüs"  näherbringen.  BASIC
stellt uns hierzu 2 äußerst nützliche und komfortable
Befehle  zur  Verfügung,  die  auch sehr gut noch für
weitere Aufgaben zu verwenden sind.                  
Als  erstes will ich den Begiff "MENÜ" einmal klären.
Bei einem Menü handelt es sich um  eine  Zusammenfas-
sung  von Unterpunkten innerhalb eines Programms, die
der Benutzer einzeln aufrufen kann. Sie  kennen  dies
bestimmt   schon   von  meinem  kleinen  ASCII-Druck-
Programm namens "SHOWASC", das dem zweiten Teil  die-
ses  Kurses  beigefügt  war.  Hier wurden Sie nämlich
gefragt, welche Funktion des Programms Sie  wünschen.
Ich  zeige  Ihnen  hier am besten einmal das Menü von
SHOWASC, damit Sie sich ein besseres Bild machen kön-
nen:                                                 
-----------------------------------------------------
ASCII-Tabellen-Druck.                                
Written in 1988 by Uli Basters.                      
Bitte druecken Sie:                                  
====================                                 
 F1  - Ausgabe der Liste auf Drucker                 
 F7  - Ausgabe der Liste auf Bildschirm              
  E  - fuer Programmende                             
-----------------------------------------------------
Sie  können  hier  also zwischen 3 sogenannten "Menü-
punkten" wählen, die Sie durch das Drücken einer  be-
stimmten  Taste erreichen können. Kommen wir hier nun
zum ersten der beiden Befehle, die ich Ihnen vorstel-
len wollte: dem GET-Befehl.                          
Mit ihm können Sie einen Buchstaben von der  Tastatur
einlesen,  der dann - in einer Stringvariable gespei-
chert - jederzeit abgerufen  werden  kann.  Hier  ein
Auszug  aus dem Programm des Menüs von oben (ich habe
es aus Gründen der besseren Verständlichkeit ein  we-
nig abgeändert...):                                  
...                                                  
25 print"Bitte druecken Sie: "                       
26 print"===================="                       
30 print" F1  - Ausgabe der Liste auf Drucker"       
40 print" F7  - Ausgabe der Liste auf Bildschirm"    
50 print"  E  - für Programmende"                    
60 get a$:if a$=""then 60                            
In  den Zeilen 25-50 wird erst einmal der Text zu un-
serem Menü auf dem  Bildschirm  ausgegeben.  Wie  das
dann aussieht haben wir oben ja schon einmal gesehen.
In  Zeile  60 haben wir jetzt unseren GET-Befehl. Wie
Sie sehen, steht ihm die String-Variable 'a$' nach.  
Die  Taste,  die also auf der Tastatur gedrückt wird,
wird im ASCII-Code in dieser Stringvariablen  gespei-
chert. Hier könnte natürlich auch jede andere String-
variable stehen, nicht  aber  eine  Numerische,  oder
eine Intgervariable.                                 
Direkt  anschließend,  aber  immer  noch in Zeile 60,
kommt ein IF-THEN-Vergleich. Es wird geprüft, ob  der
Inhalt der Variablen a$="" ist. Sie werden sich viel-
leicht fragen, was  diese  2  Hochkommas  ausdrücken.
Nun,  ganz  einfach,  schreiben Sie irgendwo in BASIC
für einen String, bei einer Zuweisung, oder wie  hier
zum Vergleich, ein "" dann steht das für NICHTS, oder
auch  KEIN STRING. Es wird also hier bei uns geprüft,
ob 'a$' leer ist, oder ob ein String in  ihr  gespei-
chert ist. Dieser Vergleich  ist  notwendig,  da  der
Computer ja eine  Taste  in  'a$'  gespeichert  haben
könnte,  obwohl  Sie  gar  keine  gedrückt haben. Das
hängt ganz einfach mit internen  Vorgängen  zusammen.
Mit  GET  fragen  Sie nämlich grundsätzlich immer die
Tastatur ab, egal, ob jetzt eine Taste gedrückt  ist,
oder nicht - GET holt sich immer den aktuellen Tasta-
turstand in  die  ihm  nachgestellte  Stringvariable.
Sollte  also beim Aufruf von GET keine Taste gedrückt
sein, so brauchen wir gar nicht erst  weiterzumachen,
sondern  schicken den Computer gleich wieder auf GET.
Solange bis endlich eine Eingabe gebacht  wurde.  Wir
haben  hier also praktisch eine Endlosschleife produ-
ziert, die erst dann beendet wird,  wenn  eine  Taste
gedrückt wird.                                       
Jetzt  können wir prüfen, welche Taste dies war. Dies
funktioniert ganz  einfach  über  ein  paar  IF-THEN-
Abfragen, siehe auch die folgenden Zeilen:           
70 if a$="[F1]" then 300                             
80 if a$="[F7]" then 200                             
90 if a$="e" then end                                
100 goto 60                                          
Wie die eckigen Klammern ja anzeigen, haben wir hier-
wieder  2  neue  Sonderzeichen,  die   sehr leicht zu
erklären sind. Sie entstehen, wenn Sie innerhalb  der
Gänsefüßchen  die F1- (in Zeile 70) oder die F7-Taste
(in Zeile 80)  drücken.  Diese  beiden  Zeichen  sind
übrigens  gute  Beispiele für die Sonderzeichen, denn
obwohl sie nicht sichtbar sind,  wenn  man  sie  aus-
druckt,  sind  sie  doch relativ wichtig, da man ohne
sie die Abfrage der F-Tasten nur  schwer  realisieren
könnte. Sie könnten hier übrigens ebenso schreiben:  
70 if a$=chr$(133) then 300                          
80 if a$=chr$(136) then 200                          
Dies würde dasselbe bewirken, da die ASCII-Codes  133
und 136 ja den Tasten F1, und F7 entsprechen, die sie
nebenbei auch der ASCII-Tabelle im Bedienungshandbuch
des  64ers,  Anhang F, entnehmen können, oder Sie be-
nutzen ganz einfach SHOWASC.                         
Es wird hier also nach Zeile 300 verzweigt, wenn  der
Drucker  die Tabelle drucken soll, oder zu Zeile 200,
wenn sie auf dem Bildschirm dargestellt werden soll. 
Anschließend kommt in Zeile 90 unseres Programms noch
der Vergleich, ob 'a$' nicht den Buchstaben 'e' bein-
haltet. Ist dies der Fall, so wird das  Programm  mit
END beendet.                                         
Interessant  ist  noch Zeile 100. Hier wird wieder in
Zeile 60 zum GET-Befehl gesprungen,  also  zurück  in
unsere  Abfrageschleife.  Dies  ist  notwendig, da ja
auch noch andere Tasten, als F1, F7 oder e,  gedrückt
worden  sein  könnten - sei es aus Versehen, oder nur
weil der User das Programm einmal ärgern wollte.  War
dies  der  Fall,  so hat der Computer bis in Zeile 90
verglichen und festgestellt, daß keiner der 3  ASCII-
Codes  in ' a$' gespeichert ist. Jetzt würde er ja im
Programm ganz normal weitermachen. Da ich in (der nun
folgenden) Zeile 200 allerdings  das  Modul  abgelegt
habe,  das  die Ausgabe auf den Bildschirm übernimmt,
müssen wir ihn hier dann abgefangen, damit  er  nicht
unkontrolliert  in  eine  Unterroutine reinläuft, was
eben durch jenen besagten Sprung in die Zeile 60 rea-
lisiert wird.                                        
Der zweite Befehl,  den  ich  Ihnen  noch  vorstellen
möchte, heißt ON, und wird in Verbindung mit GOTO und
GOSUB benutzt. Er ist sozusagen eine  spezielle  Ver-
sion des IF-Befehls. Hinter ON folgt eine Formel, die
vom  Computer errechnet wird. Dies ist im einfachsten
Fall eine numerische Variable.  Dann  kommt  entweder
der  GOTO-  oder  der GOSUB-Befehl, gefolgt von einer
Liste mit Zeilennummern, die durch  Kommata  getrennt
werden. Praktisch sieht das etwa so aus:             
20 on x goto 100,200,300,400,500                     
Jetzt wird geprüft,  welcher Wert  in  'x'  enthalten
ist.  Ist  x=1, dann wird die erste Zeilennummer, die
in der Liste steht, angesprungen (wie  wenn  sie  ein
GOTO  100 ausführen würden). Ist x=2 dann wird die 2.
Zeilennummer angesprungen, bei  x=3  die  3.  und  so
fort...                                              
Diese eine  Zeile  entspricht  also  den  5  IF-THEN-
Zeilen:                                              
10 if x=1 then 100                                   
20 if x=2 then 200                                   
30 if x=3 then 300                                   
40 if x=4 then 400                                   
50 if x=5 then 500                                   
Sollte  x gleich 0, beziehungsweise negativ, oder gar
größer als die angegebenen Glieder der Liste sein, so
wird ganz normal im  Programm  fortgefahren.  Wollten
wir  unser  Programm  von vorhin also umschreiben, so
müßte das folgendermaßen aussehen.                   
60 input"Menüpunkt ";x                               
70 on x goto 200,300,400                             
80 goto 60                                           
Das  sieht doch schon gleich viel kürzer aus!  Aller-
dings darf man hier nicht vergessen, daß in Zeile 400
dann auch wirklich noch ein END-Befehl steht, da die-
ser  ja  in  unserem alten Programm direkt in der IF-
THEN-Abfrage kam.                                    
Ich habe hier übrigens ganz bewußt  den  INPUT-Befehl
benutzt, da wir ja gelernt haben, daß man bei GET nur
Stringvariablen einlesen kann. Hierbei haben wir dann
im  Endeffek  keine  Möglichkeit  mit  ON  zu  arbei-
ten, es sein denn man greift zu einem kleinen Trick: 
die Ziffern der Zahlen  sind  nämlich  im  ASCII-Code
alle  hintereinander  angeordnet.  Die 0 hat den Code
48, die 1 den Code 49 und so weiter, bis zur  9,  die
den  Code  57 belegt. Wird bei einer GET-Abfrage also
die 1 gedrückt, so enthält a$ den CHR$-Code 49.  Wenn
wir jetzt von dieser Zahl einfach den Wert 48 subtra-
hieren, so erhalten wir das Ergebnis 1, was ja  genau
die  Taste  ist,  die  gedrückt  wurde, nur haben wir
jetzt einen Zahlwert, mit dem ON etwas anfangen kann.
Das Programm hierzu müßte dann so aussehen:          
60 get a$:if a$="" then 60                           
70 on asc(a$)-48 goto 200,300,400                    
80 goto 60                                           
Hier haben Sie dann auch ein  Beispiel,  in  dem  wir
eine  ganze Formel benutzen, die zuerst berechnet und
dann ausgewertet wird. Wir haben dabei die, uns mitt-
lerweile  schon altbekannte, ASC-Anweisung angewandt,
um den CHR$-Code der in 'a$' gespeicherten  Taste  zu
erfahren.                                            
Wie eingangs schon erwähnt, könnten Sie hier auch den
GOSUB-Befehl verwenden, nur müssen Sie dann Ihre  Mo-
dule auch mit RETURN wieder abschließen. Denkbar wäre
auch,  daß man mit Buchstaben die Tasten abfrägt, wo-
bei man alphabetisch vorgeht. Da der  ASCII-Code  des
Zeichens 'a' den Wert 65 hat, müßten Sie hier nur den
Wert  64 subtrahieren, um brauchbare Zahlwerte für ON
herauszubekommen.                                    
Hiermit möchte ich nun für diesen Monat wieder einmal
schließen und mich bis Mai verabschieden.  Wir werden
uns dann, wie ich diesmal schon angedeutet hatte,  um
etwas höchst wichtiges kümmern, was unerläßlich  ist,
wenn man sich ein wenig mit der Grafik- und Soundpro-
grammierung des C64 beschäftigen möchte. Ich rede von
dem sogenannten Binärsystem  und  dem  Speicheraufbau
unseres kleinen Freundes. Mehr dann  nächsten  Monat.
Bis dann also, Ihr                                   
                                  Uli Basters.       
     BASIC-Kurs:  "Von Adam und Eva..." (Teil 5)     
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾     
Herzlich  Willkommen beim fünften Teil unseres Basic-
kurses. Wie letzten Monat schon versprochen  geht  es
diesmal  um  das sogenannte Binärsystem und den Spei-
cheraufbau unseres 64ers. Dieses Thema hat eigentlich
mit BASIC im allgemeinen ganz  und garnichts zu  tun,
doch  ist es unerläßlich wenigstens einige Kenntnisse
davon zu haben, wenn man sich  mit  der  Grafik-  und
Soundprogrammierung auf dem C64 beschäftigen möchte. 
Zunächst einmal eine kleine Erläuterung zu Zahlen  im
allgemeinen:                                         
Wie Sie ja wissen benutzen wir Menschen ein Zahlensy-
stem  mit dessen Hilfe wir Maße, Gewichte, Geldsummen
oder ähnliches bequem ausdrücken können. Ich  spreche
vom  sogenannten  "Dezimalsystem".  Indem wir uns der
Ziffern 0123456789 bedienen, können wir durch  belie-
biges  kombinieren dieser Ziffern Zahlen von unendli-
cher Länge bilden. Ein  Beispiel  wäre  da  die  Zahl
1989. Sie gliedert sich in 4 Teile auf, die ich Ihnen
im Folgenden einmal grafisch darstellen möchte:      
                                      Die  Buchstaben
                                      T,H,Z   und   E
                                      stehen      für
                                      "Tausender",   
                                      "Hunderter",   
                                      "Zehner"    und
                                      "Einer".    Das
                                      heißt also, daß
                                      die  Zahl  1989
                                      in  eine   Zahl
                                      mit vier Kompo-
                                      nenten   aufge-
                                      spaltet wird.  
Mathematisch läßt sich das folgendermaßen ausdrücken:
1000*T +  100*H +   10*Z +    1*E = THZE (oder auch) 
10↑3*T + 10↑2*H + 10↑1*Z + 10↑0*E = THZE             
Oder in unserem Beispiel:                            
1000*1 +  100*9 +   10*8 +    1*9 =                  
10↑3*1 + 10↑2*9 + 10↑1*8 + 10↑0*9 =                  
  1000 +    900 +     80 +      9 = 1989             
Jeder  Stelle  der  Zahl  ist also eine Potenz von 10
zugeordnet  (1=10↑0,  10=10↑1,  100=10↑2,  1000=10↑3,
usw...).  Daher auch der Name DEZIMALsystem - "decum"
kommt aus dem lateinischen und heißt "zehn".         
Dieses Verfahren läßt sich natürlich auch bei größer-
stelligen Zahlen anwenden. Bei der Zahl  2313660  ist
die höchste  Zehnerpotenz  10↑6. Hierbei ist übrigens
noch anzumerken, daß die letzte Ziffer eine Null ist,
bei der der ihr zugehörige Potenzfaktor  (hier  10↑0)
sozusagen  "wegmultipliziert" wird, denn 1*0=0,  wes-
halb auch hier als Endsumme aller Produkte der Poten-
zen  2313660  herauskommt.  Das scheint alles kompli-
zierter als es ist - wichtig ist, daß  Sie  begriffen
haben,  daß  eine  Dezimalziffer nur aus der Addition
von 10er-Potenzen besteht.                           
Sie sehen auch, daß jedesmal nachdem wir die  höchste
Ziffer  einer  Potenz  erreicht haben, nämlich die 9,
die nächste Zahl als ein Vielfaches der nächsthöheren
Potenz darstellen können. Haben  Sie  also  die  Zahl
neun  erreicht,  so findet ein sogenannter "Überlauf"
statt, das heißt, daß  die  nun  folgende  Zahl  eine
Stelle mehr bekommt, und ihre höchste 10er Potenz mit
der  Ziffer  1  als  Multiplikator versehen wird. Der
Nachfolger von 9 ist 10 wobei letztgenannte Zahl eine
zweistellige ist, erstere allerdings  nur  eine  ein-
stellige.                                            
Ebenso  kommen  Überläufe vor, wenn wir von 19 auf 20
zählen. Hier wird der Zähler der nächsten  Potenz  um
eins  erhöht.  Auch von 29 auf 30 verhält es sich so,
und so fort. Bei jedem Überlauf erhält also die nied-
rigere  Potenz  die  Ziffer  0 in den Zähler, während
die höhere die nächst höhere Ziffer verpasst bekommt.
Beim Zählen von 99 auf  100  zum  Beispiel  geschieht
dies  sogar  gleich  zweimal.  Zum Einen erhalten die
"Einer" (10↑0) die Nullziffer und es findet ein Über-
lauf  zu  den "Zehnern" (10↑1) statt, zum Anderen be-
wirkt dieser wiedrum, daß die "Zehner" überlaufen und
somit den Zähler 0 erhalten,  wobei  die  "Hunderter"
(10↑2)  um  1 erhöht werden und nun die Ziffer 1 dort
im Zähler steht.                                     
Sehen  Sie  hier  das Ganze ein wenig grafisch aufge-
macht (denn ein Bild sagt mehr als tausend Worte):   
Wir haben also gelernt, daß die 10 mit ihren Potenzen
die Basis unseres Zahlensystems liefert, da alle  De-
zimalzahlen  als  Summe von 10er-Potenzen dargestellt
werden können. Sie werden jetzt fragen:              
"Was hat das Ganze denn mit dem Binärsystem  zu  tun,
darum geht es hier doch?"                            
Nun, das Binärsystem folgt nämlich (fast) genau  die-
sem  Muster, mit dem einzigen Unterschied (daher auch
die Einschränkung eben), daß wir hier nicht mit einer
Basis von 10 sondern mit der  von  2  arbeiten.  Auch
hier  können Sie den Namen des Systems von ihr ablei-
ten "Bi" steht für Zwei. Da  wir  ja  nun  alle  2er-
Potenzen  verwenden, brauchen wir logischerweise auch
nur zwei Ziffern, mit denen  wir  unsere  Binärzahlen
darstellen (im Dezimalsystem hatten wir ja 10 davon -
Sie  sehen, es werden immer soviele Ziffern benötigt,
wie die Basis angibt). Dies  sind  ganz  einfach  die
Ziffern  0  und  1.  Demnach kann man also sagen, daß
eine Binärzahl so aussehen könnte:   11001010.  Diese
hier  zum Beispiel ist achtstellig. Das hat einen be-
sonderen Grund, wie wir später erkennen werden.      
Wie  sich  eine  solche  Zahl jetzt zusammensetzt ist
klar - wir müssen ganz einfach  die  Potenzen  von  2
nebeneinander  schreiben (allerdings mit der niedrig-
sten ganz links und der höchsten ganz rechts) und die
Produkte der Binärziffern mit den  ihnen  zugehörigen
Potenzen  miteinander addieren. Als Ergebnis erhalten
wir dann  unsere  Binärzahl  in  Dezimalschreibweise.
Führen wir dies doch einmal durch:                   
MD8905/MD8905-KURS-5.8.hires.png
Sie sehen also:  wir  benutzen  hier  genau  dasselbe
Prinzip  wie beim Dezimalsystem, mit dem Unterschied,
daß hier die Produkte der 2er-Potenzen  addiert  wer-
den.                                                 
Doch warum das alles?  Wozu können wir  das  Binärsy-
stem  gebrauchen,  und warum sind achtstellige Binär-
zahlen etwas Besonderes?  Leider muß ich  zur  Beant-
wortung dieser Frage wiederum etwas weiter ausholen: 
Im  Prinzip  kann man sagen - und das wird mir jeder,
der sich  mit  Computern  gut  auskennt  bestätigen: 
"Computer  sind dumm".                               
  Sie  können  nämlich  ausschließlich  nur  zwischen
"STROM  AN" und "STROM AUS" unterscheiden. Das heißt,
daß sie nur erkennen können, ob auf einer ihrer  vie-
len  Leitungen  ein  elektrischer  Strom fließt, oder
nicht. Was Computer jetzt allerdings so schlau macht,
daß wir Ihnen Befehle eingeben können, die  sie  dann
ausführen  können  liegt  einfach  nur daran, daß sie
immens viele socher EIN/AUS-Leitungen  besitzen   und
daß  diese in richtiger Kombination bestimmte Wirkun-
gen erzielen können.  Ein  recht  einfaches  Beispiel
wäre etwa folgendes:                                 
Angenommen,  ein  Computer  hätte  vier Leitungen vor
sich, die er auf EIN oder AUS überprüfen  könnte.  Er
erkennt,  daß  Leitung 1 EINgeschaltet (sprich:  "auf
ihr fließt  Strom),  Leitung  2  AUSgeschaltet  (hier
fließt also KEIN Strom), Leitung 3 wieder EINgeschal-
tet und  Leitung  4  ebenfalls  wieder  EINgeschaltet
sind. Daraus ergibt sich die Kombination:            
EIN                                                  
AUS                                                  
EIN                                                  
EIN                                                  
Nun weiß unser Computerchen zusätzlich noch, daß  er,
wenn  diese  Kombination eintreten sollte, beispiels-
weise die Hintergrundfarbe auf Dunkelgrau  umschalten
soll. Diese Information ist irgendwo in seinem Aufbau
gespeichert.                                         
Sie sehen also, so einfach (oder kompliziert) ist es,
einen  Computer  ganz elementar zu programmieren, das
heißt  also  ganz  grundsätzlich,  ohne  irgendwelche
Hilfsmittel  ihm  einen Befehl zu erteilen, indem man
bestimmte Stromleitungen in ihm ein-  oder  ausschal-
tet.  Kompliziert  ist  dies vielleicht deshalb, weil
man hierzu alle  möglichen  Kombinationen  mit  ihrer
Wirkung  kennen muß. Das sind bei vier Leitungen zwar
"nur" 16 verschiedene, aber es könnten ja  beispiels-
weise  auch viel mehr Leitungen zum Unterscheiden zur
Verfügung stehen.                                    
Hm - Moment einmal, die Zahl 16 hatten wir doch heute
schon einmal!!!  Genau - 16 ist die vierte Potenz von
2  (also  2↑4),  der  Wert  der  fünften  Ziffer  des
Binärsystems!   Und genau das ist es, worauf ich hin-
aus möchte:  die oben  genannte   EIN/AUS-Kombination
könnte  nämlich auch genausogut folgendermaßen ausse-
hen (wenn man anstelle von EIN die Ziffer 1  und  an-
stelle von AUS die Ziffer 0 schreibt):               
EIN AUS EIN EIN                                      
  1   0   1   1                                      
Und siehe da:  da haben wir doch eine echte  (vorläu-
fig vierstellige) Binärzahl!  Ins Dezimalsystem umge-
rechnet lautet sie übrigens 11 (elf). Und tatsächlich
ist es auch so, daß wenn wir  unserem  C64  an  einer
bestimmten  Stelle in seinem Speicher die Zahl 11 an-
geben, er den Bildschirm in die Farbe Dunkelgrau  um-
färben wird.  "An einer bestimmten Stelle" hört  sich
vielleicht  etwas merkwürdig an, doch werden wir dies
jetzt noch klären.                                   
Wollen wir uns nun mit dem Speicheraufbau unseres C64
befassen.  Anschließend  werden  Sie feststellen, daß
das Wort "Stelle" absolut passend ist.               
Wie Sie vielleicht einmal gehört haben, oder in Ihrem
C64  Bedienungshandbuch  gelesen  haben,  verfügt Ihr
kleiner Freund über 64 (sogenannte) Kilobytes (Abkür-
zung :   KB) Speicher (bei denjenigen Lesern, die die
Funktionsweise des Binärsystems begriffen haben soll-
ten, müßte eigentlich gerade eben ein Licht aufgegan-
gen sein - 64 ist die  sechste  Potenz  von  2,  also
2↑6).  Bestimmt  konnten Sie bis jetzt absolut nichts
damit anfangen, weshalb wir jetzt erst einmal  klären
wollen  was  ein  Kilobyte, oder besser ein einzelnes
Byte ist. Zuerst einmal zum Byte:                    
Ein Byte ist die Zusammenfassung  von  acht(!)  soge-
nannten  Bits. Man kann also sagen:  1 Byte = 8 Bits.
Doch was, um alles in der Welt, ist jetzt wieder  ein
Bit?   Nun,  ein  Bit ist ganz einfach eine von jenen
vielen Leitungen, wie ich sie oben schon  beschrieben
hatte,  die ein- und ausschaltbar sind. Eine von die-
sen Leitungen, die ein  Computer  miteinander  kombi-
niert, um den Befehl, den er ausführen soll zu ermit-
teln. Womit unsere Frage nach dem "Warum  eine  acht-
stellige  Binärzahl"  beantwortet wäre:  da unser Bit
für eine stromführende Leitung  steht,  die  entweder
EIN-  oder  AUSgeschaltet  sein kann (1 oder 0) , und
weil acht Bit einem  Byte  entsprechen,  kann  dieses
Byte  mit  Hilfe  einer  achtstelligen Binärzahl aus-
gedrückt werden. Man spricht hier von dem "Wert"  ei-
nes Bytes. Von der Binärzahl also, die in diesem Byte
enthalten ist, oder anders gesagt:  von den Bits, die
in diesem Byte "gesetzt" (Bit=1) oder "nicht gesetzt"
(Bit=0) sind.                                        
Würde  man also sagen:  dieses Byte hat den Wert 202,
so würde man  damit  die  Bitgruppe  11001010  meinen
(hier einmal die Werte unseres Beispiels von oben).  
Ein Kilobyte ist jetzt ganz  einfach  die  Gesamtheit
von  1024  Bytes.  Dies verhält sich etwa ähnlich wie
bei Gramm und  Kilogramm.  Ein  Kilogramm  sind  1000
Gramm,  oder  das 10↑3-fache von 1. Bei Bytes rechnet
man mit einer Potenz von 2, da die Bytes ja auch  auf
ein System aus 2er-Potenzen aufgebaut sind, und somit
die  Zahlen besser "harmonieren". Doch dies ist jetzt
unwichtig, da Sie  die  Bedeutung  dieser  "Harmonie"
erst  verstehen  müssen,  wenn Sie einmal die Maschi-
nensprache (auch "Assembler genannt) lernen werden.  
Des Weiteren sind ein  Megabyte demnach also 1024 Ki-
lobytes. Am Rande vielleicht eine kleine  Umrechnung-
stabelle:                                            
1 Megabyte = 1024 Kilobytes = 1024*1024 Bytes        
(1024*1024 sind übrigens  1048576,  also  "ein  klein
wenig" mehr als eine Million...)                     
Jetzt wissen Sie also, daß  wir  insgesamt  64*1024*8
(=524288)  Leitungen  in  unserem  C64  haben  (64 KB
eben), die alle in verschiedenster  Weise  ein-  oder
ausgeschaltet sein können. Zahlenmäßg gesehen ist das
ja eine ganz schöne Menge, in der Realität werden wir
allerdings  nur  eine  Handvoll davon effektiv nutzen
können. Man kann etwa sagen, daß gute 99 Prozent die-
ser  64  Kilobytes  nur  zur Speicherung von Befehlen
benutzt wird. Das heißt also, daß sich  der  Computer
in  diesen  Bereichen  die Befehle, die er irgendwann
einmal ausführen soll, einfach nur zwischenspeichert,
damit er sie bei Bedarf dann gleich griffbereit  hat,
um sie abzuarbeiten. Doch dies fällt ebenfalls in den
Themenbereich  der Maschinensprache, wo es sogar eine
sehr große Rolle spielt.                             
Diese 65536 Bytes (=64 KB), können jetzt alle einzeln
mit ihren Nummern angesprochen werden. Bildlich könn-
te  man  sich das etwa wie eine Straße vorstellen, in
der es 65536 Häuser gibt, mit ebenso vielen  Hausnum-
mern. Möchten Sie jetzt beispielsweise einen Brief an
das Haus mit der Nummer 53281 schicken, so müßten Sie
diesen an folgende Adresse schicken:                 
An                                                   
Herrn Byte                                           
Speicherstraße 53281                                 
64KB Commodore 64                                    
Der  Name  des  Adressaten und der adressierten Stadt
dient hier nur zur Untermalung, wichtig  ist  jedoch,
daß  Sie  erkennen,  daß  Sie so einen "Brief" an das
Haus mit der Nummer 53281 schicken können. Der Inhalt
dieses Briefes könnte etwa folgendermaßen aussehen:  
Sehr geehrter Herr Byte,                             
00001011                                             
Herzlichst, Ihr Programmierer.                       
Auch diesmal nur ein kleines aufmunterndes  Beispiel,
um  den  Zweck des "Verschicken eines Briefes" aufzu-
zeigen. Tatsächlich sagt man sogar, daß man ein  Byte
"adressiert",  also  seine  "Adresse" angibt, und ihm
dann einen Wert zuweist. Mit unserem Brief hätten wir
also dem Byte 53281  den  Wert  00001011  zugewiesen,
womit wir wieder beim Binärsystem wären. Der aufmerk-
same Leser hat bestimmt schon längst gemerkt, daß wir
hier die Binärzahl von vorhin auf dem Bildschirm ste-
hen  haben,  nämlich  die dezimale 11. Diesmal aller-
dings achtstellig, da wir ja gelernt haben,  daß  man
das  ganze  Byte adressiert, und somit auch auf jeden
Fall 8 Bits verändert. Die höherwertigen 4 Bits bein-
halten  jetzt  ganz  einfach die Ziffer 0, womit ihre
Produkte mit ihren jeweiligen Potenzen auch zu 0 wer-
den, weshalb sie auch nicht zu Gewicht schlagen.     
Wollen wir nun endlich den BASIC-Befehl kennenlernen,
mit  dem  wir "Briefe verschicken" können:  der POKE-
Befehl.                                              
Die Syntax von POKE ist denkbar einfach:  Sie  müssen
hinter dem Befehlswort POKE ganz einfach nur noch die
Adresse  des  zu  verändernden  Bytes angeben und an-
schließend, durch ein Komma voneinander getrennt, den
Wert, der zugewiesen werden soll, allerdings in dezi-
maler  Schreibweise. Daher also auch die vorangehende
langwierige Erklärung des Binärsystems,  denn  später
müssen  Sie  sich Ihre Bitkombinationen selbst zusam-
menrechenen können.                                  
Um unser Adressierungsbeispiel gleich in die Realität
umzusetzen  -  hier  ist der Brief an Herrn Byte, wie
wir ihn in BASIC schreiben mÜssten:                  
POKE 53281,11                                        
Wir  haben  also der Speicherzelle (das ist die deut-
sche Übersetzung für Byte) 53281 den  Dezimalwert  11
beziehungsweise  den  Binärwert  00001011 zugewiesen.
Probieren Sie es doch einmal aus, und beobachten Sie,
was passiert... Na?  Verblüfft?  Eben genau  DAS  ist
eingetreten, was ich Ihnen vorhin beschrieben hatte: 
der  Hintergrund  des  Bildschirms Ihres C64 hat sich
vom üblichen Blau in ein tristes Dunkelgrau verfärbt.
Sie sehen also, man muß nur die richtigen STELLEN  im
Speicher  des  64ers verändern, um gewisse Ergebnisse
zu erzielen.                                         
Jetzt möchte ich Ihnen allerdings nicht verschweigen,
daß  es  ebenso  möglich ist, von einer Speicherzelle
einen Brief zu erhalten. Das heißt also, daß Sie  als
Programmierer  die Speichezelle dazu veranlassen kön-
nen, ihren Inhalt (oder ihren Wert) Ihnen  zuzuschik-
ken.  Dies kann in BASIC mit der PEEK-Funktion reali-
siert werden. Die Syntax von PEEK ist ebenfalls  sehr
einfach:   Sie  müssen  nach dem Befehlswort PEEK nur
noch die gewünschte Byteadresse, in Klammern gesetzt,
angeben, um den Inhalt dieses Bytes zu erhalten.  Ich
möchte  darauf aufmerksam machen, daß es sich hierbei
um eine FUNKTION handelt. Sie können PEEK  also  ohne
alles  kaum  effektiv  nutzen, es solte nämlich schon
ein PRINT-Befehl, eine Variablenzuweisung,  oder  ein
Vergleich durch IF-THEN dabei stehen, um der Funktion
entsprechend  einen  Sinn zu geben. Eine Möglichkeit,
sich den Inhalt einer Speicherzelle  anzusehen,  wäre
über PRINT gegeben. Versuchen Sie doch einmal folgen-
des:                                                 
PRINT PEEK(53281)                                    
Jetzt sollten Sie eine Zahl auf dem Bildschirm stehen
haben.  Sie  gibt  die Farbe des Hintergrundes an, da
das Byte 53281  ja  für  die  Farbe  des  Bildschirms
zuständig  ist,  wie wir es vorhin gelernt hatten. Es
kann durchaus sein, daß Sie jetzt hier etwas  anderes
als 11 auf dem Bildschirm stehen haben. Das hat etwas
mit  der  computerinternen  Handhabung  der Farben zu
tun, doch das wollen wir an späterer  Stelle  genauer
behandeln. Prinzipiell kann man jetzt also sagen, daß
Sie mit Hilfe von PEEK und POKE ein Byte zu verschie-
denen Aktionen veranlassen können.  Mit  PEEK  lassen
Sie  sich von dem Byte einen Brief schicken, der sei-
nen Wert beinhaltet und mit POKE können Sie das Spiel
umkehren und dem Byte einen Brief zuschicken, der den
Wert beinhaltet, den es annehmen soll. Wie wir  gese-
hen haben, ist gerade letztere Funktion ja sehr nütz-
lich, wenn wir verschiedene Dinge im Computer  bewir-
ken wollen, man muß nur wissen an welchen Stellen man
Änderunngen  vornehmen  muß, um einen gewissen Effekt
zu erzielen.                                         
Womit  wir  wieder  bei den Stellen wären. Ich möchte
Ihnen hier einmal eine kleine Übersicht aller Stellen
(Bytes, Speicherzellen, Hausnummern,  Adressen,  oder
wie  Sie es auch immer nennen möchten) geben, wie Sie
im C64 vorkommen. Man kann diese 65536 Bytes  nämlich
in  gewissen Aufgabenbereichen zusammenfassen, um et-
was Ordnung in die Tausenden von verschiedenen Zellen
zu bringen:                                          
MD8905/MD8905-KURS-5.22.hires.png
Ich habe hier den Speicher des C64 einmal  mit  Hilfe
eines  Balkens, der in verschiedene Teilbereiche auf-
gespalten ist, dargestellt. Unten sehen Sie die Spei-
cherzelle  0, und am oberen Rand haben wir das letzte
Byte, mit der Adresse 65535. Sie  werden  jetzt  fra-
gen:   "Warum  65535  wo  wir doch die ganze Zeit von
65536 Bytes reden ?" - Nun, wir  müssen  hier  wieder
berücksichtigen,  daß  das  Byte mit der Adresse 0 ja
auch mitzählt, somit  haben  wir  (rein  zahlenmäßig)
dann   65535   Bytes   plus  ein  0-Byte,  das  macht
65535+1=65536!                                       
Ich möchte Ihnen hier dann gleich noch  die  Aufgaben
der verschiedenen Speicherbereiche erläutern, wie ich
sie  im  Bild  schon angedeutet habee. Hierbei möchte
ich allerdings vorerst die  Bytes  von  0  bis  40960
übergehen, da Sie deren Funktionsweise besser verste-
hen können, wenn Sie die der Folgenden schon kennen. 
Beginnen wir also bei 40960 bis 49152. Hier steht das
sogenannte  BASIC-ROM.  Klären  wir  zunächst einmal,
wofür ROM steht. Hierzu sollte ich vielleicht  erwäh-
nen,  daß es zwei verschiedene Arten von Speicherzel-
len in Ihrem C64 gibt. Bestimmte  Teilbereiche  haben
also  bestimmte Eigenschaften, die ein anderer wiede-
rum nicht hat. Die zwei Arten, von denen hier gespro-
chen wird, nennt man RAM und ROM. RAM steht für "Ran-
dom Access Memory" und ROM für  "Read  Only  Memory".
Übersetzen  wir  dies  aus  dem  Englischen, so haben
wir:  "Speicher für beliebigen  Zugriff"  und  "Spei-
cher,  der  nur  gelesen  werden kann." Dies heißt im
Klartext, daß RAM-Speicherzellen beschrieben UND  ge-
lesen  werden  können,  im Gegensatz zu ROM-Adressen,
die NUR gelesen werden. Sie können sich dies etwa mit
folgendem Bild verdeutlichen:  die RAM-Adressen  sind
schreibfreudige Mitbürger. Sie erhalten gerne Briefe,
und  beantworten  diese auch, sollten sie dazu aufge-
fordert worden sein. ROM-Adressen hingegen sind  eher
Kontaktscheu,  sie  ignorieren  ihre Post, und werfen
sie, wie Sie es vielleicht auch manchmal  bei  Werbe-
sendungen tun, ungelesen in den Mülleimer. Sie kennen
ihren Programmierer schon gut genug, weshalb sie auch
nur  dann  an ihn ihren Inhalt senden, wenn dieser es
unbedingt verlangt. Außerdem sind  ROM-Adressen  sehr
konservative  Individuen,  sie haben nämlich auch gar
nicht vor, ihre Einstellung (also ihren Wert) zu  än-
dern  und  bleiben  auch auf Immer und Ewig bei ihrem
voreingestellten Wert.                               
Doch  jetzt  einmal  Spaß beiseite - der Grund, warum
man ROM und RAM schuf, war einfach der, daß man einen
Speicher benötigte, der auch ohne  Stromzufuhr,  also
im ausgeschalteten Zustand des Computers, in der Lage
ist,  seine in ihm gespeicherten Informationen zu be-
halten. Da man sonst bei jedem neuen Einschalten  ei-
nes  Computers  ein  gewisses  Grundprogramm jedesmal
wieder von Neuen hätte eingeben müssen, wobei  natür-
lich die Frage aufkommt, wie man dies getan hätte, da
in  einem  leeren  Computer ohne Programm auch nichts
getan werden kann, um Daten  aufzunehmen,  da  dieser
immer  ein Programm braucht, das ihm diese Daten ein-
liest. Ebenso ist es bei BASIC. In dem  vorhin  ange-
sprochenen  Bereich des BASIC-ROMs sind die Grundpro-
gramme gespeichert, die es uns ermöglichen, in  BASIC
mit  unserem 64er zu kommunizieren. Alle Befehle, die
wir bisher behandelt haben,  ebenso  wie  diese,  die
noch  kommen werden, sind hier genauestens definiert,
so daß der Computer immer genau weiß, was er  zu  tun
hat,  wenn Sie ihn Beispielsweise mit der Buchstaben-
folge PRINT konfrontieren.                           
ROM  braucht also keinen Strom, um die in ihm gespei-
cherten Bits zu behalten. Sie können sich  dies  etwa
als  eine  Unmenge von Leitungen vorstellen, die fest
und unveränderlich sind. Und nicht, wie es  beim  RAM
der  Fall ist, durch Schalter ein-, oder ausschaltbar
sind. ROM-Bits STEHEN ganz einfach schon auf EIN oder
AUS.                                                 
Der Vorteil am RAM ist ganz einfach, daß  man  seinen
Inhalt  sozusagen  "von Hand" verändern kann und wäre
dies nicht möglich, so könnte man beispielsweise  die
Bildschirmfarbe  auch gar nicht verändern. Dafür geht
diese dann allerdings auch  verloren,  wenn  man  die
Stromzufuhr unterbricht.                             
Doch machen wir nun wieder in  unserer  Speicherüber-
sicht  weiter. Es folgt nun der Bereich von 49152 bis
53248. Hier ist freier RAM-Speicher, der vom Computer
nicht benutzt wird. Wir als Programmierer, können ihn
uns zwar zu Nutze machen, doch  das  ebenfalls  erst,
wenn Sie sich einmal mit Assembler befassen sollten. 
Der  folgende  Speicherbereich ist der für uns BASIC-
Programmierer wichtigste,  weshalb  ich  anschließend
auch  etwas  genauer darauf eingehen werde. Der soge-
nannte I/O-Bereich,  oder  Input/Output-Bereich  (von
53248 bis 57344), enthält die Speicherzellen der ver-
schiedenen  Ein-/Ausgabe-Bausteine  (Input/Output   =
Eingabe/Ausgabe).  Das sind jene Bausteine (oder Com-
puterchips) in unserem C64, die dafür  verantwortlich
sind,  daß  zum Beispiel der Ton aus dem Lautsprecher
kommt, daß das Floppylaufwerk auch odrnungsgemäß sei-
ne Daten speichert, oder daß, wie oben schon gezeigt,
der  Bildschirm  in  dunkelgrauer  Farbe  dargestellt
wird. Wir wollen uns Speziell um zwei bestimmte Chips
aus diesem Bereich kümmern, sie tragen die Namen  SID
und VIC.                                             
SID steht für "Sound Interface Device" was  etwa  so-
viel  heißt wie "Musikerzeuger" (nicht wörtlich über-
setzt, doch das hier trifft die Aufgabe von  SID  auf
den  Punkt genau). Um ihn werden wir uns in einer der
nächsten Ausgaben noch kümmern.                      
VIC ist die Abkürzung für "Video  Interface  Control-
ler".  Wie sein Name schon verrät (Überwacher der Vi-
deoschnittstelle, oder  frei nach J.R.R. Tolkien "Der
Herr der Videoschnittstelle"), ist er  zuständig  für
Bildschirmaufbau  und Grafik innerhalb unseres Compu-
ters. Er wird auch unser Hauptthema sein, um  das  es
sich nächsten Monat drehen wird.                     
Nun wollen wir noch unsere  Speichertabelle  zu  Ende
abhandeln.  Da  wäre zunächst einmal noch der Bereich
von 57344  bis  zum  Ende  des  Speichers  (also  bis
65535).  Hier haben wir wieder einen ROM-Bereich vor-
liegen, diesmal allerdings das Betriebssystem-ROM.   
Das Betriebssystem ist der wichtigste Teil eines Com-
puters, da in ihm alle Unterprogramme enthalten sind,
die zur Steuerung des Computers beim Einschalten  und
während  der Eingabe über die Tastatur unbedingt not-
wenig sind. Hier liegt das eigentliche Herzstück  des
C64,  ohne  das er nur bedingt leben könnte. Wenn wir
das   aus   unserer   Sicht   als   werdende   BASIC-
Programmierer  betrachten,  könnte  er es sogar über-
haupt nicht. Hier muß ich dann abermals auf  die  Ma-
schinensprache verweisen, denn bei dieser ist es dur-
chaus möglich, den C64 OHNE Betriebssystem zu  benut-
zen, doch ist dies auch hier nur unter -relativ- gro-
ßem Aufwand machbar. Auch werden  Sie  beim  Erlernen
der Maschinensprache nicht umhin kommen, sich mit dem
Betriebssystem eingehender zu befassen, Sie werden es
nach einiger Zeit sogar sehr zu schätzen wissen.     
Zum Abschluß noch  die  Speicherbereiche  von  0  bis
40960,  deren  Funktionen  Sie jetzt besser verstehen
werden:                                              
Da  wäre ja zuerst einmal der Bereich von 0 bis 1024.
In diesem Bereich findet  sich  eine  Ansammlung  von
Bytes,  die ausschließlich vom Betriebssystem und von
BASIC benutzt werden, um bestimmte Werte  zwischenzu-
speichern.  Uns  als BASIC-Programmierern bleiben die
meisten davon verschlossen, und wir können Sie nur in
bedingtem Maße für uns nutzen, doch auch dies zu  ei-
nem späteren Zeitpunkt.                              
Dann  käme als nächstes das VIDEO-RAM, oder der Bild-
schirmspeicher, von 1024 bis 2048. Auf diesen Bereich
werden wir nächsten Monat auch noch genauer eingehen,
da er, wie sich aufgrund  des  Namens  vielleicht  ja
schon  vermuten  läßt, etwas mit VIC zu tun hat. Hier
sei nur gesagt, daß in diesem  Bereich  die  Zeichen,
wie  sie  normalerweise immer auf dem Bildschirm ste-
hen, in genau der Reihenfolge abgespeichert sind, wie
Sie sie auf diesem abgebildet sehen.                 
Als letztes hätten wir dann noch den Bereich von 2048
bis 40960. Zugegebenermaßen wohl der größte Speicher-
bereich  im 64er. Hier werden in aller Regel die Pro-
grammzeilen, so wie Sie sie eingeben gespeichert.    
Der LIST-Befehl tut  also  nichts  anderes,  als  die
BASIC-Zeilen, die hier gespeichert  sind,  Ihnen  auf
dem Bildschirm darzustellen.                         
In  diesem  Bereich finden übrigens gleichzeitig auch
alle Variablen Platz, die Sie  in  Ihren   Programmen
verwenden.                                           
Hiermit bin ich nun wieder am Ende  der  Folge  ange-
langt  und  hoffe, Ihnen nicht zu sehr die Gehirnwin-
dungen mit der Thematik des Speicheraufbaus  und  des
Binärssystems verknotet zu haben. Wie Sie ja merkten,
hatten wir diesmal eigentlich kaum  etwas  mit  BASIC
zu tun, wenn man einmal von PEEK und POKE absieht.   
Doch  glaube  ich  mit diesem Artikel bei Ihnen einen
Grundstein für das "wirkliche" Vertändnis von  Compu-
tern  gelegt  zu haben, da Sie mit Hilfe der Informa-
tionen, die Sie hier und heute  erlangt  haben,  sich
viele  Phänomene der Informatik sehr einfach und ver-
ständlich verdeutlichen können.                      
Ich darf Ihnen nun noch ein fröhliches  Gehirnentkno-
ten  wünschen  und verabschiede mich bis nächsten Mo-
nat, wenn es dann heißt "Von nun an wirds aber bunt -
die Grafikprogrammierung als solche",                
                                     Ihr Uli Basters.
     BASIC-Kurs : "Von Adam und Eva..." (Teil 6)     
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾     
Herzlich  Willkommen zum 6. Teil unsers BASIC-Kurses.
Nachdem mich meine Mitredakteure letzen  Monat  wegen
Platzmangels  aus  meiner  Sparte  geschmissen haben,
geht es nun wieder weiter im  Text.  Allerdings  kann
ich Ihnen eine weitere kleine Enttäuschung nicht vor-
enthalten. Ich hatte Ihnen im Mai  zwar  versprochen,
daß  wir  uns  dieses Mal mit der Grafik beschäftigen
würden, doch möchte ich dies  nun  erst  einmal  auf-
schieben.  Der  Grund  hierfür  liegt darin, daß nach
diesem Kurs hier ein Grafikkurs geplant ist. Da  habe
ich dann auch genügend Platz und Freiheit, Ihnen die-
ses Thema besser zu erläutern und näher zu bringen.  
Gerade  die  Grafik  ist  beim C64 ein sehr brisantes
Thema, zumal BASIC die Grafikprogrammierung in  kein-
ster Weise unterstützt, wie man das von größeren Com-
putern (ich sage da ja nur "AMIGA" und  "AmigaBasic")
gewohnt  ist.  Doch  ganau das wird dann Thema dieses
Kurses werden, weshalb ich Sie jetzt  noch  3  Monate
vertrösten muß. Dann wird nämlich der Basickurs been-
det sein.                                            
Nun wollen wir aber einmal mit diesem sechsten Basic-
kurs  beginnen.  Ich  möchte Sie nun ein wenig in die
Soundprogrammierung des  64ers  einführen,  die  auch
nicht  gerade  ohne ist, und für die Sie die Informa-
tionen über das Binärsystem  und  den  Speicheraufbau
des  C64  vom  letzten  Mal genauso, wenn nicht sogar
noch mehr, benötigen.                                
Erinnern  wir  uns  : mit der Soundprogrammierung hat
der SID, der Chip der Musik erzeugt,  etwas  zu  tun.
Wir hatten ja gelernt, daß die Adressen mit denen man
ihn  programmiert  im sogenannten I/O-Bereich (INPUT-
/OUTPUT- oder EIN-/AUSGABE-Bereich) liegen, der  sich
von  Adresse 53248 bis 57344 erstreckt. "Puh!" werden
Sie sagen, "Das sind ja mehr  als  4000  Speicherzel-
len !  Wie soll man sich die denn alle merken !" Doch
keine Angst ich kann Sie beruhigen.  Der  SID  belegt
lediglich  28  davon.  Ebenso  wie  alle anderen Ein-
/Ausgabe-Bausteine (es sind derer insgesamt vier, die
wir hier allerdings, außer dem SID,  nicht  behandeln
werden),  die  auch nicht mehr als 50 Bytes in diesem
Riesenbereich belegen. Doch Vorsicht. Sie können hier
zwar die meisten Adressen mit beliebigen  Werten  be-
schreiben,  doch  ist  es NICHT möglich die nicht be-
nutzten Speicherzellen zu benutzen. Sollten Sie  hier
einen  Wert  hineinschreiben, so wird gar nichts pas-
sieren, da die adressierte Speicherzelle nämlich phy-
sisch,  also  im  Innern  Ihres 64ers, gar nicht exi-
stiert. Sie bekommen irgendwelche Werte beim Auslesen
mit PEEK geliefert, und beim Schreiben mit POKE  wird
der  zu  schreibende Wert einfach, wie bei einer ROM-
Speicherzelle, ignoriert.                            
Doch  gehen  wir nun einmal zu den Speicherzellen die
wir benutzen DÜRFEN. Die sogenannte Basisadresse  des
SID liegt bei Adresse 54272. Dies ist die erste Spei-
cherzelle des SID. Sie ist deshalb so  wichtig,  weil
wir  sie  benutzen  wollen,  um sogenannte "Register"
adressieren zu können. Ein Register  ist  eine  Spei-
cherzelle  des SID (oder eines anderen I/O-Bausteins)
die man mit Hilfe der Basisadresse und der  Register-
nummer anspricht. Hierzu vielleicht ein Beispiel. Mit
dem Befehl:                                          
POKE SI+24,15                                        
setzt man  die  Lautstärke  der  erzeugten  Töne  auf
"laut". Hierbei steht die Variable SI für die Basisa-
dresse des SID, wir haben ihr also  vorher  den  Wert
54272  zugeordnet !  Das  Register 24 des SID ist für
die Lautstärke verantwortlich. Schreibt  man  hier  0
hinein, so wird der Ton gänzlich abgeschaltet. Mit 15
schalten  Sie  volle Lautstärke ein. Natürlich können
Sie auch alle Werte zwischen 0 und 15 hier  benutzen.
Diese  sind  dann eben je nach dem mehr, oder weniger
laut.                                                
Nachdem Sie nun hoffentlich über die Bedeutung  eines
Registers ausfgeklärt sind, möchte ich erst einmal zu
den  Grundlagen  übergehen. Wie Sie vielleicht wissen
verfügt Ihr 64er über drei "Stimmen".  Das  heißt  er
kann  3  verschiedene Töne gleichzeitig gerenerieren.
Deshalb gibt man einer Stimme des SID auch den  etwas
päßlicheren  Namen  "Tongenerator". Diese sind aufge-
teilt in Tongenerator 1, 2 und 3. Jeder dieser  Gene-
ratoren  arbeitet unabhängig von den anderen und kann
eigene Töne erzeugen ohne  seine  Kollegen  damit  zu
stören.  Sie können jeden einzelnen von Ihnen mit ei-
ner bestimmten "Tonhöhe" und einem bestimmten "Klang"
programmieren. Damit Sie dies ein wenig  besser  ver-
stehen, schlage ich vor, daß wir einmal einen kleinen
Ausflug in die Physik machen:                        
Wie Sie vielleicht wissen besteht ein Ton, so wie ihn
das  menschliche Ohr hört, aus nichts anderem als ei-
nem extrem schnellen Schwingen der Luft. Auch bekannt
unter dem Namen "Schall". Die Art dieses Tones, warum
sich Töne also voneinander unterscheiden können, wird
von zwei Komponenten bestimmt. Da wäre zum einen  die
Wellenform  und zum anderen die Frequenz. Die Wellen-
form gibt an, wie die Schwingungen  verlaufen.  Diese
lassen sich durch eine Grafiklinie darstellen, häufig
sogar durch eine mathematische Funktion. Ein Beispiel
wäre  da  sie Sinuskurve. Mit ihr lässt sich eine Si-
nuswelle erzeugen. Dies klingt  dann  etwa  wie  eine
Oboe.  Ein weicher und "perfekter" Klang, da die Wel-
lenform  ja   dem   perfektesten   geometrischen   2-
dimensionalen Körper zugrunde liegt, dem Kreis.      
Jedem der 3 Tongeneratoren Ihres C64 können  Sie  nun
eine eigene Wellenform einprogrammieren, die dann von
diesem  erzeugt  wird. Eine Sinuskurve kriegt der SID
zwar nicht ganz hin, doch reicht es immerhin zu einer
Dreieckskurve, die der Sinuskurve in Punkto Hoch- und
Tiefpunkten ja schon sehr ähnlich kommt. Sollten  Sie
jetzt hier nur "Bahnhof,  Abfahrt und Koffer geklaut"
verstehen,  so  möchte  ich  sie  mit  dem  Folgenden
noch  ein  wenig mehr aufklären. Jede Wellenform kann
nämlich auch mit Hilfe eines Oszillators als Tonwelle
sichtbar gemacht werden. Aus der  Schule  kennen  Sie
bestimmt noch diese Experimente, wo dann auf so einem
kleinen  runden Bildschirm eine merkwürdige Kurve er-
schien, wenn der Lehrer irgend einen Ton von sich gab
(oder mit Hilfe eines Tongenerators  erzeugte).      
Der C64 versteht es nun, 4 veschiedene solcher Kurven
zu erzeugen, zwischen denen Sie dann auch wählen kön-
nen, wenn Sie einem Tongenerator  eine  "persönliche"
Note geben möchten. Diese sind die Dreieck- (ich hat-
te diese Kurve oben schon  erwähnt),  Rechteck-,  und
Sägezahnkurve.  Dann  gibt es da noch eine Wellenform
die eher eine Sonderstellung einnimmt, die Rauschkur-
ve.  Man  kann  hier  eigentlich nicht mehr von einer
Wellenform reden, da das Rauschen  nicht  nach  einer
vorgegebenen Kurve erzeugt wird, sonden von verschie-
denen Zufallswerten, die den Abstand zum 0-Wert ange-
ben  und  einfach  nur  aneinandergereiht  werden. So
entsteht ein Eindruck des Rauschens.                 
Die Rechteckskurve nimmt ebenfalls  eine  Sonderstel-
lung ein, was ihre Programmierung betrifft. Dies wer-
de ich ein weinig später erläutern.                  
Wie  man nun dem SID klarmacht, welche der 4 Möglich-
keiten man auf einer Stimme spielen möchte, werde ich
Ihnen gleich erklären. Zunächst einmal  noch  zu  der
2ten  Komponente,  mit der sie einen Ton beeinflussen
können,  der  Frequenz.  Davon  haben Sie sicher auch
schon einmal gehört. Je höher die Frequenz ist, desto
schneller wird die Luft zu Schwingungen angeregt.  Es
kommen  quasi mehr Dreiecksspitzen einer Dreieckkurve
(beispielsweise) in gleichen Zeitabständen  an  Ihrem
Ohr  an,  als bei einer niedrigeren Frequenz. Dadurch
werden die Hörnerven mehr gereizt und es entsteht  im
Gehirn  der  Eindruck  eines höheren Tones. Dies kann
bis zum Schmerz gehen, wenn der  Ton  besonders  laut
und  intensiv gespielt wird, wie etwa bei einer Säge-
zahnkurve, oder bei manchen Rechteckkurven (mit  laut
meine  ich RICHTIG laut - wenn Sie auf einem Rockkon-
zert einmal nahe den Boxen standen als der Leadgitta-
rist  ein  Solo von sich gab, dann wissen Sie was ich
meine).                                              
Diese Frequenzen kann man nun auch jedem Tongenerator
angeben, so daß dieser dann genau weiß,  wie  er  den
Ton zu gestalten hat. Um beispielsweise den Kammerton
A  zu  spielen benötigen Sie eine Frequenz von 440 Hz
(Hertz). Geben Sie diese dem Computer an, so wird  er
Ihnen  genau diesen Ton vordüdeln. Das hört sich doch
ganz einfach an ! Nun ja,  ist  es  allerdings  nicht
unbedingt.  Denn Sie können dem SID nicht einfach die
Zahl 440 irgendwo hinschreiben. Dem stehen 2 Dinge im
Weg. Erstens einmal benötigt der SID auch noch weite-
re  Angaben  über einen Ton, bevor er richtig "losle-
gen" kann und zweitens gibt es mit der Frequenzangabe
auch noch einige kleine Probleme, die etwas  mit  der
Hardware des 64ers zu tun haben.                     
Zunächst möchte ich Ihnen eine Übersicht  aller  SID-
Register  geben. Anschließend können wir dann richtig
anfangen. Ich muß noch hinzufügen, daß ich die  Regi-
ster  25-28  aus  Platzgründen  ausgelassen habe. Wir
werden uns mit diesen sowieso nicht befassen, da  de-
ren  Funktion  für  uns  kaum von Nutzen ist. Nur als
Assemblerroutinen wären diese Register  effektiv  von
Nutzen, und dann auch nur sehr, sehr selten. Nun aber
zu unsrer Tabelle :                                  
Register  Adresse  Funktion                          
–––––––––––––––––––––––––––––––––––––––––––––––––––––
  00       54272   Frequenz für Stimme 1 - LO        
  01       54273   Frequenz für Stimme 1 - HI        
  02       54274   Pulsbreite für Stimme 1 - LO      
  03       54275   Pulsbreite für Stimme 1 - HI      
  04       54276   Ton anschlagen und Wellenform für 
                   Stimme 1                          
  05       54277   Hüllkurve ATTACK/DECAY Stimme 1   
  06       54278   Hüllkurve SUSTAIN/RELEASE Stimme 1
  07       54279   Frequenz für Stimme 2 - LO        
  08       54280   Frequenz für Stimme 2 - HI        
  09       54281   Pulsbreite für Stimme 2 - LO      
  10       54282   Pulsbreite für Stimme 2 - HI      
  11       54283   Ton anschlagen und Wellenform für 
                   Stimme 2                          
  12       54284   Hüllkurve ATTACK/DECAY Stimme 2   
  13       54285   Hüllkurve SUSTAIN/RELEASE Stimme 2
  14       54286   Frequenz für Stimme 3 - LO        
  15       54287   Frequenz für Stimme 3 - HI        
  16       54288   Pulsbreite für Stimme 3 - LO      
  17       54289   Pulsbreite für Stimme 3 - HI      
Register  Adresse  Funktion                          
–––––––––––––––––––––––––––––––––––––––––––––––––––––
  18       54290   Ton anschlagen und Wellenform für 
                   Stimme 3                          
  19       54291   Hüllkurve ATTACK/DECAY Stimme 3   
  20       54292   Hüllkurve SUSTAIN/RELEASE Stimme 3
  21       54293   Filter-Grenzfrequenz LO           
  22       54294   Filter-Grenzfrequenz HI           
  23       54295   Resonanz und Filterschalter       
  24       54296   Filtermodus und Lautstärke        
Doch  nun  frisch  ans Werk. Wie Sie ja gesehen haben
gibt es hier jeweils 7 Register für jede Stimme.  Als
aufmerksamer  Leser  sind  Ihnen hierbei bestimmt für
Stimme 1 die Register 00, 01 und 04 aufgefallen.  Mit
diesen  Registern  nämlich  können  wir  unsere  Töne
beeinflussen, so wie wir das bisher gelernt haben. In
Register  00  und  01  wird die Frequenz des Tons für
Stimme 1 angegeben und in Register 04 die Wellenform.
Wollen  wir  nun das Problem lösen, wie wir eine Fre-
quenz, in Hertz gemessen, in  diese  beiden  Register
eingeben.  Ich  hatte  ja  schon angedeutet, daß dies
nicht so einfach sein wird.                          
Ich  hole  hierzu  einmal ein wenig weiter aus. Viel-
leicht haben Sie ja schon einmal gehört, daß der  C64
mit  einer  bestimmten Taktfequenz "getaktet" ist, so
wie das bei jedem Computer der Fall ist.  Ein  Mikro-
prozesor  und  überhaupt  alle logischen Bausteine in
einem Computer brauchen so etwas ganz einfach,  damit
die  Arbeiten  im  Computer  geregelt und gleichmäßig
ablaufen. Als Herzstück dient  hierzu  ein  Quarzbau-
stein,  der eine bestimmte Taktfrequenz vorgibt. Alle
Bausteine greifen sich nun den Takt von diesem  Quarz
ab  und  modulieren ihn meistens auf eine eigene Fre-
quenz, mit der sie besser arbeiten können. Der Mikro-
prozessor  in Ihrem C64 arbeitet zum Beispiel mit ei-
ner Taktfrequenz von 985.2484 KHz. Dies ist genau der
18  Teil  der  Systemtaktfrequenz,  die   vom   Quarz
herrührt.  Diese  beträgt demnach 17 734 472 Hz. Also
knapp 17.7 MHz. Der SID benutzt nun  ebenfalls  diese
Frequenz. Um nun aus internen Gründen des Aufbaus des
SID  auf den richtigen Wert zu kommen, mit dem dieser
dann die echte Tonfrequenz spielt muß man vorher noch
eine kleine Umrechnung  vornehmen.  Diese  folgt  der
folgenden Formel :                                   
WERT=Tonfrequenz * 2'24 / Taktfrequenz               
Möchten Sie also den Kammerton A, mit 440  Hz,  spie-
len,  so müssen Sie erst den SID-Wert hierfür berech-
nen. Dies sieht dann so aus :                        
440Hz * 2'24 / 17734472 = 416.25                     
Lassen wir nun noch die Stellen hinter dem Komma weg-
fallen,  so  erhalten  wir den Wert 416. Genau diesen
Wert müssen Sie jetzt an  den  SID  übergeben,  damit
dieser  einen  440  Hz-Ton erzeugt. Hierbei haben wir
allerdings ebenfalls  noch  ein  kleines  Problem  zu
bewältigen. Wie Sie sich errinnern können wir mit dem
POKE-Befehl lediglich ein Byte verändern, also 8 Bit.
Die  größte  Zahl,  die  Sie mit dem POKE-Befehl also
übergeben können ist die Zahl 255 (2↑8 Bits - 1), die
nun folgende Zahl, die 256 also, hat  jetzt  schon  9
Bits,  da  ja ein Überlauf stattfand. Ich zeige Ihnen
das einmal in Form von (16 stelligen) Binärzahlen:   
dezimal    binär                                     
  255      0000 0000 1111 1111                       
  256      0000 0001 0000 0000                       
Nun  ist aber die Zahl 416 größer als 255, somit müs-
sen wir zu einem kleinen  Trick  greifen  um  sie  zu
übermitteln. Wir schreiben sie einfach mit 16 Bit, da
eine  16-Bit-Zahl  maximal  den  Wert 65535 aufnehmen
kann, was für unsere Zwecke vollkommen  reicht.  Dies
sieht dann so aus:                                   
416 (dez.)  =  0000 0001 1010 0000 (bin.)            
Diese 16-Bit spalten wir jetzt ganz einfach  in  zwei
8-Bit-Zahlen  auf. Die Eine nennen wir "höherwertiges
Byte", die Andere  "niederwertiges  Byte"  einer  16-
Bit-Zahl.  Das  sähe dann für 416 etwa folgendermaßen
aus :                                                
416 = 0000 0001 1010 0000                            
Höherwertiges Byte (die ersten 8 Bits von links) :   
0000 0001 = 256 (dez.)                               
Niederwertiges Byte (die nächsten 8 Bits von links) :
1010 0000 = 160                                      
Und siehe da, schon hätten wir unsere  Zahl  in  zwei
Bytes  zerlegt,  die  wir  nun einzeln, mit Hilfe des
POKE-Befehls, an den  SID  übergeben  können.  Dieser
setzt  sie  dann  intern  wieder zusammen und erzeugt
dann die Frequenz 440 Hz !                           
Für  diese beiden Frequenzbytes der Stimme 1 sind nun
die Register 00 und 01 zuständig. Oben in  der  Regi-
stertabelle  waren  deren  Funktionen beschrieben mit
"Frequenz für Stimme 1 - LO" und "Frequenz für Stimme
1 - HI". Das "LO" und "HI"  steht  hierbei  für  "LOw
significant  byte"  und  für  "HIgh significant byte"
oder höher- und niederwertiges Byte. Sie müssen  also
den  LO-Wert  von 416, also 160, in Register 00 POKEn
und den HI-Wert 1 in  Register  01.  Dies  sieht  als
kleines Programm geschreiben dann so aus :           
10 SI=54272:REM BASISADRESSE SID                     
20 POKE SI+0,160                                     
30 POKE SI+1,1                                       
Und schon wäre der Kammerton A programmiert. Um  das-
selbe  bei Stimme 2 tun zu können, müssen Sie die Re-
gister 07 und 08 benutzen, bei Stimme 3  Register  14
und 15.                                              
So, die Frequenz wäre gesetzt, aber hören können  Sie
jetzt noch nichts. Wir müssen zuerst ja noch die Wel-
lenform angeben. Nehmen wir hierzu doch einfach  ein-
mal  eine Dreieckskurve.  Was ist nun zu tun, um dies
dem SID klarzumachen ? Hierzu benötigen wir für Stim-
me  1 das Register 04 (analog für Stimme 2 und 3, die
Register 11 und 18). Dieses Register vereint  mehrere
Funktionen   in  einem.  Die einzelnen Bits in diesem
Register haben  verschiedene  Aufgaben,  die  erfüllt
werden,  wenn  man  das entspechende Bit auf 1 setzt.
Ich möchte Ihnen die Bitbelegung hier  einmal  anhand
einer Grafik darstellen :                            
MD8907/MD8907-KURS-2.16.hires.png
Die Bits 1, 2 und 3 sind für uns unwichtig. Sie akti-
vieren zu komplexe Funktionen, als daß  sie  hier  in
den  Kurs  passen  würden. Für uns sind eher die Bits
4-7 und Bit 0 wichtig. Wie Sie sehen steht jedes die-
ser  Bits  (außer  dem 0.) für eine bestimmte Wellen-
form. Wir möchten  nun  eine  Dreieckskurve  spielen.
Also  setzen  wir  einfach Bit 4. Die anderen bleiben
unberührt und haben somit den Wert 0. Unser Byte sähe
Binär geschrieben dann so aus :                      
0001 0000                                            
Das enstpricht der dezimalen Zahl 16 (der Wert des 4.
Bits).  Sollten  Sie  diese Zahl jetzt in Register 04
schreiben, so wird allerdings immer  noch  nichts  zu
hören  sein.  Der SID benötigt nämlich noch 2 weitere
Angaben. Zum Einen müssen wir noch die Lautstärke der
vom SID  gespielten  Musik  setzen  und  zum  anderen
braucht dieser auch noch eine sogenannte "Hüllkurve",
die  etwas  über  den Verlauf des gespielten Tons an-
gibt. Kommen wir jedoch erst einmal zur Lautstärke.  
Diese schalten Sie am besten  auf  volle  Lautstärke.
Wir hatten dies ja oben schon einmal. Sie müssen ein-
fach den Wert 15 (Maximalwert) in das Lautstärkeregi-
ster 24 schreiben. Also :                            
POKE SI+24,15                                        
So. Nun machen wir uns einmal an die Hüllkurve heran.
Physikalisch  haben  wir den Ton ja nun schon festge-
legt.  Wir  können  jetzt  allerdings   noch   seinen
Lautstärkeverlauf,  WÄHREND  er gespielt wird bestim-
men, eben mit Hilfe  der  oben  genannten  Hüllkurve.
Diese  besteht  aus 4 Phasen. Diese heißen "Attack-",
"Decay-", Sustain-" und "Releasephase" und werden  in
der  eben angezeigten Reihenfolge vom SID durchgegan-
gen. Wozu nun das ganze ?                            
Wie Sie ja vielleicht wissen ist nicht jeder Ton, der
die gleiche Frequenz hat, allerdings von 2  verschie-
denen   Instrumenten   gespielt wird, vom  Klang  her
gleich. Eine Oboe zum Beispiel hört sich "weicher" an
als ein Glockenspiel, obwohl die Wellenformen  einan-
der sehr ähnlich sind. Das Glockenspiel wird "härter"
gespielt als die Oboe. Das heißt, daß beim Anschlagen
einer  Metalleiste des Glockenspiels der Ton die mei-
sten Schwingungen  erzeugt  und  somit  am  lautesten
klingt.  Im Gegensatz zur Oboe, bei der die hindurch-
geblasene Luft erst einmal  einen  Ton  erzeugen  und
quasi  "in Schwingung" gebracht werden muß. Ein ande-
res Beispiel wäre  eine  Klaviersaite.  Schlagen  Sie
eine  Taste auf der Klaviatur an, so wird der Ton an-
fangs am lautesten sein und nach und nach  abklingen.
Dies  kann  manchmal bis zu 50 Sekunden dauern, wobei
die Oboe kaum mehr als 0.5 Sekunden braucht. Sie  se-
hen  also,  daß ein Ton einen sogenannten Lautstärke-
verlauf bestitzt.  Genau  diesen  Verlauf  beschreibt
eben die Hüllkurve. Wie Sie in der obigen SID-Tabelle
sahen sind die Hüllkurvenregister für den ersten Ton-
generator die Register 05 und 06. In ihnen werden die
Werte für die 4 Hüllkurvenphasen gespeichert. Da  wir
4  Werte  haben, allerdings nur 2 Register, wird dies
so gehandhabt, daß  jedes  Register  in  zwei  4-Bit-
Bereiche aufgeteilt wird. So, daß die vier "höherwer-
tigen" Bits eine, und die vier "niederwertigen"  Bits
eine andere Phase darstellen. Diese sind folgenderma-
ßen verteilt :                                       
Register   Bits 4-7 (HI)   Bits 0-3 (LO)             
––––––––––––––––––––––––––––––––––––––––             
  05       Attack          Decay                     
  06       Sustain         Release                   
Somit  sind  Werte  von  0-15  für jede Phase möglich
(2↑4-1). Wollen wir nun klären, welche  Aufgaben  die
einzelnen Phasen haben :                             
1.) Die Attackphase:                                 
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                                 
Mit  ihr  kann  die Zeit angegeben werden, in der ein
Ton von Lautstärke 0 auf die in Register 24 angegebe-
ne Lautstärke ansteigt, wobei bei dem Wert 0 diese am
schnellsten, und beim Wert 15 am langsamsten erreicht
wird. Hier eine Tabelle mit den genauen Werten :     
 WERT       ZEIT (in Sekunden)                       
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                       
  0        0.002                                     
  1        0.008                                     
  2        0.016                                     
  3        0.024                                     
  4        0.038                                     
  5        0.056                                     
  6        0.068                                     
  7        0.080                                     
  8        0.100                                     
  9        0.250                                     
 10        0.500                                     
 11        0.800                                     
 12        1.000                                     
 13        3.000                                     
 14        5.000                                     
 15        8.000                                     
2.) Die Decayphase :                                 
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                                 
Diese  Phase  gibt  an, in welcher Zeit der soeben in
der Attackphase erreichte Wert  der  Lautstärke,  auf
den Lautstärkewert absinkt, der als Sustainwert ange-
geben wird.                                          
3.) Sustain-spanne :                                 
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                                 
Hier wird ein Wert zwischen 0 und 15  angegeben,  der
die Endlautstärke nach ablauf der Decay-Phase angibt.
4.) Releasephase :                                   
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                                   
Wird  ein  Ton  abgeschaltet  (dazu kommen wir gleich
noch) dann wird unverzüglich die Releasephase  einge-
leitet.  Sie  gibt an in welcher Zeit der Ton von der
Sustainlautstärke wieder auf 0 absinkt.              
Die Zeitwerte für die Decay- und Releasephase  können
Sie der folgenden Tabelle entnehmen :                
 WERT       ZEIT (in Sekunden)                       
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾                       
  0             0.008                                
  1             0.024                                
  2             0.048                                
  3             0.072                                
  4             0.114                                
  5             0.168                                
  6             0.204                                
  7             0.240                                
  8             0.300                                
  9             0.750                                
 10             1.500                                
 11             2.400                                
 12             3.000                                
 13             9.000                                
 14            15.000                                
 15            24.000                                
Angenommen,  wir wollten ein Glockenspiel mit dem SID
simulieren, dann bräuchten wir einen Ton der  schnell
auf  voller  Lautstärke  steht  und dann auch relativ
schnell wieder abklingt.  Wählen  wir  also  folgende
Werte für die einzelnen Phasen :                     
Attack   -  00                                       
Decay    -  07                                       
Sustain  -  09                                       
Release  -  01                                       
Die 2 Bytes für die Hüllkuve müßten dann folgenderma-
ßen aussehen :                                       
1.) 0000  0111                                       
     A=0   S=7                                       
2.) 1001  0001                                       
     S=9   R=1                                       
Nun müssen Sie diese Bytes also nur noch ins dezimale
System umrechnen und in die Register 05 und 06 poken.
Die Werte wären demnach 7 und  145.  Zugegebenermaßen
ist  dies  eine  ein wenig mühselige Arbeit, wenn man
nicht gerade über einen Taschenrechner  verfügt,  der
das Binärsystem beherrscht. Deshalb kann das auch ein
wenig  einfacher  gehandhabt werden. Denn ebenso, wie
man HI- und LO-Bytes bilden kann,  lassen  sich  auch
"HI-  und  LO-Halb-Bytes"  bilden.  Diese heißen dann
"Nibble". Nun müssen Sie nur noch nach einem bestimm-
ten  Schema  die  verschiedenen  Werte miteinander zu
multiplizieren (der Umgekehrte Weg der  Zerlegung  in
LO- und HI-Byte). Nämlich nach der Formel :          
HI-Nibble * 16 + LO-Nibble                           
In unserem Fall hätten wir dann folgende Berechnungen
durchzuführen :                                      
Attack- und Decay-Byte    : 0*16+7=  7               
Sustain- und Release-Byte : 9*16+1=145               
Und schon wären wir am Ziel. Nun gilt es nur noch die
Werte im SID zu setzen, also :                       
POKE SI+5,7                                          
POKE SI+6,145                                        
Das wäre geschafft ! Doch  -  oh  Enttäuschung  -  es
kommt immer noch nichts aus dem Lautsprecher !!! Kei-
ne Panik, das ist ganz normal so, denn wir haben noch
eine weitere Operation durchzuführen.  Der  SID  weiß
jetzt zwar welche Frequenz er zu spielen hat, was für
eine  Wellenform  er unserem Ton geben soll, und wel-
chen Klangverlauf dieser haben soll,  damit  er  aber
nun  endlich die Hüllkurve abspielt, muß man ihm auch
noch mitteilen, wann er dies zu tun hat.  Wir  müssen
ihm  also  quasi ein "Startzeichen" geben, daß er die
Attackphase einleiten darf. Dies geschieht mit  Hilfe
des  0.  Bits  aus  Register  04 (ich hatte es vorhin
schon einmal erwähnt, siehe auch Grafik).  Erst  wenn
dieses  Bit  gesetzt wird, beginnt er nämlich die At-
tackphase einzuleiten. Wir müssen somit also  zu  dem
Wellenform-Wert  16  für  die Dreieckskurve auch noch
eine 1 addieren, damit dies der Fall ist (1  ist  die
Wertigkeit  des 0. Bits). Schreiben Sie also nun fol-
genden Befehl :                                      
POKE SI+4,17                                         
Nun kommt er endlich aus dem Lautsprecher, unser lang
erwarteter Ton. Lange hat es gedauert, doch  schließ-
lich  und  endlich haben wir es doch noch geschafft! 
Wie Sie jetzt allerdings schnell merken werden,  hört
er gar nicht mehr auf zu spielen, sondern brummt mun-
ter weiter. Das war allerdings gar nicht der  Effekt,
den wir erzielen wollten. Der Ton sollte doch eigent-
lich wieder in der Releasephase abklingen ! Der Grund
hierfür liegt darin, daß die  Releasephase  noch  gar
nicht  eingeleitet  wurde !  Dies  geschieht  nämlich
erst, wenn das 0. Bit in Register  04  wieder  auf  0
gesetzt  wird.  Bitte,  probieren Sie - diesmal kommt
also nur  16  in  dieses  Register,  da  wir  ja  die
Dreieckswellenform  ja  noch beibehalten möchten, al-
so :                                                 
POKE SI+4,16                                         
Und schon hört der Krach auf. Dies ist ein Punkt  den
Sie   beim  Soundprogrammieren  genauestens  beachten
sollten. Die Zeit, in der der Ton  auf  der  Sustain-
Lautstärke  gehalten wird, bestimmen Sie als Program-
mierer, nicht der SID. Sie müssen ihn erst "von Hand"
wieder abschalten. Praktisch läßt sich das  etwa  mit
einer Verzögerungsschleife realisieren.              
Sie  programmieren  einfach eine Schleife, in der der
Computer  zwar  mit  dem  Abarbeiten   der   Schleife
beschäftigt  ist,  jedoch  nichts  tut. Es fehlt ganz
einfach der Schleifenrumpf. Hier ein Beispiel :      
FOR I=1 TO 100:NEXT                                  
Sie sehen, die Schleife zählt ganz still und heimlich
bis 100. Effektiv tut der Computer jedoch nichts.  So
können  wir das Programm mit Scheinberechnungen quasi
"anhalten", damit der SID auch genug  Zeit  hat,  die
ersten  3 Phasen auch durchzuspielen. Am besten sehen
Sie sich einmal das Programm "MINISOUNDDEMO" auf  der
Rückseite der MagicDisk einmal an. Hier habe ich alle
notwendigen  Befehle  noch  einmal   zusammengerafft,
damit Sie auch ein kleines praktisches  Beispiel  ha-
ben.                                                 
Nun will ich Ihnen noch erklären welch eine Besonder-
heit die Rechteckskurve auf sich hat, und  wofür  die
Register  02  und 03 benutzt werden. In diesen beiden
Registern können Sie nämlich die Pulsbreite der Rech-
teckskurve  für Stimme 1 angeben. Wie Sie oben in der
Wellenformgrafik gesehen haben, wird der Abstand, der
zwischen den beiden Punkten liegt, an dem  die Recht-
eckskurve  von ihrem Tiefstpunkt zu ihrem Höchstpunkt
"springt"  in der sogenannten "Pulsbreite" angegeben.
Sie können in diesen beiden Registern also ganz  ein-
fach  den Abstand dieser beiden Rechtecksseiten ange-
ben. Dadurch können Sie den Klang der  Rechteckskurve
noch  einmal drastisch verändern. Mit niedrigen Puls-
breiten gespielt hört sich diese Welle  sehr  "kräch-
zend"  an,  fast  schon wie ein "Sägezahn". Je größer
die Abstände werden, desto weicher  und  voller  wird
der  Klang.  Hier  liegt  es  an Ihnen, die einzelnen
Zustände einmal durchzuprobieren.  Es  sei  nur  noch
gesagt,  daß  hier  mit  einem 12-Bit-Wert gearbeitet
wird. Das heißt, daß die Bits  4-7  von  Register  03
KEINE  Auswirkung auf die Pulsbreite haben. Der maxi-
male Pulsbreitenwert liegt  somit  bei  2↑12-1,  also
4095.  Probieren  Sie einfach einmal ein wenig herum,
denn, wie heißt es so schön : "Nur  die  Übung  macht
den  Meister." Wie Sie dies handhaben, sollten Sie ja
mittlerweile wissen, ich hatte Ihnen die  Problematik
von  HI-  LO-Byte  oben  ja schon erklärt. Sie müssen
hier nur darauf achten, daß Sie im Register  04  auch
die  Rechteckwellenform  einschalten, und daß das HI-
Nibble (Bits 4-7) der Pulsbreite immer 0 ist.        
Im übrigen sei noch erwähnt, daß Sie  alle  hier  ge-
nannten  Vorgänge mit Registern  usw. natürlich eben-
falls an den Stimmen 2 und 3 durchführen können.  Sie
müssen  nur  in  der Registertabelle nach dem entspe-
chenden Äquivalent des Registers für die entspechende
Stimme suchen. Sie werden merken, daß diese  alle  in
der  gleichen  Reihenfolge  für die einzelnen Stimmen
angeordnet sind. Im übrigen sind die meisten Register
des SID nicht auslesbar (bis auf die der 3.  Stimme).
Es  passiert also dasselbe, wie wenn Sie auf eine der
oben erwähnten I/O-Adressen zugreifen...             
Ich möchte mich nun bis nächsten Monat wieder  verab-
schieden, wenn wir uns dann ein wenig mit der  Daten-
speicherung und der Peripherie des 64ers beschäftigen
werden.  Sie  werden  dann  auch gleich noch den noch
fehlenden Befehlssatz von BASIC 2.0 kennenlernen.    
Ich bedanke mich nun für Ihre Aufmerksamkeit und wün-
sche ein fröhliches SID-Gedüdels, bis in einem Monat,
                                     Ihr Uli Basters.
 BASIC-Kurs:"Von Adam und Eva" (Teil 7) 
 -------------------------------------- 
 Hallöchen da draußen ! Weiter gehts in 
unserem Basickurs. Nachdem wir nun  auch
schon ein bißchen  Musik  machen  können
mit unserem 64er, wollen wir uns in die-
sem Monat einmal um die  Dateiverwaltung
und die Programmierung der  Floppy  küm-
mern. Gleichzeitig lernen Sie dann  auch
noch  etwas  über  das  Ansteuern  eines
Druckers, da diese beiden Themen nämlich
sehr nahe  beieinander  liegen  und  die
Programmierung  von  BASIC   aus   sogar
(fast) gleich ist. Man braucht halt  nur
noch ein paar Backgroundinformationen zu
den einzelnen Geräten. Begeben  wir  uns
nun also in die Außenwelt unseres C64 in
die Welt der Peripherie...              
Beginnen wir mit der Floppy. Die Befehle
LOAD  und  SAVE  brauche  ich  Ihnen  ja
bestimmt nicht mehr  zu  erklären.  Wenn
Sie die nicht kennen würden, würden  Sie
ja diesen Kurs gar nicht lesen können.  
Zu LOAD bleibt nur zu sagen,  daß  es  2
Arten gibt, diesen Befehl  zu  benutzen:
Die  eine  Möglichkeit  kennen  Sie  be-
stimmt. Nachdem Sie  ein  BASIC-Programm
mit    dem    Befehl    SAVE"PROGRAMM",8
gespeichert hatten, konnten Sie es immer
wieder  mit  LOAD"PROGRAMM",8   in   den
Basicspeicher  Ihres  64ers  laden.  Wie
ich  schon  im  5.  Teil  dieses  Kurses
erwähnte, ist das der Bereich  von  2048
bis 40960. Ein BASIC-Programm wird  also
immer an die Adresse 2048  und  folgende
geladen. Wenn Sie allerdings einmal  ein
Maschinenprogramm  haben,  das  an  eine
andere  Speicheradresse  geladen  werden
soll, so müssen Sie LOAD  folgendermaßen
benutzen :                              
LOAD"PROGRAMM",8,1                      
Wir haben also an das ",8" noch ein ",1"
angehängt. Dieser  Appendix  teilt  LOAD
mit, daß nun an  eine  absolute  Adresse
geladen wird. Das heißt, an eine Adresse
die in dem File schon angegeben wird.   
Dies kann von Nutzen sein, wenn wir  zum
Beispiel Grafikdaten an  eine  bestimmte
Adresse im Speicher  laden  wollen.  Ich
werde in dem diesem Kurs  anschließenden
Grafikkurs  hierauf  noch  einmal  näher
eingehen.                               
Im übrigen gibt es auch noch einen  wei-
teren Befehl, der mit LOAD nahe verwandt
ist. Ich spreche von dem  VERIFY-Befehl.
Diesen benutzen  Sie  ebenso  wie  LOAD,
nämlich:                                
VERIFY"PROGRAMM",8                      
Dieser ist nur in Verbindung von  BASIC-
Programmen  sinnvoll,  daher  auch  kein
",1" am Ende.                           
VERIFY macht nun nichts anderes als  ein
Programm auf der Diskette mit  dem  sich
im Speicher befindlichen  BASIC-Programm
zu vergleichen. Sie können hiermit  also
prüfen, ob auf der Diskette eine  andere
Version des Programms  vorliegt.  Sollte
das der Fall sein, so meldet sich VERIFY
mit "VERIFY ERROR ?" zurück.            
Andernfalls schreibt es einfach nur  ein
"OK" auf den Bildschirm. Das Programm im
Speicher, ebenso wie das  auf  der  Dis-
kette, bleiben jedoch komplett erhalten.
Es wird somit also NICHTS  an  den  Pro-
grammen verändert!                      
So. Nach diesem  kleinen  "Vorgeplänkel"
wollen wir uns  nun  um  die  "seriösen"
Anwendungen in BASIC  zusammen  mit  der
Floppy kümmern. Es besteht nämlich  auch
die Möglichkeit, Daten, wie zum Beispiel
Variablen, DIREKT in ein File zu schrei-
ben und sie hieraus  wieder  auszulesen.
Dies ist sehr sinnvoll,  wenn  man  eine
Anwendung schreiben möchte, die  irgend-
welche  Werte  zwischenspeichern   soll,
oder wenn Sie bei einem Spiel die  High-
scoreliste der Nachwelt  erhalten  möch-
ten.                                    
Damit wir dieses Problem jedoch  richtig
angehen können, muß ich erst etwas  wei-
ter ausholen und  Sie  einmal  über  die
Ein-/Ausgabe in BASIC aufklären.        
Alle Geräte, die an Ihrem  64er  hängen,
haben, wie Sie vielleicht wissen, eigene
Gerätenummern. Die Floppy  zum  Beipsiel
die 8, wie man das am LOAD-Befehl  sehen
kann. Das ",8" gibt ihm nämlich an,  daß
er von der Floppy  laden  soll.  Wollten
Sie von der Datasette laden  (heutzutage
nur noch von wenigen benutzt), so müßten
Sie dies mit einem ",1" kenntlich machen
(also LOAD"PROGRAMM",1). Hier einmal ei-
ne Liste aller möglichen Gerätenummern: 
Nummer Gerät                            
----------------------------------------
0 Tastatur                              
1 Datasette                             
2 RS232 - Serielle Schnittstele am User-
  Port für Datenfernübertragung (DFÜ)   
3 Bildschirm                            
4 Drucker 1                             
5 Drucker 2 (am Drucker selbst einstell-
  bar)                                  
8 Diskettenlaufwerk 0 (normal)          
9,10,11 Weitere Diskettenlaufwerke      
Der C64 ist nun so  ausgelegt,  daß  man
ihm zuerst einmal sagen muß, mit welchem
der oben erwähnten Geräte  man  arbeiten
möchte. Dies geschieht in BASIC mit  dem
OPEN-Befehl. OPEN ist englisch und heißt
"Öffne".  Es  heißt  nämlich  auch,  man
"öffnet" einen sogenannten Filekanal für
ein Gerät.                              
Damit  man  nun  mit  mehreren   Geräten
gleichzeitig arbeiten kann, ohne hierbei
jedesmal den Kanal wieder neu öffnen  zu
müssen, kann man jeden Filekanal mit ei-
ner eigenen Nummer zwischen  1  und  127
versehen, die  dann  quasi  als  Kennung
dient, wenn  man  auf  einen  Kanal  zu-
greift. Tun Sie dies, so weiß unser  C64
gleich, mit welchem Gerät er zu kommuni-
zieren hat und handhabt dies  dann  auch
entspechend, da alle Geräte ja in  einer
besonderen Art und Weise "bedient"  sein
wollen. Diese Filenummern muß  man  also
ebenfalls dem OPEN-Befehl  mit  auf  den
Weg geben,  damit  er  die  Gerätenummer
auch  der  richtigen  (Erkennungs-)File-
nummer zuordnet. Bei einem  Drucker  zum
Beispiel (mit der Geräteadresse 4)  sähe
das dann etwa folgendermaßen aus:       
OPEN 1,4                                
Schon hätten wir einen Filekanal für den
Drucker eröffnet, an den wir  nun  Daten
senden könnten. Hierzu  wird  dann  eine
kleine Abwandlung  unseres  mittlerweile
altbekannten PRINT-Befehls benutzt - der
PRINT#-Befehl. Das Doppelkreuz (#)  hier
ist sehr wichtig,  da  BASIC  sonst  die
beiden  Befehle  ja  nicht  auseinander-
halten könnte - PRINT ohne "#"  gibt  ja
ausschließlich auf den Bilschirm aus.   
Daß PRINT  "drucke"  heißt,  wissen  Sie
mittlerweile   ja   auch   schon.    Das
Doppelkreuz  ist  eine   im   englischen
allgemein   bekannte    Abkürzung    für
"Nummer". Die komlette  Übersetzung  von
PRINT# wäre  demnach  also  "Drucke  auf
Nummer".   Diese   Nummer    wird    nun
anschließend angegeben  und  stellt  die
oben erwähnte  Filenummer  dar.  Um  nun
also Daten  an  den  Drucker  zu  senden
müßten  wir,  nachdem   wir   den   oben
erwähnten    OPEN-Befehl    durchgeführt
haben, folgendes schreiben:             
PRINT#1,"Das ist eine Datenausgabe"     
Hier haben wir einmal eine Zeichenkette,
wie auch bei  PRINT  durch  Gänsefüßchen
eingeklammert, ausgegeben. Ebenso können
Sie hier jedoch auch mit  Variablen  ar-
beiten, etwa so:                        
PRINT#1,a$                              
PRINT#1,x                               
PRINT#1,z%                              
Beim Zugriff auf die  Floppy  ist  diese
Vorgehenweise nun  genau  dieselbe.  Wir
müssen zuerst  einen  Kanal  öffnen  und
können  anschließend  mit  PRINT#  Daten
übergeben. Allerdings  müssen  wir  hier
wieder ein wenig unterscheiden, denn die
Floppy kann nämlich in  zwei  Richtungen
bedient   werden;   zum   einen   "Daten
schreiben",  hierzu  benutzt  man   dann
PRINT#, und zum anderen "Daten Lesen".  
Da brauchen wir dann einen neuen Befehl,
doch hierzu später. Zuerst einmal müssen
wir einen Filekanal für die Floppy  öff-
nen. Dies ist leider nicht mehr ganz  so
einfach wie beim Drucker (daher auch zu-
erst das Beispiel  mit  selbigem),  denn
der OPEN-Befehl verlangt für die  Floppy
mehr Parameter als nur File- und Geräte-
nummer. Da wäre nämlich zunächst  einmal
noch  die  sogenannte  "Sekundäradresse"
und dann noch ein  entsprechender  File-
name, damit das Laufwerk auch weiß,  mit
welchem File wir arbeiten wollen.       
Kommen wir zunächst einmal zur Sekundär-
adresse. Diese gibt an, auf  welche  Art
und Weise wir Daten verarbeiten möchten.
Sie wird in Form  einen  Zahl  angegeben
und bezeichnet damit vorher  vereinbarte
Funktionen. Die Floppy akzeptiert insge-
samt 16 Sekundäradressen,  die  folgende
Funktionen belegen:                     
Sekundäradresse Funktion                
----------------------------------------
0 Daten Lesen (LOAD)                    
1 Daten Schreiben (SAVE)                
2-14 Daten Lesen ODER schreiben         
15 Sek.adresse für Befehlskanal         
Für uns sind im Augenblick nur die  Num-
mern von 2 bis 14 wichtig,  die  anderen
werde ich Ihnen später erklären.        
Zuerst muß ich Sie noch ein  wenig  über
die verschiedenen Filearten  der  Floppy
auflären. Es gibt derer fünf, von  denen
wir allerdings nur  2  benutzen  werden.
Jede der verschiedenen Arten wird in der
Fileliste einer Diskette, dem  sogenann-
ten  Directory  (LOAD"$",8),  mit  einem
kleinen Kürzel versehen, so daß man  er-
kennt, welche Fileart man vor sich  hat.
Programme haben zum Beispiel  immer  das
Kürzel "PRG". Das kennen Sie ja bestimmt
aus vielen Directories.  Hier  nun  eine
Liste aller weiteren Filearten:         
1.) PRG - PRoGramm.  Diese  Fileart  ist
    eigens für Programme reserviet.  Die
    Datenbytes, die an  die  Floppy  ge-
    sandt werden,werden in sequentieller
    Reihenfolge, also ein Byte nach  dem
    anderen, gespeichert. Das PRG-Kürzel
    gibt an, daß man  das  Programm  mit
    LOAD  in  den  Speicher  des   64ers
    laden kann. Alle Programme, die  Sie
    mit   SAVE   abspeichern,   erhalten
    ebenfalls  dieses   Filekürzel   zur
    Erkennung.                          
2.) SEQ - SEQuenz.  Diese  Fileart  wird
    genauso  wie  PRG  gehandhabt.   Die
    Daten folgen also Byte für Byte  auf
    der  Diskette,  mit   dem   einzigen
    Unterschied,  daß  Sie  diese  Daten
    NICHT mit LOAD laden können. Es  ist
    quasi  ein   Erkennungszeichen   für
    Datenfiles von Programmen, aus denen
    auf diese Files zugegriffen wird.   
3.) REL - RELatives File. Relative Files
    sind  Files,  in   denen   bestimmte
    Datenblöcke,  sogenannte  "Records",
    gespeichert sind. Duch Angabe  einer
    Recordnummer wird NUR dieser  Record
    geladen, und nicht das ganze File.  
    Reltive Files werden auch "Files mit
    Wahlfreiem Zugriff genannt" und sind
    sehr  häufig  bei  Dateiverwaltungs-
    programmen  zu  finden,   da   durch
    diese  Fileart  schnell  auf   einen
    bestimmten   Datensatz   zugegriffen
    werden kann, ohne gleich  die  ganze
    Datei zu  durchforsten.  Leider  ist
    sie nicht sehr einfach in  BASIC  zu
    Programmieren, weshalb  wir  sie  an
    dieser Stelle auch  nicht  behandeln
    werden.                             
4.) DEL  -  DELeted.  Files  mit  diesem
    Kürzel sehen Sie in der  Regel  NIE,
    da  diese  Fileart   lediglich   für
    floppyinterne Anwendungen reserviert
    ist.  Sie  gibt  an,  daß  ihr  File
    gelöscht wurde, daß also die von ihm
    belegten   Datenblöcke    auf    der
    Diskette   wieder   benutzt   werden
    können.                             
5.) USR -  USeR  File.  Der  Aufbau  ist
    derselbe wie bei PRG  und  SEQ.  USR
    gibt lediglich an,  daß  das  hierin
    gespeicherte Programm  NUR  von  der
    Floppy ausführbar ist, also für  uns
    uninteressant.                      
Wir wollen uns hier nur mit  den  ersten
beiden  Arten   beschäftigen.   Zunächst
einmal die SEQuenz-Dateien. Wie Sie oben
ja schon lesen konnten ist diese Fileart
für Daten im Allgemeinen reserviert. Daß
wir das mit den  Filearten  zuerst  noch
klären mußten ist  deshalb  wichtig,  da
diese Angabe beim OPEN-Befehl  ebenfalls
mitangegeben werden muß. Dies  geschieht
zusammen mit dem Filenamen. Hier  einmal
ein Beispiel, damit Sie wissen  wie  das
öffnen  eines  Kanals  für  die   Floppy
aussieht:                               
 OPEN 1,8,2,"HIGHSCORE,S,W"             
Dabei ist:                              
1 - die Filenummer                      
8 - die Geräteadresse (Floppy)          
2 - die Sekundäradresse                 
HIGHSCORE - der eigentliche Filename    
S - die Fileart                         
W - die Betriebsart                     
Sie sehen also, zuerst  kommen  die  uns
bisher schon bekannten  Parameter  dran,
also   Filenummer   und   Geräteadresse.
Anschließend, mit einem Komma  vom  Rest
getrennt, folgt die Sekundäradresse,  in
unserem Beispiel die 2. Sie könnten  na-
türlich auch alle anderen Nummern von  2
bis 14 benutzen, dies wäre  kein  Unter-
schied. Jetzt  jedoch  zum  Filenamen  -
nachdem Sie auch diesen mit einem  Komma
vom  Rest  abgehoben  haben  folgt,   in
Gänsefüßchen  gesetzt,  der  eigentliche
Filename. Wie Sie jedoch  sehen,  werden
zusammen  mit  dem  Filenamen   noch   2
weitere Parameter übergeben. Da wäre zum
einen die Fileart,  markiert  durch  den
Buchstaben  "S"  und  zum  anderen   die
Betriebsart, hier  in  unserem  Beispiel
durch den Buchstaben "W" dargestellt.   
Beide  Parameter   werden   wieder   mit
Kommata vom Filenamen abgetrennt,  wobei
allerdings zu beachten  ist,  daß  beide
sich  zusammen  mit   dem   eigentlichen
Filenamen   in    dem    Filename-String
befinden, so  daß  die  Parameter  NAME,
FILE-  und  BETRIEBSART"  alle  in   EIN
Gänsefüßchenpaar gefaßt sind.           
Wie Sie vielleicht schon erraten  haben,
bezeichet das "S"  die  Fileart  SEQenz.
Wir haben hier  also  ein  sequentielles
File geöffnet.  Bei  einem  Programmfile
hätten  wir  hier  ein   "P"   einsetzen
müssen. Nun zur Betriebsartkennung.  Der
Buchstabe "W" im Beispiel oben steht für
"Write",  zu  Deutsch  "Schreibe".   Der
Kanal wurde also zum Schreiben geöffnet.
Die Floppy erwartet nun,  daß  Daten  an
sie gesandt werden, die sie dann auf die
Diskette   in   das   angegebene    File
schreibt. Für uns heißt das nun, daß wir
mit Hile von PRINT# jetzt Daten auf  den
Kanal 1 schicken können  und  diese  auf
Diskette gespeichert werden. Senden  wir
doch einfach einmal etwas an die Floppy:
na$="Fritz Meier"                       
sc=100000                               
PRINT#1,"Highscoreliste"                
PRINT#1,pl$                             
PRINT#1,sc                              
Hier haben wir  nun  den  Highscore  von
Fritz  Meier  abgespeichert,  der   sich
auf 100000  Punkte  beläuft,  indem  wir
die verschiedenen Werte erst  einmal  in
Variablen definierten  und  anschließend
nacheinander  (sequentiell  !)  an   die
Floppy  gesendet   haben.   Sie   hätten
natürlich   die   Daten   auch    dirket
schreiben können, wobei der  String  na$
in Gänsefüßchen hätte stehen müssen  und
die Zahl ohne, so wie das bei dem String
"HIGHSCRORELISTE" zu sehen ist.  Wichtig
ist, daß Sie jedes  einzelne  Datum  mit
einem EINZIGEN PRINT#-Befehl senden, und
nicht etwa von Kommata  getrennt  -  wie
man    das    vielleicht    nach     der
Parametertrennung   bei   OPEN    denken
könnte.  Diese  Kommatrennung  ist  zwar
auch  möglich,  doch  bewirkt  Sie  hier
etwas anderes, wozu  ich  später  kommen
werde. Außerdem könnten Sie  mit  Komma-
trennung später die Daten nicht mehr  so
einfach einlesen, doch hierzu  ebenfalls
später mehr.                            
Unsere Daten wären  jetzt  also  an  die
Floppy geschickt und somit  gespeichert.
Den Filekanal brauchen wir  jetzt  nicht
mehr. Deshalb müssen wir ihn zuerst noch
wieder schließen, bevor wir  fortfahren.
Dies ist sehr sehr wichtig, da wir somit
nicht nur den Computer  entlasten,  weil
der sich jetzt auch nicht mehr den Kanal
"merken" muß, der mit der Floppy zu  tun
hat, sondern  durch  ein  Schließen  des
Kanals veranlassen wir gleichzeitig auch
die Floppy das File komplett und richtig
auf der Diskette anzulegen.  Das  heißt,
daß sie jetzt auch den  Eintrag  in  der
Fileliste der Diskette machen und diesem
Eintrag  auch  die  entspechenden  Daten
zuweisen kann. Das Schließen  eines  Ka-
nals wird in BASIC mit dem Befehl  CLOSE
durchgeführt.  Als  Parameter   benötigt
CLOSE  lediglich  die   Filenummer,   in
unserem Fall also die 1:                
CLOSE 1                                 
Nun haben wir  also  das  File  komplett
angelegt.  Schauen  Sie   doch   einfach
einmal ins Directory -  hier  sehen  Sie
nun ein weiteres File, das etwa so  aus-
sieht:                                  
1     "HIGHSCORE" SEQ                   
Der CLOSE-Befehl muß übrigens  ebenfalls
beim Drucker, wie auch bei allen Geräten
bei denen Sie vorher einen Filekanal mit
OPEN  öffneten,  angewandt  werden.  Ich
hatte dies vorhin nur nicht erwähnt,  da
es mir zunächst einmal um  die  Funktion
von OPEN ging.                          
Um die Fortsetzung dieses Kurses zu  le-
sen, wählen Sie bitte den  zweiten  Teil
des Basic-Kurses an.                    
 Jetzt wollen wir aber einmal versuchen,
unsere gespeicherten Daten wieder einzu-
lesen. Dies geschieht in etwa  nach  dem
selben Schema. Zuerst müssen  wir  einen
Kanal öffnen:                           
OPEN 1,8,2,"HIGHSCORE,S,R"              
Wie Sie sehen, sieht dieser  OPEN-Befehl
fast genauso aus wie der obige. Ich habe
hier also dieselben  Parameter  benutzt,
bis  auf  den   Kennungsbuchstaben   der
Betriebsart. Hier haben  wir  jetzt  ein
"R" was einen weiteren Modus umschreibt,
nämlich "Read" für "Lese".              
Wir haben also wieder ein  sequentielles
File geöffnet mit der Filenummer 1,  der
Geräteadresse 8, der  Sekundäradresse  2
und  dem  Namen   "HIGHSCORE",   diesmal
allerdings zum Lesen, denn wir wollen ja
unsere   gespeicherten   Daten    wieder
zurückholen. Dies  geschieht  mit  einem
neuen Befehl, einer  kleinen  Abwandlung
von INPUT, dem  INPUT#-Befehl.  Wie  Sie
sehen ist  auch  hier  einfach  nur  ein
Doppelkreuz   angehängt   worden.    Die
Eingabe ist nun ja denkbar einfach.  Wir
müssen  nach   INPUT#   nur   noch   die
Filenummer  unseres  Kanal  angeben  und
anschließend, durch Komma getrennt,  die
Variable,  der  das  einzulesende  Datum
zugewiesen werden soll, also:           
INPUT#1,x$                              
INPUT#1,na$                             
INPUT#1,sc                              
In  "X$"  hätten  wir  nun  den   String
"Highscoreliste"  gespeichert   und   in
"NA$"  den  vorhin  gepeicherten   Namen
"Fritz  Meier".  In  "SC"  steht   jetzt
100000, die Punktzahl von Fritz Meier.  
Sie können diese Daten nun  also  wieder
weiterverarbeiten. Übrigens  sollte  ich
hier  vielleicht   erwähnen,   daß   der
INPUT#-Befehl, ebenso wie  INPUT,  NICHT
im Direktmodus anwendbar ist. Sie können
ihn   also   ausschließlich    NUR    in
Programmen anwenden.  Auch  sollten  Sie
den dazugehörigen OPEN-Befehl in  diesem
Programm aufführen, und  nicht  etwa  im
Direktmodus   das   File   öffnen    und
anschließend ein Programm mit den obigen
INPUT#-Anweisungen   starten,   da   RUN
leider die Merktabellen,  die  sich  der
64er   intern   über   alle   geöffneten
Filenummern anlegt, wieder  löscht.  Die
Floppy bekommt jedoch davon nichts  mit,
so daß für sie der Kanal noch offen ist,
für  den  Computer  ist  er   allerdings
geschlossen. Sie können sich  vielleicht
vorstellen, was für  ein  Chaos  hierbei
entstehen könnte...  In  solchen  Fällen
hift es  dann  immer,  einmal  kurz  die
Diskette aus dem Laufwerk zu  holen,  da
die  Floppy  dann  den  Kanal  ebenfalls
(zumindest intern) schließt.  Die  Daten
können   dabei    allerdings    verloren
gehen.                                  
Nachdem  wir  nun  unsere  Daten  wieder
eingelesen   haben,   müssen   wir   den
Lesekanal  natürlich  wieder  mit  CLOSE
schließen, also:                        
CLOSE 1                                 
Nun sollten sie mit SEQ-Files ja bestens
umgehen können, was laden und  speichern
zumindest  angehen.  Die  Floppy   kennt
jetzt  allerdings  noch   eine   weitere
Betriebsart. Außer  "Read"  und  "Write"
gibt es nämlich auch noch "Append".  Das
ist  englisch  und  heißt   soviel   wie
"hinzu- oder anfügen". Mit diesem  Modus
können Sie also  an  eine  schon  früher
erstellte Datei weitere Daten anhängen. 
Angenommen, Sie wollten vielleicht einen
weiteren  Highscore  abspeichern,   dann
bräuchten Sie nur einen  Floppykanal  in
der Betriebsart "Append" zu öffnen.  Für
"Append"  kennt  die  Floppy  das   "A"-
Kürzel, also:                           
OPEN 1,8,2,"HIGHSCORE,S,A"              
Jetzt können Sie mit  Hilfe  von  PRINT#
weitere Daten an das alte File anhängen,
nach "Fritz Meier"  und  100000  könnten
wir nun also auch  z.B.  "Heinz  Müller"
und 99999 an die  Floppy  schicken.  Bei
einem erneuten Einlesen der Datei müßten
wir  dann  noch  einmal  gesondert  alle
Daten von vorne bis hinten auslesen.    
Kommen wir nun zur Fileart PRG. Wie  ich
oben  ja  schon  erwähnte,   ist   diese
Fileart nur für Programme reserviert.   
Trotzdem kann  man  sie  von  BASIC  aus
ansprechen und auch Daten  in  PRG-Files
speichern. Dies wird  ebenso  gehandhabt
wie  mit  SEQ,  da  PRG-Files,  physisch
gesehen,  also   im   Aufbau   auf   der
Diskette, ebenso  angelegt  werden,  wie
SEQ-Files. Der Zugriff auf ein  PRG-File
ist somit haargenau  derselbe,  mit  dem
einzigen Unterschied, daß jetzt  an  den
Filenamen angehängt nicht mehr  ein  "S"
als Parameter für die  Fileart,  sondern
ein "P" für PRG steht.  Der  OPEN-Befehl
für ein PRG-File  sähe  also  folgender-
maßen aus:                              
OPEN 1,8,2,"DATEI,P,R" zum Lesen, oder  
OPEN 1,8,2,"DATEI,P,W" zum Schreiben.   
Ansonsten können Sie ebenso verfahen als
hätten Sie ein SEQ-File geöffnet.  Eines
gibt es allerdings schon noch hierzu  zu
sagen. Der OPEN-Befehl hat für PRG-Files
nämlich noch  zwei  kleine  Sonderheiten
eingebaut.  Bei   den   Sekundäradressen
hatte ich ja schon einmal angegeben, daß
die Adressen 0 und 1 jeweils  eine  Son-
derstellung einnehmen.                  
Diese lassen  sich  jetzt  sehr  einfach
erklären,  nachdem  wir  uns   mit   der
Materie  der  Betriebsart  eines   Files
schon ein wenig beschäftigt  haben.  Mit
der Sekundäradresse  0  können  Sie  der
Floppy nämlich schon gleich angeben, daß
Sie ein READ-File (also ein File aus dem
Sie lesen) öffnen möchten.              
Gleichzeitig geht diese dann auch  davon
aus, daß es sich hierbei um ein PRG-File
handelt,  Sie  können  damit  also   die
Angabe  der  File-  und  Betriebsart  im
Filenamen wegfallen lassen. Etwa ähnlich
verhält es sich mit der  Sekundäradresse
1. Sie gibt an, daß Sie Daten  schreiben
möchten, ebenfalls in ein PRG-File.     
Somit ergeben sich  dann  also  folgende
Vereinfachungen  des  OPEN-Befehls   für
PRG-Files:                              
OPEN 1,8,0,"DATEI" zum Lesen, und       
OPEN 1,8,1,"DATEI" zum Schreiben.       
Wenn Sie allerdings ein PRG-File öffnen,
um    beispielsweise    ein    richtiges
BASIC-Programm  daraus  auszulesen,  aus
welchen Gründen auch  immer,  so  werden
Sie mit INPUT# nicht viel Glück haben.  
INPUT# verläßt sich nämlich darauf,  daß
Sie vorher alle Ihre  Daten  mit  PRINT#
eingegeben haben, wobei  Sie  für  jedes
Datenelement einen eigenen PRINT#-Befehl
benutzten. PRINT# arbeitet nämlich eben-
so wie PRINT, wenn man  keinen  weiteren
Parameter hinter dem Befehl  angibt.  Es
macht einen  sogenannten  "Wagenrücklauf
mit Zeilenvorschub". Oder auch "Carriage
Return" genannt. In der Praxis wird  bei
diesem  Wagenrücklauf   nichts   anderes
getan, als daß der Cursor lediglich eine
Zeile tiefer, in die erste  Spalte  die-
ser Zeile befördert wird, und  daß  eine
weitere Ausgabe auf  dem  Bildschirm  an
dieser Stelle dann ausgeführt wird.     
Der Wagenrücklauf hat auch  einen  eige-
nen  ASCII-Code  (er   ist   eines   der
Steuerzeichen,   die   eine    besondere
Funktion  erfüllen,  wie  ich  bei   den
ASCII-Zeichen erwähnte), die 13 nämlich.
Mit einem PRINT CHR$(13)  erzwingen  Sie
also einen solchen Wagenrücklauf.       
Probieren Sie das  doch  einfach  einmal
mit folgendem Programm aus:             
10 PRINT"DAS IST ZEILE 1";CHR$(13)      
20 PRINT"DAS IST ZEILE 2"               
Sie sehen, zwischen  den  beiden  Zeilen
ist nun  eine  Leerzeile,  was  ja  ohne
CHR$(13) nicht wäre.  Der  PRINT#-Befehl
sendet nun ebenfalls ein CHR$(13) an die
Floppy,   nachdem   er    seine    Daten
übertragen   hat.   Beispielsweise   die
einzelnen      ASCII-Code-Bytes      der
Buchstaben einer String-Variable. INPUT#
erkennt nun an diesem Wagenrücklauf, daß
hier das Ende des Strings  erreicht  ist
und beendet seine Eingabe. Alle Zeichen,
die vor dem Carriage Return kamen werden
nun der  Variablen  zugeordnet,  die  am
Ende  von  INPUT#  steht,  jedoch   ohne
dabei das CHR$(13)  mit  anzuhängen.  Es
dient  also  lediglich  als  Trennmarke,
nicht aber  als  Datenelement.  Das  hat
aber  auch  einen  entscheidenden  Nach-
teil  -  sollten  Sie  einmal   in   die
Verlegenheit kommen, einen Wagenrücklauf
mitabzuspeichern, oder sollten Sie nicht
wissen, ob der  Wagenrücklauf  überhaupt
in einem File  (z.B.  ein  PRG-File  mit
einem  BASIC-Programm)   existiert,   so
sollten Sie die  Alternative  zu  INPUT#
benutzen, den Befehl GET#. Wie Sie sehen
haben wir auch hier ein Doppelkreuz, das
für Filenummer  steht,  das  Befehlswort
selbst  kann   man   etwa   mit   "Hole"
übersetzen. Der 64er soll sich also  ein
Byte von dem Kanal mit  der  Filenummer,
die  hinter  dem  "#"  angegeben   wird,
holen. Dies geschieht  wie  bei  INPUT#,
namlich folgendermaßen:                 
GET#1,A$                                
Hiermit hätten wir  der  Variablen  "A$"
jetzt ein Byte  vom  Filekanal  1  zuge-
wiesen. Dieses können wir jetzt  weiter-
verarbeiten.  Entweder  Sie   geben   es
gleich mit PRINT aus, etwa so:          
PRINT A$;                               
Oder Sie schauen sich an,  ob  wir  hier
überhaupt ein  druckbares  ASCII-Zeichen
vorliegen haben, oder ob es sich hierbei
nicht doch um ein Sonderzeichen handelt,
indem Sie sich  einfach  den  ASCII-Code
des Bytes ausgeben lassen. Etwa so:     
A=ASC(A$)                               
IF A=13 THEN PRINT "DAS IST EIN CARRIAGE
RETURN."                                
IF A=19 THEN PRINT "DAS IST DAS         
'HOME'-ZEICHEN."                        
oder einfach :                          
PRINT ASC(A$)                           
Allerdings gibt es hier noch ein kleines
Problem. Da  wir  ja  ein  sequentielles
File auslesen und bei  diesem  ein  Byte
nach dem anderen folgt, wird mit ziemli-
cher Sicherheit auch  irgendwann  einmal
das letzte Byte über den Kanal gewandert
kommen und  anschließend  ist  dann  nix
mehr los mit  Bytes  auslesen.  Trotzdem
aber   holt   sich   GET#   immer   noch
irgendwelche nicht existenten Bytes  vom
Kanal  und  übergibt  diese   an   unser
Programm, was  ja  nun  nicht  unbedingt
sein  soll.   Hier   hilft   dann   eine
Sondervariable des  64ers.  Ich  spreche
von  der  Statusvariablen  "ST".  Diesen
Variablennamen  dürfen  Sie   in   Ihren
Programmen  übrigens  NIE  benutzen,  da
diese  Variable  halt   für   den   eben
genannten Zweck  reserviert  ist.  BASIC
stellt in dieser Variablen nämlich immer
den sogenannten  Status  des  Disketten-
kanals bereit. Wie Sie  sehen  ist  "ST"
ja  eine   numerische   Variable,   also
liefert sie einen Zahlenwert zurück.    
Sollten Sie nun bei  einer  Abfrage  von
ST einmal feststellen, daß Sie den  Wert
64 beinhaltet, so sind Sie am Ende eines
Diskettenfiles angelangt.               
Bei allen anderen Zahlen ist dies nicht 
der Fall. Das Durchlesen eines Files    
sähe also so aus:                       
10 OPEN 1,8,0,"PROGRAMM"                
20 GET#1,A$                             
30 PRINT A$                             
40 IF ST<>64 THEN 100                   
50 CLOSE 1                              
"ST" dürfen Sie natürlich auch benutzen,
wenn Sie mit INPUT# auslesen. Dies  wäre
sogar nur  sinnvoll  und  wünschenswert,
wenn Sie flexibel arbeiten möchten.     
Aus Platzmagel muß ich  nun  leider  die
heutige Folge dieses Kurses abschließen.
Nächsten Monat werden wir dann mit einem
neuen  Hauptprogramm  hier  in  der   MD
aufwarten können, durch das  ich  wieder
mehr Platz haben werde ihnen die Sprache
BASIC näherzubringen. Ich werde nächsten
Monat dann das Thema Floppy  noch  been-
den und  Sie  über  die  noch  fehlenden
Befehle von BASIC V2.0  aufklären.  Dann
müßten wir eigentlich  mit  allem  durch
sein, und Sie sollten das  Grundzeug  zu
einem guten  BASIC-Programmierer  besit-
zen. Doch noch sind wir  nicht  ganz  so
weit,  deshalb  verabschiede  ich   mich
jetzt bis nächsten Monat, Ihr           
                            Uli Basters.
 Basickurs:"Von Adam und Eva..."(Teil 8)
 ---------------------------------------
Willkommen zum 8.  Teil  unseres  Basic-
kurses. Ich werde Ihnen heute  noch  ein
klein Wenig über die Floppy erzählen und
die etwas kleineren  Befehle  und  Funk-
tionen von BASIC 2.0 erwähnen.          
Wie  Sie sich vielleicht erinnern hatten
wir letzten Monat  etwas  über  Sequenz-
und  Programmfiles gehört. Hierbei lern-
ten wir die Befehle OPEN, CLOSE, PRINT#,
INPUT#  und  GET#  kennen.  Zum   Schluß
erklärte  ich  Ihnen  noch die Bedeutung
der Statusvariablen ST.                 
Es gibt jetzt noch ein paar  Dinge  über
ST  zu sagen, die ich Ihnen letzte Woche
verschwiegen hatte. Wie  ich  ja  damals
schon  erwähnte, kann man durch den Wert
64 in ST feststellen, daß  man  am  Ende
eines  Files  angelangt ist, doch ST ist
noch für 3 weitere Zwecke zu gebrauchen.
Hier eine kleine Übersicht:             
Wert Bedeutung                          
--------------                          
 64  Fileende erreicht                  
 66  Über das Fileende herausgelesen    
  1  Fehler beim Schreiben              
128  Floppy nicht angschlossen          
Die 64 kennen wir  ja.  Sobald  wir  das
letzte  Byte gelesen hatten, stand diese
Zahl in ST. Sollten wir jetzt, aus  wel-
chem Grund auch immer, noch ein weiteres
Byte  auslesen wollen, so werden wir ein
falsches, da nicht-existentes  Datenbyte
zurückerhalten.  Nach diesem Lesevorgang
meldet ST den Wert 66,  was  heißt,  das
wir  versucht  haben, ein Byte aus einem
mittlerweile schon bis zum Ende  gelese-
nen File auszulesen. Sollte also  einmal
ein solcher Fehler auftreten,  so werden
Sie wissen, woran es liegt.             
Als  nächstes  gibt es da noch die 1 als
Wert für ST.  Sollten  Sie  diesen  Wert
einmal  zurückbekommen, so bedeutet das,
daß beim Schreiben in  eine  Write-Datei
ein  Fehler  aufgetreten  ist.          
Zum Beispiel,wenn die Diskette voll ist.
Das wäre dann ein "DISK FULL"-Error.  In
In diesem Fall ist es dann sinnvoll, den
Fehlerkanal der Floppy  abzufragen,  was
ich Ihnen gleich noch erklären werde.   
Zunächst noch zu dem 4. Fall für ST, der
Wert  128.  Er  gibt an, daß die Floppy,
die angesprochen  werden  sollte,  nicht
angeschlossen   beziehungsweise   ausge-
schaltet ist. Doch gibt es da  noch  ein
kleines Problem. Sollte nämlich ein sol-
cher Fehler einmal  auftreten,  so  wird
der  64er das momentan laufende Programm
sofort abbrechen und einen "DEVICE NOT -
PRESENT"-Error auf dem Bildschirm ausge-
ben. Das ist ja nicht unbedingt im Sinne
eines komfortablen  Programms,  außerdem
erhalten wir somit noch nicht einmal die
Gelegenheit,  uns  einmal den Inhalt von
ST anzuschauen, da der C64 hier  schnel-
ler  reagiert  und VOR einer eventuellen
Abfrage abbricht. Doch es gibt eine  Mö-
glichkeit, diesen  kleinen  Nachteil  zu
umgehen. Wie wir ja im 5.  Teil  gelernt
haben,  kann man mit dem POKE-Befehl By-
tes im Speicher unseres C64 verändern.  
Damals  hatte  ich den Bereich von Spei-
cherzelle 0 bis 1024 als wenig  interes-
sant für uns erklärt, da dort hauptsäch-
lich Speicherzellen untergebracht  sind,
die  für interne Arbeiten im 64er reser-
viert sind. Doch hier und da bieten sich
in diesem Speicherbereich schon noch ein
paar sinnvolle Anwendungen.  In  unserem
Beispiel  wäre da die Speicherzelle 768.
Ändert man  nämlich  den  Inhalt  dieser
Speicherzelle in den Wert 61 um, so wird
jegliche   Ausgabe  von  Fehlermeldungen
ganz einfach unterdrückt.  Dies  ist  in
unserem Fall ganz interessant, zumal wir
die  Meldung von "DEVICE NOT PRESENT" ja
gar nicht gebrauchen können.            
Wir können diese Abfrage ja auch selbst 
über ST vornehmen. Nachdem wir dies dann
jedoch taten, sollten wir unsere Fehler-
meldungsausgabesperre jedoch wieder  zu-
rücknehmen, da ja auch noch ganz  andere
Fehler auftreten könnten,  zum  Beispiel
ein "SYNTAX ERROR". Das  Programm  würde
in diesem Fall versuchen  weiterzuarbei-
ten und das  könnte  verheerende  Folgen
haben.  Rückgängig  machen  wir   unsere
Sperre  mit  dem  Befehl  "POKE768,139".
Jetzt ist wieder alles  beim  Alten  und
Fehler brechen das Programm  wieder  wie
gewohnt ab und  drucken  ihren  entspre-
chenden Text dann auch  aus.  Hier  noch
ein kleines Beispiel zur Abfrage, ob die
Floppy angeschlossen ist:               
10 POKE 768,61 :REM FEHLER SPERREN      
20 OPEN 1,8,15 :REM FLOPPY ANSPRECHEN   
30 CLOSE 1     :REM KANAL WIEDER ZU     
40 POKE 768,139:REM FEHLER ZULASSEN     
50 IF ST=128 THEN PRINT "FLOPPY IST NICH
T ANGESCHLOSSEN !"                      
Nun  möchte ich Ihnen noch ein wenig den
Sinn und die Bedeutung des Befehlskanals
der Floppy näherbringen.  Letzten  Monat
hatte  ich  Ihnen  ja schon erzählt, daß
dieser Kanal  eine  Sonderstellung  ein-
nimmt,  weshalb  er auch eine eigene Se-
kundäradresse, nämlich die  15,  besitzt
(siehe auch Tabelle von letztem Monat). 
Über  jenen  Befehlskanal  kann  man nun
kleine Befehle an die Floppy senden, die
diese zu bestimmten  Operationen  veran-
laßt, wie zum Beispiel das Löschen eines
Files, oder  das Formatieren einer Disk.
Letzteres  möchte ich hier einmal anhand
eines Beispiels erläutern.  Wie  Sie  ja
vielleicht  wissen, muß man eine Disket-
te, bevor man sie mit Daten  beschreiben
kann, "formatieren", das heißt, man gibt
der Floppy den Befehl die Diskette quasi
zu "ordnen", da  sich  die  Magnetspuren
auf  ihr, wenn sie ganz frisch als Leer-
diskette aus der Fabrik kommt,  noch  in
einem undefinierten Zustand befinden.   
Man muß sie durch das "Formatieren" also
in einen definierten Zustand bringen, so
daß  Daten  auf  sie  geschrieben werden
können. Dies ist von Computer zu  Compu-
ter verschieden, der C64  beziehungswei-
se   die  Diskettenlaufwerke  desselben,
benutzen  ein  eigenes  Format,  MS-DOS-
Rechner, sei das ein XT oder AT benutzen
wiederum ein anderes, weshalb eine  Dis-
kette für jeden Rechnertyp eigens forma-
tiert werden muß.                       
Bei der  C64-Floppy  (normalerweise  die
1541,  es  gibt jedoch auch noch andere,
zum Beispiel die 1571, die auch für  den
C128 benutzbar ist) geschieht dies durch
den Befehlskanal. Hierzu müssen wir die-
sen erst einmal öffnen. Zu diesem  Zweck
brauchen  wir  natürlich erst eine File-
nummer, dann die Geräteadresse (in unse-
rem Fall die 8 - jedoch können Sie durch
die Geräteadressen von 9 - 11 auch ande-
re   Zusatzlaufwerke   ansprechen)   und
schließlich  und  endlich die  Sekundär-
adresse, die für den Befehlskanal  immer
15 ist. Filenamen oder ähnlichs brauchen
wir  zunächst  einmal nicht, also öffnen
wir den Kanal mit:                      
OPEN 1,8,15                             
Nun, da er geöffnet ist, können wir über
diesen Kanal eine Vielzahl von Befehlen,
mit  Hilfe  von  PRINT#,  an  die Floppy
schicken, die diese dann ausführen wird,
wobei wir uns dann nicht mehr darum küm-
mern  müssen.  Ich  hatte ja angedeutet,
daß ich dies anhand eines Format-Befehls
einmal demonstrieren wollte. Beim Forma-
tieren ist noch zu beachten, daß wir der
Floppy   einen  Diskettennamen  und  ein
2stelliges Identifikationskürzel mit auf
den Weg geben. Diese sogenannte "ID" ist
quasi  ein  Erkennungszeichen  für   die
Floppy, damit sie verschiedene Disketten
voneinander unterscheiden kann. Der Dis-
kettenname an sich darf maximal 16  Zei-
chen  lang sein, beide Parameter werden,
ähnlich wie bei  OPEN  durch  ein  Komma
getrennt,  an die Floppy übergeben. Hier
also einmal ein PRINT#-Befehl,  der  die
Floppy  eine  Diskette formatieren läßt,
mit dem Namen "NEUE  DISKETTE"  und  der
ID-Kennung "MD" :                       
PRINT#1,"N:NEUE DISKETTE,MD"            
Unter  der  Vorraussetzung,  daß wir den
Befehlskanal vorher mit der Filenummer 1
geöffnet hatten und daß  Sie  auch  eine
Diskette  eingelegt  hatten, beginnt nun
die Floppy, die Diskette zu formatieren.
Doch  VORSICHT,  vergewissern  Sie sich,
daß Sie auf  jeden  Fall  eine  Diskette
eingelegt  haben, die KEINE, beziehungs-
weise,  für   Sie   UNBRAUCHBARE   Daten
enthält !!!  Jegliche  Art von Daten auf
dieser Diskette  wird  nämlich  mit  dem
Format-Befehl UNWIDERRUFLICH gelöscht!  
Nicht also, daß Sie  sich  versehentlich
diese  Ausgabe der MD löschen, wir über-
nehmen für  eine  solche  Fehlbehandlung
keine Haftung und auch keine Garantie!  
Wenn  Sie  sichergehen möchten, daß eine
Ihrer Disketten nicht durch einen zufäl-
ligen  Irrtum  gelöscht  wird, so kleben
Sie doch einfach einen kleinen  Schreib-
schutzstreifen auf die Schreibschutzker-
be dieser Diskette.  Dann  wird  nämlich
bei  einem  vermeindlichen Format-Befehl
abgebrochen.  Diese  Kerbe  finden  Sie,
wenn Sie die Diskette von vorne betrach-
ten, an der rechten Seite, ich meine den
etwa 7-8mm langen und 4mm  breiten vier-
eckigen Einschnitt.                     
Sollte  nun mit der eingelegten Diskette
alles in Ordnung  und der  Schreibschutz
an  ihr  auch  nicht  vorhanden sein, so
werden Sie feststellen, daß  die  Floppy
nun  läuft  und  munter  diese  Diskette
formatiert.  Gleichzeitig  blinkt   auch
noch  der  Cursor bei unserem 64er, wenn
Sie obigen PRINT#-Befehl im  Direktmodus
eingaben.  Für  uns  heißt  das, daß die
Floppy nun eigenständig arbeitet und wir
mit dem 64er weiterarbeiten können, ohne
uns an dem Formatiervorgang  zu  stören.
Dies ist jedoch nur so lange  der  Fall,
bis wir einen  weiteren  Befehl  an  die
Floppy  senden,  dann  wartet  der  64er
nämlich intern  auf  ein  "OK"  von  der
Floppy, daß diese mit dem  Formatiervor-
gang fertig ist. Dann  erst  schickt  er
den nächsten Befehl nach. Da der  CLOSE-
Befehl ebenfalls die  Aufmersamkeit  der
Floppy beansprucht ist dies bei ihm  ge-
nauso der Fall. Schließen wir  also  den
Befehlskanal jetzt wieder mit "CLOSE 1",
so müssen wir warten, bis das  Formatie-
ren beendet  ist.  Im Programm  ist  das
eigentlich ganz brauchbar, da  es  sonst
vielleicht ein paar Probleme geben könn-
te mit der Koordinierung der Operationen
von Floppy und Rechner.                 
Ihnen  ist  bestimmt oben in dem PRINT#-
Befehl aufgefallen, daß ich vor den Dis-
kettennamen  und  der ID noch den Prefix
"N:" gesetzt hatte. Das war  das  Erken-
nungszeichen für die Floppy, daß es sich
bei  diesem Befehl um einen Formatbefehl
handelt.  Das  "N"  steht  nämlich   für
"NEW",  was soviel bedeutet, wie "NEUan-
legen der Diskette". Logisch, die  über-
setzung,  nicht  wahr?  Auf diese  Weise
können auch noch andere Befehlskürzel an
die Floppy gesandt werden, die dann auch
andere Aufgaben erfüllen. Jeder Befehls-
buchstabe  wird  grundsätzlich mit einem
Doppelpunkt (":") von den Parameteranga-
ben  getrennt.  Im  Folgenden möchte ich
Ihnen noch die 3 wichtigsten, da für uns
als Basicprogrammierer am  sinnvollsten,
Floppybefehle erklären.                 
Der Scratch-Befehl "S" :                
------------------------                
Mit dem "S"-Befehl können Sie die Floppy
dazu  veranlassen ein oder mehrere Files
auf der eingelegten Diskette zu löschen.
"Scratch"  heißt  nämlich   soviel   wie
"kratzen", und somit geht es hier um das
sinnbildliche  "wegkratzen"  eines Files
von der  Oberfläche  der  Diskette.     
Der  Scratchbefehl  wird  folgendermaßen
benutzt :                               
PRINT#1,"S:FILENAME1,FILENAME2,FILENAME3
,...,FILENAME n"                        
Sie können also beliebig viele Filenamen
anhängen,  jeweils  durch  Kommata   ge-
trennt,  die  dann  gelöscht werden. Das
Ganze steht natürlich wieder  in  Anfüh-
rungsstrichen, da dies der PRINT#-Befehl
ja so verlangt. Möchten Sie nur EIN File
löschen  so gehen Sie analog vor, lassen
Sie jedoch das Komma am Ende des Filena-
mens  weg  und  schließen Sie den Befehl
gleich mit einem Gänsefüßchen ab.       
Der Rename-Befehl "R" :                 
-----------------------                 
Mit  diesem  Befehl können Sie ein schon
vorhandenes File auf  der  Diskette  mit
einem  neuen  Namen  versehen.  "Rename"
bedeutet nämlich nichts anderes als "um-
benennen".                              
Dies funktioniert folgendermaßen:       
PRINT#1,"R:NEUER NAME=ALTER NAME"       
Sie geben nach dem "R:"-Prefix also ein-
fach  den Namen an, den das File von nun
an haben soll.  Anschließend  geben  Sie
mit Hilfe eines "="-Zeichens an, daß das
File  mit  dem nun folgenden Namen umbe-
nannt werden soll.                      
Der COPY-Befehl "C" :                   
---------------------                   
Mit diesem Befehl können Sie 2 oder meh-
rere SEQuentielle Files auf der Diskette
zu EINEM File, von ebenfalls sequentiel-
ler   Art,  zusammenkopieren.  Dies  ge-
schieht so:                             
PRINT#1,"C:NEUER NAME=ALT1,ALT2,ALT3,...
,ALT n"                                 
Sie geben also einfach den neuen Filena-
men  an, den die zusammenkopierten Files
haben sollen und schreiben, nachdem  Sie
ein  "="  eingefügt haben, die Files die
zusammenkommen, durch  Kommata  getrennt
hintereinander  auf.  In  dem neuen File
werden dann die alten Files in  der  von
Ihnen vorgegebenen Reihenfolge stehen.  
Soviel zu den  einzelnen  Befehlen.  Nun
möchte  ich  Ihnen  noch  etwas über den
Fehlerkanal erzählen. Wie ich oben schon
erwähnt hatte, kann  die  Statusvariable
ST  ja  auch  den  Wert  1 annehmen. Das
heißt, daß  ein  Fehler  beim  Schreiben
aufgetreten  ist.  Ich hatte da ja schon
angedeutet, daß man anschließend  einmal
den  sogenannten  "Fehlerkanal" auslesen
sollte, um festzustellen, welcher Fehler
im  Einzelnen  aufgetreten  ist.  Dieser
Fehlerkanal  wird ebenfalls über den Be-
fehlskanal der Floppy angesprochen. Feh-
lermeldungen  sind übrigens die einzigen
Daten, die man  vom  Befehlskanal  LESEN
kann,  ansonsten  wird  nur  dorthin GE-
SCHRIEBEN. Aus  diesem  Grund  weiß  die
Floppy  direkt,  daß  sie, falls gelesen
wird, die aktuelle Fehlermeldung  senden
soll. Diese besteht aus insgesamt 4 Tei-
len und sieht etwa folgendermaßen aus:  
FNR,NAME,SPUR,SEKTOR                    
Die Abkürzungen bedeuten :              
FNR    : Dies  ist die Fehlernummer. Je-
         der Floppyfehler hat  eine  be-
         stimmte Nummer, mit der man ihn
         identifizieren  kann. Eine Auf-
         listung  dieser  Fehler,  ihrer
         Nummern  und  ihrer  Bedeutung,
         finden  Sie   im   Anhang   des
         Floppyhandbuchs.               
NAME   : Dies  ist  eine  kleine Kurzbe-
         schreibung  des  Fehlers.  Wenn
         Sie zum Beispiel auf eine schon
         randvolle  Diskette  (0  BLOCKS
         FREE) zu  schreiben  versuchen,
         so kommt hier die Meldung "DISK
         FULL" von der Floppy.          
TRACK  : Die Tracknummer,  auf  der  der
         Fehler  auftrat.  Was ein Track
         ist, paßt  nicht  unbedingt  in
         den  Rahmen  dieses  Kurses und
         soll an anderer Stelle  genauer
         erklärt werden.                
SEKTOR : Die Sektornummer des Tracks auf
         dem der  Fehler  auftrat.  Auch
         dies  gehört nicht hier hinein,
         weshalb wir es  ebenfalls  aus-
         lassen werden.                 
Wie Sie sehen, haben wir hier drei nume-
rische  Werte (FNR,TRACK,SEKTOR) und ei-
nen Stringwert (NAME). Um nun  die  Feh-
lermeldung    auszulesen,   müssen   wir
zunächst  wie gewohnt, den  Befehlskanal
mit  OPEN öffnen. Anschlißend müssen die
einzelnen Parameter mit INPUT# ganz ein-
fach  ausgelesen  werden, dies geschieht
denkbar  einfach,  nämlich   mit   Hilfe
dreier numerischer und einer $-variable.
INPUT#1, NR,NA$,SP,SE                   
Nun können wir die eben geholte  Fehler-
meldung ausdrucken :                    
PRINT NR;NA$;SP;SE                      
Sollten Sie zum Beispiel versucht haben,
ein File zu laden, daß auf der  Diskette
gar  nicht  existiert,  so haben Sie nun
folgendes auf dem Bildschirm stehen:    
 62 FILE NOT FOUND 0  0                 
Wir sollten übrigens auch nicht  verges-
sen,  den  Fehlerkanal wieder zu schlie-
ßen. Hier noch einmal das komplette Pro-
gramm,  das  Sie  übrigens  auch auf der
Rückseite dieser Ausgabe der MAGIC  DISK
64  finden werden (unter dem Namen "FEH-
LERKANAL"):                             
10 OPEN 1,8,15                          
20 INPUT#1,NR,NA$,SP,SE                 
30 CLOSE 1                              
40 PRINT NR;NA$;SP;SE                   
Wenn  übrigens  gar kein Fehler vorliegt
(rote LED der Floppy blinkt NICHT)  dann
werden Sie folgende Meldung erhalten:   
 0 OK 0  0                              
Als Nächstes möchte ich Ihnen noch einen
kleinen  Befehl  zeigen,  der  ebenfalls
etwas  mit  der Datenausgabe zu tun hat.
Er wird  hauptsächlich  in  Zusammenhang
mit  einem  Drucker  benutzt,  kann aber
auch für andere Geräte angewandt werden.
Ich spreche  von  dem  sogenannten  CMD-
Befehl.  Mit  CMD können Sie alle Ausga-
ben, die sonst auf  den  Bildschirm  ge-
macht  werden, auf einen logischen File-
kanal leiten, den Sie  vorher  natürlich
mit  OPEN  geöffnet  hatten.            
Angenommen, Sie wollten ein Programm auf
dem Drucker ausgeben,  dann  müßten  Sie
lediglich folgendes eingeben :          
OPEN 1,4:CMD 1                          
LIST                                    
Wir öffnen hier also einen Filekanal mit
der Filenummer 1 und der Geräteadresse 4
für den Drucker. Anschlißend  geben  wir
dem  C64  bekannt, daß alle Ausgaben von
nun an auf den Kanal mit  der  Nummer  1
umgelenkt  werden  sollen.  Wenn Sie nun
LIST eingeben dann  erscheint  Ihr  Pro-
grammlisting  nicht  auf dem Bildschirm,
sondern es wird ohne  Umwege  gleich  an
den  Drucker  geschickt. Auf diese Weise
können Sie beispielsweise in Programmen,
die irgendwelche Tabellen auf dem  Bild-
schirm  ausdrucken,  ganz einfach diesen
Tabellendruck auch auf den  Drucker  um-
leiten, indem Sie nämlich VOR der Druck-
routine  für den Bildschirm  einen  CMD-
Befehl   einschieben.                   
Man könnte  dies  vielleicht  sogar  mit
einer IF-THEN- Abfrage lösen, wobei  zu-
erst der Benutzer nach dem  Ausgabegerät
gefragt wird und anschließend entschied-
en wird, ob ein  CMD  ausgeführt  werden
soll oder nicht.                        
Eine andere Anwendungsweise  wäre  viel-
leicht  die Möglichkeit, ein Programm in
Form von ASCII-Zeichen in einem File  zu
speichern, um es, zum Beispiel mit Hilfe
eines Terminalprogramms, in eine Mailbox
zu  schicken.  In diesem Fall müßten Sie
nur ein sequentielles File zum Schreiben
öffnen, mit CMD die Ausgabe  auf  dieses
File  umleiten  und  das  Programm  dann
LISTen.                                 
Eines wäre jedoch noch zu beachten.  Da-
mit  Sie  nämlich  wieder  aus  dem CMD-
Befehl herauskommen, um dann die Ausgabe
wieder auf  den  Bildschirm  zu  leiten,
müssen Sie einen einfachen PRINT#-Befehl
nachschieben, ohne Parameter, etwa so:  
PRINT#1                                 
Wobei hier anstelle der  "1"  auch  jede
andere  Zahl  stehen könnte, je nachdem,
welche Filenummer Sie vorher beim  OPEN-
Befehl benutzt hatten, auf dessen geöff-
neten Kanal Sie dann die Ausgabe  umlei-
teten.                                  
Anschließend sollte man den  Kanal  auch
noch schließen, also:                   
CLOSE 1 :REM (je nach Filenummer)       
Damit hätten wir  das  Thema  Peripherie
abgeschlossen.  Ich  muß  Ihnen nun noch
etwas über Variablen erzählen.  Wie  wir
diese  handhaben  und vor allem, wie wir
deren Namen wählen, hatten wir ja  schon
im 1. und 2. Teil dieses Kurses geklärt.
Es gibt allerdings noch eine weitere Art
Variablen zu benutzen, nämlich durch die
Definition von sogenannten Variablenfel-
dern.  Dies  klingt   vielleicht   etwas
merkwürdig,  doch werden Sie gleich ver-
stehen, was damit geimeint ist.         
Ein Feld, oder eine Fläche, hat ja,  wie
Sie  vielleicht  aus dem Geometrieunter-
richt noch wissen, zwei Ausdehnungen.   
Zum  einen die Länge und zum anderen die
Breite. Man sagt auch "ein Feld hat zwei
Dimensionen". Es ist also ein Objekt der
Zweiten Dimension. Ebenso gibt  es  eine
Erste Dimension, die alle Strecken bein-
haltet. Diese  haben  nur  eine  einzige
Ausdehnung, nämlich die Länge.          
Diesen  Begriff  der  Dimension kann man
nun auch auf  Variablen  übertragen.  Es
gibt  nämlich  in BASIC die Möglichkeit,
mehrere Variablen mit dem gleichen Namen
anzulegen, die alle  jedoch  voneinander
unterschieden  werden,  indem  man ihnen
einen sogenannten Index gibt. Das heißt,
daß jeder Variable eine  bestimmte  Zahl
nachgestellt  wird,  die  eine  ganz be-
stimmte Variable darstellt.  Anwendungs-
gebiete  gibt  es  hierfür  wie  Sand am
Meer. Angenommen, Sie möchten  ein  Pro-
gramm schreiben, daß alle Adressen Ihrer
Bekannten  und Verwandten speichert. Ge-
hen wir einmal davon aus, daß dies maxi-
mal  100 bis 200 an der Zahl sind. Möch-
ten Sie nun alle diese Namen in  "norma-
len"  Variablen speichern, so würden Sie
jedesmal einen neuen Variablennamen  he-
raussuchen  müssen,  damit  BASIC  diese
voneinander unterscheiden kann.  Stellen
Sie  sich  einmal das Chaos vor, daß Sie
dann in einem Programm hätten.  200  Va-
riablen,  von denen Sie nicht mehr genau
wissen was zu wem gehört. Wenn man davon
ausgeht, daß  Sie  vielleicht  zu  jedem
Namen  auch  noch  Straße,   Hausnummer,
Wohnort und Telefonnummer speichern wol-
len, dann  müßte  Herr  Müller  aus  der
Bahnhofstaße  37  in  8000  München  und
der Telefonnummer 089/12345678  etwa  in
folgenden Variablen verteilt werden :   
AX$="Herr Mueller"                      
FR$="Bahnhofstraße"                     
KL=37                                   
OG=8000                                 
TA$="Muenchen"                          
XD$="089/12345678"                      
Sie  sehen  also, wir haben hier wahllos
verteilte Variablen vor uns, die  nichts
über ihren Inhalt aussagen, da jeder nur
erdenkliche Variablenname genutzt werden
muß.  Stellen  Sie sich doch nur die me-
terlangen Listings von IF-Abfragen  vor,
die  man  machen müßte, um eine ganz be-
stimmte Adresse herauszufinden. Außerdem
wüßte man noch nicht einmal  welche  Va-
riablen  zu  einer Adresse gehören. Des-
halb gibt es die Feldvariablen. Sie sol-
len hier eine Abhilfe schaffen. Auf die-
se Art und  Weise  können  nämlich  bei-
spielsweise  alle  Namen in einem Varia-
blennamen  zusammengeafßt  werden,  oder
alle  Straßennamen,  oder alle Städtena-
men...                                  
Doch wie wirds gemacht?  Dazu wollen wir
jetzt kommen.  Zuerst  müssen  wir  eine
Variable "dimensionieren".  Im  Klartext
heißt  das,  daß  wir  einen  Namen  für
das  Variablenfeld  und die maximale An-
zahl  der in ihm zu speichernden  Daten,
festlegen  müssen.                      
In unserem Fall  einer  Adressverwaltung
nehmen wir (beispiels- weise) den  Vari-
ablennamen NA$ für "Na- me". Die  Dimen-
sionierung wird mit einem eigenen BASIC-
Befehl durchgeführt, dem DIM-Befehl. Bei
diesem wird zuerst der Name des  Variab-
lenfeldes  angegeben  und   anschließend
seine maximale  Ausdehnung.  Wir  wollen
also 200  Stringvariablen  im  Feld  NA$
speichern. Deshald also diese Anweisung:
DIM NA$(200)                            
Schon wäre unser Feld dimensioniert. Wir
haben hier ein eindimensionales Feld vor
uns,  dem  DIM-Befehl  wird  zuerst  der
Feldname  und  dann  die maximale Anzahl
aller  Datenelemente,  in  Klammern  ge-
setzt,  nachgestellt.  In  dem  Feld NA$
können wir nun also 200 Variablen unter-
bringen.                                
Um jetzt ein einzelnes dieser 200  Date-
nelemente  adressieren zu können, müssen
wir  seine  Indexnummer,  ebenfalls   in
Klammern  gesetzt, einfach dem Feldnamen
nachstellen. Diese  Datenelemente  eines
Feldes  werden  übrigens genauso gehand-
habt, wie die Variablenart  in  der  sie
dimensioniert  wurden.  Wir  haben  hier
einen  Stringvariablennamen   angegeben,
also  haben wir auch 200 Stringvariablen
vordefiniert. Demnach sind auch die  Zu-
weisungen  ausgelegt.  Wie  bei  Strings
auch geben Sie den obigen  "Variablenna-
men"  an  und  weisen  ihm mit Hilfe des
"="-Zeichens eine Zeichenkette zu.  Etwa
so:                                     
NA$(0)="HERR MUELLER"                   
Hier  haben  wir dem 0. Datenelement den
String "Herr  Mueller"  zugewiesen.  Sie
erinnern  sich  ja :  der Computer fängt
immer bei 0 an  zu  zählen,  dementspre-
chend  ist das 0. Datenelement der erste
Eintrag in unserem Datenfeld.  Doch  wir
müssen hier keineswegs einer numerischen
Reihenfolge  der Variablenzuweisung vor-
gehen.  Vielmehr  können  Sie  ebenfalls
auch  Zuweisungen  von  Werten bei nume-
risch größeren Variablen vornehmen.  Sie
haben hierbei also freie Hand. Wie wärs,
wenn  wir "Herrn Schultze" im 134. Date-
nelement unterbrächten, kein Problem:   
NA$(134)="SCHULTZE"                     
Doch die eigentliche Stärke der  Feldva-
riablen  liegt  nicht darin, daß man sie
in einem Namen zusammenfassen kann, son-
dern  vielmehr,  daß man mit Hilfe einer
Schleife gezielt  ein  Feld  nach  einem
bestimmten  Datensatz  durchsuchen kann,
ohne  dabei  großen   Programmieraufwand
leisten  zu müssen. Angenommen wir woll-
ten Herrn Schultze in unserem  Datenfeld
wiederfinden,  dann  wäre folgendes Pro-
gramm schnell und einfach geschrieben:  
100 FOR I=0 TO 200                      
110 IF NA$(I)="HERR SCHULTZE" THEN 130  
120 NEXT                                
130 PRINT"HERR  SCHULTZE STEHT IM DATENS
ATZ NR.";I                              
Wenn wir nun die anderen Daten ebenfalls
so anlegen, daß  wir  200  Datenelemente
darin  speichern können  und den einzel-
nen  Feldelementen  mit  dem  Index  134
ebenfalls  die zu Herrn Schultze gehöri-
gen Daten zuordnen, so können  wir  ganz
einfach  mit  Hilfe  der Variablen I auf
alle Datenelemente der Adresse  von  ihm
zugreifen, etwa so:                     
200 PRINT NA$(I) :REM NAME              
210 PRINT SR$(I) :REM STRASSE           
220 PRINT NR(I)  :REM HAUSNUMMER        
230 PRINT PL(I),OR$(I) :REM PLZ UND ORT 
240 PRINT TE$(I) :REM TELEFONNUMMER     
Und schon wäre die gesamte  Adresse  von
Herrn  Schultze  ausgedruckt,  da wir ja
vorher die einzelnen Elemente  ebenfalls
den  Feldelementen  mit  der  Nummer 134
zuweisen wollten. So einfach ist es dann
beispielsweise einen  bestimmten  Daten-
satz  zu  finden.  Auch beim Abspeichern
haben wir keine Probleme,  wir  brauchen
lediglich  eine  Schleife zu programmie-
ren, die alle Datenelemente  des  Feldes
von   0   bis   200  in  ein  WRITE-File
schreibt.                               
Wie  Sie sahen, hatten wir ein eindimen-
sionales Feld  dimensioniert.  Es  hatte
also  nur EINE Ausdehnung. Man kann dies
jedoch beliebig erweitern. Wie  wäre  es
denn  mit  einem  zwei-, drei-, oder gar
vierdimensionalen Feld? Bitte:          
DIM A$(1000,10)                         
DIM B%(10,3)                            
DIM C(5,5,5)                            
Mit diesen Dimensionierungen  haben  wir
nun  also  veranlaßt, daß beispielsweise
ein Feld mit dem Namen A$ für 1000 Date-
nelemente dimensioniert wurde, von denen
jedes einzelne wiederum 10  weitere  Da-
tennelemente aufnehmen kann. Diese  kön-
nen Sie dann folgendermaßen ansprechen: 
PRINT A$(523,3)                         
 Hier hätten wir das 3. Datenelement des
523.  Hauptelements  von A$ ausgedruckt,
dies kann man in beliebig vielen  Dimen-
sionen  weiterführen, soweit diese sinn-
voll sind. Eines sollte ich jedoch  noch
sagen:  bei  einer  Dimensionierung  von
Variablen reserviert der  C64  für  jede
einzelne Variable einen bestimmten Spei-
cherbereich.  Bei  FLOAT-Variablen   ist
dies   besonders  Speicherintensiv.  Pro
Variable gehen nämlich 5  Bytes  flöten,
die  nicht mehr für andere Variablen be-
nutzt  werden  können.  Hierbei  ist  es
übrigens  egal,  ob  diese  Variable nun
einen Inhalt hat  oder  nicht.  Man  muß
sich   also  immer  ausrechnen,  wieviel
Speicherplatz so ein Feld  einnimmt,  um
nicht  in Speichermangel zu kommen, denn
dann bricht der  64er  unweigerlich  mit
einem "?OUT OF  MEMORY  ERROR" ab. Woll-
ten  Sie  beispiel  ein  6-dimensionales
Feld mit jeweils 4 Datenelementen dimen-
sionieren, so könnten Sie mit dem  Spei-
cherplatz knapp werden:                 
DIM A(3,3,3,3,3,3)                      
Wenn  Sie sich wundern, warum hier immer
3 anstatt 4 steht, wie ich ja eben  sag-
te,  so  denken Sie bitte daran, daß das
0. Datenelement ebenfalls mitzählt, also
0,1,2,3 = vier  Elemente.  Oben  bei  A$
hätte ich auch schreiben sollen, daß wir
dort  anstatt  1000 sogar 1001 Elemente,
mit 11 anstatt 10 Unterelementen  dimen-
sioniert  haben,  doch habe ich dies zum
besseren Verständnis zu jenem  Zeitpunkt
weggelassen.                            
Wir  hätten  hier  also  4*4*4*4*4*4=4↑6
Variablen  dimensioniert, für die alle 5
Bytes Speicherplatz  reserviert  werden,
also  4↑6*5  Bytes  oder  4096*5 Bytes =
20480 Bytes, das entspricht etwa 2/3 des
gesamten Basicspeichers (38911 Bytes).  
Es ist  also  keineswegs  egal, wieviele
Elemente  Sie dimensionieren. Suchen Sie
ein Optimum heraus. Bei String- und  In-
tegervariablen ist der Speicherplatzver-
brauch  etwas  geringer.                
Probieren Sie doch einfach  einmal  aus,
wie viel Platz Sie haben.               
Kommen  wir  nun  noch  zu drei weiteren
kleinen Befehlen,  die  ich  ihnen  noch
erklären  muß.  Da  wäre zunächst einmal
der DEF FN-Befehl. Dies  ist  eigentlich
nichts  weiter als eine kleine  Program-
mierhilfe, die man zwar nicht  unbedingt
braucht,  die  jedoch ganz nützlich sein
kann, wenn man strukturiert  programmie-
ren  möchte.  FN  ist  quasi  ein Varia-
blenkürzel für  eine  vorher  definierte
Funktion.  Sie  müssen  an dieses Kürzel
nur  noch   einen   FLOAT-Variablennamen
anhängen (also einen Variablennamen OHNE
"%"  oder  "$").  Auf diese Weise können
Sie häufig benutzte Funktionen, zum Bei-
spiel  komplexere Rechenformeln vordefi-
nieren, die Sie dann durch einen simplen
und kurzen Aufruf komplett durchrechenen
können. Dies ist rechenzeit-  und  spei-
cherplatzsparend.                       
Doch  hier  die  Praxis. Zunächst wollen
wir erst einmal eine  Funktion  vordefi-
nieren,  hierzu  benutzt  man  das  DEF-
Statement:                              
DEF FNAX(X)=(10/X)*SIN(X)+201           
Hier haben wir der FunktioN AX die  For-
mel  (10/X)*SIN(X)+201  zugeordnet.  Das
"X" in Klammern der Definition muß immer
mit angehängt werden.  Möchten  Sie  nun
einmal  das  Ergebnis  der Formel ausge-
druckt haben, wenn Sie für X  beispiels-
weise  den  Wert  7 einsetzen, so müssen
Sie dies folgendermaßen tun:            
PRINT FNAX(7)                           
Schon erhalten  Sie  ein  Ergebnis.  Die
Möglichkeit  eine Funktion zu definieren
eignet sich gut  für  Kurvendiskussions-
programme, da Sie bei einer Funktionsbe-
rechnung natürlich auch  Variablen  ver-
wenden können. So zum Beispiel die Lauf-
variable einer Schleife, die eine Werte-
tabelle ausdruckt.                      
Als  Nächstes hätten wir da den WAIT Be-
fehl. Mit ihm können wir den 64er darauf
warten lassen,  daß  eine  Speicherzelle
einen anderen Wert annimmt. Als Beispiel
nehme ich hierzu einmal die Speicherzel-
le 198, aus  dem  oben  schon  genannten
Speicherbereich   für  interne  Aufgaben
unseres Computers. In dieser Spicherzel-
le  wird nämlich vom Betriebssystem zwi-
schengespeichert, wieviele Tasten  schon
vom  Benutzer  gedrückt wurden, ohne daß
das  dazugehörige  Zeichen   ausgedruckt
wurde.  Wenn Sie sich im Direktmodus be-
finden steht hier nie mehr als der  Wert
1  drin,  da  der  64er die Tastendrücke
schneller druckt,  als  Sie  sie  tippen
können.  Doch  während  eines  laufenden
Programms kann  diese  Zahl  auch  schon
einmal bis zu 10 ansteigen. Deshalb wol-
len wir vor der Abfrage dieser Speicher-
zelle  besser  eine  0  hineinPOKEn.    
Ich möchte Ihnen nämlich nun zeigen, wie
man ganz einfach ein  Programm  zum  An-
halten bringt,  so,  daß  es  auf  einen
Tastendruck wartet. Hier ein Beispiel:  
10 POKE 198,0:WAIT 198,1:POKE 198,0     
Hier löschen wir zuerst einmal jeglichen
Inhalt der eben genannten Speicherzelle,
um sicherzugehen, daß hier auch wirklich
nichts   drinsteht.  Mit  dem  folgenden
WAIT-Befehl warten wir auf das Ereignis,
daß eine Taste gedrückt wird,  daß  also
eine  1  vom Betriebssystem in die Spei-
cherzelle 198 geschrieben wird. Ist dies
der Fall, so fährt der 64er mit dem Pro-
gramm fort, wo wir dann gleich noch ein-
mal die Zelle  198  löschen,  damit  das
eben eingegebene Zeichen nicht doch noch
einmal irgendwann eingelesen werden kann
und  irgendwelche, nicht gewollte, Funk-
tionen im Programm verursacht.          
Als drittes noch  kurz  der  SYS-Befehl.
Dieser  Befehl ist für BASIC-Programmier
eigentlich wenig wichtig. Mit  ihm  kann
man den 64er dazu veranlassen die BASIC-
Ebene zu verlassen und ein Maschinenpro-
gramm an einer bestimmten Speicheradres-
se auszuführen. Der Befehl  "SYS  49152"
zum  Beispiel, startet ein Assemblerpro-
gramm, das in  Speicherzelle  49152  be-
ginnt.  Wenn  Sie übrigens mehr über As-
sembler  bzw.  Maschinensprache   wissen
möchten,  so möchte ich an dieser Stelle
darauf hinweisen, daß wir, die Redaktion
der MAGIC DISK 64, planen,  etwa  Anfang
nächsten  Jahres einen Assemblerkurs auf
einer eigenen Diskette quasi als Sonder-
ausgabe,  herauszubringen.  Wenn  es so-
weit sein wird, werden wir Sie dann auch
auf jeden Fall noch  rechtzeitig  infor-
mieren. Der Kurs wird übrigens ebenfalls
von mir sein, falls Sie also  meine  Er-
klärungen für einsichtlich  und  einfach
halten,  so  wird diese Diskette ein Muß
für alle angehenden Assemblerprogrammie-
rer unter Ihnen sein.                   
Der letzte Teil des  Basickurses  sollte
dies sein. Aber das Basic V2.0  beinhal-
tet noch ein paar weitere Befehle. Diese
sind besonders  bei  der  Programmierung
der Grafik wichtig, weswegen sie eigent-
lich im sich  anschließenden  Grafikkurs
abgehandelt werden sollten.             
Da aber zu befürchten ist, daß  die  ei-
gentliche  Beschreibung  und   Erklärung
dieser Befehle im Rahmen  eines  Grafik-
kurses zu kurz gerät, haben wir uns ent-
schlossen,  diese  letzten  Befehle   in
einem weiteren, nun aber endgültig letz-
ten Basickursteil abzuhandeln.          
Diesen neunten Teil finden  Sie  in  der
Oktoberausgabe   der   Magic  Disk.   Im
November werden wir dann  aber  voll  in
die Grafikprogrammierung einsteigen.    
                         Ihr Uli Basters
 ASICKurs: "Von Adam und Eva..."(Teil 9)
----------------------------------------
Hallihallo, da sind wir wieder. Entgegen
allen  Gerüchten, die ich das letzte Mal
aufgestellt  habe,  ist  der   Basickurs
jetzt  doch  noch einen Teil länger. Wir
haben uns dazu entschlossen, daß es doch
besser ist, wenn dieser Kurs  hier  kom-
plett  abgeschlossen ist, so daß es kei-
ner langwierigen Erklärungen mehr  benö-
tigt,  wenn  wir uns ab nächten Monat an
die Grafik machen werden.               
Heute  kommen  nun  noch  die  ultimativ
letzten Basicbefehle an die  Reihe,  mit
denen  sich  auch  noch einiges anfangen
läßt...                                 
1.) Die Stringfunktionen :              
--------------------------              
Wie diese Überschrift schon verrät, bie-
tet  uns BASIC V2.0 eine Fülle von Funk-
tionen, mit denen wir auf einfachste Art
und Weise Stringvariablen verändern  und
manipulieren können. Was kann man darun-
ter verstehen?  Nun, vielleicht ist  Ih-
nen  ja  schon im letzten Teil aufgefal-
len, daß ich dort ein sequentielles File
mit dem Befehl :                        
OPEN 1,8,2,NA$+",S,W"                   
zum Schreiben geöffnet hatte. Vielleicht
haben Sie sich gefragt, was dieses  "+"-
Zeichen  bewirken  soll.  Nunja, wie wir
dann ja feststellten,  diente  es  dazu,
die  beiden  Stringketten (zum einen der
String  in  NA$  und  zum  anderen   das
",S,W") miteinander zu verknüpfen. Stün-
de beispielsweise der String  "FILENAME"
in  NA$,  so  hieße  das  für  den OPEN-
Befehl, daß er hier  die  Gesamtzeichen-
kette  "FILENAME,S,W"  vor sich hat. Der
notwendige Appendix ist somit direkt  an
den veränderbaren oder variablen Text in
NA$  angehängt  worden.  Genau  dies ist
auch als Variablenzuweisung möglich, wie
es das folgende Programm demonstriert : 
10 A$="STRINGS KOENNEN "                
20 B$="MIT '+' VERKETTET "              
30 C$=A$+B$+"WERDEN!"                   
Nach  Ablauf des Programms haben wir nun
also in A$ den Text  "STRINGS KOENNEN ",
in  B$ den Text "MIT ↑+↑ VERKETTET " und
in  C$  "STRINGS KOENNEN MIT '+' VERKET-
TET WERDEN!" stehen.                    
Umgekehrt,  beim Zerlegen eines Strings,
verhält  sich  dies   allerdings   etwas
schwieriger.   Sie  können  hier  leider
nicht mit dem Minuszeichen ("-")  arbei-
ten.  Dazu  haben  wir  allerdings   die
Stringfunktionen LEFT$, RIGHT$ und  MID$
zur  Verfügung, die sogar noch viel bes-
ser arbeiten, als  es  mit  "-"  möglich
wäre.  Mit  Ihnen kann man nämlich einen
String gezielt in Stücke zerhacken, ohne
dabei großen Aufwand zu haben.          
Zum  einen  wäre  da  LEFT$.  Mit dieser
Funktion können wir einen Teil aus einer
Stringvariablen isolieren, der von LINKS
nach RECHTS reicht. Hierzu übergeben wir
LEFT$ ganz einfach den zu  bearbeitenden
String  und, durch ein Komma voneinander
getrennt, die Anzahl der zu  übernehmen-
den  Buchstaben  an. Dies geschieht etwa
folgendermaßen :                        
A$="BASIC IST TOLL"                     
PRINT LEFT$(A$,5)                       
Nach dieser Befehlssequenz  sollten  Sie
dann  nur  die  5 Buchstaben "BASIC" auf
dem Bildschirm stehen haben.  Es  wurden
also  die  ersten  5  Buchstaben aus dem
String A$ herausisoliert.               
Ebenso verhält es sich nun  mit  RIGHT$,
nur  daß  nun  die Buchstaben von RECHTS
nach LINKS isoliert  werden,  wobei  sie
ihre   Reihenfolge  jedoch  beibehalten,
nicht also rückwärts geschrieben  sind !
Hier ein Beispiel :                     
A$="BASIC IST TOLL"                     
PRINT RIGHT$(A$,4)"                     
Nun erhalten  Sie  also  die  4  letzten
Buchtaben   des  Strings  A$,  den  Text
"TOLL".                                 
Wem das noch nicht genügt, der kann  auf
MID$  zurückgreifen.  MID$  stellt quasi
eine Mischung aus  LEFT$  (von  "Links")
und  RIGHT$ (von "Rechts") dar. Sie kön-
nen hiermit, wie der Befehl schon  sagt,
eine  Zeichenkette "aus der Mitte" eines
Strings herausisolieren. Hierbei  müssen
wir,  wie  bei den beiden Verwandten von
MID$ auch, erst einmal den  zu  Untersu-
chenden Stringnamen angeben, gefolgt von
der  Nummer  des Buchstabens, von dem an
wir die folgenden Buchstaben  übernehmen
möchten,  und der Anzahl der Buchstaben,
die übernommen werden sollen; alle Para-
meter  jeweils  durch  Kommata getrennt.
Den Text  "IST"  aus  unserem  Beispiel-
string  "BASIC IST TOLL" können wir also
folgendermaßen isolieren :              
A$="BASIC IST TOLL"                     
PRINT MID$(A$,7,3)                      
Hier werden also ab  dem  7.  Buchstaben
des  Strings A$, 3 Buchstaben herausiso-
liert: das Wort "IST".                  
Jetzt werden Sie sicher sagen, "Na schön
und gut, doch wofür  kann  man  denn  so
etwas  brauchen ?"  Zugegeben, viele An-
wendungen  finden  die  Stringfunktionen
vielleicht  nicht,  doch  kann ich Ihnen
ein höchst wichtiges Problem  aufzeigen,
das  geradezu "wie geschaffen" für unser
Thema  ist :  die  Eingaberoutine  eines
Textadvetures zum Beispiel.             
Wenn Sie diese Art von  Spielen  kennen,
so  werden  Sie  sicher  wissen, daß die
Eingaben an das Programm meist mit Hilfe
einer Kommandozeile abgewickelt  werden,
über  die  die  einzelnen Befehle an das
Programm gehen. Sie wissen sicher  auch,
daß  solche  Befehle  in aller Regel aus
Verben und Objekten  bestehen,  wie  zum
Beispiel  "NIMM BUCH".  Hier  haben  wir
also ein Verb, das angibt WAS getan wer-
den  soll und ein Objekt MIT DEM wir et-
was tun wollen. Nun gilt es also  diesen
Kommandostring in seine einzelnen Unter-
worte  aufzusplitten,  damit  wir  keine
Probleme  bei  der  Erkennung  der Worte
bekommen. Wir  müssen  also  in  unserem
String  nach Leerzeichen suchen, die die
Worte ja voneinander trennen, und bis zu
dieser Stelle ein Wort isolieren.  Damit
unser Beispiel nicht komplizierter wird,
als  es in diesem Rahmen sein soll, set-
zen wir einmal vorraus, daß nur 2  Worte
in  der  Eingabe vorkommen, daß also der
Anfang eines Strings, bis  zum  Leerzei-
chen,  ein  Wort  bildet, und alles, was
danach folgt, ein weiteres.  Erschwerend
kommt  noch hinzu, daß wir ja nicht wis-
sen WIE LANG der  gesamte  Eingabestring
ist.  Doch dieses Problem können wir mit
Hilfe einer weiteren Stringfunktion  lö-
sen,  der  LEN-Funktion.  Diese funktio-
niert denkbar einfach, wir  müssen  näm-
lich lediglich den Namen des zu untersu-
chenden Strings,  in  Klammern  gesetzt,
nach  dem  Befehlswort LEN angeben. Etwa
so:                                     
10 A$="OEFFNE TRUHE"                    
20 A=LEN(A$)                            
Danach steht in A der Wert 12, denn  so-
viele  Buchstaben  enthält  die Variable
A$. Nun können wir uns  um  die  Analyse
des  Strings  kümmern.  Zunächst  einmal
eine Schleife, mit deren Hilfe wir fest-
stellen  wollen,  an  welcher  Stelle in
unserem String sich das Leerzeichen  be-
findet.  Hierzu  bedienen  wir  uns dann
MID$. Er holt  sich  jeweils  nur  EINEN
Buchstaben aus unserem String, damit wir
prüfen  können  welches  Zeichen wir vor
uns haben :                             
30 FOR I=1 TO A                         
40 X$=MID$(A$,I,1) :REM NUR EIN ZEICHEN 
50 IF X$<>" "THEN NEXT                  
Die  Schleife  holt  sich  hier also nur
solange Zeichen aus dem String, wie die-
se  ungleich dem Leerzeichen (" ") sind.
Ist dies nicht mehr der  Fall,  so  sind
wir an dem Punkt angelangt, wo die Worte
getrennt  werden.  In der Laufvariable I
ist nun die Stelle des  Leerzeichens  in
unserem String gespeichert. Wir brauchen
uns  die  einzelnen Komponenten nur noch
mit Hilfe von LEFT$ und RIGHT$ in  eige-
nen Variablen zuweisen. Hierbei ist noch
zu  beachten,  daß  wir beim ersten Wort
auch das Leerzeichen am Ende mitbekommen
würden, würden wir  I  so  benutzen.  Da
dies  jedoch nur behindernd ist brauchen
wir also lediglich alle  Buchstaben  bis
I-1  herauszuisolieren.  Bei dem zweiten
Wort müssen wir dann auch erst noch  be-
rechnen, wieviele Stellen wir von Rechts
gebrauchen können, das tun wir mit Hilfe
der  Formel  A-I.  Das  ganze sieht dann
folgendermaßen aus :                    
60 W1$=LEFT$(A$,I-1)                    
70 W2$=RIGHT$(A$,A-I)                   
80 PRINT"DAS ERSTE WORT IST  : ";W1$    
90 PRINT"DAS ZWEITE WORT IST : ";W2$    
Wir  haben  also  nun ein kleines Anwen-
dungsbeispiel für die bisherigen String-
funktionen  durchgeführt. Nebenbei haben
wir da  dann  auch  noch  LEN  kennenge-
lernt.  BASIC  kennt aber noch 4 weitere
Stringfunktionen. Zwei davon kennen  wir
bereits, CHR$ und ASC, weshalb ich nicht
mehr  auf  diese eingehen werde, doch es
gibt noch zwei weitere.                 
Zum einen wäre  da  STR$.  STR$  liefert
ganz  einfach  den  String einer numeri-
schen Variablen, so wie  sie  mit  PRINT
ausgedruckt  worden  wäre. So können Sie
zum Beispiel auf einfache Art und  Weise
eine  INTEGER- oder FLOAT-Variable einer
Stringvariablen  zuweisen,   wobei   der
String  dann  halt  die  ASCII-Werte der
einzelnen Ziffern enthält.  Zum  Rechnen
können Sie diesen String natürlich nicht
mehr  verwenden, jedoch kann diese Funk-
tion manchmal ganz von nutzen sein. Hier
einmal ein Beispiel :                   
A=1989                                  
X$=STR$(A):REM IDENTISCH MIT 'X$="1989"'
Hiermit hätten wir also der Stringvaria-
blen X$ den String "1989" zugewiesen und
können  diesen  nun   weiterverarbeiten.
Beispielsweise  gibt  es  da eine Formel
zur Berechnung  des  Wochentages  anhand
des reinen Datums die mit Parametern wie
"Jahrhundert" oder "Jahrzehnt" arbeitet.
Hierzu  bietet es sich dann an mit LEFT$
und RIGHT$ eben jene Parameter  zu  iso-
lieren und mit der nun folgenden String-
funktion wieder in eine  Zahl  zurückzu-
wandeln.                                
Die  Funktion von der ich rede heißt VAL
und tut genau das umgekehrte  wie  STR$.
Angenommen,  wir  hätten das Jahrhundert
aus "1989"  mittlerweile  herausisoliert
und fein säuberlich in der Variablen JH$
gespeichert. Dann könnten wir den String
"19"  mit  folgendem Befehl ganz einfach
zur Zahl 19 machen:                     
JH=VAL(JH$)                             
Das wars schon. Sie können nun  wie  ge-
wohnt  mit  JH  rechnen, denn dort haben
wir nun tatsächlich den numerischen Wert
19 stehen, und nicht etwa  die  Zeichen-
kette "19".                             
Soviel zum Thema  Stringfunktionen,  ma-
chen  wir  nun  weiter  mit den ominösen
Befehlen, die eigentlich erst im Grafik-
kurs gekommen wären, ich werde Sie Ihnen
hier  jedoch  anhand  eines anderen Bei-
spiels erläutern:                       
2.) Datenhandling im Programm :         
-------------------------------         
Bestimmt haben Sie schon einmal ein  Ba-
sicprogramm  aus einer Zeitschrift abge-
tippt, die NICHT über  den  Vorteil  der
Magic Disk 64 verfügte, daß die Program-
me zum Heft alle auf einer Diskette mit-
geliefert  werden.  Dabei mußten Sie mit
ziemlicher Sicherheit (denn  dies  kommt
häufig vor) auch lange Kolonnen von Zei-
len abtippen, in  denen  am  Anfang  das
Befehlswort DATA stand, gefolgt von vie-
len Zahlen, alle durch Kommata voneinan-
der  getrennt.  Wie  dieser Befehl schon
sagt, werden  hier  DAT(A)enwerte  abge-
legt.  Auf  ein  Programm  selbst hat er
eigentlich wenig Einfluß - er wird  ganz
einfach  von BASIC überlesen. Nur in Zu-
sammenhang mit einem  weiteren  Basicbe-
fehl  hat DATA überhaupt einen Sinn, ich
spreche von dem READ-Befehl. Im  übrigen
könnte  dieser  ohne DATA auch wenig an-
richten, die  beiden  hängen  also  fest
zusammen  und  voneinander  ab. READ ist
(wie immer) englisch und  heißt  "LESE".
Wir  können  den  Computer  also hiermit
anweisen ein Datenelement zu LESEN - und
woher nimmt  er  sich  dieses  Datenele-
ment?    Natürlich   von   einem   DATA-
Statement!  READ liest nun also das  er-
ste Datenelement hinter der ersten DATA-
Anweisung im Programm in  eine  Variable
ein,  die  wir  ihm schlicht und einfach
nachstellen.                            
Ich gebe zu, daß es  langsam  vielleicht
etwas  langweilig erscheint immer wieder
das Beispiel eines Textadventures durch-
zukauen,  doch paßt dieses Beispiel hier
genau hin und erklärt  hoffentlich  ein-
deutig,  wozu  READ  und  DATA notwendig
sind.                                   
Also angenommen, Sie wollten ein Textad-
venture schreiben,  das  mehrere  Verben
und  mehrere  Objekte (wie das ja, schon
oben beschrieben, zu JEDEM Textadventure
gehört) verstehen soll. Zuerst haben wir
einmal die Eingabe vom Spieler in  seine
Einzelteile  zerlegt und in W1$ das Verb
und in W2$ das Objekt  gespeichert.  Nun
geht es darum zuerst einmal das eingege-
bene Verb zu  analysieren  und  mit  dem
Programmwortschatz zu vergleichen. Hier-
zu benutzen wir ein  Variablenfeld  (Sie
erinnern  sich  an das letzte Mal...) in
dem alle Verben gespeichert werden  sol-
len.  Damit  das bei einem Programm, das
vielleicht  100  Verben  verstehen  soll
nicht in Arbeit ausartet, wollen wir die
einzelnen  Verbdaten  mit  Hilfe   einer
Schleife  den Variablen zuordnen. Hierzu
legen wir alle Verben in DATA-Zeilen  ab
und  lesen  sie,  eins nach dem anderen,
ein und weisen sie somit einer Variablen
in unserem Feld zu. READ liest also  im-
mer  das nächste Element aus einem DATA-
Statement aus,  solange  bis  es  nichts
mehr zu lesen gibt. Das sollten Sie wis-
sen, damit READ nicht zuviele Daten ein-
zulesen  versucht.  Hier einmal ein Bei-
spiel, bei dem ich 7 Verben in  dem  Va-
riablenfeld VE$(X) speichern möchte. Wie
die  Schleife  schon  zeigt, werden hier
auch nur  7  Datenelemente  gelesen,  (6
Elemente plus das 0. Element).          
10 DIM VE$(6)                           
20 FOR I=0 TO 6:READ VE$(I):NEXT        
30 DATA NIMM,GIB,OEFFNE,SCHLIESSE,SCHLAG
E,DRUECKE,RUFE                          
Somit hätten wir uns also das mühsehlige
Auflisten von  Variablenzuweisungen  ge-
spart. Sie müssen doch zugeben, daß fol-
gendes etwas umständlicher wäre :       
10 VE$(0)="NIMM"                        
20 VE$(1)="GIB"                         
30 VE$(2)="OEFFNE"                      
40 VE$(3)="SCHLIESSE"                   
und so fort...                          
Doch  nicht  genug,  in  DATA-Statements
kann man nicht nur Strings ablegen, son-
dern  auch INTEGER- oder FLOAT-Werte und
das dann noch bunt gemischt:            
100 DATA 100,3.14,HALLO,2.689,BASIC,12  
Alles worauf wir dann beim Lesen  achten
müssen,  ist, daß die einzelnen Elemente
auch  den  entsprchenden  Variablentypen
zugeordnet  werden.  Es ist Ihnen ja mit
Sicherheit klar, daß wir  nicht  einfach
so  einen  Text  einer INTEGER-Variablen
zuweisen können oder ähnliches.         
Allerdings  gibt  es noch zwei Besonder-
heiten, die man in Zusammenhang mit DATA
erwähnen muß. Sie  werden  nämlich  ganz
schöne  Probleme  bekommen,  sollten Sie
einmal versuchen, ein Komma (",") in Ih-
ren  Strings  zu verwenden, die bei DATA
abgelegt sind. Wie wir wissen dient  das
Komma ja zur Trennung der einzelnen Ele-
mente, was für den Computer  heißt,  daß
wir  ihm da zwei einzelne Elemente,  an-
statt nur einem  gegeben  haben.  Machen
Sie also niemals folgenden Fehler:      
100 DATA HALLO,IHR!                     
Hier  haben  wir  nämlich   die   beiden
Strings "HALLO" und "IHR" abgelegt, ans-
tatt dem eigentlich gewollten Text "HAL-
LO,IHR!"  In  diesem Fall müssen wir den
abzulegenden String dann ganz einfach in
Anführungszeichen setzen, damit er rich-
tig erkannt wird, also :                
100 DATA "HALLO,IHR!"                   
Und schon bekommen wir auch das, was wir
wollen. Es bleibt noch zu erwähnen,  daß
dies  derselbe  Fall bei dem Doppelpunkt
(":") und bei Leerzeichen (" ") der Fall
ist. Sollten Sie also  einmal  in  einem
Stringelement  ein  Komma, einen Doppel-
punkt  oder  ein  Leerzeichen  enthalten
haben,  so müssen Sie dieses Element UN-
BEDINGT  in  Gänsefüßchen  setzen.   Bei
Strings,  wo  dies nicht zutrifft können
Sie  sie  auch  weglassen  (müssen  aber
nicht).                                 
Das zweite, was noch zu sagen wäre, ist,
daß man manche Datenelemente auch abkür-
zen kann. Das spart zum einen  Speicher-
platz und zum anderen läuft das Programm
dann  später auch schneller ab. Wenn man
nach einem Komma, das  ja  zur  Trennung
der  einzelnen  Datenelemente dient, ein
weiteres Komma  nachstellt,  also  prak-
tisch  KEIN  Datenelement angibt, so in-
terpretiert unser 64er diesen  Datensatz
als  den  Wert  0. Hier ein kleines Bei-
spiel:                                  
100 DATA 200,,,10,,,                    
Diese Zeile entspicht haargenau dem fol-
genden  Ausdruck  und bewirkt auch genau
dasselbe:                               
100 DATA 200,0,0,10,0,0,0               
Der Unterschied  ist,  daß  wir  weniger
Tipparbeit  hatten  und  somit Speicher-
platz gespart haben, UND daß  die  erste
DATA-Zeile  auch  noch schneller abgear-
beitet werden kann - mit einem Wort, nur
Vorteile.                               
Als  Nächstes sollte ich vielleicht noch
erwähnen, daß READ  grundsätzlich  immer
das  ERSTE  Datenelement  aus dem ERSTEN
DATA-Statement zuerst liest. Es ist  da-
bei  egal, WO sie Ihre DATAs im Programm
unterbringen, READ liest  rigoros  alles
durch,  solange  bis es keine Daten mehr
finden kann. Hierauf sollten  Sie  immer
achten, denn sonst kann es zu einem "OUT
OF  DATA ERROR" kommen. Sie sollten auch
wissen, daß READ sich quasi "merkt"  bis
zu welchem Datenelement es schon gelesen
hat.  Dieser  Merkspeicher  ändert  sich
solange nicht, bis Sie das Programm wie-
der  mit  RUN  starten.  Es wird hierbei
also der  Merkspeicher  wieder  auf  das
allererste  Datenelement  zurückgesetzt,
so daß Sie die Daten  wieder  von  vorne
lesen können.                           
Für diese Funktion gibt es übrigens  so-
gar einen eigenen BASIC-Befehl. Er heißt
RESTORE,  was  soviel heißt wie "zurück-
setzen". Er tut haargenau  dasselbe  was
auch  unter  anderem  bei  RUN  passiert
(nämlich  das  Zurücksetzen  des   DATA-
Merkspeichers),  nur  daß Sie ihn mitten
im Programm aufrufen können, ohne  hier-
bei  das Ganze von vorne starten zu müs-
sen. RESTORE braucht übrigens keine  Pa-
rameter.                                
 3.) Die kleinen, aber feinen,   Sonder-
funktionen.                             
----------------------------------------
Im  letzten  Abschnitt  dieses  Artikels
möchte  ich  mich  noch ein wenig um ein
paar  kleine  Sonderfunktionen  kümmern,
die  BASIC  so  bietet.  Diese  kann man
nicht einfach  unter  einem  Überbegriff
zusammenfassen, denn jede Funktion erle-
digt jeweils eine in sich abgeschlossene
Aufgabe. Fangen wir einmal mit einer der
Wichtigsten dieser  Funktionen  an,  der
RND-Funktion :                          
RND  steht  für RaNDom, was soviel heißt
wie Zufall. Mit dieser  Funktion  können
wir  uns  Zufallszahlen  liefern lassen,
wie sie in einer Fülle von Spielprogram-
men  ihre Verwendung finden. Erst einmal
zur Arbeitsweise von RND. Mit  dem  Aus-
druck RND(X) liefert Ihnen der C64 einen
Zufallswert  zwischn  0  und eins, wobei
der Wert von X keine Rolle spielt (X ist
eine Variable). Da man aber meist  wenig
mit  solchen  Dezimalbrüchen  zwischen 0
und 1 anfangen kann, gibt es  auch  eine
besondere  Formel,  mit  denen  man sich
auch ganze Zahlen (also OHNE  Kommastel-
len)  in  einem  vordefinierten Wertebe-
reich abrufen kann. Diese Formel  lautet
folgendermaßen:                         
ZU=INT(RND(1)*Y)+X                      
Wobei  X  für  die untere, und Y für die
obere Zahlengrenze  steht.  Wollten  wir
also  ein  kleines Lottoprogramm schrei-
ben, a la "6 aus  49",  so  müßte  unser
Ausdruck folgendermaßen lauten :        
ZU=INT(RND(1)*49)+1                     
Ich habe hier einmal die Werte von X und
Y  schon  direkt  eingesetzt.  Natürlich
könnten Sie auch unsere allgemeine  For-
mel  benutzen  und vorher in X und Y be-
stimmte Werte festlegen.                
Es sei jedoch noch zu erwähnen, daß  die
Zufallszahlen,  die  RND  liefert  nicht
unbedingt "zufällig" sind. Der 64er  ist
eben  ein  Computer  und bei diesen geht
alles immer korrekt und logisch zu.  Die
Zufallszahlen,  die  RND  liefert werden
deshalb immer auch nach einem bestimmten
Schema berechnet, so daß  es  Ihnen  gut
passieren  kann,  daß  Sie, wenn Sie den
Rechner gerade frisch eingeschaltet  ha-
ben immer dieselben Zufallszahlen erhal-
ten. Probieren Sie das doch einmal aus. 
Lassen Sie sich einmal ein paar Zufalls-
zahlen, direkt nach dem Einschalten  des
64ers ausgeben, schalten Sie dann wieder
AUS  und  EIN,  und rufen Sie wieder mit
RND ein paar Zahlen ab. Sie werden fest-
stellen,  daß  diese haargenau dieselben
sind, die wir vorher  auch  hatten.  Das
kann  höchst  negative  Auswirkungen auf
ein Spiel haben, zumal Sie bei dem  Lot-
tobeispiel von oben immer dieselben Zie-
hungen hätten.                          
Um  dieses  Problem  zu  umgehen gibt es
einen kleinen Trick. Der 64er  verwaltet
nämlich  auch  eine  kleine interne Uhr.
Diese  Uhr  benutzt  zwei  vordefinierte
Variablen,  ähnlich  wie  bei  ST. Diese
Variablennamen dürfen Sie nie für eigene
Zwecke benutzen, da sie vom System  vor-
definierte  Werte  enthalten.  Zum einen
wäre da die interne  Uhr  TI$.  TI$  ist
eine  Stringvariable, wie man zweifellos
erkennen kann. In ihr steht  eine  immer
abrufbereite, interne Uhr zur Verfügung.
Wenn  Sie  also  PRINT TI$  eingeben, so
wird der C64 Ihnen die Zeit, seitdem Sie
ihren Rechner eingeschaltet haben anzei-
gen,  in dem Format HHMMSS, wobei HH für
Stunde steht, MM für Minute und  SS  für
Sekunde.  Möchten  Sie diese Uhr nun auf
einen eigenen Wert setzen, weil Sie  zum
Beispiel die aktuelle Tageszeit in einem
Programm  verwenden  wollen, so kann man
dies mit einer einfachen  Variablendefi-
nition  bewerkstelligen.  Angenommen  es
ist 10 Uhr  42  und  15  Sekunden,  dann
reicht  folgende  Definition  vollkommen
aus:                                    
TI$="104215"                            
Anschließed steht diese Zeit in der  in-
ternen Uhr gespeichert, die die Sekunden
von diesem Zeitpunkt an mitzählt.       
Die  zweite  Variable, die etwas mit der
Uhr zu tun hat, und die wir auch benöti-
gen, um mit RND "richtige" Zufallszahlen
zu  erhalten,  heißt  TI.  Wie Sie sehen
eine numerische Variable.  TI  wird  nun
alle  1/60-Sekunde  vom C64 hochgezählt.
Das wiederholt sich solange bis Sie  TI$
wieder  neu setzen. TI selbst können Sie
nicht verändern. Man kann diese Variable
gut in Programmen  benutzt  werden,  die
ziemlich  genau  arbeiten sollen, jedoch
sei gesagt, daß BASIC wahrscheinlich  zu
langsam  ist, als daß solche Veränderun-
gen von BASIC schnell genug festgestellt
werden könnten. Sie können ja einmal ein
bißchen mit TI herumexperimentieren...  
Es  sei  ebenfalls noch erwähnt, daß die
interne Uhr TI$ sehr, sehr, ungenau ist.
Es ist gut möglich,  daß  sie  innerhalb
von  24 Stunden um eine halbe Stunde (!)
von der wirklichen Zeit abweichen kann. 
Auch  wenn  Sie irgendwelche Operationen
mit Ihrem Diskettenlaufwerk machen, kann
die Uhr gebremst werden. Bei  Disketten-
operationen  wird  sie  nämlich gänzlich
abgeschaltet, so daß die  Zeit,  in  der
die  Floppy  tätig  war  erst  gar nicht
gezählt wurde. Solche Abweichungen  kön-
nen  sich sehr schnell summieren, so daß
die Uhr am Ende total falsch geht.  Also
Vorsicht bei der Benutzung von TI$...   
("richtige" Uhren kann man eigntlich nur
in  Assembler  programmieren,  doch  ich
glaube,  daß  wir  auch schon einmal auf
einer Magic Disk dieses  Problem  einge-
hender Behandelt haben)                 
Nun noch zu der Sache mit  den  Zufalls-
zahlen.  TI spielt dabei eine große Rol-
le. Um praktisch die  internen  Zufalls-
zahlen  "zu mischen" benutzt man nämlich
einfach folgenden Ausdruck:             
X=RND(-TI)                              
Was wir hier als Ergebnis in X  erhalten
kann  ignoriert werden. Wichtig ist, daß
wir nun die Zufallszahlen durcheinander-
geworfen haben, so daß wir ab jetzt sehr
gut mit unserer Allgemeinformel Zufalls-
werte abrufen  können,  die  jetzt  auch
verschieden voneinander sind.           
In  unserer  allgemeinen  Formel für Zu-
fallszahlen zwischen X und Y  ist  Ihnen
bestimmt  der  merkwürdige  Ausdruck INT
aufgefallen. INT stellt  ebenfalls  eine
besondere  Funktion  dar,  dieser Befehl
schneidet nämlich ganz einfach bei einer
Dezimalzahl den Nachkommastellen ab. Das
heißt,   daß   beispielsweise  die  Zahl
2.54873 zu einer einfachen  2  reduziert
wird. Die mit INT erhaltenen Zahlen sind
also  immer  gleich oder kleiner als die
Ursprungszahl. Bei negativen Zahlen  be-
deutet  das,  das  immer  auf die nächst
kleinere Zahl abgeschnitten  wird,  dem-
nach  ist  INT(-2.54873) gleich -3, weil
-3 ja kleiner ist als -2 !              
Ansonsten hätten  wir  da  noch  FRE(X).
FRE(X)  gibt  einem den noch verfügbaren
Basicspeicher an,  wobei  es  egal  ist,
welchen  Wert  X enthält. Allerdings ist
diese Funktion etwas fehlerhaft. Es  ist
quasi unter C64-Kennern ein  alter  Feh-
ler, der schon  von  Anfang  an  im  Be-
triebssystem  enthalten  war, und meines
Wissens niemals geändert wurde. Es benö-
tigt nämlich einer besonderen Formel, um
den  tatsächlichen  freien Speicherplatz
zu  ermitteln.  Geben  Sie  nämlich  nur
FRE(0)  ein, so wird Ihnen Ihr 64er eine
negative Zahl ausspucken, mit der wir im
Endeffekt ja garnichts richtig  anfangen
können.  Um  die wahre Anzahl der freien
Bytes zu erhalten, müssen  Sie  mit  der
folgenden Formel arbeiten :             
PRINT 65538+FRE(0)                      
Nun haben Sie den richtigen Wert.       
Damit sind wir  nun  endgültig  am  Ende
unseres Basickurses angelangt. Ich  ver-
abschiede mich zunächst  von  Ihnen  und
hoffe, Ihnen  die  Programmierung  Ihres
C64  einigermaßen  verständlich   veran-
schaulicht zu haben.                    
                        Ihr Uli Basters 



Valid HTML 4.0 Transitional Valid CSS!