VDC
VDC steht für Video Display Controller (in deutsch etwa: Videoanzeigencontroller) und bezeichnet einen Videochip der Firma MOS. Ursprünglich für den CBM 900 entwickelt, kam der VDC letztendlich im 1985 veröffentlichten C128 zum Einsatz. Dort übernimmt er die Bildschirmausgabe im 80-Zeichen-Modus. Es wurden 2 nicht vollständig kompatible Versionen produziert, der 8563 und der 8568. Die Ausgabe erfolgt als RGBI- und als Monochrom-Signal, somit können CGA- und Monochrom-Bildschirme direkt angeschlossen werden.
Der VDC besitzt ein eigenes Video-RAM von 16 KByte (2x 4416) oder 64 KByte (2x 4464) und wird asynchron zum Rest des C128 getaktet, wobei ein 16 MHz Pixeltakt zugrunde liegt.
Fähigkeiten[Bearbeiten | Quelltext bearbeiten]
- 16 Farben (RGBI)
- Textmodus:
- standardmäßig 25 Zeilen à 80 Zeichen
- Zeilenanzahl und Anzahl Zeichen/Zeile kann weitgehend frei bestimmt werden.
- 2 Zeichensätze à 256 Zeichen sind gleichzeitig benutzbar.
- Vordergrundfarbe für einzelne Zeichen wählbar
- 4 Attribute/Zeichen: invertiert, blinkend, unterstrichen, Zeichensatz 1 oder 2
- hardwaremäßiges Interlace
- variable Zeichenhöhe von 2 bis 32 Pixel
- Hardware-Textcursor mit automatischem Blinkmodus
- Grafikmodus:
- Auflösung von 640×200 Pixel, bei 64 KByte Speicher bis zu 800×240 Pixel
- Auflösung variierbar
- Vorder- und Hintergrundfarbe kann für einzelne Farbzellen separat eingestellt werden.
- Selbständiges Verschieben von bis zu 256 Bytes großen Datenblöcken
Bildausgabe[Bearbeiten | Quelltext bearbeiten]
Der VDC ist für die Bildausgabe auf einen CGA- oder einen Monochrom-Monitor ausgelegt, die Bildwiederholfrequenz ist für PAL bzw. NTSC-Modus anpassbar. Ein Anschluss an RGB-Monitore bzw. Fernseher mit RGB-Eingang ist mit einfachen Adaptern möglich, wobei allerdings die Helligkeitsinformation verlorengeht und somit nur 8 unterschiedliche Farben dargestellt werden können. Mit zusätzlichem Aufwand kann auch ein RGBI-nach-VGA-Adapter gebastelt werden, der alle 16 Farben ausgibt.
Nachfolgend eine Tabelle mit den 16 möglichen Farben:
| Farbwert VDC |
RGBI | Farbname | Farbe | Farbwert VDC |
RGBI | Farbname | Farbe | |
|---|---|---|---|---|---|---|---|---|
| 0 | 0000 | Schwarz | 8 | 1000 | Dunkelrot | |||
| 1 | 0001 | Dunkelgrau | 9 | 1001 | Hellrot | |||
| 2 | 0010 | Dunkelblau | 10 | 1010 | Dunkelviolett | |||
| 3 | 0011 | Hellblau | 11 | 1011 | Hellviolett | |||
| 4 | 0100 | Grün | 12 | 1100 | Dunkelgelb/Braun | |||
| 5 | 0101 | Hellgrün | 13 | 1101 | Gelb | |||
| 6 | 0110 | Türkis | 14 | 1110 | Hellgrau | |||
| 7 | 0111 | Helltürkis | 15 | 1111 | Weiß |
Einen Sonderfall stellt der Farbcode 12 dar. Dieser ist zwar eigentlich ein dunkles Gelb, wird aber in vielen CGA-Monitoren durch eine spezielle Schaltung als Braun ausgegeben.
Vor- und Nachteile gegenüber dem VIC[Bearbeiten | Quelltext bearbeiten]
Im Vergleich zum VIC-II ergeben sich folgende
Vorteile:
- Höhere Auflösung
- Gestochen scharfe Darstellung
- Horizontales und vertikales Hardware-Scrolling ohne Tricks
- Doppelt so viele unterschiedliche Zeichen darstellbar als beim VIC (4× soviel, wenn man auch die Reverse-Darstellung berücksichtigt)
- Einfachere Datenorganisation des Hires-Modus
- Hardware-Textcursor
Nachteile:
- Keine Sprites
- Kein Multicolor-Modus
- Kein Rasterzeilen-Interrupt
- Umständliche und langsame Programmierung bzw. Datenaustausch mit der CPU
- Kein Refresh des DRAM-Hauptspeichers
Programmierung des VDC[Bearbeiten | Quelltext bearbeiten]
Der VDC verfügt über 36 (8563) bzw. 37 (8568) interne Register, diese sind jedoch nur indirekt über 2 Register im Ein-/Ausgabe-Bereich an der Adresse $D600/$D601 zu erreichen. Dieses Design vereinfachte den internen Aufbau des Chips und sparte Pins.
- In Register $D600 das gewünschte VDC-Register schreiben.
- Warten, bis Bit 7 von $D600 gesetzt ist.
- Den Wert des gewünschten Registers aus $D601 auslesen bzw. in $D601 schreiben.
Auch der Videospeicher des VDC ist nur auf diese Weise erreichbar.
Beim C128 ist am einfachsten die Nutzung der zwei Betriebssystemfunktionen bei $CDCC (VDC-Register schreiben) und $CDDA (VDC-Register lesen). Ein Beispiel in BASIC (erhöht die Zeilenhöhe auf 9 Rasterzeilen):
SYS DEC("CDCC"),8,9
Beim Auslesen hat Adresse $D600 folgende Bedeutungen:
| Bit | Bezeichnung | Funktion |
|---|---|---|
| 7 | Status | Dieses Bit signalisiert, ob der VDC mit seiner letzten Tätigkeit fertig ist. (1 = fertig) |
| 6 | LP | Lichtgriffel (Lightpen) |
| 5 | VBlank | Kathodenstrahlrücklauf (1 = Rücklauf) |
| 4..3 | Ohne Funktion | |
| 2..0 | VER | VDC-Version |
Interne Register des VDC[Bearbeiten | Quelltext bearbeiten]
| Register | Standardwert dez. (hex) binär |
Bits | Funktion | Bemerkung |
|---|---|---|---|---|
| 0 | 126 ($7E) NTSC %01111110 127 ($7F) PAL(*) %01111110 |
7..0 | Anzahl der Zeichen - 1 zwischen zwei horizontalen Synchronisationspulsen | Hier werden die maximal zur Verfügung stehenden Zeichen pro Zeile festgelegt. Die Zeichenzahl sollte durch 8 teilbar sein. Entspricht der Horizontalfrequenz, ausgehend vom Pixeltakt: 16.000.000 / ((Register0 + 1) * 8) in Hz |
| 1 | 80 ($50) %01010000 |
7..0 | Anzahl der angezeigten Zeichen pro Zeile | Hier wird die tatsächliche Zeichenzahl pro Zeile festgelegt. Alle Werte die kleiner als Register 0 sind, sind möglich. |
| 2 | 102 ($66) %01100110 |
7..0 | Horizontale Sync-Position | Hier wird der linke Rand positioniert. Erlaubt sind alle Werte, die größer als Register 1 sind. Wenn die Zahl in diesem Register mit einem kleineren Wert überschrieben wird, wandert das Bild nach rechts. Interessante Effekte sind damit möglich. |
| 3 | 73 ($49) %01001001 |
7..4 | Breite des vertikalen Synchronisationspulses | Wert ist ein Vielfaches einer Rasterperiode. Null entspricht dem Wert 16. |
| 3..0 | Breite des horizontalen Synchronisationspulses | Pulsbreite in Zeichen + 1. Der Wert 0 lässt sich nicht programmieren. | ||
| 4 | 32 ($20) NTSC %00100000 38 ($26) PAL(*) %00100110 |
7..0 | Gesamte Anzahl der Zeilen | In diesem Register wird die Anzahl der Zeichenzeilen - 1 inklusive des vertikalen Strahlrücklaufs angegeben. Bildzeilen = (Register4 + 1) * (Register9 + 1) |
| 5 | 25 ($19) %00011001 |
7..5 | unbenutzt | Bits immer gesetzt |
| 4..0 | Feinjustierung von Register 4 | |||
| 6 | 25 ($19) %00011001 |
7..0 | Anzahl der angezeigten Zeilen | Hier wird festgelegt, wie viele Zeilen der VDC anzeigt; Größere Werte als in Register 4 sind nicht möglich. |
| 7 | 32 ($20) %00100000 |
7..0 | Vertikale Sync-Position | Hier wird festgelegt, an welcher Stelle die erste Zeile beginnt. Je größer die Zahl, um so weiter unten beginnt die erste Zeile. |
| 8 | 32 ($20) %00100000 |
7..2 | unbelegt | Bits immer gesetzt |
| 1..0 | Interlace & Video-Modus | Wert 00 oder 01 => Normaler, Nicht-Interlace-Modus Wert 10 => Interlace-Sync-Modus: | ||
| 9 | 231 ($E7) %11100111 |
7..5 | ungenutzt | Bits immer gesetzt |
| 4..0 | Rasterzeilen pro Zeichen | bestimmt die Höhe eines Zeichens in Rasterzeilen (Wert - 1) | ||
| 10 | 160 ($A0) %10100000 |
7 | ungenutzt | Bits immer gesetzt |
| 6..5 | Cursormodus | 00 => Cursor-Blinken aus 01 => Cursor aus | ||
| 4..0 | Cursor-Startzeile | Rasterzeile, wo der Textcursor anfängt. Bestimmt zusammen mit Register 11 die Höhe des Cursors. | ||
| 11 | 231 ($E7) %11100111 |
7..5 | ungenutzt | Bits immer gesetzt |
| 4..0 | Cursor-Endzeile | Rasterzeile + 1, wo der Textcursor aufhört. | ||
| 12 | 0 ($00) %00000000 |
7..0 | Beginn Videospeicher High | High-Byte der Adresse, an der das Video-RAM beginnt. |
| 13 | 0 ($00) %00000000 |
7..0 | Beginn Videospeicher Low | Low-Byte der Adresse, an der das Video-RAM beginnt. |
| 14 | 0 ($00) %00000000 |
7..0 | Cursor-Position High | High-Byte der Position des Textcursors. |
| 15 | 0 ($00) %00000000 |
7..0 | Cursor-Position Low | Low-Byte der Position des Textcursors. |
| 16 | undefiniert | 7..0 | Lightpen vertikal | Vertikale Lightpen-Position in Zeichenzeilen + 1 |
| 17 | undefiniert | 7..0 | Lightpen horizontal | Horizontale Lightpen-Position in Zeichen + 8 |
| 18 | undefiniert | 7..0 | Update-Adresse High | High-Byte der Adresse, die man lesen oder beschreiben will. Wird vom VDC automatisch inkrementiert. |
| 19 | undefiniert | 7..0 | Update-Adresse Low | Low-Byte der Adresse, die man lesen oder beschreiben will. Wird vom VDC automatisch inkrementiert. |
| 20 | 4 ($04) %00000100 |
7..0 | Beginn Attributspeicher High | High-Byte der Adresse, an der das Attribut-RAM beginnt. |
| 21 | 0 ($00) %00000000 |
7..0 | Beginn Attributspeicher Low | Low-Byte der Adresse, an der das Attribut-RAM beginnt. |
| 22 | 120 ($78) %01111000 |
7..4 | Maximale Zeichenbreite | Zeichenbreite in Pixel - 1, inkl. Zeichenzwischenraum |
| 3..0 | Angezeigte Zeichenbreite | Zeichenbreite in Pixel - 1, ohne Zeichenzwischenraum | ||
| 23 | 232 ($E8) %11101000 |
7..5 | ungenutzt | Bits immer gesetzt |
| 4..0 | Zeichenhöhe | Rasterzeilen - 1 der angezeigten Zeichenhöhe ohne Zeilenzwischenraum. Sollte kleiner oder gleich Register 9 sein. | ||
| 24 | 32 ($20) %00100000 |
7 | Block-Copy | 0 => Block wird geschrieben 1 => Block wird kopiert. |
| 6 | Revers/Normal-Darstellung | 0 => Normaldarstellung 1 => Bildschirm wird invertiert. | ||
| 5 | Blinkrate der Buchstaben | 0 => Rate entspricht 1/16 der Bildwiederholfrequenz, 1 => Rate entspricht 1/32 der Bildwiederholfrequenz. | ||
| 4..0 | Vertikales Smooth (Soft)-Scrolling | Anzahl der Rasterzeilen, um die die Darstellung nach oben verschoben wird. | ||
| 25 | 64 ($40) %01000000 |
7 | Darstellungsmodus | 0 => Textmodus 1 => Grafikmodus (Hires) |
| 6 | Attribute ein/aus | 0 => Zeichen-Attribute ausgeschaltet 1 => Zeichen-Attribute eingeschaltet | ||
| 5 | Semigrafik | 0 => der Zeichenzwischenraum wird mit der Hintergrundfarbe gefüllt, 1 => der Zeichenzwischenraum wird mit der Farbe des letzten Zeichens gefüllt. | ||
| 4 | Pixelbreite | 0 => normale Pixelbreite 1 => doppelte Pixelbreite | ||
| 3..0 | Horizontales Smooth (Soft)-Scrolling | Anzahl der Pixel, um die die Darstellung nach links verschoben wird. | ||
| 26 | 240 ($F0) %11110000 |
7..4 | Vordergrundfarbe | Vordergrundfarbe bei abgeschaltetem Attribut-RAM |
| 3..0 | Hintergrundfarbe | Hintergrund und Rahmenfarbe | ||
| 27 | 0 ($00) %00000000 |
7..0 | Adressen-Inkrement pro Zeile | Wert, der am Ende jeder Zeichenzeile zum Video- und Attribut-RAM-Zeiger aufaddiert wird, um die Adresse der neuen Zeile zu erhalten. |
| 28 | 47 ($2F) %00101111 |
7..5 | Startadresse des Zeichengenerators | Startadresse wird in 8KByte-Schritten festgelegt. |
| 4 | Größe des VDC-RAMs | 0 => 16 KByte RAM 1 => 64 KByte RAM (keine automatische Erkennung) | ||
| 3..0 | ungenutzt | |||
| 29 | 231 ($E7) %11100111 |
7..5 | ungenutzt | Bits immer gesetzt |
| 4..0 | Unterstreichungszeile | Pixelzeile in welcher ein Zeichen unterstrichen wird. | ||
| 30 | undefiniert | 7..0 | Anzahl Block-Write- oder Block-Copy-Zyklen | Gibt die Größe eines Write- oder Copy-Blockes an. 0 entspricht 256 Bytes. Ein Beschreiben des Registers startet den Zyklus. |
| 31 | undefiniert | 7..0 | Data | Lesen: Inhalt der durch Register 18/19 angegebenen Adresse Schreiben: Wert wird in die durch Register 18/19 angegebene Speicherzelle geschrieben. Anschließend kann der Wert für Block-Write benutzt werden. |
| 32 | undefiniert | 7..0 | High-Byte der Block-Copy-Quelladresse | High-Byte der Startadresse des zu kopierenden Blockes. |
| 33 | undefiniert | 7..0 | Low-Byte der Block-Copy-Quelladresse | Low-Byte der Startadresse des zu kopierenden Blockes. |
| 34 | 125 ($7D) %011100111 |
7..0 | Beginn 1. Zeichen | Anzahl der Zeichen vom Beginn der dargestellten Zeile bis zur positiven Flanke des Display-Enable-Pins. |
| 35 | 64 ($40) %01000000 |
7..0 | Ende letztes Zeichen | Anzahl der Zeichen vom Beginn der dargestellten Zeile bis zur negativen Flanke des Display-Enable-Pins. |
| 36 | 245 ($F5) %11110101 |
7..4 | ungenutzt | Bits immer gesetzt |
| 3..0 | DRAM-Refresh | Anzahl der Refresh-Zyklen pro Rasterzeile. |
Anmerkung:
- ab ROM-Version von 1986
Bildparameter[Bearbeiten | Quelltext bearbeiten]
Details siehe Literatur und Diskussionen in Foren zur VDC-Programmierung[1].
Pixelfrequenz/-takt:
T = 16 MHz
Horizontal-/Zeilenfrequenz:
HF = T / ((Register0 + 1) * 8)
Bildzeilen:
Zeilen = (Register4 + 1) * (Register9 + 1)
Vertikalfrequenz oder Bildwiederholfrequenz/-rate:
BF = HF / Zeilen
- Einheit: Hz
- Standardwert:
- PAL: 50,08 Hz
- NTSC: 59,65 Hz
Emulation[Bearbeiten | Quelltext bearbeiten]
Die exakte Nachbildung des Verhaltens bei C128-Emulatoren verbessert sich laufend. Schon sehr nahe kommt aber der schon seit 2015 schon recht gereifte Emulator Z64K, der neben anderen Plattformen den VDC sehr zyklengenau emulieren kann, alle bekannten VDC-Modi unterstützt und zudem (im Gegensatz zu VICE) Deinterlacing-Optionen anbietet.[2]
Pin-Belegung des VDC 8563[Bearbeiten | Quelltext bearbeiten]
| Pin | Beschreibung | |
|---|---|---|
|
CCLK | Character Clock |
| DCLK | Video Dot Clock D | |
| HSYNC | Horizontales Sync-Signal | |
| n/c | nicht verbunden | |
| CS | Chip Select | |
| RS | Register Select:
| |
| R/W | Read/Write - Register lesen oder schreiben | |
| D0 - D7 | Datenbus Bits 0 - 7 (Register 0 und 1) | |
| Vss | Systemmasse | |
| DISPEN | Display Enable | |
| VSYNC | Vertikales Sync-Signal | |
| INIT | bei Low-Pegel werden die internen Control-Latches gelöscht | |
| RES | Reset-Eingang | |
| TEST | ||
| LPEN | Eingang für Lightpen | |
| Vcc | Versorgungsspannung +5 V DC | |
| R, G, B, I | Ausgabe Farbwerte für Rot, Grün, Blau, Intensität | |
| DR/W | Read/Write - VDC-RAM lesen/schreiben | |
| DA0 - DA7 | Adressbus Bits 0 - 7 bzw. 8 - 15 (CAS/RAS-Multiplex) VDC-RAM | |
| DD0 - DD7 | Datenbus Bits 0 - 7 VDC-RAM | |
| RAS | Row Address Strobe für VDC-RAM | |
| CAS | Column Address Strobe für VDC-RAM |
Literatur[Bearbeiten | Quelltext bearbeiten]
Weblinks[Bearbeiten | Quelltext bearbeiten]
| Wikipedia: MOS Technology VDC |
| Wikipedia: MOS Technology 8563 |
Quellen[Bearbeiten | Quelltext bearbeiten]
- ↑ Thema: VICE x128 und VDC: Kein Interlace möglich? auf Forum64.de
- ↑ Z64K laufende VDC-Entwicklung: VDC 101 demo
