Difference between revisions of "YM2151 Programming"
(21 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
== Mapping the XM YM2151 into address space == | == Mapping the XM YM2151 into address space == | ||
− | The XM | + | 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 [http://www.7800xm.com/XMdevelopers.htm XM developer docs]) |
+ | |||
+ | Once the YM2151 is mapped in, it is ready and active at addresses $460 and $461. | ||
− | |||
== Updating Registers on the YM2151 == | == Updating Registers on the YM2151 == | ||
Line 18: | Line 19: | ||
bmi WaitForYMReady | 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. | + | 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 | YM2151BASE = $460 | ||
Line 33: | Line 34: | ||
sta YM2151BASE+1 | sta YM2151BASE+1 | ||
rts | rts | ||
+ | |||
== The YM2151 Register Map == | == 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 locations internal to the YM2151, and can only be reached through YM2151 register update mechanism. | + | 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 | |+YM2151 Registers | ||
− | ! Location | + | ! Location |
− | ! Bits Used | + | ! Bits Used |
− | ! | + | ! Registers |
− | ! Register | + | ! Register Descriptions |
− | ! Alt Register Names | + | ! Alt Register Names |
− | ! | + | ! Comment |
|- | |- | ||
− | | 01 || <tt>%TTTTTTTT</tt> || TEST || Test || - || not | + | | 01 || <tt>%TTTTTTTT</tt> || TEST || Test || - || not used for XM |
+ | |- | ||
+ | | 08 || <tt>%-SSSSCCC</tt> || SN,CN || Slot Number, Channel Number || - || Send Note-on or Note-off | ||
+ | |- | ||
+ | | 0F || <tt>%E--FFFFF</tt> || NE,NFRQ|| Noise Enable, Noise Frequency || - || Enable Noise | ||
+ | |- | ||
+ | | 10 || <tt>%CCCCCCCC</tt> || CLKA1 || Clock A1 || - || Clock Frequency Determination | ||
+ | |- | ||
+ | | 11 || <tt>%------CC</tt> || CLKA2 || Clock A2 || - || Clock Frequency Determination | ||
+ | |- | ||
+ | | 12 || <tt>%CCCCCCCC</tt> || CLKB || Clock B || - || Clock Frequency Determination | ||
+ | |- | ||
+ | | 14 || <tt>%C-FFIILL</tt> || CSM,FReset,IRQEN,LOAD || TBD || - || not used for XM | ||
+ | |- | ||
+ | | 18 || <tt>%LLLLLLLL</tt> ||LFRQ || TBD || - || TBD | ||
+ | |- | ||
+ | | 19 || <tt>%MMMMMMMM</tt> ||AMD/PMD || TBD || - || TBD | ||
+ | |- | ||
+ | | 1B || <tt>%CC----WW</tt> ||CT,W || MHz, LFO Wave (Saw,Sqr,Tri,Noise) || - || Control (not used for XM?), change LFO Wave | ||
+ | |- | ||
+ | | 20-27 || <tt>%RLFFFCCC</tt> || R-EN,L-EN,FL,CON || Enable Left/Right, Feedback lvl, Connection algorithm || R,L,FB,CONECT || Per channel, operator connectivity | ||
+ | |- | ||
+ | | 28-2F || <tt>%-OOONNNN</tt> || OCT,NOTE || Octave, Note || KC || Per channel, octave and note to use when note-on is triggered | ||
+ | |- | ||
+ | | 30-37 || <tt>%KKKKKK--</tt> || KF || Key Fraction || - || Per channel, for pitch bend | ||
+ | |- | ||
+ | | 40-47 || <tt>%-DDDMMMM</tt> || DT1,MUL || Detune1, Multiply || - || Per channel, OP1 | ||
+ | |- | ||
+ | | 48-4F || <tt>%-DDDMMMM</tt> || DT1,MUL || Detune1, Multiply || - || Per channel, OP3 | ||
+ | |- | ||
+ | | 50-57 || <tt>%-DDDMMMM</tt> || DT1,MUL || Detune1, Multiply || - || Per channel, OP2 | ||
+ | |- | ||
+ | | 58-5F || <tt>%-DDDMMMM</tt> || DT1,MUL || Detune1, Multiply || - || Per channel, OP4 | ||
+ | |- | ||
+ | | 60-67 || <tt>%-TTTTTTT</tt> || TL || Total Level (volume) || - || Per channel, OP1 | ||
+ | |- | ||
+ | | 68-6F || <tt>%-TTTTTTT</tt> || TL || Total Level (volume) || - || Per channel, OP3 | ||
+ | |- | ||
+ | | 70-77 || <tt>%-TTTTTTT</tt> || TL || Total Level (volume) || - || Per channel, OP2 | ||
+ | |- | ||
+ | | 78-7F || <tt>%-TTTTTTT</tt> || TL || Total Level (volume) || - || Per channel, OP4 | ||
+ | |- | ||
+ | | 80-87 || <tt>%KK-AAAAA</tt> || KS,AR || Keyscale, Atack || - || Per channel, OP1 | ||
+ | |- | ||
+ | | 88-8F || <tt>%KK-AAAAA</tt> || KS,AR || Keyscale, Atack || - || Per channel, OP3 | ||
+ | |- | ||
+ | | 90-97 || <tt>%KK-AAAAA</tt> || KS,AR || Keyscale, Atack || - || Per channel, OP2 | ||
|- | |- | ||
− | | | + | | 98-9F || <tt>%KK-AAAAA</tt> || KS,AR || Keyscale, Atack || - || Per channel, OP4 |
|- | |- | ||
+ | | A0-A7 || <tt>%A--DDDDD</tt> || AME,D1R || AMS-enable, Decay D1R || - || Per channel, OP1 | ||
+ | |- | ||
+ | | A8-AF || <tt>%A--DDDDD</tt> || AME,D1R || AMS-enable, Decay D1R || - || Per channel, OP3 | ||
+ | |- | ||
+ | | B0-B7 || <tt>%A--DDDDD</tt> || AME,D1R || AMS-enable, Decay D1R || - || Per channel, OP2 | ||
+ | |- | ||
+ | | B8-BF || <tt>%A--DDDDD</tt> || AME,D1R || AMS-enable, Decay D1R || - || Per channel, OP4 | ||
+ | |- | ||
+ | | C0-C7 || <tt>%TT-DDDDD</tt> || dT2,D2R || Detune dT2, Decay D2R || - || Per channel, OP1 | ||
+ | |- | ||
+ | | C8-CF || <tt>%TT-DDDDD</tt> || dT2,D2R || Detune dT2, Decay D2R || - || Per channel, OP3 | ||
+ | |- | ||
+ | | D0-D7 || <tt>%TT-DDDDD</tt> || dT2,D2R || Detune dT2, Decay D2R || - || Per channel, OP2 | ||
+ | |- | ||
+ | | D8-DF || <tt>%TT-DDDDD</tt> || dT2,D2R || Detune dT2, Decay D2R || - || Per channel, OP4 | ||
+ | |- | ||
+ | | E0-E7 || <tt>%DDDDRRRR</tt> || D1L,RR || Decay D1L, Release Rate || - || Per channel, OP1 | ||
+ | |- | ||
+ | | E8-EF || <tt>%DDDDRRRR</tt> || D1L,RR || Decay D1L, Release Rate || - || Per channel, OP3 | ||
+ | |- | ||
+ | | F0-F7 || <tt>%DDDDRRRR</tt> || D1L,RR || Decay D1L, Release Rate || - || Per channel, OP2 | ||
+ | |- | ||
+ | | F8-FF || <tt>%DDDDRRRR</tt> || 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. |
Latest revision as of 14:39, 28 February 2020
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.
Contents
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.
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.