OOStuBS/MPStuBS
|
Die CGA (Color Graphics Adapter) wurde 1981 von IBM als farbfähige Grafikkarte für den IBM-PC eingeführt. Neben zwei Textmodi wurden auch drei Grafikmodi unterstützt. Für Betriebssystembau verwenden wir lediglich einen Textmodus. Die heutige Grafikhardware hat noch die Unterstützung für die CGA-Hardware für die Abwärtskompatibilität.
In diesem Textmodus wird der Bildschirm in ein Raster von 80x25 Zeichen eingeteilt. D.h., es ist lediglich möglich, an 80 horizontalen bzw. 25 vertikalen Zellen ein Zeichen zu platzieren, nicht jedoch dazwischen. CGA erlaubt zusätzlich noch dem Zeichen selbst bzw. dessen Hintergrund eine Farbe zu geben oder es blinken zu lassen. Weiter verfügt die Hardware über einen Cursor, der die aktuelle Stelle in der Konsole anzeigen soll, sowie einige weitere Features, die wir in BSB allerdings außen vor lassen.
Intern wird der Bildschirm als ein Array an Adresse 0xb8000
dargestellt (siehe Memory Mapped I/O). Jede Stelle wird als ein 16-Bit Eintrag repräsentiert: ein Byte für den ASCII-Wert des gewünschten Zeichens und ein Byte für Darstellungsattribute, also Farben und das Blinkend-Bit.
Byte 0 | Byte 1 | ||
---|---|---|---|
ASCII-Wert | Blinken (1 Bit) | Hintergrundfarbe (3 Bit) | Vordergrundfarbe (4 Bit) |
Die Darstellung erfolgt zeilenweise im Videospeicher. D.h., dass zunächst an der Adresse 0xb8000
die erste Zeile des Bildschirms beginnt. An die erste Zeile anschließend folgt die zweite (analog zu einem zweidimensionalen Array in C). Die CGA-Grafikkarte liest diesen speziellen Speicherbereich automatisch aus und übersetzt es in Videosignal, was an den Monitor übertragen wird. Der Prozessor des PCs also muss lediglich die Zeichen im Array ersetzen oder Attribute umsetzen und kann die Ausgabe auf die Grafikkarte auslagern und andere Aufgaben übernehmen.
Zu jedem Zeichen können die Merkmale Vordergrundfarbe, Hintergrundfarbe und Blinken einzeln festgelegt werden. Für diese Attribute steht pro Zeichen ein Byte zur Verfügung, dessen Bits folgende Bedeutung haben:
Darstellungsattribute | |
---|---|
Bits 0-3 | Vordergrundfarbe |
Bits 4-6 | Hintergrundfarbe |
Bit 7 | Blinken |
Im CGA Textmodus stehen die folgenden 16 Farben zur Verfügung:
Farbpalette | |||
---|---|---|---|
0 | Schwarz | 8 | Dunkelgrau |
1 | Blau | 9 | Hellblau |
2 | Grün | 10 | Hellgrün |
3 | Cyan | 11 | Hellcyan |
4 | Rot | 12 | Hellrot |
5 | Magenta | 13 | Hellmagenta |
6 | Braun | 14 | Gelb |
7 | Hellgrau | 15 | Weiß |
Da für die Hintergrundfarbe im Attributbyte nur drei Bits zur Verfügung stehen, können auch nur die ersten acht Farben zur Hintergrundfarbe gewählt werden.
Der memory-mapped Videospeicher kann über einen Zeiger benutzt werden (siehe Memory Mapped I/O). Um den Speicher für eine einzelne Zelle (Zeichen + Attribute) anzusprechen, empfehlen wir die Verwendung eines Bitfelds. Eine nicht zu empfehlende Lösung ist die folgende:
Der Cursor soll die aktuelle Position anzeigen, ist aber voll durch Software steuerbar. Für den Cursor und weitere Funktionen stellt die CGA-Hardware 18 Steuerregeister bereit, die jeweils 8 Bit weit sind.
Diese Steuerregister werden von zwei I/O-Ports (siehe Port-based I/O) gemultiplext, d.h. durchgeleitet. I/O-Ports werden nicht wie der Speicher über Zeiger in einer Hochsprache angesprochen, sondern benötigen spezielle in
und out
Prozessorbefehle und haben einen vom Speicher getrennten Adressraum. Weil es die Instruktionen nicht in C++ gibt und damit die Verwendung von Assembler nötig ist, haben wir entsprechende Wrapper-Routinen in machine/io_port.h bereits vorbereitet.
Die CGA-Hardware exportiert die 18 Steuerregister aber nicht direkt, sondern über eine Indirektion, wodurch lediglich zwei I/O-Ports verwendet werden müssen. Der Index-Port (I/O-Port 0x3d4
) bestimmt das Register, was verwendet werden soll. Der Data-Port (I/O-Port 0x3d5
) erlaubt dann den Zugriff auf das ausgewählte Register.
Für den Cursor sind die Register 14 und 15 wichtig, die die höheren und die unteren Bits der Cursor-Position beinhalten. Die Cursorposition wird allerdings nicht als X,Y-Wert gespeichert, sondern als relativer Zeiger in den Videospeicher (also zellenweise). D.h., dass eine 244 angegeben werden muss, wenn der Cursor in Spalte 4, Zeile 3 sein soll.