
          ͻ
                    Tutorial de Assembler de Adam Hyde 1.0        Ŀ
                                                                   
                                   PARTE XI                        
                      Traduzido por Renato Nunes Bastos            
          ͼ 
            


Verso   :  1.2
Data     :  19-12-1996
Contato  :  blackcat@vale.faroc.com.au
            http://www.faroc.com.au/~blackcat
;Renato  :  bastos@lci.ufrj.br
            krull@geocities.com
            http://www.geocities.com/SiliconValley/Park/3174



Nota: O Tutorial de Assembler de Adam  PROTEGIDO POR DIREITOS AUTORAIS, 
	e todos os direitos so reservadas pelo autor. Voc pode redistribuir 
	s o arquivo ORIGINAL livremente, e os tutoriais no deveriam ser 
	editados de qualquer forma. 

(by Renato - antes que algum me pergunte, desde o incio, antes de traduzir a
 1 palavra do Tutorial 1, eu j havia pedido ao Adam a permisso para fazer isso,
 OK? Suponho que eu possa traduzir, j que ele deixou - embora, como ele mesmo disse,
 ele no entenda nada de Portugus, ou Espanhol -- tinha algum traduzindo para 
 Espanhol.)

  

Bem, este tutorial realmente chega atrasado e eu me sinto particularmente 
culpado sobre isto. Todavia, eu ainda inclu outro programa demonstrativo com 
esta edio de forma que isto compensa um pouco. 

Apenas uma palavrinha sobre o ltimo programa de demonstrao - FIRE!.  
Depois de obter uma verso mais recente do TASM, eu descobri aquele FIRE! no gosta 
de compilar tudo direitinho, assim tenha certeza de que voc tem a verso 
mais recente do Tutorial Oito (V 1.4) com o bugfix (by Renato - hmmmm, no sei que 
erro  esse, e no tenho essa verso 1.4 - o cara sumiu - se algum souber 
de algum erro me diz que vou ver se sei consertar). Voc sempre pode obter 
diretamente todas as revises mais novas dos tutoriais de 
ftp.faroc.com.au no diretrio /pub/blackcat/programming/tutorials, e isso  
altamente recomendado. 

De qualquer maneira, vamos l com: 


  

          Ŀ
                                                                    
                              E/S DE ARQUIVOS                   	   
                                                                    
          


Cedo ou tarde, voc vai querer mexer com arquivos. Tudo que voc tem que 
ter em mente aqui  que tudo  BASEADO EM HANDLES. Aqueles de vocs que usaram ou 
experimentaram com XMS percebero o que eu quero dizer com handles 
exatamente, mas se voc no, ento aqui vai um resumo rpido: 

  * Voc abre/cria um arquivo. 
  * Voc recebe um inteiro de 16 bits sem sinal para referenci-lo. 

Qual a dificuldade nisso? 


Nota: Antigamente, antes do DOS 2, voc tinha que usar Blocos de Controle de 
Arquivo (FCB) para referenciar seus arquivos. (Voc provavelmente j viu 
FCBS=xxxx em arquivos de CONFIG.SYS, e isso  para ajudar programas que 
foram projetados para o XT.)  Ns podemos esquecer agora tudo sobre FCBs, j
eles esto quase obsoletos. 


  

  Abrindo UM Arquivo:           (Interrupo 21H) 

   AH = 3DH 
   AL = tipo de operao: 

            0 = operao s de leitura; 
            1 = operao s de escrita; 
            2 = operao de leitura/escrita. 

   DS:DX = nome do arquivo


  Retorna: 

   Se foi realizada com sucesso, o flag de carry  zerado, e o handle de arquivo 
    returnado em AX. Porm, se algo saiu errado, o flag de carry  setado em um, 
   e o cdigo de erro volta em MACHADO. Para uma lista de todo os cdigos de erro,
   veja a seguinte tabela mais abaixo. 


Agora, depois de tudo isso, um exemplo: 


   .MODEL SMALL
   .STACK 200H
   .DATA

      FileName   DB "EXAMPLE.TXT$"
      Error      DB "Uh oh$"

   .CODE

   START:

      MOV   AX, @DATA               ; Aponta AX para o segmento de dados
      MOV   DS, AX                  ; AX --> DX
      MOV   DX, OFFSET FileName     ; Pe o offset do arquivo a abrir em DX
      MOV   AH, 3DH                 ; Abre
      MOV   AL, 00H                 ; s para leitura
      INT   21H

      JC    Problem                 ; Aconteceu algo de errado?

      ; Aqui voc deveria ter o handle AX, e fazer alguma coisa

      JMP   Done                    ; Nada

   Problem:

      MOV   DX, OFFSET Error        ; Uh oh
      MOV   AH, 09H
      INT   21H

   Done:

      MOV   AX, 4C00H               ; Pula de volta pro DOS - fechando qualquer 
      INT   21H                     ; arquivo aberto. Relaxado, ns ainda no sabemos 
                                    ; como fechar arquivos.
   END START


  

OK... simples bastante, espero. Agora, suponha que queiramos criar um 
arquivo novo?  apenas uma outra subfuno simples da interrupo 21H.  
 assim que se faz:


  Criando UM Arquivo Novo:      (Interrupo 21H) 

   AH = 3CH 
   CX = tipo de arquivo: 

            0 = arquivo normal; 
            1 = s de leitura; 
            2 = arquivo escondido; 
            4 = arquivo de sistema; 

   DS:DX = nome do arquivo 


  Retorna: 

   Como antes, se realizar com sucesso, o flag de carry  zerado, e o
   handle do arquivo  retornado em AX. Note que voc deve tomar cuidado
   com arquivos existentes antes de criar um arquivo novo com mesmo nome.  
   O DOS no conferir se um arquivo do mesmo nome j existe, e escrever 
   por cima do velho.

   Antes de criar um arquivo novo - tente abrir o arquivo primeiro. Se 
   voc obtiver o cdigo de erro 2 em AX, (arquivo no existe), ento prossiga e 
   crie o arquivo novo. Se voc no conseguiu o erro 2, voc estar escrevendo 
   por cima de um arquivo j existente! 


  

Como voc deveria saber de experincias com linguagens de alto-nvel, voc tem que 
fechar seus arquivos antes de terminar seu programa. (Na verdade, a funo
4CH fecha todos os arquivos abertos de qualquer maneira, mas isso  um modo 
relaxado de fazer as coisas.) Para fechar um arquivo aberto, voc deveria fazer 
isto: 


  Fechando UM Arquivo:           (Interrupo 21H) 

   AH = 3EH 
   BX = handle de arquivo 


  Retorna: 

   De novo, qualquer erro  refletido no flag de carry e AX.


  

Finalmente, cdigos de erro. Apenas checando o CF para ver se qualquer 
coisa saiu errado, nos deixar saber certamente se algo est faltando, 
mas ns realmente gostamos de mais detalhes. Examinar o AX depois de um erro 
ser descoberto  o caminho a seguir, e AX poderia conter qualquer um dos 
cdigos seguintes: 


        ͻ
          Cdigo  Explicao                                        
        Ķ
         	00H 	 erro Desconhecido 					     
         	01H 	 nmero de funo invlido				     
         	02H 	 Arquivo no achado					     
         	03H 	 Caminho no achado 					     
         	04H 	 muitos arquivos abertos				     
         	05H 	 Acesso negado 						     
         	06H 	 handle invlido						     
         	07H 	 Blocos de controle destrudos			     
         	08H 	 Falta de memria 					     
         	09H 	 endereo de bloco de controle Ruim 		     
         	0AH 	 ambiente invlido					     
         	0BH 	 formato invlido					     
         	0CH 	 cdigo de acesso invlido				     
         	0DH 	 dados invlidos						     
         	0EH 	 erro desconhecido					     
         	0FH 	 drive invlido						     
         	10H 	 no pode remover diretrio atual 			     
         	11H 	 Dispositivo no  o mesmo 				     
         	12H 	 mais nenhum arquivo disponvel 			    
         	13H 	 Disco protegido contra escrita			     
         	14H 	 unidade Ruim 						     
         	15H 	 Drive no pronto 					    
         	16H 	 comando Desconhecido 					     
         	17H 	 erro de CRC						     
         	18H 	 tamanho de estrutura ruim				     
         	19H 	 erro de procura						     
         	1AH 	 mdia invlida						    
         	1BH 	 Setor no achado					     
         	1CH 	 Impressora desligada ** 				     
         	1DH 	 erro de escrita						     
         	1EH 	 erro de leitura						     
         	1FH 	 falha geral 						     
	  ͼ 


  ** Eu sei, eu no cheguei l ainda. Eu acho que isso est l porque o DOS
     trata tudo como arquivo. 

Ufa!  Tudo cortesia da boa e velha referncia tcnica do DOS. Algum deles l 
encima so bem obscuros - na verdade s h alguns que voc precisa de se lembrar.  
Algum de meu *favoritos * :  Setor no achado, Erro de procura e Erro de CRC  
no meio de uma pilha de disquetes relaxados arjeados.  o tipo de porcaria
que traz recordaes.  :) 


  

Certo, assim ns vimos como criar, abrir e fechar arquivos. Agora vamos fazer
algo com eles. Para ler alguns bytes de um arquivo, voc tem que usar funo 
3FH. Assumindo que voc j abriu o arquivo de onde voc quer ler, voc pode 
usar um pouco de cdigo como o abaixo: 


   MOV   AH, 3FH                      ; L byte(s)
   MOV   BX, Handle                   ; arquivo a trabalhar
   MOV   CX, BytesToRead              ; quanto a ler
   MOV   DX, OFFSET WhereToPutThem    ; um array ou varivel
   INT   21H

   JC    DidSomethingGoWrong          ; Checa erros


Se voc est tendo problemas em sacar algo disso - no se preocupe muito. Apenas
volte aos exemplos acima e veja como pode fazer sentido.  
Prximo tutorial ns continuaremos com sprites - (e como carrreg-los do disco) - 
assim voc ver um bom exemplo.

Bem... agora, escrevendo em um arquivo. Muito semelhante a ler, ns usamos a funo 
40H. Um cdigo para escrever um byte se pareceria com isso: 


   MOV   AH, 40H                      ; Escreve byte(s)
   MOV   BX, Handle                   ; arquivo para se escrever nele
   MOV   CX, BytesToWrite             ; quanto escrever
   MOV   DX, OFFSET WhereToWriteFrom  ; de onde os dados esto vindo
   INT   21H
   JC    DidSomethingGoWrong          ; algum erro?


Bem, aquilo quase conclui E/S de arquivos para este tutorial. Embora no seja um 
componente principal da peogramao da linguuagem Assembly, E/S de arquivos  todavia, 
um conceito importante para se pegar. 


  

          Ŀ
                                                                    
                        CHAMANDO O ASSEMBLER NO C/C++               
                                                                    
          


Eu suponho que j passou da hora de falar sobre como linkar o Assembler no C.  
Pessoalmente, eu prefiro codificar VGA numa combinao de Assembler/Pascal.  
Porm, C tem seu lugar, e linkar com C  um assunto importante que ns 
deveramos cobrir. 


Voc deve ter percebido que voc pode entrar cdigo Assembly em seu programa de 
C desse jeito: 


   / * Seu cdigo em C vai aqui * / 

   asm { 
                / * * / 
                / * Seu cdigo em Assembler vai aqui * / 
                / * * / 
   } 

   / * Seu cdigo em C continua daqui * / 


Agora, considerando que ns podemos inserir o Assembly diretamente no cdigo em 
C, por que nos preocuparamos em escrever cdigo externo? A resposta 
 bastante simples. Usando rotinas externas, temos cdigo que  mais 
rpido de se executar, mais rpido de compilar, que pode usar algumas das 
caractersticas especiais de Turbo Assembler - como modo ideal, e pode ser at mesmo 
portvel a outras linguagens. 

Escrever cdigo externo para C  bem simples, e  gratificantemente mais fcil 
que escrever cdigo externo para Pascal. (Veja o Tutorial Sete). Como voc 
pde observar no Tutorial Sete, ns tnhamos que declarar o segmento de cdigo e 
o de dados usando o a meio confusa diretiva SEGMENT. Isto  devido ao modo 
como o Pascal gosta de organizar a memria, e s h um modo de contornar
problema - ns podemos usar o modelo TPASCAL. Infelizmente, TPASCAL  um 
modo antiquado de fazer as coisas, assim ns temos que pr um pouco de trabalho 
nisso. Eu no vou falar novamente em TPASCAL, assim ns podemos nos esquecer 
seguramente de detalhes chatos. 


Note que nada disto aplica a ns em C - ns podemos usar felizmente nossos 
simples e agradveis esqueletos de Assembler. H algumas  
restries colocadas, entretanto, a ns pela maioria dos compiladores: 


    O compilador usa SI e DI para armazenar variveis registradoras.  Se voc usou 
variveis registradoras em seu cdigo, lembre-se de dar um push e pop em SI e DI em 
seu cdigo externo. 

    O compilador provavelmente no vai dar push e pop em CS, DS, SS e BP, ento 
tenha certeza de ter cuidado se for alterar algum desses registradores.


Alm desses pequenos detalhes, h pouco que ns precisamos ter em mente.
Vamos l!


  

OK... agora ns vamos escrever uma pequena rotina externa e linkar isto ao C. 
Vamos dar uma olhada num esqueleto bsico que apenas pe algum texto na tela. 


   ============================  LIBRARY.ASM  =============================


   .MODEL    SMALL
   .DATA

   Message   DB "Well looky here - we got ourselves some text$"

   .CODE

   PUBLIC    _sample

; ---------------------------------------------------------------------------

;
; void sample();
;

_sample      PROC   NEAR        ; Declara uma procedure near

   MOV   AH, 00H                ; Acerta o modo de video
   MOV   AL, 03H                ; Modo 03H
   INT   10H

   MOV   AH, 09H                ; Imprime uma string
   MOV   DX, OFFSET Message     ; DS:DX <-- Mensagem
   INT   21H

   RET                          ; Fora daqui!

_sample      ENDP

END


  

Bem.... no h nada muito engenhoso l. Agora, e o cdigo C que vai junto com isto? 


   =============================  EXAMPLE.C ==============================


   extern void sample();

   int main()
   {

      sample();
      return 0;

   }


  

E para compilar o lote, a linha abaixo far o trabalho. 

C:\> TCC EXAMPLE.C LIBRARY.ASM

Claro que, se voc est usando ento que outro "sabor" de C, substitua TCC com 
qualquer outro interpretador de linha de comando que voc tiver. Tambm  possvel 
fazer o C reconhecer variveis declaradas em Assembler, e o seguinte
esqueleto explica como isso  feito: 


   ============================  LIBRARY.ASM  =============================


   .MODEL SMALL
   .DATA

   PUBLIC _YourVariable      ; Declara uma varivel externa

   _YourVariable  DW 9999    ; Faz a varivel ser uma word valendo 9999

   .CODE

   END



   =============================  EXAMPLE.C ==============================


   extern int YourVariable;

   int main()
   {

      printf("The Assembler external variable is: %d", YourVariable);
      return(0);

   }


Novamente, compile isto com:  TCC EXAMPLE.C LIBRARY.ASM 


Mas que tal passar parmetros para suas rotinas?  Ns poderamos fazer isso  
do modo difcil, como ns fizemos com Pascal, ou alternativamente, poderamos usar a
diretiva ARG. 

ARG  brilhante, porque simplifica grandemente as coisas -- mas tem algumas 
negligncias. Isto , em toda rotina voc precisa de umas trs instrues 
adicionais. Se voc quer velocidade e no se incomoda com um pouco de trabalho duro, 
trabalhe diretamente com a pilha como ns fizemos no Tutorial Sete. 

Aqui est como se usa ARG: 


   ============================  LIBRARY.ASM  =============================


   .MODEL SMALL
   .DATA
   .CODE

   PUBLIC _putpixel        ; Declara a procedure externa

; ---------------------------------------------------------------------------
;
; void putpixel(int x, int y, char color, int location);
;

_putpixel   PROC NEAR

   ARG   X : Word, Y : Word, Color : Byte, Location : Word

   PUSH  BP                ; Salva BP
   MOV   BP, SP            ; BP *deve ser* igual a SP para ARG funcionar

   MOV   AX, [Location]    ; Parmetros podem ser acessados facilmente agora
   MOV   ES, AX
   MOV   BX, [X]
   MOV   DX, [Y]
   MOV   DI, BX
   MOV   BX, DX
   SHL   DX, 8
   SHL   BX, 6
   ADD   DX, BX
   ADD   DI, DX
   MOV   AL, [Color]
   MOV   ES:[DI], AL

   POP   BP                ; BP precisa ser restaurado!

   RET

_putpixel   ENDP

END


   =============================  EXAMPLE.C ==============================


   extern void putpixel(int x, int y, char color, int location);

   int main()
   {

      asm {
         mov   ax, 0x13
         int   0x10
      }

      putpixel(100, 100, 12, 0xa000);
      sleep(2);

      asm {
         mov   ax, 0x03
         int   0x10
      }

      return(0);
   }



No  to macetoso, hein? Porm, se voc escolher escrever rotinas externas
porque voc quer a velocidade que o Assembler pode lhe dar, ento acesse
a pilha do modo difcil. Esses extras push's e pop's realmente podem crescer
se sua rotina de putpixel for chamada 320x200 vezes! 


  

          Ŀ
                                                                    
                          UMA INTRODUO S MACROS                  
                                                                    
          


Macros so uma das caractersticas mais poderosas que voc tem  sua disposio 
quando est trabalhando com o Assembler. Freqentemente voc se achar 
repetindo as mesmas poucas linhas de cdigo inmeras vezes quando estiver escrevendo 
programas maiores. Voc no quer fazer aquela dificuldade de criar um 
procedimento -- que reduziria a velocidade do cdigo, mas voc no quer continuar 
se repetindo. 

A resposta.... MACROS. 


Uma macro  s um conjunto de instrues que recebe um nome pelo qual ela ser
referenciada no cdigo. Voc pode definir um macro assim: 


   MyMacroName    MACRO

      ;
      ; Suas instrues vo aqui
      ;

   ENDM           MyMacroName


E dali em diante, sempre que voc puser MyMacroName em seu cdigo, sero 
colocadas as instrues contidas dentro da macro no lugar do nome da macro. 


OBS.:  provavelmente melhor declarar qualquer macro antes de declarar o 
segmento de dados. Para ficar mais claro, coloque todas suas macros em outro arquivo 
de texto e ento use INCLUDE<nomedoarquivo> para incluir as macros. 


  

Macros tambm podem ter parmetros e podendo ser muito teis. Por 
exemplo, eu usei muito a funo DOS 09H para pr uma string na tela. Eu 
poderia fazer os programas que eu escrevo mais fceis de ler  primeira vista 
criando a seguinte macro: 

   PutText  MACRO TextParam

      MOV   AH, 09H                  ; TextParam  o parmetro--NO 
      MOV   DX, OFFSET TextParam     ; uma varivel.  Substitua TextParam com 
      INT   21H                      ; qualquer nome que voc escolher. 

   ENDM     PutText


Ento, assumindo no segmento de dados que eu tenha declarado uma string assim: 

   AString   DB "This is a string$"


Eu poderia exibir aquela string escrevendo: 

   PutText   AString


OBS.:  Quando voc est trabalhando com macros, tenha cuidado em observar 
	 que registradores elas mudam. Se estiver em dvida, d um push e um pop em 
	 quaisquer registradores que voc sente que possam ser afetados. 


  

Embora aquela macro simples realmente no fosse nada de especial, macros tm 
muitas outras utilidades. Eu no vou dizer mais nada sobre macros agora, 
mas eu as usarei de vez em quando em programas de demonstrao no futuro, e 
voc aprender outras tcnicas que voc pode pr em bom uso. 

De qualquer maneira, vamos ao que eu queria fazer: 


  

          Ŀ
                                                                    
                           O PROGRAMA DEMONSTRATIVO                 
                                                                    
          



No princpio eu ia lanar este tutorial sem um programa demo, mas 
vendo como eu fui um pouco preguioso esse tempo todo, (e tambm porque 
um amigo meu h pouco tempo fez uma demonstrao como essa), eu decidi 
incluir um demo de plasma. 

Plasmas podem ser um pouco engenhosas em umas partes -- me levou um bom tempo 
para fazer a coisa funcionar direito por causa de um problema que eu tive com 
minha tabela de lookup. Mas se voc seguir o algoritmo abaixo, voc 
no deve ter nenhum problema. 


 ***  Antes de comear, voc precisar de QUATRO variveis temporrias em       ***
	seu cdigo. Em Assembler isto pode se pr um pouco trabalhoso porque voc 
	se achar freqentemente com falta de registradores. Voc poderia declarar 
	alguns bytes no segmento de dados, mas  mais rpido usar registradores.  
	Estas quatro variveis temporrias armazenaro s nmeros entre 0 e 255, 
	assim elas s precisam ser BYTES. 

      No algoritmo, eu me refiro a estas variveis temporrias como Temp1, 
*** Temp2, Temp3 e Temp4.                                              *** 


O algoritmo se parece com isso: 


    Crie uma tabela de lookup 

      Isto  basicamente s uma senide longa. Voc pode experimentar 
	usar uma onda de co-seno, ou alterar a amplitude da funo que voc 
	est usando. Eu criei minha tabela de lookup usando a seguinte expresso: 

     For W := 1 To 512 Do
      SinTable[W] := Round(Sin(W / 255 * Pi * 2) * 128);

     (SinTable  um array de 512 BYTES)


    Inicialize a palette

      Eu pessoalmente gosto de fazer minhas palettes depois de ver o demonstrativo 
	rodando com a palette padro. Desse modo, fazendo certas cores escuras e outras 
	muito claras, o resultado  exatamente do jeito que eu quero.
	Eu descobri que o melhor modo de fazer isto  capturar a tela quando a demonstrao 
	est rodando, com um programa como Screen Thief, ento carregar aquela tela 
	em um programa de pintura que deixe alterar a palette. 

      Depois de conseguir a palette do jeito que voc quer, salve-a para o disco como 
	um arquivo COL (se possvel) e ento escreve um pequeno programa para ler no 
	arquivo COL e escrever um arquivo tipo o PLASMA.DAT. 

      Se lembre, Screen Thief  shareware, assim se voc for us-lo, envie para 
	o autor algum dinheiro, hein? 


Loop (1):  Antes de comear a plotar a primeira linha, voc deve: 

           * Zerar Temp4; 
           * Decrementar Temp3 de dois; 

             Voc pode fazer experincias com Temp3 -- quanto maior for o nmero
		 que voc subtrair, mais rpido o plasma vai mover. 

	   Voc agora vai para o Loop (2). 


Loop (2):  Ao incio de cada linha voc deve: 

           * Incrementar Temp4 de um; 
           * Fazer Temp1 = Sintable[Linha corrente + Temp3]; 
           * Fazer Temp2 = SinTable[Temp4]; 

	   Voc agora vai para o Loop (3). 


Loop (3):  Para todo pixel na linha atual voc deve: 

           * Calcular a cor daquele pixel a ser plotado; 

             O valor de cor daquele pixel  simplesmente definido por: 

             SinTable[Temp1 + Temp2] + SinTable[Linha corrente + Temp2] 

             Infelizmente, isto  um pouco mais difcil de calcular no 
		 Assembler e acaba levando muitas linhas de cdigo!! 


           * Incrementar Temp1 de um; 
           * Incrementar Temp2 de um; 


           Depois de fazer uma linha inteira, voc ento volta atrs ao Loop (2).

	     Uma vez feitas todas as linhas (200), voc pode ento voltar ao Loop (1).



Claro que, voc tambm vai querer pr algo para checar o retrace, e seria uma boa
idia tambm se algum apertou alguma tecla!! 


NOTA:  Para quem no sabe, o VGA tem um registrador de estado que vale a pena 
	 prestar ateno em que ele serve.  registrador 03DAH, e conferindo seus 
	 vrios bits, podemos ver o que est acontecendo com o VGA. 

       (Para aqueles que querem saber para qu so exatamente todos os bits,
	  ache que deveriam obter uma cpia da Ralf Brown's Interrupt List. Isto 
	  est disponvel na minha homepage e ela contm uma lista completa de todas 
	  as interrupes, registradores e muito mais.) 

       De qualquer modo, ns estamos s interessados no quarto bit do 03DAH que nos 
	 deixa saber se um retrace est acontecendo. Se pudermos acessar o VGA enquanto 
	 o canho de eltrons do monitor est voltando (retrace) ao topo da tela -- ns 
	 podemos obter um rpido acesso, livre de flicks (tremidas..., sacou? - by Renato)
	 O que  demais, j que o retrace acontece a cada 1/80 de segundo EM TODOS OS 
	 COMPUTADORES,  agora ns temos um mtodo de fazer que nosso demo rode numa 
	 velocidade especfica em todas as mquinas. 

       Para conferir se o retrace est acontecendo, ns examinamos simplesmente 
	 o bit quatro. Se o bit quatro est setado, um retrace est em execuo.
	 Porm, ns no sabemos o quanto de um retrace j aconteceu, e no sabemos 
	 quanto tempo de acesso live de flicks ns temos. A soluo  checar de novo
	 por um retrace, de modo que podemos estar seguros de que estamos no 
	 COMEO de um. 

       Eu usei retrace no cdigo para ter certeza de que o demo ia
	 rodar  mesma velocidade em todas as mquinas. (Mais ou menos). 


       Tambm note que meu plasma  mais uma variante de plasma. Voc pode, 
	 e  encorajado a alterar o cdigo -- (tente incrementar os valores de temp 
	 em vez de decrementar e mudar a quanto o valor de temp  decrementado ou 
	 mudar o modo como o valor das corer  achado. Tambm tente mudar a palette, 
	 porque isto pode fazer o plasma parecer completamente diferente). 

        possvel criar todos os tipos de efeitos s fazendo mudanas simples, 
	 assim, experimente... seja criativo! 


  

Bem, isso conclui as coisas para este tutorial. Eu no estou precisamente 
seguro sobre o que eu porei no Tutorial Dez (by Renato - que Tutorial 10? t 
sonhando... cad? bem que eu queria que eles continuassem. Se algum souber 
onde o Adam foi parar, me avise.) -- sero cobertos sprites, mas eu posso ver 
que os tutoriais talvez tendam a efeitos de demonstrao e como voc pode 
os codificar em Assembler puro. 

At a prxima vez,  (by Renato - hahaha. Engraadinho!)

-- Adam.


(by Renato - cad a finalizao de Sempre? Sobre pegar na prxima semana? 
 Parece que o cara j sabia que esse era o ltimo. 
 E agora, as minhas despedidas:
 Bom galera, agradeo a todos vocs que me ajudaram a continuar essa traduo,
 incentivando-me a terminar logo isso, sempre me escrevendo, cobrando.
 O interesse demonstrado por vocs foi fundamental para que isso acabasse. 
 Finalmente, a traduo desses tutoriais de Assembler terminaram.
 
 Se houver erros na traduo, ou alguma frase que no t dando pra entender,
 me avisem, que eu traduzo ela de novo!, de modo a ficar inteligvel.

 Valeu! 

 Agora, vou ver se eu comeo a traduzir os tutoriais de VGA do Denthor.
 Algum sabe onde ele foi parar tambm?

 bye,
 Renato Nunes Bastos, aka Krull
 Rio de Janeiro, 3 de Novembro de 1998)