segunda-feira, maio 15, 2023

MSX: Trabalhando com Bancos de Caracteres

O ponto padrão de definição dos caracteres na BIOS do MSX é: &H1BBF, contendo 2kb com a formação de cada caractere sequencialmente.

Existem 2 variáveis de sistema (uma word e outra byte) que permitem mudar o ponto de carregamento do banco de caracteres. Por exemplo, se você alterar o banco diretamente na VRAM, a cada comando SCREEN, o MSX volta a transferir o BANCO de &H1BBF para a VRAM, voltando a usar os caracteres originais, podemos mudar este comportamento mudando estas variáveis, a saber:

  • &HF920 –> Parte baixa do novo endereço do banco
  • &HF921 –> Parte alta do novo endereço do banco
  • &HF91F –> Slot de memória onde se econtra o banco

Na inicialização do sistema, estas variáveis contém:

  • &HF920 –> &HBF
  • &HF921 –> &H1B
  • &HF91F –> 0

Além do problema de sobrescrever a VRAM a cada comando SCREEN, o truque de escrever em modo gráfico usando:

open “grp:” for output as #1 : preset(0,0) : print #1,”Ola Mundo!”

Não funciona, mesmo você tendo transferido um banco para a VRAM após o comando screen, pois o MSX-BASIC nesta operação em particular pega os caracteres apontados pelas variáveis descritas acima.

Uma maneira de corrigir este entrave e transferir o banco de caracteres para um outro local da RAM e mudar os valores destas variáveis, embora vamos perder 2Kb de RAM, teremos nosso trabalho bem facilitado.

Por exemplo, temos um banco de caracteres (veja o artigo de como extrair bancos de outros programas) gravado em disco, podemos carregar o mesmo para um endereço, por exemplo &HD000 da RAM, neste caso devemos mudar as variáveis da seguinte maneira:

poke &HF920,&H00
poke &HF921,&HD0
poke &HF91F, ss

Onde ss é o slot da RAM, no aprofundando-se no MSX (e em outras documentações) você descobre como encontrar corretamente o slot da RAM, já que o mesmo não é padronizado, mas  um truque bobo que pode resolver a maior parte dos casos é:

ss=(inp(&HA8) and &HC0) / &H40

Uma outra dica, por exemplo, você pode carregar um alfabeto do Graphos III para a RAM e trabalhar na transferência da VRAM para a RAM. Apesar deste processo em BASIC ser lento, você pode executar apenas uma vez e em seguida salvar um arquivo binário com o banco. Abaixo segue um protótipo de como proceder:

SCREEN 1 : BLOAD “ALFABETO.ALF”, S, -&H1200
D=&HD000
FOR F=&H0 to &H7FF : POKE D+F,VPEEK(F) : NEXT
BSAVE “ALFABETO.BIN”, &HD000, &HD7FF

Se for usar a Screen 0, o offset do bload deve ser alterado de –&H1200 para –&HA00, e o comando FOR que busca o endereço de formação da VRAM em &H0 na screen 1, deve ser mudado para o endereco da screen 0, que é &H800 (obviamente mudando também o endereço final para &HFFF)

Para quem usa o NBASIC a transferência é muito mais rápida, imaginando a screen 0:

bload “nbasic.bin”,r
screen 0 : bload “alfabeto.alf”,s,-&HA00
P(1)=&H800 : P(0)=0 : P(2)=255 : P(3)=&HD000 : P(4)=&H800 : e=usr(21)
bsave “alfabeto.bin”, &HD000,&HD7FF

Em seguida, temos um protótipo para a carga e preparação deste alfabeto:

bload “ALFABETO.BIN”
SS=(inp(&HA8) and &HC0) / &H40
poke &HF920, &H00
poke &HF921, &HD0
poke &Hf91F, SS
screen 2 : open “grp:” for output as #1 : preset (0,0) : print #1,”Ola Mundo!” : a$=input$(1)
screen 1: locate 0,0 : print “Ola Mundo!” : a$=input$(1)
screen 0 : list