segunda-feira, 10 de setembro de 2012

Midnight Resistance: adaptando jogo para TKMEM 128 e Beta 48

A adaptação de jogos para Spectrum 128 para um TK90X com a TKMEM 128 e a Beta 48 envolve procedimentos bastante parecidos com os que foram explicados nos tutoriais anteriores. O principal diferencial é a necessidade de carregar os diferentes banco de RAM.

Neste tutorial mostrarei a adaptação de Midnight Resistance 128K. O arquivo TZX a ser baixado deve ser do relançamento da Erbe, que não contém nenhum esquema de proteção de fita. O arquivo ZIP foi baixado do World of Spectrum e foi utilizada a imagem de fita 'Midnight Resistance - Side 2 (Erbe).tzx', pois no lado 2 é que se localiza a versão 128K.


A rotina de carregamento inicia desabilitando as interrupções, ajustando o apontador de pilha (SP) e carregando a tela e parte do código de máquina, que se situa nas páginas de 1 e 2 da memória:

24576   DI
        LD SP,24575
24580   LD HL,16384     ; Apaga a tela.
        LD (HL),0
        LD DE,16385
        LD BC,6911
        LDIR
24593   LD IX,16384     ; Carrega tela.
        LD DE,6912
        CALL 24670
24603   LD IX,28672     ; Carrega bloco 28672-49151.
        LD DE,20480
        CALL 24670

Depois passa a carregar cada um dos bancos de RAM do Spectrum 128 e, no final salta para o início do jogo:

24613   LD A,16         ; Carrega banco de RAM 0.
        CALL 24646
24618   LD A,17         ; Carrega banco de RAM 1.
        CALL 24646
24623   LD A,19         ; Carrega banco de RAM 3.
        CALL 24646
24628   LD A,20         ; Carrega banco de RAM 4.
        CALL 24646
24633   LD A,22         ; Carrega banco de RAM 6.
        CALL 24646
24638   LD A,23         ; Carrega banco de RAM 7.
        CALL 24646
24643   JP 31715        ; Inicia o jogo

Os bancos de RAM de 0 a 7 são especificados por um valor a ser atribuído no registrado A, na faixa de 16 a 23. Os bancos de RAM 2 e 5 são omitidos, pois já estão presentes nas páginas 1 e 2 da memória do TK90X+TKMEM.

A sub-rotina em 24646 serve para carregar 16384 bytes da fita para serem armazenados num banco de RAM. No ponto de entrada em 24670, serve para carregar um bloco da fita. O disassembly é:

; Carrega banco de RAM especificado em A.
24647   LD BC,32765     ; Seleciona banco de RAM em A. 
        OUT (C),A
        LD IX,49152     ; Carrega bloco 49152-65535.
        LD DE,16384
        CALL 24670
        LD A,16         ; Seleciona banco de RAM 0. 
        LD BC,32765
        OUT (C),A
24669   RET             ; Fim da sub-rotina. 
; Carrega dados da fita.
24670   SCF             ; Sinaliza 'fazer LOAD'. 
        LD A,255        ; Byte leader é 255.
        INC D
        EX AF,AF'
        DEC D
        DI
        CALL 1378       ; Sub-rotina de leitura de fita da ROM. 
        LD A,0          ; Torna preta a borda da tela.
        OUT (254),A
24684   RET C           ; Finaliza se não houver erro de leitura,
24685   LD A,R          ;senão trava o computador com cintilação
        OUT (254),A     ;de cores da borda da tela.
24689   JR 24685

Exceto pelo detalhe do chaveamento da página 3, o restante do programa pode ser facilmente transferido para o disco Beta, como foi explicado anteriormente. No emulador, basta ativar um breakpoint no endereço 31715 (início do jogo), iniciar o carregamento da fita e aguardar. Feito isto, salva-se a tela e o bloco de bytes entre 28672-49151.

O que há de novo é a necessidade de se salvar os vários bancos de RAM, acessíveis na página 3 (49152-65535). Apesar de ser possível salvar cada banco manualmente, usar um programa é mais cômodo e menos sujeito a falhas. A listagem abaixo permite salvar e carregar os bancos 0, 1, 3, 4, 6 e 7 em disco Beta:

  10 REM SAVE
  15 GO SUB 900
  20 FOR n=7 TO 0 STEP -1: IF (n=2) OR (n=5) THEN NEXT n
  30 OUT 32765,16+n: PRINT " SAVE bank ";n,USR d: REM : SAVE f$+STR$ nCODE 49152,16384
  40 NEXT n
  90 STOP
 100 REM LOAD
 110 CLEAR 49150: GO SUB 900
 120 FOR n=7 TO 0 STEP -1: IF (n=2) OR (n=5) THEN NEXT n
 130 OUT 32765,16+n: PRINT " LOAD bank ";n,USR d: REM : LOAD f$+STR$ nCODE 49152
 140 NEXT n
 800 STOP
 900 REM
 910 LET d=15363: IF PEEK d<>195  THEN LET d=15619
 920 INPUT "Base filename: ";f$
 930 RETURN

Não é necessário digitar a listagem acima, pois o programa está disponível em TZX ou Hobeta. Para rodar este programa, obviamente não será possível faze-lo diretamente, pois a RAM está ocupada pelo jogo; assim, deve-se liberar espaço na área de BASIC, sem perder o conteúdo dos bancos de RAM, o que é possível seguindo esta dica. Um bom valor para RAMTOP é 48896 (#BF00) e, antes de sair do debugger, deve-se ativar a ROM 1 com o comando out 32765 16.

Agora que todos os arquivos tipo CODE estão no disco, basta criar e digitar um carregador BASIC, que deve ser salvo no disco:

  10 POKE 23693,0: BORDER 0: POKE 23624,0: CLEAR 28000
  20 LET d=15363: IF PEEK d<>195 THEN LET d=15619
  30 LET f$="MIDN128"
  40 RANDOMIZE USR d: REM : LOAD f$+"$"CODE
  50 RANDOMIZE USR d: REM : LOAD f$+"%"CODE
  60 FOR b=7 TO 0 STEP -1: IF (b=2) OR (b=5) THEN NEXT b
  70 POKE 23388,16+b: OUT 32765,16+b: RANDOMIZE USR d: REM :
LOAD f$+STR$ bCODE
  80 NEXT b
  90 REM
 100 RANDOMIZE USR 31715

O programa acima pode, com pequenas modificações, ser usado como carregador de outros jogos. O programa adaptado como arquivos Hobeta pode ser baixado do Google Drive ou 4 Shared.

Atualização: versão 2 disponível aqui

2 comentários:

  1. Como pode um micro tão antigo com tanta novidade 128K som e adaptação software, pena que fiquei muito tempo sem usar meu TK não lembro nem pra que serve o POKE. É bom ter pessoas como vc que conhece e trabalha para essa joia rara "TK" não caia no esquecimento.

    ResponderExcluir
    Respostas
    1. Nunca é tarde para recomeçar... ;-)
      Valeu pelo comentário.

      Excluir

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