Page 1 of 2

The YM2612 Information Thread

Posted: Mon Oct 06, 2014 3:10 pm
by Count SymphoniC
THE YM2612 INFORMATION THREAD

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:
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.
In reply to this Shiru stated that:
Thats right for all other algorithms too (operators 2 and 3 in that manual must be exchanged).
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.

Now for the timing calculations.

TmEE wrote:
Timer B (and possibly A) timing calculations in manual seems to be incorrect, what I calcualted 50Hz is actually around 40...
Source code by Charles MacDonald for calculating timer frequency:

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; 
} 
}
Writing to the YM2612's registers:

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.:
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
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.

Shiru:
Anything can be changed anytime, but only changes of Frequency, TL, Multiple, Detune will be applied immediately
That was some good information for understanding how to do pitch sweeps, vibrato, and other neat effects.

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%
MCLK is master clock, 53203424 for PAL and 53693175 for NTSC.
% 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!
MCLK is master clock, 3546893 for PAL and 3579545 for NTSC.

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.

Posted: Mon Oct 06, 2014 7:11 pm
by TmEE co.(TM)
Code I use to calculate the frequency table in my stuff, with 16 steps per note :

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%
MCLK is master clock, 53203424 for PAL and 53693175 for NTSC.

% is signed int, ! is single precision float.

Posted: Tue Oct 07, 2014 6:09 pm
by Count SymphoniC
Thanks for sharing your code. I've added this to the post.

I'll have to dig through the Authoritative reference to the YM2612 thread and see if I can put some of that info in here.

Posted: Tue Oct 07, 2014 9:07 pm
by Jazzmarazz
What options are you going to give for PAL users? A toggle option?

Posted: Tue Oct 07, 2014 10:30 pm
by Count SymphoniC
Jazzmarazz wrote:What options are you going to give for PAL users? A toggle option?
I've thought about it. I don't currently know if the system allows NTSC/PAL detection, so for the time being I'm prepared to do NTSC and PAL versions separately. But if I can get it to detect what region console it's running on then I can do it all in one ROM.

By the way, I just got the opportunity to test it on Exodus, and it showed a blank grey screen. I wonder if the VRAM clearing code messed it up somehow, or maybe it's the way z80 busreq is being handled.

Posted: Tue Oct 07, 2014 10:46 pm
by Jazzmarazz
Count SymphoniC wrote:
Jazzmarazz wrote:What options are you going to give for PAL users? A toggle option?
I've thought about it. I don't currently know if the system allows NTSC/PAL detection, so for the time being I'm prepared to do NTSC and PAL versions separately. But if I can get it to detect what region console it's running on then I can do it all in one ROM.

By the way, I just got the opportunity to test it on Exodus, and it showed a blank grey screen. I wonder if the VRAM clearing code messed it up somehow, or maybe it's the way z80 busreq is being handled.
Test what? the latest version of your ROM or PAL?

Posted: Tue Oct 07, 2014 11:16 pm
by Count SymphoniC
The latest version of my ROM. It got stuck on a blank screen and was running at 30fps... the pc I tested it on is a quad core at 4+ghz, although he had two of the cores disabled for some reason. I'll have to check into it again some time. But I think I know what could cause it.

Posted: Wed Oct 08, 2014 7:49 am
by r57shell
Of course it can check region. How then "region check" works?)

Posted: Wed Oct 08, 2014 12:08 pm
by Jazzmarazz
r57shell wrote:Of course it can check region. How then "region check" works?)
Half the time I don't know if you're being an ass, but it probably the poor English. Lunks to code supporting an auto region check within a ROM?

Posted: Wed Oct 08, 2014 1:00 pm
by Count SymphoniC
r57shell:
Of course it can check region. How then "region check" works?)
Thanks for letting me know. As I've stated before, I'm still fairly new to Genesis programming, not all of the capabilities of the hardware are known to me. Where you know enough about it to write an emulator, I do not.

Jazzmarazz:
Half the time I don't know if you're being an ass, but it probably the poor English. Lunks to code supporting an auto region check within a ROM?
Careful. Many of our friends here on this board are from different countries, they are very knowledgeable on the hardware and programming it. I wouldn't want to lose the respect of a single one of them because I said something that could be taken as offensive.

Now that I think of it, I know there's roms that are JUE regions. I can't believe I didn't think about this before.

Posted: Wed Oct 08, 2014 2:42 pm
by powerofrecall
Jazzmarazz wrote:Half the time I don't know if you're being an ass
He's a good guy. I think it's a cultural thing, and his English is better than my Russian!

But as for what I think could use some clarification on this topic, just how different would the pitch be on a PAL console using NTSC pitch values? I've never seen this demonstrated.

Posted: Wed Oct 08, 2014 3:01 pm
by TmEE co.(TM)
There's a 0.9% difference.

Posted: Wed Oct 08, 2014 3:10 pm
by Count SymphoniC
TmEE co.(TM) wrote:There's a 0.9% difference.
And that's enough of a difference for me to have both NTSC and PAL frequency tables in the tracker. You sure know alot about the sound chips.

I'm kind of curious, what uses could Timers A and B have in a tracker like this? Fundamental or otherwise.

Posted: Wed Oct 08, 2014 3:47 pm
by TmEE co.(TM)
If you want custom timing for music you can use the timers, but it makes some things complicated such as maintaining consistent PCM playback during DMAs. Also async 68K and Z80 side may be hard to manage too.

Posted: Wed Oct 08, 2014 4:11 pm
by r57shell
Jazzmarazz wrote:Half the time I don't know if you're being an ass, but it probably the poor English. Lunks to code supporting an auto region check within a ROM?
My english is bad, yes. But I don't worry about it. Also, I'm not so stupid to add in signature "sorry for my bad eng" :D

If you wanna example, try to run Comix Zone (J) with PAL Megadrive :). You'll see something like "It's developed for NTSC only".

Most of difference in sound you'll get if you use VBLANK counter, because it's 60 Hz vs 50 Hz. Most of games using VBLANK as main timer has different speeds in gameplay on different regions. I know only one example where speed of gameplay is same: UMK3. But even there, timer of round is different. And if you check MK3 (E) vs MK3 (U) you'll see very strong difference in gameplay timing. I think, reason why gameplay timing is different NTSC vs PAL: developers of that time didn't notice or just didn't have BOTH consoles at place where they develop games.