YM2151 Programming
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 Ctrl register is used to map devices in and out of address space. Writing the value #$84 will 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 appropriately. (see the official XM developer docs)
The YM2151 is now 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.
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.
Location | Bits Used | Register | Register Description | Alt Reg Name | 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/instrument setup |
28-2F | %-OOONNNN | OCT,NOTE | Octave, Note | KC | Per channel, octave and note to play next |
30-37 | %KKKKKK-- | KF | Key Fraction | - | Per channel, fraction change |
40-47 | %-DDDMMMM | DT1,MUL | Detune1, Multiply | - | Per channel |