# MOS VDC

Il MOS VDC (acronimo di Video Display Controller, anche MOS 8563) è un processore prodotto da MOS Technology ed utilizzato come chip video nel computer Commodore 128.
Era capace di gestire una modalità ad 80 colonne (640x200 pixel) in formato RGBI (RGB plus Intensity), il cui segnale è compatibile con lo standard CGA. I modelli D/DCR del C128 usano invece il più avanzato 8568 [D]VDC. È stato il chip più difficile da produrre rispetto a tutti gli altri chip di MOS, ha avuto anche problemi tecnici legati a difetti di timing che portavano al suo malfunzionamento.

## Storia

Originariamente previsto per l'uso in un computer da ufficio basato su Unix che non fu mai realmente costruito, la Commodore ripensò il VDC per l'uso su diversi prodotti: di questi solo il C128 vide la produzione.
Poco dopo il rilascio del C128, la modalità bitmap del VDC fu descritta in dettaglio in un libro pubblicato inizialmente dalla casa editrice tedesca Data Becker, dove un listato in linguaggio Assembly proposto dagli autori permetteva di accendere o spegnere qualunque pixel video o, utilizzando il BASIC per effettuare i necessari calcoli, generare figure geometriche in bitmap sullo schermo ad 80 colonne. Nel febbraio del 1986 la rivista informatica americana RUN pubblicava Ultra Hi-Res Graphics, un articolo in cui descriveva la modalità bitmap del VDC ed includeva un listato in Assembly che estendeva il BASIC 7.0 per supportare la modalità grafica a 640x200 offerta dall'8563. Gli autori Lou Wallace e David Darus convertirono il programma Ultra Hi-Res in un pacchetto commerciale denominato BASIC 8.0, che divenne uno dei più popolari programmi di utilità per il C128. Successivamente Commodore offrì la documentazione completa del VDC nel Commodore 128 Programmer's Reference Guide e le modalità bitmap del chip furono intensamente utilizzate nella versione per C128 del sistema operativo GEOS.

## Caratteristiche e descrizione

Ufficialmente il VDC era un chip nato per sole modalità testuali, anche se un'attenta lettura dei documenti tecnici che gli ingegneri MOS fornirono con il chip, permise di capire agli sviluppatori del C128 che sarebbe stato possibile utilizzare il chip in una modalità grafica ad alta risoluzione (640x200 pixel) di tipo bitmap, anche se il BASIC 7.0 del Commodore 128 supportava modalità grafiche solo nei modi a 40 colonne (320x200 pixel) attraverso il vecchio chip VIC-II. A differenza dei precedenti chip video MOS quali il VIC-II, il VDC aveva una RAM video dedicata di 16 KB (espandibili a 64) nel C128 originale e di 64 KB nel Commododore 128D (la versione con tastiera separata dal computer). Questa RAM non era direttamente utilizzabile dal microprocessore.
Il VDC non supportava inoltre gli sprite e ciò limitava il suo uso nei giochi. Era però capace di supportare il blitting, vale a dire poteva effettuare copie di blocchi della sua memoria video: questa funzionalità fu usata dall'editor video in ROM per pulire o scorrere rapidamente sezioni video.

## Specifiche tecniche

* Uscita RGBI (RGB plus Intensity) compatibile con lo standard video CGA di IBM.
* 16 o 64 kilobyte di memoria dedicata (separata dalla memoria di sistema).
* Risoluzione di 640x200 pixel (640×400 in modalità interlacciata).
* Risoluzione di 720x700 pixel (risoluzione massima con 64 KB di memoria video)
* Modalità testuali ad 80x25, 80x50 e 40x25 caratteri.
* 8 colori con 2 intensità.

## Programmazione

L'indirizzamento dei registri interni e della memoria video dedicata del VDC deve essere fatto in maniera indiretta. Prima di tutto bisogna dire al VDC quale dei suoi 37 registri interni deve essere usato, poi il programma deve attendere finché il VDC non è pronto all'accesso ed infine si può accedere in lettura o scrittura. Il seguente codice Assembly è per un'operazione di lettura:
Mentre il seguente codice è per una tipica operazione di scrittura:
L'accesso ai registri del VDC è possibile anche attraverso il BASIC, chiamando alcune routine del KERNAL :
Il codice seguente permette la lettura di uno dei registri del VDC, dove register è un numero tra 0 e 36 (vedi tabella):
Il codice seguente invece implementa la scrittura di uno dei registri del VDC, dove register è un numero tra 0 e 36 (vedi tabella), e value è un numero tra 0 to 255
A causa di questo curioso modo di controllo del VDC il frame rate massimo in modalità bitmap è in genere troppo basso per un qualunque gioco in stile "arcade" dove invece la manipolazione intensiva dei bit è una caratteristica fondamentale.

## Elenco dei registri

Questo elenco è stato estrapolato dalla guida Commodore 128 Programmer's Reference Guide
| Registro | $Hex | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | Descrizione |
| 0 | $00 | HT7 | HT6 | HT5 | HT4 | HT3 | HT2 | HT1 | HT0 | Horizontal Total |
| 1 | $01 | HD7 | HD6 | HD5 | HD4 | HD3 | HD2 | HD1 | HD0 | Horizontal Displayed |
| 2 | $02 | HP7 | HP6 | HP5 | HP4 | HP3 | HP2 | HP1 | HP0 | Horizontal Sync Position |
| 3 | $03 | VW3 | VW2 | VW1 | VW0 | HW3 | HW2 | HW1 | HW0 | Vertical/Horizontal Sync Width |
| 4 | $04 | VT7 | VT6 | VT5 | VT4 | VT3 | VT2 | VT1 | VT0 | Vertical Total |
| 5 | $05 | -- | -- | -- | VA4 | VA3 | VA2 | VA1 | VA0 | Vertical Adjust |
| 6 | $06 | VD7 | VD6 | VD5 | VD4 | VD3 | VD2 | VD1 | VD0 | Vertical Displayed |
| 7 | $07 | VP7 | VP6 | VP5 | VP4 | VP3 | VP2 | VP1 | VP0 | Vertical Sync Position |
| 8 | $08 | -- | -- | -- | -- | -- | -- | IM1 | IM0 | Interlace Mode |
| 9 | $09 | -- | -- | -- | -- | CTV4 | CTV3 | CTV2 | CTV1 | Character Total Vertical |
| 10 | $0A | -- | CM1 | CM0 | CS4 | CS3 | CS2 | CS1 | CS0 | Cursor Mode, Start Scan |
| 11 | $0B | -- | -- | -- | CE4 | CE3 | CE2 | CE1 | CE0 | Cursor End Scan Line |
| 12 | $0C | DS15 | DS14 | DS13 | DS12 | DS11 | DS10 | DS9 | DS8 | Display Start Address High Byte |
| 13 | $0D | DS7 | DS6 | DS5 | DS4 | DS3 | DS2 | DS1 | DS0 | Display Start Address Low Byte |
| 14 | $0E | CP15 | CP14 | CP13 | CP12 | CP11 | CP10 | CP9 | CP8 | Cursor Position High Byte |
| 15 | $0F | CP7 | CP6 | CP5 | CP4 | CP3 | CP2 | CP1 | CP0 | Cursor Position Low Byte |
| 16 | $10 | LPV7 | LPV6 | LPV5 | LPV4 | LPV3 | LPV2 | LPV1 | LPV0 | Light Pen Vertical Position |
| 17 | $11 | LPH7 | LPH6 | LPH5 | LPH4 | LPH3 | LPH2 | LPH1 | LPH0 | Light Pen Horizontal Position |
| 18 | $12 | UA15 | UA14 | UA13 | UA12 | UA11 | UA10 | UA9 | UA8 | Update Address High Byte |
| 19 | $13 | UA7 | UA6 | UA5 | UA4 | UA3 | UA2 | UA1 | UA0 | Update Address Low Byte |
| 20 | $14 | AA15 | AA14 | AA13 | AA12 | AA11 | AA10 | AA9 | AA8 | Attribute Start Address High Byte |
| 21 | $15 | AA7 | AA6 | AA5 | AA4 | AA3 | AA2 | AA1 | AA0 | Attribute Start Address Low Byte |
| 22 | $16 | CTH3 | CTH2 | CTH1 | CTH0 | CDH3 | CDH2 | CDH1 | CDH0 | Character Total Horizontal, Character Display Horizontal |
| 23 | $17 | -- | -- | -- | CDV4 | CDV3 | CDV2 | CDV1 | CDV0 | Character Display Vertical |
| 24 | $18 | COPY | RVS | CBRATE | VSS4 | VSS3 | VSS2 | VSS1 | VSS0 | Vertical Smooth Scrolling |
| 25 | $19 | TEXT | ATR | SEMI | DBL | HSS3 | HSS2 | HSS1 | HSS0 | Horizontal Smooth Scrolling |
| 26 | $1A | FG3 | FG2 | FG1 | FG0 | BG3 | BG2 | BG1 | BG0 | Foreground/Background color |
| 27 | $1B | AI7 | AI6 | AI5 | AI4 | AI3 | AI2 | AI1 | AI0 | Address Increment per Row |
| 28 | $1C | CB15 | CB14 | CB13 | RAM | -- | -- | -- | -- | Character Base Address |
| 29 | $1D | -- | -- | -- | UL4 | UL3 | UL2 | UL1 | UL0 | Underline Scan Line |
| 30 | $1E | WC7 | WC6 | WC5 | WC4 | WC3 | WC2 | WC1 | WC0 | Word Count |
| 31 | $1F | DA7 | DA6 | DA5 | DA4 | DA3 | DA2 | DA1 | DA0 | Data Register |
| 32 | $20 | BA15 | BA14 | BA13 | BA12 | BA11 | BA10 | BA9 | BA8 | Block Start Address High Byte |
| 33 | $21 | BA7 | BA6 | BA5 | BA4 | BA3 | BA2 | BA1 | BA0 | Block Start Address Low Byte |
| 34 | $22 | DEB7 | DEB6 | DEB5 | DEB4 | DEB3 | DEB2 | DEB1 | DEB0 | Display Enable Begin |
| 35 | $23 | DEE7 | DEE6 | DEE5 | DEE4 | DEE3 | DEE2 | DEE1 | DEE0 | Display Enable End |
| 36 | $24 | -- | -- | -- | -- | DRR3 | DRR2 | DRR1 | DRR0 | DRAM Refresh Rate |