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

    Alguma vez aconteceu de voc ter aquela rotina quase concluda e
quando foi test-la viu  que  estava faltando alguma coisa?!  Bem...
se no aconteceu voc  um sortudo...  Quando eu estava comeando  a
entender  o funcionamento da placa VGA me dispus a construir rotinas
bsicas de  traagem  de  linhas  horizontais  e verticais... porm,
quando tinha algum bitmap atrs da linha acontecia  uma  desgraa!!!
Parte do bitmap sumia ou era substitudo por uma sujeirinha chata!

    Obviamente  eu  ainda  no  tinha  dominado  o  funcionamento da
placa... por isso, vamos continuar com os nossos estudos...


     A mascara de bits e os LATCHES da VGA.

    Existe uma maneira  de  no  alterarmos  bits indesejveis em um
byte de cada plano...  Suponha que queiramos modificar apenas o  bit
mais  significativo  de  um  byte  nos  planos  de  bits, deixando o
restante exatamente como estavam antes!

    Well...  Isso pode ser feito  de  duas formas:  Primeiro lemos o
byte de um plano, realizamos um OR ou um AND com esse byte e o  byte
com  o  bit  a  ser alterado (zerando-o ou setando-o de acordo com a
modificao que faremos...  veja  as  instrues  AND  e  OR num dos
textos iniciais do curso de ASM para ter um  exemplo  de  como  isso
pode  ser feito!)... depois da operao lgica, escrevemos o byte na
mesma posio... Essa  a maneira mais dispendiosa!

    A placa  VGA  permite  que  criemos  uma  mascara  de  bits para
podermos alterar apenas aqueles bits desejados...  Isso  feito pelo
registrador BitMask.  Mas, antes temos que  ler  o  byte  inteiro...
hummm...  acontece que existe um registrador intermedirio, interno,
que retm o ltimo byte lido de um plano de bits... esse registrador
 conhecido como LATCH.

    Basta ler um byte da memria  do sistema que os bytes dos quatro
planos de bits vo para seus LATCHES...  Depois precisamos  mascarar
os  bits  que  no queremos modificar no registrador BitMask para s
ento escrever na memria  do  sistema  (no  plano de bits!)...  No
esquecendo de setar os planos  de  bits  que  queremos  alterar  via
MapMask, como visto no ltimo texto!

    O  funcionamento  dos  latches  em  conjunto  com  BitMask    o
seguinte:   Uma vez carregados os latches, apenas os bits ZERADOS de
BitMask sero copiados de volta  para os planos de bits selecionados
por  MapMask.   Em  contrapartida,  os  bits  SETADOS   em   BitMask
correspondem  aos  bits  vindos  da  memria  do  sistema,  que  so
fornecidos  pela  CPU.   Dessa  maneira  a  nossa rotina no tem que
propriamente ler o contedo de  um  plano  de bits (alis, o que for
lido pela CPU pode muito bem ser ignorado!)... no necessitamos  nem
ao  menos  efetuar  operaes  lgicas  para  setar  ou  resetar  um
determinado bit do byte que ser escrito num plano de bits!

    Vmos  no  ltimo  texto  que  o  registro  MapMask faz parte do
circuito SEQUENCIADOR da VGA.  O registro BitMask est localizado em
outro circuito.  Mais  exatamente  no  controlador grfico (Graphics
Controller  - que chamaremos de GC)...  O funcionamento  o mesmo do
que o circuito sequenciador, em  termos  de endereos de I/O, citado
no ltimo texto:  Primeiro devemos informar o nmero do  registro  e
depois  o valor.  O GC pode ser acessado a partir do endereo de I/O
03CEh e o nmero do registro BitMask  8.

    Eis nosso segundo exemplo:

 Ŀ
   ; VGA2.ASM                                                     
   ; Compile com:                                                 
   ;                                                              
   ;   TASM vga2                                                  
   ;   TLINK /x/t vga2                                            
   ;                                                              
   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    ; Seleciona planos 0 e 2...            
                                                                  
       mov     ax,0502h    ; dem a fazer: mov al,2               
                           ;               mov ah,0101b           
                                                                  
       out     dx,ax                                              
                                                                  
       mov     dx,03CEh    ; Mascara todos os bits,               
       mov     ax,8008h    ;  exceto o bit 7                      
       out     dx,ax                                              
                                                                  
       mov     al,[byte es:bx]     ; carrega os latches da VGA    
                                   ;  note que AL no nos         
                                   ;  interessa!!!                
       mov     [byte es:bx],0FFh   ; Escreve 0FFh                 
                                                                  
       sub     ah,ah       ; Espera uma tecla!                    
       int     16h         ; ... seno no tem graa!!! :)        
                                                                  
       mov     ax,3        ; Volta p/ modo texto 80x25            
       int     10h                                                
                                                                  
       int     20h         ; Fim do prog                          
                                                                  
   end start                                                      
 

    Temos algumas novidades aqui...  Primeiro:   possvel  escrever
o  nmero  de um registro e o dado quase que ao mesmo tempo... basta
usar a instruno OUT DX,AX - recorra a textos anteriores para ver o
funcionamento dessa  instruo!.   Segundo:   mesmo  escrevendo 0FFh
(todos os bits setados) na memria do sistema, apenas o bit que  no
est mascarado ser modificado, graas ao BitMask!!  Terceiro:  Mais
de  um  plano  de  bits  pode ser alterado ao mesmo tempo!  Note que
nesse cdigo escrevemos na  memria  de  vdeo  apenas  uma vez e os
planos 0 e 2 foram alterados (continua a cor MAGENTA, no?!).


     Problemas  vista!

    Ok... aparentemente a  coisa  funciona  bem...  dai  eu fao uma
simples  pergunta:   O que aconteceria se o ponto em (0,0) estivesse
inicialmente "branco" e usassemos a rotina acima?!

    Hummmm...  Se o ponto   branco,  a  cor   15...  15  1111b em
binrio, ou seja, todos os planos de bits teriam o bit 7 do primeiro
byte setados...  A rotina acima "seta" os bits 7  do  primeiro  byte
dos planos 0 e 2... assim  a  cor CONTINUARIA branca!!  MAS COMO SOU
TEIMOSO, EU QUERO MAGENTA!!!

    A soluo seria colocar as seguintes linhas antes  da  instruo
"sub ah,ah" na listagem acima:

 Ŀ
   mov     dx,03C4h    ; Seleciona os planos 1 e 3                 
   mov     ax,0A02h                                                
   out     dx,ax                                                   
                                                                   
   mov     [byte es:bx],0 ; escreve 0 nos planos 1 e 3             
 

    Precisamos zerar os bits 7  dos  planos  1  e 3...  Note que nas
linhas acima no carreguei os latches da VGA atravs  de  leitura...
alis... no carreguei de forma  alguma.   No preciso fazer isso os
latches dos planos 1 e 3 no foram  alterados  desde  a  sua  ltima
leitura...   repare  que  no  "desmascarei"  os  bits  no  registro
BitMask... dai no ter  a  necessidade  de mascar-los de novo... s
preciso escrever 0 nos planos 1 e 3 para que o bit 7 seja alterado.

    Puts... que  mo-de-obra!!...   Felizmente  existem  meios  mais
simples  de  fazer  isso tudo...  Ahhhhhh, mas  claro que isso fica
pra um prximo texto! :))
                                                              
