quinta-feira, 10 de janeiro de 2013

Carregador BASIC que não corrompe a tela

Uma das características mais marcantes dos programas comerciais para TK90X, em especial os jogos, é a tela exibida durante o carregamento da fita. Ao longo de 5 minutos sem ter nada a fazer, o usuário tinha pelo menos alguma coisa para ficar olhando.

O sistema de carregamento da fita do monitor BASIC Sinclair é bastante sofisticado e, entre outras características, apresenta informações do arquivo encontrado.


Apesar de ser útil, a impressão de informações tem como efeito colateral arruinar a tela de carregamento. Para evitar que a tela fosse corrompida, os programadores lançavam mão de alguns truques. A seguir, apresento alguns dos truques que encontrei em programas comerciais.

Tela de carregamento com uma linha vazia

A tela de carregamento é desenhada de forma que sobre no mínimo uma linha vazia. Por exemplo, no jogo Ad Astra:


A linha 17, logo acima do logotipo "AD ASTRA", há uma linha vazia. O truque consiste em deixar em azul tanto o fundo (PAPER 1) como a frente (INK 1) e, antes de carregar o bloco, fazer com que o cursor fique uma linha acima de onde se deseja que a impressão ocorra (PRINT AT 16,0;). Assim que os blocos de dados são lidos da fita, a tela não se corromperia se não fosse por um detalhe:


O programador esqueceu de ajustar o brilho (BRIGHT 1), que é denunciado pelo azul um pouco mais escuro na linha 17, logo acima das letras "AD AS", decorrente da impressão ocorrida durante o carregamento.

Ao invés de manipular cada atributo com uma cor determinada, o melhor seria utilizar os atributos transparentes (INK 8, PAPER 8, BRIGHT 8 e FLASH 8), para evitar que sejam sobrepostos pelos atributos dos caracteres que estão sendo impressos.

Esta técnica foi empregada nos jogos mais antigos, mas foi superada por outras que não requerem uma linha vazia na tela.

Impressão com OVER

Um dos modos de impressão no BASIC é OVER 1, que mistura o conteúdo atual da tela com o que está a ser imprimido através da operação booleana XOR. Se esta operação for repetida duas vezes, retorna-se ao conteúdo inicial da tela, como se nada tivesse sido impresso. Este fato pode ser aproveitado para proteger a tela de carregamento.

Quando um bloco de bytes é lido, imprime-se na tela "Bytes: ", seguido pelo nome do arquivo salvo na fita. O truque seria salvar o arquivo com nome que se sobreporia à mensagem normalmente impressa, por exemplo:
SAVE CHR$ 22+CHR$ 1+CHR$ 0+"Bytes:" CODE end,compr 
A sequência de CHR$ corresponde ao comando AT 1,0; que posiciona o cursor. Basta o carregador BASIC definir OVER 1, tornar os atributos transparentes e posicionar o cursor adequadamente antes de ler a fita.

Esta técnica pode ser encontrada na versão de Fairlight relançada pela The Micro Selection.

POKE na saída do canal S

A linguagem BASIC do Sinclair possui um sistema de entrada e saída admiravelmente avançado para a época, com disponibilidade de streams e canais. Graças a esta característica, uma operação de escrita (PRINT) pode ser direcionada para a tela, impressora ou outro dispositivo. Um canal define quais sub-rotinas em linguagem de máquina devem ser chamadas nas operações de escrita e leitura.

O canal S normalmente direciona a escrita de dados para a rotina da ROM em 2548 (#09F4), responsável por imprimir um caractere na tela. Porém através do comando:
POKE 23739,111
pode-se redirecionar a saída para a rotina em 2415 (#096F) que nada faz, como se vê no disassembly:
2415   RET
O efeito deste POKE é desativar por completo as impressões na tela e, consequentemente, a leitura de fita não corromperá a tela. Após todos os blocos terem sido carregados, para restabelecer a impressão, deve-se executar:
POKE 23739,244
Este é o procedimento que tenho adotado nas minhas conversões de jogos para TKMEM-128 em formatos TAP ou TZX, devido à simplicidade e eficiência.

Carregador em linguagem de máquina

Elaborando suas próprias rotinas de carregamento, pode-se fugir das mensagens impressas pelo monitor BASIC, além de poder proteger os programas contra pirataria. Portanto esta foi a opção mais empregada pelos programas comerciais. Alguns esquemas tornaram-se bastante famosos, como Alkatraz, Bleeploader e os vários Speedlocks.

Não é muito difícil escrever tais rotinas, fazendo uso da rotina LD_BYTES da ROM, localizada a partir de 1366 (#0556).  Mesmo assim, ainda prefiro usar o comando LOAD do BASIC, sempre que for possível.

Nenhum comentário:

Postar um comentário

Seu comentário é bem vindo, mas peço que use este espaço adequadamente.