Teil 20 „The ZX81 Printer“

Der C-Kurs
Antworten
Benutzeravatar
bodo
User
Beiträge: 319
Registriert: 14.02.2007, 17:21
Kontaktdaten:

Teil 20 „The ZX81 Printer“

Beitrag von bodo » 02.01.2011, 13:25

C für BASIC-Programmierer

Arbeiten mit dem z88dk Cross-Compiler

von Jens Sommerfeld und Bodo Wenzel

Teil 20

Und wieder einmal werden wir ein Kapitel aus Vickers' Handbuch missbrauchen: „The ZX81 Printer“. Denn nach den bisherigen Erkenntnissen können wir nicht direkt aus C heraus drucken.

Aus C heraus drucken

Moment, eben hieß es doch noch anders?! Nun ja, mit den Erkenntnissen aus Teil 13 können wir das auch dem BASIC überlassen! Der zu druckende Text wird dazu in eine BASIC-Stringvariable geschrieben, und dann wird eine BASIC-Zeile mit dem passenden LPRINT-Befehl aufgerufen. „Ach so, so geht das!“ Jedenfalls theoretisch, bitte erzählt von euren Ergebnissen im Forum.

Damit hätten wir der Überschrift Genüge getan... ;-)

Variantenreiche Ausgabe – der VT/ANSI-Emulator

Oh je, was heißt das denn schon wieder? Nun, so wird das in der z88dk-Dokumentation genannt, was wir euch heute vorstellen wollen. Es handelt sich nämlich um einen „Treiber“ für Textausgabe, und hier kommt jetzt die Erläuterung der einzelnen Kürzel und Begriffe:
  • VT Dies ist die Abkürzung für Video Terminal, als Teil der Bezeichnung von Computerterminals des Herstellers DEC, in unserem Fall das VT100.
  • ANSI Dies ist die Abkürzung für American National Standards Institute, dem amerikanischen Pendant zum DIN. In diesem Fall ist aber der Satz von Steuerzeichen gemeint, um den es hier geht.
  • Emulator Unser ZX81 ist ja kein VT100, aber er soll so tun, als wäre er eins. Und wenn eine Hard- und/oder Software etwas nachahmt, nennt man das Emulation (http://de.wikipedia.org/wiki/Emulator).
Die z88dk-Macher waren so freundlich, in einer Variante des HRG-Treibers auch eine Textausgabe vorzusehen, die bestimmte Steuerzeichen erkennt und dementsprechend Text auf den Bildschirm zeichnet. Um das Rad nicht neu zu erfinden, haben sie auf einen bekannten Standard (http://inwap.com/pdp10/ansicode.txt) zurückgegriffen, der auch auf dem VT100 implementiert wurde.

Um euch Appetit zu machen, ist hier ein kleines Testprogramm, das ein paar der Fähigkeiten zeigt:

Code: Alles auswählen

#include <graphics.h>
#include <stdio.h>

int main(void) {
    clg();

    puts("\033[10;11H\2334mUnterstreichen geht!\2330m");
    puts("\23320;41H\033[7mInvertieren geht auch.\033[0m");

    return 0;
}
Wenn ihr das Programm compiliert, müsst ihr statt der Option „+zx81“ die Option „+zx81ansi“ verwenden. Und natürlich dürft ihr nicht „-startup=3“ oder einen anderen Grafikmodus vergessen, denn den Emulator gibt es nur in HRG! Die Kommandozeile lautet demnach z.B.:

Code: Alles auswählen

zcc +zx81ansi -vn -Wall -create-app -startup=3 -lgfx81hr192 CfBASIC_20-1.c -o CfBASIC_20-1.bin
Bevor wir es vergessen: es wird ein Zeichensatz mit 4 Pixeln Breite und 8 Pixeln Höhe benutzt, so dass wir 64 Zeichen in 24 Zeilen ausgeben können. Der Zeichensatz lässt sich ohne weiteres nicht ändern, laut der z88dk-Dokumentation geht es aber durch erneute Compilation der HRG-Bibliothek. Das ist nur etwas für echte Profis!

Zunächst einmal können wir jetzt alle 96 Zeichen des ASCII-Zeichenvorrats verwenden. Dabei sind Groß- und Kleinbuchstaben, Ziffern, alle wichtigen Sonderzeichen, aber keine Umlaute. Von den Steuerzeichen werden die folgenden korrekt erkannt und ausgeführt:

Tabelle: Vom VT/ANSI-Emulator ausgewertete ASCII-Steuerzeichen
20.png
20.png (42.43 KiB) 2771 mal betrachtet
Das war der einfache Teil, jetzt wird's etwas schwieriger – aber eigentlich auch doch nicht. Irgendwie müssen wir ja jetzt dem VT100 (ja, ja, dem Emulator...) mitteilen, was wir von ihm wollen. Dazu wird ein spezielles Zeichen verwendet, das im ASCII den hübschen Namen ESC (Code 0x1B, dezimal 27; ESC ist die Abkürzung von Escape, das heißt auf deutsch Flucht. Dazu gibt es eine nette kleine Geschichte. Ein Editor auf dem Atari ST reagierte auf das Drücken der ESC-Taste mit einer Box, in der stand: „Flüchten? Weshalb, wohin?!) trägt. Der deutsche Name dafür heißt Fluchtzeichen, und mit diesem Zeichen wird ein Befehl an das VT100 eingeleitet. Die folgenden Zeichen werden also nicht ausgegeben!

Interessanterweise gibt es zwei Alternativen für die Einleitung eines Befehls:
  1. ESC und '[': Mit diesen beiden Zeichen werden die Befehle üblicherweise in der Dokumentation dargestellt. Diese Kombination ist für Datenkanäle geeignet, die nur 7 Bit eines Zeichens übertragen – ja, so alt ist das Ganze!
  2. 0x9B, dezimal 155: Dies ist das Zeichen ESC, aber mit gesetztem achten Bit. Auf dem ZX81 können wir das benutzen, um je Befehl ein Byte zu sparen.
Wenn ihr dieses Zeichen in C angeben wollt, empfehlen wir die oktale Kodierung \233 (siehe Teil 11, Tabelle 1). Diese könnt ihr sowohl als Einzelzeichen ('\233') als auch als Zeichen in einem String ("\233")benutzen.

Das eigentliche Befehlszeichen kommt als letztes! Wie so häufig bei „richtigen“ Computern wird hier zwischen großen und kleinen Buchstaben unterschieden. Zwischen dem Befehlsanfang und dem Befehlszeichen können Parameter stehen, häufig gibt es sinnvolle Defaults. Von den vielen Befehlen des echten VT100 kann der Emulator im z88dk allerdings nur die folgenden Befehle:
  • Befehl 'm', Parameter Art: Zeichenattribut setzen, die Art wird durch eine Ziffer angegeben:
    • 0 = normal (alle Attribute aus)
    • 4 = unterstrichen
    • 7 = invertiert
  • Befehl 'A', Parameter Anzahl: Cursor um Anzahl Zeilen nach oben stellen; Anzahl ist optional, der Default ist 1.
  • Befehl 'B', Parameter Anzahl: Cursor um Anzahl Zeilen nach unten stellen; Anzahl ist optional, der Default ist 1. Dummerweise ist dieser Befehl fehlerhaft implementiert, der Cursor landet immer in der untersten Zeile. :-(
  • Befehl 'C', Parameter Anzahl: Cursor um Anzahl Zeichen nach rechts stellen; Anzahl ist optional, der Default ist 1.
  • Befehl 'D', Parameter Anzahl: Cursor um Anzahl Zeichen nach links stellen; Anzahl ist optional, der Default ist 1.
  • Befehl 's': Aktuelle Cursorposition retten, um sie mit 'u' wiederherstellen zu können.
  • Befehl 'u': Durch 's' gespeicherte Cursorposition wiederherstellen.
  • Befehl 'H', Parameter Zeile;Spalte: Cursor an die Position Zeile und Spalte setzen. Vorsicht, die Zeile wird dabei von 0 bis 23 nummeriert, die Spalte aber von 1 bis 64!
  • Befehl 'b': Löscht vom Anfang des Bildschirms bis zum Cursor. Leider stürzt der Zeddy bei diesem Befehl ab...
  • Befehl 'J', Parameter Bereich: Löscht einen Teil des Bildschirms, Bereich gibt als Ziffer an welchen Bereich:
    • 0 = von der aktuellen Cursorposition bis zum Ende des Bildschirms (Leider hat das z88dk hier den Fehler, dass nur jede zweite Zeile gelöscht wird.)
    • 1 = vom Anfang des Bildschirms bis zur aktuellen Cursorposition (Leider stürzt der Zeddy hierbei auch ab...)
    • 2 = den ganzen Bildschirm (Das geht auch einfacher mit '\f'.)
  • Befehl 'o': Löscht vom Anfang der Zeile bis zur aktuellen Cursorposition einschließlich.
  • Befehl 'K', Parameter Bereich: Löscht einen Teil der Zeile, in der der Cursor steht, Bereich gibt als Ziffer an welchen Bereich:
    • 0 = von der aktuellen Cursorposition bis zum Ende der Zeile
    • 1 = vom Anfang der Zeile bis zur aktuellen Cursorposition
    • 2 = die ganze Zeile
  • Befehl 'l', Parameter Anzahl: Löscht Anzahl Zeilen ab der Zeile, in der der Cursor steht. Die darunter stehenden Zeilen werden hochgeschoben. Anzahl ist optional, der Default ist 1.
Eigentlich könnten wir hier jetzt die Zeichenketten des Beispielprogramms im Detail erläutern. Aber der Lerneffekt ist sicher größer mit ...

Hausaufgaben
  1. Erläutert die Zeichenketten des Beispielprogramms. Wenn ihr Schwierigkeiten habt, teilt ihr die Zeichenkette in einzelne Zeichen und versucht dann, VT100-Befehle und tatsächlich auszugebende Zeichen zu identifizieren.
  2. Schreibt ein Programm, mit dem ihr über die Cursortasten ('5' bis '8') einen Stern (das Zeichen '*') über den Bildschirm steuern könnt. Dabei soll die Bewegung an den Rändern durch das Programm gestoppt werden.
B0D0: Real programmers do it in hex.

Antworten