Sur Amiga, que se passe-t-il lorsque j'écris par erreur dans $DFC5A0 ?

Aug 18 2020

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 D0est supérieur à 3, alors l'écriture (A0,D0.W)est hors limites. Dans mon cas, il écrit à $DFC5A0, car après le décalage, D0c'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 $D50comme 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 - $DFF0D0gamme ?

Réponses

9 Jean-FrançoisFabre Aug 19 2020 at 04:36

note : Je réponds à ma propre question après plus de recherches et d'expérimentations.

La $DFF000base 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-DFFFFFdonc n'importe quelle base comme $DFx000fonctionne.

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 $12345678par $DFC0A0exemple, $12345678apparaîtra dans $DFF0A0lors de la lecture de registres personnalisés (à l'aide de l'émulateur): $DFC000est aussi bon qu'une $DFF000adresse 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 $1A0et $1A2qui sont des registres de couleur 16 et 17 ( $5A0est 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.