terça-feira, maio 16, 2023

MSX: Convertendo Alfabetos de Programas/Jogos para uso no MSX e no Graphos

Muitas vezes, tenho interesse em aproveitar algum alfabeto bacana em meus programas, as vezes de jogos ou de outros programas, aqui descrevo o procedimento que normalmente eu adoto para poder aproveitar estes alfabetos.

Introdução

Dá para tentar procurar o alfabeto no binário do programa/jogo, mas, exige uma paciência enorme, normalmente não valendo a pena o esforço, mas, as vezes este é o único método, principalmente quando temos apenas o MSX para nos auxiliar.

Um método mais simples pode ser executado, usando um emulador. Neste caso, estou usando o openMSX. Basicamente, devemos emular o programa/jogo, e salvar uma cópia da VRAM em algum arquivo, tendo esta cópia, podemos depois, no MSX, carregar a mesma, e com auxilio do POKE/VPOKE do MSX-BASIC, podemos isolar a área de formação dos caracteres (dependendo da Screen em uso), com alguns truques a mais, podemos até salvar o alfabeto no formato do Graphos e usar o mesmo para pequenas alterações.

Prática

Como exemplo, vamos simular a extração do alfabeto de um programa que roda na Screen 0, em 40 colunas. Executando o programa dentro do opensMSX, assim que a tela estiver formada, ou você ter certeza que o alfabeto já está em uso, entre no modo console (F10).

O openMSX tem boas ferramentas offline para depuração de código, e uma em particular que salva áreas de memória (mais informações podem ser obtidas com o comando “debug help”), por exemplo, para gravar toda a área da VRAM em um arquivo, basta comandar, no console:

save_debuggable VRAM arquivo.vrm

Isto gera um arquivo de 128k (mesmo sendo emulado um MSX 1), no meu exemplo, eu salvei toda a VRAM do programa com o comando

save debuggable VRAM D:\\MSX\\TEMP\\screen0.vrm

Note as barras duplas quando for usar diretórios.

Como o programa é para MSX 1 e para a Screen 0, o primeiro passo é limpar toda a área excedente dos 16k, para isso, basta usar um editor hexadecimal e limpar de &H4000 até o final.

Mas isto ainda não permite carregar o arquivo no MSX, para isso, vamos preparar o arquivo como se fosse um gerado pelo comando BSAVE,S, então, no início do arquivo screen0.vram, vamos inserir 7 códigos hexadecimais:

  • #FE (marca de arquivo binário).
  • #0000 (início da VRAM).
  • #03FF (fim da VRAM).
  • #0000 (não usado na VRAM).

Usando pelo BASIC

Com isto, temos um arquivo que facilmente vai ser carregado no MSX com o programa abaixo:

10 SCREEN 0 : WIDTH 40 : BLOAD “screen0.vrm”,s

Apesar de alguma sujeira na tela, o alfabeto deve ter sido carregado sem problemas. Agora temos algumas possibilidades, como salvar apenas a área de formação de caracteres da Screen 0 com o formato BSAVE,S, para usar em programas simplesmente carregando com BLOAD,S após entrar em Screen 0.

BSAVE “alfabeto.scr”,&H800,&HFFF,S

Podemos também transferir para alguma área da RAM, para depois carregar e mudar as variáveis que inicializam/aponta a tabela de formação de caracteres da BIOS, permitindo assim, manter os alfabetos mesmo dando outros comandos SCREEN.

10 D=&HC000
20 FOR F=&H800 TO &HFFF
30  A=VPEEK(F)
40  POKE D+F-&H800,A
50 NEXT F
60 BSAVE “ALFABETO.BIN”,&HC000,&HC7FF

Este pequeno programa transfere o alfabeto da VRAM (a área de caracteres da Screen 0 vai de &H800 a &HFFF) para a RAM (no caso, de &HC000 a &HC7FF), o programa estando nesta área, permite, apesar de gastar 2k da RAM, usar o alfabeto de maneira mais eficiente e em todos os modos de tela, bastando para isso, mudar algumas variáveis de ambiente:

10 BLOAD “ALFABETO.BIN”
20 POKE &HF920,&H00
30 POKE &HF921,&HC0
40 POKE &HF91F,S
50 SCREEN n

Os edereços &HF920 e &H921 armazenam o endereço de memória que contém a tabela de formação de caracteres, e é consultado a cada comando SCREEN, por exemplo, por padrão eles apontam para a tabela da BIOS, e o programa muda para a tabela recuperada e transferida.

O outro poke é muito importante, pois contem o slot da RAM, existe uma boa documentação de como encontrar este valor nos livros da Aleph (Aprofundando-se no MSX, por exemplo), e talvez eu inclua um pequeno tutorial nesta entrada em seguida. Como exemplo, se formos testar em um Expert, ou em alguns Panasonics, o valor de S é 3, no Hotbit é 2.

A última linha é apenas para demonstrar que qualquer um dos modos de tela pode entrar que o alfabeto será carregado para a VRAM.

Usando com o Graphos III

Podemos gravar numa área especial, para que o alfabeto seja lido facilmente pelo Graphos III. isto combinado com a dica anterior, permite fazer um banco que é facilmente editável no Graphos III, para, posteriormente ser deslocado para uma área em definitivo do seu programa.

Esta área é a partir de &H9200, já que um banco de alfabetos do Graphos III, nada mais é que um binário endereçado de &H9200 a &H99FF.

10 CLEAR 0,&H9200 : D=&H9200
20 FOR F=&H800 TO &HFFF : POKE D+F-&H800, VPEEK(F) : NEXT : BSAVE “GRAPHOS.ALF”,&H9200,&H99FF

A dica e salvar o alfabeto  no padrão do Graphos III, ir alterando até chegar na forma desejada, e depois de finalizado, transferir para uma área mais alta (no caso de ser usado em BASIC).

Usando em Assembly

No caso de usar em assembly, pode-se gerar uma gravação RAW dos dados e incluir na compilação, ou pode ser feita uma pequena alteração no programa em BASIC, para gerar um arquivo texto contendo o dump de memória precedido de instruções DB para ser usado em outros programas assembly, uma boa ideia e alterar levemente o programa 7.C do livro “100 dicas para o MSX”, Gerando Linhas Data.

100 REM GERA DB/ASM
110 REM
120 CLEAR 1000
130 OPEN “A:ALFABETO.ASM” FOR OUTPUT AS #1
140 DEFSNG A-Z
150 L$=""
160 INPUT”ENTRE O ENDERECO INICIAL”;I$
170 I=VAL(“&H”+I$)
180 IF I<&H8000 OR I>&HFFFF THEN 170
190 INPUT”ENTRE O ENDERECO FINAL”;F$
200 F=VAL(“&H”+F$)
210 IF F<I OR F>&HFFFF THEN 200
220 L$=L$+”DB #”
230 FOR N=I TO F
240  X$=”00?+HEX$(PEEK(N))
250  X$=RIGHT$(X$,2)
260  X=X+1
270  L$=L$+X$
280  IF X/8<>X8 THEN 320
290   PRINT #1,L$
300   L$=”DB #”
310   GOTO 330
320  L$=L$+”,#”
330 NEXT N
340 IF RIGHT$(L$,1)<>”,” THEN 370
350 L$=LEFT$(L$,LEN(L$)-1)
360 PRINT #1,L$
370 END

Este programa pede um edereço inicial e um final e (no nosso exemplo, basta informar C000 e C7FF, ou 9200 e 99FF) gera um arquivo como o abaixo:

DB #00,#00,#00,#00,#00,#00,#00,#00
DB #00,#00,#00,#F0,#10,#18,#18,#18
…
DB #FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF

Fontomas

Isso já dá uma boa visão da coisa, pretendo ampliar este blog com mais algumas informações no futuro.

fontomas.dsk: Contendo o programa geradb.bas, mais o graphos III e algumas fontes de exemplo, tem um protótipo de programa para pegar uma fonte do graphos, e copiar caracteres da ROM para dentro da mesma, bom para completar alfabetos, ou fazer programas nacionais rodarem bem em micros japoneses.