No Amiga, o que acontece quando escrevo para $DFC5A0 por engano?

Aug 18 2020

Estou consertando um jogo (TV Sports Basketball) que tenta gravar em dados de áudio (usando o intervalo $DFF0A0para $DFF0D0), mas por algum motivo (programação ruim), o índice às vezes (nem sempre) é falso

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 D0for maior que 3, a gravação (A0,D0.W)está fora dos limites. No meu caso, ele escreve para $DFC5A0, porque após o deslocamento D0é $D500. Também depende da localização da memória da expansão de memória (usar apenas a memória do chip não aciona o bug).

Eu sei que o sistema de endereçamento do Amiga tem máscaras para registradores personalizados e CIAs, e talvez ele realmente escreva para o endereço correto (duvido com $D50um valor base para o índice do canal...), mas se eu corrigir o problema por removendo a gravação quando o índice está fora do intervalo, talvez o som não funcione, enquanto funciona com esse endereço falso.

Por exemplo, se eu escrever algo para $DFC09Aele, na verdade, tem efeito sobre $DFF09A(INTENA, mais fácil de verificar com este registro específico que possui uma contraparte somente leitura), mas se eu escrever $DFC59A, não tem efeito sobre o INTENA.

Não quero deixar esse endereço falso como está, porque ele viola o layout da memória. Existe uma fórmula para mascarar esse endereço e voltar ao $DFF0A0 - $DFF0D0intervalo?

Respostas

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

nota: estou respondendo minha própria pergunta depois de mais pesquisa e experimentação.

A $DFF000base é o endereço base de registro de chip personalizado recomendado pela Commodore .

Mas muitos outros endereços básicos funcionam. Algumas linhas de endereço selecionam a base de chip personalizada e outras são ignoradas.

A área de endereço do chip personalizado é DF0000-DFFFFFpara que qualquer base $DFx000funcione.

Isso se confirma fazendo alguns testes no emulador WinUAE, que é muito fiel a esses aspectos, e que tem a interessante capacidade de poder ler o que está escrito no registrador usando seu depurador interno.

Então, se eu escrever $12345678, $DFC0A0por exemplo, $12345678aparecerá $DFF0A0ao ler registros personalizados (usando o emulador): $DFC000é tão bom quanto $DFF000um endereço de base de chip personalizado e alguns jogos (por exemplo Curse of Ra) usam endereços de base personalizados alternativos (Curse of Ra usa $DFE000), talvez para confundir os hackers, ou apenas para ser original.

Agora, quando escrevo um valor de 32 bits para $DFC5A0(exemplo da vida real), o endereço é convertido em registros personalizados $1A0e $1A2que são os registros de cores 16 e 17 ( $5A0é mascarado para $1A0, existem apenas registros personalizados de $ 100 de 16 bits, qualquer bit superior é ignorado ), portanto, nesse caso, o registro de áudio não é gravado, mas os registros de cor são gravados, então realmente há um bug na rotina de som.

Agora, por que não tem um efeito visual? Porque escrever em registros de cores geralmente não tem efeito: a maioria das listas de cobre sobrescreve aquelas a cada início do feixe, a cada 20ms em PAL. Pode ser perceptível para a cor de fundo (o fundo piscaria brevemente), mas para as cores do primeiro plano seria pouco visível ou mesmo invisível.

Então agora só tenho que decidir se não executo nenhuma ação nesse caso (como no jogo original) ou se mascaro o valor para selecionar um canal de áudio válido e ver se ele altera o som e talvez corrija um bug de longo prazo no o jogo.