As sete faces da SCREEN1 – parte 1

sete_faces-1_abertura

Para ser sincero, tanto o modo texto de 32×24, a SCREEN 1, quanto o modo gráfico de 256×192, a SCREEN 2, dos MSX são visões diferentes do mesmo modo de vídeo. Ambas apresentam a mesma resolução física e a grande diferença é justamente a maneira como o VDP está organizando, na tela, aquilo que está armazenado na VRAM.

Falando assim até parece complicado mas minha ideia neste artigo é mostrar como mais ou menos como estão organizadas as coisas na VRAM e como é possível “dizer” ao VDP para mostrá-las de um jeito um pouco diferente para se produzir alguns efeitos bastante interessantes e com um custo (quase) zero de CPU.

Este artigo está dividido em três partes, nesta primeira temos uma enxurrada teórica e na segunda (depois de amanhã) algo um pouco mais divertido. Na terceira, as conclusões a respeito.


Em virtude da realização da 6ª edição da RetroRio (entre os dias 31/5 a 2/6/2018) como também do lançamento do 1º número da revista Clube MSX resolvi (re)publicar as três partes da série do Retrocomputaria sobre o VDP do MSX1 que, justamente, se interligam com uma série de outras coisas publicadas por aqui.

Organização da VRAM

A ideia aqui não é explicar detalhadamente o funcionamento do TMS-9918, é só mostrar onde ficam guardadas algumas coisas na VRAM. Intencionalmente estou deixando de lado a parte dos sprites (fica para uma outra oportunidade) e aquilo que nos interessa por enquanto saber é que dos 16 KiB da VRAM, endereçado entre 0 e 16.383 (0x0000…0x3FFF), no caso específico das SCREEN 1 e SCREEN 2, estão organizados assim:

  • A tabela de padrões encontra-se entre 0 e 6.143 (0x0000–0x17FF) — já explico;
  • A tabela de atributos fica entre 8.192 e 14.335 (0x2000–0x37FF) — calma, já explico e
  • A tabela de nomes tem 768 bytes e fica espremida entre 6.144 e 6.911 (0x1800–0x1AFF) — já não disse que vou explicar?

Acontece que lá na distante década de 1980, quando o TMS-9918 foi concebido, a memória já havia começado a ficar barata mas ainda não o suficientemente, então a solução para acomodar os 49.152 pontos de uma tela em 256×192 usando 12 KiB (ou sejam 1/4 do espaço necessário) foi esta:

  • Cada bloco de 8×1 pontos ocupa um byte e representa apenas pontos acesos (1) e pontos apagados (0). Por exemplo, um padrão de tijolos com 8×8 pontos poderia ser desenhado (em hexa, em binário ficaria enorme mas lembrem-se que F é 1111 e E é 1110) como : FE, FE, FE, 00, EF, EF, EF, 00
  • E cada um deles é colorido também por um byte, onde os 4 bits mais significativos (os primeiros da esquerda para a direita) informam a cor dos pontos acesos (INK) enquanto que os outros, os menos significativos, a cor dos apagados (PAPER). Por uma “incrível coincidência” em 4 bits cabem perfeitamente todas as 16 cores VDP. Uma fórmula simples seria INK×16+PAPER e, assim, colorir o mesmo padrão de tijolos usando belos tons de vermelho usaríamos (ainda em hexa) : 91, 81, 61, 61, 91, 81, 61, 61

Se você ainda não conseguiu visualizar os tijolos, tente assim:

10 COLOR 15,0,0:SCREEN 2
20 FOR I%=0 TO 7:READ J%:VPOKE I%,J%:NEXT I%
30 FOR I%=0 TO 7:READ J%:VPOKE 8192+I%,J%:NEXT I%
40 GOTO 40
50 DATA &HFE, &HFE, &HFE, &H00, &HEF, &HEF, &HEF, &H00
60 DATA &H91, &H81, &H61, &H61, &H91, &H81, &H61, &H61

A parte chata desta abordagem é que ficamos limitados a ter apenas duas cores para cada conjunto horizontal de oito pontos. Ruim? Poderia ser pior, no caso do C64 o VIC-II implementa um modo bastante parecido, o HiRES (320×200, ou 40×25), que, tal qual o ZX Spectrum (256×192, ou 32×24), a tabela de cores faz referencia blocos inteiros de 8×8 pontos — sabem o que é color clashing? É claro que também poderia ser melhor, como é o caso dos modos FLI (Flexible Line Interpretation) e MCI (Multi Color Interlace), do mesmo C64.

A parede da cozinha

Mas voltando ao MSX, o primeiro sujeito, o dos pontos acesos e apagados, é a tal tabela de padrões e a que indica as cores a tabela de atributos. Estes dois conceitos são essenciais, mas ainda faltam outros. Um deles é a tabela de nomes que, no caso dela, é mais fácil mostrá-la em ação, no programa anterior inclua:

15 FOR I%=0 TO 127:VPOKE 6144+I%,0:NEXT I%

E agora temos uma parede de tijolos ocupando 1/6 da tela! Mas como? Antes um outro exercício, altere a linha 10 do programa para:

10 COLOR 15,4,0:SCREEN 1

O que aconteceu? A princípio a mesma coisa mas os tijolos ficaram laranja e ao pressionar «Control»+«Stop» e interromper o programa descobrimos que as cores de alguns caracteres estão em tons de vermelho com o fundo preto, ao invés das agradáveis letras brancas em fundo azul. Isto acontece pois, por padrão, a tabela de atributos da SCREEN 1 tem somente 32 bytes e cada um deles colore de uma vez um conjunto de 8 caracteres.

Aliás, acharam curioso o mesmo programa funcionar da mesma maneira em modo “texto” e em modo “gráfico”? Agora altere o valor de 255 para 767 na linha 15 e veja que em SCREEN 1 a tela inteira será preenchida com tijolos enquanto que na SCREEN 2 teremos apenas 1/3 da tela será digna deles. Guarde este número, o 3 é nosso número mágico!

Mas voltando à tabela de nomes, imagine que ela é (aí falando bonito) uma tabela com vetores que apontam para um conjunto de 8 elementos, da tabela de padrões e consequentemente da de atributos e indica ao VDP qual é o “ladrilho” que deve ser posto naquela área específica da tela, na SCREEN 1 é fácil de visualizá-la em ação pois justamente é o modo texto, peça o ladrilho 65 e teremos uma letra “A”! Não a vemos com a mesma facilidade na SCREEN 2 pois ela é sempre inicializada de modo a ficar invisível para nós, mas sempre é possível bagunçar um pouco as coisas:

10 COLOR 15,1,0:SCREEN 2
20 FOR I%=0 TO 63 STEP 3:LINE (I%,I%)-(63-I%,191-I%),,B:NEXT I%
30 FOR J%=0 TO 23:FOR I%=0 TO 7
40 K%=6144+J%*32+I%
50 VPOKE K%+8,VPEEK(K%)
60 VPOKE K%+16,VPEEK(K%)
70 VPOKE K%+24,VPEEK(K%)
80 NEXT I%,J%
90 GOTO 90

E assim falta explicar que a VRAM não é linear¹! Ou seja, os pontos não ficam enfileirados um ao lado do outro (como ficam os caracteres em uma tela de texto). Para o VDP tudo está organizado em caixas de 8×8 pontos, enfileiradas uma ao lado da outra como a parede de azulejos da cozinha (ou do banheiro). Se por um lado facilita a criação de um modo texto, a SCREEN 1, ou mesmo a produção de jogos tão distintos como Road Fighter e The Castle, por outro aumentou razoavelmente a matemática necessária para se plotar um singelo ponto na tela a partir de coordenadas X e Y:

10 X=0
20 Y=0 
30 P=(Y\8)*256+(Y MOD 8)+(X\8)*8
40 A=2^(7-X MOD 8)
50 PRINT "ENDEREÇO NA VRAM=";P,"VALOR=";A

Altere a vontade os valores das variáveis X e Y com números entre 0 e 255, no caso do X, e 0 e 191, no caso do Y e veja como pontos vizinhos no eixo cartesiano podem não estar assim tão próximos dentro da VRAM. Ou seja, o TMS-9918 foi feito mesmo para rodar Zaxxon e não para desenhar gráficos de pizza! Só não precisa ficar com remorso por cada vez que usou o PSET, LINE, CIRCLE ou PAINT!

(¹) Apesar de que é possível deixá-la “quase” linear com auxílio da tabela de nomes; E em defesa do MSX, a organização do vídeo do ZX Spectrum é mais doida ainda.

A SCREEN2 não existe!

Aqui entra o principal conceito! Lembra do meu comentário sobre SCREEN 1 e SCREEN 2 serem o mesmo modo de vídeo mas interpretados de forma diferente? No MSX-BASIC a SCREEN 1 utiliza uma tabela de padrões de 2 KiB, uma de atributos de 32 bytes e, quando iniciada, tem cada uma das 768 posições da tabela de nomes preenchida com o valor 32 (que é o código ASCII para o espaço em branco). Duvida?

VPOKE 256,128

A SCREEN 2 consome mais VRAM, ela utiliza para cada uma das tabelas de padrões e atributos blocos de 6 KiB, cada, e preenche a de nomes com três sequências de 0 até 255 (sim, 0, 1, 2, 3, … 254, 255) na tabela de nomes. Mas para todos os efeitos é como se a SCREEN 2 fosse, na realidade, não uma tela de 256×192 contígua mas sim três telinhas de 256×64 (quase que) independentes e empilhadas uma sobre a outra. E este é o último conceito! (ou ninguém reparou que 6.144 e 768 são múltiplos de 3?)

Dependendo de onde mexemos nos registradores do VDP a SCREEN 1 passa a apresentar um comportamento bem diferente de um modo texto e bem e mais próximo de um modo gráfico. Esta informação está lá no datasheet do integrado mas confesso que de uma maneira meio obscura (ao menos o que eu li no texto não batia muito bem com o que eu via na prática — talvez eu possa estar lendo errado). Ou seja, não há ineditismo, o único programa que conheço a utilizar alguns destes modos é o Print-X-Press, uma suíte de três² programas (DESIGNER, COMPILER e MANUSCRIPT) que formavam um despretensioso pacote de desktop publishing.

Foi dele que copiei a técnica usada para “colorir” a SCREEN 1 que usei no LIKE e num monte de outros programas meus desde então, sendo o (pen)último o Retromania. Acredito que alguns jogos japoneses também tenham utilizado estes modos híbridos e a única forma de comprovar seria usando um emulador para verificar os valores dos registradores do VDP, mas com razoável certeza é possível afirmar que os jogos que foram convertidos de speccy não usaram.

E aqui encerramos esta primeira parte, já tem informação demais por hoje. Até a segunda parte!

(²) A minha versão o programa vinha com um quarto módulo, o FONT CONVERTER, que servia para fazer a conversão de fontes do GRAPHOS III para ele e vice-versa. Uma contribuição (anônima) feita por algum brasileiro.


Texto originalmente publicado no Retrocomputaria em 07 de abril de 2013.