
                               ASSEMBLY
                          Placas de vdeo e programao
                                Aula nr. 21 de 26

    Ol!!...  Acho que voc concorda comigo que essa srie de textos
no estaria completa se eu  no  falasse  alguma coisa a respeito de
progrmao da placa de vdeo VGA, n?!  Acho que ns temos razo  em
pensar assim! :)

    Inicialmente comearei a descrever  a  placa  VGA, depois vem as
descries da SVGA e VESA.  No pretendo gastar "trocentas" horas de
digitao e depurao de cdigo na descrio desses padres..  quero
apenas dar uma idia geral do funcionamento desses dispositivos para
que voc possa caminhar com as prprias pernas mais tarde...


     Video Graphics Array

    O  padro  VGA  o sucessor dos padres EGA e CGA, todos criados
pela IBM...  A diferena  bsica  do  VGA  para  os  outros dois  o
aumento da resoluo e de cores.  Eis uma comparao  dos  modos  de
maior  resoluo  e  cores  desses trs padres (aqui esto listados
apenas os modos grficos!):

     Ŀ
                            CGA        EGA        VGA     
     ͵
      Maior resoluo     640x200     640x350    640x480  
     Ĵ
       Maior nmero de       4          16         16     
            cores        (320x200)   (640x350)  (640x480) 
                                                          
                                                   256    
                                                (320x200) 
     

    O  padro  VGA  suporta  at 256 cores simultanemente no modo de
vdeo 13h (320x200x256).  E no modo de mais alta resoluo suporta o
mesmo nmero de cores que a EGA, que so apenas 16.

    Quanto ao  nmero  de  cores,  as  placas  EGA  e  VGA  so mais
flexveis  que  a  irm   mais   velha   (a   CGA).   As  cores  so
"reprogramveis", isto , de uma palette de 256k cores (256 * 1024 =
262144 cores), na VGA, podemos escolher 256...  Duma palette  de  64
cores  podemos  usar  16, na EGA...  A VGA , sem sombra de dvidas,
superior!

    A  forma como podemos selecionar essas cores todas ser mostrada
mais abaixo (Como  sempre  as  coisas  boas  so sempre deixadas pra
depois, n?! hehe).

    Em tempo:  O modo 640x480 (16 cores) ser usado como exemplo nas
prximas listagens dos textos daqui pra frente...  O modo grfico de
320x200 com 256 cores ser discutido em outra oportunidade, bem como
o famoso MODE X (modo de vdeo no documentado da VGA - e largamente
descrito por Michael Abrash em  seus  artigos  para  a  revista  Dr.
Dobb's).


     Memria de vdeo

    Existe  um  grande  obstculo  com  relao  a modos grficos de
resolues altas:   A  segmentao  de  memria!   Lembre-se  que os
processadores Intel enxergam  a  memria  como  blocos  de  64k  no
sequenciados  (na  verdade,  sobrepostos!)...   No  modo  grfico de
resoluo 640x480 da VGA (que  suporta  16 cores no mximo), suponha
que cada byte da memria de vdeo armazenasse  2  pixeis  (16  cores
poderia  equivaler a 4 bits, no poderia?!)...  Well isso nos d 320
bytes por linha (meio byte por pixel -> 640 / 2 = 320!).

    Com os 320 bytes por  linha  e  480 linhas teriamos 153600 bytes
numa tela cheia!  Ocupando  3  segmentos  da  memria  de  vdeo  (2
segmentos  contguos  completos  e mais 22528 bytes do terceiro!)...
Puts...  Imagine a complexidade  do  algoritmo que escreve apenas um
ponto no vdeo!  Seria necessrio selecionarmos o segmento do  pixel
e  o  offset...  isso  pra  aplicativos grficos de alta performance
seria um desastre!

    A  IBM  resolveu  esse  tipo  de  problema  criando  "planos" de
memria...  Cada plano equivale a um bit de um pixel.  Dessa  forma,
se  em  um  byte  temos  oito  bits e cada plano armazena 1 bit de 1
pixel... em um byte de  cada  plano  teremos  os 8 bits de 8 pixeis.
Algo como:  O byte no plano 0 tem os oito bits 0 de  oito  pixeis...
no  plano  1  temos  os  oito  bits  1 de oito pixeis... e assim por
diante.  De forma que o  circuito  da VGA possa "sobrepor" os planos
para formar os quatro bits de um  nico  pixel...   A  representao
grfica abaixo mostra a sobreposio dos planos:

            Ŀ
          Ŀ 
        Ŀ  
      Ŀ   
                                                     
                                                     
                                                    3
                                                   2
                                                  1
                                                0 
      

    Esses  so  os  quatro  planos  da memria de vdeo.  O plano da
frente   o  plano  0,  incrementando  nos  planos  mais interiores.
Suponha que na posio inicial de cada plano tenhamos  os  sequintes
bytes:

 Ŀ
   Plano 0: 00101001b                                             
   Plano 1: 10101101b                                             
   Plano 2: 11010111b                                             
   Plano 3: 01010100b                                             
 

    Os  bits  mais  significativos  de  cada  plano formam um pixel:
(0110b), os  bits  seguintes  o  segundo  pixel  (0011b), o terceiro
(1100b), e assim por diante at o oitavo pixel (1110b).  Como  temos
16 cores no modo 640x480, cada pixel tem 4 bits de tamanho.

    Com  esse  esquema  biruta temos um espao de apenas 38400 bytes
sendo usados para cada plano  de  vdeo...   Se cada byte suporta um
bit de cada pixel ento temos que uma linha tem 80 bytes de  tamanho
(640 / 8).  Se temos 480 linhas, teremos 38400 bytes por plano.

    Tome  nota  de duas coisas... estamos usando um modo de 16 cores
como exemplo para facilitar  o  entendimento  (os modos de 256 cores
so mais complexos!) e esses 38400 bytes em cada plano de bits   um
espao  de  memria  que pertence  placa de vdeo e  INACESSVEL a
CPU!!!!  Apenas a placa de vdeo pode ler e gravar nessa memria.  A
placa VGA (e  tambm  a  EGA)  usam  a  memria  RAM do sistema para
saberem quais  posies  de  um  (ou  mais)  planos  de  bits  sero
afetados.  Isso  assunto para o prximo tpico:


     A memria do sistema:

    Os  adaptadores  VGA  usam  o  espao  de "memria linear" entre
0A0000h  e  0BFFFFh  (todo  o  segmento  0A000h  e  todo  o segmento
0B000h)...  Essa memria  apenas uma rea de  rascunho,  j  que  a
placa  VGA  tem  memria  prpria...   A  CPU precisa de uma memria
fisicamente presente  para  que  possa  escrever/ler  dados... da a
existencia desses dois segmentos contguos de memria, mas a VGA no
os usa da mesma forma que a CPU!

    Citei dois segmentos contguos... mas no existe a limitao  de
apenas  um  segmento?!   Well... existe... o segmento 0B000h  usado
apenas nos modos-texto (onde o  segmento 0B800h  usado...  0B000h 
para o adaptador monocromtico - MDA)... os modos-grficos  utilizam
o  segmento 0A000h (a no ser aqueles modos grficos compatveis com
a CGA!).

    A memria do sistema  usada  como rascunho pela VGA (e pela EGA
tambm!!)...  A VGA colhe  as  modificaes  feitas  na  memria  do
sistema e transfere para a memria de vdeo.  A forma com que isso 
feito  depende  do  modo  com  que programamos a placa de vdeo para
faz-lo... podemos modificar  um  plano  de  bits  por vez ou vrios
planos, um bit por vez, vrios bits de uma vez, etc.  Na  realidade,
dependendo  do  modo  com que os dados so enviados para a placa VGA
no precisamos  nem  ao  menos  saber  O  QUE  estamos escrevendo na
memria do sistema, a VGA toma conta de ajustar a memria  de  vdeo
por  si  s,  usando apenas o endereo fornecido pela CPU para saber
ONDE deve fazer a modificao!


     Selecionando os planos de bits...

    Em todos os modos de  escrita precisamos selecionar os planos de
bits que sero afetados...  Isso  feito atravs de  um  registrador
da  placa  VGA:   MapMask...  Porm, antes de sairmos futucando tudo
quanto  endereo de I/O da  placa VGA precisamos saber COMO devemos
us-los!

    A maioria dos registradores da placa VGA  esto  disponveis  da
seguinte  maneira:  Primeiro informamos  placa qual  o registrador
que queremos acessar e  depois  informamos  o  dado a ser escrito ou
lido...  A tcnica  a seguinte:  escrevemos num endereo de  I/O  o
nmero  do  registrador... no endereo seguinte o dado pode ser lido
ou escrito...

    No caso de MapMask, este  registrador    o nmero 2 do CIRCUITO
SEQUENCIADOR  da  placa  VGA.   O  circuito  sequenciador  pode  ser
acessado pelos endereos de I/O 3C4h e 3C5h (3C4h conter  o  nmero
do registro e 3C5h o dado!).  Eis a estrutura do registro MapMask:

                            7 6 5 4 3 2 1 0
                           ͻ
                           ????    
                           ͼ
                                       
                                        plano 0
                                       plano 1
                                      plano 2
                                     plano 3

    De  acordo  com  o  desenho  acima...  os quatro bits inferiores
informam a placa VGA qual dos planos ser modificado.  Lembre-se que
cada plano tem um bit de um pixel (sendo o plano 0 o proprietrio do
bit menos significativo).  Vamos a nossa primeira rotina:

 Ŀ
   ; VGA1.ASM                                                     
   ; Compile com:                                                 
   ;                                                              
   ;   TASM vga1                                                  
   ;   TLINK /x/t vga1                                            
   ;                                                              
   ideal                                                          
   model tiny                                                     
   locals                                                         
   jumps                                                          
                                                                  
   codeseg                                                        
                                                                  
   org 100h                                                       
   start:                                                         
       mov     ax,12h      ; Poe no modo 640x480                  
       int     10h                                                
                                                                  
       mov     ax,0A000h   ; Faz ES = 0A000h                      
       mov     es,ax                                              
       sub     bx,bx       ; BX ser o offset!                    
                                                                  
       mov     dx,03C4h    ; Aponta para o registro               
       mov     al,2        ; "MapMask"                            
       out     dx,al                                              
                                                                  
       inc
                                           
