I will now present my notes on the previously undocumented register $2C on the YM2612.
A little backstory:
Back in 2008 I was working on a Sonic 1 hack called "Sonic 1 Oergomized". I was porting music from Columns III to the Sonic 1 sound driver. Because I wasn't able to do it manually because I was too incompetent I used a program called "Music Pointer Fixer" that would do the work for me to fix all these little flags in the file. It seemed to work, so I didn't bother more about it. Around that time I got the idea to try hacks on real hardware, so naturally I flashed mine to the cartridge and tried it. It worked fine, mostly, but one thing was broken. The music from Columns III I had ported only worked correctly in part. At first it played correctly, but then I noticed the PCM samples became really loud and the rest of the song was not hearable anymore. I recorded that and posted it on youtube for reference so I could get someone with real knowledge to fix it for me. Puto, a member of Sonic Retro and quite knowledgeable about the SMPS music format used in the Sonic games at the time, went ahead and scanned the file for broken flags. It turned out that there was one flag that didn't belong where it was and he took it out and that fixed it. I didn't think much of it at first, but then I noticed, every source said that you cannot control volume of the PCM channel. As the PCM sound was really loud with the buggy version of the music, something could not be right. I told people like Tweaker and other regulars about it, but they all went like "Nah, u crazy" and so it was forgotten. This is the youtube video in question:
Recently I talked to MarkeyJester in the SSRG IRC channel. I don't know what we were talking about (probably MD development stuff), but we got into talking about such subjects like undocumented features, and I mentioned it on the side that I once found something really weird, meaning the stuff that had happened almost 4 years ago. MarkeyJester, for some reason, showed some real interest in this and decided that, if I could find the ROM back, he would investigate it.
I looked everywhere, and in the darkest corners of my hard drive, I found the beta version of my hack that still had this bug. I gave it to MarkeyJester and he ran it on hardware to verify it happened.
<MarkeyJester> shit <MarkeyJester> it happens on the MD 2 <MarkeyJester> happens on MD 1 <MarkeyJester> that's pretty fucking loud too <MarkeyJester> Also on NoMad <MarkeyJester> sorry to do this Oerg, but it's time to break your rom open <Oerg866> You may proceed <MarkeyJester> it can't be <MarkeyJester> how does that even work <MarkeyJester> it's not 24 <MarkeyJester> it must be two of them <TmEE> I knew about the lound PCM thing for quite a few years and at one point I tried to enable it through software but never succeeded... I only could get it by glithching YM on real HW haha <TmEE> loud* <TmEE> it would make PCM at FM TL 0 instead of 16 <MarkeyJester> so that's YM2612 address 2C <MarkeyJester> now to find out what's being written to it <MarkeyJester> I just checked one of the manuals <Jorge> well, I have a test reg here on this pdf <TmEE> which allows you to do fun things <MarkeyJester> doesn't exist <TmEE> woo, another test reg <Jorge> at 21 and 2C <TmEE> I am excited hahaha <Oerg866> ASS reg <Jorge> it just says LSI Test data <Jorge> its interesting it comes after the DAC regs, maybe it has something todo with the DAC, heh
As I did not know at the time how to really interface with the YM2612, I could not test stuff myself. MarkeyJester found out that if you set Bit 5 in YM register $2C to 1, this odd behaviour occured. What it was for, we didn't know.
TmEE did some research on his part to kind-of figure out why FM was muted and what everything does. He came up with these assumptions:
- FM waveforms affect PCM panning
- The more complex and loud the waveforms playing on either side, the more the panning would be dragged in either direction
- This way you can achieve very smooth PCM panning.
With the recent development of my setup that allows realtime code testing on real hardware, I decided to learn how to talk to the YM chip and I wrote some code:
- A routine that loads an FM instrument
- A routine that sets YM registers
- A routine that keys on an FM instrument
- A routine that plays a loop of PCM data over and over
What I came up with is a program that does this: sets the undocumented test bit $2C as follows:
move.b #$2C, ($A04000) move.b #$20, ($A04001) ; Set bit 5 (this is the relevant bit)
And then plays some stuff on the FM channels while constantly playing a loop of PCM data.
My immediate findings were the following:
- PCM gets set to FM TL 0 instead of the set value of FM TL 16 (this cannot be changed in any way as far as we know, the only bit that does it is this one)
- FM gets muted.
To verify that FM stuff affects panning in any shape or form, I used the FM code I wrote to gradually play some stuff in a certain pattern.
My first test of that were a test instrument that used algorithm 7 (all operators produce a simple sine wave, all of which get added together in the end), a decline of 0 (no decline) and a TL of 00 on all operators. I loaded this instrument to all channels when the program started. Or so I thought.
Every time the loop starts, I flip between left or right side on all FM channels, key on all operators on all channels and then gradually turn off the FM channels one after another as the sample is playing. The result was this:
At last! I verified that FM panning gets dragged in either direction using the FM channels. Now what interested me was making my FM code more easy to work with. I tested the code out in an emulator and it turns out that due to a bug in my code, 4 of the 5 channels did not even have the instrument loaded. Upon further investigation I came to the following conclusion:
The waveform does not matter. You can load whatever instrument and it will behave the same.
Quite interesting so far, but what about frequency? To test that, I slided the frequency around a bit on every channel while playing the sample. This did not affect the output either.
The only thing left that I could imagine that could possibly do anything is this:
The YM has 4 key on bits for every channel. Every key on bit turns on an operator. What if we gradually enable them?
Bupkis. It still sounds the same.
Now I just said "screw it" and did not even key on any operators.... It still affected the panning like usual! So we can conclude that the only thing that affects panning is how many FM channels have that particular side turned on/off.
To verify that definitely, I removed everything to do with FM except setting the parameter that turns on/off the sides (For FM channel 0 that would be $B4 in $A04000 set to 0x80 for the left side and 0x40 for the right side. That still worked as before.
Another interesting thing is that it gets affected by every FM channel *except* FM5, meaning FM1,2,3,4 and FM6.
That means ultimately we can describe the register $2C of the YM2612 as follows:
When Bit 5 of YM Register $2C is set to 1, Panning gets affected by the L/R part of the L/R/AMS/FMS reg of these channels:
$B4 in Bank 1 of the YM2612 for Channel FM1
$B5 in Bank 1 of the YM2612 for Channel FM2
$B6 in Bank 1 of the YM2612 for Channel FM3
$B4 in Bank 2 of the YM2612 for Channel FM4
$B6 in Bank 2 of the YM2612 for Channel FM6
With the following conclusions related to other claims mentioned above:
- FM Waveform does not matter. The FM channel can be empty for all it cares.
- FM Total level does not matter (!)
- FM Key on does not matter (all key on bits can be set to 0 and it will still work)
- The only thing that actually affects PCM panning is how many FM channels have either the L or R bit set to 1
I have a picture that illustrates the affection of panning on the left channel according to how many channels are set:
Corresponding recording can be found here
It can also be seen that when all the channels are turned off but the register $2C set, PCM is still roughly four times as loud as without:
This concludes my research and documentation of this previously undocumented register. I hope it was an entertaining read and helpful to some emulator developers out there. It would probably require some more testing to get a really good approximation formula for it, but at least we have something now.
And now, for something fun ;D
26KHz test with super-smooth panning :P
Want to try it on your Mega Drive / Genesis?