Bits sparen, Videoprozessor und -controller
Heute wieder ein kleiner Wissenshappen, als Abfallprodukt meiner derzeitigen Beschäftigung mit alten Rechnern.
Was ich in den Achtzigern nicht wusste, war, dass viele Grafikprozessoren der 8 Bit Ära Bits einsparten. Ein 8 Bitter hatte ja mit 64 KByte nicht viel Speicher und selbst mit nur 4 Bits pro Farbe konnte eine ansprechende Grafik dann schon einen größeren Teil des Arbeitsspeichers beanspruchen. Bei meinem CPC war der Grafikspeicher 16 KByte groß, also ein Viertel des Gesamtspeichers, was folgende Modi ermöglichte:
- 640 x 200 in zwei Farben
- 320 x 200 in vier Farben
- 160 x 200 in 16 Farben, jeweils aus einer Palette von 27 frei auswählbar.
Im Allgemeinen ist der Speicherbedarf berechenbar nach PixelX x PixelY * ld(Farben)/8, wobei ld() der Logarithmus zur Basis 2 ist (1 bei zwei, 2 bei vier, 4 bei 16 Farben).
Viele Grafikprozessoren dieser Zeit trennten aber Bitmap und Farben. Es gab einen „Bitmap“-Speicher, der das monochrome Pixelmuster aufnahm und dessen Größe man mittels PixelY*PixelY/8 berechnen konnte und einen Farbspeicher, wobei aber mehrere Pixel jeweils die gleiche Farbinformation hatten. Üblich als Modi waren:
- 8 Pixels in X-Richtung nebeneinander (TMS 9918/9 und Nachfolger)
- 64 Pixels eines Zeichens (8×8) (Spectrum, C64 im normalen Grafikmodus)
- Der C64 hatte noch eine Abwandlung bei dem synchron zum Auslesen der Grafikspeicher verschoben wurde, sodass aus dem Normalmodus der Modus des TMS 9918 wurde, der natürlich dann den achtfachen Speicherbedarf für den Farbspeicher hatte,
Konkret hieß dies: in 8 bzw. 64 Bit sind nur zwei Farben erlaubt, aber in den nächsten 8 / 64 Bit wieder eine andere Kombination. Als ich das zum ersten Mal las, dachte ich mir „da hat aber jemand viel Aufwand betrieben, um auch noch das letzte Bit herauszuquetschen“. Aber beim Nachdenken ist die Idee genial. Es geht ja bei der Grafik meist um zwei Anwendungen. Das eine sind Spiele und das Zweite sind irgendwelche Diagramme entweder geschäftliche oder Funktionsplotter. In Spielen hat man oft monochrome Muster oder feste Texturen wie Wände. Innerhalb eines kleinen Bereiches wechseln die Farben kaum. Ähnlich sieht es bei Nutzgrafik aus, egal ob Tortendiagramme. Ballkendiagramme oder Funktionsplotter – wenn sie nicht schon, um die höchste Auflösung für eine Hardcopy zu haben, monochrom sind, dann kommen auch dort in einem kleinen Bereich maximal zwei Farben vor. Probleme sind nur Spielfiguren, die sich bewegen. Der C64 und TMS 9918 hatten Sprites die vom Videoprozessor bewegt wurden, also konnte er auch die korrekte Farbinformation ausgeben. Beim Spectrum ohne diese Fähigkeit, aber mit einer noch gröberen Farbauflösung scheint Pixelsalat, wo Hintergrundpixel dann abrupt ihre Farbe ändern, üblich gewesen sein und auch das Vermeiden dessen ziemlich aufwendig. Der Lohn. Man kann viel Speicher einsparen. Hier mal eine Berechnung für 320 x 200 Pixel und die gängigen Farben (8 oder 32 Farben gehen nicht geradzahlig in ein Byte und erhöhen so den Aufwand beim Schreiben und Auslesen)
Auflösung | Farben | Jeder Punkt farbig | 8 Punkte eine Farbe | 64 Punkte eine Farbe |
---|---|---|---|---|
320 x 200 | 2 | 8 KByte | 8 KByte | 8 KByte |
320 x 200 | 4 | 16 KByte | 12 KByte | 8,5 KByte |
320 x 200 | 16 | 32 KByte | 16 KByte | 9 KByte |
Der Spareffekt wird um so größer je mehr Farben man einsetzt, mehr als 16 Farben hatten die Heimcomputer nicht, doch wenn man damals schon 256 Farben gehabt hätte, man wäre mit 24 bzw. 10 anstatt 64 KByte ausgekommen. Für einen Computer also durchaus eine Option, vor allem wenn er Hardware animierte Spielfiguren hat, dann fällt das Einsparen von Bits meist nicht mal auf.
Das Einsparen von Bits gab es auch noch später. Beim Amiga nutzte man das RLL-Verfahren, das damals auch Festplattenkontroller nutzten. Anstatt jedes Pixel abzuspeichern, zählte das Grafik-IC, wie viele Pixel in einer Zeile dieselbe Farbe hatten, und speicherte Farbwert und Anzahl ab. Bei den typischen Bildern mit weitestgehend monochromen Flächen spart das enorm viel Speicher ein. Das Verfahren ist Basis des PCX-Bildstandards, das heißt, man kann es heute noch leicht ausprobieren. Nur wenn jemand ein Pixel An-Pixel-Aus Muster hatte, belegte das mehr Speicher als normal. Allerdings klappte das beim Amiga trotz schnellerem 68000 Prozessor nur, weil der Graphic-Prozessor ein spezielles ASIC war, das diese Funktion in Hardware verankert hatte.
Video Display Controller vs. Video Display Processor
Für die Ausgabe des Bildschirminhalts gab es damals drei Methoden:
- Man löst das mit eigener Hardware, entweder auf Basis von Schieberegistern und TTL Schaltungen wie bei der ersten Videokarte, der Dazzler, später integrierte man dies in einen anwendungsspezifischen Baustein, eine ULA. So bei der Sinclair Reihe (ZX80/81, Spectrum), Apple II oder dem Oric.
- Man setzt einen Video Display Controller (VDC) ein. So bei der CPC-Serie, dem IBM PC, Dragon, TRS-80
- Man setzt einen Video Display Processor (VDP) ein: So beim ti 99/4A, MSX, Commodore 8 Bit Reihe
Doch was sind die Unterschiede zwischen einem Video Display Controller und einem Prozessor?
Ein Video Display Controller ist nur dafür da die Anzeige zum Monitor zu schicken (für eine Ausgabe auf einen Fernseher musste man noch einen PAL-Modulator hinterherschalten). Er verarbeitet sie aber in keiner Weise.
Ein Video Display Processor verwaltet einen Speicherbereich selbst und er kann die Daten auch beeinflussen. In den Achtzigern hatten VDP noch keine Möglichkeit die Grafik selbst zu zeichnen, das musste nach wie vor der Hauptprozessor machen. Aber die populärsten VDP hatten die Fähigkeit Sprites zu definieren. Das waren „Spielfiguren“ meistens maximal etwa 30 x 30 Pixel groß, die vom VDP selbst bewegt wurden. Er übernahm dabei eine wichtige Arbeit, nämlich das Restaurieren des Bildschirminhalts, nachdem ein Sprite einen Bereich überquert hatte, das entlastete den Hauptprozessor und der konnte sogar ein anderes Programm abwickeln und wurde vom VDP über einen Interrupt unterbrochen, wenn zwei Sprites kollidierten oder eines den Bildschirmrand erreichte. Für Spiele Entwickler, die ja oft kleine Figuren hatten, (man denke an Pac-Man oder einen Ball) war das eine tolle Eigenschaft. Die zweite wichtige Eigenschaft wurde weniger genutzt: da der Video Display Prozessor ein eigenes RAM hatte, konnte es unabhängig vom Hauptspeicher sein und belegte so keinen Platz. Bei dem knappen Speicher eines 8 Bitters ein Vorteil. Das hatte aber auch den Nachteil, das nun die Haupt-CPU nicht nur den Zugriff auf den Speicher abstimmen musste (das war auch bei VDC nötig, spezielles schnelles VRAM wurde damals in der Regel nicht verbaut) sondern nur über den VDP auf den Speicher zugreifen konnte, das heißt ihm beim Lesen erst die Adresse mitteilen musste und dann warten, bis der Video Prozessor die Daten ausgelesen hatte. Bei der MSX-Serie war das so, was für deren langsamen Bildaufbau mitverantwortlich war. Beim C128 hatte der VDP ein gemeinsam genutztes RAM, das aber separat vom Hauptspeicher war. Das absolut kurioseste Konzept war, das des Ti 99, der nur Video-RAM hatte und der Hauptprozessor dort seine BASIC-Programme ablegte.
Video Display Controller hatten andere Vorteile. Sie waren oft flexibler, was Grafikmodi betrag. Der Motorola 6845 wurde z.B. in der CPC-Serie verwendet (verschiedene Grafikmodi von 160 x 200 x 16 bis 640 x 200 x 2), der CGA (Textmodi bis 80 x 25, Grafik bis 320 x 200 x 4), Hercules Grafikkarte (nur monochrom bis 720 x 348) wie auch EGA (bis maximal 640 x 350 x 16) und VGA (640 x 480 x 16 aus 256, dort allerdings für mehr Farben von Custom-ICs unterstützt) und konnte bis zu 512 KB RAM adressieren.
Eine 8-Bit-CPU alleine hätte die Grafikausgabe nicht geschafft: Selbst bei einer Grafik mit 320 x 200 Pixeln und 4 Farben (belegt 16 KBytes) hätte sie bei 25 Bildern/s (PAL-Standard) 400 KByte pro Sekunde übertragen müssen – das schafft sie nicht, wenn man bedenkt, dass man jedes Byte zuerst in die CPU laden, dann an einen Ausgabeport schreiben muss, dann den Adresszähler erhöhen und vergleichen muss (Zeilensprung / neues Bild). Gemacht hat dies soweit ich weiß nur die 6502 im VCS2600 System, das daher nur eine geringe Auflösung von 40 Pixeln pro Zeile bot (aber aufgrund des Schreibens „on the fly“ konnte jede Zeile anders aussehen). Bei einer so reduzierten Auflösung ging das noch.