Brasil

SETI@Home: units

  Seti@Home

 
.
Mail

.


você esta em: / hardware -> yy

>> A Lenda dos 192KB de VRAM

Por: Daniel Caetano

.

Back
   Um desejo comum dos usuários de MSX desde a década de 90 era o de ter um MSX com 192KB de VRAM. Em especial, os usuários programadores das Screen 7 e superiores, sempre desejaram os 64KB adicionais como deseja ar quem está se afogando. E eu me incluo dentre esses usuários programadores.

   Por volta de 2007, no encontro de Jaú, finalmente consegui que Luciano Sturaro instalasse os 64KB adicionais e, finalmente, meu MSX poderia se esbaldar na "monstruosa" quantidade de memória de vídeo adicional e, finalmente, poderia fazer jogos "de verdade" em Screen 8. Mesmo que a especificação do MSX deixe claro que não há como usar essa memória para display - isto é, ela só serve para armazenamento de shapes e sprites que devem ser copiados para outra área da VRAM para que apareçam na tela, já era recurso suficiente para possibilitar uma série de truques... ao menos na teoria.

   Na prática, entretanto, os resultados foram bem menos promissores. Vou tentar, neste sucinto artigo, apresentar as razões pelas quais os 64KB adicionais são um tanto quanto inúteis... além de apresentar algumas alternativas e soluções para os problemas.

   Boa leitura!

1. Vídeo Rápido, Memória Lenta

   Um dos problemas enfrentados pela equipe de desenvolvimento do VDP do MSX2 era a lentidão das memórias do tipo DRAM disponíveis na época, considerados os custos das mesmas. As memórias disponíveis até então, a um preço acessível, eram rápidas o suficiente para construir uma tela do tipo Screen 5, com um dois bytes a cada dois pixels, mais as informações de sprite. Isso deixava as VRAMs disponíveis no limite - em especial quando o programa está também escrevendo na VRAM e o VDP também está executando seus comandos.

   Ocorre que nas screens mais altas, a velocidade de acesso precisava ser ainda mais rápida, já que cada pixel tem o dobro da informação (um byte por pixel, no caso da screen 8 ou superiores) ou o tempo para desenhar o pixel cai pela metade (no caso da screen 7, onde há 512 pontos na linha, ao invés de 256)... sem contar nos acessos de escrita e leitura à VRAM por parte da CPU e do próprio VDP, durante a execução dos comandos.

   Como o tempo de resposta das memórias DRAM, a um preço razoável, não era suficiente para estes modos de tela, alguém teve uma brilhante idéia: guardar os bytes pares da imagem em um banco de memória e os bytes ímpares da imagem em outro banco de memória. Desta maneira, como os bytes são acessados na maior parte do tempo de maneira sequencial, era como se as memórias tivessem um tempo de resposta duas vezes mais rápido.

   Quem já programou o vídeo do MSX vai pensar: "Mas como eu não percebo isso?" A resposta é: você não percebe porque o VDP "mascara" isso. Para você, tudo se comporta como se houvesse uma única DRAM contínua. Observe o esquema abaixo, num exemplo de tela fictícia com 8x8 pixels:

Imagem:



Vídeo DRAM Virtual
Endereço        0 1 2 3 4 5 6 7 8 9 A B C D E F 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
   "                                            0 1 2 3 4 5 6 7 8 9 A B C D E F 
Dado                      ▒             ▒       ▒ 

Vídeo DRAM0
Endereço        0 1 2 3 4 5 6 7 8 9 A B C D E F
Dado                 ▒ ▒ ▒        

Vídeo DRAM1
Endereço        0 1 2 3 4 5 6 7 8 9 A B C D E F
Dado            ▒ ▒              

   Que confusão! Como o VDP sabe em qual DRAM ler o dado? Isso é fácil: basta observar, em binário, os endereços "virtuais" dos dados que vão na memória DRAM0 e DRAM1:

DRAM0                           DRAM1
End.Hex End.Bin                 End.Hex End.Bin
0x00    00000000b               0x01    00000001b
0x02    00000010b               0x03    00000011b
0x04    00000100b               0x05    00000101b
0x06    00000110b               0x07    00000111b
0x08    00001000b               0x09    00001001b
0x0A    00001010b               0x0B    00001011b
0x0C    00001100b               0x0D    00001101b
0x0E    00001110b               0x0F    00001111b
0x10    00010000b               0x11    00010001b
0x12    00010010b               0x13    00010011b
0x14    00010100b               0x15    00010101b
0x16    00010110b               0x17    00010111b
0x18    00011000b               0x19    00011001b
0x1A    00011010b               0x1B    00011011b
0x1C    00011100b               0x1D    00011101b
0x1E    00011110b               0x1F    00011111b

   Nestes endereços "virtuais" binários, observe o último bit (o mais da direita): nos dados da DRAM0, o último valor é sempre 0 e, no caso da DRAM1, o valor é sempre 1. O VDP chama esse bit de seletor de CAS0 e CAS1, respectivamente, e o endereço real é composto pelos demais bits do endereço virtual:

DRAM0                           DRAM1
End.Hex End.Real CAS            End.Hex End.Real CAS
0x00    0000000b 0b             0x01    0000000b 1b
0x02    0000001b 0b             0x03    0000001b 1b
0x04    0000010b 0b             0x05    0000010b 1b
0x06    0000011b 0b             0x07    0000011b 1b
0x08    0000100b 0b             0x09    0000100b 1b
0x0A    0000101b 0b             0x0B    0000101b 1b
0x0C    0000110b 0b             0x0D    0000110b 1b
0x0E    0000111b 0b             0x0F    0000111b 1b
0x10    0001000b 0b             0x11    0001000b 1b
0x12    0001001b 0b             0x13    0001001b 1b
0x14    0001010b 0b             0x15    0001010b 1b
0x16    0001011b 0b             0x17    0001011b 1b
0x18    0001100b 0b             0x19    0001100b 1b
0x1A    0001101b 0b             0x1B    0001101b 1b
0x1C    0001110b 0b             0x1D    0001110b 1b
0x1E    0001111b 0b             0x1F    0001111b 1b

   Observe *atentamente* os endereços reais do byte 0x00 e 0x01. Agora, faça o mesmo comparando os endereços reais dos bytes 0x02 e 0x03... são os mesmos endereços reais! Isso ocorre para todo byte par e o byte impar subsequente: eles sempre possuem o mesmo endereço real; a única diferença é o valor do CAS, que é 0 para os bytes pares e 1 para os bytes ímpares.

   CAS0 é um sinal elétrico que habilita a DRAM0 e CAS1 é um sinal que habilita a DRAM1. Se o valor do bit CAS for 0, o circuito do VDP "liga" o pino CAS0 e "desliga" o pino CAS1; da mesma forma, se o bit CAS for 1, o circuito "desliga" o pino CAS0 e "liga" o pino CAS1 e, assim, a mágica é feita.

   No MSX, tanto o banco de memória DRAM0 quanto o banco de memória DRAM1 são de 64KB, o que dá o total de 128KB que estamos acostumados a encontrar.

2. CASX: O Patinho Feio

   O que chama a atenção nos VDPs de MSX2 e superiores (V9938 e V9958) é que, além da existência dos pinos CAS0 e CAS1, existe um pino CASX, que pode ser acionado por programação do VDP, sendo possível utilizar o "terceiro banco de RAM" como origem e destino de dados de operações do VDP.

   Não tardou muito para algum hardwarezeiro de plantão ligar um terceiro banco do DRAM de 64KB neste pino. Vamos chamar esse banco de DRAMX. Tudo lindo, não fosse um pequeno problema.

   Aparentemente, o VDP tem *internamente* DOIS pinos: CASX0 e CASX1. Se esses pinos estivessem disponíveis, não teríamos um MSX com 192KB de VRAM, mas sim com 256KB de VRAM (dos quais apenas 192KB estariam disponíveis, por limitações dos comandos existentes no VDP). Entretanto, estes pinos NÃO estão disponíveis externamente: ambos estão ligados EXATAMENTE NO MESMO PINO *CASX*. Isso significa que, quando o terceiro banco é usado, o pino CASX é acionado para os bytes _pares_ *E* para os bytes _ímpares_.

   Isso se torna um problema porque o VDP continua usando o esquema de endereçamento virtual e, assim, ocorre uma confusão das brabas com o conteúdo do terceiro banco: os pixels ímpares são "espelhos" dos bytes pares: o que escreve no byte par, aparece no ímpar correspondente e vice versa. Para entender isso claramente, vou apresentar um preenchimento da VRAM normal (bancos 0 e 1) e, depois, o preenchimento da VRAM extendida (banco X). A idéia é escrever, sequencialmente, os valores 0x0 a 0xF na memória VRAM. Será apresentada apenas uma linha de 4 pixels da tela

2.1. Preenchimento da VRAM normal

********
PASSO A) 
  COMANDO:   Escrever  no primeiro pixel (posição virtual 0x00)

  VDP EXECUTA:  Escrever  no endereço 0x00, CAS0

Vídeo DRAM Virtual    DRAM0 (CAS0)  DRAM1 (CAS1)
Endereço  0 1 2 3   0 1      0 1                                
Dado               

Imagem Gerada:



********
PASSO B) 
  COMANDO:   Escrever  no segundo pixel (posição virtual 0x01)

  VDP EXECUTA:  Escrever  no endereço 0x00, CAS1

Vídeo DRAM Virtual    DRAM0 (CAS0)  DRAM1 (CAS1)
Endereço  0 1 2 3   0 1      0 1                                
Dado                      

Imagem Gerada:



*******
PASSO C) 
  COMANDO:   Escrever  no terceiro pixel (posição virtual 0x02)

  VDP EXECUTA:  Escrever  no endereço 0x01, CAS0

Vídeo DRAM Virtual    DRAM0 (CAS0)  DRAM1 (CAS1)
Endereço  0 1 2 3   0 1      0 1                                
Dado                    

Imagem Gerada:



********
PASSO D) 
  COMANDO:   Escrever  no quarto pixel (posição virtual 0x03)

  VDP EXECUTA:  Escrever  no endereço 0x01, CAS1

Vídeo DRAM Virtual    DRAM0 (CAS0)  DRAM1 (CAS1)
Endereço  0 1 2 3   0 1      0 1                                
Dado                    

Imagem Gerada:
 

2.2. Preenchimento da VRAM estendida

********
PASSO A) 
  COMANDO:   Escrever  no primeiro pixel (posição virtual 0x00)

  VDP EXECUTA:  Escrever  no endereço 0x00, CASX0 (CASX)

Vídeo DRAM Virtual    DRAMX (CASX)
Endereço  0 1 2 3   0 1
Dado              

Como deveria ser a imagem gerada:
▒▒


********
PASSO B) 
  COMANDO:   Escrever  no segundo pixel (posição virtual 0x01)

  VDP EXECUTA:  Escrever  no endereço 0x00, CASX1 (CASX)

Vídeo DRAM Virtual    DRAMX (CASX)
Endereço  0 1 2 3   0 1
Dado              

Como deveria ser a imagem gerada:
▒▒


*******
PASSO C) 
  COMANDO:   Escrever  no terceiro pixel (posição virtual 0x02)

  VDP EXECUTA:  Escrever  no endereço 0x01, CASX0 (CASX)

Vídeo DRAM Virtual    DRAMX (CASX)
Endereço  0 1 2 3   0 1
Dado             

Como deveria ser a imagem gerada:
▒▒▒▒


********
PASSO D) 
  COMANDO:   Escrever  no quarto pixel (posição virtual 0x03)

  VDP EXECUTA:  Escrever  no endereço 0x01, CASX1 (CASX)

Vídeo DRAM Virtual    DRAMX (CASX)
Endereço  0 1 2 3   0 1
Dado        ▒ ▒    

Como deveria ser a imagem gerada:
▒▒▒▒
 

2.3. Análise dos resultados

   Nos exemplos acima, os dados escritos na VRAM foram , , e . No caso da VRAM normal, o resultado armazenado (e que pode ser recuperado) é , , e - exatamente como previsto. Entretanto, no caso da VRAM extendida, o resultado armazenado e que pode ser recuperado foi , , , - completamente inadequado.

   Obviamente, como todo "efeito colateral", esse "recurso" pode ser usado em algum demo para simplificar algum tipo de tarefa (pixelar uma imagem?), mas esse espelhamento dos bytes pares e ímpares na VRAM extendida a torna inútil para trabalhar em modos de vídeo altos, onde esse banco seria de grande valia.

   No caso das Screen 4, 5 e (talvez) 6*, talvez seja possível usar os bancos adicionais, já que nesses modos não precisa ser usado o esquema de endereçamento virtual da VRAM (e, de fato, é possível trabalhar nessas screens com apenas 64KB de VRAM). Entretanto, nessas screens os 128KB de VRAM usualmente já são suficientes para o trabalho, sendo de utilidade limitada a adição dos 64KB.

   De qualquer forma, eu nunca testei os 64KB adicionais nestes modos, de modo que não posso afirmar que funcione, pois é possível que, com a existência de dois bancos (ou mais) de VRAM, o VDP use ambos para permitir um tempo de resposta reduzido e, com isso, acelerar o acesso à VRAM.

   (*) Não tenho certeza se o timing do Screen 6, devido à alta resolução, já não exige dois bancos de VRAM).

 

3. Por quê existe o CASX?

   O CASX tem toda a "cara" de um recurso que não está completo. Eu tenho duas teorias a respeito.

   A primeira delas é que o VDP teria sido desenvolvido considerando que existiriam memórias rápidas o suficiente para todos os seus modos de vídeo e, assim, não seria necessário o esquema de memória virtual: os endereços de 0 a 64K ficariam no primeiro banco, de 64K a 128K no segundo banco e de 128K a 192K no terceiro banco... entretanto, a realidade se mostrou menos generosa com a Yamaha e ela acabou tendo que criar um "chuncho" para permitir que o VDP rodasse com memórias mais lentas. Esse "chuncho" teria consumido um bom tempo do ciclo de desenvolvimento e, em cima do deadline, não sobrou tempo para excluir a parte do circuito que gerencia o CASX.

   A segunda é que, desde o início, trabalhou-se com o conceito de dois bancos conjugados para os modos que exigiam baixos tempos de acesso à memória e, com isso, existiam também CASX0 e CASX1... mas na hora de finalizar, faltaram "pernas" no CI e o CASX0 e CASX1 foram ligados à mesma perna, chamada de CASX.

   Em ambos os casos, a memória estendida ao menos poderia fazer sentido no caso dos modos de vídeo que não exigissem baixos tempos de resposta da DRAM.

   De qualquer forma, é uma tristeza que não tenham pensado melhor. À custa de exigir um mínimo hardware adicional para ligar o VDP à memória, quando o sinal sai pelo CASX poderia também ser ativado o CAS0 ou o CAS1, de maneira que com apenas um pino CASX fosse possível ligar duas memórias no CASX. Elas seriam acionadas com uma porta AND: DRAMX0 apenas se CAS0 e CASX ativos e DRAMX1 apenas se CAS1 e CASX ativos... por outro lado, as memórias normais também teriam atraso de uma porta lógica AND e um inversor, dado que a DRAM0 só seria acessada se CAS0 AND *NOT* CASX, o mesmo valendo para a DRAM1, que só seria acessada se CAS1 AND *NOT* CASX

 

4. Como consertar o CASX?

   É possível dar um uso para o CASX e ligar 256KB de memória reais ao MSX2 e superiores, mas isso exige um hardware e uma padronização da programação da memória extendida. Se for definido e fixado que o acesso à DRAMX seja *sempre* feito de 2 em 2 bytes e sempre se iniciando pelo byte *PAR* (ou seja, se acessar o endereço extendido 0, é obrigatório acessar o endereço extendido 1, mesmo que não se vá usá-lo), é possível fazer um circuito que chaveie o sinal CASX entre dois bancos DRAMX0 e DRAMX1. Isso significa que, na primeira subida do sinal no CASX, o circuito aciona a DRAMX0; na subida subsequente do CASX, o circuito aciona a DRAMX1.

   Neste caso, é como se o banco DRAMX de 128KB x 8 bits fosse de 64KB x 16 bits, com leitura multiplexada (parte da responsabilidade é do software, entretanto). Considerando que a VRAM extendida serve apenas para guardar shapes e sprites, as exigências impostas não são excessivas: basta garantir que os shapes sejam sempre de dimensões pares e que, tanto o acesso aos shapes quanto aos sprites desta área, sejam acessados sempre respeitando esses limites.

   Entretanto, esse ajuste exige um circuito mais complexo do que simplesmente pendurar um novo chip de DRAM no equipamento, o que torna a coisa toda mais complicada.

 

5. Efeitos Colaterais do uso da VRAM Extendida

   Durante os meses em que fiz testes com o banco DRAMX, reparei que a temperatura das memórias, de uma maneira geral, bem como a temperatura do VDP, subiram sensivelmente. Isso significa que caso instale o pente de memória extra, seu VDP e seu MSX vão trabalhar em condições mais adversas, propenso inclusive ao travamento - que eu consegui resolver com um dissipador passivo.

   Entretanto, fique atento para não estragar seu VDP caso faça a expansão e tome os cuidados necessários.

 

6. Alternativas ao uso do CASX

   Se você quer ter mais memória de vídeo, uma alternativa talvez seja fazer uma MegaVRAM, algo que o Ademir Carchano já fez com sucesso, ligando 512KB de VRAM. A idéia é fazer com que a VRAM seja composta por bancos de memória que possam ser chaveados externamente (por uma porta, por exemplo, como funciona a MegaRAM tradicional). É um circuito mais complexo, mas pode proporcionar um resultado muito mais eficaz, inclusive por possibilitar que a memória de vídeo extra seja usada para exibir imagens na tela.

   O custo computacional de uma MegaVRAM é quase zero, ficando como ônus a dor de cabeça para o programador de gerenciar a memória de vídeo e cuidar dos chaveamentos nos momentos adequados (linha do screen split, tempo do retraço... etc) para evitar artefatos e tearing.

 

7. Conclusões

   O sonho da "expansão fácil" para 192KB pode ser realmente apenas um sonho, impossível na realidade - tanto que nenhuma empresa usou essa capacidade do VDP, que revela potenciais bugs de projeto. Entretanto, com algum empenho e hardware adicional, é possível utilizar o recurso do CASX ou mesmo obter efeito similar sem nem mesmo utilizar o pino CASX, como é o caso da MegaVRAM.

   Infelizmente o público do MSX é hoje muito reduzido, o que torna todas estas observações apenas curiosidades; como já há uma certa padronização em torno do processador de vídeo adicional V9990, da Yamaha, que aceita até 512KB de VRAM e dispõe de diversos recursos interessantes para a programação de jogos, este acaba sendo um caminho mais natural do que transformar o MSX em um completo Frankenstein para possibilitar a expansão da memória de vídeo, dado que esta não resolveria outros gargalos do processador e da arquitetura.

 

8. Demonstração

   Você pode fazer o download no link abaixo, de um programa que exemplifica tudo o que foi dito acima. A maquina para fazer o teste, deverá ter os 192KB de VRAM. Você pode usar o BlueMSX pra isso.

   Este programa foi publicado na MSX Magazine, e quem o digitou e disponibilizou foi o Slotman.

   192KBVRAM.DSK


© 2012 by MSXPró

.
Esta página é melhor visualizada em
resolução de 1024x768 @ True Color
Utilizando o navegador Mozilla

Visitante:

.

Valid HTML 4.01 Transitional   Valid CSS!