New Documentation: An authoritative reference on the YM2612

For anything related to sound (YM2612, PSG, Z80, PCM...)

Moderator: BigEvilCorporation

Post Reply
TulioAdriano
Very interested
Posts: 81
Joined: Tue Jul 10, 2007 7:45 pm
Location: Brazil / USA
Contact:

Post by TulioAdriano » Thu Jun 26, 2008 8:33 pm

Shiru wrote:
TulioAdriano wrote:Btw, I haven't seen any concrete report on the famous channel 3 special mode which would allow individual operators to be set on different frequencies.

As far as I know most tests on that feature failed to succeed, maybe wrong documentation again?
What you mean 'failed'? This mode works well both in emulators and on real hardware, some games use it. I even added basic support for this mode in TFM MM long ago.
Ok dude, it was just a question. You don't need to get angry... :shock:
Image

Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru » Thu Jun 26, 2008 8:59 pm

Mask of Destiny wrote:My guess is he's thinking of the tests as to whether or not Channel 3 special mode also worked on Channel 6.
Documentation has no mentions that second bank has any registers below #30. My test, which tried to use special mode on second bank by setting corresponding bit in register #27 of second bank, confirmed it (both for hardware and emulators). We also know that register #27 of first bank has two bits for special mode and CSM control and no free bits. So, I think, this information enough for 'concrete report'.

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sun Jun 29, 2008 5:17 am

Ok, here's everything I know about CSM mode. The operation is quite simple in the end, but I did a lot of tests searching for unusual behaviour along the way. All this information is based entirely on tests performed on the YM2612 hardware.


Enabling CSM mode:
CSM mode is a special mode of operation for channel 3 only. First of all, here's a complete description of the effects of the channel 3 mode flags in register $27:

Code: Select all

----------------------
|Mode| Behaviour     |
|----|---------------|
| 00 | Normal        |
| 01 | Special       |
| 10 | Special + CSM |
| 11 | Special       |
----------------------
Normal mode is of course when no special mode is in effect for channel 3, and it behaves like any other channel. Special mode is when a separate frequency/octave can be assigned to each operator within the channel, which we already have documentation on. CSM mode is where Timer A performs automatic key on/off for channel 3. As you can see from the table above, Special mode is always active when CSM mode is active. CSM mode is only active when the mode bits are set to 10, NOT when they are set to 11.

In order for CSM mode to have any effect, Timer A must be loaded. In other words, bit 0 of reg $27 must be set to 1. None of the other timer-related flags, including the reset and enable bits, nor the state of Timer B, have any impact on CSM mode whatsoever, and the act of changing the state of these settings at any time have no impact on the operation of the CSM mode, as long as the channel 3 mode, and Timer A load flag remain unchanged.


The effects of CSM mode:
When CSM mode is correctly enabled, each time Timer A expires, the following two steps occur, in the specified order:
1. Key-on is sent to all operators in channel 3
2. Key-off is sent to all operators in channel 3

In other words, key on occurs, immediately followed by key-off, at the instant Timer A expires. CSM mode is only evaluated when Timer A expires. The YM2612 does not evaluate the CSM mode when Timer A is loaded, only when it expires, and any changes to the CSM mode while Timer A is running will take effect immediately. If Timer A is currently running and CSM mode is enabled, key on/off will occur when the timer next expires. If Timer A is currently running and CSM mode is disabled, key on/off will not occur when the timer next expires.

There is a big implication related to the instant key on/off behaviour of CSM mode. As described in the documentation on the envelope generator, there are several phases the envelope passes through once key-on is triggered, which determine the overall volume of the operator over time. The first phase is the Attack Phase, where the volume of the operator rises from 0 towards TL, the Total Level, at a rate governed by AR, the Attack Rate. When key off occurs, the volume of the operator immediately starts to drop at a rate governed by RR, the Release Rate. If an operator is keyed off during the attack phase and it has not reached TL yet, the volume of the operator will stop rising, and will immedaitely start to fall according to the release rate.

Since the key-on and key-off occur at the same time in CSM mode, the only way a sound can be produced is if the volume level starts at something greater than 0. This means the only supported value for the Attack Rate in CSM mode is $1F, which is described as "infinity" in the documentation, meaning the volume of the channel starts at the level specified by TL. Testing has shown that a setting of $1E also works, and produces an identical output as $1F for this purpose (and possibly is identical under all circumstances. Would need further testing). All other settings for AR fail to produce any waveform, since they start with a volume level of 0. Since you can only use an AR value of infinity, and key-off occurs instantly, TL and RR are the two parameters which govern the envelope under CSM mode. DR, SR, and SL will have no impact.


The interaction of CSM and manual key on/off:
One subtle point about CSM mode is how it interacts with manual key on/off events triggered through register $28. CSM mode doesn't trigger a "real" key-on or key-off event. Timer A expiring will NOT key-off an operator which was manually keyed on by a write to register $28. CSM mode cannot trigger a key-on or key-off for any operator which has been manually sent a key-on event to register $28, until that operator is keyed off manually by a write to register $28.

In other words, CSM mode only affects operators which are currently keyed off. If you were to manually key-on all operators in channel 3, then enable CSM mode, the CSM mode would have no effect until you sent a manual key-off event. If you never send a manual key-off, CSM mode will never take effect, even when the output of the operators decay to 0.

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sun Jun 29, 2008 7:16 am

Here's a test ROM which uses CSM to generate a fading, repeating A6 tone:
http://nemesis.hacking-cult.org/MegaDri ... smmode.bin

Here's the source:
http://nemesis.hacking-cult.org/MegaDri ... smmode.asm

And here's a sample of the output you get on a PAL MD1600 MegaDrive, recorded at 96KHz:
http://nemesis.hacking-cult.org/MegaDri ... smmode.wav


In an emulator that doesn't support CSM, you'll only get silence if you run this ROM. I haven't come across any Mega Drive emulator which emulates CSM mode as of yet.

notaz
Very interested
Posts: 192
Joined: Mon Feb 04, 2008 11:58 pm
Location: Lithuania

Post by notaz » Sun Jun 29, 2008 12:52 pm

Nemesis wrote:I haven't come across any Mega Drive emulator which emulates CSM mode as of yet.
It works in MESS, as MAME YM2612 core supports CSM mode.

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sun Jun 29, 2008 1:47 pm

Ok then, no emulator that emulates it correctly. :) MAME has an attempt at CSM support implemented, but it doesn't work properly, as is noted in the sourcecode. I've just tried the CSM test ROM in HazeMD, and it just plays a solid tone, which isn't silence, but it isn't correct. I haven't tried MESS, but it's based on the MAME core as I understand it, so it's probably in the same boat.

EDIT: Yep, tried in MESS. Same as MAME.

Chilly Willy
Very interested
Posts: 2854
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Jun 29, 2008 8:05 pm

Does changing the frequency during the release period take affect, or does it wait for the next KEY_ON? If the frequency only changes when you KEY_ON, it makes sense why they made CSM work this way. CSM is meant for speech synthesis, so here's what you'd do:

Set frequency of all ch3 ops for your formants.
Set TIMERA and enable CSM.
loop:
Wait for TIMERA overflow.
Set TIMERA for the period of the phoneme.
Set ops for the next phoneme's formants.
goto loop

This would give you properly timed phonemes while allowing you to set up for the next one ahead of time. Many phonemes are sensitive to how long they last. This form of speech synthesis usually has a table with the formant center frequencies, and the length of the phoneme.

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Mon Jun 30, 2008 2:15 am

I've just tested, and frequency changes take effect immediately. If you change the frequency for an operator, the new frequency is used for the very next sample, regardless of the current position in the output wave, or the state of the envelope generator. This is consistent with how frequency changes occur without CSM mode active.

Even without the ability to setup the freqencies ahead of time, it wouldn't change the length of time each frequency is active for, it would just introduce some minor latency after each Timer A overflow before the frequencies are updated, and create a slight offset between the frequency changes of each operator. This would occur both leading into and out of each Timer A period, so the length wouldn't be affected, merely the timing of the changes. It would be most noticeable if the decay phase of the envelope was extreme, as the initial "attack" for each new key-on would be using the frequency of the previous phoneme. If there was virtually no decay for each key-on, which it sounds like is probably how it's intended to be used, there would be no noticeable effect whatsoever, apart from the minor offset between each operator receiving frequency changes.

In a way it could be a good thing. If you set a very short Timer A period, there might not be time to update all 4 frequency values before the timer overflows. If you were leading into a very long Timer A period, and the frequency was latched at key-on only, it could result in a very long phoneme being played with one or more operators set to the wrong frequency, as the new frequency values couldn't be written in time.

Chilly Willy
Very interested
Posts: 2854
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Mon Jun 30, 2008 2:50 am

Well, in the terms of the YM2612 clock or the Z80, phonemes are LONG. I don't think there would be one so short that you couldn't set the operators before the timer overflowed. Perhaps in SEGA's arcade systems where they used this for speech synthesis, they actually had the int line tied to the processor so that TIMERA actually generated an int. Then the behavior would work even with the frequency changing immediately. You'd just change three or four operators during the int handler. I would guess the point of the CSM mode is to eliminate the envelop almost completely. If you set the decay to be long, you have virtually no attack, just a waveform that starts at max and stays very close. The only thing that would change is the frequencies.

TmEE co.(TM)
Very interested
Posts: 2397
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Mon Jun 30, 2008 3:12 pm

CSM mode works on MD2 (PAL VA1 board). There is tonal difference, but that is because you used too low TL value (values below 8 should not be used).
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Jul 01, 2008 1:56 pm

I've just uploaded a new version of the YM2608 manual translation. It includes too many fixes to detail. Suffice to say, it corrects numerous transcription errors in the previous document (eg, the write wait times on page 14), a bucketload of OCR corrections I missed the first time around which greatly improves the translation in several sections, adds some entire sentences I somehow skipped when I was doing the initial translation, includes proper equivalents for words that were spelt phonetically, lots of improvements to the overall formatting, etc etc. If you downloaded the first translation, you should update it with the new version.

I don't expect to change this document again in the near future, unless I find some whopping big error, or I get someone who actually reads Japanese to check the translation. You can download the latest version from the following link:
http://nemesis.hacking-cult.org/MegaDri ... slated.PDF

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Jul 01, 2008 3:34 pm

Here are a few more things I've found out about the YM2612 over the last few days:

1. Status registers
The YM2608 manual describes 3 separate status registers that can be read. Significantly, one of them reportedly returns an ID number for the chip, when the status register is read while register location $FF is latched. After testing, I can confirm that this does not apply to the YM2612. The normal status register appears to be returned from the YM2612 under all circumstances, regardless of the address the YM2612 is being read from (part 1 address/data or part 2 address/data), or the register that is latched at the time the status register is read.

2. Prescaler registers
The YM2608 manual describes registers $2D, $2E, and $2F as prescaler register addresses, which reportedly simply latching will adjust the multipliers used to calculate the internal clock for the FM generator. This does not seem to exist in the YM2612. Latching or writing to these registers had no noticeable effect.

3. Interrupts
I've conducted a full set of tests on the behaviour of the interrupt (INT) line of the YM2612. Even though it's not connected in the Mega Drive, it's still a functional part of the YM2612, and for the sake of completeness if nothing else, I wanted to confirm how it operated. Emulators like MAME could make use of this info too.

First and foremost, I've confirmed that interrupt control flags for the YM2608 in register $29 do not exist on the YM2608.

The interrupt line can be triggered by either Timer A or Timer B. Using the terms applied in the YM2608 manual, when a timer is "loaded" (bits 0 and 1 of reg $27), it starts with a number loaded into it as specified in the counter registers for each timer, and will count down at a regular rate, until it tries to count down from 0 and overflows. At this time, it will re-load the counter. What else happens as a result of a timer overflowing depends on the setting of the "enable" flag (bits 2 and 3 of reg $27). As described in the documentation, when the enable bit is set and the timer overflows, it will set the overflow flag for that timer in the status register, and trigger an interrupt.

And now for the new stuff. Although not mentioned in the documentation, the reset flag directly affects interrupt generation. When a timer overflows, the YM2612 checks the current state of the timer overflow bit for that timer in the status register. The YM2612 will only generate an interrupt for that timer if the overflow bit is currently unset. If the overflow bit is unset, and the enable flag is set in the timer control register, the INT line will be asserted. The INT line will remain asserted, until the reset bit for that timer is set to 1 in the timer control register, or until the timer overflows again. If the reset bit for the timer is cleared at any time, the interrupt line will immediately be negated. If the timer overflows while INT is still asserted, that is, without reset being written to, the interrupt line will immediately be negated. From this point on, no interrupts will be generated for that timer until the reset bit is set. Once the reset bit has been set when an interrupt has been missed, the INT line will not immediately be asserted. The INT line will remain negated until the timer overflows again.

This means in order to use the YM2612 interrupt line, the interrupt handler must always write the reset bit for that timer before exiting the interrupt handler. This tells the YM2612 to stop asserting the INT line for that timer, and prepares the YM2612 to trigger another interrupt when the timer overflows again. Additionally, in periods where the YM2612 interrupt is masked, it may be possible for a YM2612 interrupt to be missed, requiring the reset bit to be written in order to resume interrupt generation. The overflow bit in the status register would allow missed interrupts to be detected. The overflow bit should only be asserted in the interrupt handler where YM2612 interrupts are being used, as the overflow bit is set at the same time as the interrupt is generated, and the reset operation when leaving the interrupt handler clears this flag.

Sorry if that's confusing. It's easier to understand when you're just looking at the oscilloscope. I might put some pictures up for this later on. I'm not sure that I explained this very well.

4. Timers
Two things here. First of all, I've tested the timer A registers, and confirmed that they are NOT "ganged together" like the frequency registers are. Changes to either register $24 or $25 affect Timer A the next time it overflows or is loaded, regardless of the order the registers are written to.

Secondly, I've confirmed the timer periods in the YM2612 are half the rate of the timers described in the YM2608 documentation, or in other words, the YM2612 timers take twice as long to count down as the timers in the YM2608. Here are the formulae to calculate the correct timer periods for the YM2612:

Code: Select all

To calculate Timer A period in microseconds:

TimerA = 144 * (1024 - NA) / M
   NA:     0~1023
   M:      Master clock (MHz)

Eg, where clock = 7.61Mhz
   TimerA(MAX) = 144 * (1024 - 0) / 7.61 = 19376.61 microseconds
   TimerA(MIN) = 144 * (1024 - 1023) / 7.61 = 18.92 microseconds


To calculate Timer B period in microseconds:

TimerB = (144*16) * (256 - NA) / M
   NB:     0~255
   M:      Master clock (MHz)

Eg, where clock = 7.61Mhz
   TimerB(MAX) = (144*16) * (256 - 0) / 7.61 = 77506.44 microseconds
   TimerB(MIN) = (144*16) * (256 - 255) / 7.61 = 302.76 microseconds


I think that's about it so far. I'm finding so many bits out about this chip that I probably will end up compiling it all into a "YM2612 Undocumented" reference of some kind, at some point in the future.

As for what's still to come, I'm making very significant progress on SSG-EG. I hope to have a full description of SSG-EG completed within the next few days, so that should be of interest to some people. I also plan to revisit the detune overflow bug as well, as I haven't got all the needed info in order to emulate that correctly yet.

Eke
Very interested
Posts: 864
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Tue Jul 01, 2008 4:17 pm

very nice...

about the timers, could you precise in which condition a timer counter is reloaded:

what has been verified:
1/ when the counter underflows


what's still unsure:
2/ each time the LOAD bit is set (unlikely)
3/ each time the LOAD bit switch from 1 to 0 or from 0 to 1 (or does the counter restart from the last point where it was stopped ?)
4/ when the timer base value is modified

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jul 02, 2008 7:33 am

After some testing, it appears that the timer counter is only reloaded at the following times:
1. When the counter underflows
2. When the load bit is switched from 0 to 1 (IE, the counter is changed from the stopped state to the running state). The counter does not restart from the last point it was up to when it is re-enabled.

The timer counter is NOT reloaded when:
1. The load bit is already 1, and reg $27 is written to setting the load bit as 1 again
2. The reset or enable bits are changed
3. The timer counter registers are modified

Eke
Very interested
Posts: 864
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Wed Jul 02, 2008 12:45 pm

Thanks for the clarification again :)

at least , this was not correctly emulated in emulators (counter was reloaded every time the timer load value was changed), this should not affect any games but it's still better to know

Post Reply