sexta-feira, 2 de novembro de 2012

Especificações: Tabelão de Modos Gráficos da VDP

Segue um Tabelão dos modos gráficos da VDP do MSX e a compração com a VDP melhorada do sms.



Screen 0
Screen 1
Screen 2
Screen 3
Screen4
TMS9918A
(SMS)
Resolução (pixels)
256 x 192
256 x 192
256 x 192
256 x 192
256 x 192
Numero de Caracteres (Tiles) na tela
40 x 24
(8 x 6)
32 x 24
(8x8)
32 x 24
(8x8)
32 x 24
(8x8)
32 x 24
(8x8)
Cores simultaneas
16
16
16
16
16
Numero de cores an Paleta
16
16
16
16
32
(configuraveis)
Cores por caracter (tile)
2
2 por grupo de 8 carcateres
2 para cada linha em um caracter
2
multicolor
Numero de Sprites simultaneos na Tela
n/a
32
Sincle color
32
Sincle color
32
Sincle color
64
multicolor
Número de sprites em uma mesma linha
n/a
4
4
4
8
Tamanho dos sprites
n/a
8 x 8
16 x 16
8 x 8
16 x 16
8 x 8
16 x 16
8 x 8
8 x 16
Scrolling Vertical e Horizoltal
n/a
n/a
n/a
n/a
Sim
Espelhamento de caracateres
n/a
n/a
n/a
n/a
Sim, vertical e Horizontal
Memoria de Video (VRAM)
16k
16k
16k
16k
16k
Memória para padrões de caracteres (tiles)
2k
(2048 a 4095)
2k
(0 a 2047)
6k
(0 a 6143)
n/a
14k
(448 chars/sprites)
Memória para posição de caracteres (tiles na tela, ou Backdrop Map)
960 bytes
(0 a 959)
768
bytes
(6144 a 6911)

768
bytes
(6144 a 6911)

1,5k
(2048 a 3583)
1792 bytes
Tabela de Cores dos caracteres (tiles)
n/a
32 bytes
(8192 a 8223)
6k
(8192 a 14335)
2k
(0 a 2047)
n/a
Memória para padrões de sprites
n/a
2k
(256s 8 x 8
64x 16x16)
2k
(256s 8 x 8
64x 16x16)
2k
(256s 8 x 8
64x 16x16)
Compartilhada c/ Memoria de padrão de caracteres
Tabela de Atributos de Sprites
n/a
128 bytes
128 bytes
128 bytes
256 bytes

Abraços.
O Editor

quarta-feira, 31 de outubro de 2012

Emuladores: Como escrever um emulador

Essa semana fiquei pensando como os emuladores de computadores e consoles são programados.

O primeiro passo para criarmos um emulador é emular o processador central. No caso do MSX que é o tema principal do nosso blog (lembre-se que em outro post eu disse que o blog é de eletrônica e computação também :) . No caso do Z80, precisamos pensar nos seguintes aspectos: input, processamento e output. Sabendo que o Z80 tem: 40 pinos, 22 registradores internos, uma ULA (Unidade Logica Aritimetica) e, 158 instruções elementares. O clock do Z80 é de ~3,58MHZ

Então vamos lá. Sugiro fazer a implementação em C/C++ ou em Java.

O nosso processador emulado deve ser capaz de ler as instruções da ROM e da RAM virtuais, processa-las e então mudar o estado de seus pinos de acordo com o resultado. Isso tudo em um loop de programação que é "regulado" pelo nosso clock emulado que deve ser de ~3,58MHZ (mesmo que nossos PCs sejam de 2,20GHZ e com dois processadores!). Esse seria um tipo de emulador interpretador. O clock do Z80 é no pino 6 que em HW verdadeiro é alimentado por um gerador de clock que gera uma onda quadrada. No emulador devemos simular isso calculando e ajustando a velocidade do loop, ou se você preferir, criando uma função geradora de clock que chama uma função principal que vai emular o Z80 no nosso emulador a frequência do clock.

Assim, vamos precisar de 22 variáveis no escopo interno da função do processador (locais) que são os registradores do Z80. Sendo que 18 delas são de 8 bits (A, B, C, D, E,  F, H, I, L, R, A', B', C', D', E', F', H', I', L', R') e 4 são de 16 bits (IX, IY, SP, PC).

Também vamos precisar de 40 variáveis para representar os pinos do Z80. Tanto no escopo interno da função do processador quanto para serem retornadas globalmente para o emulador, já que os pinos estão "soldados" a nossa placa-mãe virtual. Assim, por exemplo, as variáveis que representam os barramentos de dados, endereços e controle são vistas pelo escopo do emulador inteiro. Lembre-se que os barramento de dados tanto pode ler quanto escrever na memoria RAM.

A brincadeira começa quando o Z80 lê do registrador PC (Program Conter) o endereço de memoria RAM da próxima instrução a ser executada. Lembre que no Z80 os endereços são de 16 bits e o conteúdo de cada endereço da memoria é de 8 bits. Assim, a nosso loop deve ler da nossa memoria virtual essa instrução processa la e em seguida atualizar os valores de todos os pinos de saída (Variáveis corres pondentes) e incrementar o PC.

Quanto as 158 instruções do Z80, você já deve estar imaginado que vamos precisar de um swith/case para tratar todas elas e quem sabe chamar método específicos para cada uma delas.

Não parece tão difícil, mas também não e tão fácil escolher a melhor estrutura do programa emulador. Lembre-se que o emulador dever emular outros circuitos como a VDP e o processador de som, entre outros e você terá que atualizar o estado de cada elemento do computador virtual no loop principal do emulador.

Por hora é só pessoal. Em tempo atualizarei esse post quando tiver mais ideias ou melhorias no texto.
Abraços,

O Editor.

sábado, 27 de outubro de 2012

Manutenção: Caracteres deformados no Hotbit

Eu tive um problema de letras deformadas em meu HB8000 original de 1985 1.1, o modelo branco que não tem o logo MSX no teclado. As letras apareciam achatadas (o O, o 0  ou G pareciam um D, mas não em todas as posições da tela). Esse defeito era no conversor de RF. Os primeiros HB fabricados em 1985 não tinham um conversor de RF muito eficiente. Alias esses dispositivos e os de alguns videogames de 8 bits geravam interferências em TVs próximas e eram o terror das irmãs que assistiam as novelas. Meu pai até havia imposto um horário para eu ligar meu Hotbit. Há artigos informando que a fabrica melhorou o conversor de RF a partir do HB preto 1.2. Eu tenho esse versão e realmente a imagem parece melhor que os meus HB brancos (mesmos os mais novos de 1986 e 1987 são que já apresentam o logo MSX acima das teclas de setas, no teclado). Porém se o problema for caracteres com pixels estranhos o problema pode estar na ROM que contem o mapa de caracteres. Neste caso o problema pode estar no CI da ROM que contem o mapa de caracteres. Recomendo neste caso testar o aparelho com um cartucho de jogo e ver o que acontece. Se funcionar sem o problema pode estar mesmo no CI da ROM cujos caracteres não serão usados pelo jogo. O fato é que é melhor abrir o aparelho e fazer uma revisão completa.

Abraços,
O Editor

quarta-feira, 6 de junho de 2012

Programação: Jogos MSX1

Da primeira vez que possui um MSX 1.0, no final dos anos 80 e começo dos 90, sempre tentava programar jogos. Fazia varias telas com desenhos elaborado em modo screen 2, telas de apresentação, sprites em movimento. Porém, sempre esbarrava em três problemas: 1) quando movimentava o sprite do jogador com o teclado ou joystick, os sprites controlados pelo computador não se movimentavam, ou quando conseguia o contrario o jogador não se movia, ou quando conseguia os dois, o cenário ficava paralisado; 2) as figuras formadas por  mais de um sprite não se moviam juntas e sempre parecia que não estavam "coladas" uma nas outras; 3) as telas de cenários sempre eram mostradas sendo pintadas pela comando paint. Naquela época não havia internet e muito pouca informação havia nos manuais.

Depois de muito tempo, após fazer engenharia e aprender a programar para PC em 2D e 3D, voltei ao velho exercício em basic e descobri a solução para os problemas acima.

1) O loop básico de jogos:
    Para conseguir que tudo na tela se mova ao mesmo tempo é preciso implementar o conceito mais básico de loop de jogos eletrônicos:
  • Ler o input do usuário (joystick Teclado)
  • Atualizar as coordenadas X,Y ( e Z, se houver) do jogador segundo regras de movimentação ( física do jogador, etc.).
  • Atualizar a posição dos objetos do cenário
  • Atualizar a posição dos personagens controlados pelo computador
  • Verificar colisão de sprites e tomar as ações necessárias
  • Desenhar tudo na tela.
  • voltar p/ o 1o passo.
O loop básico pode apresentar algumas variações, mais esse o minimo necessário para fazer um jogo. Note que no MSX, provavelmente para a maioria dos jogos, não era feito contagem de tempo em cada interação do loop como nos PCs modernos, para que o jogo rode com a mesma velocidade em diferentes micros.

2) neste caso a melhor opção é codificar o jogo em assembler, pois é muito mais rápido do que o Basic, e há técnicas que não serão discutidas neste post para evitar o problema.

3) neste caso a saída e desenhar direto na memória de video usando comandos POKE ou assembler. Ñão seria possível usar a técnica conhecida como double buffer, muito usado para jogos de hoje. Esta técnica consiste em criar o desenho da tela em um porção de memória (buffer) e depois copiar o buffer na memória de video. Isso dado a limitação de memória do MSX1 ser de 32k para programas residentes na RAM e 16k para o VDP. Mesma questão dos video games de 8 bits da época.

No que dis respeito aos modos da VDP para o MSX1, as opções são:
  • Screen 1 (modo texto 2)
  • Screen 2 (modo gráfico 1)
Tanto no screen 1 como no 2 temos uma resolução de 256 por 192 pixels de imagem e até 32 sprites.

No screen 1 cada setor de 8 x 8 pixels pode usar 2 cores das 16 disponiveis. Sendo que cada grupo de 8 characteres na memoria de padrões devem usar somente duas cores.
No screen 2 cada linha de 8 pixels pode usar 2 cores das 16 disponiveis.

Parece que muitos jogos da época usavam o screen 1 ao invés do screen 2. Assim os desenhos dos plano de fundo eram construídos usando caracteres (tiles) redefinidos com até duas cores cada um. Na verdade ao inves de "escrever" texto na tela o código do jogo escrevia texto mas com os caracteres redefinidos como elementos gráficos. Depois era so desenhar os sprites e pronto.

Assim em resuma os jogos de MSX eram compostos de um plano de fundo (background) com 32 colunas x 24 linhas, assim como no modo texto, em cada posição era colocado um tile (caractere) de até duas cores, formando assim o cenário.

Em cima do plano de fundo eram desenhados os sprites de 8x8 ou 16x16 que eram monocromáticos. Assim muitos personagens eram compostos de vários sprites para se obter personagens coloridos.

O por quê desta diferença é que a VDP não faz verificação de colisão coms os tiles do background. Ao passo que para os sprites a VDP pode fazer o check de colisão. Então como restringir um sprite em relação ao background, isso pode ser limitado por um mapa de coordenadas mas não há verificação "gráfica" de sprites verus tiles na VDP.

Sabemos também que a limitação da VDP é de 5 sprites por linha. Então como havia jogos com muitos sprites. Para isso era usado uma técnica que consistia em desenhar até 5 sprites por linha em uma interação do loop básico e alternar os sprites que aparecia na tela nas prximas passagens do loop. como o olho humano não percebe o truque, temos a sensação de fluide s gráfica.´

Já quanto a divisão da memória da VDP para os modos 1 e 2 temos:
  • background map: 768 bytes (32 colunas * 24 linhas) onde cada posição aponta para um tile (caracter) na tabela de padrões (tile set)
  • tabela de padrões (tile set): 2048 bytes no screen 1 e 6144 bytes no screen 2. Lembre-se que no screen 1 cada conjunto de 8 tiles no tile set, pode ter no máximo duas cores (exemplo: os 8 primeiros tiles, no tile set, usam verde claro e verde escuro os próximo 8 amarelo e vermelho, os próximos 8 azul e branco e assim por diante). Ao passo que no screen 2 cada tile pode usar duas cores sem a amarração do grupo de 8 tiles no tile set e, por esse motivo, o screen 2 consome mais memória da VDP do que o screen1.
  • Tabela de atributos de sprites 128 bytes (32 sprites * 4 bytes) onde temos em cada bytes os parâmetros, X, Y, Cor , padrão do sprite na tabela de sprites

Bom, por hoje é só folks,
O Editor

sexta-feira, 6 de abril de 2012

MSX Tunning: Troca da VDP

Após alguns dias estudando as especificações da VDP do MSX1.0 e, tentando descobrir porque os jogos do MSX não se equiparavam em qualidade gráfica aos dos consoles de 8bits, descobri que por exemplo o master system usava uma versão melhorada do VDP derivada do TMS9918. Assim fiquei pensando na possibilidade de substituir o VDP original do MSX1 pelo do ms. Neste caso teriamos um MSX1 tunado.
Para isso seria preciso saber se a VDP do ms era composta de um chip discreto ou integrado no ci do Z80 e se o basic iria suportar a ativação dos modos de texto e gráficos correspondentes.

Recentemente decobri que a pinagem da VDP do master system é diferente da do MSX, sendo assim tal modificação só seria, talvez possivel, através de um cartucho adaptado. Fica lançada a ideia.

Abraços,
O Editor