Le son ATARI YM2149
BEAUCOUP de consoles d’arcades des années 80 et d’ordinateurs 8bits étaient dotés du Programmable Sound Generator (PSG) AY-3-8910, puce sonore de General Instrument. L’ordinateur 16bits Atari ST (1985) a gardé ce composant, sous forme du clone sous licence fabriqué par Yamaha, le YM-2149F. Le son produit servait pour les jeux et la musique des démos.
2022.02.20
Pour la description des formats de fichier YM d’Arnaud, qui permet voir cette page.
0. Remerciements
1. Registres du YM-2149F
1.1 Les registres
1.2 Tonalité des voies
1.3 Plages de bruits
1.4 Mixage ton / bruit
1.5 Volume des voies
1.6 Période de l’enveloppe
1.7 Forme de l’enveloppe
1.8 Registres non utiles
2. Mise en œuvre
2.1 Avertissement
2.2 L’adressage
2.3 Allumer une voie
2.4 Ajouter du bruit
2.5 Ajouter une enveloppe
2.6 Récapitulatif
3. Machines
Tout le processeur d’origine, le Software-Controlled Sound Generator (SSG) YM-2149F comprend trois voies pouvant chacune produire une seule note et/ou un bruit. La note la plus basse est le B0 , ou Si-1 (30,5Hz), la plus haute bien au delà des 20 000 encore audibles par l’oreille humaine. Les bruits blancs peuvent être filtrés selon 32 plages de fréquence. 16 niveaux de volume sont disponibles par voie, qui peut également être soumis à huit types d’enveloppe, ce qui permet de produire, au lieu de l’onde carré, des ondes en dents de scie ou encore triangulaires (montagnes).
Le BASIC Omikron 3.01 est capable d’utiliser ce soundchip de façon confortable avec les instructions TUNE, VOLUME et NOISE, mais cette page s’intéresse davantage à la façon dont la puce fonctionne, en adressant des données directement en mémoire.
0. Remerciements
La doc technique sur le YM-2149 et son aîné le AY-3-8910 a été plus facile à trouver qu’à déchiffrer ; des infos plus terre-à-terre pour la mise en œuvre, c’est autre chose. Grand merci à fxjavadevblog pour son article instructif et surtout pratique : c’est là qu’il faut aller pour une mise en œuvre en C ou en assembleur.
Comme je n’ai pas le temps de ressortir mon assembleur 68000 HiSoft ou de chercher un compilateur C pour Atari, je me suis tourné vers mon bon vieux BASIC Omikron 3.01 (merci à ses auteurs) et ses bons vieux POKE pour tester l’adressage des données vers $FF8800 et $FF8802.
1. Registres de la carte YM-2149F
1.1 Tableau des registres
Reg. | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | |
---|---|---|---|---|---|---|---|---|---|
R00 | Tonalité voie 1 | Octet de poids faible | |||||||
R01 | de poids fort | ||||||||
R02 | Tonalité voie 2 | Octet de poids faible | |||||||
R03 | de poids fort | ||||||||
R04 | Tonalité voie 3 | Octet de poids faible | |||||||
R05 | de poids fort | ||||||||
R06 | Plage de bruit | 5 bits | |||||||
R07 | Input / Output, mixer | Input / Output | Bruit | Tonalité | |||||
R15 | R14 | Voie 3 | Voie 2 | Voie 1 | Voie 3 | Voie 2 | Voie 1 | ||
R08 | Niveau de la voie 1 | 5 bits | |||||||
R09 | Niveau de la voie 2 | 5 bits | |||||||
R10 | Niveau de la voie 3 | 5 bits | |||||||
R11 | Période enveloppe | Octet de poids faible | |||||||
R12 | Octet de poids fort | ||||||||
R13 | Forme d’enveloppe | Cont | Att | Alt | Hold | ||||
R14 | Données I / O | Octet | |||||||
R15 | Données I / O | Octet |
1.2 Registres de R0 à R5 (→ tableau)
Les six premiers registres concernent les périodes des voies 1, 2 et 3. Pour la voie 1, R0 est le registre pour l’octet de poids faible (valeurs de 0 à 255), R1 de poids fort (limité à quatre bits, valeurs de 0 à 15). Le Timer de l’Atari ST est de 2 000 000Hz, que l’on divise par 16, ce qui donne 125 000Hz ; pour calculer la période à inscrire sur ces registres, il faut calculer le nombre d’oscillations pour la fréquence désirée. Pour 440 (le LA3, «A4»), il s’agit de 125 000 / 440, c’est-à-dire 282.
Calcul des valeurs à passer sur les registres : 282 / 256 donne 1 comme valeur de poids fort à inscrire sur R1, et le reste, 26, l’octet de poids faible, sur R0. Ces douze bits permettent de définir 4096 valeurs (212), de 0 à 4095.
Les périodes 1 à 5 sont inaudibles (ultrasons), 6 vaut à peu près 20 833Hz, limite de l’audition humaine. Le maximum, 4095, vaut environ 30,53Hz, presque le Do–1, «C1». Inscrire 0 sur les registres RO et R1 est l’unique manière d’éteindre la voie 1.
Les registres R2 et R3 définissent la voie 2 de la même manière, les R4 et R5 la voie 3.
1.3 Registre R6 (→ tableau)
Le registre R6 reçoit les valeurs de 0 à 31, ce qui filtre le bruit blanc pour obtenir un son aigu (0) à grave (31).
1.4 Registre R7 (→ tableau)
Les trois bits de poids faible concernent la production de musique pour chacune des voies, les trois du milieu concernent la production de bruit. Attention : ces six bits à zéro produisent le son ; à 1, ils masquent le son. Pour la voie 1 (les autres bits sont indéterminés pour cet exemple) :
--321321
----0--0 bruit plus onde
----0--1 seulement le bruit
----1--0 seulement l’onde
----1--1 ni bruit, ni onde
Les bits 6 et 7 concernent les registres R14 et R15. De fait, la manipulation du registre 7 doit peut-être se faire de façon plus ciblée, les bits 6 et 7 concernant le transit des données par le modem et l’imprimante via les registres 14 et 15, ce do,t il ne sera pas question ici.
1.5 Registres de R8 à R10 (→ tableau)
Le registres 8 à 10 concernent repectivement les volumes des voies A à C, écrit sur 5 bits. Si le bit 4 est 0, le niveau (fixe) est déterminé par les quatres bits de poids faible, de 0 à 15. Si le bit 4 est 1, le canal est concerné par l’enveloppe définie par les trois registres suivants.
1.6 Registres R11 et R12 : période de l’enveloppe (→ tableau)
Les registres 11 et 12 sont respectivement les octets de poids faible et de poids fort de la période (durée) de l’enveloppe, qui forment le nombre R12 * 256 + R11, de 0 à 65535. Une seconde correspond à 7812.5 , à savoir 2 000 000 / 256. La valeur maximale sur deux octets, 65535, vaut 8,39 secondes.
1.7 Registre R13 (→ tableau)
Les quatre bits de poids faible | - | - | - | - | b3 | b2 | b1 | b0 | du registre 13 donnent la forme de l’enveloppe.
Le bit3 (CONT pour continu) est à 0 si l’enveloppe n’est jouée qu’une fois. Dans ce cas, seules deux enveloppes sont possibles selon la position du bit2 (ATT pour attack), les bits 1 et 0 n’ont ici aucune importance :
- bit2 à 1 pour une montée progressive suivie d’un effondrement
- bit2 à 0 pour une descente progressive du volume maximal au minimal
0 (à 3) : 00-- forme |\ (son piano)
4 (à 7) : 01-- forme /| (montée douce)
Le bit 3 CONT est positionné à 1 pour permettre la continuité. Le bit2 ATT donne toujours le mode d’attaque, le bit 1 (ALT) positionné à 1 détermine l’alternance (montées et descentes progressives) ; à 0 pour une répétition du schéma de base du bit2 ATT. Le bit 0 (HOLD) positionné à 1 limite le cycle à une occurrence. :
8 : 1000 forme |\|\|\|\|\|\ 0 (à 3) répété
9 : 1001 forme |\__________ comme 0 (à 3)
10 : 1010 forme |\/\/\/\/\/\ attaque franche et ondes triangulaires
11 : 1011 forme |\|¯¯¯¯¯¯¯¯¯ la moins naturelle des enveloppes
12 : 1100 forme /|/|/|/|/|/| 4 (à 7) répété
13 : 1101 forme /¯¯¯¯¯¯¯¯¯¯¯ montée et tenu
14 : 1110 forme /\/\/\/\/\/\ montée et ondes triangulaires
15 : 1111 forme /|__________ comme 4 (à 7)
Note : toute écriture dans ce registre réinitialise l’enveloppe, qui s’applique donc parallèlement aux voies dont le volume dépasse 15.
1.8 Registres R14 et R15 (→ tableau)
Sous réserves ! Ce sont les registres où transitent les données vers le port parallèle (le plus souvent l’imprimante, seulement en sortie sur l’AtariST) et le port série (le plus souvent le modem, bidirectionnel), ce qui n’est pas le sujet sur cette page.
2. Mise en œuvre logicielle
2.1 Avertissement
Le langage utilisé, l’Omikron BASIC, fonctionne en mode superviseur, ou privilégié, qui permet l’adressage de données dans des zones interdites au commun des mortels. Songez-y si vous utilisez un langage normal, qui tourne en mode utilisateur, comme l’assembleur, le C ou le GFA BASIC :
! en GFA super%=GEMDOS(32,L:0) ! passage en mode superviseur et récupération de l’adresse courante de la pile les adressages ~GEMDOS(32,L:super%) ! restitution de l’adresse pour la sortie (obligatoire!) du mode privilégié
Ceux qui roulent en C ou en assembleur devraient pouvoir traduire l’exemple GFA ci-dessus dans leur dialecte. L’appel à la fonction GEMDOS 32 avec passage du nombre 1 en paramètre renvoie -1 en mode privilégié et 0 en mode utilisateur.
2.2 L’adressage
Sur l’Atari ST, deux adresses servent à passer les valeurs aux 14 registres utiles du soundchip YM-2149F :
- FF8800 (octet) adresse pour la désignation du registre, de 0 à 13
- FF8802 (octet) adresse de la valeur à passer au registre
Le BASIC Omikron permet l’adressage d’octets en mémoire avec l’instruction POKE adresse, octet. Ce n’est pas intuitif, mais faut d’abord désigner le registre à l’adresse $FF8800 avant d’inscrire l’octet de donnée à l’adresse $FF8802.
La première routine affecte la valeur d’un octet sur un registre unique, la seconde pour le passage d’un mot (deux octets) sur deux registre contigus, comme les six premiers pour la tonalité des trois voies, ou la période de l’enveloppe sur les registres 11 et 12 :
DEF PROC Spl(Reg,Octet) POKE $FF8800,Reg POKE $FF8802,Octet RETURN DEF PROC Dbl(Reg,Mot) Faible = Mot MOD 256 : Fort = Mot \ 256 POKE $FF8800,Reg : POKE $FF8802,Faible POKE $FF8800,Reg+1 : POKE $FF8802,Fort RETURN
2.3 Allumer une voie
Ceci étant fait, il est simple d’entrer le mot 443 (125000/443 = 282Hz) sur les registres R0 et R1 de la voie 1. Cela ne suffit pas: il faut également débloquer la voie 1 en éteignant le bit 0 du registre 7 et fixer le volume (de 0 à 15) de la voie 1 sur le registre 8. On laisse 1 seconde et puis on éteint la voie 1 en mettant les deux premiers registres à 0 :
Dbl(0,443) Spl(7,254) Spl(8,13) WAIT 1 Dbl(0,0)
2.4 Ajouter du bruit
Le bruit se paramètre avec un nombre de 0 (plus aigu) à 31 (plus grave) sur le canal 6. Il faut ensuite le mixer à la voie choisie, en mettant le bit3 à zéro (255 - 8) pour la voie 1.
Spl(6,5) Spl(7,247) WAIT 1 Spl(7,255)
On peut combiner tonalité et bruit sur la voie 1, le registre 7 recevant alors la valeur 246 (255 - 8 - 1) :
Dbl(0,443)' voie 1: registres 0 et 1 Spl(8,13)' voie 1: volume à 13 Spl(6,5)' bruit plutôt aigu Spl(7,246)' voie 1: tonalité + bruit (255 - 1 - 8) WAIT 1' une seconde passe Dbl(0,0)' éteinte la tonalité de la voie 1 Spl(7,255)' voie 1, 2, 3: masquage du bruit (et de la tonalité)
2.5 Ajouter une enveloppe
Jusqu’à présent, les sons étaient en continu. Voyons maintenant comment utiliser une enveloppe :
Dbl(0,443)' voie 1: inscrition aux registres 0 et 1 Spl(7,254)' voie 1: ouverture de la tonalité Spl(8,16)' volume > 15: enveloppe Dbl(11,3900)' durée de l'enveloppe d'environ 1/2 seconde Spl(13,0)' enveloppe de type piano WAIT 1 Dbl(0,221)' voie 1: note à l'octave (période divisée par 2), Spl(13,0)' réinitialisation de l'enveloppe Dbl(0,0)' voie 1: extinction des registres Spl(7,255)' fermeture de toutes les voies
2.6 Récapitulatif
Fichier BASIC Omikron 3.01 reprenant toute la section «mise en œuvre logicielle». On peut charger ce programme avec LOAD_BLOCK du super-éditeur, appelable avec EDIT.
3. Machines
3.1 General Instruments AY-3-8910
Non exhaustif…
AY-3-8910 : Oric 1 (1983), MSX (1983)
AY-3-8912 : Amstrad CPC (1984), ZX Spectrum (1985), (1990) GX4000
AY-3-8913 : Mockingboard v1 ((2x, 2005), Mockingboard v1a (2x, 2010)
AY-3-8914 : Intellivision (1979), Intellivision II (1982)
1.3 Yamaha YM-2149
YM-2149 : MSX2 (1985) et MSX2+ (1988)
YM-2149F : ATARI-ST (1985) et MSX TurboR (1990)