J'ai regardé également rapidement le code DSP (uniquement) et il y a quelques trucs qui me semble un peu bizarre, mais je peux me tromper et puis surtout ça n'a surement aucun rapport avec le bug.
Première chose, les interruptions utilisent obligatoirement les registres de la banque 0. Du coup tu peux utiliser la banque 1 pour le programme "normal" et la banque 0 uniquement pour ton interruption. Ca te permet de ne pas être obligé de sauvegarder ou d'initialiser certains registres à chaque fois.
Je dis ça vu que la routine d'interruption initialise dès le début plusieurs registres qui ne semblent pas être modifié tout le long.
ex : timerint:
movei #D_FLAGS,r30
et
movei #L_I2S,r15
Ensuite, bon tu n'en est peut être pas à la phase d'optimisation, mais au cas où pense à l'entrelacement du code.
Par exemple au début
timerint:
movei #D_FLAGS,r30
load (r30),r29 <- wait state ici car r30 est verrouillé par l'instruction du dessus
moveq #0,r24
move r24,r25 <- même chose ici car r24 est verrouillé
Peut avantageusement être entrelacé comme :
timerint:
movei #D_FLAGS,r30
moveq #0,r24
load (r30),r29
move r24,r25
Bon alors ok ça ne fait gagner que 2 cycles mais....
Il me semble que pour l'interruption des échantillons tu prends le problème à l'envers.
Si je ne me trompe pas lors de l'interruption tu fais les calculs avant, et ensuite tu charges les registres I2S avec le résultat.
Pour la génération du son la routine du chargement des échantillons doit être la plus courte possible et n'avoir si possible aucun changement de flux ou de condition (jmp, cmp, etc.)
La moindre différence du nombre de cycle entre chaque échantillon provoquera des distorsions de fréquence ou même des craquements si par exemple tu vas lire les échantillons en DRAM et que le BUS est trop occupé.
Il faut donc dès le début de l'interruption charger les registres I2S avec les valeurs calculées dans l'interruption précédente (ou une autre routine)
L'interruption pour les échantillons devrait se comporter comme si c'était un DMA : charger les échantillons déjà calculés, FIN.
Par endroit tu fais des protections de registre (pour activer le mécanisme du scorboard quand il fait défaut) qui ne me semble pas utile (et qui peuvent faire perdre des cycles du coup puisque il devient également inutile d'entrelacer le code)
Par exemple :
movei #_timer8KHz,r21
or r21,r21
load (r21),r22
Pourquoi or r21,r21 ?
Sauf erreur il n'y a rien qui nécessite un verrouillage forcé de r21
Par contre là oui :
load (r21),r22
or r22,r22
addq #1,r22
car ici c'est en effet le "bug" de la double écriture d'un registre sans lecture préalable
r22 est écrit une première fois et sans l'instruction "or" il ne serait pas verrouillé lors de l'instruction addq et le résultat serait... inattendue
Il y a quelques endroit ou tu fais une protection également étrange :
add r22,r23 ; step
or r23,r20 ; scoreboard bug
2 choses :
1 - Pourquoi : or r23, r20 ? et pas or r23,r23 ?
Bon à priori de ce que j'ai vu r20 n'a pas d'importance à ce moment là, mais si un jour tu ajoutes du code qui utilise r20 tu pourrais passer à coté d'un bug énervant.
2 - c'est à confirmer, mais je crois que le bug du scorboard sur l'adressage indexé ne concerne QUE les instructions à très long cycle. C'est à dire.... quasiment que le DIV en fait. C'est d'ailleurs indiqué dans le documentation (long latency instruction)
Pourquoi ? Tout simplement parce que l'adressage indexé prend 2 cycles de plus qu'un LOAD (ou STORE) normal. Ducoup, le temps que l'adressage soit calculé, l'instruction précédente est déjà fini et le registre est libre et avec la bonne valeur.
Avec un DIV qui prend 16cycles je crois, s'il est placé juste avant ou en tout cas pas trop loin du STORE indexé, il n'aura clairement pas fini sont calcul et l'écriture du registre tombera après ou en même temps.
Tout ça c'est de la spéculation dans la mesure ou je n'est pas testé, je me base sur ce qui est écrit dans la doc (d'autant que celle ci parle bien de 2 cycles supplémentaire pour le LOAD indexé mais pas le STORE, mais il parait logique qu'il prenne + de temps aussi)
De la même façon il n'est pas nécessaire de protéger les registres ici :
add r22,r23 ; step
add r26,r24 ; mix left
add r27,r25 ; mix right
or r23,r20 ; scoreboard bug
store r23,(r14+CVoiceSplCpti)
.endtimerint:
or r24,r20 ; scoreboard bug
store r24,(r15)
or r25,r20 ; scoreboard bug
store r25,(r15+1)
Tous les registres concernés (r23, r24, r25) sont éloignés de leur STORE respectif, de très loin même) dont 1 qui n'est pas indexé
Bon voilà, j'ai peut être dis un tas de conneries, dans ce cas n'en tiens pas compte
