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, 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

3.1 General Instruments AY-3-8910
3.2 Yamaha YM-2149

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.

1. Registres de la carte YM-2149F

1.1 Tableau des registres

Reg.b7b6b5b4b3b2b1b0
R00Tonalité voie 1Octet de poids faible
R01de poids fort
R02Tonalité voie 2Octet de poids faible
R03de poids fort
R04Tonalité voie 3Octet de poids faible
R05de poids fort
R06Plage de bruit5 bits
R07Input / Output, mixerInput / OutputBruitTonalité
R15R14Voie 3Voie 2Voie 1Voie 3Voie 2Voie 1
R08Niveau de la voie 15 bits
R09Niveau de la voie 25 bits
R10Niveau de la voie 35 bits
R11Période enveloppeOctet de poids faible
R12Octet de poids fort
R13Forme d'enveloppeContAttAltHold
R14Données I / OOctet
R15Données I / OOctet

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 :

  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 :

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)

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 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.