1

bonjour

je découvre la jaguar a travers les docs dispos, et quelques sources style player de module remover
et j'ai déssassemblé le moteur de son U235

je suis capable de rejouer un sample à la bonne fréquence, au dsp en utilisant n'importe quel timer ( IS2 , timer 1 et timer 2 )
( merci la décomposition en nombres premiers pour trouver les 2 valeurs pour les timers, ca promet )

et j'ai quelques questions sur le son et les interruptions:

- est ce que le serial I2S a une forme de buffer, permettant d'avoir le temps de le re-remplir ?

- dans la gestion des interruptions j'ai compris que lorsqu'une interruption se déclenche, le dsp bascule sur son second jeu de registre. or dans le source du U235, aucune interruption ne s'inquiete de sauvegarder les registres avant de les modifier.
et il y a 3 timers en parallèle dans leur moteur.
donc 2 possibilités :
- je n'ai pas compris l'utilisation des registres / du jeu de registre , lors d'une interruption ? et il n'y a pas de conflit entre les routines en i2s/ timer 1/timer 2
- chaque routine bloque les autres interruptions lorsqu'elle fonctionne, dans ce cas le son doit etre déformé au final ? j'ai souvenir que sur ST il fallait absolument produire le son de façon régulière et sans en louper ( par exemple en full screen dans les ligne de synscroll) pour ne pas dégrader la qualité sonore percue ?
si le timer 1 ou le timer 2 bloque le I2S, le son en cours reste trop longtemps ?

si vous avez des docs autres que le jag V8 je suis preneur bien sur !
avatar

2

ericde45 (./1) :
je suis capable de rejouer un sample à la bonne fréquence, au dsp en utilisant n'importe quel timer ( IS2 , timer 1 et timer 2 )
Il faut utiliser uniquement l'interruption I²S pour mettre à jour les registres audio. Le faire via une autre interruption timer pose plusieurs problèmes (et ça utilise un timer qui pourrait servir à autre chose).

ericde45 (./1) :
- est ce que le serial I2S a une forme de buffer, permettant d'avoir le temps de le re-remplir ?
Non, y'a pas de buffer. Il faut l'implémenter toi-même si tu en as besoin.

ericde45 (./1) :
- dans la gestion des interruptions j'ai compris que lorsqu'une interruption se déclenche, le dsp bascule sur son second jeu de registre.
Oui.

ericde45 (./1) :
or dans le source du U235, aucune interruption ne s'inquiete de sauvegarder les registres avant de les modifier.
et il y a 3 timers en parallèle dans leur moteur.
donc 2 possibilités :
- je n'ai pas compris l'utilisation des registres / du jeu de registre , lors d'une interruption ? et il n'y a pas de conflit entre les routines en i2s/ timer 1/timer 2
- chaque routine bloque les autres interruptions lorsqu'elle fonctionne, dans ce cas le son doit etre déformé au final ? j'ai souvenir que sur ST il fallait absolument produire le son de façon régulière et sans en louper ( par exemple en full screen dans les ligne de synscroll) pour ne pas dégrader la qualité sonore percue ?
si le timer 1 ou le timer 2 bloque le I2S, le son en cours reste trop longtemps ?

si vous avez des docs autres que le jag V8 je suis preneur bien sur !
Je n'ai pas décortiqué le code de U235, mais il est possible que le code d'interruption s'exécute suffisamment rapidement pour que ça ne pose pas de problème. Par rapport à un 68000, le DSP a un ratio instruction / cycle d'horloge nettement supérieur, on peut faire pas mal de choses dans une interruption avant d'avoir des soucis de timing.
La meilleure solution est probablement de demander à l'auteur 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

- Il n'y a pas de buffer I2S, ou disons qu'il est de profondeur = 1.
la valeur écrite est celle utilisée pour la sérialisation, ie : si tu modifies la valeur dans le registre durant le transfert au DAC ça influera directement la sortie audio.
Il faut donc écrire dans les registres I2S le plus vite possible après le démarrage d'une interruption I2S.

- Lors d'une interruption, le DSP force l'utilisation de la bank0 de registres.
Je ne sais pas comment est fait U235 vu que le code n'est pas publique, mais en général le programmeur réserve les registres bank0 qu'il a besoin pour chaque niveau d'interruption afin d'éviter de faire des sauvegardes / restauration de registres.
La bank1 est généralement utilisée pour le code principale ou pour stoker des valeurs.
Le DSP n’exécute pas une nouvelle interruption si il est déjà dans une routine d'interruptions : il faut explicitement indiqué au DSP que l'interruption est traité pour qu'il exécute une autre interruption potentiellement en attente.

Donc oui, si tu as des interruptions, il faut que les routines soient les plus courtes possibles.
En général il ne devrait pas y avoir de problème étant données que le DSP est très rapide et que l'I2S est l'interruption la plus prioritaire.
avatar

4

cool, merci beaucoup pour vos réponses !

il y a un truc que j'apprécie déjà c'est que il n'y a pas d'OS qui fait suer. Le hardware est accessible en direct et il a un fonctionnement stable en grande majorité ( j'ai vu la liste de bugs mais pour l'instant c'est un peu hors de ma compréhension )

je vais continuer à creuser.
avatar

5

Ah ben ça c'est sûr, y'a pas d'OS : c'est déjà tout juste si y'a un SDK grin
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

6

hello

concernant l'approche de la contention du bus mémoire de la Jaguar, je projette de suivre les idées ci dessous ;

- je met mon code dsp dans la ram dsp.
- Je lis des valeurs de samples de 32 bits, pas octet par octet
- quel est l’intérêt de lire + de 32 bits ? le bus est il plus rapide si on lit une série de long words qui se suivent dans la ram centrale, pour les stocker dans la ram dsp ?

en général je privilégie un temps cpu stable par VBL ou par cycle de rafraichissement. donc si il n'y a pas de gain en lisant plusieurs long words à la suite, quel interet ?

( j'ai vu ce conseil , de lire plusieurs octets de sample, sur atariage, il me semble, donné par un codeur de jeu sur Jaguar, mais je n'ai pas retrouvé le lien )
avatar

7

D'un point de vue DSP, niveau performance c'est plus rentable de faire des "burst" car tu peux utiliser l'avantage du pipeline.
D'un point de vue globale, ça dépend du besoin en ressource du reste des CPU car le DSP est le CPU qui a la plus haute priorité après l'OP.
avatar

8

Vu que chaque accès externe occupe le bus principal indépendamment de la taille des données, il vaut mieux en effet lire 32 bits d'un coup (quitte à décomposer en octets ensuite). C'est ce que je fais dans mon code audio, et je crois qu'U235 fait pareil.

Faire plusieurs accès 32 bits à la suite apporte théoriquement un léger gain, vu que les accès consécutifs à une même page de RAM sont un peu plus rapides que les accès aléatoires. En poussant la logique, on pourrait même gérer un cache local en RAM DSP qui est rechargé par bursts.

Après :
- comme le dit SCPCD, il ne faut pas oublier les autres composants qui ont besoin du bus
- il faut voir si le gain en performance vaut vraiment le coup par rapport à la complexité supplémentaire du code
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

merci.

effectivement gérer un cache DSP c'est déjà + complexe
et quand je vois la logique de gérer un gestionnaire de chargement de routines pour le GPU pour faire de la 3D, ça doit etre très sympathique pour s'y retrouver.
avatar

10

hello

nouvelle question sur le son
j'ai commencé à refaire ma routine de YM pour pouvoir la debugger plus facilement

au lieu de calculer 1 sample à chaque interruption I2S, je remplis un buffer
et là je m'aperçois que mon buffer qui par exemple devrait etre de 437 octets, en fait seuls 393 ou 394 octets sont lus par l'I2S entre chaque appel du replay

soit mon calcul de fréquence I2S est faux ( j'ai rien inventé, j'ai regardé dans le player remover pour comprendre comment fonctionne l'i2S)
soit je suis en ntsc au lieu de pal

est ce que quelqu'un a des infos pour :

- calculer la valeur I2S, en accord avec la doc : Serial Clock Frequency = System Clock Frequency / (2 * (N+1))
où puis je trouver la System Clock Frequency ? en PAL ? en NTSC ?

- comment checker que je suis en PAL ou en NTSC ?

merci d'avance
avatar

11

La fréquence d'horloge est quasiment la même pour PAL et NTSC, donc ça ne vient pas du DSP :
tTK5

Pour vérifier si tu es en PAL ou en NTSC, c'est dans le registre JOYBUTS :
tXHl
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

12

je suis bien en pal

je ne comprends pas pourquoi avec

pour I2S:
SCLK = $12 = 18
Serial Clock Frequency = System Clock Frequency / (2 * (N+1))
Serial Clock Frequency = 26593900 / (2 * 16 * 2 * (18+1)) = 21 869,98355263158 Hz


pour timer 1:
Timer 1 Pre-scaler = 146-1
Timer 1 Divider = 3643-1

26593900 / 146 = 182150
182150 / 3643 = 50

donc le timer 1 est en 50 hz

dans le timer 1 je swap un pointeur sur un buffer
dans le I2S je lis ce buffer et j'incremente ce pointeur

et quand je vérifie, je devrai avoir : 21 869,98355263158 / 50 = 437
et j'ai 393 ou 394

que ce soit sous Virtual Jaguar ou Phoenix

j'ai même ré-autorisé les interruptions dès le début de ma routine timer 1 pour ne pas bloquer le I2S

voyez vous une erreur ?

question complémentaire :

comment puis je avoir un flag sur la VI Vertical Interrupt avec le 68000 ?
j'ai vu CPU Interrupt Control Register. mais c'est pas très clair smile

ça me permettrait de vraiment faire du 50 hz en dur pour debugger
avatar

13

Faudrait que je prenne le temps de vérifier tes calculs, mais sur le principe, tu n'as pas vraiment besoin du timer, l'interruption I²S suffit : tu fais un buffer FIFO partagé, lu par l'interruption et écrit par le code principal. Le code principal attend qu'il y ait au moins (fréquence d'échantillonnage / 50) emplacements libres dans le buffer, génère ces échantillons, et recommence. C'est plus simple et ça libère un timer pour d'autres choses 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

14

le code principal va prendre pas mal de temps machine
sur un amiga à 8 mhz ça prend 80% du temps cpu d'émuler un YM2149
je sais pas ce que ça donne sur le DSP, surtout que dans cette version orientée debug, je dois stocker dans la ram centrale puisque je fais plein de buffers ( Noise basé sur des nombres aléatoires, parcours du noise et de 3 ondes carrées, + le parcours de l'enveloppe, et buffer final)
ça me permet ensuite de les analyser pour voir ce qui cloche.

quand je met un marqueur de couleur c'est genre 15-20% du temps à l'écran

donc je dois forcément faire 2 buffers

après je peux faire une 1ere partie avec un I2S et un timer 1, et le 68000 qui compte le nombre d'octets et je refais mes calculs de tables de frequence avec cette valeur

mais ça n'explique pas la différence

à 394 je suis à 19700 Hz

sur la console réelle, je ne vois pas la valeur , forcément, mais j’entends bien que ça déconne smile
avatar

15

Je suis d'accord que ta méthode devrait fonctionner aussi, mais pour le reste je maintiens, tu n'as pas besoin de faire deux buffers et d'utiliser un timer smile

Sinon, par rapport au 68000, le DSP est rapide... très rapide grin

S'il doit juste émuler un YM, ton code principal va passer la plupart de son temps à attendre d'avoir quelque chose à faire... en particulier si tu optimises ensuite (les signaux carrés peuvent être générés sans table [à part une toute petite pour l'amplitude], et pareil pour le bruit : c'est un LFSR. D'ailleurs le vrai YM n'utilise pas de tables, ça prendrait trop de place sur la puce).
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

16

j'utilise des tables/buffers pour debugger

parce que quand les valeurs sont calculées dans l'interruption I2S c'est quand même difficile d'avoir une visions des choses, style je vois que j'ai un noise etc
ma routine d'onde carrée est hyper simple : j'incremente , je shift de 31 bits, je fais un neg et j'ai une onde carrée à la bonne fréquence ( 0 ou $FFFF)

et émuler du YM c'est aussi émuler le MFP
pour faire du SID, du buzzer, du sinus sid


j'ai dédié un registre pour compter les interruptions I2S entre chaque interruption timer 1 , et j'obtiens les mêmes valeurs : $18C => si mon timer 1 est vraiment à 50 hz, ça donne 19800 Hz
si il y avait un problème avec le I2S je pense que tout le monde le saurait déjà

ça vient surement du timer 1
avatar

17

Zerosquare (./5) :
Ah ben ça c'est sûr, y'a pas d'OS : c'est déjà tout juste si y'a un SDK grin
On a quand même un BIOS... Ok... J'ai rien dit...

18

hello

bon je continue à creuser
suite à la remarque de Zerosquare sur la génération du noise/bruit sur le YM, j'ai regardé ce qu'est le LFSR
je suis tombé sur cette page particulièrement intéréssante : https://www.smspower.org/Development/YM2413ReverseEngineeringNotes2018-05-13

j'ai donc basculé ma génération de noise sur la formule expliquée

là je m'interroge sur la décompression
mon player joue des YM7
ce sont des fichiers faits de blocs LZ4
actuellement je décompresse l'ensemble du fichier, tous les blocs, à l'initialisation , et je remplis un gros bout de la ram.
je suis en train de basculer sur une décompression au 68000, au fil de l'eau, lorsque j'ai fini de jouer un bloc ( j'ai un bloc de buffer bien sur )
et je me demande si c'est intéressant de recoder la decompression au DSP, pour pouvoir mettre le 68000 en stop $2700 ? sachant que mes blocs sont dans la ram centrale. donc une decompression au DSP implique qu'elle se fera sur de la ram externe au DSP

( @ dilinger : je suis content d'avoir modifié VJ pour pouvoir visualier la ram DSP wink )
avatar

19

Content de savoir que VJ est utile.
Pour la décompression, i existe une routine de décompression via le GPU ou DSP. Je ne sais pas si tu es au courant.
Unpacking routJagware Voila LA routine de décompactage de la Jag :   LZW_JAG.ZIP   C'est une adaptation Gpu ou Dsp de la routine de décompactage de Ray (TSCC)   Tout est dedan...

Je ne m'en suis jamais servi mais elle semble efficace.

20

cool, merci
ça m'évitera d'ajouter des bugs smile

edit : au final, c'est pas intéressant car au lieu de diffuser le source, ce n'est qu'un .o ...
avatar

21

Le source est quelques posts plus bas, non ?
Et une version optimisée par CJ en page 2.
avatar
De nouveaux jeux pour vos vieilles consoles ? En 2024 ?
https://yastuna-games.com

22

je n'avais pas vu j'ai juste consulté le ZIP
en tout cas , merci à vous deux

si vous avez besoin un jour, le lien vers les versions de Leonard / oxygene en 68000 :
GitHub - arnaud-carre/lz4-68k: very fast LZ4 68k decoderGitHubvery fast LZ4 68k decoder. Contribute to arnaud-carre/lz4-68k development by creating an account on GitHub.


la version smallest est particulièrement petite smile
avatar

23

bonjour,

au final j'ai recodé la version de Leonard car LZ4 ce n'est pas LZW, ou pas exactement.
je l'ai "dépliée" pour éviter les bsr, c'était plus simple à recoder
c'était nécessaire, car certains fichiers YM7 font + de 2 Mo décompressés smile

prochaine étape : gérer les sinus SID

et ensuite je ferai un programme de test des timers I2S 1 et 2, avec affichage de compteurs remis à zéro par la VBL ( VI )
ça sera mon premier affichage sur Jaguar avec l'Object processor, ça promet !
ça me permettra d'afficher sur la jaguar réelle.
avatar

24

vous reprendrez bien un peu de Mad Max sur Jaguar cette fois ?

avatar

25

C'est à 32 kHz ? Ça sonne vachement bien smile
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

26

55 khz
mais ça ne change rien au final.
je bosse à 35 khz sans différence notable.
avatar

27

Joli ça, je savais pas que la jaguar pouvait faire autant smile
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

28

l'avantage de l'émulation YM c'est que ça lit peu de valeurs (entre 14 et 20 par replay) dans la ram centrale contrairement aux modules avec des samples
donc tu peux pousser la fréquence, tu ne satures pas le bus mémoire
les SIDs sont dans la ram DSP


ça doit aussi être possible de faire un player de module qui ne lit les samples que quand il avance dans le sample, ça permettrait de monter haut en fréquence de replay sans charger le bus mémoire.
avatar

29

Du coup t'as pas besoin d'interruption non plus et d'écrire sur le DAC avec le processeur ?
J'avais en tête qu'il fallait forcément le faire, ou alors je confonds avec la Lynx 🤔
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

30

Sur Jag, le DSP est interfacé directement au DAC, si c'est ca ta question.


ericde45 > king
C'était quoi du coup le pb de buffer ?
avatar