terça-feira, 17 de julho de 2012

Adaptação de jogos de fita para Beta 48 (parte 7)

Continuando a adaptação do Sanxion 128k, um decodificador foi quebrado e a listagem da rotina de carregamento da fita tornou-se disponível. Fazendo um disassembly desta rotina que começa em 64896, há várias operações envolvendo principalmente a tela. O que realmente interessa é o carregamento da fita, que se inicia no seguinte trecho:
64952   LD IX,16384
64956   LD DE,6912
64959   CALL 65325
64963   LD IX,23808
64966   LD DE,40960
64969   CALL 65325
64972   LD HL,64986
64975   LD DE,23776
64978   LD BC,32
64981   LDIR
64983   JP 23776


As instruções entre 64952 e 64959 dão impressão de se referirem a rotina de carregamento de fita, por causa dos registradores IX (endereço inicial) e DE (comprimento) comumente empregados para isso. Olhando a listagem da sub-rotina em 65325:
65325   XOR A
65326   SCF
65327   INC D

65328   EX AF,AF'
65329   DEC D
65330   DI
65331   LD A,8
65333   OUT (254),A
...     ...

Fica bem claro tratar-se de uma rotina de carregamento semelhante ao da ROM do TK90X. Portanto, voltando à primeira listagem, inicialmente carrega-se uma tela da fita:
64952   LD IX,16384
64956   LD DE,6912
64959   CALL 65325

Seguido pelo carregamento de bloco de 40960 bytes na memória a partir de 23808:
64963   LD IX,23808
64966   LD DE,40960
64969   CALL 65325

em seguida uma rotina é copiada para 23776 e executada:
64972   LD HL,64986
64975   LD DE,23776
64978   LD BC,32
64981   LDIR
64983   JP 23776


Para continuar a análise, coloca-se desta vez um breakpoint em 23776 e continua-se no emulador. Quando a janela do monitor/debugger retorna, observa-se a listagem:
23776   LD HL,64767      ; Copia conteúdo dos endereços 23807-64767
23779   LD DE,65535      ;para 24575-65535 (40961 bytes).
23782   LD BC,40961
23785   LDDR
23787   LD SP,24575      ; Pilha do Z80 fica em 24575.
23790   LD IY,23610      ; Restaura valor de IY para o padrão do
23794   EI               ;BASIC e habilita interrupções.
23795   JP 24576         ; Salta para 24576.
 

As linhas acima dão impressão de que o código de máquina do jogo está contida na memória a partir do endereço 24576. Aparentemente o que está contido entre 23807 a 23775 não tem importância, pois é copiada para a RAM a partir de 24575. Para confirmar, coloca-se um breakpoint em 24576 para analisar a listagem, que é a seguinte:
24576   DI               ; Desabilita interrupção.
24577   LD SP,24575
24580   LD A,16          ; Seleciona banco de RAM 0 (para ZX
24582   LD BC,32765      ;Spectrum 128).
24585   OUT (C),A
24587   LD A,254         ; Define valor #FD para registrador I
24589   LD I,A           ;(vetor de interrupção) e coloca em
24591   IM 2             ;mode de interrupção 2.
24593   IN A,(31)        ; Faz leitura do joystick Kempston.
24595   OR A             ; Se o valor lido não for 0,
24596   JR NZ,24608
24598   INC A
24599   LD (24795),A     ;coloca valor 1 em 24795 e valor 22825
24602   LD HL,22825      ;em 24758.
24605   LD (24758),HL
24608   XOR A            ; Exibe borda preta.
24609   OUT (254),A
...     ...

O trecho acima nada mais tem a ver com carregamento de códigos de fita, portanto parece realmente ser o início do jogo. Isto significa que basta salvar a RAM a partir de 24576 (40960 bytes) no disco. O comando USR 24576 faria com que o jogo iniciasse.

Aproveitando que o emulador está paralisado graças ao breakpoint, use no menu do Fuse a opção File > Save binary data... para salvar a tela (endereço 16384 e comprimento 6912) e o código de máquina (endereço 24576 e comprimento 40960). Estes dois arquivos serão salvos no disco do seu PC com os nomes escolhidos (no meu caso eram 'Sanxion.scr' e 'RAM_24576_40960.bin', mas qualquer nome serve).

Resta agora passar os arquivos para a imagem virtual de disco TRD. Faça o emulador dar reset (tecla F5) para apagar a memória. Crie um arquivo TRD vazio (no Fuse use a opção do menu Media > Disk > Beta  > Drive A: > Insert New e formate o disco virtual) e deixe-o no drive A. Volte ao BASIC e digite CLEAR 24570 para reservar espaço acima do RAMTOP.

Para salvar a tela, digite no BASIC o comando:
PAUSE 0: PRINT USR 15619: REM : SAVE "SANXION$"CODE 16384,6912
Selecione no meu do Fuse a opção File > Open SCR screenshot, carregue a tela salva no disco do PC e pressione uma tecla para salvar no disco TRD.

Em seguida, carregue na RAM o arquivo com o código de máquina salvo no PC com a opção do menu File > Load binary data....


Para salvar o código no disco TRD, basta digitar:
PRINT USR 15619: REM : SAVE "SANXIONC"CODE 24576,40960

Observação: o endereço do USR para operação do TR-DOS é 15619 porque o Fuse emula a interface Beta 128. No caso no Beta 48 emulado pelo SpecEmu, o endereço deve ser 15363.

Para finalizar, digite o programa em BASIC (carregador) abaixo e salve no disco:
10 BORDER 7: PAPER 7: INK 7: CLEAR 24575 
20 RAND USR 15363: REM : LOAD "SANXION$"CODE
30 RAND USR 15363: REM : LOAD "SANXIONC"CODE
40 RAND USR 24576

Agora a imagem TRD pode ser transferida para um disquete e testado no TK90X. Na adaptação que eu fiz, comprimi o bloco de código de máquina com o LERM Code Compressor 1 para economizar espaço em disco (vide esta postagem para ver instruções). 

Conclusão

Conseguimos copiar e adaptar um jogo completo para disquete de Beta 48, quebrando a rotina de proteção. No caso de Sanxion 128k, havia um descodificador e blocos sem cabeçalhos (headerless). Existem outros esquemas de proteção, sendo alguns famosos por nome: Alkatraz, Speedlock, Uniloader, Bleeploader, ... Com as informações dadas nesta série até o momento, é possível conseguir quebrar essas proteções para fazer as adaptações dos programas.

3 comentários:

  1. Muito legal Flávio, finalmente eu tive uma idéia de como funciona todo o processo de adaptação. Seu curso foi muito esclarecedor. Algumas dúvidas. Arquivos .TAP não possuem as rotinas de proteção da fita original, possuem? Qual era a finalidade dessas proteções se em última análise poderia ser feita uma cópia da fita de audio em si?

    ResponderExcluir
    Respostas
    1. Alguns arquivos TAP, pelo que pude ver, foram crackeados por alguém e não são originais.

      A proteção com certeza era para desencorajar a pirataria, mas como você já disse, no final poder-se-ia fazer uma cópia de áudio (mas a qualidade talvez não fosse boa). Aliás, com a M1, não havia como impedir a pirataria, tanto que grande parte dos jogos vinham no Brasil nesse formato.

      Excluir
  2. É verdade, lembro-me de um vendedor de jogos piratas aqui em Campinas, você podia comprar quantos jogos coubessem numa fita K7, mas necessariamente todos os jogos eram copiados com o M1. Naquela época, não éramos exigentes, então, não ter a tela de loading, não era o fim do mundo.

    ResponderExcluir

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