Что произойдет на Amiga, если я по ошибке напишу на $ DFC5A0?

Aug 18 2020

Я исправляю игру (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диапазон?

Ответы

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

Примечание: я отвечаю на свой вопрос после дополнительных исследований и экспериментов.

$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. Это может быть заметно по цвету фона (фон будет кратковременно мигать), но для цветов переднего плана он будет едва заметен или даже невидим.

Итак, теперь мне просто нужно решить, не выполняю ли я никаких действий в этом случае (как в оригинальной игре), или я замаскирую значение, чтобы выбрать допустимый аудиоканал и посмотреть, изменит ли он звук, и, возможно, исправить долговременную ошибку в игра.