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.
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.