Info
Sammeln
Dokumentation
Anleitungen
Schnittstellen
Prozessoren
Videochips
Soundchips
Computer
Videospiele


KC85-Basic, Teil 2
4. Ein- / Ausgabe

4.1 Textausgabe auf dem Bildschirm


PRINT
PRINT [<Ausdruck>[;|,[<Ausdruck>]][...]]

Der PRINT-Befehl ermöglicht die Ausgabe beliebiger Informationen auf den Bildschirm Als <Ausdruck> können Sie entweder Strings, Stringvariablen oder numerische Ausdrücke angeben, wobei letztere vor der Ausgabe ausgerechnet werden. Werden zwei Ausdrücke durch Semikolon getrennt, hängt sie der Printbefehl direkt aneinander. Ein Komma als Trennzeichen lässt eine Lücke. Komma oder Semikolon können auch am Ende des Printbefehls stehen, sie wirken sich darauf aus, wie die Ausgabe des nächsten Printbefehls angefügt wird.
Ein PRINT-Befehl alleine bewirkt einen Zeilenvorschub, d.h. der darauf folgende PRINT-Befehl beginnt mit der Ausgabe eine Zeile tiefer.
Es gibt noch einige weitere Möglichkeiten, die den PRINT-Befehl noch universeller machen:
Die Funktion TAB ermöglicht eine tabularische Ausgabe, indem sie die nächste horizontale Ausgabeposition auf die als Argument angegebene Spaltennummer setzt. Natürlich kann das nur funktionieren, wenn die nächste Ausgabeposition vor dem Aufruf von TAB noch links der angegebenen Spalte gewesen wäre.
100 PRINT "NAME";TAB(8);"PUNKTE"
110 PRINT "KLAUS";TAB(8);"15"
120 PRINT "SANDRA";TAB(8);"18"
130 PRINT "PAUL";TAB(8);"9"
140 PRINT "MARGARETHE";TAB(8);"10"

Das Beispielprogramm produziert folgende Ausgabe:
NAME PUNKTE
KLAUS 15
SANDRA 18
PAUL 9
MARGARETHE10

Die letzte Zeile zeigt, daß durch den langen Namen die Punktzahl bei Margarethe nicht mehr auf die Tabulatorposition 8 geschrieben werden kann.
Die SPC-Funktion fügt in der Printanweisung die angegebene Anzahl Leerzeichen ein:
100 PRINT " ";STRING$(28, "-")
110 FOR I=1 TO 18
120 PRINT "|";SPC(28);"|"
130 NEXT I
140 PRINT " ";STRING$(28, "-")

Dieses Beispiel zeichnet einen 30 Zeichen breiten und 20 Zeichen hohen Rahmen.

PRINT AT
PRINT AT(<zeile>,<spalte>);<ausdruck>[,[<ausdruck>]]...

Mit PRINT AT beginnt die Ausgabe an einer vorgegebenen Bildschirmposition. Ansonsten funktioniert PRINT AT genauso wie PRINT - allerdings sind mehrere Ausdrücke durch Komma zu trennen, das Semikolon ist hier nicht erlaubt.

POS
POS(0)

Die Funktion POS liefert die Spaltenposition, an der die nächste Ausgabe mit PRINT beginnen würde. Das Argument der POS-Funktion ist ohne Bedeutung und wird normalerweise auf 0 gesetzt.

CLS

Löscht den Bildschirm

WINDOW
WINDOW [<erstezeile>, <letztezeile>, <erstespalte>, <letztespalte>]

WINDOW schränkt den mit PRINT und INPUT nutzbaren Bildschirmbereich auf ein rechteckiges Fenster ein. WINDOW ohne Parameter hebt die Einschränkung wieder auf.
Der Bereich außerhalb des Fensters bleibt unverändert.

PAPER, INK, BORDER
PAPER <farbnummer>
INK <farbnummer>
BORDER <farbnummer>

Mit diesen Befehlen legen Sie die Hintergrund-, Text- bzw. Rahmenfarbe fest. Die Farbnummer muß in jedem Fall zwischen 1 und 8 liegen, wobei folgende Zuordnung gilt:
1 schwarz 3 grün 5 blau 7 blaugrün
2 rot 4 gelb 6 pink 8 weiß


PRINT mit Farbangabe
PRINT [INK <farbnummer>[,]][PAPER <farbnummer>][;AT(...)];...

Auch direkt bei einem PRINT-Befehl kann die Text- oder Hintergrundfarbe (oder beide) festgelegt werden. Diese gelten dann jedoch nur für diesen einen Befehl. Auch die Kombination mit PRINT AT ist machbar:
PRINT INK 2;AT(5,10);"*"

...schreibt in die 5. Zeile in der 10. Spalte ein rotes Sternchen.

4.2 Eingaben über die Tastatur


INPUT
INPUT ["<Ausgabetext>",]<Variablenname>[,<Variablenname>][...]

Falls angegeben, schreibt der INPUT-Befehl zuerst den Ausgabetext auf den Bildschirm, gefolgt von einem Fragezeichen und dem Eingabecursor. Ohne Ausgabetext produziert INPUT nur ein Fragezeichen und den Cursor. Der Programmbenutzer muß nun die Werte für die angegebenen Variablen in der richtigen Reihenfolge eingeben.
Es ist eine gute Idee, mit jedem INPUT-Befehl nur eine Variable eingeben zu lassen. Das reduziert die Fehleranfälligkeit und gibt Ihnen die Möglichkeit, die Plausibilität jeder einzelnen Eingabe zu prüfen bevor die nächste erfolgt.

INKEY$

INKEY$ prüft, ob über die Tastatur ein Zeichen eingegeben wurde. Wenn ja, enthält INKEY$ dieses Zeichen, andernfalls einen Leerstring. Im Gegensatz zum INPUT-Befehl wartet INKEY$ nicht auf eine Tastatureingabe.
Mit INKEY$ können Sie auf auf Tastendrücke prüfen, denen kein Bildschirmzeichen zugeordnet ist - die Pfeiltasten z.B. oder ESC, DEL und die Eingabetaste. Die Abfrage erfolgt dann über den ASCII-Code:
100 IF ASC(INKEY$)<>13 THEN GOTO 100

Dieses Miniaturprogramm bewegt sich in einer Endlosschleife - Solange bis jemand die Eingabetaste (ASCII-Code 13) betätigt.
Das folgende Programm wartet auf Tastendrücke und zeigt die gedrückte Taste und ihren ASCII-Code:
100 A$=INKEY$
110 IF A$="" THEN GOTO 100
120 IF A$>=" " THEN PRINT A$; " = ";
130 PRINT ASC( A$ )
140 GOTO 100


4.3 Ansteuerung von Peripheriegeräten


4.3.1 Joystick


JOYST
JOYST( 1|2 )

Fragt die Richtung ab, in die der Joystick mit der angegebenen Nummer (1 oder 2) gerade gedrückt wird. Die Rückgabewerte sind folgendermaßen definiert:
9 8 10
\ | /
1--0--2
/ | \
5 4 6

Wird zudem die Feuertaste gedrückt, erhöht sich der Wert um 16.
Die einfachste Abfrageroutine für den Joystick funktioniert über eine bitweise Auswertung:
100 A=JOYST(1)
110 IF A=0 THEN GOTO 100
120 IF (A AND 1) = 1 THEN PRINT "LINKS ";
130 IF (A AND 2) = 2 THEN PRINT "RECHTS ";
140 IF (A AND 4) = 4 THEN PRINT "UNTEN ";
150 IF (A AND 8) = 8 THEN PRINT "OBEN ";
160 IF (A AND 16) = 16 THEN PRINT "FEUER";
170 PRINT
180 GOTO 100

Die Funktion des Joysticks kann auch die Tastatur wahrnehmen. Die Pfeiltasten und die ESC-Taste ermöglichen dies. Die Diagonalbewegungen des Joysticks können Sie durch den Druck von zwei Pfeiltasten gleichzeitig simulieren.
Während der Programmsteuerung mit dem Joystick sollte die Tastatur nicht benutzt werden. Sollte nach der Benutzung des Joysticks die Tastatur nicht mehr richtig funktionieren, drücken Sie entweder die "GRAPHIC"-Taste oder eine der Tasten 1 bis 8.

4.3.2 Drucker

Um einen Drucker am KC85 verwenden zu können, benötigen Sie ein Druckermodul.
Ausdrucke können Sie auf verschiedene Arten erzeugen: Im Direktmodus drücken Sie einfach CONTR und P gemeinsam und jede Bildschirmausgabe geht dann zusätzlich auch an den Drucker. Der gleiche Tastendruck beendet den Spuk wieder.
Eine Bildschirmhardcopy erzeugen Sie durch Druck auf CONTR zusammen mit N.
Beide Funktionen können Sie natürlich auch im Programmbetrieb aufrufen. Die Ausgabeumlenkung aktivieren und deaktivieren Sie mit PRINT CHR$(16) und die Hardcopy starten Sie mit PRINT CHR$(14).

4.4 Grafik

4.5 Tonerzeugung


BEEP

BEEP erzeugt einen kurzen Signalton.
5. Fortgeschrittene Programmierung


5.1 Programme testen

Wenn ein Programm nicht so läuft, wie Sie es sich als sein Schöpfer eigentlich gedacht hatten, werden Sie sich sicher schnell etwas Unterstützung bei der Erziehung des mißratenen Sprößlings wünschen. Ein sehr wirksamer Weg ist die Verwendung von TRON und TROFF, die eine permanente Überwachung der Aktivitäten des laufenden Programms ermöglichen.

TRON, TROFF

TRON schaltet die Programmverfolgung ein, TROFF schaltet sie wieder aus. Bei aktiver Programmverfolgung wird die Zeilennummer jeder abgearbeiteter Programmzeile angezeigt. So sehen Sie, welche Wege der Interpreter in Ihrem Code einschlägt und finden so auch sicherlich heraus, an welcher Stelle das Programm aus dem Ruder läuft.
Nähere Analysen können Sie dann mit Hilfe des STOP-Befehls betreiben.

5.2 Manipulation von Speicherstellen

Die meisten Basicdialekte ermöglichen die Manipulation beliebiger Speicherstellen des Arbeitsspeichers. So auch das Basic des KC85. Während das Auslesen des Speicherinhalts noch recht ungefährlich ist, müssen Sie bei der Veränderung schon sehr genau wissen, was Sie tun.

POKE
POKE <adresse>,<wert>

POKE schreibt an der angegebenen Adresse den Wert (1 Byte) in den Arbeitsspeicher. Die Adresse muß im Bereich von -32768 bin 32767 liegen, wobei bei den negativen Werten im Geiste 65536 hinzugezählt werden muß.

DOKE
DOKE <adresse>,<wert>

Der "Doppel-POKE" schreibt einen 2-Byte-Wert an die angegebene Adresse und die darauf folgende.

PEEK
PEEK( <adresse> )

Die Funktion PEEK liefert den Inhalt der angegebenen Speicherstelle.

DEEK
DEEK( <adresse> )

DIe Funktion DEEK liefert den Inhalt der angegebenen und der darauf folgenden Speicherstelle als 2-Byte-Wert.

CALL, CALL*
CALL <adresse>
CALL* <hexadresse>

CALL ruft ein Maschinenspracheprogramm ab der angegebenen Adresse auf.

USR
USR( <parameter> )

Die USR-Funktion ist eine benutzerdefinierbare Maschinensprachefunktion. Um sie aufrufen zu können, müssen Sie jedoch zunächst festlegen, ab welcher Position im Arbeitsspeicher das aufzurufende Maschinenprogramm abgelegt ist. Dies machen Sie am besten mit einem DOKE-Befehl, und zwar beim RAM-Basic in Speicherstelle 11012 und beim ROM-Basic in Speicherstelle 772.
Der Parameter kann vom Maschinenprogramm ausgewertet werden.

OUT, INP, WAIT
OUT <adresse>,<wert>
INP( <adresse> )
WAIT <adresse>,<wert1>[,<wert2>]

OUT beschreibt die angegebene I/O-Adresse mit einem bestimmten Wert. Mit INP() können Sie den Wert einer I/O-Adresse auslesen und mit WAIT auf ein Ereignis an einem I/O-Port warten.
I/O-Adressen sprechen direkt bestimmte Funktionen auf den Ein-/Ausgabechips des Computers an. Eine wichtige I/O-Adresse ist z.B. 136. Dort ist bitweise codiert nicht nur die Farbe des Bildschirmrands hinterlegt, sondern auch die Einstellung der Zeilenzahl (20 oder 24 Zeilen), der Grafikmodus und die Aktivierung des Piepsers.

5.3 Programme als Quelltext speichern

Programme werden normalerweise in kodierter Form abgespeichert. Das ist keine Sicherheitsmaßnahme sondern ganz einfach die interne Darstellung des Programmtextes und mithin die schnellste und einfachste Methode, das Programm zu laden und zu speichern.
Falls Sie ein Basicprogramm auf ein anderes Rechnersystem übertragen wollen, sollte das Programm jedoch im Klartext vorliegen. Mit dem Befehl LIST# können Sie dies bewerkstelligen und mit LOAD# ein solches Programm auch wieder laden.

LIST#, LOAD#
LIST#<gerät>"<dateiname>"
LOAD#<gerät>"<dateiname>"

LIST# sendet das Programm im Arbeitsspeicher unter dem angegebenen Namen auf das angegebene Gerät. Als Gerät sind die Nummern 0 (Bildschirm) und 1 (Datenrekorder) zulässig.
LOAD# lädt ein mit LIST# gespeichertes Programm wieder ein.

NULL
NULL <anzahl>

Mit NULL legen Sie fest, wieviele Nullzeichen am Ende jeder Zeile bei der Ausgabe per LIST# angehängt werden sollen. Diese Nullzeichen sind beim Einlesen mit LOAD# wichtig, da hierbei jede Zeile einzeln in den Arbeitsspeicher geschrieben werden muß, was jedesmal einen winzigen Moment dauert. Falls in diesem Moment der Datenrekorder bereits mit dem Senden der nächsten Zeile beginnt, schlägt das Einladen des Programms fehl. Wenn genügend Nullzeichen vorhanden sind, reicht die Zeit bis zum Beginn der Übertragung der nächsten Zeile aus. Der optimale Wert für NULL muß experimentell ermittelt werden.