I'm fixing a game (TV Sports Basketball) that tries to write in audio data (using the range $DFF0A0
to $DFF0D0
) but for some reason (bad programming), the index is sometimes (not always) bogus
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
if D0
is greater than 3, then the write to (A0,D0.W)
is way out of bounds. In my case it writes to $DFC5A0
, because after shifting D0
is $D500
. It also depends on the memory location of the memory expansion (using only chip memory doesn't trigger the bug).
I know that the Amiga addressing system has masks for custom registers and CIAs, and maybe it will actually write to the correct address (I doubt it with $D50
as a base value for the channel index...), but if I fix the issue by removing the write when the index is out of range, maybe that the sound won't work, whereas it works with that bogus address.
For instance, if I write something to $DFC09A
it actually has an effect on $DFF09A
(INTENA, easier to check with this particular register which has a read-only counterpart) but if I write to $DFC59A
it has no effect on INTENA.
I don't want to leave that bogus address as is, because it violates the memory layout. Is there a formula to mask this address and get back in the $DFF0A0 - $DFF0D0
range ?