quarta-feira, 16 de junho de 2010

MSX - Redefinindo os Caracteres ASCII

E aí amigos como estão?

Hoje vou escrever sobre um assunto que eu adoro: o clássico computador MSX. Mais especificamente, vou mostrar como redefinir os caracteres na Screen 1 e alterar as cores também. É muito legal usar essas informações para criar jogos simples em modo texto. Redefinindo os caracteres ASCII é possível obter efeitos bem interessantes para desenhar os "gráficos" do jogo. Então vamos ver agora como se faz. Repare que os exemplos e explicações aqui se aplicam apenas à SCREEN 1 (modo texto de 32 colunas do MSX) salvo quando é especifiado outro modo.


Primeiro clique na imagem abaixo para observar/baixar a tabela de redefinição que eu criei:



Nesta tabela, a coluna e linha coloridas em azul indicam o código ASCII (em notação hexadecimal) do caractere desejado. Por exemplo, o código 50h (50 em hexadecimal) representa o caractere da letra 'P' (veja na tabela, 50h = linha 5, coluna 0). Eu só coloquei os caracteres alfanuméricos, alguns símbolos e caracteres especiais pois eu imagino que esses são os mais importantes, e que geralmente você não vai querer redefinir. As outras posições eu deixei em branco pois achei irrelevante desenhar os caracteres correspondentes a essas posições.

Nota-se que a tabela está dividida em dois pedaços: o lado esquerdo é colorido em cinza escuro e o lado direito em cinza claro. Essa divisão serve apenas para facilitar a visualização dos conjuntos de 8 caracteres em cada linha. Na Screen 1 do MSX, só é possível alterar as cores dos caracteres "de 8 em 8". Quer dizer, se você altera as cores do caractere 30h, todos os outros 7 caracteres adiante na mesma linha vão ser alterados automaticamente com a mesma cor. Isso não tem como mudar, é uma limitação de hardware do MSX: digitando no interpretador BASIC o comando VPOKE 8192,&H42, você altera a cor dos 8 primeiros caracteres da primeira linha da tabela para azul no fundo verde. Digitando o comando VPOKE 8193,&H42, você altera a cor dos 8 últimos caracteres da primeira linha da tabela azul no fundo verde. Ou seja, sempre de 8 em 8 caracteres em cada linha.

Agora, explicando os pequenos números em vermelho na tabela. Os números vermelhos que aparecem em pares na primeira coluna (colorida em azul) da tabela, representam o endereço da VRAM (memória de vídeo) onde se encontra o atributo de cor dos caracteres do primeiro conjunto e do segundo conjunto, respectivamente. Por exemplo, na primeira linha da primeira coluna existe o par 8192-8193. Esses são os dois endereços da VRAM onde estão os atributos de cor dos caracteres do primeiro conjunto de 8 caracteres (de 0 a 7, lado esquerdo cinza escuro na primeira linha tabela) e do segundo conjunto de 8 caracteres (de 8 a F, lado direito cinza claro na primeira linha tabela).

Já os números vermelhos que aparecem em cada posição da tabela, indicam o endereço da VRAM onde inicia a definição de padrão (o desenho) do caractere. Repare que esse número aumenta sempre de 8 em 8. O primeiro da tabela é 0, depois vai pra 8, depois pra 16, depois pra 24, 32, 40, 48, e assim por diante. Isso é porque cada caractere é definido com 8 bytes. Cada byte da definição é usado para desenhar uma linha do caractere, cada um é formado por 8 linhas de pixeis.

Confuso? Não se preocupe. Agora, vou explicar em detalhes e mostrar exemplos pra facilitar o entendimento.


Os Comandos VPEEK e VPOKE


Pra quem não conhece esses dois comandos do BASIC-MSX, a sintaxe deles é muito simples. Eles servem para obter o valor e alterar o valor, respectivamente, no endereço da VRAM (memória de vídeo) especificado. VPEEK é uma função do BASIC e retorna o byte contido no endereço especificado. VPOKE é um comando e insere o byte especificado no endereço especificado. Confira a sintaxe de ambos os comandos:


variavel = VPEEK(endereco)

VPOKE endereco, byte


Em VPEEK, variavel é qualquer variável inteira que receberá o byte contido no endereço. Em VPOKE, endereco é o endereço da VRAM onde se deseja inserir um byte, e byte é o valor que se deseja inserir naquele endereço. Confira os exemplos:

Retorna em val o byte contido no endereço 8192h:


VAL = VPEEK(&h8192)


Insere o valor 20h no endereço 8192h:


VPOKE &h8192, &h20


Viram como é simples? Agora vou explicar exatamente como utilizar esses comandos, especialmente o VPOKE, para redefinir os caracteres ASCII e suas cores.


As cores do MSX


O computador MSX é capaz de exibir no máximo até 16 cores diferentes, sendo que uma das entradas na paleta de cores é transparente e não aparece na tela. Cada cor no MSX é representada por um códigVeja a tabela a seguir, mostrando as cores e seus códigos correspondentes:


Código — Nome
Código —Nome
0 (0h) — transparente 8 (8h) — vermelho
1 (1h) — preto
9 (9h) — vermelho claro
2 (2h) — verde
10 (Ah) — amarelo
3 (3h) — verde claro
11 (Bh) — amarelo claro
4 (4h) — azul
12 (Ch) — verde escuro
5 (5h) — azul claro
13 (Dh) — magenta
6 (6h) —vermelho escuro
14 (Eh) — cinza
7 (7h) — ciano 15 (Fh) — branco


Para conseguir redefinir as cores dos caracteres, é importante saber a notação hexadecimal. Isso porque cada caractere contém 2 informações para o atributo de cor: cor de frente e cor de fundo. A cor de frente é a cor dos "pixeis acesos" do padrão do caractere (bits 1), e a cor de fundo é a cor dos "pixeis apagados" do padrão do caractere (bits 0). Em hexadecimal, o valor do atributo de cor de cada caractere é expresso em um único byte, ou seja, um valor decimal entre 0 e 255, ou em hexadecimal, entre 00h e FFh. Em notação decimal, fica complicado definir as cores do caractere porque os valores da cor de fundo e cor de frente estão "juntos" num só byte, mas em hexadecimal fica fácil pois o primeiro algarismo sempre representa a cor de frente e o segundo algarismo sempre representa a cor de fundo. Sendo assim, confira exemplos para alterar as cores dos 8 primeiros caracteres da primeira linha da tabela ASCII:


Fundo azul e frente verde: VPOKE &h8192, &h24
(24h = 2h é a cor verde, 4h é a cor azul).

Fundo amarelo e frente vermelho escuro: VPOKE &H8192, &h6A
(6Ah = 6h é a cor vermelho escuro, Ah é a cor amarelo).

Fundo magenta e frente verde escuro: VPOKE &H8192, &hCD
(CDh = Ch é a cor magenta, Dh é a cor verde escuro).


É tudo uma questão de especificar o endereço da VRAM correspondente aos 8 caracteres que se deseja redefinir a cor (verifique a tabela, os pares de números vermelhos na primeira coluna de fundo azul), e juntar dois algarismos hexadecimais para especificar a cor de frente e fundo, sendo o primeiro algarismo a cor de frente e o último a cor de fundo.


Redefinição do padrão dos caracteres


Essa parte é tão simples quanto a redefinição dos atributos de cor. Para redefinir os caracteres, nós usamos o mesmo comando VPOKE, porém agora é importante saber a notação binária. Ou seja, para facilitar o trabalho, usamos apenas os números 0 e 1 para representar os "pixeis acesos" (número 1) e "pixeis apagados" (número 0) do caractere. Confira o exemplo a seguir para esclarecer como funciona o procedimento:

O trecho de código BASIC-MSX a seguir redefine o caractere da letra 'A' na Screen 1 para um outro formato:


10 SCREEN 1
11 VPOKE 520, &B00110000
12 VPOKE 521, &B01111000
13 VPOKE 522, &B11001100
14 VPOKE 523, &B11001100
15 VPOKE 524, &B11111100
16 VPOKE 525, &B11001100
17 VPOKE 526, &B11001100
18 VPOKE 527, &B00000000
19 PRINT "A"
20 END


Digite esse trecho de código no interpretador BASIC do MSX e execute com o comando RUN. Repare que o programa redefine o caractere da letra 'A' e o mostra na tela. Repare que ocorre a redefinição de 8 bytes na VRAM. Olhe na tabela que eu coloquei nessa postagem: o endereço 520 da VRAM corresponde ao byte usado para gerar a primeira linha do caractere 'A'. Os 7 endereços seguintes são as próximas 7 linhas do caractere, ou seja, para cada caractere a redefinir, você redefine 8 endereços da VRAM, um para cada linha do caractere. Observe atentamente os valores inseridos nos endereços da VRAM. São valores em notação binária. Repare que os números 1 e 0 acabam formando uma letra 'A', com formato diferente do padrão . Repare também que o padrão de "pixeis acesos e apagados" são representados na notação binária, onde os pixels contendo o valor 0 não aparecem (estão "apagados"), e os pixels contendo o valor 1 aparecem (estão "acesos"). Caso você já esteja acostumado a converter entre notação binária e hexadecimal, ou entre binário e decimal, o exemplo acima fica mais compacto se você converter os valores binários para decimal, no entanto, fica muito mais complicado de "visualizar" no código o formato do caractere.

Viram como é simples? Agora só vou dar uns avisos importantes:

- Como você aprendeu, ao redefinir as cores dos caracteres, elas são redefinidas sempre de 8 em 8, ou seja, redefinindo a cor de um caractere, ao mesmo tempo os outros 7 caracteres que estiverem na mesma região da VRAM terão a mesma cor redefinida automaticamente.

- Ao redefinir o padrão dos caracteres, diferentemente de redefinir as cores, cada caractere é redefinido individualmente, ou seja, definir o formato de um caractere não afeta nenhum outro caractere na tabela.

- Não é possível redefinir os caracteres especiais NUL (nulo) e CSR (cursor) através da manipulação da VRAM.

- O caractere especial SPC (espaço) se refere ao "espaço", o caractere que aparece quando você pressiona a barra de espaço no teclado do MSX. Redefinindo esse caractere, você vai acabar redefinindo o padrão da tela inteira! Isso porque, na região da VRAM que define o que está aparecendo na tela do MSX, as posições onde não há nenhum caractere visível são preenchidas com o caractere 20h (ou seja, o caractere especial SPC).

Enfim, era isso. Qualquer dúvida envie pra mim.