Amiga'da yanlışlıkla $ DFC5A0'a yazdığımda ne olur?
Ses verilerine (aralığı $DFF0A0
kullanarak $DFF0D0
) yazmaya çalışan bir oyunu (TV Spor Basketbolu) düzeltiyorum, ancak bazı nedenlerden dolayı (kötü programlama), dizin bazen (her zaman değil) sahte oluyor
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
eğer D0
3'ten büyüktür, daha sonra yazma için (A0,D0.W)
sınırlar dışında yoludur. Benim durumumda bu yazar $DFC5A0
değişen çünkü sonra D0
ise $D500
. Ayrıca, bellek genişletme işleminin bellek konumuna da bağlıdır (yalnızca yonga belleğinin kullanılması hatayı tetiklemez).
Amiga adresleme sisteminin özel kayıtlar ve CIA'lar için maskeleri olduğunu biliyorum ve belki de aslında doğru adrese yazacaktır ( $D50
kanal indeksi için temel değer olduğundan şüpheliyim ...), ancak sorunu şu şekilde düzeltirsem dizin aralık dışındayken yazmanın kaldırılması, belki ses çalışmayabilir, oysa bu sahte adresle çalışır.
Örneğin, eğer $DFC09A
ona bir $DFF09A
şey yazarsam aslında bir etkisi olur (INTENA, salt okunur muadili olan bu özel sicil ile kontrol etmek daha kolaydır), ancak $DFC59A
ona yazarsam INTENA üzerinde hiçbir etkisi olmaz.
Bu sahte adresi olduğu gibi bırakmak istemiyorum çünkü bellek düzenini ihlal ediyor. Bu adresi maskelemek ve $DFF0A0 - $DFF0D0
aralığa geri dönmek için bir formül var mı ?
Yanıtlar
not: Daha fazla araştırma ve deney yaptıktan sonra kendi sorumu cevaplıyorum.
$DFF000
Baz özel çip kayıt taban adresidir Commodore tarafından tavsiye .
Ancak diğer birçok temel adres çalışır. Bazı adres satırları özel çip tabanını seçer ve bazıları göz ardı edilir.
Özel çip adres alanı, DF0000-DFFFFF
herhangi bir temel gibi $DFx000
çalışır.
Bu, bu yönlere çok sadık olan ve dahili hata ayıklayıcısını kullanarak kayıtta yazılanları okuyabilme gibi ilginç bir yeteneğe sahip olan WinUAE emülatörü üzerinde bazı testler yapılarak doğrulanır .
Ben yazarsam Yani $12345678
içinde $DFC0A0
örneğin $12345678
görünecektir $DFF0A0
(emülatörü kullanarak) özel kayıtlarını okurken: $DFC000
olarak iyi gibidir $DFF000
(Laneti özel çip taban adresi olarak ve (Ra örneği Laneti) bazı oyunlar alternatif özel taban adresleri kullanır Ra kullanır $DFE000
), belki bilgisayar korsanlarının kafasını karıştırmak için veya sadece orijinal olmak için.
Ben bir 32-bit değeri yazma Şimdi zaman $DFC5A0
(gerçek hayatta örneğin), adres özel kayıtlar ile çevirir $1A0
ve $1A2
16 ve 17 (renk kayıtları hangi $5A0
şekilde gizlenmiş olabilir $1A0
, herhangi bir yüksek bit orada yok sayılır sadece 100 $ 16 bit özel kayıtları vardır ), yani bu durumda, ses kaydı yazılmaz, bunun yerine renk kayıtları yazılır, bu nedenle ses rutininde gerçekten bir hata vardır.
Şimdi neden görseller üzerinde bir etkisi yok? Renkli kayıtlara yazmanın genellikle bir etkisi olmadığı için: çoğu bakır liste, her 20 ms PAL'de ışının her başlangıcında bunların üzerine yazar. Arka plan rengi için fark edilebilir (arka plan kısaca yanıp söner), ancak ön plan renkleri için zar zor görünür ve hatta görünmez olur.
Şimdi bu durumda (orijinal oyun gibi) herhangi bir işlem yapıp yapmayacağıma veya geçerli bir ses kanalı seçmek için değeri maskeleyip sesi değiştirip değiştirmediğine ve belki de uzun vadeli bir hatayı düzeltip düzeltmeyeceğime karar vermeliyim. oyun.