Sur Amiga, que se passe-t-il lorsque j'écris par erreur dans $DFC5A0 ?
Je répare un jeu (TV Sports Basketball) qui essaie d'écrire des données audio (en utilisant la plage $DFF0A0
à $DFF0D0
) mais pour une raison quelconque (mauvaise programmation), l'index est parfois (pas toujours) faux
MOVEA.L #$00DFF0A0,A0 ;004e78: 207c00dff0a0 load custom address in A0
MOVE.W $0008(A5),D0 ;004e80: 302d0008 audio channel 0-3
LSL.W #4,D0 ;004e84: e948 shifting (mul by 16)
MOVE.L -$346E(A4),(A0,D0.W) ;004e86: 21accb920000 write to register
si D0
est supérieur à 3, alors l'écriture (A0,D0.W)
est hors limites. Dans mon cas, il écrit à $DFC5A0
, car après le décalage, D0
c'est $D500
. Cela dépend également de l'emplacement mémoire de l'extension de mémoire (utiliser uniquement de la mémoire à puce ne déclenche pas le bogue).
Je sais que le système d'adressage Amiga a des masques pour les registres personnalisés et les CIA, et peut-être qu'il écrira à la bonne adresse (j'en doute avec $D50
comme valeur de base pour l'index de canal...), mais si je résous le problème en supprimer l'écriture lorsque l'index est hors de portée, peut-être que le son ne fonctionnera pas, alors qu'il fonctionne avec cette fausse adresse.
Par exemple, si j'écris quelque chose $DFC09A
, cela a un effet sur $DFF09A
(INTENA, plus facile à vérifier avec ce registre particulier qui a une contrepartie en lecture seule) mais si j'écris $DFC59A
, cela n'a aucun effet sur INTENA.
Je ne veux pas laisser cette fausse adresse telle quelle, car elle viole la disposition de la mémoire. Existe-t-il une formule pour masquer cette adresse et se remettre dans la $DFF0A0 - $DFF0D0
gamme ?
Réponses
note : Je réponds à ma propre question après plus de recherches et d'expérimentations.
La $DFF000
base est l'adresse de base du registre de puce personnalisée recommandée par Commodore .
Mais de nombreuses autres adresses de base fonctionnent. Certaines lignes d'adresse sélectionnent la base de puce personnalisée et d'autres sont ignorées.
La zone d'adresse de puce personnalisée est DF0000-DFFFFF
donc n'importe quelle base comme $DFx000
fonctionne.
Ceci est confirmé en faisant quelques tests sur l'émulateur WinUAE, qui est très fidèle à ces aspects, et qui a la capacité intéressante de pouvoir lire ce qui est écrit dans le registre à l'aide de son débogueur interne.
Donc, si j'écris $12345678
par $DFC0A0
exemple, $12345678
apparaîtra dans $DFF0A0
lors de la lecture de registres personnalisés (à l'aide de l'émulateur): $DFC000
est aussi bon qu'une $DFF000
adresse de base de puce personnalisée, et certains jeux (par exemple Curse of Ra) utilisent des adresses de base personnalisées alternatives (Curse of Ra utilise $DFE000
), peut-être pour confondre les pirates, ou simplement pour être original.
Maintenant, lorsque j'écris une valeur 32 bits $DFC5A0
(exemple réel), l'adresse se traduit par des registres personnalisés $1A0
et $1A2
qui sont des registres de couleur 16 et 17 ( $5A0
est masqué en $1A0
, il n'y a que 100 $ de registres personnalisés 16 bits, tout bit supérieur est ignoré ), donc dans ce cas, le registre audio n'est pas écrit, les registres de couleur sont écrits à la place, donc il y a vraiment un bogue dans la routine sonore.
Maintenant, pourquoi cela n'a-t-il pas d'effet sur les visuels ? Parce que l'écriture dans les registres de couleur n'a généralement aucun effet : la plupart des listes de cuivre écrasent celles à chaque démarrage du faisceau, toutes les 20 ms en PAL. Cela peut être perceptible pour la couleur d'arrière-plan (l'arrière-plan clignoterait brièvement), mais pour les couleurs de premier plan, il serait à peine visible, voire invisible.
Alors maintenant, je dois juste décider si je n'effectue aucune action dans ce cas (comme le jeu original) ou si je masque la valeur pour sélectionner un canal audio valide et voir si cela change le son, et peut-être corriger un bug à long terme dans le jeu.