Hlavní navigace

Osmibitové počítače Commodore a čip VIC-II - dokončení

23. 7. 2009
Doba čtení: 14 minut

Sdílet

V dnešním pokračování seriálu o architekturách počítačů dokončíme popis grafického čipu VIC-II. Řekneme si, jakým způsobem tento čip pracuje se sprity a taktéž si ukážeme některé známé i méně známé triky, které je možné s tímto obvodem provádět (například se jedná o zvýšení počtu barev či současně zobrazených spritů).

Obsah

1. Spritová grafika na osmibitových počítačích
2. Čip VIC-II a podpora zobrazení spritů
3. Řídicí registry čipu VIC-II, pomocí nichž se řídí zobrazení spritů
4. Sprity zobrazené v režimu hi-res
5. Sprity zobrazené v režimu multi-color
6. Zobrazení většího množství spritů
7. Další vlastnosti čipu VIC-II, zvýšení počtu barev v režimu FLI
8. Režim IFLI
9. Literatura a odkazy na Internetu

1. Spritová grafika na osmibitových počítačích

Na některých osmibitových domácích počítačích a taktéž osmibitových herních konzolích se ve hrách, ale i v dalších aplikacích zaměřených na počítačovou grafiku, často používala možnost zrychleného vykreslování jednoduchých rastrových obrázků nazývaných sprity. Generování obrazů spritů na televizi či obrazovce monitoru přitom probíhalo nezávisle na vykreslování ostatní scény (v tomto případě nazývané pozadí – background, popř. hrací plocha – playground), přičemž bylo možné definovat prioritu vykreslování, tj. zda bude ve výsledném obrázku upřednostněn pixel z pozadí nebo ze spritu. Grafické subsystémy těchto počítačů, které podporovaly práci se sprity, také většinou obsahovaly takzvané kolizní registry, do kterých se ukládaly příznaky překryvu pozadí se sprity (kolize spritu s barvou pozadí) nebo mezi několika sprity navzájem (kolize spritů). Tím se při práci s pohyblivými obrazy předmětů nemusely provádět zdlouhavé testy mezi všemi zobrazovanými pixely, postačilo pouze přečíst stav z kolizních registrů.

pc7101

Obrázek 1: Screenshot ze hry Starquake ve verzi pro osmibitové počítače Atari. Tyto počítače podporovaly vykreslování čtyř jednobarevných spritů (každý sprite samozřejmě mohl mít jinou barvu), jejichž rozlišení bylo 8×128 resp. 8×256 pixelů a dále čtyř takzvaných střel, což byly sprity zúžené na 2×128 nebo 2×256 pixelů (všechny střely se navíc mohly spojit do pátého spritu). Hrací plocha hry Starquake je vytvořena v monochromatickém grafickém režimu číslo ANTIC 15 (GRAPHICS 8), ovšem hráč je vykreslen pomocí spritu, tj. může mít barvu odlišnou od okolní scény a může se pohybovat v horizontálním i vertikálním směru bez nutnosti přesunů dat v obrazové paměti.

U většiny osmibitových počítačů, které podporovaly vykreslování spritů, byly video paměti určené pro uložení pozadí (hrací plochy) a paměti pro uložení rastrových dat spritů od sebe odděleny a teprve až v průběhu vykreslování na obrazovku se provedla kombinace pixelů pozadí a pixelů uložených ve spritech – viz druhý obrázek. Sprity byly poprvé použity v dnes již zapomenutém počítači Elektor TV Games Computer z roku 1979. Později byly podporovány například na již popsaných osmibitových počítačích Atari, na počítači Commodore C64 (viz další kapitoly) a v pozdější době i na slavných počítačích Amiga. U prvních typů grafických karet pro personální počítače (IBM PC) se podpora spritů zcela vytratila, aby se s velkou slávou (jako „převratná novinka“) objevila u některých karet typu SVGA, kde se sprity používaly především pro zobrazení kurzoru myši nezávisle na zobrazeném pozadí. S nástupem 2D a 3D akcelerátorů bylo možné sprity nahradit obrázky či texturami s alfa kanálem, tj. s možností přiřazení průhlednosti některým pixelům či texelům. Je zde však jeden důležitý rozdíl: zatímco u osmibitových počítačů se sprity vytvářely zcela nezávisle na pozadí a vykreslovaly se až kombinací barev pixelů při jejich čtení z paměti, u moderních grafických akcelerátorů jsou všechny grafické údaje zapsány společně do framebufferu, ze kterého mohou být následně přečteny a vykresleny.

pc6904

Obrázek 2: Tok dat mezi operační pamětí, mikroprocesorem a čipy ANTIC i GTIA při generování video signálu na osmibitových počítačích Atari.

2. Čip VIC-II a podpora zobrazení spritů

Grafický čip VIC-II použitý v počítači Commodore C64 podporuje, podobně jako obvod GTIA u osmibitových Atari, práci se sprity. Spritů může být (pokud není použita některá z technik popsaných v dalším textu) současně zobrazeno osm, přičemž každý sprite má velikost 24×21 pixelů v monochromatickém (hi-res) režimu nebo 12×21 pixelů v režimu multi-color. Pomocí vhodně naprogramované přerušovací rutiny je však možné zobrazit i více spritů – využívá se změna vertikální polohy některého již vykresleného spritu, což znamená, že omezení na osm spritů ve skutečnosti platí pouze pro jeden obrazový řádek. Ze čtyřiceti sedmi řídicích osmibitových registrů čipu VIC-II je jich plných 34 určeno pro ovládání spritů. U spritů je možné nastavovat jejich horizontální i vertikální polohu, barvu, velikost (zvětšení ve směru horizontální a/nebo vertikální osy), grafický režim (hi-res, multi-color) a kolize typu sprite-sprite a sprite-bitmapa. Také je možné měnit prioritu spritů vůči pozadí, vzájemná priorita spritů je však neměnná a je určena číslem spritu.

pc7103

Obrázek 3: Osm čtyřbarevných spritů zobrazených v režimu multi-color.

Způsob zobrazení spritů nezávisle na pozadí je v čipu VIC-II řešen podobným způsobem, jako u již popsaného čipu GTIA používaného u osmibitových počítačů Atari. Hlavní rozdíl (spíše rozšíření) spočívá v možnosti vertikálního posunu spritů a taktéž v možnosti jejich zobrazení ve více barvách.

 IRQ <---------------------------------+
                                       |
            +---------------+ +-----------------+
            |Refresh counter| | Interrupt logic |<----------------------+
            +---------------+ +-----------------+                       |
        +-+    |               ^                                        |
  A     |M|    v               |                                        |
  d     |e|   +-+    +--------------+  +-------+                        |
  d     |m|   |A|    |Raster counter|->| VC/RC |                        |
  r     |o|   |d| +->|      X/Y     |  +-------+                        |
  . <==>|r|   |d| |  +--------------+      |                            |
  +     |y|   |r| |     | | |              |                            |
  d     | |   |.|<--------+----------------+ +------------------------+ |
  a     |i|   |g|===========================>|40×12 bit video matrix-/| |
  t     |n|<=>|e| |     |   |                |       color line       | |
  a     |t|   |n| |     |   |                +------------------------+ |
        |e|   |e| |     |   |                            ||             |
        |r|   |r| |     |   | +----------------+         ||             |
 BA  <--|f|   |a|============>|8×24 bit sprite |         ||             |
        |a|   |t|<----+ |   | |  data buffers  |         ||             |
 AEC <--|c|   |o| |   | v   | +----------------+         ||             |
        |e|   |r| | +-----+ |         ||                 ||             |
        +-+   +-+ | |MC0-7| |         \/                 \/             |
                  | +-----+ |  +--------------+   +--------------+      |
                  |         |  | Sprite data  |   |Graphics data |      |
        +---------------+   |  |  sequencer   |   |  sequencer   |      |
 RAS <--|               |   |  +--------------+   +--------------+      |
 CAS <--|Clock generator|   |              |         |                  |
 Φ0  <--|               |   |              v         v                  |
        +---------------+   |       +-----------------------+           |
                ^           |       |          MUX          |           |
                |           |       | Sprite priorities and |-----------+
 ΦIN -----------+           |       |  collision detection  |
                            |       +-----------------------+
   VC: Video Matrix Counter |                   |
                            |                   v
   RC: Row Counter          |            +-------------+
                            +----------->| Border unit |
   MC: MOB Data Counter     |            +-------------+
                            |                   |
                            v                   v
                    +----------------+  +----------------+
                    |Sync generation |  |Color generation|<-------- řCOLOR
                    +----------------+  +----------------+
                                   |      |
                                   v      v
                                 Video output
                               (S/LUM and COLOR)

3. Řídicí registry čipu VIC-II, pomocí nichž se řídí zobrazení spritů

V následující tabulce jsou vypsány ty řídicí registry čipu VIC-II, pomocí nichž je možné zvolit způsob zobrazení spritů na obrazovce, měnit souřadnice spritů (registry 0 až 16) a popř. přečíst příznaky kolize spritů (registr 30 a 31). Povšimněte si, že vzhledem k horizontálnímu rozlišení čipu VIC-II, tj. 320 pixelům, je nutné horizontální souřadnice spritů uložit do devíti bitů, přičemž hodnoty nejvyšších bitů jsou pro všechny sprity sdruženy do řídicího registru číslo 16. Taktéž je možné pro každý sprite zvolit barvu nezávisle na barvách ostatních spritů (a samozřejmě nezávisle na barvě pozadí) či zvětšit sprite v horizontálním či vertikálním směru (registr 23 a 29). Změnou hodnoty uložené v registru číslo 21 lze libovolný sprite povolit či zakázat. Význam některých řídicích registrů bude popsán v navazujících kapitolách.

 #| Adr.  |Bit7|Bit6|Bit5|Bit4|Bit3|Bit2|Bit1|Bit0| Function
--+-------+----+----+----+----+----+----+----+----+------------------------
 0| $d000 |                  M0X                  | X coordinate sprite 0
--+-------+---------------------------------------+------------------------
 1| $d001 |                  M0Y                  | Y coordinate sprite 0
--+-------+---------------------------------------+------------------------
 2| $d002 |                  M1X                  | X coordinate sprite 1
--+-------+---------------------------------------+------------------------
 3| $d003 |                  M1Y                  | Y coordinate sprite 1
--+-------+---------------------------------------+------------------------
 4| $d004 |                  M2X                  | X coordinate sprite 2
--+-------+---------------------------------------+------------------------
 5| $d005 |                  M2Y                  | Y coordinate sprite 2
--+-------+---------------------------------------+------------------------
 6| $d006 |                  M3X                  | X coordinate sprite 3
--+-------+---------------------------------------+------------------------
 7| $d007 |                  M3Y                  | Y coordinate sprite 3
--+-------+---------------------------------------+------------------------
 8| $d008 |                  M4X                  | X coordinate sprite 4
--+-------+---------------------------------------+------------------------
 9| $d009 |                  M4Y                  | Y coordinate sprite 4
--+-------+---------------------------------------+------------------------
10| $d00a |                  M5X                  | X coordinate sprite 5
--+-------+---------------------------------------+------------------------
11| $d00b |                  M5Y                  | Y coordinate sprite 5
--+-------+---------------------------------------+------------------------
12| $d00c |                  M6X                  | X coordinate sprite 6
--+-------+---------------------------------------+------------------------
13| $d00d |                  M6Y                  | Y coordinate sprite 6
--+-------+---------------------------------------+------------------------
14| $d00e |                  M7X                  | X coordinate sprite 7
--+-------+---------------------------------------+------------------------
15| $d00f |                  M7Y                  | Y coordinate sprite 7
--+-------+----+----+----+----+----+----+----+----+------------------------
16| $d010 |M7X8|M6X8|M5X8|M4X8|M3X8|M2X8|M1X8|M0X8| MSBs of X coordinates
--+-------+----+----+----+----+----+----+----+----+------------------------
21| $d015 | M7E| M6E| M5E| M4E| M3E| M2E| M1E| M0E| Sprite enabled
--+-------+----+----+----+----+----+----+----+----+------------------------
23| $d017 |M7YE|M6YE|M5YE|M4YE|M3YE|M2YE|M1YE|M0YE| Sprite Y expansion
--+-------+----+----+----+----+----+----+----+----+------------------------
27| $d01b |M7DP|M6DP|M5DP|M4DP|M3DP|M2DP|M1DP|M0DP| Sprite data priority
--+-------+----+----+----+----+----+----+----+----+------------------------
28| $d01c |M7MC|M6MC|M5MC|M4MC|M3MC|M2MC|M1MC|M0MC| Sprite multicolor
--+-------+----+----+----+----+----+----+----+----+------------------------
29| $d01d |M7XE|M6XE|M5XE|M4XE|M3XE|M2XE|M1XE|M0XE| Sprite X expansion
--+-------+----+----+----+----+----+----+----+----+------------------------
30| $d01e | M7M| M6M| M5M| M4M| M3M| M2M| M1M| M0M| Sprite-sprite collision
--+-------+----+----+----+----+----+----+----+----+------------------------
31| $d01f | M7D| M6D| M5D| M4D| M3D| M2D| M1D| M0D| Sprite-data collision
--+-------+----+----+----+----+----+----+----+----+------------------------
37| $d025 |  - |  - |  - |  - |        MM0        | Sprite multicolor 0
--+-------+----+----+----+----+-------------------+------------------------
38| $d026 |  - |  - |  - |  - |        MM1        | Sprite multicolor 1
--+-------+----+----+----+----+-------------------+------------------------
39| $d027 |  - |  - |  - |  - |        M0C        | Color sprite 0
--+-------+----+----+----+----+-------------------+------------------------
40| $d028 |  - |  - |  - |  - |        M1C        | Color sprite 1
--+-------+----+----+----+----+-------------------+------------------------
41| $d029 |  - |  - |  - |  - |        M2C        | Color sprite 2
--+-------+----+----+----+----+-------------------+------------------------
42| $d02a |  - |  - |  - |  - |        M3C        | Color sprite 3
--+-------+----+----+----+----+-------------------+------------------------
43| $d02b |  - |  - |  - |  - |        M4C        | Color sprite 4
--+-------+----+----+----+----+-------------------+------------------------
44| $d02c |  - |  - |  - |  - |        M5C        | Color sprite 5
--+-------+----+----+----+----+-------------------+------------------------
45| $d02d |  - |  - |  - |  - |        M6C        | Color sprite 6
--+-------+----+----+----+----+-------------------+------------------------
46| $d02e |  - |  - |  - |  - |        M7C        | Color sprite 7
--+-------+----+----+----+----+-------------------+------------------------
pc7104

Obrázek 4: S využitím jednoduchého triku je možné zobrazit i více spritů než osm, jak je ukázáno na tomto screenshotu. Jediné omezení spočívá v tom, že se na jednom obrazovém řádku nesmí vyskytovat více než osm spritů, jejich celkový počet je limitován pouze výpočetním výkonem mikroprocesoru.

4. Sprity zobrazené v režimu hi-res

Sprity podporované čipem VIC-II mohou být zobrazeny, podobně jako pozadí (viz předchozí část tohoto seriálu), buď v režimu hi-res (vyšší horizontální rozlišení, jeden bit na pixel) nebo multi-color (poloviční horizontální rozlišení, dva bity na pixel). Režim zobrazení každého spritu lze nastavit příslušným bitem v registru 28 (sprite multicolor). Nejprve si popíšeme způsob zobrazení spritu v režimu hi-res. V tomto režimu má sprite rozlišení 24×21 pixelů, přičemž každý pixel je reprezentován pouze jediným bitem. Z toho vyplývá, že bitmapa se spritem má velikost 63 bytů, protože 24×21/8=63. V případě, že má bit odpovídající pixelu ve spritu hodnotu 0, jedná se o průhledný pixel, tj. příslušným pixelem může prosvítat buď jiný sprite nebo pozadí (v závislosti na tom, o který sprite se jedná). Pokud je bit odpovídající danému pixelu nastavený na hodnotu 1, je pixel vybarven barvou přečtenou z řídicího registru 39–46, opět v závislosti na tom, o který sprite 0–7 se jedná. Pomocí řídicího registru 23 a 29 je možné zvolit zvětšení spritu v horizontální či vertikální ose. Pokud je bit příslušný danému spritu nastaven na jedničku, je sprite 2× zvětšen buď v horizontální (registr 29) či vertikální (registr 23) ose, tj. nezmění se rozlišení spritu ale velikost jeho pixelů.

pc7105

5. Sprity zobrazené v režimu multi-color

V případě, že je mód zobrazení spritu nastavený do režimu multi-color, jsou pro každý pixel ve spritu vyhrazeny dva bity. Velikost obsazené paměti zůstává zachována – 63 bajtů, ovšem horizontální rozlišení spritu se v tomto režimu snižuje na 12 pixelů a pixely mají dvojnásobnou šířku oproti režimu hi-res. Vzhledem k tomu, že je pomocí dvou bitů možné zakódovat celkem čtyři stavy, je určení barvy pixelu zajímavější než v režimu hi-res. Všechny sprity spolu sdílí dvě společné barvy z barvové palety, přičemž indexy těchto barev jsou uloženy v řídicích registrech 37 a 38. Třetí barva je pro každý sprite individuální – viz řídicí registry 39–46. Poslední bitová kombinace odpovídá pozadí, tj. v tomto případě je pixel spritu průhledný. I v režimu multi-color je možné sprity zvětšit v horizontální i vertikální ose, ovšem s tím rozdílem, že zvětšení v ose horizontální je buď dvojnásobné nebo čtyřnásobné oproti základní velikosti pixelu (odpovídající grafickému režimu hi-res).

pc7106

6. Zobrazení většího množství spritů

V předchozích kapitolách jsme si řekli, že bitmapa každého spritu je vždy uložena v 63 bajtech, bez ohledu na to, zda se jedná o sprite zobrazovaný v režimu hi-res či multi-color. Těchto 63 bajtů je umístěno v adresovém prostoru o velikosti 16 kB, do kterého má v daném okamžiku čip VIC-II přístup (minule jsme si řekli, že tento čip dokáže přímo adresovat pouze 16 kB paměti, jelikož má na adresovou sběrnici vyvedeno pouze 14 vodičů). Mikroprocesor může změnit počáteční adresu bitmapy reprezentující sprite v krocích po 64 bajtech, což mj. znamená, že změna zobrazovaného tvaru je velmi rychlá – jedná se o přepis jediného bajtu. Pokud programátor dokáže ve chvíli, kdy elektronový paprsek neprovádí vykreslování, změnit adresu, na které se nachází bitmapa spritu, souřadnice spritu a popř. i jeho barvu (barvy), je možné zvýšit celkový počet zobrazitelných spritů z původních osmi až na řádově stovky. Platí zde jediné omezení – na jednom obrazovém řádku se vykreslí pouze osm pixelů, jejichž podobu není možné měnit. Důvodem je to, že VIC-II si na začátku každého obrazového řádku přečte aktuální řádek každého spritu (tj. tři bajty) do svých interních bufferů, které jsou na výše zobrazeném blokovém schématu označeny „8×24 bit sprite data buffers“. Právě díky tomu, že je obsah těchto bufferů obnovován v každém obrazovém řádku, je umožněno zvýšení celkového počtu spritů i postupná změna jejich souřadnic.

pc7107

Obrázek 7: Demo, ve kterém se současně (na jedné obrazovce) zobrazuje 144 spritů.

7. Další vlastnosti čipu VIC-II, zvýšení počtu barev v režimu FLI

Ke grafickému čipu VIC-II bylo možné připojit světelné pero. Při stisku tlačítka na světelném peru se na základě výpočtu souřadnic elektronového paprsku, který vykresluje obraz, zaznamenala x-ová a y-ová souřadnice pera. Obě souřadnice se však ukládaly pouze do osmi bitů, to znamená, že x-ová souřadnice měla poloviční přesnost než rozlišení obrazovky. Jinými slovy – horizontální souřadnici bylo možné zjistit s přesností na dva pixely. Ovšem pro většinu uživatelů byly důležitější jiné vlastnosti čipu VIC-II, které do značné míry zapříčinily úspěšnost a oblíbenost C64. Tyto vlastnosti budou popsány v následujících odstavcích.

pc7108

Obrázek 8: Statický obrázek vytvořený v režimu FLI.

Pomocí podprogramů spouštěných při přerušení (interrupt) vyvolávaného v průběhu zpětného horizontálního a vertikálního běhu elektronového paprsku obrazovky, tj. v době, kdy nedocházelo k přímým změnám obrazu, bylo možné vytvářet různé grafické efekty, například výše popsané zobrazení více spritů. Pravděpodobně nejzajímavějším efektem byl trik takzvaný FLI – Flexible Line Interpretation, ve kterém se využívalo přeprogramování čipu VIC-II tak, aby se barvové atributy nenačítaly až po zobrazení osmi řádků, ale na každém obrazovém řádku zvlášť (barvové atributy si čip uchovával v bloku 40×12 bitů, který je zobrazený na výše uvedeném blokovém schématu). Tímto způsobem bylo možné měnit barvovou paletu (přesněji čtyři současně použitelné dostupné barvy) nikoli v blocích 8×8 resp. 4×8 pixelů, ale v bloku 8×1 resp. 4×1 pixelů. Zvýšilo se tak barevné rozlišení rastrové grafiky. Tento trik byl používán ve velké míře pro statické obrazy a podporovaly ho i některé grafické editory – viz též screenshoty 8 a 9.

pc7109

Obrázek 9: Další statický obrázek, pro jehož zobrazení byl použit režim FLI.

8. Režim IFLI

Dalším režimem, který se používal pro zvýšení počtu současně zobrazených barev, se nazýval IFLI, což je zkratka celého názvu Interlaced Flexible Line Interpretation. Ve své podstatě se jedná o kombinaci dvou grafických efektů. První efekt – FLI – jsme si ve stručnosti popsali v předchozí kapitole. Druhý současně aplikovaný efekt spočívá ve využití dvou samostatných obrázků, které jsou při vykreslování na obrazovce neustále přepínány – v sudém půlsnímku je vykreslen první obrázek, v půlsnímku lichém obrázek sudý, navíc jsou snímky oproti sobě posunuty o jeden pixel (přepínání snímků je snadné – přes I/O port je možné změnit paměťovou banku, ze které čip VIC-II načítá barvové atributy i vlastní bitmapu). Tento efekt je tedy nutné načasovat přesně na dobu, kdy probíhá vertikální zpětný běh elektronového paprsku. Vlivem rychlého přepínání mezi dvojicí barev na ploše jednoho pixelu je možné dosáhnout zdánlivého výskytu třetí barvy, která dokonce ani nemusí ležet v barvové paletě standardních šestnácti barev C64. Tento režim samozřejmě vyžaduje dvojnásobné množství obrazové paměti a v případě, že na obou obrázcích jsou rozdíly větší než několik desítek pixelů, může být poblikávání nepříjemné.

pc7110

Obrázek 10: Statický obrázek vykreslený v režimu IFLI.

root_podpora

9. Literatura a odkazy na Internetu

  1. Sprite (computer graphics)
    http://en.wiki­pedia.org/wiki/Spri­te_(computer_grap­hics)
  2. Sprite (počítačová grafika)
    http://cs.wiki­pedia.org/wiki/Spri­te_(počítačová_gra­fika)
  3. Elektor TV Games Computer
    http://en.wiki­pedia.org/wiki/E­lektor_TV_Games_Com­puter
  4. C64.com
    http://www.c64­.com/
  5. C64 Wiki
    http://www.c64-wiki.com/index­.php/C64
  6. The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64
    http://www.zim­mers.net/cbmpic­s/cbm/c64/vic-ii.txt
  7. Wikipedia: Commodore 64
    http://en.wiki­pedia.org/wiki/C64
  8. Wikipedia: Video Display Controller
    http://en.wiki­pedia.org/wiki/Vi­deo_Display_Con­troller
  9. Wikipedia: MOS Technology VIC-II
    http://en.wiki­pedia.org/wiki/MOS_Techn­ology_VIC-II
  10. Wikipedia: List of Commodore 64 games
    http://en.wiki­pedia.org/wiki/Lis­t_of_Commodore64_ga­mes
  11. Wikipedia: Commodore 64 demos
    http://en.wiki­pedia.org/wiki/Com­modore64_demos
pc7111

Obrázek 11: Další statický obrázek vykreslený v režimu IFLI.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.