---- na VGA ---- Jakákoliv barva se dá složit z poměrů tří základních barev: červené (Red), zelené (Green) a modré (Blue) - ve zkratce RGB. Bílá barva vznikne jestliže jsou všechny složky plně naplněny, černá když všechny chybí, fialová stejným zastoupením červené a modré a vynecháním zelené.... Takhle by se dalo pokračovat do nekonečna. Na adaptéru VGA je každá složka 6-bitová - tzn. že může nabívat hodnot od 0 do 63. Počet kombinací barev je tedy 64x64x64=262144 barev. Pixel je ale jen 8-bitový, takže může být najednou zobrazeno 256 barev z 262144 možných kombinací (samozřejmě v některých módech můžete zobrazit i víc barev). Teď pár pojmů a názvů: CLUT (Color Look Up Table) - tabulka s 256 18-bitovými (na zpracování každé barvy stačí 3*6 bitů=18) údaji REGISTRY ČÍSLICOVĚ ANALOGOVÉHO PŘEVODNÍKU: PEL Address (write mode) - R/W - port 3C8h - používá se k zápisu pozice v CLUT (jaká barva se má nastavovat) PEL Address (read mode) - WO - port 3C7h - používá se k zápisu pozice v CLUT, když z ní chceme číst jednotlivé složky RGB (od jaké barvy se bude číst) DAC State - RO - port 3C7h - čtení pozice v PEL PEL Data - R/W - port 3C9h - čtení/zápis jednotlivých složek -RGB PEL Mask - R/W - port 3C6h - vnitřně maskuje všechny R, G a B - zápisem 0 na tento port se dá rychle ztmavit obrazovka. R/W - čtení i zápis RO - jen čtení WO - jen zápis Po každém vstupu na port 3C9h se automaticky pozice v CLUT zvýší o jedna. Jak nastavit jednu barvu z palety? Mohlo by to vypadat takhle: procedure setrgb(barva,r,g,b:byte); assembler; asm mov al,[barva] {al <- barva } mov dx,3c8h {dx <- 3c8h } out dx,al {port[3c8h] <- al} inc dx {dx <- dx+1 } mov al,[r] {al <- r } out dx,al {port[3c9h] <- al} mov al,[g] {al <- g } out dx,al {port[3c9h] <- al} mov al,[b] {al <- b } out dx {port[3c9h] <- al} end; Ta je vhodná na nastavení jedné barvy, pokud nastavujete celou paletu, nebo souvislý blok palety, dá se využít (zneužít) automatického nastavování Dac write index registru - po 3. outu na port 3C9h se obsah 3C8h zvýší o jedničku a můžete si vesele dál zapisovat po sobě jdoucí složky RGBRGBRGB... anižbyste se před každou barvou zdržovali se zápisem na 3C8h. type paleta:array[1..768] of byte; {256*3} var pal:paleta; procedure setpal(pal:paleta); var i:word; begin port[3c8]:=0; for i:=1 to 768 do port[3c9]:=pal[i]; end; begin pal[1]:=63; . {naplneni promene pal} . setpal(pal); {a nastaveni palety na pal} ... end; - Pokud programujete např. v Pascalu nemusíte používat assembler - můžete rovnou psát na porty. Je dobré udělat si typ paleta se kterým se potom dobře pracuje. Zjišťování aktuální paletky se dělá stejně, jen s tím rozdílem že se k zápisu od jaké barvy se bude číst se používá port 3C7h. - Tady je př.: procedure getpal(var pal:paleta); var i:word; begin port[3c7]:=0; for i:=1 to 768 do pal[i]:=port[3c9]; end; procedure getrgb(barva:byte; var r,g,b:byte); begin port[3c7]:=barva; r:=port[3c9]; g:=port[3c9]; b:=port[3c9]; end; • Fade-in • Fade-out • Fade-up • Fade-to-pal • Fade-to-gray • Fade-from-gray Fade je např. použit ve Výhni při "rozsvěcování" a "zhasínámí" obrázků a textu - pomocí něho lze docílit např. plynulý přechod mezi 2 různými obrázky - první nejdříve plynule ztmavne do černa a druhý se plynule rozsvítí - je to celkem efektní a hlavně příjemné na oči. Není na tom nic těžkého, jde o to že se postupně snižuje (zvyšuje) jas barev (u Fade-in a Fade-out). Tady máte procedůrky: procedure fadein(pal:paleta); {zesvetleni z cerna do pal} var i,j:word; begin port[3c8]:=0; for j:=0 to 63 do begin retrace; {cekani na paprsek - viz poznamka} for i:=1 to 768 do port[3c9]:=pal[i]*j div 63; {nastavovani jasu kazde slozky} end; end; procedure fadeout(pal:paleta); {ztmaveni z pal do cerna} var i,j:word; begin port[3c8]:=0; for j:=63 downto 0 do {tady je jediny rozdil - misto zesvetleni} begin {se ztmavuje} retrace; for i:=1 to 768 do port[3c9]:=pal[i]*j div 63; end; end; DŮLEŽITÁ POZNÁMKA: Paleta by se měla nastavovat v dobu kdy není žádná informace posílána na DAC - jinak se na obrazovce objeví "sněžení" před každým nastavováním palety se tedy musí počkat až paprsek dojede dolu a vrací se - pak tento efekt nevzniká. Čekání na paprsek: procedure retrace; assembler; asm mov dx,3dah {dx <- 3dah } @1:in al,dx {al <- port[3dah] } test al,8 {testuje bit 8 v al } jz @1 {jestli je 0 tak skoc na @1} @2:in al,dx {al <- port[3dah] } test al,8 {tesuje bit 8 v al } jnz @2 {jestli je 0 tak skoc na @2} end; Další problém je jestli se celá paleta stačí naplnit než se paprsek vrátí. Na 8086 nikdy, na 286 málokdy, na 386 většinou ano a na 486 už vždycky. 1/2 výheň