Что произойдет на Amiga, если я по ошибке напишу на $ DFC5A0?
Я исправляю игру (TV Sports Basketball), которая пытается записать аудиоданные (используя диапазон $DFF0A0
до $DFF0D0
), но по какой-то причине (плохое программирование) индекс иногда (не всегда) является поддельным
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
если D0
больше 3, то запись в (A0,D0.W)
не допустима. В моем случае он пишет в $DFC5A0
, потому что после переключения D0
есть $D500
. Это также зависит от места расширения памяти (использование только памяти микросхемы не вызывает ошибки).
Я знаю, что в системе адресации Amiga есть маски для пользовательских регистров и CIA, и, возможно, она действительно будет писать на правильный адрес (я сомневаюсь, что $D50
это базовое значение для индекса канала ...), но если я исправлю проблему с помощью удаление записи, когда индекс находится вне диапазона, возможно, звук не будет работать, тогда как он работает с этим фиктивным адресом.
Например, если я напишу что-нибудь, $DFC09A
это действительно повлияет на $DFF09A
(INTENA, проще проверить этот конкретный регистр, который имеет аналог только для чтения), но если я напишу в $DFC59A
него, это не повлияет на INTENA.
Я не хочу оставлять этот фиктивный адрес как есть, потому что он нарушает структуру памяти. Есть ли формула, чтобы замаскировать этот адрес и вернуться в $DFF0A0 - $DFF0D0
диапазон?
Ответы
Примечание: я отвечаю на свой вопрос после дополнительных исследований и экспериментов.
$DFF000
База является пользовательским чипом регистра базового адреса , рекомендованный Commodore .
Но работают многие другие базовые адреса. Некоторые адресные строки выбирают пользовательскую базу микросхемы, а некоторые игнорируются.
Область пользовательского адреса чипа такова, DF0000-DFFFFF
что любая база вроде $DFx000
работает.
Это подтверждается проведением некоторых тестов на эмуляторе WinUAE, который очень точно отражает эти аспекты и обладает интересной способностью читать то, что записано в регистре, с помощью своего внутреннего отладчика.
Так что, если я пишу $12345678
в $DFC0A0
, например, $12345678
появится $DFF0A0
при чтении пользовательских регистров ( с помощью эмулятора): $DFC000
так хорошо , как в $DFF000
качестве базового адреса пользовательского чипа, и некоторые игры (например : Проклятие Ra) использовать альтернативные пользовательские базовые адреса (Проклятье Ра использует $DFE000
), может быть, чтобы сбить с толку хакеров, или просто чтобы быть оригинальным.
Теперь , когда я пишу 32-разрядное значение $DFC5A0
(например , в реальной жизни), адрес переводится пользовательскими регистры $1A0
и $1A2
которые являются цветными регистрами 16 и 17 ( $5A0
замаскированы в $1A0
, есть только $ 100 16 бит пользовательских регистры, любое более бит игнорируется ), поэтому в этом случае звуковой регистр не записывается, вместо него записываются регистры цвета, так что в звуковой подпрограмме действительно есть ошибка.
Теперь почему это не влияет на визуальные эффекты? Потому что запись в регистры цвета обычно не имеет никакого эффекта: большинство списков меди перезаписывают их при каждом начале луча, каждые 20 мс в PAL. Это может быть заметно по цвету фона (фон будет кратковременно мигать), но для цветов переднего плана он будет едва заметен или даже невидим.
Итак, теперь мне просто нужно решить, не выполняю ли я никаких действий в этом случае (как в оригинальной игре), или я замаскирую значение, чтобы выбрать допустимый аудиоканал и посмотреть, изменит ли он звук, и, возможно, исправить долговременную ошибку в игра.