There's a lot of scattered information across this board on the YM2612, alot of it is important. So I'm going to periodically collect information I come across, numbers/corrections to the manual/stuff like that. Mainly to help keep myself more organized and in better understanding of the chip, but also to help others as well that are interested in learning how to program for it, without having to dig the depths of these forums.
Note: I'll add more as I find more. Also if someone has corrections to make to this information or additions, I'll gladly update this post.
Corrections to the Sega Sound Manual:
For the operator algorithms...
TmEE co. wrote:
In reply to this Shiru stated that:There's a major incorrection in Sega YM2612 manual. The algorithm 4 is not (1 * 2) + (3 * 4) but its (1 * 3) + (2 * 4) like in TFMmaker.
So I'm assuming that all the algorithms for the operators in the Sega sound manual are technically incorrectly shown. Hopefully someone will chime in on this for clarity. I want facts on this thread.Thats right for all other algorithms too (operators 2 and 3 in that manual must be exchanged).
Now for the timing calculations.
TmEE wrote:
Source code by Charles MacDonald for calculating timer frequency:Timer B (and possibly A) timing calculations in manual seems to be incorrect, what I calcualted 50Hz is actually around 40...
Code: Select all
void sound_init(void)
{
/* Timers run at half the YM2612 input clock */
float clock = ((MCLK / 7) / 2);
int i;
/* Make Timer A table */
for(i = 0; i < 1024; i += 1)
{
/* Formula is "time(us) = 72 * (1024 - A) / clock" */
fm_timera_tab[i] = ((int)(float)(72 * (1024 - i)) / (clock));
}
/* Make Timer B table */
for(i = 0; i < 256; i += 1)
{
/* Formula is "time(us) = 1152 * (256 - B) / clock" */
fm_timerb_tab[i] = (int)(float)(1152 * (256 - i)) / clock;
}
}
Here's some tidbits on YM2612 writes I thought should be added to this post. Some of it is already in the manual, but is useful to know anyways.
TmEE co.:
The YM2612 seems like it has some quirks not present in the VDP and PSG. This stuff is nice to know for someone like myself who knows how to work with those chips but not the YM2612. Thanks TmEE.ALWAYS write the high part first if some regs are "ganged together" (what a funny expression). If you don't, you'll get very funny notes.
DAC can play samples at 60KHz continuously, anything above is unstable.
2 NOPs after each write to YM2612 is ALWAYS enough (if you don't plan to overclock the Z80), that comes in handy when you have all regs used, and need very fast code. LATER CORRECTION: 2 NOPs isn't always enough... but 3 is
Shiru:
That was some good information for understanding how to do pitch sweeps, vibrato, and other neat effects.Anything can be changed anytime, but only changes of Frequency, TL, Multiple, Detune will be applied immediately
FREQUENCY TABLES:
Neologix posted a link of PSG and YM2612 frequency tables that he did, note that these tables use the NTSC clocks in their calculations, we'll need PAL tables too. http://www.luxatom.com/md-fnum.html
If you want to to calculate the frequencies yourself here is some code that TmEE shared:
Code: Select all
OPNclk = MCLK / 7 / 144 ' Useful for calculations elsewhere ------------
FOR Okt% = 0 TO 7 ' Generate musical note to OPN freq table ------
FOR NoteS% = 60 TO 71
MiniStep! = 0
FOR MiniS% = 0 TO 15
MFREQ! = 8.1757989156# * (2 ^ ((NoteS% + MiniStep!) / 12))
OPNnoteStep(Okt%,NoteS%-60,MiniS%)=((MFREQ!*131072)/OPNclk)OR(Okt% SHL 11)
MiniStep! += (1 / 16)
NEXT MiniS%
NEXT NoteS%
NEXT Okt%
% is signed int, ! is single precision float.
Might as well add in PSG calculations too:
Code: Select all
PSGclk = MCLK / 15 / 32 ' Useful in calculations elsewhere ----------------
Noot% = 9 ' Generate freqs ----------------------------------
Okt% = 1
FOR MIDInote! = 45 TO 119
MiniStep! = 0
FOR MiniSteps% = 0 TO 15
MIDIfreq! = 8.1757989156 * (2 ^ ((MIDInote! + MiniStep!) / 12))
PSGnoteStep(Okt%,Noot%,MiniSteps%) = PSGclk / MIDIfreq!
MiniStep! += (1 / 16)
' PRINT PSGnoteStep(Okt%,Noot%,MiniSteps%);
NEXT MiniSteps%
Noot% += 1
IF Noot% = 12 THEN Noot% = 0 : Okt% += 1
NEXT MIDInote!
DOCUMENTATION:
Sega Sound Manual
http://www.smspower.org/maxim/Documents/YM2612 (HTML)
More information to come, I'll probably need to do layout changes so it's easier to read this post, espcially if it get's larger.