Die Bytes auf dem Monitor

Sichtbare Daten: Das klingt nach digitaler Utopie, nach Cyberspace und ein bisschen nach »Matrix«. Bei der visuellen Wiedergabe binär kodierter Daten stehen Pixel im Zentrum. Lässt sich aus dem Bild des Monitors auf die zugrundeliegenden Daten zurückschließen? Und was hat Karopapier mit einem selbst programmierten Computerspiel aus dem letzten Jahrtausend zu tun?

$1 BIT

Alles, was wir auf Bildschirmen sehen können, findet sich als Nullen und Einsen irgendwo auf den gigabytegroßen RAM-Speicherblöcken unserer Smartphones, Laptops und Desktop-Computer. Deren Displays bilden Speicherinhalte als farbige Punkte auf dem Anzeigegerät ab. Man könnte sagen: Displays visualisieren, was in einem elektronischen Speicher liegt; sie machen Daten für das Auge sichtbar. In diesem Vorgang werden binär gespeicherte Daten in menschenverstehbare Codes übersetzt, etwa in Schrift, Bild oder Grafik von unterschiedlichsten Farben und Formen. Die Bitfolge »01000001« könnte beispielsweise als Buchstabe »A« oder als Farbe  Lila  interpretiert werden.[1] Sind Pixel also Daten in sichtbarer Form?

Die Informationstechnik bevorzugt es, (Speicher-)Inhalt und (Bildschirm-)Darstellung möglichst getrennt voneinander zu behandeln. Üblicherweise stehen im Arbeitsspeicher sehr viele Daten, von denen der Nutzer fast immer nur einen Teil übermittelt bekommen möchte. Die anzuzeigenden Informationen werden in einem eigenen Prozess in Bildpunkt-Farbwerte übersetzt. In animierten Computerspielen geschieht dies 30–60 Mal pro Sekunde, während dies in Textverarbeitungs-Programmen eher dann geschieht, wenn der Nutzer eine Eingabe tätigt. Das hieße allerdings, dass Pixel eben nicht Daten sind, sondern nur eine visuelle Krücke für den Menschen, der nicht imstande ist, einen binären Datenstrom zu entziffern.

$2 KARO

Rufe man sich die Mathehefte aus der Schule in Erinnerung, mit dessen Quadratraster es sich hervorragend »Käsekästchen« oder »Tic Tac Toe« spielen ließ. Das Spielgeschehen konnte direkt auf das Karopapier gemalt werden. Das Papier enthielt somit alle Informationen, die für das Spiel notwendig waren – und es stellte sie gleichzeitig dar: Informationstechnisch betrachtet, fallen hier Speicher und Display zusammen. Dies kommt der menschlichen Wahrnehmung entgegen, die allen weismacht, dass eine Information identisch mit einer Abbildung dieser Information sei.

Eine Art Karopapier gibt es auch auf Computern. Dieses nennt sich »Bildschirmspeicher« und enthält für jeden einzelnen Punkt des Bildschirmrasters einen Farb- oder Zeichenwert. Schreibt ein Programm die binäre Zeichenfolge »01000001« in das erste Byte des Bildschirmspeichers, erscheint in der linken oberen Ecke des Displays ein lila Bildpunkt oder – je nach Betriebsmodus[2] – der Buchstabe »A«. Es ist aber auch möglich, den Bildschirmspeicher auszulesen, um zu ermitteln, welche Farbe in der linken oberen Ecke aktuell gesetzt ist. Der Bildschirmspeicher lässt sich im Prinzip wie der normale Arbeitsspeicher verwenden – mit dem Unterschied, dass der Speicher physisch mit dem Display gekoppelt ist. Der Bildschirmspeicher funktioniert deshalb exakt wie ein Karoheft: Jede Information, die dort eingetragen wird, ist sofort auch sichtbar.

In der Praxis adressiert man beim Programmieren den Bildschirmspeicher nur selten direkt. Zu unterschiedlich sind die möglichen Displays, und daher überlässt man die Verantwortung für den Bildschirmspeicher besser den Systemprogrammen. Meistens zumindest.

$3 TRON

Im Jahr 1998 habe ich auf meinem PC eine Variante des Spiels »Lightcycles« implementiert. Wer das Spielprinzip noch nicht kennt, hier die Story: Mehrere Motorradfahrer treten gegeneinander in einer Arena an. Alle starten gleichzeitig. Auf den Fahrspuren, direkt hinter den Motorrädern, entstehen undurchdringbare Wände aus Licht. Wer gegen eine Wand fährt, zerschellt und scheidet aus. Niemand kann anhalten. Wer als letzter übrig bleibt, gewinnt. Das Spiel ist ein Element aus dem Hollywood-Film »Tron«IMDB aus dem Jahr 1982: Dort kämpfen »Programme« und deren »User« gegeneinander als humanoide Gestalten in einer virtuellen Spielwelt.[3]

https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Tron_light_walls_arcade_style.svg/369px-Tron_light_walls_arcade_style.svg.png
So könnte ein Screenshot aus dem Spiel »Lightcycles« aussehen.
Quelle: Wikimedia Commons. Rechte: Bisco/Public Domain.

Wenn man auf 3D-Animationen verzichten kann, lässt sich dieses Spiel selbst auf den einfachsten Computerdisplays (und auch mit Karoheften) prima umsetzen. Das Grafikraster stellt die Arena in der Draufsicht dar. Jedes Fahrzeug startet darin als einzelner Farbpunkt. Bewegt sich ein Fahrer nach oben, unten, links oder rechts, wird dorthin ein neuer Farbpunkt gesetzt. Die zuvor gesetzten Farbpunkte bleiben als Fahrspuren stehen. Wenn man prüfen wollte, ob ein Spieler gegen eine Wand fahren würde, musste man bloß den Farbwert an der nächsten Position überprüfen: Entsprach dieser nicht der Hintergrundfarbe, konnte es ja nur die Wand eines Spielers oder die der Arena sein.

Dieses Verfahren verstößt zwar gegen einen guten Grundsatz. Gleichzeitig ist dieses Verfahren sehr pragmatisch, denn es entlastet Prozessor und Arbeitsspeicher. Man muss lediglich akzeptieren, dass Spielfeldraster und Bildschirmraster 1:1 miteinander verbunden sind. Dann wären Pixel ja tatsächlich Daten aus dem Bildschirmspeicher in visueller Erscheinungsform. Aber heißt das, der Mensch könnte den Inhalt des Bildschirmspeichers rückschließend mit dem Auge ermitteln?

$4 MEM

In der Programmiersprache Turbo Pascal, die ich damals immer noch[4] verwendete, gab es einen Ausdruck, mithilfe dessen man direkt auf den Bildschirmspeicher zugreifen konnte: mem.[5] Das war eine vordefinierte Variable, die direkt mit dem Arbeitsspeicher des Computers gekoppelt war. Man musste noch lediglich die genaue Speicheradresse kennen: Der Bildschirmspeicher lag auf der Adresse »$A000« (das ist die Hexadezimalschreibweise für das 40.960ste Byte des Arbeitsspeichers). Dessen erstes Byte erreichte man mit mem[$A000:0], es entsprach dem oberen linken Punkt des Bildschirms. Mit mem[$A000:1] adressierte man den nächsten Punkt rechts daneben und so weiter. Bei einer Bildschirmauflösung von 320 Pixel in der Breite begann die zweite Zeile bei $A000:320, die dritte bei $A000:640; der letzte Punkt rechts unten war schließlich $A000:63999. Damit ließ sich jeder Punkt des Bildschirms an den Koordinaten (x|y) anhand der Formel mem[$A000:320*y+x] auslesen oder zuweisen.

Dazu ein kurzes Code-Beispiel: Wenn man den gesamten Bildschirm in mit einer bestimmten Farbe ausfüllen wollte, konnte man mithilfe einer simplen For-Schleife alle 64.000 Bytes des Bildschirmspeichers mit demselben Wert beschreiben.

Mit einer For-Schleife und der mem-Variable lässt sich der Bildschirm in einer beliebigen Farbe füllen.

$5 VGA

Nun musste man aber noch die richtige Farbcodierung kennen. Der damals verbreitete Standard nannte sich VGA (Video Graphics Adapter). Dort standen auf einer sogenannten »Palette« 256 vordefinierte Farben zur Verfügung, die in drei Gruppen geteilt waren: a) 16 Grundfarben, b) eine Grauskala mit 16 Abstufungen und c) eine Reihe von 24 Farben aus dem Farbenkreis mit verschiedenen Helligkeits- und Sättigungsstufen. Die letzten acht Einträge blieben undefiniert.[6]

Die Standardfarben des VGA-Modus 13.

In den Bildschirmspeicher wurde keine Farbe geschrieben, sondern eine Ordnungszahl, die auf diese Farbpalette verwies. Das sparte etwas Speicher, denn für den Verweis auf einen Eintrag der Farbtabelle brauchte es lediglich 8 Bit (28 = 256). Für die Beschreibung der Palettenfarbe standen indessen 18 Bit zur Verfügung: Für jeden Farbkanal des menschlichen Auges (Rot, Grün, Blau) waren 6 Bit reserviert, das heißt jeweils 26 = 64 mögliche Abstufungen. Beispiel: Ein dunkles Lila, das an sechster Stelle steht, würde man hier mit der adressieren können (die 0 zählt mit!). In der Palette steht der RGB-Farbwert »101010 000000 101010«: etwas Rot + kein Grün + etwas Blau = dunkles Lila.

Die Farbpalette konnte man selbst ändern, denn die vorgegebenen Palettenfarben waren lediglich als Vorschlag für Standardanwendungen intendiert. Insgesamt konnte man also 256 von 262.144 möglichen Farben für die Palette auswählen.

Insofern hängt zwischen dem Binärcode des Bildschirmspeichers und der Darstellung auf dem Display noch einiges an Übersetzungsschritten. Die Daten aus der Abbildung wieder zu rekonstruieren ist jedoch ohne die Kenntnis der Palette nicht möglich, da die Farben auf dem Bildschirm nicht eindeutig einer Ordnungszahl der Palette zuordenbar sind.[7]

$6 RUN

Die letzte Version meines Spiels stammt dem Anschein nach vom 7. Januar 1998. Ich versuchte, das über 20 Jahre alte Programm wieder zum Laufen zu bekommen. Der erste Versuch schlug erwartungsgemäß fehl, denn aktuelle Systeme können sehr alten Code nicht aus dem Stand starten. Ein sogenannter Emulator half jedoch: Die »DOSbox« ist eine Anwendung, die so tut, als wäre sie ein Computer, auf dem das alte Betriebssystem MS-DOS läuft.[8] Nachdem ich eine Dateipfade angepasst hatte, ließ sich der Programmcode anstandslos kompilieren und starten.[9] Voilà:

Startbildschirm des Spiels »Thron«.
Szene aus dem Spiel »Thron«.

Da erschienen sie also wieder, die gepixelten Fahrspuren, die schnurgerade in rechten Winkeln über das Display wuchsen, bunt wie mit Filzern auf Karopapier gemalt. Was repräsentieren die einzelnen Bildpunkte des Displays? Was können sie repräsentieren? Es sind Versuche, aus gespeicherten Daten eine menschenverstehbare Abbildung zu erzeugen. Der Blick durch den Pixel auf den Boden der Datenmatrix bleibt dem menschlichen Auge jedoch verwehrt. Auf älteren Systemen kommt man mit relativ einfachen Mitteln noch relativ nahe heran. Das unmittelbare Verhältnis von Information und Darstellung, wie man es vom Buch kennt, löste sich in der Geschichte des Computers nicht schlagartig, aber allmählich auf. Aber wo liegt dann die Wahrheit? Liegt sie im Binärcode? Ist sie das, was auf dem Bildschirm erscheint? Oder ist es schlussendlich die Logik, die zwischen Speicher und Bildschirm übersetzt?


Referenzen

[1] Im American Standard Code for Information Interchange (ASCII) steht die Binärzahl »01000001« (im Zehnersystem die 65) für den Buchstaben A. Im 8-Bit-Farbraum hingegen geben die ersten drei Binärziffern (010) den Rotanteil an, die nächsten drei (000) den Grünanteil und die letzten beiden (01) den Blauanteile: Die Mischung (010 Rot + 000 Grün + 01 Blau) ergibt ein dunkles Lila.

[2] Man unterscheidet zwischen Textmodus und Grafikmodus. Im Grafikmodus kann man mit einzelnen Bildpunkten arbeiten, während im Textmodus die kleinste Einheit ein Schriftzeichen ist.

[3] Zum Design des Films und dessen Rezeption in der Kinogeschichte siehe Glen Helfans: »Tron’s 20th Anniversary. Director discusses groundbreaking computer animated film«, in: SFGate, 9. Januar 2002, zuletzt aktualisiert am 10. Februar 2012. (URL | Wayback Machine 06.10.2020)

[4] Turbo Pascal stand uns im Informatikunterricht zur Verfügung und war damals schon etwas in die Jahre gekommen. Die letzte Version (7.01) stammt aus dem Jahr 1993. Nachfolger wurde Borland Delphi, das bereits für windowsbasierte Betriebssysteme ausgelegt war.

[5] Siehe »Direct memory access«, in: Turbo Pascal Language Guide, Scotts Valley: Borland 1992, S. 230. (URL | Wayback Machine 17.02.2020)

[6] Vgl. Kevin Matz: »Introduction to VGA Graphics Programming Using Mode 13h«, in: Atrevida Game Programming Tutorials, 4. Juni 1997. (URL | Wayback Machine 05.02.2020)

[7] Auf moderneren Systemen wäre zudem das →Subpixel-Rendering zu berücksichtigen, das hier vernachlässigt wurde.

[8] Für die Programmierumgebung Turbo Pascal steht ein Emulations-Paket mit DOSBox zur Verfügung; siehe Luu Nguyen Thien Hau: »Turbo Pascal with DOSBox«, Sourceforge, letztes Update vom 13. April 2020 (URL | Wayback Machine 18.06.2020).

[9] Ich war recht erstaunt, wie viele zusätzliche Spielmöglichkeiten ich damals eingebaut hatte. Wer es gerne selbst mal ausprobieren möchte: Ich habe den originalen Turbo-Pascal-Code auf GitHub veröffentlicht.


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.