Cambio de mandos

A raíz del clon del Atari sin soporte para paddles, me puse a leer un poco la Stella Developer’s Guide para ver qué tan complejo sería adaptar un juego como el Tac-Scan de SEGA, donde el control proporcional no parece escencial, para que funcione con joysticks. Resultó ser un desafío simple pero entretenido.

TacScan screenshot

Como en tantas otras cosas, el Atari es muy básico a la hora de lidiar con los potenciómetros de los paddles: en vez de devolver un valor concreto en un momento dado, requiere que el programador lleve la cuenta del tiempo que tarda en cargarse un capacitor y en base a eso determine la orientación del control.

Tras una pasada del DiStella, pude ver que el Tac-Scan utiliza las direcciones $BB y $BC para tal fin. En $F7C9 comienza la rutina que, a partir del valor almacenado en $BC, carga el acumulador (A) con un offset ($81, $9B ó $B5) a la imagen de la nave, y el registro X con el bit 3 encendido si hay que «espejarla». En el registro Y se carga la orientación de la nave, con valores entre $FE y $02 (-2, -1, 0, 1 y 2), donde 0 es el norte.

Para empezar, fue necesario apartar dos direcciones de RAM para almacenar la última posición registrada del joystick y un contador que nos permita controlar la velocidad de reacción de los mandos. ¿Qué mejor que las mencionadas $BB y $BC? Así que comencé por anular todas las instrucciones del estilo INC $BB, STA $BC y las llamadas a la rutina en $FFEB, que también las afectaba. A partir de ahí, mi objetivo fue escribir una rutina que se ocupara de cargar los registros con los valores correctos y que cupiera en el mismo espacio de la rutina original, para evitar reubicar código y lograr que el resultado difiriera en la menor cantidad de bytes posibles.

Luego de un par de intentos, pude escribir una que calzara justo entre $F7C9-$F80C (68 bytes) más una pequeña tabla de offsets colocada a partir de $FFEC. Algunas operaciones pueden parecer redundantes, pero gracias a ellas se resuelve también el valor inicial, cuando todavía no se han tocado los controles, para que la nave tenga la imagen correcta y esté apuntando hacia el norte. El código es el siguiente:

LF7C9: LDX #$08
       LDA SWCHA         ;lee estado de las palancas
       AND #$C0          ;descarto lo que no sea izq/der
       CMP $BC
       BEQ SAME          ;misma posición de la palanca
       STA $BC
       LDY #$0A          ;restablezco el contador
       STY $BB
 SAME: CMP #$C0
       BEQ DFLT          ;palanca al centro -sin cambios
       DEC $BB           ;decremento retardo
       BNE DFLT
       LDY $F0
       CMP #$80
       BEQ LEFT
       CPY #$02
       BEQ VOID
       INY
 VOID: JMP UPDT
 LEFT: CPY #$FE
       BEQ UPDT
       DEY
 UPDT: STY $F0           ;guardo la dirección calculada
       LDY #$0A          ;restablezco el contador
       STY $BB
 DFLT: LDY $F0
       BPL POS
       LDX #$00
       TYA
       EOR #$FF
       CLC
       ADC #$01
       TAY
  POS: LDA CABJ,Y        ;tabla de punteros
       LDY $F0
       ...
 CABJ: .byte $81,$9B,$B5,$0D,$10,$50

Para compilar el código fuente y generar un binario que podamos correr en un emulador necesitamos el DAsm, un maravilloso ensamblador para 6502, 6811, 68HC11 y 68705. La órden que necesitamos es la siguiente:

DASM tacscan.s -otacscan.bin -f3

Si lo que te interesa es la versión modificada, podés aplicarle mi parche completo a la ROM usando el Hack-O-Matic 3, utilidad que recomiendo, además, para hacer otro tipo de modificaciones a los juegos del Atari.

Deja un comentario