---- 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ň