1

hello,

juste pour info sur mon github, dans le code de mon replay YM il y a une routine de decompression LZ4 en 68000, et la même en DSP

https://github.com/ericde45/YM2149_JAG/blob/main/ym1.s

le compresseur lz4.exe se récupere ici :
GitHub - lz4/lz4: Extremely Fast Compression algorithmGitHubExtremely Fast Compression algorithm. Contribute to lz4/lz4 development by creating an account on GitHub.


on compresse avec un : lz4.exe -9 -l --no-frame-crc [fichier input] [fichier output]

et le début des datas compressées est en +8 du fichier

le -l genere un format en legacy frame, + simple.
la doc du format legacy frame est ici : https://android.googlesource.com/platform/external/lz4/+/HEAD/doc/lz4_Frame_format.md
ça bascule en taille de bloc de 8 Mo donc pour la jaguar on a qu'un bloc par fichier.
avatar

2

Bon boulot, tu devrais le partager aussi sur AtariAge smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3

Peut-être que cela serait aussi une belle addition au SDK de cubanismo.

4

il y a une chose que je commence à vraiment apprécier sur la Jaguar, c'est que si on rend un processeur indépendant en pensant bien son code, on peut faire du joli parallélisme bien propre
sur Jalaga, j'en suis au stade où je charge en cours de jeu des graphismes de la rom, en les decompressant au dsp, pendant que le gpu continue de créer l'object list et que la musique est sans coupure.
( le 68000 attend, car il est trop lent wink )
avatar

5

bonjour

petite question posée aussi sur atariage, mais sans réponse claire :

lorsque je decompresse au dsp, les interruptions I2S du dsp pour jouer de la musique ( module amiga) sont ralenties et le son devient 'faux' comme une fausse note
est ce que quelqu'un a une idée pour donner plus de possibilités d'interruption au code en I2S, même si ça ralentit le code principal de décompression ?

je suis a 16000 Hz donc je ne sature pas le dsp uniquement avec le replay de musique
avatar

6

hmm, difficile à dire.
Faudrais que je regarde le code pour comprendre d'où ca peut provenir.
avatar

7

voila le code executé dans la boucle principale
le code en interruption est très long ( i2S + timer 1 pour la gestion du module + timer 2 pour la gestion des pads )
edit : j'ai ajouté des or comme conseillé sur atariage mais je n'ai pas encore testé le résultat.

lz4_depack_smallest_DSP:
move R20,R24
add R5,R24 ; packed buffer end
moveq #0,R5
moveq #0,R2
moveq #$F,R4
movei #$FF,R12

.tokenLoop_smallest_DSP:
loadb (R20),R5
addq #1,R20
move R5,R6
shrq #4,R6
movei #.lenOffset_smallest_DSP,R10
cmpq #0,R6
jump eq,(R10)
nop

.readLen_smallest1_DSP:
movei #.readEnd_smallest1_DSP,R11
cmp R6,R4 ; cmp.B !!!!
jump ne,(R11)
nop

.readLoop_smallest1_DSP:
loadb (R20),R2
addq #1,R20
add R2,R6 ; final len could be > 64KiB

not R2
and R12,R2 ; not R2.b
movei #.readLoop_smallest1_DSP,R10
cmpq #0,R2
jump eq,(R10)
nop

.readEnd_smallest1_DSP:

.litcopy_smallest_DSP:
loadb (R20),R13
storeb R13,(R21)
addq #1,R20
addq #1,R21
movei #.litcopy_smallest_DSP,R10
subq #1,R6
cmpq #0,R6
jump ne,(R10)
nop

; end test is always done just after literals
movei #.readEnd_smallest_DSP,R11
cmp R20,R24
jump eq,(R11)
nop

.lenOffset_smallest_DSP:
loadb (R20),R6 ; read 16bits offset, little endian, unaligned
addq #1,R20
loadb (R20),R13
addq #1,R20
shlq #8,R13
add R13,R6

move R21,R23
sub R6,R23 ; R6/d1 bits 31..16 are always 0 here

moveq #$F,R6
and R5,R6 ; and.w d0,d1 .W !!!

.readLen_smallest2_DSP:
movei #.readEnd_smallest2_DSP,R11
cmp R6,R4 ; cmp.B !!!!
jump ne,(R11)
nop

.readLoop_smallest2_DSP:
loadb (R20),R2
addq #1,R20
add R2,R6 ; final len could be > 64KiB

not R2
and R12,R2 ; not R2.b
movei #.readLoop_smallest2_DSP,R10
cmpq #0,R2
jump eq,(R10)
nop

.readEnd_smallest2_DSP:
addq #4,R6

.copy_smallest_DSP:
loadb (R23),R13
storeb R13,(R21)
addq #1,R23
addq #1,R21
movei #.copy_smallest_DSP,R10
movei #.tokenLoop_smallest_DSP,R11
subq #1,R6
jump ne,(R10)
nop
jump (R11)
nop

.readLen_smallest_DSP:
movei #.readEnd_smallest_DSP,R11
cmp R6,R4 ; cmp.B !!!!
jump ne,(R11)
nop

.readLoop_smallest_DSP:
loadb (R20),R2
or R2,R2
addq #1,R20
add R2,R6 ; final len could be > 64KiB
or R2,R2

not R2
and R12,R2 ; not R2.b
or R2,R2
movei #.readLoop_smallest_DSP,R10
cmpq #0,R2
jump eq,(R10)
nop

.readEnd_smallest_DSP:

movei #LZ4_pointeur_sur_bloc_a_decompresser,R6
moveq #0,R23
movei #DSP_boucle_centrale,R4
store R23,(R6) ; mets a zero l'adresse du bloc a decompresser / decompression terminée


jump (R4)
nop
avatar

8

Tu utilises les interruptions timer, ou tu lis les timers manuellement dans l'interruption I²S ?
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

9

j'utilise les interruptions timers
dans l'I2S je ne fais que mixer les 4 samples + 4 samples de son de jeu. ( dans la version dont je parle actuellement )

movei #D_FLAGS,r30
movei #D_I2SENA|D_TIM1ENA|D_TIM2ENA|REGPAGE,r29 ; I2S+Timer 1+timer 2
store r29,(r30)


elle est étrange ta question, je veux bien que tu explicites ce que tu envisages ou que tu as déjà fait ainsi ?
avatar

10

Si tu utilises le code d'interruption "classique", le bit IMASK de D_FLAGS (qui bloque toutes les interruptions sans distinction) est réinitialisé seulement à la fin du code, après tout le reste. Par conséquent, si le code d'une ou de l'autre de tes interruptions timer prend plus de 1/16000ème de seconde à s'exécuter, tu vas louper des interruptions I²S et donc ralentir la sortie audio.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

11

oui j'avais capté ça j'ai essayé d'utiliser des registres différents entre timer 1 et I2S pour pouvoir redemarrer l'I2S des le debut du timer 1 mais je n'ai pas repris ce point pour l'instant
mais là je parle du code de decompression qui tourne en boucle principale du dsp, et qui ralentit les interruptions I2S
alors que le reste du temps, même quand le 68000 et le gpu turbine à fond, j'ai pas ce souci
avatar

12

une précision : la source de lecture des loadb ( données compressées ) est en ROM ( sur le GD actuellement )
donc ça doit amplifier le ralentissement
avatar

13

bon j'ai ajouté un nop, un or Rx,Rx et un autre nop après chaque loadb
et c'est assez atténue pour que je n'entende plus la dissonance du son.
avatar

14

Ajouter du nop/or/nop aide, vu que ça libère du cycle pour insérer les interruptions plus facilement.

- dans le code (du ./1), on voit que l'écriture right/left channel dans l'I2S se fait à la toute fin du code I2S et est précédé d'environ 700 lignes de codes, avec des tas de sauts conditionnels zappant des partis de codes non négligeable (j'ai pas spécialement fait gaffe si il y avait des loop). donc je dirais qu'il y a probablement une énorme différence entre le moment où l'interruption I2S démarre et le moment où les registres sont écrits pour chaque échantillons.
- lors d'une décompression qui va charger le bus avec les loads et donc probablement bloquer le flux d'instruction pour avoir la data voulu, va ajouter du jitter entre le moment ou l'interruption est triggée et le moment où l'insertion du code va réellement avoir lieu

Dans ces conditions, en cumulant les 2, ainsi que les cycles potentiellement pris par le Timer1, si il est déclenché et non fini avant l'interruption I2S, on doit probablement avoir un jitter énorme.

Tu peux essayer en écrivant la valeur dans l'I2S dès le début de l'interruption I2S au lieu de le faire à la fin : en gros calculer l'échantillon N+1 au lieu de calculer l'échantillon N.
Peut-être que ça aidera aussi.
avatar

15

pour l'instant j'ai basculé sur une décompression au 68000, beaucoup plus lente

mais je garde en tête d'écrire les samples droite et gauche en debut de I2S
avatar

16

bon j'ai mis l'écriture des samples en début d"I2S ( facile puisque j'avais séparé l'utilisation des registres entre les timers )
la qualité doit être meilleure, en théorie
pas de changement face à la décompression au dsp de data venant de la rom : ca ralentit l'I2S
avatar