AY-3-8910 / YM2149 emulation

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
AY-3-8910 / YM2149 emulation
by on (#236581)
Recently implemented this chip for an MSX core, but for some reason something else is wrong so I can't test it. Figured I'd ask here in case anyone was familiar with it.

I'm going off the official manual, plus notes from MAME's implementation:
https://github.com/mamedev/mame/blob/ma ... ay8910.cpp

It says the counters increment instead of decrement, easy enough:

Code:
auto PSG::Tone::clock() -> void {
  if(++counter < period) return;
  counter = 0;
  phase ^= 1;
}

//note: lfsr.bit(n) == (lfsr >> n & 1)
auto PSG::Noise::clock() -> void {
  if(++counter < period) return;
  counter = 0;
  if(phase ^= 1) lfsr = (lfsr.bit(0) ^ lfsr.bit(3)) << 16 | lfsr >> 1;
}


The envelopes get tricky ... MAME is doing all this weird stuff to reduce cases:
https://github.com/mamedev/mame/blob/ma ... .cpp#L1129

Too evil. So I just went off of the official PDF instead and came up with this:

Code:
auto PSG::Envelope::clock() -> void {
  if(holding) return;
  if(++counter < period) return;
  counter = 0;
  if(!attacking) {
    if(phase !=  0) return (void)phase--;
  } else {
    if(phase != 15) return (void)phase++;
  }
  if(!repeat) {
    phase = 0;
    holding = 1;
  } else if(hold) {
    if(alternate) phase ^= 15;
    holding = 1;
  } else if(alternate) {
    attacking ^= 1;
    if(!attacking) {
      phase--;
    } else {
      phase++;
    }
  } else {
    phase = !attacking ? 15 : 0;
  }
}

//called when writing to the envelope mode register
auto PSG::Envelope::reload() -> void {
  holding = 0;
  attacking = attack;
  phase = !attacking ? 15 : 0;
}


Idea was, if we are attacking, and we count from 0 to 15, we should allow the value to actually be 15 for a full cycle, rather than immediately load in a new value once incrementing to 15. I don't see how/if MAME is doing this, but it seems logical.

If we're not in continue mode (I call it repeat because continue is a C++ keyword), the PDF says the output drops to 0. So that'd give us:
0,1,2,3,...14,15,0,0,0,0,... or
15,14,13,...,2,1,0,0,0,0

Next, if it's hold mode, we freeze the envelope output (phase) indefinitely. And this also allows to alternate/invert the final output:
0,1,2,...,14,15,0,0,0 or
15,14,13,...,2,1,0,15,15,15...

Next, if it's just alternating, then we flip the attack value (which I've cached to attacking since you can read back the written register values), and so that it looks like a proper triangle wave instead of repeating, we force an increment/decrement after alternating between attack/decay, so:
0,1,2,...,13,14,15,14,13,12,...2,1,0,1,2,...
Whereas without the extra inc/dec we'd end up with:
0,1,2,...,13,14,15,15,14,13,12,...,2,1,0,0,1,2,...

Finally, the last case are the sawtooth style waves where it just keeps repeating:
0,1,2,...13,14,15,0,1,2,...,13,14,15,0,1,2,...

I think this is all correct. Not sure about I/O register writes:

Code:
auto PSG::write(uint8 data) -> void {
  switch(io.register) {
  case  0:
    toneA.period.bits(0, 7) = data.bits(0,7);
    break;
  case  1:
    toneA.period.bits(8,11) = data.bits(0,3);
    toneA.unused.bits(0, 3) = data.bits(4,7);
    break;
  case  2:
    toneB.period.bits(0, 7) = data.bits(0,7);
    break;
  case  3:
    toneB.period.bits(8,11) = data.bits(0,3);
    toneB.unused.bits(0, 3) = data.bits(4,7);
    break;
  case  4:
    toneC.period.bits(0, 7) = data.bits(0,7);
    break;
  case  5:
    toneC.period.bits(8,11) = data.bits(0,3);
    toneC.unused.bits(0, 3) = data.bits(4,7);
    break;
  case  6:
    noise.period = data.bits(0,4);
    noise.unused = data.bits(5,7);
    break;
  case  7:
    channelA.tone  = data.bit(0);
    channelB.tone  = data.bit(1);
    channelC.tone  = data.bit(2);
    channelA.noise = data.bit(3);
    channelB.noise = data.bit(4);
    channelC.noise = data.bit(5);
    io.portA       = data.bit(6);
    io.portB       = data.bit(7);
    break;
  case  8:
    channelA.amplitude = data.bits(0,3);
    channelA.envelope  = data.bit (4);
    channelA.unused    = data.bits(5,7);
    break;
  case  9:
    channelB.amplitude = data.bits(0,3);
    channelB.envelope  = data.bit (4);
    channelB.unused    = data.bits(5,7);
    break;
  case 10:
    channelC.amplitude = data.bits(0,3);
    channelC.envelope  = data.bit (4);
    channelC.unused    = data.bits(5,7);
    break;
  case 11:
    envelope.period.bits(0, 7) = data.bits(0,7);
    break;
  case 12:
    envelope.period.bits(8,15) = data.bits(0,7);
    break;
  case 13:
    envelope.hold      = data.bit (0);
    envelope.alternate = data.bit (1);
    envelope.attack    = data.bit (2);
    envelope.repeat    = data.bit (3);
    envelope.unused    = data.bits(4,7);
    envelope.reload();
    break;
  }  //14,15, I/O ports not implemented yet
}


Do any of these register writes reset the counters to zero, eg for tone, noise, or envelope?

Next up is the mixing. The manual says you can enable tone and/or noise on each channel, so I came up with this:

Code:
auto PSG::mix() -> double {
  double output = 0.0;
  if((toneA.phase && !channelA.tone) || (noise.lfsr.bit(0) && !channelA.noise)) {
    output += amplitudes[channelA.envelope ? envelope.phase : channelA.amplitude];
  }
  if((toneB.phase && !channelB.tone) || (noise.lfsr.bit(0) && !channelB.noise)) {
    output += amplitudes[channelB.envelope ? envelope.phase : channelB.amplitude];
  }
  if((toneC.phase && !channelC.tone) || (noise.lfsr.bit(0) && !channelC.noise)) {
    output += amplitudes[channelC.envelope ? envelope.phase : channelC.amplitude];
  }
  return output / 3.0;
}


However, MAME selects channels like this:
Code:
m_vol_enabled[chan] = (m_output[chan] | TONE_ENABLEQ(chan)) & (NOISE_OUTPUT() | NOISE_ENABLEQ(chan));


In my code it'd be:
Code:
(toneN.phase | channelN.tone) & (noise.lfsr.bit(0) | channelN.noise);


The enable bits are inverted, so I'm almost certain these two are equivalent, but I think my way is easier to understand, though I may rename the variables, so it's && !channelC.toneDisable or whatnot.

Finally, the last issue is that every last AY-3-8910 implementation has different logarithm values.

MAME has a hardware measurement table here:
https://github.com/mamedev/mame/blob/ma ... 10.cpp#L37

Then later it says:
vol(i) = exp(i/2-7.5)

Then later we have these measurements:
https://github.com/mamedev/mame/blob/ma ... 0.cpp#L722

Other AY-3-8910 cores have different volume scales as well. None of them match. Which values should I be using for the MSX1?

Now getting into MAME notes more:

Quote:
The main difference between the AY-3-8910 and the YM2149 is, that the
AY-3-8910 datasheet mentions, that fixed volume level 0, which is set by
registers 8 to 10 is "channel off". The YM2149 mentions, that the generated
signal has a 2V DC component. This is confirmed by measurements. The approach
taken here is to assume the 2V DC offset for all outputs for the YM2149.
For the AY-3-8910, an offset is used if envelope is active for a channel.
This is backed by oscilloscope pictures from the datasheet. If a fixed volume
is set, i.e. envelope is disabled, the output voltage is set to 0V. Recordings
I found on the web for gyruss indicate, that the AY-3-8910 offset should
be around 0.2V. This will also make sound levels more compatible with
user observations for scramble.


I ... don't understand any of that.

So it's saying that whenever the fixed volume for the channels is set to 0, it means the channel is off.
What does that mean? The counters won't run? But they do on the YM2149?
MAME is only actually using this via zero_is_off in build_3D_table which looks ... insanely complicated.
Reminds me a bit of the NES where the volume of one channel biases the volume of other channels. Is that what this is?
And then the YM2149 has a 2V DC offset ... so a fixed amount to add/subtract by ... only for a fixed volume of zero, or for any volume?
How do I convert a 2VDC offset to an amount to add/subtract by? Is it positive or negative?
And then it's saying ... the AY-3-8910 only gets the offset if the envelope is enabled, and it's 0.2VDC here?
Should I even bother with this? My code runs a 20hz highpass filter on the final output to remove any DC bias anyway.

What is the actual frequency of this chip? The PDF says the counters run on a clock divider of 16, so I've just been doing 3.58MHz/16, and each step at that frequency, clocking the tones/noise/envelope by one.

Then there's this note:
Quote:
Also, note that period = 0 is the same as period = 1. This is mentioned
in the YM2203 data sheets. However, this does NOT apply to the Envelope
period. In that case, period = 0 is half as period = 1.


As far as I see, MAME isn't doing anything different between the tone/noise/envelope periods, all three are:
Code:
counter++;
if(counter >= period) ...


As a result, period 0 is the same as period 1 even for envelopes:
https://github.com/mamedev/mame/blob/ma ... .cpp#L1117

What am I missing there?

... finally, I feel it's best to separate the AY-3-8910 and YM2149 implementations, so for now mine is just strictly AY-3-8910.
It's only a hundred lines of code or so to duplicate, which seems more sensible to me than having m_step, m_env_step_mask, etc.
The big question I'll have for YM2149 is ... if the envelopes now have 32 states, then that means we need a 32-state logarithmic volume table. So, would anyone happen to have actual values for such a table?

Thanks in advance if anyone is able to answer any of these questions ^-^
Re: AY-3-8910 / YM2149 emulation
by on (#236582)
Here's my guess in Python:
Code:
# for SN76489
num_steps = 16
decibels_per_step = 2.0

# for AY-3-8910
num_steps = 16
decibels_per_step = 3.0

# for YM2149
num_steps = 32
decibels_per_step = 1.5

# formula follows
full_scale = 8000
[0] + [int(round(full_scale * pow(10, x * decibels_per_step / 20.))) for x in range(2 - num_steps, 1)]

# result for YM2149
# [0, 45, 53, 64, 76, 90, 107, 127, 151, 179, 213, 253, 301, 357, 425, 505, 600, 713, 847, 1007, 1197, 1423, 1691, 2010, 2388, 2839, 3374, 4009, 4765, 5664, 6731, 8000]


Another angle is to ask NSFPlay maintainer rainwarrior about volumes in Sunsoft 5B, which contains a YM2149, either here or on the FamiTracker.org Discord server.
Re: AY-3-8910 / YM2149 emulation
by on (#236589)
I don't have all the details on instant recall, the best I could say is that NSFPlay's implementation was inherited from Mitsutaka Okazaki's original version, and subsequently modified to more closely match the 5B by myself. I've done no tests of an AY-3-8910 to compare, nor of a plain YM2149.

You made a lot of comments that don't look like a question (e.g. your envelope is probably fine, alternating mode should have 15,15 and 0,0 in it, etc.) so I might not comment much there.

byuu wrote:
Do any of these register writes reset the counters to zero, eg for tone, noise, or envelope?

Only the envelope has a phase reset. That should be very explicitly described in its datasheet.

The rest are permanently in an indeterminate phase, though there's a "trick" of setting the period register to 0 briefly then setting back to an audible period, which will effectively "reset" the phase to either 0 or 180 degrees. Not sure how useful that is, but maybe a 50/50 sync would be better than nothing for some purpose.

byuu wrote:
Finally, the last issue is that every last AY-3-8910 implementation has different logarithm values.

In my experience with the 5B, the output does seem to match the logarithmic curve described by the datasheet, but then followed by its own internal amplifier which has an unfortunate nonlinear curve. I was investigating that in this thread, though the 5B's amplifier is unique and unrelated to the underlying AY/YM component, AFAIK.

So... on another system hosting an AY/YM you might be dealing with a second amplifier that messes with the curve, which could account for people wanting to tweak the values like that.

byuu wrote:
Quote:
The main difference between the AY-3-8910 and the YM2149 is, that the
AY-3-8910 datasheet mentions, that fixed volume level 0, which is set by
registers 8 to 10 is "channel off". The YM2149 mentions, that the generated
signal has a 2V DC component. This is confirmed by measurements. The approach
taken here is to assume the 2V DC offset for all outputs for the YM2149.
For the AY-3-8910, an offset is used if envelope is active for a channel.
This is backed by oscilloscope pictures from the datasheet. If a fixed volume
is set, i.e. envelope is disabled, the output voltage is set to 0V. Recordings
I found on the web for gyruss indicate, that the AY-3-8910 offset should
be around 0.2V. This will also make sound levels more compatible with
user observations for scramble.


I ... don't understand any of that.

I'm not certain how to interpret that either. Since I've only worked with the 5B and not a YM directly, its own amplifier would remove DC bias too. If the goal is to emulate audio, I don't know that it's relevant, since we can't hear DC offset (...and if you do your tests with audio hardware and not an oscilloscope like I usually do, that device will probably filter it off too).

In dealing with the logarithmic curve, to produce absolute values you need to set some arbitrary nonzero output for volume "0" that can be multiplied against. I don't know if that would be related to the DC bias, but it's something that I needed to account for in my model. I guess this is baked into the log table output used by the emulation.

byuu wrote:
What is the actual frequency of this chip? The PDF says the counters run on a clock divider of 16, so I've just been doing 3.58MHz/16, and each step at that frequency, clocking the tones/noise/envelope by one.

It has an external clock, so the frequency depends where it's hosted. The YM2419 also has a second divider that can be turned on and off that halves the tone resolution but doubles the envelope resolution (the 5B operates this way, using the Famicom's CPU clock 1.79MHz). What I know is described here.

Edit: it maybe halves the envelope too. At current I can only state that the 5B works as described on the wiki. I don't know for certain what happens when SEL is high/nc on a YM2149.

byuu wrote:
Then there's this note:
Quote:
Also, note that period = 0 is the same as period = 1. This is mentioned
in the YM2203 data sheets. However, this does NOT apply to the Envelope
period. In that case, period = 0 is half as period = 1.

Yes, the 0=1 thing seems to be true. It is a bit bizarre to me. I have verified that 0 is not a halt and it does keep changing phase during.

The envelope I'm not sure about. MAME's implementation seems to suggest that what I have in NSFPlay is off by 1 for the envelopes. This is something I will have to test. I believe I tried to make sure the frequencies matched in my earlier tests, so I'd be very surprised to be off by 1, but it is something I need to test again, so I can't comment on that yet, sorry.

byuu wrote:
The big question I'll have for YM2149 is ... if the envelopes now have 32 states, then that means we need a 32-state logarithmic volume table. So, would anyone happen to have actual values for such a table?

Like above, I think the table output may be some compromised combination of the true output + some external amplifier. Not sure though, as I only know about 5B really.
Re: AY-3-8910 / YM2149 emulation
by on (#236594)
Oh wow, I completely forgot the 5B was a YM2149F! I guess I might as well refactor that code to support the envelope now.

> You made a lot of comments that don't look like a question

Mostly just in case I made an obvious mistake someone might spot. Never know.

> (e.g. your envelope is probably fine, alternating mode should have 15,15 and 0,0 in it, etc.)

Wait, it *should* have that? I expected it to be 14,15,14 and 1,0,1. Not 14,15,15,14 and 1,0,0,1.

The former gives you an actual triangle, the latter will not.

> Only the envelope has a phase reset.

For the 16-bit period/counter as well, or for just the 4/5-bit output that counts after each period reload?

> In my experience with the 5B, the output does seem to match the logarithmic curve described by the datasheet, but then followed by its own internal amplifier which has an unfortunate nonlinear curve.

Yeah, I'm thinking my base class should just output per-channel 4/5-bit samples. Then each implementation can mix freely. Should also allow support Game Gear's SN76489 "stereo" mode.

> I don't know that it's relevant, since we can't hear DC offset

All it really does is distort other audio applications on your host system that happen to be mixed in. So even though your emulator audio appears silent, your MP3 player gets garbled because the emulator's DC offset crushes the available audio range. So in effect we really, really want to get rid of DC offset in emulators.

That's the limit of my understanding of it. I don't even understand how a high-pass filter removes it.

> The YM2419 also has a second divider that can be turned on and off that halves the tone resolution but doubles the envelope resolution

I mean, it's one or the other, right? You could think of it as halving the tone, or doubling the envelope resolution, but not both? Or have I misunderstood it?

> I can't comment on that yet, sorry.

No worries, and no rush. We can always fix things later. Thank you for your reply!
Re: AY-3-8910 / YM2149 emulation
by on (#236596)
byuu wrote:
Wait, it *should* have that? I expected it to be 14,15,14 and 1,0,1. Not 14,15,15,14 and 1,0,0,1.

The former gives you an actual triangle, the latter will not.
Pedantically they're both real triangles: the 14,15,15,14 waveform ("x" below) is a half-sample delay of a 14.5,15.5,14.5,13.5 ("y"):

x 14
y 14.5
x 15
y 15.5
x 15
y 14.5
x 14
y 13.5

Quote:
That's the limit of my understanding of it. I don't even understand how a high-pass filter removes it.
The simplest highpass filter is subtracting the previously generated sample from the current one. This would be written y[n]=x[n]-x[n-1]

Say the generated audio as audible and DC components (x[n]=a[n]+d). The DC component can't vary with time, otherwise it would be audible. When you subtract the generated samples, the DC component is subtracted away from itself (a[n]+d-a[n-1]-d).
Re: AY-3-8910 / YM2149 emulation
by on (#236616)
byuu wrote:
Wait, it *should* have that? I expected it to be 14,15,14 and 1,0,1. Not 14,15,15,14 and 1,0,0,1.

Well, the alternative seems like it would be that one of the envelope modes has a very different period length than the others?

byuu wrote:
The former gives you an actual triangle, the latter will not.

If it's any consolation, with the logarithmic output it's not really much of a triangle either way.

byuu wrote:
rainwarrior wrote:
Only the envelope has a phase reset.

For the 16-bit period/counter as well, or for just the 4/5-bit output that counts after each period reload?

It should reset the whole envelope generator. I don't remember ever seeing any evidence that the first tick was shortened.

byuu wrote:
All (DC offset) really does is distort other audio applications on your host system that happen to be mixed in. So even though your emulator audio appears silent, your MP3 player gets garbled because the emulator's DC offset crushes the available audio range. So in effect we really, really want to get rid of DC offset in emulators.

There are some other cases where a DC offset on an output will cause audible effects on some system it's being played through, but none of them have anything to do with emulating the sound of a chip like this.

If something has a constant DC offset, it should not be emulated at all. However, if it's a DC offset that can be turned on and off by some state of the chip, that will make an audible difference when it changes, and that's something that should be emulated. I couldn't quite tell from the description you pasted whether it's suggesting that the AY shifts its DC offset when you use envelopes? It's a bit muddled to me. In my experience with the 5B, envelope 0 seemed to be identical to volume 0, but it's possible that's not the case for AY, based on what that seems to be saying?

byuu wrote:
That's the limit of my understanding of it. I don't even understand how a high-pass filter removes it.

A DC offset is the same as an infinitely low frequency, for the purposes of a high-pass filter.

The other way to think of a high pass filter is that it's a circuit that automatically counter-balances the incoming signal to return it to zero, but it has a delay (exponential decay) that makes it happen slowly. The slower it is, the weaker the filter, and fast changes will pass right through it before it can affect them much, but nothing's slower than a constant DC offset.

(Nothing really wrong with emulating a DC offset higher up in the chain as long as there's a highpass that removes it before the final output, but there's also no reason to add a constant if all you're doing to do is remove it.)

byuu wrote:
rainwarrior wrote:
The YM2419 also has a second divider that can be turned on and off that halves the tone resolution but doubles the envelope resolution

I mean, it's one or the other, right? You could think of it as halving the tone, or doubling the envelope resolution, but not both? Or have I misunderstood it?

With this mode enabled, the tone/noise will run at half speed, and so will the envelope, but the envelope will be twice as smooth.

It's as if you were using an AY at half the clock rate, and the envelope had some magic internal 2x interpolation.

Edit: this might be wrong. The SEL might halve the envelope too. Perhaps the YM always has 32 steps? Not sure. The 5B has the clock relationship I described on the wiki, but I don't know what SEL high/nc does for sure.
Re: AY-3-8910 / YM2149 emulation
by on (#236618)
> Well, the alternative seems like it would be that one of the envelope modes has a very different period length than the others?

I mean, I don't actually know which it is. Does anyone know for sure which one it is? MAME's code is too clever with using a signed 8-bit envelope phase and using d6 as a toggle, so it's hard to reason about, but it looks to me like MAME is likely doing 14,15,15,14.

Whichever it is is fine, I'll emulate it how it's supposed to be emulated ^-^

> It should reset the whole envelope generator. I don't remember ever seeing any evidence that the first tick was shortened.

Very interesting! MAME doesn't emulate that in that case. It only resets the 5-bit phase:
https://github.com/mamedev/mame/blob/ma ... .cpp#L1006

> However, if it's a DC offset that can be turned on and off by some state of the chip, that will make an audible difference when it changes, and that's something that should be emulated

Oh boy, that's a good point. Even for my obsessiveness with accuracy, I'd have to make something like that an option. Not only does it wreck other audio playing on your system, it'd cause audible popping when you turn the sound chip on and off programmatically (which you have to do often with the Neo Geo Pocket to switch between PSG and DAC mode, for instance.)

> A DC offset is the same as an infinitely low frequency, for the purposes of a high-pass filter.

I mean, that makes sense for why the filter would work on that, and why even a high-pass of 5hz is enough, but it's not clear to me how outputting an 8-bit unsigned audio sample of 0x40 (so a 1.25V DC offset) always is equal to an infinitely low frequency. It's not any frequency at all, it's 0hz. It's unchanging. It's infinitely low in the same way that 0/1 has an infinite remainder, but division by zero is not infinity at all. It's just undefined.

Anyway it's not important I understand it, thank you both for explaining the concepts a bit though :D

I used to not understand audio stuff at all, and slowly but surely it's starting to make sense and I can implement PSG chips pretty easily, save for the fine details that aren't documented well. Hopefully one day I can do the same with FM chips.

> It's as if you were using an AY at half the clock rate, and the envelope had some magic internal 2x interpolation.

Got it, thanks. Yeah, I'm going to implement YM2149(F) separately. I think I have enough for the initial implementation.

A shame Gimmick doesn't use the envelopes. Would be a great test case.
Re: AY-3-8910 / YM2149 emulation
by on (#236619)
byuu wrote:
division by zero is not infinity at all. It's just undefined.

This is true in real numbers. However, division by zero in the projective reals produces a number called "infinity". This number appears, for example, as the tangent of tau/4 radians or 90 degrees. The extended reals, by contrast, have two "infinity" numbers, one at each end of the real line; IEEE 754 floating point infinity behavior models extended reals.

byuu wrote:
A shame Gimmick doesn't use the envelopes. Would be a great test case.

There are plenty of other test cases among what MSX, ZX Spectrum 128K, Atari ST, and FamiTracker composers have done.
Re: AY-3-8910 / YM2149 emulation
by on (#236622)
byuu wrote:
I mean, I don't actually know which it is. Does anyone know for sure which one it is? MAME's code is too clever with using a signed 8-bit envelope phase and using d6 as a toggle, so it's hard to reason about, but it looks to me like MAME is likely doing 14,15,15,14.

Yes, what you think MAME is likely doing is in fact the correct thing.

byuu wrote:
MAME doesn't emulate that in that case. It only resets the 5-bit phase.

Thanks for pointing it out. That's not how I have it implemented, but I will make a note to test this later. (I would generally assume MAME to be correct here, their sources are newer than the implementation I was building on, but it never hurts to verify.)

byuu wrote:
I mean, that makes sense for why the filter would work on that, and why even a high-pass of 5hz is enough, but it's not clear to me how outputting an 8-bit unsigned audio sample of 0x40 (so a 1.25V DC offset) always is equal to an infinitely low frequency. It's not any frequency at all, it's 0hz. It's unchanging. It's infinitely low in the same way that 0/1 has an infinite remainder, but division by zero is not infinity at all. It's just undefined.

Well, in the context of a high-pass filter, it's not really like division by zero. It's more like multiplying by zero. The attenuation at 0.00000000001Hz is going to be only very slightly different from the attenuation at "0Hz" (DC constant), and for a slice of time that's not long enough to see the value rising and falling, you wouldn't be able to tell the difference between the two. The transition all the way down to 0 is clean and continuous.

I think it works out conveniently like this in a bunch of related places like in a Fourier Transform the DC offset will end up described as 0Hz as well.
Re: AY-3-8910 / YM2149 emulation
by on (#236637)
Oh boy, the YM2149 is even more fun.

MAME sets m_step=2 for the AY, m_step=1 for the YM, then does:
Code:
if(++m_ctr >= envelope_counter * m_step) {
  m_ctr=0;
  //step the envelope phase
}

Which means that envelopes will take twice as long to step one phase on the YM, not half as long. And now that there's 32 phases instead of 16, that would effectively make it four times slower. It doesn't change anything to do with the tone/noise periods in YM mode. Even if you clock the YM externally twice as often to compensate, that's still going to be twice as slow, not twice as fast. You'd have to clock it eight times faster to actually make the envelopes run compatibly (save for the smoother steps) to the AY.

I also get conflicting answers on whether the YM2149 adds 15 additional steps (so 0-30 or 1-31) or 16. Internet forum posts say 15, MAME says the steps are doubled, which would be 16. Logically, it needs to be doubled, otherwise it's not going to be directly backward compatible.

> There are plenty of other test cases among what MSX, ZX Spectrum 128K, Atari ST, and FamiTracker composers have done.

Writing a small partial VGM music player may well be a good idea, yeah.

> Yes, what you think MAME is likely doing is in fact the correct thing.

Wild. Okay, thank you.
Re: AY-3-8910 / YM2149 emulation
by on (#236652)
byuu wrote:
Which means that envelopes will take twice as long to step one phase on the YM, not half as long. And now that there's 32 phases instead of 16, that would effectively make it four times slower. It doesn't change anything to do with the tone/noise periods in YM mode. Even if you clock the YM externally twice as often to compensate, that's still going to be twice as slow, not twice as fast. You'd have to clock it eight times faster to actually make the envelopes run compatibly (save for the smoother steps) to the AY.

I can't tell you how to read whatever MAME is doing, but that's not what the YM does. What I said above is correct, I don't think it's possible that I was off by a factor of 2 or 4 for this. That would have been noticed.

Though maybe worth saying that YM does have two modes of operation, which are controlled by a pin (SEL in the datasheet). With the pin high, it's supposed to be backward compatible with the AY with 16 step envelopes (...I think. Have not personally tested/verified.) With the SEL pin low, it's what I described. This probably wouldn't be software switchable (though theoretically the host system could build a latch/register for it), but there are two different behaviours, which the emulator might require two modes for.

byuu wrote:
I also get conflicting answers on whether the YM2149 adds 15 additional steps (so 0-30 or 1-31) or 16. Internet forum posts say 15, MAME says the steps are doubled, which would be 16. Logically, it needs to be doubled, otherwise it's not going to be directly backward compatible.

It has 32 steps.

byuu wrote:
tepples wrote:
There are plenty of other test cases among what MSX, ZX Spectrum 128K, Atari ST, and FamiTracker composers have done.

Writing a small partial VGM music player may well be a good idea, yeah.

When I was testing 5B in NSFPlay I ended up translating a bunch of YM music into NSF form to give myself additional tests. (There's a couple of different AY/related formats besides VGM. Dunno which is easiest to parse.)
Re: AY-3-8910 / YM2149 emulation
by on (#236653)
Might also be worth consulting another source on this. Ay Emul is one I've often compared against, and it's been continually maintained for a long time and is still current.
https://bulba.untergrund.net/main_e.htm

It also has a related Vortex Tracker II project that builds a tracker on top of that emulator, which might be handy for making tests, or just playing with how the chips sound interactively.
Re: AY-3-8910 / YM2149 emulation
by on (#236654)
If you can emulate a Zilog Z80, you can play a couple of these "AY/related formats". (The Z80 is very similar to the SM83 core in the LR35902 coprocessor that higan already emulates for Super Game Boy, except Z80 has two more 16-bit pointer registers for offset addressing (IX and IY) and a second pair of AFBCDEHL, and HRAM instructions instead access a separate I/O bus. I see quite a few Z80 machines among platforms that higan emulates.)

KSS format originates from the MSX community. It's similar to NSF, but it uses a Z80 instead of a second-source MOS 6502. Both KSS and NSF support YM2149 SSG. KSS maps the YM2149 to out $A0 (command) and out $A1 (data); NSF maps it to sta $C000 (command) and sta $E000 (data). KSS supports Konami SCC; NSF supports Namco 163, whose capability is similar. KSS supports YM2413 (OPLL); NSF supports VRC7 (OPLL with different patch set and only 6 usable voices).

SGC, from the Coleco and Sega scene, is another Z80-driven NSF-style format. It supports OPLL and TI SN76489 (and Yamaha's clone thereof), but not the AY-3-8910. The SN76489 is a bit more limited; it has a 1/16 duty pulse instead of envelope bass, and it has three hardcoded noise frequencies that can play at the same time as tone instead of mixing noise and tone.
Re: AY-3-8910 / YM2149 emulation
by on (#236672)
Okay, to follow up on a few questions I didn't have an answer to, I wrote a test (envelope_5b), and have attached a recording if you'd like to see how I verified it.

The following is true of the 5B in my Gimmick! cartridge:

1. The frequencies of the tone and envelope are exactly as currently described on our wiki.

The test plays tones and envelope against matching APU tones, and the wavelengths match perfectly. (They use the same clock, after all.) If the APU frequencies are described correctly, therefore so are the 5B's.

2. Envelope period 0 acts as if the envelope's period is 1.

I don't think I'd tested this before, but using a value of 0 for the envelope's period does not halt it. It will instead behave exactly as if its period value was 1. (I have been told that the square wave tones do this as well, but the resulting frequency is above audible and I haven't verified with a scope.) NSFPlay currently gets this wrong.

Edit: noise does not halt on 0 either, and as far as I can tell from audio recordings noise period 0 acts as period 1. I should make some longer recordings of it later and verify it has the expected LFSR period.

3. Writing to register $0D does reset both components of the envelope's phase.

In the recording I see the first step of the envelope given its full duration every time. It is never shorted. (This is what I expected, and it is what NSFPlay currently does.)
Re: AY-3-8910 / YM2149 emulation
by on (#236679)
rainwarrior wrote:
I don't think I'd tested this before, but using a value of 0 for the envelope's period does not halt it. It will instead behave exactly as if its period value was 1. (I have been told that the square wave tones do this as well, but the resulting frequency is above audible and I haven't verified with a scope.)

Could you make a tone by bit banging the log volume of an ultrasonic (period 0 or 1) wave and then compare the volume of that tone to other volumes you can coax out of the chip?
Re: AY-3-8910 / YM2149 emulation
by on (#236691)
tepples wrote:
rainwarrior wrote:
I don't think I'd tested this before, but using a value of 0 for the envelope's period does not halt it. It will instead behave exactly as if its period value was 1. (I have been told that the square wave tones do this as well, but the resulting frequency is above audible and I haven't verified with a scope.)

Could you make a tone by bit banging the log volume of an ultrasonic (period 0 or 1) wave and then compare the volume of that tone to other volumes you can coax out of the chip?

You're going to have to explain a bit more about how this would measure its frequency. (I can't control its phase, if that's what you were thinking.)

I'm pretty sure that I've verified in the past that it doesn't halt, and that it makes output (when trying to see if it would reset phase). The unverified part is just the frequency.

The only reasonable idea I have for this frequency is that it's a duplicate of period 1 (56 kHz), which would be consistent with the envelope and noise and some other emulator implementations I've seen. 0 as a value doesn't work as a division, obviously. I don't know what's left to consider otherwise? It's above audible. It's not zero. So... it's either equivalent to 1 or 2, or it's something else out of left field.

If I could generate some other frequency close to it but slightly different maybe I could get it to heterodyne, but everything is dealing with divisions of the same clock... maybe $4011 has a chance there?

...or I could just measure it with a scope, probably. :P

Either way, if it isn't 1 the difference is probably going to be too trivial for most emulators. One inaudible result is probably as good as the next. :P
Re: AY-3-8910 / YM2149 emulation
by on (#236693)
If your soundcard is new enough to actually really support recording at 192kHz, you can probably still use it.
Re: AY-3-8910 / YM2149 emulation
by on (#236694)
rainwarrior wrote:
tepples wrote:
Could you make a tone by bit banging the log volume of an ultrasonic (period 0 or 1) wave and then compare the volume of that tone to other volumes you can coax out of the chip?

You're going to have to explain a bit more about how this would measure its frequency. (I can't control its phase, if that's what you were thinking.)

It's enough to demonstrate the distinction between halt and halfway, at least good enough for testing an emulator. Also try feeding a small amount of ultrasound into the video signal and seeing how big the additive interference bars are. (Horizontal sync in LD/SDTV is close to 15.7 kHz.)
Re: AY-3-8910 / YM2149 emulation
by on (#236699)
tepples wrote:
It's enough to demonstrate the distinction between halt and halfway, at least good enough for testing an emulator.

That part is already known, the only remaining detail is the exact frequency, which I have no good reason to suspect is anything but 56 kHz.

tepples wrote:
Also try feeding a small amount of ultrasound into the video signal and seeing how big the additive interference bars are. (Horizontal sync in LD/SDTV is close to 15.7 kHz.)

??? How does one "feed" ultrasound into the video signal?

lidnariq wrote:
If your soundcard is new enough to actually really support recording at 192kHz, you can probably still use it.

Sometimes I forget that I might have devices that do extra high frequencies like that. That's potentially a really good solution though, with a good effort vs. importance-of-knowing-this-particular-piece-of-trivia tradeoff. ;)
Re: AY-3-8910 / YM2149 emulation
by on (#236701)
Okay, so the Realtek sound device on my desktop computer indeed does 192 kHz. The high frequencies were very attenuated, but still enough was there to verify confidently that indeed tone period 0 is remapped to tone period 1.

I also verified that noise period 0 is remapped to noise period 1 while I was at it.

I also measured the repetition of noise at ~2.37s at 56 kHz ~= 2^17 so that should verify that the LFSR is 17 bit.

So... nothing interesting, just confirmation of things that had been strongly presumed true already. (Relevant tests were added to noise_5b.)
Re: AY-3-8910 / YM2149 emulation
by on (#236703)
Just one more confirmation: the LFSR described on the wiki is correct. 17 bits, taps at 13 and 16.

Attachment:
5b_LFSR_vs_NSFPlay.png
5b_LFSR_vs_NSFPlay.png [ 25.76 KiB | Viewed 8251 times ]

NSFPlay's current implemenation perfectly matches the recorded noise bit stream. (MAME's LFSR looks equivalent.)
Re: AY-3-8910 / YM2149 emulation
by on (#236705)
You can always underclock the relevant parts, most of these devices are static and won't mind running at significantly lower clocks.
Re: AY-3-8910 / YM2149 emulation
by on (#236708)
Yes, that's another theoretical option.

It would be an extremely disproportionate amount of electronics work to answer that question, though. Especially since it was mostly inconsequential, and we almost certainly already knew the answer. (...and a few posts up I confirmed that we did already have the answer.)

Like just using a scope would have been even easier than that. I probably would have done that if lidnariq hadn't pointed out that my sound device can do higher frequencies. Was really more about finding a time and place to slip a test for this in with the other stuff I was working on.


Anyhow, sorry to clutter up byuu's thread with that. I just wanted to confirm those last few things about the 5B that I hadn't gotten around to verifying yet. For the purposes of his question, I can say a lot of things with certainty about the 5B, and as far as I've seen it corresponds exactly to a YM2149F (with SEL low).

I haven't personally tested YM2149F or AY hardware at this point, but I've had a ton of second-hand confirmation of how they work, so my knowledge of them isn't totally based on emulators, but I hope I've made it clear what things I have explicit first-hand knowledge of, and what I only know from others' work. (I can back up everything on the wiki page about 5B audio.)

I might some time in the future set up a board to test a real AY and/or YM2149 (when resource/time/interest aligns), but at the moment I'm able to directly run tests on the 5B at least, and any lack of correspondence between that and a YM2149F would be a huge surprise. (I'm personally out of hanging questions about the 5B though, everything on my list to check is now verified.)
Re: AY-3-8910 / YM2149 emulation
by on (#236721)
Had to dredge up my last stupid topic on the subject to jog my memory, but it looks like you've crossed off all of my edge cases too - except for what happens when you write to period registers in-flight, to confirm the chip counts up like the MAME code says. But periods 0 and 1 being identical strongly suggests that's the case anyway.

(The issue I reported of some VGMs playing different pitches for noise period zero turned out to be a bug in the reference VGM player - it masks out the high bits of the noise period register after special-casing zero, resulting in a low pitch instead of a high pitch for VGMs that write garbage to those bits. But I overzealously masked them out before my debug printouts, so I saw two identical logs playing two different sounds. Herp.)
Re: AY-3-8910 / YM2149 emulation
by on (#236726)
Ah, yes I do believe you will see an immediate flip if you lower the period during a longer wave, prematurely ending that half-wave. I think I verified this when I was testing that 50/50 "phase reset" trick earlier, but it's a thing I can't find my records of if I actually did it. (I have a memory of doing it... but why didn't I post it anywhere if I did??)

Anyhow, will write a test for that and run it. I think the most sensible implementation of the counters is increment the phase and >= with the period value each tick. What NSFPlay is doing for this is almost certainly wrong.

(That reminds me I need to test what N163 does when you cut down a long wave too.)
Re: AY-3-8910 / YM2149 emulation
by on (#236733)
> Anyhow, sorry to clutter up byuu's thread with that.

Nah, go for it! Anything that improves emulation is great. Thanks for your hard work!

On my own front, I spent today greatly improving my Z80 core, and I have good audio from MSX games now, so I just need to find a good MSX1 game that uses the envelopes extensively.

> NSFPlay's current implemenation perfectly matches the recorded noise bit stream. (MAME's LFSR looks equivalent.)

I am surprised the chosen taps end up equivalent. I remember them being quite picky on the Neo Geo Pocket.

> I'm personally out of hanging questions about the 5B though, everything on my list to check is now verified.

Only thing I can think of at the moment is to get precise measurements of the 32 possible volume states, but it's not super important now that we're past the days of treating the volume as being linear, heheh.
Re: AY-3-8910 / YM2149 emulation
by on (#236734)
One more test ROM (phase_5b) to verify those two things, as well as another question about the envelope that I realized was open after re-reading what byuu was asking about its volumes.

1. When you change from a long period to a short one, the shorter period takes effect immediately. It does not wait for the next flip.

i.e. the "phase counts up, flips and resets when >= period" behaviour should be correct.

2. Volume 0 is indeed silent.

i.e. it's not like VRC7's logarithmic attenuation where maximum attenuation of a channel is just very quiet and not silent.

I was almost completely sure of both of those things, but hadn't ever properly documented a test of it.


3. Envelope volume 0 and 1 are both silent. Envelope (YM) 31 = tone (AY) volume 15.

Byuu had been asking whether the envelope volumes are in between, and after thinking about it I realized the ambiguity that was created by it having 32 steps.

The YM datasheet actually has a graph that depicts the voume 15 being equal to tone 31, but 0 was a bit ambiguous on that scrunched graph. Though we should probably always be suspicious of datasheet diagrams. ;)

So with the clarification that envelope volume 0 and 1 are the same, the rest seems to follow logically: every odd step of the 5-bit envelope output is equivalent to a 4-bit volume setting. 1=0, 3=1, 5=2... 27=13, 29=14, 31=15. The others are in between, and 0 is clamped back to 0.
Re: AY-3-8910 / YM2149 emulation
by on (#236735)
byuu wrote:
I am surprised the chosen taps end up equivalent.

They're the exact same taps / LFSR operation. It's just expressed slightly differently.

(I assume they came from the same information source. I don't remember if I had put that into NSFPlay after hearing about a decap, or whether it was there before...)

byuu wrote:
Only thing I can think of at the moment is to get precise measurements of the 32 possible volume states, but it's not super important now that we're past the days of treating the volume as being linear, heheh.

See the post above for the relationship between fine envelope and volume.

As far as exact measurements, 5B won't apply to YM because it has its own internal amplifier, and it depends on the total mix rather than the output of a single channel independently.

So... what I have measured seemed to match a model of the specified 1.5 db per step + the 5B's nonlinear curve very well. I couldn't say whether the AY/YM achieve a perfect 1.5db or if their logarithmic DAC has its own typical curve, but 1.5 db seemed close enough to accurately describe the 5B output (with the secondary amplifier characteristics on top). Every step measured pretty close to 3.0 dB before it hit the nonlinearity.

There were some graphs of this in my other thread here: 5B amplifier research (note that I incorrectly though it was a compressor at the time, and not just a nonlinear amp)
Re: AY-3-8910 / YM2149 emulation
by on (#236745)
Added one more set of tests to phase_5b. Just a verification that the tones, the noise, and envelope are never halted. All of them are continually active whether or not they're connected to an audible output.

Things that have been verified not to halt things:
  • Volume 0 does not halt tone or noise
  • Tone disable bit ($07) does not halt tone
  • Setting all 3 noise disable bits ($07) does not halt noise
  • Clearing all 3 channel volume envelope bits does not halt envelope
  • Period value of 0 does not halt any of these (treated as period 1 in all cases)

So basically just everything continues cycling at all times. I can't really think of any other stuff that might potentially halt something on here.

Again, was pretty sure, but it's common to see emulators halt things that aren't doing anything... I think that's a tempting implementation "optimization", but it's wrong here if you want accuracy. Though it's not really that big a deal, since envelope phase has an explicit reset, and noise/tone phase is anything but guaranteed with this thing.
Re: AY-3-8910 / YM2149 emulation
by on (#236752)
For those who don't know, there are two ways of implementing an LFSR: Fibonacci and Galois. You can convert from one form to the other without changing the output by simply reversing the order of the taps. (Note that the internal state is not equivalent, so you may have to do a bit of juggling to get it to start at the same point.)

For example, my implementation of the AY-3-8910 LFSR is:
Code:
   lsb = lfsr & 1;
   lfsr >>= 1;
   lfsr ^= (-lsb) & 0x12000;

You can easily verify if a given conversion produces the same output sequence by brute force.
Re: AY-3-8910 / YM2149 emulation
by on (#236782)
From the other thread:
Pokun wrote:
I have some stupid 5B questions I could not find answers for in the wiki or these threads.

1)
The Sunsoft 5B ties the /SEL pin low so that the internal divider is used and the input clock is halved. Does this mean that the clock is half of the CPU clock (NTSC: 1.789773 MHz, PAL: 1.662607 MHz), in other words 0.8948865 MHz and 0.8313035 MHz for NTSC and PAL respectively? So the formula to calculate the period value for a given frequency for an NTSC system is: "Period = 894886.5 / (32 * Frequency)" and not "Period = 1789773 / (32 * Frequency)" correct?

I also read somewhere that the NTSC clock is 1.7897725 MHz or even other values (might not affect the final period values though).


2)
Is it verified that the YM2149F SSG's smoother envelope ramping is because the internal divider is used? I've read about the different envelope levels in the SSG and AY before (here, there are some other interesting info here too like the unused bits that can store values) but there it didn't say that it only applies when using the divider, confusing me.
I know that some MSX computers that uses an SSG instead of an AY for its PSG uses the divider but also uses a faster clock (3.579545 MHz) so to maintain the MSX standard of 1.7897725 MHz for the PSG. I guess these systems benefits from the smoother envelope while still running at the proper speed for the PSG?


3)
What is the difference between YM2149 and YM2149F? I think I read somewhere that the 5B is an YM2149F but not an YM2149.


1/2. The formulas on the wiki are for the Famicom CPU clock of 1789772 Hz. The 32 given in those formulae are dividing that clock. The Famicom CPU clock is the clock that drives the chip, so it would never be any other value unless the Famicom's clock was modified.

The other day I tried to revise the description on the Wiki, since 5B doesn't have an option not to use SEL, I don't think the wiki's description of 5B should be encumbered with too much explanation of what SEL does (which I tried to pare back in my revision, hoping to be less confusing).

As I understand it, leaving SEL high or disconnect makes the YM into a backward-compatible AY. I believed it would switch the envelope into a 16-step mode compatible with the AY, but I don't have a YM to verify this with (yet). I may have been completely mistaken about that. Hypothetically, if SEL was high, this would mean the formulae on the wiki for tone and noise would use 16 instead of 32, and either the envelope formula would look the same (but only have 16 steps), or it would use 8 clocks per step instead of 16 and still have 32 total steps. I don't know which is true. For the actual 5B, the tone/noise frequency factor is 32, and 16 clocks per step for the envelope, as given.

So for the 5B, all I can say for certain is that it is in SEL-low mode, because the division by 2 is required for the pitch of the tone and noise. The YM2149 datasheet is a little bit vague about SEL and the envelope. It's possible that the envelope will tick every 8 clocks with SEL high, instead of every 16 like on the 5B (SEL low), and not what I had long assumed. If anyone knows the truth of that please let me know. Maybe you're right about it being a concession for later computers which were a lot faster than the first generation that was using AY and would rather drive the whole chip at half speed.

This is a case where looking back, I don't know where the source of my belief about what SEL high means for the envelope is. It's possible it was based on something I'd read or tried, or it's possible I made it up by accident or misunderstanding. So... all I can do is retract it for now, pending some more authorative information. (I am trying to be better about documenting my sources in the present.)

I can't comment on being able to read the registers, since the 5B has no read access to it.

3. I think YM2149F is just the full name for the "YM2149". I've not heard of any other versions (other than later clones with different numbering, YMZ294 etc.) The Yamaha datasheet just calls it YM2149 though.

E.g. if I search eBay for YM2149 all of them have an F.
Re: AY-3-8910 / YM2149 emulation
by on (#236784)
Thanks, wasn't sure which of the two threads to ask this in myself.

rainwarrior wrote:
The formulas on the wiki are for the Famicom CPU clock of 1789772 Hz. The 32 given in those formulae are dividing that clock.
Ah right, I forgot that the original formula in the data sheet was multiplying with 16 instead of 32. I guess I have to recalculate the MSX PSG note pitch table to use for the Famicom and PAL NES.

rainwarrior wrote:
The other day I tried to revise the description on the Wiki, since 5B doesn't have an option not to use SEL, I don't think the wiki's description of 5B should be encumbered with too much explanation of what SEL does (which I tried to pare back in my revision, hoping to be less confusing).
I think this is an important bit of information and should remain being mentioned somewhere on that wiki page though. Maybe in a section with additional notes if you think it unnecessarily encumbers the wiki page. It explains why the pitch formulae is different from the data sheet, and it's not something you can just check on pinout diagrams either.

rainwarrior wrote:
As I understand it, leaving SEL high or disconnect makes the YM into a backward-compatible AY.
I understood it as that the internal pull-up pulls it high even if it's disconnected so that it can replace an AY where the same pin (TEST 2 pin) is normally required to be disconnected, making it pin-compatible but not necessarily compatible on every little quirk. According to the article I linked, it sounds like the /SEL pin is just for making it possible to use a faster clock without changing anything else (maybe the faster clocks was cheaper?). The AY is rated for 2 MHz maximum while the SSG can use up to a 4 MHz clock.

byuu wrote:
Even if you clock the YM externally twice as often to compensate, that's still going to be twice as slow, not twice as fast. You'd have to clock it eight times faster to actually make the envelopes run compatibly (save for the smoother steps) to the AY.
Ah! If this is true, doubling the clock would not be enough, and the MSX computers that uses a 3.579545 MHz clock would run too slow and play the wrong pitch and envelope. Is this really right?

rainwarrior wrote:
I can't comment on being able to read the registers, since the 5B has no read access to it.
Oh I totally forgot about that! I guess the same can be said about the I/O ports that the MSX uses for joystick I/O and that the 5B doesn't seem to connect if they are even still in there at all.
Re: AY-3-8910 / YM2149 emulation
by on (#236785)
Here's a YM2149 C. I know of no differences with the various revisions, though.
https://imgur.com/a/8h9n7m3
Re: AY-3-8910 / YM2149 emulation
by on (#236787)
Pokun wrote:
rainwarrior wrote:
The formulas on the wiki are for the Famicom CPU clock of 1789772 Hz. The 32 given in those formulae are dividing that clock.

Ah right, I forgot that the original formula in the data sheet was multiplying with 16 instead of 32. I guess I have to recalculate the MSX PSG note pitch table to use for the Famicom and PAL NES.

The x32 is for the whole period, by the way. The actual operation needs to flip the square wave every 16 clocks. (The noise is every 32 clocks. The envelope is every 16.)

Pokun wrote:
rainwarrior wrote:
The other day I tried to revise the description on the Wiki, since 5B doesn't have an option not to use SEL, I don't think the wiki's description of 5B should be encumbered with too much explanation of what SEL does (which I tried to pare back in my revision, hoping to be less confusing).
I think this is an important bit of information and should remain being mentioned somewhere on that wiki page though. Maybe in a section with additional notes if you think it unnecessarily encumbers the wiki page. It explains why the pitch formulae is different from the data sheet, and it's not something you can just check on pinout diagrams either.

It's still mentioned, but not as many times. Previously there was a bunch of references to the AY and the clock being divided etc. and I think it was making it really hard to read. (Sorta like the Tau/Pi thing. Having to parse 2x in every formula probably doesn't help comprehension.)

Pokun wrote:
I understood it as that the internal pull-up pulls it high

Yes, high and NC are equivalent. That's described in the datasheet.

byuu wrote:
Here's a YM2149 C. I know of no differences with the various revisions, though.
https://imgur.com/a/8h9n7m3

Ah! Well that's interesting.
Re: AY-3-8910 / YM2149 emulation
by on (#236793)
rainwarrior wrote:
So for the 5B, all I can say for certain is that it is in SEL-low mode, because the division by 2 is required for the pitch of the tone and noise. The YM2149 datasheet is a little bit vague about SEL and the envelope. It's possible that the envelope will tick every 8 clocks with SEL high, instead of every 16 like on the 5B (SEL low), and not what I had long assumed. If anyone knows the truth of that please let me know. Maybe you're right about it being a concession for later computers which were a lot faster than the first generation that was using AY and would rather drive the whole chip at half speed.
I mean, no-where in the PDF does it claim that SEL does anything other than add a prescaler.

But I do think it's interesting that the "normalized voltage" graph in the datasheet strongly insinuates that the envelope has a nonzero magnitude when it's at 1/31, while your measurement on the 5B has found that to not be true.
Re: AY-3-8910 / YM2149 emulation
by on (#236795)
lidnariq wrote:
I mean, no-where in the PDF does it claim that SEL does anything other than add a prescaler.

Yeah, I couldn't find anything either. I don't know where I got the notion that it only applied to the tone/noise, and the more I look for it the more I'm thinking it's unlikely that it's anything more than my own fabrication/misunderstanding.

lidnariq wrote:
But I do think it's interesting that the "normalized voltage" graph in the datasheet strongly insinuates that the envelope has a nonzero magnitude when it's at 1/31, while your measurement on the 5B has found that to not be true.

I don't think the insinuation is strong. There's a lot of noise, and it's scanned at an angle, putting an unfortunate 1 pixel step up right in the middle of the value you're trying to interpret. (At any rate even if it were clear, it was still worth verifying.)
Re: AY-3-8910 / YM2149 emulation
by on (#236796)
Hmm. An AY can be bought for much cheaper ($1.45 @ ≥100pcs) than an YM249F ($2.49 @ ≥100pcs). A d-flip flop to halve the clock could be had for a 0.1-0.3 cents*.

32 envelope steps notwithstanding, that might be a good approach to make sunsoft 5b-like boards available for homebrew at a decent price.


*Actually, a quad d-flop (or octal for that matter) would cost about 0.3 cents so you might even have a cpu clock divider and get an octave divided pseudo-channel from each of the analog outputs for free. Well, i'd need a cheap way to gate them. Probably fixed R values to mix them lower than the source, too.
Re: AY-3-8910 / YM2149 emulation
by on (#236797)
Well with a CPLD at your disposal I don't think you'd even need a separate component for a divider?

InfiniteNESLives has offered a 5B reproduction board for a long time now:
http://www.infiniteneslives.com/nessupplies.php#FME7

I think they're using an AY. Info here:
https://forums.nesdev.com/viewtopic.php?f=9&t=8808&start=75#p100622
Re: AY-3-8910 / YM2149 emulation
by on (#236798)
I was maybe thinking more an UxROM-style mapper (ie lower in price to begin with). The chip/no chip margin seems to be closer together, too, from my comparison at chips available from utsource. Purpose being putting out a music cartridge to begin with, sort of to demo it. But i'm completely new to digital circuits so i might be missing something that wouldn't make it worthwhile.
Re: AY-3-8910 / YM2149 emulation
by on (#236800)
Years ago, Zzo38 invented a mapper concept for just using a AY-3-8910 (with the 16 GPIO pins) - nesdevwiki:User:Zzo38/Mapper A. GNROM class, but its extreme minimalism - it's hidden behind the PPU - cripples it.

MAME's documentation on the AY-3-8910 says that the "TEST 2" pin - same as the divider select on the YM2149 - is apparently another active-high chip enable. Two active-high chip enables isn't quite enough to map it to a place that doesn't overlap with ROM, though.
Re: AY-3-8910 / YM2149 emulation
by on (#236808)
rainwarrior wrote:
Pokun wrote:
rainwarrior wrote:
The formulas on the wiki are for the Famicom CPU clock of 1789772 Hz. The 32 given in those formulae are dividing that clock.

Ah right, I forgot that the original formula in the data sheet was multiplying with 16 instead of 32. I guess I have to recalculate the MSX PSG note pitch table to use for the Famicom and PAL NES.

The x32 is for the whole period, by the way. The actual operation needs to flip the square wave every 16 clocks. (The noise is every 32 clocks. The envelope is every 16.)
What do you mean flip every 16 clocks? "Table 5.1" here is not enough for square (except that it is for the MSX clock)? Do I need to do something else than just make a table of note pitches to feed it with?

rainwarrior wrote:
It's still mentioned, but not as many times. Previously there was a bunch of references to the AY and the clock being divided etc. and I think it was making it really hard to read. (Sorta like the Tau/Pi thing. Having to parse 2x in every formula probably doesn't help comprehension.)
I see, fair enough.

byuu wrote:
Here's a YM2149 C. I know of no differences with the various revisions, though.
https://imgur.com/a/8h9n7m3
So the F is a revision number after all. I found the post that made me think that it was an important point that the 5B contained an F version. Reading it again I see that it was not about the F but about the YM. It was an important point that it's an YM rather than an AY.

FrankenGraphics wrote:
Hmm. An AY can be bought for much cheaper ($1.45 @ ≥100pcs) than an YM249F ($2.49 @ ≥100pcs). A d-flip flop to halve the clock could be had for a 0.1-0.3 cents*.

32 envelope steps notwithstanding, that might be a good approach to make sunsoft 5b-like boards available for homebrew at a decent price.


*Actually, a quad d-flop (or octal for that matter) would cost about 0.3 cents so you might even have a cpu clock divider and get an octave divided pseudo-channel from each of the analog outputs for free. Well, i'd need a cheap way to gate them. Probably fixed R values to mix them lower than the source, too.
I didn't know these were in production anymore? I know you can find them on ebay and whatnot but I assumed they are NOS or knockoffs. Someone also said they can be bad chips as well.

rainwarrior wrote:
Well with a CPLD at your disposal I don't think you'd even need a separate component for a divider?

InfiniteNESLives has offered a 5B reproduction board for a long time now:
http://www.infiniteneslives.com/nessupplies.php#FME7

I think they're using an AY. Info here:
https://forums.nesdev.com/viewtopic.php?f=9&t=8808&start=75#p100622
I just wish there was an 60-pin option though so that it can actually be used with a Famicom.

There's also this thing.
Re: AY-3-8910 / YM2149 emulation
by on (#236813)
pokun wrote:
I didn't know these were in production anymore?

They may be from time to time. the ay-3 machine was popular in various applications, including casino slot machines. You may use it in anything that beeps. While the envelopes aren't too musical seen as volume envelopes, they come in handy when you want a beeper have a couple of different signals.

The vendor i'm looking at (utsource) has 134.500 units in stock (!!!) which means they've likely picked up the rest of a big factory order. But utsource simply buy up stocks of components from multiple sources when they can be had for cheap, so you can't really source it. Just guess at the label and if you can spot solder marks, i guess.

I don't think they're knockoffs, and if they were, there's no difference either way. Someone in an FB group bought the same item and they worked just fine. :)

Quote:
Someone also said they can be bad chips as well.

They're not bad per definition, but some NOS parts may have the factory set identifier be non-zero, which you'll want to verify before soldering a whole batch onto boards. The preset is 0 unless requested by some customer (usually for keeping several devices on the same address).


Actually, it seems you can get 100 pcs of AY-3 for $0.975 / piece and YM:s for $1.53, via some fluctuating wholesale price option through the same vendor.
At under a dollar, that would make a lot of difference for homebrew viability. :O
Re: AY-3-8910 / YM2149 emulation
by on (#236815)
Pokun wrote:
rainwarrior wrote:
The x32 is for the whole period, by the way. The actual operation needs to flip the square wave every 16 clocks. (The noise is every 32 clocks. The envelope is every 16.)
What do you mean flip every 16 clocks?

I mean the 5B's square generator operates by incrementing a counter every 16 clocks. After increment, if the counter is >= the period register value, it toggles between high and low.

That means the signal changes every 16 clocks x the period register value. An entire square wave, on the other hand, requires two changes to make a complete wave. Half the wave will be up, half will be down. So the entire wave will take 32 clocks x the period register for the whole wave.

It's a question of whether you are trying to calculate the frequency of the waveform produced (probably what you want to know if trying to make music with it), or trying to understand how often it needs to update the signal (probably what you want to know if trying to write an emulator).

For the AY (or YM with SEL high/nc) it's every 8 clocks instead.

Pokun wrote:
"Table 5.1" here is not enough for square (except that it is for the MSX clock)? Do I need to do something else than just make a table of note pitches to feed it with?

What you need depends on what you want to do.

That table of pitches is relative to the clock of the MSX. If the clock is faster or slower than your target, the pitches will be higher or lower accordingly, but as a musical scale they will still be relatively correct.

From earlier...
Pokun wrote:
Ah! If this is true, doubling the clock would not be enough, and the MSX computers that uses a 3.579545 MHz clock would run too slow and play the wrong pitch and envelope. Is this really right?

If the clock is 2x the NES clock, and it's an AY or SEL high/nc YM (another 2x relative to 5B), then its frequencies will be 4x what the 5B does. Two octaves up.

If you want to play some music on both devices at the same pitch, you could just shift the table over by 2 octaves I guess? One will be able to go 2 octaves lower, though, and the other will have more precision in its high frequencies.

For more minor changes in frequency, you could probably usually just leave the playback as-is, like 2MHz vs 1.8MHz will be a different pitch but all the tones will still be correct relative to each other. A change in octave is pretty big, but a smaller change in pitch doesn't normally affect anything about the music negatively, unless you're trying to stay in tune with a second audio source.


On a different line of thinking though... and this is kind of beyond the scope of what I'd want to try and emulate but I wonder if the chip updates all channels at once in a synchronized way, or if they're staggered.

The AY updates tone every 8 clocks, noise every 16 clocks, and envelope every 16 clocks. I wonder if that indicates a cycle of 2 clocks per tone, then 2 clocks per noise/envelope alternating? A repeating pattern of Tone 0, Tone 1, Tone 2, Noise, Tone 0, Tone 1, Tone 2, Envelope?

On the YM, though, the envelope ticks twice as often, so this idea breaks down there. I guess instead of alternating it might also tick the envelope Envelope a second time when the Noise is updated...

Anyway, that's just speculation. I wouldn't really want to put that knowledge to use in an emulator. Since phase can't be read back from the chip (whether or not its registers are readable, it's not on any register), software couldn't try to get in sync with it anyway, and the difference is entirely above audio samplerates.
Re: AY-3-8910 / YM2149 emulation
by on (#236846)
FrankenGraphics wrote:
They may be from time to time. the ay-3 machine was popular in various applications, including casino slot machines. You may use it in anything that beeps. While the envelopes aren't too musical seen as volume envelopes, they come in handy when you want a beeper have a couple of different signals.
I see, I guess they are useful if you need something a bit more advanced than a buzzer and the hardware envelopes lets you get around having to program a sophisticated driver for it.

FrankenGraphics wrote:
I don't think they're knockoffs, and if they were, there's no difference either way. Someone in an FB group bought the same item and they worked just fine. :)
I hope you are right. I might order an SSG (or maybe an AY) just to play around with. Not sure what I need besides a microcontroller and a speaker though. An amplifier I guess.

rainwarrior wrote:
I mean the 5B's square generator operates by incrementing a counter every 16 clocks. After increment, if the counter is >= the period register value, it toggles between high and low.

That means the signal changes every 16 clocks x the period register value. An entire square wave, on the other hand, requires two changes to make a complete wave. Half the wave will be up, half will be down. So the entire wave will take 32 clocks x the period register for the whole wave.

It's a question of whether you are trying to calculate the frequency of the waveform produced (probably what you want to know if trying to make music with it), or trying to understand how often it needs to update the signal (probably what you want to know if trying to write an emulator).

For the AY (or YM with SEL high/nc) it's every 8 clocks instead.
Oh I see. My goal for now is to program it and make sounds and music come out of it and eventually include it in my Famicom sound driver. So I'm calculating the period values needed for each frequency in a musical note system to use as a lookup table in the sound driver.

rainwarrior wrote:
That table of pitches is relative to the clock of the MSX. If the clock is faster or slower than your target, the pitches will be higher or lower accordingly, but as a musical scale they will still be relatively correct.
Yeah I figured since the MSX clock is exactly the same as the NTSC Famicom, only that the clock is halved for the 5B, I can use the same note pitch table as for MSX. It's just that the square tone on the Famicom's 5B will be one octave lower than on the MSX's PSG for the same reason the Famicom's APU Square is one octave lower (as in lower pitch) than the APU Triangle.
I noticed that the note pitch table I stole from Konamiman (the above link) seems to be a bit off though so I'll just recalculate the note pitches anyway. Besides I need to recalculate them for PAL NES (PAL MSX computers use the same clock as the NTSC computers so the pitch is same on both).

rainwarrior wrote:
If the clock is 2x the NES clock, and it's an AY or SEL high/nc YM (another 2x relative to 5B), then its frequencies will be 4x what the 5B does. Two octaves up.
MSX computers use the same clock as Famicom and the AY as the PSG to follow the MSX computer standard definition. Some later manufacturers used the YM as the PSG for legal reasons and also used the doubled clock and halving it by setting the /SEL pin low. So the PSG should just run at twice the speed of the 5B and therefore the PSG is one octave up if I understand everything right.
Re: AY-3-8910 / YM2149 emulation
by on (#236848)
Pokun wrote:
I might order an SSG (or maybe an AY) just to play around with. Not sure what I need besides a microcontroller and a speaker though. An amplifier I guess.
The similar SN764(89/94/96) is even cheaper than the used/NOS AYs are. Only 10 bits of tuning, no hardware envelopes (but I think they're more useful as another voice instead of actually as envelope control).

Little-Scale built a simple board with a Teensy (ARM, Arduino) and eight of these.

You can just use a standard commercial amplifier.
Re: AY-3-8910 / YM2149 emulation
by on (#236849)
Yeah the AY3 is coming in hot at 1vpp per channel, each about double the voltage of consumer audio levels for a mix. For experimenting I'd sum them at the virtual ground of an inverting op amp pair and use that to tone the volume down while at it. you may also want a potentiometer in there, but fixed resistors could do, and regulate volume on your speakers.