64'er

VDC - 80 Zeichen ist nicht alles

Teil 3 (64'er 07/87)

Wissen Sie eigentlich, wozu die ganzen Register im VDC gut sind und was damit alles gemacht werden kann? Der dritte Teil unserer kleinen Artikelserie sagt Ihnen alles, was Sie über die VDC Register wissen müssen.

Mit den Registern haben wir im letzten Teil dieser Artikelserie in Ausgabe 5/87 begonnen. Hier ist die Fortsetzung mit den restlichen VDC-Registern. Wir hoffen, daß Ihnen die hier vorgestellten Tricks helfen, den VDC besser zu beherrschen.

Register 8: Anzeigeform
Ausgangswert: 252 ($FC)

Von diesem Register können nur die Bits 0 und 1 angesprochen werden, die anderen sind immer auf "1" gesetzt. Wenn Bit 0 den Wert "0" hat, also den Normalzustand besitzt, wird kein Zeilensprung (so steht es im C 128-Handbuch) ausgelöst. Ansonsten kann durch Bit 1 dieser Zeilensprung verdoppelt werden. Dies führt zu mittlerem Chaos, der Bildschirm sieht so aus, als ob alle Zeilen gegeneinander verschoben wären:

BANK 15:SYS DEC("CDCC"),3,8

Durch folgendes wird ein Zittern ausgelöst:

BANK 15:SYS DEC("CDCC"),1,8

Vielleicht mag es den einen oder anderen stören, daß ich hin und wieder auch Hinweise gebe, wie man den VDC in Unruhe versetzt. Dies ist aber nicht nur eine Spielerei, sondern soll zeigen, wie unerforscht der VDC noch ist - diese Artikelserie versucht, einen Teil der Geheimnisse des VDC zu entschleiern, wozu eben auch solche Gags gehören.

Register 9: Zeichenlänge
Ausgangswert: 231 ($E7)

Technisch gesehen, handelt es sich um die Anzahl der Rasterzeilen pro Zeichen-1. Durch den Wert 230 wird die unterste Zeile eines Zeichens geschluckt, das heißt von der obersten Zeile des nächsten Zeichens überlagert. Andere Werte ergeben keinen rechten Sinn.

Register 10: Cursor-Darstellung
Ausgangswert: 160 ($A0)

Dieses Register hat ein immer gesetztes Bit 7 und ist ansonsten in zwei Abschnitte eingeteilt, die beide mit dem Cursor zusammenhängen: Bit 5 und 6: Blinkmodus des Cursors

Die Kombination "00" steht für einen starren Cursor, "01" für einen ausgeschalteten, "10" für einen schnell blinkenden und "11" (Normaleinstellung) für einen langsam blinkenden Cursor. Die Bits 5 und 6 bewirken also folgende Werte:
Cursor ist starr (Festcursor) = 0
Cursor ist aus (kein Cursor) = 32
Cursor blinkt schnell = 64
Cursor blinkt langsam (normal) = 96
Bit 0 bis 4: Start des Cursors in Zeichen

Bei einem Strichcursor kann in diesen Bits der Start innerhalb der Punktmatrix des Zeichens unter dem Cursor festgehalten werden. Die Werte "0" bis "7" sind möglich, "0" ist der Ausgangswert (in unterster Zeile geht's los). Den gesamten Wert für diese Adresse erhält man aus:

128 + Blinkmodus (0, 32, 64, 96) + Cursorstart (0 bis 7)

Beispiel: 128 + 64 + 2 ergibt einen schnell blinkenden Strichcursor, der relativ dick ist. Der so ermittelte Wert muß nach 2603 ($0A2B) im Hauptspeicher (BANK 15) geschrieben werden; auslesen muß man ihn aber von der Originalquelle, also aus Register 10 des VDC. Ein Schreibzugriff hat deshalb keine Wirkung, weil im Systeminterrupt das Register 10 an 2603 ($0A2B) angeglichen wird.

Ähnliches kennen Sie vielleicht vom VIC-Register 18.

Register 11: Cursorende
Ausgangswert: 231 ($E7)

Dieses Register, dessen oberste drei Bits immer gesetzt sind, gibt die Endmatrixzeile des Cursors im Zeichen an. Beim Ausgangswert für den Blockcursor reicht dieser also von Zeile 0 (siehe Register 10) bis 7 (Low-Byte von $E7), überdeckt also das gesamte Zeichen. Der Strichcursor hingegen umfaßt nur Zeile 7, da dieser in Register 10 bei Zeile 7 gestartet wird.

Folgende Eingabe ruft einen Strichcursor hervor, der das Zeichen nicht unterstreicht, sondern überstreicht, da er nur Zeile 0 umfaßt:

BANK 15:POKE 2603,128+96+0:SYS DEC("CDCC"),0,11
Erstaunlich, oder?
So gibt es einen Durchstreich-Cursor:
BANK 15:POKE 2603,128+96+3:SYS DEC("CDCC"),4,11

Weitere Beispiele möchte ich hier aus Platzgründen nicht aufzählen, aber Sie sehen, daß man den Cursor innerhalb gewisser Grenzen frei definieren kann.

Registerpaar 12/13: Start des Bildschirmspeichers
Ausgangswert: 0 ($0000)

Wie beim VDC im Gegensatz zjm Prozessor 8502 üblich, enthält das erste Register das High-Byte, während das zweite (hier: Register 13) das Low-Byte aufnimmt. merken Sie sich diese Änderung gut. Für einen geübten Maschinenspracheprogrammierer ist dies eine unbequeme Umstellung.

Solange man das Video-RAM (Bildschirmspeicher) des VDC direkt beschreibt, was uns später interessieren wird, genügt es, hier einen anderen Wert hineinzuschreiben. Verwendet man aber - was wohl der Normalfall ist - die Betriebssystemroutinen, so muß diesen zusätzlich die neue Adresse mitgeteilt werden. Das Low-Byte einer vom Betriebssystem verwendbaren Adresse ist immer 0, das High-Byte steht in Adresse 2607 ($0A2F).

Listing 1 macht davon Gebrauch. Die Zeilen 400 bis 430 verlegen den Bildschirmspeicher (Video-RAM) an die Adresse 4096, ab der zufällig ein freier Platz im VDC-RAM ist (mehr dazu später). Die Zeilen 1000 und 1010 verlegen ihn zurück nach Adresse 0. In 530/540 werden die Funktionstasten und so belegt, daß man mit den ersten und mit den zweiten Bildschirm ansteuert. Eine einfachere Methode gibt es wirklich nicht! Beachten Sie aber, daß das Attribut-RAM, das unter anderem die Farbe jedes Zeichens enthält, nicht umgelagert wird. Dafür finden wir demnächst eine Lösung.

Registerpaar 14/15: Cursorposition im Video RAM
Ausgangswert: - (wird ständig verändert)

Im (ungewöhnlichen) High-Low-Format wird hier die Adresse des Cursors innerhalb des Video-RAMs gespeichert. Diese errechnet sich aus:

Zeile*80 + Spalte

Die Zeilen und Spalten werden von Null an numeriert. Da das Betriebssystem selbsttätig dieses Registerpaar steuert, ist es nur bei Verwendung eigener Ausgaberoutinen von Bedeutung.

Registerpaar 16/17: Lightpen-Position
Ausgangswert: -

Die Kurzbeschreibung im Handbuch soll genügen, da dieses Register im allgemeinen uninteressant ist.

Registerpaar 18/19: Adresse im VDC-RAM
Ausgangswert: -

Da auch das gesamte 16 KByte große VDC-RAM nicht über PEEK und POKE angesprochen werden kann, dienen diese beiden Adressen zur Übertragung von Daten in das VDC-RAM beziehungsweise zum Auslesen von Daten aus diesem.

Dazu schreibt man zunächst das High-Byte der Adresse in Register 18 und das Low-Byte in Register 19. Daraufhin transportiert der VDC den Inhalt dieser Adresse nach Register 31, von wo er auch gelesen werden kann. Schreibt man hingegen einen Wert nach Register 31, so wird dieser in die entsprechende Adresse transportiert. Beim nächsten Mal lernen wir alle Möglichkeiten kennen, die die Manipulation des VDC-RAMs bietet. Für diese Folge nur kurz die Speicheraufteilung (Tabelle 1).

Adressen dezimal    Adressen hexadezimal    Bedeutung
0    - 2047         $0000 - $07FF           Video-RAM
2048 - 4095         $0800 - $0FFF           Attribut-RAM
4096 - 8191         $1000 - $1FFF           unbenutzt (!)
8192 - 16383        $2000 - $3FFF           Zeichensatz

Tabelle 1. Aufbau des VDC RAM

Registerpaar 20/21: Startadresse des Attribut-RAM
Ausgangswert: 2048 ($0800)

Dieses Registerpaar ist vergleichbar mit den Registern 12/13. Das High-Byte wird über die Adresse 2607 ($0A2F) gesteuert. Mit folgendem Befehl könnte man das Attribut-RAM also nach 4096 ($1000) verschieben:

POKE 2607,16

Die genaue Wirkungsweise des Attribut-RAMs ist unter anderem Thema der nächsten Folge.

Registerpaar 22/23: Zeichenformat
Ausgangswerte: Register 22: 120 ($78); Register 23: 232 ($E8)

In Register 22 steht in den Bits 4 bis 7 die Zeichenbreite in Pixel-1, inklusive des horizontalen Zwischenraums.

Die Bits 0 bis 3 enthalten die Zeichenbreite ohne Zwischenraum.

Register 23 ist entsprechend aufgebaut und beinhaltet die Zeichenlänge. Das schon besprochene Register 9 schließlich entspricht den Bits 0 bis 3 von Register 22.

Eine sinnvolle Anwendung ist mir nicht bekannt, was nicht unbedingt heißen muß, daß es keine gibt. Möglicherweise ist Ihnen eine bekannt?

Register 24: Zeichenbreite und Flags
Ausgangswert: -

Durch Ändern der Bits 0 bis 4 kann ein Aufwärts-Scrolling realisiert werden. Dies zeigt folgende Eingabe:

BANK 15:SYS DEC("CDCC"),8,24:FOR F=8 TO 31:SYS DEC("CDCC"),F,24:FOR G=1 TO
15:NEXT G,F

Die Werte 0 bis 7 führen zu Fehlfunktionen und werden deshalb von der Schleife nicht durchlaufen.

In Bit 5 ist eine Angabe zur Blinkfrequenz für die blinkenden Zeichen enthalten (es sei an das Steuerzeichen CHR($15) erinnert). Ist Bit 5 gleich "1", so handelt es sich um den Normalzustand, ansonsten (Bit 5 = "0") blinken die Zeichen doppelt so schnell. Dies zeigt folgende Eingabe, vor deren Betätigung am Bildschirm blinkende Zeichen stehen sollten:

BANK 15:SYS DEC("CDDA"),,24:RREG A:A=A AND 255-32:SYS DEC("CDCC"),A,24

In Bit 6 steht das Reversflag für den gesamten Bildschirm. Wird durch dieser invertiert, so setzt das Betriebssystem das Bit 6 in Register 24, bei wird es gelöscht. Folgende Eingabe invertiert den Bildschirm:

BANK 15:SYS DEC("CDDA"),,24:RREG A:A=A OR 64:SYS DEC("CDCC"),A,24

Das letzte Bit (Bit 7) hängt mit den Blockoperationen im VDC-RAM zusammen, die später besprochen werden.

Register 25: Diverse Steuerzwecke
Ausgangswert: - (hängt auch von VDC-Version ab)

Die Bits 0 bis 3 sind wie die Bits 0 bis 4 im letzten Register zum Scolling vorgesehen, diesmal allerdings nach links. Ist Bit 4 gesetzt, so wird die doppelte Zeilenbreite ausgelöst. Damit müßte es möglich sein, eine Art 40-Zeichen-Modus hervorzurufen, in welchem die Zeichen genau so breit wie beim VIC sind. Allerdings muß man noch andere Parameter angleichen, was mir bislang noch nicht zufriedenstellend gelungen ist. Bitte teilen Sie es uns mit, wenn Sie eine Lösung dafür haben!

Bit 5 löst eine sogenannte Semigrafik-Betriebsart aus. Ist es gesetzt, hat der horizontale Zwischenraum zweier Zeichen die Farbe des Hintergrundes, ist Bit 5 gleich "1", so wird der Zwischenraum mit Zeichenfarbe gefüllt.

Ist Bit 6 mit "0" belegt, wird der gesamte Bilicschirm mit einer einheitlichen Schriftfarbe, die in Register 26 enthalten ist, dargestellt, ansonsten wird die Farbinformation für jedes einzelne Zeichen aus dem Attribut-RAM entnommen.

Am interessantesten ist das siebte Bit. Durch Setzen von diesm wird der VDC in den Grafikmodus versetzt. Wie man diesen programmiert, besprechen wir in der kommenden Folge.

Register 26: Farbregister
Ausgangswert: - (Ändert sich recht häufig)

Im Grafik-Modus kann man hier die Farbeinstellung vornehmen. Die Bits 0 bis 3 enthalten in jedem Fall die Hintergrundfarbe.

Register 27: Adressen-Inkrement pro Zeile
Ausgangswert: 0

Beim Übergang von einer Bildschirmzeile in die andere wird der Inhalt dieses Registers addiert. Ausgegangen wird von 80 Zeichen pro Zeile, bei weniger (zum Beispiel 40) muß hier ein Wert stehen, der einen Ausgleich schafft. Hier muß man probieren, um die richtigen Werte zu finden.

Register 28: Startadresse des Zeichensatzes
Ausgangswert: 8192 ($2000)

Die Bits 5 bis 7 legen die Startadresse fest. Normalerweise ist nur Bit 5 gesetzt. Ein Veschieben des Zeichensatzes ist nicht sinnvoll.

Bit 4 gibt den DRAM-Type (DRAM = Dynamic RAM = dynamisches RAM) an (0 oder 1) und definiert somit die VDC-Version.

Register 29: Position der Unterstreichung
Ausgangswert: 231 ($E7)

Die Bits 0 bis 4 bestimmen, in welcher Zeile der Punktmatrix der Unterstrich steht (normalerweise 7, also unterste Zeile). Dieses Register mag zunächst nutzlos erscheinen, aber wenn Sie Listing 2 ausprobieren (bitte genau wie abgedruckt abtippen und starten!), werden Sie ins Staunen geraten. Dort wird nämlich zunächst der ganze Bildschirm mit unterstrichenen Leerzeichen gefüllt (Zeilen 400/410), dann ein sinnvoller Text ausgegeben (Zeilen 420 bis 450) und schließlich in Zeile 500 bis 550 eine Endlosschleife durchlaufen, in der die Position des Unterstrichs regelmäßig geändert wird. Die Zeile 530 dient der Verzögerung. Nach folgender Änderung rollen die Sriche aufwärts:

540 :PU=PU-1-8*(PU=0)

Wenn man DO/LOOP bei Tastendruck durch EXIT verläßt, hat man einen tollen Effekt zur Aufmachung eines Titelbildes für ein eigenes Pogramm.

Register 30: Zählregister
Ausgangswert: -

Bei Blockoperationen enthält dieses Register die Anzahl der zu verschiebenden oder zu schreibenden Bytes.

Register 31: Datenregister
Ausgangswert: -

Beim Zugriff auf das VDC-RAM (siehe Registerpaar 18/19) haben wir dieses Register schon angesprochen. Im Zusammenhang mit Blockoperationen kann es das Füllbyte enthalten.

Registerpaar 32/33: Startadresse des Blocks
Ausgangswert: -

Bei Blockoperationen steht hier die Startadresse des zu verschiebenden Blocks. Die Blockoperationen werden in der nächsten Folge ausführlich besprochen.

Register 34 bis 36: technische Werte
Ausgangswerte: Register 34: 125 ($7D); Register 35: 64 ($40); Register 36: 245 ($F5)

Diese Register sind programmtechnisch bedeutungslos.

Damit haben wir alle VDC-Register angesprochen. In der nächsten Folge lernen wir noch das VDC-RAM kennen, was uns weitere Möglichkeiten eröffnet. Bis dahin, viel Spaß mit den Tricks aus dieser Folge, wobei Ihnen vor allem der optische Effekt (Listing 2) mit Sicherheit gefallen wird.

(Florian Müller/dm)

Literaturverzeichnis:
Larry Greenly u.a.: Das C 128-Buch, Sybex-Verlag
Schieb, Thrun, Wrobel: C 128 Intern, Data Becker Verlag
Florian Müller: Vom C 64 zum C 128 Tips & Tricks, Markt & Technik Verlag