Depois que o meu joystick passou a funcionar, comecei a testá-lo na entrada existente no TK90X. Quando tentei jogar Ad Astra, percebi que o controle não funcionava como deveria.
No menu acima, as opções 5 e 6 corresponderiam às duas entradas disponíveis no ZX Interface 2 (vide mais detalhes no TK-Wiki). Entretanto somente uma das entradas era acionada em ambas as opções e, por uma infelicidade, justo a que não correspondia ao padrão do TK90X .
Resolvi investigar no debugger do Fuse e encontrei a rotina de leitura dos controles. Esta rotina assume que o acumulador (registrador A do Z80) indica o tipo de interface selecionado. O início da listagem revela que o padrão de bits representado o estado da interface Kempston é armazenado na variável em 24811:
A rotina segue e, se a entrada 2 da Interface 2 está sendo usada, faz se a leitura as teclas 1 a 5 e o resultado é guardado na mesma variável após o devido tratamento:
Na sequência examina-se a possibilidade a opção da entrada 1 da Interface 2:
Na terceira linha deste trecho, verifica-se o uso de uma variável em 24814 que indica qual jogador está na vez. No modo para 1 jogador, seu valor é sempre 1; caso seja para 2 jogadores, a variável pode assumir valor 1 (jogador 1) ou 2 (jogador 2). Nas linhas seguintes da listagem pode-se observar que na vez do jogador 1, o programa desvia sempre para a leitura do joystick 2 da Interface 2. Somente quando for a vez do jogador 2, aciona-se o joystick 1.
Agora ficou claro do motivo do Joystick 1 não funcionar no modo para 1 jogador, o que é uma dificuldade para o TK90X. A solução deste problema é simples, basta inverter a lógica do desvio condicional em 25591 de
que pode ser introduzido via Multiface 1 ou no carregador BASIC.
Agora sim, consigo jogar Ad Astra no TK90X com o meu joystick renovado.
Resolvi investigar no debugger do Fuse e encontrei a rotina de leitura dos controles. Esta rotina assume que o acumulador (registrador A do Z80) indica o tipo de interface selecionado. O início da listagem revela que o padrão de bits representado o estado da interface Kempston é armazenado na variável em 24811:
; O acumulador contém 1=Kempston, 2=Sinclair 2, 3=Sinclair 1
;e 4=Cursor.
25537 CP 1 ; Salta para diante se não for
JR NZ,25550 ;
Kempston.
LD BC,31 ; Porta para Kempston.
IN A,(C) ; Faz leitura da porta.
LD (24811),A ; Guarda resultado da leitura.
RET
A rotina segue e, se a entrada 2 da Interface 2 está sendo usada, faz se a leitura as teclas 1 a 5 e o resultado é guardado na mesma variável após o devido tratamento:
25550 CP 2 ; Salta para diante se não for
JR NZ,25582 ;
Sinclair 2.
25554 LD BC,63486 ; Porta para Sinclair 2.
IN A,(C)
; Faz leitura da porta.
LD B,0 ; Inicializa modelo de bits.
BIT 0,A ; Se a tecla 1 (esquerda) foi
JR NZ,25567 ;
pressionada,
levanta bit 1 de B.
SET 1,B
25567 BIT 1,A ; Se a tecla 2 (direita) foi
JR NZ,25573 ;
pressionada,
levanta bit 0 de B.
SET 0,B
25573 AND 011100 ; Zera os bits exceto b2 a b4.
XOR 011100 ; Inverte os bits b2 a b4 e
OR B ;
mescla com os bits
em B.
LD (24811),A ; Guarda resultado final.
RET
Na sequência examina-se a possibilidade a opção da entrada 1 da Interface 2:
25582 CP 3 ; Salta para diante se não for
JR NZ,25635 ;
Sinclair 1.
LD A,(24814) ; Lê Sinclair 2 se for o primeiro
CP 1 ;
jogador no
modo 2 jogadores.
25591 JR Z,25554
LD BC,61438 ; Porta para Sinclair 1.
IN A,(C) ; Faz leitura da porta.
BIT 0,A ; Se tecla 0 foi pressionada,
JR NZ,25606 ;
levanta
bit 4 de B.
SET 4,B
25606 BIT 1,A ; Se tecla 9 foi pressionada,
JR NZ,25612 ;
levanta
bit 3 de B.
SET 3,B
25612 BIT 2,A ; Se tecla 8 foi pressionada,
JR NZ,25618 ;
levanta
bit 2 de B.
SET 2,B
25618 BIT 3,A ; Se tecla 7 foi pressionada,
JR NZ,25624 ;
levanta
bit 0 de B.
SET 0,B
25624 BIT 4,A ; Se tecla 6 foi pressionada,
JR NZ,25630 ;
levanta
bit 1 de B.
SET 1,B
25630 LD A,B
LD (24811),A ; Guarda resultado final.
RET
Na terceira linha deste trecho, verifica-se o uso de uma variável em 24814 que indica qual jogador está na vez. No modo para 1 jogador, seu valor é sempre 1; caso seja para 2 jogadores, a variável pode assumir valor 1 (jogador 1) ou 2 (jogador 2). Nas linhas seguintes da listagem pode-se observar que na vez do jogador 1, o programa desvia sempre para a leitura do joystick 2 da Interface 2. Somente quando for a vez do jogador 2, aciona-se o joystick 1.
Agora ficou claro do motivo do Joystick 1 não funcionar no modo para 1 jogador, o que é uma dificuldade para o TK90X. A solução deste problema é simples, basta inverter a lógica do desvio condicional em 25591 de
JR Z
para JR NZ
, com o seguinte POKE:POKE 25591,32
que pode ser introduzido via Multiface 1 ou no carregador BASIC.
Agora sim, consigo jogar Ad Astra no TK90X com o meu joystick renovado.
Nenhum comentário:
Postar um comentário
Seu comentário é bem vindo, mas peço que use este espaço adequadamente.