YM2151 Programming

From 8BitDev.org - Atari 7800 Development Wiki
Revision as of 14:39, 28 February 2020 by MSaarna (talk | contribs) (Mapping the XM YM2151 into address space)
Jump to: navigation, search

The YM2151 is a Yamaha FM-based soundchip. The focus of this article is programming this chip with regard to the Atari 7800 XM module, though there will get information that applies to other systems that support the YM2151.

If you wish to just use the existing XMYM tracker (instead of programming the YM2151 at a low level) you can skip this article, and get a hold of the DefleMask composing software, and the dmf2asm converter, so you can make your music and convert it to XMYM compatible format.


Mapping the XM YM2151 into address space

The XM Cntrl1 register ($470) is used to map devices in and out of address space. Writing the value #$84 to this location will make the YM2151 and cartridge ROM available. If you want other hardware present, like the pokey sound chip, you'll need to modify the value you write appropriately. (see the official XM developer docs)

Once the YM2151 is mapped in, it is ready and active at addresses $460 and $461.

Updating Registers on the YM2151

The YM2151 can be busy with updates you've previously sent to it, so previous to any communications you need to check if it's ready with something like...

 WaitForYMReady
   bit $461
   bmi WaitForYMReady

To update the YM registers, you write the YM register location to the $460 location, and then the value you wish to write to the YM register to $461. For convenience, the following subroutine will write the A register contents to the X register location, with all of the necessary waiting.

YM2151BASE = $460
WriteToYM_X
  ; utility function: writes A to the YM, at register location X
  ; on entry: X=YM Register, A=Value to write
WaitForYMXReady1
  bit YM2151BASE+1
  bmi WaitForYMXReady1
  stx YM2151BASE
WaitForYMXReady2
  bit YM2151BASE+1
  bmi WaitForYMXReady2
  sta YM2151BASE+1
  rts


The YM2151 Register Map

Here's the summary of the YM2151 register locations. It's important to note that these aren't locations in 6502 address space, but rather locations internal to the YM2151, and can only be reached through the YM2151 register update mechanism.


YM2151 Registers
Location Bits Used Registers Register Descriptions Alt Register Names Comment
01 %TTTTTTTT TEST Test - not used for XM
08 %-SSSSCCC SN,CN Slot Number, Channel Number - Send Note-on or Note-off
0F %E--FFFFF NE,NFRQ Noise Enable, Noise Frequency - Enable Noise
10 %CCCCCCCC CLKA1 Clock A1 - Clock Frequency Determination
11 %------CC CLKA2 Clock A2 - Clock Frequency Determination
12 %CCCCCCCC CLKB Clock B - Clock Frequency Determination
14 %C-FFIILL CSM,FReset,IRQEN,LOAD TBD - not used for XM
18 %LLLLLLLL LFRQ TBD - TBD
19 %MMMMMMMM AMD/PMD TBD - TBD
1B %CC----WW CT,W MHz, LFO Wave (Saw,Sqr,Tri,Noise) - Control (not used for XM?), change LFO Wave
20-27 %RLFFFCCC R-EN,L-EN,FL,CON Enable Left/Right, Feedback lvl, Connection algorithm R,L,FB,CONECT Per channel, operator connectivity
28-2F %-OOONNNN OCT,NOTE Octave, Note KC Per channel, octave and note to use when note-on is triggered
30-37 %KKKKKK-- KF Key Fraction - Per channel, for pitch bend
40-47 %-DDDMMMM DT1,MUL Detune1, Multiply - Per channel, OP1
48-4F %-DDDMMMM DT1,MUL Detune1, Multiply - Per channel, OP3
50-57 %-DDDMMMM DT1,MUL Detune1, Multiply - Per channel, OP2
58-5F %-DDDMMMM DT1,MUL Detune1, Multiply - Per channel, OP4
60-67 %-TTTTTTT TL Total Level (volume) - Per channel, OP1
68-6F %-TTTTTTT TL Total Level (volume) - Per channel, OP3
70-77 %-TTTTTTT TL Total Level (volume) - Per channel, OP2
78-7F %-TTTTTTT TL Total Level (volume) - Per channel, OP4
80-87 %KK-AAAAA KS,AR Keyscale, Atack - Per channel, OP1
88-8F %KK-AAAAA KS,AR Keyscale, Atack - Per channel, OP3
90-97 %KK-AAAAA KS,AR Keyscale, Atack - Per channel, OP2
98-9F %KK-AAAAA KS,AR Keyscale, Atack - Per channel, OP4
A0-A7 %A--DDDDD AME,D1R AMS-enable, Decay D1R - Per channel, OP1
A8-AF %A--DDDDD AME,D1R AMS-enable, Decay D1R - Per channel, OP3
B0-B7 %A--DDDDD AME,D1R AMS-enable, Decay D1R - Per channel, OP2
B8-BF %A--DDDDD AME,D1R AMS-enable, Decay D1R - Per channel, OP4
C0-C7 %TT-DDDDD dT2,D2R Detune dT2, Decay D2R - Per channel, OP1
C8-CF %TT-DDDDD dT2,D2R Detune dT2, Decay D2R - Per channel, OP3
D0-D7 %TT-DDDDD dT2,D2R Detune dT2, Decay D2R - Per channel, OP2
D8-DF %TT-DDDDD dT2,D2R Detune dT2, Decay D2R - Per channel, OP4
E0-E7 %DDDDRRRR D1L,RR Decay D1L, Release Rate - Per channel, OP1
E8-EF %DDDDRRRR D1L,RR Decay D1L, Release Rate - Per channel, OP3
F0-F7 %DDDDRRRR D1L,RR Decay D1L, Release Rate - Per channel, OP2
F8-FF %DDDDRRRR D1L,RR Decay D1L, Release Rate - Per channel, OP4


Miscellaneous Application Notes

  • Avoid issuing a note-off too soon after a note-on, as this will cause a lot of distortion in the sound. One way around this is to reverse the usual order, and issue a note-off on your channel prior to the note-on.