A mi me sirvió entender el porqué de la inestabilidad del raster para entender lo demás... así que empiezo por el principio:
¿por qué la IRQ del raster es inestable?El barrido de la pantalla se hace unas 50 veces por segundo en PAL-B (la Commodore europea).
Y uno le puede decir a la commodore que te avise cuando empiece el barrido, y que te avise cuando el raster esta en cierta posición del barrido.
Supongamos que quiero que la interrupción me avise cuando el raster esta en la posición 50.
Entonces se hace lo tradicional de poner el vector $314 apuntando a donde queres, poner #50 en $d012, y demas.
Pero vas a ver que a veces sos llamado en el medio de la "scan line", o a veces al principio... como si fuera aleatorio.
Pero en verdad no es aleatorio, y sos llamado de acuerdo a lo siguiente:
a) Supongamos que el raster llega a la linea 50
b) La interrupción interrumpe lo que esta sucediendo en bucle principal
c) Para eso tiene que dejar terminar la instrucción que se este ejecutando
d) y luego pone en el stack A,X,Y, status y PC.
e) y luego te llama a tu código.
La unica incógnita es c)... no se sabe que instrucción se esta ejecutando... y hay instrucciones que tardan 2 ciclos y otras que pueden tardar 7.
Y esos 5 ciclos de diferencia es el "randomness" que ves en las "raster inestables".
¿Como prevenirlos?Hay distintas técnicas. La que yo estoy usando es una llamada "doble IRQ" que esta muy bien explicada aca:
http://codebase64.org/doku.php?id=base:stable_raster_routineLa idea es la siguiente:
Como no sabes lo que pasa en c), la idea es poner una primera IRQ llena de NOPs y luego otra, con la idea de que la segunda IRQ se llame cuando se estan ejecutando los NOPs... y luego un truquito más que esta explicado en ese documento.
El código mencionado ahí lo puse en esta macro en format CA65:
https://github.com/ricardoquesada/c64-the-muni-race/blob/master/src/mymacros.mac