segunda-feira, 2 de dezembro de 2019

A cassete do ZX Spectrum (III) - turbo loaders

Ignorando as protecções todas à volta, e centrando-nos na parte de transferência de dados, os turbo loaders são simplesmente rotinas alteradas de save e load da ROM.

Apenas a rotina de LOAD está normalmente presente num jogo. A rotina de SAVE, embora tenha sido escrita e usada, não é normalmente passada para cassete.

As rotinas de turbo loader mais simples apenas modificam os timings da rotina para ser mais rápida.
Outras, usam outras cores para o border, ou têm um contador de tempo de carregamento, ou outros artefactos. Havia pelo menos um jogo que tinha um jogo mais simples na rotina de loading.

Com um pouco de imaginação, pode-se fazer algo enquanto se carrega a tape, entre as instruções código máquina de carregamento de dados, desde que se tenha os timings em conta.

Normalmente, as rotinas turbo são as rotinas LD_BYTES e SA_BYTES que já falamos, mas com os timings alterados. Outra alteração muito simples de se fazer, é mudar as cores do border. Outra ainda, é tirar o byte/os 8 bits de tipo de bloco. Nem é necessário, já que estamos a nossa própria rotina. Ele apenas é para uso das rotinas da ROM.

Dado a qualidade das cassetes audio, as rotinas turbo que usem cassete, e não outro meio de armazenamento mais recente, nunca poderão ser muito mais rápidas que a ROM para preservar a fiabilidade dos dados.

Normalmente, isto são os tempos normais para um bloco:

SA_LEAD: 5s se A for 0 (header) ; 
                     2s se A não for 0 (bloco de dados)

6675672T LEADER 2132T OFF / ON (dados)
667T off SYNC1          
735T on  SYNC2
855T off + 855T on - 0
855T * 2 = 1710T off + 1710T on - 1 (HEADER + DATA + CHECKSUM)

941T off

No nosso caso do turbo loader de demonstração, mudados os tempos para metade. Cortamos do código o período final de silêncio.

Demonstração video de um turbo loader, escrito para este artigo

Nestas rotinas de turbo loader (and saving), modificamos ligeiramente as rotinas LD-BYTES e SA-BYTES da ROM, e modificamos os tempos de load e saving para metade (aproximadamente 3000 bauds).

Modificamos também as cores do border na rotina de turbo loading.


Código fonte em assembly  Ficheiro de cassette em formato TZX

Loader BASIC. Fazendo GOTO 50,  constrói a tape TZX dada como exemplo. Para implementar o loader num jogo , deve colocar-se o BORDER e COLOUR na linha 25 com a cor dominante do background da imagem, antes de saltar para a rotina de turbo loader. Isto não foi feito nesta demonstração em TZX, apenas para evidenciar o carregamento da área de pixels.

10 CLEAR 49999
20 LOAD ""CODE: REM Load de rotina C/M no link código fonte
30 RANDOMIZE USR 50000: REM chama rotina C/M de turbo loader
40 GO TO 60
50 SAVE "loader" LINE 10: REM grava este programa BASIC
51 SAVE "turboload"CODE 50000,296: REM grava as rotinas C/M
52 PAUSE 0:RANDOMIZE USR 50001: REM turbo saving
60 BORDER 0
70 PAUSE 0

No código fonte em assembly, primeiro vem as rotinas de loading, e depois as de saving. No final, tem em comentários, o estudo de timings T das rotinas da ROM SA-BYTES e LD-BYTES.

Nota: Devido à contenção de RAM, qualquer rotina que controle directamente a tape,  tem de ficar fora dos primeiros 16KB de RAM.

As míticas rotinas de turbo loader, são bastante simples, o que era complicado era quebrar todo o esquema de protecções que era construído para proteger estas rotinas e os jogos. Note-se que este exemplo está feito para ser legível; seria mais efectivo e de carga mais rápida em cassete incluir o assembly na zona BASIC e depois transferi-lo para uma zona de memória sem contenção.

Incluímos aqui a rotina de turbo loader (demasiado extensa para colocar no corpo do post).

Sem comentários:

Enviar um comentário