quarta-feira, 1 de agosto de 2012

Revolution e Speedlock 2

Depois de destrinchar o Speedlock 1 com o Highway Encounter, eu vou comentar sobre Speedlock 2 com o jogo do mesmo autor (Costa Panayi), o Revolution.


Speedlock 2

A estrutura do arquivo 'Revolution.tzx' é dada pelo TZX Show:

Block 1: header
    Saved name: "REV       "
    Type: BASIC program
    Auto-start line: 0
    Program size without variables: 186
    Total length: 205
Block 2: data bytes
    Length: 205
Block 3: header
    Saved name: "revolution"
    Type: BASIC program
    Auto-start line: 0
    Program size without variables: 1351
    Total length: 1770
Block 4: data bytes
    Length: 1770
Block 5: group start
    Group name: SpeedLock 2 Block 1
Block 6: pure tone, 2174 pulses of 18 T-state period
Block 7: pulse sequences, 715 T, 715 T
Block 8: pure tone, 2174 pulses of 18 T-state period
Block 9: pulse sequences, 715 T, 715 T
Block 10: pure tone, 2174 pulses of 18 T-state period

Existem dois programas BASIC, ambos com listagens desprotegidas que podem ser examinadas com Basic Lister. A listagem do primeiro programa ("REV") é:

0 PAPER 0: INK 0: BORDER 0: CLS : PRINT USR 23829 : LOAD ""

Eu não vou mostrar o disassembly a partir de 23829 por não ser importante por ora, mas a rotina copia RAM de 23832-23936 para 65432-0.

O segundo programa BASIC ("revolution") é igual ao do Speedlock 1, com a linha mais importante sendo:

0 POKE (PEEK 23613+256*PEEK 23614),PEEK 23627: POKE (PEEK 23613+256*PEEK 23614)+1,PEEK 23628

que irá desviar a execução para o endereço 25244.

O disassembly mostra algumas instruções que servem para confundir a leitura, mas finalmente  encontra-se um decodificador, semelhante ao Speedlock 1:

25260   LD A,R
25262   XOR (HL)
25263   LD (HL),A
25264   LDI
25266   RET PO
25267   DEC SP
25268   DEC SP
25269   RET PE

o loop situa-se entre 25620-25269 e sai por 64015.

Prosseguindo a análise do programa a partir de 64015, encontra-se o mesmo decodificador que o acima, entre  64051-64060, que sai por 60461.

Depois de 60461, há um outro decodificador entre 64070-64096.

Finalmente chega-se à parte que carrega os dados da fita:

64689   LD IX,40960     ;Carrega header em 40960.
        LD DE,17
        CALL 64561
64699   LD IX,16384
        LD DE,6911
        LD HL,64420
        LD (64418),HL
64712   CALL 64179      ;Carrega todo bloco Speedlock.

Apesar do IX=16384 e DE=6911 dar impressão de carregar apenas uma tela, na realidade a sub-rotina em 64179 carrega todos os dados do Speedlock. Depois do carregamento, uma parte da RAM é apagada e finalmente, entra-se na execução do jogo:

64736   LD IY,23610
        IM 1
        LD HL,10072
        EXX
        LD SP,24831
64746   JP 34714        ;Entrada para o jogo.

Interessante ver que IY, HL' e o modo de interrupção são restaurados para valores padrões do BASIC. O registrador SP assume valor 24831.

Portanto se pode concluir que Speedlock 1 e 2 são bem parecidos, mas a rotina de carregamento propriamente dito diferem. Do ponto de vista de hacking essa diferença importa pouco, pois em ambos os casos basta usar o debugger do emulador.

Registrador R

Como ocorre com Speedlock 1, o registrador R tem que estar com o bit 7 igual 1. No World of Spectrum consta como um bug, mas na realidade seria uma forma de proteção.

Adaptação para Beta 48

A princípio, poder-se-ia pensar em salvar toda a RAM no disquete, mas isso não é necessário. Uma análise do início do jogo mostra que boa parte da memória não precisa ser salva, pois é apagada:

34714   DI              ;Zera RAM 16384-23295.
        LD HL,23295
        LD DE,23294
        LD (HL),0
        LD BC,6911
        LDDR
        CALL 48020      ;Zera RAM 52480-58623.
        CALL 48006      ;Zera RAM 59392-65535.
        LD A,67
        CALL 47998      ;Preenche RAM 58624-59391 com byte 67.

Portanto, basta salvar a tela (16384-23295) e o bloco de bytes em 23296-52479. O bloco de bytes pode ser tranquilamente salvo numa região que não se sobreponha à região do BASIC, para depois ser relocado com um pequeno programa em código de máquina. Este programa deve ainda levantar o bit 7 do registrador R, ajustar valor de SP e executar o jogo.

O Revolution adaptado, com documentação sobre o procedimento, pode ser baixado em um dos links: Google Drive ou 4 Shared

Atualização em 14/11/2012: nova versão disponível. 

Nenhum comentário:

Postar um comentário

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