Truques com o VDP

vdp1-checks

Um efeito muito bacana que pode ser produzido em um MSX1 com algumas poucas linha de código (em assembly), reorganização da VRAM e a troca do valor de um registrador do VDP. Esta ideia surgiu a partir de uma publicação no grupo TRS-80/Color Computer do Facebook sobre como implementar um efeito semelhante em um CoCo3 alterando a paleta de cores — thanks Simon Jonassen for the inspiration!

Isto me chamou a atenção pois poderia ser replicado em um MSX2 mas seria possível fazer em um MSX1? Bem, após pensar um pouco sobre como fazê-lo, eis aqui o resultado…

O que você vê? Dois planos quadriculados deslizando pela tela, o deslocamento é suave (linha a linha) e a animação executada a 30 quadros por segundo em sistemas NTSC e PAL-M — em sistemas PAL ela cai para 25 quadros por segundo.

Mas antes de contar como foi feito, a explicação de como NÃO fazê-lo! Usando de força bruta:

A cópia sequencial dos 64 quadros da animação da RAM para a VRAM. Mas nele há dois problemas: (i) a taxa de transferência dos dados entre Z80 e VDP que limitaria bastante a velocidade da animação e (ii) a necessidade de se ter 128KiB de RAM só para armazenar os dados¹.

E como foi feito? Simples, não há quadriculado algum deslizando na tela, é tudo enganação! 🙂

(¹) É força bruta, logo, compressão de dados está fora do escopo e cada quadro tem 2KiB.

Um pouco de teoria

Dentro do VDP do MSX1 os dados que compõe aquilo que o usuário VERÁ e CHAMARÁ de “a imagem na tela” encontram-se armazenados dentro de três tabelas²: Atributos,Nomes e Padrões. E a ideia é manipulá-las de modo a criar o efeito de animação e, também, simplificar o código.

Caso alguma informação fique solta ou mesmo confusa, recomendo a leitura das partes Um, Dois e Três d’As sete faces da SCREEN1 publicado no Retrocomputaria Plus escritas no “distante” ano de 2013. 🙂

(²) Fora outras duas tabelas que contém os atributos e os padrões específicos para os Sprites.

Tabela de padrões

A primeira coisa é produzir o quadriculado. Eu o fiz com o Gimp, salvei o resultado em formato BMP monocromático em 256×192 e converti para a SCREEN 2 do MSX. O resultado é este aqui:

vdp1-stripes

Cadê o quadriculado? Quero meu dinheiro de volta!

Mas isto são listras, não são? Explico, este será o conteúdo da tabela de padrões da VRAM e a ideia é deixá-la estática, o quadriculado em si será produzido através da tabela de atributos que alternará os valores de frente e fundo para criar alternância de cores.

Reorganizando a VRAM

Para melhor entender o próximo passo, esta imagem contendo a tabela de caracteres do MSX organizada de duas maneiras:

vdp1-almost_linear

Tabela BRASCII dos MSX nacionais, observe os símbolos monetários!

As cores intercaladas em azul e vermelho servem para destacar os agrupamentos de caracteres em blocos de oito elementos (esta informação é importante).

O modo convencional

No primeiro conjunto a tabela de nomes da VRAM está organizada do modo convencional, ou seja, iniciando em 0x00 e seguindo de maneira incremental da esquerda para a direita e de cima para baixo até 0xff:

00 01 02 03 04 05 .. 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 .. 3a 3b 3c 3d 3e 3f
.. .. .. .. .. .. .. .. .. .. .. .. ..
c0 c1 c2 c3 c4 c5 .. da db dc dd de df
e0 e1 e2 e3 e4 e5 .. fa fb fc fd fe ff

Acontece que se a ideia é fazer uma animação linha a linha, o tal do scroll fino, esta disposição não ajuda nem um pouco pois os valores da 8ª linha de cada padrão estarão sempre 256 bytes de distância uns dos outros.

Isto não torna a tarefa impossível só aumenta a complexidade do código, portanto é interessante pensar em alguma alternativa.

O modo “linear”

Uma forma de simplificação é reorganizar a tabela de nomes da VRAM. Repare que o outro conjunto também começa em 0x00 mas desce de maneira incremental até somar 8 caracteres, daí retorna ao início, avança para a direita e repete o processo até também alcançar o valor 0xff.

00 08 10 18 20 28 .. d0 d8 e0 e8 f0 f8
01 09 11 19 21 29 .. d1 d9 e1 e9 f1 f9
.. .. .. .. .. .. .. .. .. .. .. .. ..
06 0e 16 1e 26 2e .. d6 de e6 ee f6 fe
07 0f 17 1f 27 2f .. d7 df e7 ef f7 ff

Nesta disposição o valor da linha seguinte ao padrão 0x00 está justamente em 0x01 — que é o byte “ao lado” — e este padrão se repete nos demais conjuntos, produzindo 32 colunas de 64 bytes que passam a compartilhar uma certa linearidade — ou pseudo linearidade se preferir.

Tabela de nomes

Como isto afeta o que é visto na tela é necessário (re)organizar o “quadriculado” na tabela de padrões da SCREEN 2 antes rearrumar a tabela de nomes. O resultado preliminar é este aqui:

vdp1-non_linear

Agora é possível até mesmo ver umas partes quadriculadas.

Claro, a “bagunça” se desfaz quando a tabela de nomes também é modificada:

vdp1-stripes

De volta a como estava antes.

Apenas ressaltando que este procedimento não está “multiplicando duas vezes por -1”, o resultado na tela pode ser igual mas o conteúdo da VRAM está completamente modificado (e para melhor).

Tabela de Atributos

Agora é a vez de enganar o VDP! Isto consiste em alterar o valor do endereço base da tabela de atributos (o registrador 3) fazendo com que ela reduza seu tamanho de 6144 bytes para apenas 64 bytesVDP(3)=128 no MSX-BASIC. Como uma tabela mais curta o que o VDP faz é replicá-la por toda a tabela de padrões e assim cada uma das 32 “colunas” passam a compartilhar o mesmo conjunto de atributos! Ou seja, agora só é preciso escrever em 64 endereços da VRAM para “pintar” toda a tela.

Na realidade serão 128 bytes — VDP(3)=224 — pois preciso ter tabelas de atributos distintas para cada um dos terços da tela ou então os padrões que formam o teto e o chão seguirão em sentidos opostos.

O código

O programa é bem simples, inicializa a SCREEN2, copia os dados necessários para a VRAM e daí fica indefinidamente girando os padrões do teto e chão. Mas não irei listá-lo aqui, criei um repositório no GitHub e o coloquei lá — assim como colocarei outros pedaços interessantes de código mais tarde.

Concluindo

Um detalhe, o programa foi testado em um MSX2 real mas constatei que o ele não funciona corretamente quando o openMSX emula modelos de MSX usando os TMS9928A e TMS9929A e como não posso testar “no metal” fico sem saber exatamente onde estaria o erro, já que o datasheet não diz coisa alguma.

Pode-se fazer uma versão do Space Harrier para MSX usando este truque? Não com esta abordagem já que ela funciona estritamente para este caso, fora que desperdiça muita VRAM. Não se esqueça que este programa é, acima de tudo, pura enganação visual!

E quem aguentou ler até aqui já se deu contar de que isto é o tipo de coisa usada pelo pessoal de demoscene… eu só não coloquei um texto rolando pela tela pois ficaria muito óbvio! 🙂


Complementando o provável problema da emulação dos TMS992XA no openMSX e ao qual preferi não me aprofundar muito sem saber direito como acontecia “no metal” — algo que ocorre na emulação do T6950.

Aqui está o programa sendo executado no hardware real, que é o mesmo resultado que também ocorre no openMSX.

vdp-1_v992x

Obrigado ao Leonard Oliveira por ter realizado os testes (em um MSX1 e em um MSX2) e por me mandar as imagens.

Anúncios

9 comentários sobre “Truques com o VDP

  1. Esses chips diferentes não possuem o modo espelhado, vai falhar nesses modelos de msx mesmo.

    Pro efeito ficar mais realista tem que fazer a altura de cada faixa diminuir também, se bobear deve caber na mesma tabela de nomes.

    Curtir

  2. Funcionou perfeitamente no WebMSX!
    A propósito Giovanni, se vc quiser demonstrar coisas assim já rodando online é muito fácil criar um link para o WebMSX apontando uma ROM ou DSK, para as pessoas já verem o software rodando no Browser.

    Parabéns!

    Curtir

  3. Pingback: Telas do speccy no MSX – parte 1 | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s