Su Amiga, cosa succede se scrivo per errore su $DFC5A0?
Sto riparando un gioco (TV Sports Basketball) che tenta di scrivere dati audio (usando l'intervallo $DFF0A0
to $DFF0D0
) ma per qualche motivo (cattiva programmazione), l'indice a volte (non sempre) è fasullo
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
se D0
è maggiore di 3, la scrittura in (A0,D0.W)
è fuori limite. Nel mio caso scrive a $DFC5A0
, perché dopo lo spostamento D0
è $D500
. Dipende anche dalla posizione di memoria dell'espansione della memoria (l'utilizzo solo della memoria del chip non attiva il bug).
So che il sistema di indirizzamento Amiga ha maschere per registri personalizzati e CIA, e forse scriverà effettivamente all'indirizzo corretto (ne dubito con $D50
come valore base per l'indice del canale...), ma se risolvo il problema con rimuovendo la scrittura quando l'indice è fuori portata, forse il suono non funzionerà, mentre funziona con quell'indirizzo fasullo.
Ad esempio, se ci scrivo qualcosa $DFC09A
ha effetto su $DFF09A
(INTENA, più facile da controllare con questo particolare registro che ha una controparte di sola lettura) ma se ci scrivo $DFC59A
non ha effetto su INTENA.
Non voglio lasciare quell'indirizzo fasullo così com'è, perché viola il layout della memoria. Esiste una formula per mascherare questo indirizzo e rientrare $DFF0A0 - $DFF0D0
nell'intervallo?
Risposte
nota: sto rispondendo alla mia stessa domanda dopo ulteriori ricerche e sperimentazioni.
La $DFF000
base è l'indirizzo di base del registro del chip personalizzato raccomandato da Commodore .
Ma molti altri indirizzi di base funzionano. Alcune righe di indirizzo selezionano la base di chip personalizzata e altre vengono ignorate.
L'area dell'indirizzo del chip personalizzato è DF0000-DFFFFF
quindi qualsiasi base come $DFx000
funziona.
Ciò è confermato facendo alcuni test sull'emulatore WinUAE, che è molto fedele a questi aspetti, e che ha l'interessante capacità di poter leggere ciò che è scritto nel registro usando il suo debugger interno.
Quindi, se scrivo $12345678
ad $DFC0A0
esempio, $12345678
apparirà $DFF0A0
durante la lettura dei registri personalizzati (utilizzando l'emulatore): $DFC000
è buono come $DFF000
un indirizzo di base del chip personalizzato e alcuni giochi (ad esempio Curse of Ra) utilizzano indirizzi di base personalizzati alternativi (Curse of Ra usa $DFE000
), forse per confondere gli hacker, o semplicemente per essere originale.
Ora, quando scrivo un valore a 32 bit in $DFC5A0
(esempio di vita reale), l'indirizzo si traduce in registri personalizzati $1A0
e $1A2
che sono i registri di colore 16 e 17 ( $5A0
è mascherato a $1A0
, ci sono solo $ 100 registri personalizzati a 16 bit, qualsiasi bit superiore viene ignorato ), quindi in tal caso, il registro audio non è scritto, vengono invece scritti i registri colore, quindi c'è davvero un bug nella routine del suono.
Ora, perché non ha un effetto visivo? Perché la scrittura sui registri dei colori di solito non ha alcun effetto: la maggior parte delle copperlist sovrascrive quelle a ogni inizio del raggio, ogni 20 ms in PAL. Può essere evidente per il colore di sfondo (lo sfondo lampeggerebbe brevemente) ma per i colori in primo piano sarebbe appena visibile o addirittura invisibile.
Quindi ora devo solo decidere se eseguire alcuna azione in quel caso (come nel gioco originale) o se mascherare il valore per selezionare un canale audio valido e vedere se cambia il suono, e magari correggere un bug a lungo termine in il gioco.