Su Amiga, cosa succede se scrivo per errore su $DFC5A0?

Aug 18 2020

Sto riparando un gioco (TV Sports Basketball) che tenta di scrivere dati audio (usando l'intervallo $DFF0A0to $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 $D50come 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 $DFC09Aha effetto su $DFF09A(INTENA, più facile da controllare con questo particolare registro che ha una controparte di sola lettura) ma se ci scrivo $DFC59Anon 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 - $DFF0D0nell'intervallo?

Risposte

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

nota: sto rispondendo alla mia stessa domanda dopo ulteriori ricerche e sperimentazioni.

La $DFF000base è 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-DFFFFFquindi qualsiasi base come $DFx000funziona.

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 $12345678ad $DFC0A0esempio, $12345678apparirà $DFF0A0durante la lettura dei registri personalizzati (utilizzando l'emulatore): $DFC000è buono come $DFF000un 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 $1A0e $1A2che 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.