New Documentation: An authoritative reference on the YM2612

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

Moderator: KanedaFr

User avatar
Sauraen
Interested
Posts: 40
Joined: Sat Sep 19, 2015 2:44 pm
Contact:

Re: New Documentation: An authoritative reference on the YM2612

Postby Sauraen » Sun Aug 14, 2016 3:40 am

GManiac wrote:
operators are shifted arithmetically (not logically) by 5 bits



The top 9 bits of the 14-bit operator output are sent to the accumulator, which adds the operators within one voice. So there's no question of shifting--it just takes the top 9 bits and discards the bottom 5. Only on PC where you are actually running these calculations in a 32-bit register does it matter which kind of shift you're using. The correct one here would indeed be an arithmetic shift, though depending on your implementation of the saturation (clipping) when operators are added, it may not matter. Remember, these are signed numbers, not unsigned numbers with an extra sign bit.

Any emulator which is outputting 14-bit audio is not authentic, simply because the YM2612 DAC is 9 bit.

The ladder effect is a result of the resistor string DAC--when the MSB is 0 and the string is between VDD and the midpoint, it pulls up the midpoint voltage slightly, and vice versa when the MSB is 1 and the string is between GND and the midpoint. Basically, the two halves of the range have decent linearity in themselves, but they don't quite meet in the middle. A decent way of emulating this would be to offset negative values by a constant amount (which it sounds like you're doing). Determining what that amount is has probably already been done quite well by someone with a good scope, but I can't do an effective job of that just by reading the die. :)

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

Re: New Documentation: An authoritative reference on the YM2612

Postby Eke » Mon Aug 15, 2016 2:15 pm

GManiac wrote:Can anyone add this "feature" to existing emulators / players plugins? Usually I listen music via Maxim's plugin.


I am emulating the 9-bit DAC (although not 100% accurately for all algorithms since bits 0-4 masking is done after the operator 14-bit outputs have been eventually summed while it should be done on each operator carrier).

Problem with emulating the "ladder effect" is that no precise measures/tests have been made on DAC output to actually emulate it accurately, we just know that an "offset" must be added for negative values but I'm still not sure how large it should be and to which levels it should be applied. So I was actually waiting to be able to accurately measure the voltage on MOL/MOR for each 512 DAC levels before implementing something.

I guess that we could use the recently discovered 9th bit for Ch6 DAC mode in test register $2C (bit 3) to write a test ROM that outputs all 512 levels by muting all channels except Ch6 and writing directly to DAC register.

jotego
Newbie
Posts: 5
Joined: Sat Jan 28, 2017 8:30 am
Location: Valencia (Spain)
Contact:

Re: New Documentation: An authoritative reference on the YM2612

Postby jotego » Sun Feb 26, 2017 8:30 pm

Hi all,

I have finished reading the full thread and I have enjoyed every bit of it. Let me add to it now.

First, I am working on a verilog module that replicates in hardware the YM2612/YM3438 to a very precise level. The internal operation is likely to be pretty much the same as the original. Everything runs in parallel, with pipelines, circular shift registers and stuff. I had actually developed this architecture when I did the YM2151 clone (the JT51). Then I was asked to do the YM2612, found Sauraen's and Nemesis' findings and was just very glad to see the convergence between JT51 architecture and actual hardware. On this new clone, the JT12, I am getting even closer. BTW, I also want to say thank you to HardWareMan for taking the die pictures. I have seen contributions on this thread of many others, thank to all of you.

JT12 is GPL. You can have a look here. The folder hdl contains actual verilog files.

Note that the work is not complete yet, though it is probably just a couple of weeks away from completition. You can check the issues page to see then pending tasks. You can also see it working with the current status here. It is running on a MiST FPGA board.

Many of the things discussed in the thread make a lot of sense when you take a look at the hardware implementation in the verilog files. Aspects such as the duration of the BUSY signal, or EG behaviour are much clearer when look at from the eyes of a digital design, rather than software. By the way, the operator implementation (jt12_op.v) is pretty much a copy of Sauraen's VHDL file. Although converted to verilog and with style modifications, in essence, it is the same thing.

Second, I have a blunt offer to people working on emulators. I think it might make sense to use Verilator in order to obtain a C++ model of the Verilog files, which is cycle-clock accurate. With that model you do not need an emulator, you just get the actual chip running inside your software! Although this might sound like a slow solution, I have seen some YM2612 emulator work which is so high level in terms of objects, abstraction layers, interfaces and stuff that it cannot be fast either!

Third, let me make a couple of comments to things that were said at some point in the thread:

HardWareMan wrote:
TmEE co.(TM) wrote:I'm not very sure but I think the 2 big zig zags (capacitors ?) right next to each other under DAC part are part of channel switching.

Yeah, it could be capacitors. Or it could be power current amplifier. I'm not sure for now. But, there are lot of capacitors, that interconnect some power rails on die. Look at bidirectional pin:
Image
And analog output pin:
Image
Analog output has only one transistor, wich connected to AVCC. Thus, analog output can only source current, not sink. External resistor required.

And here those "zig-zags". Definitely this is a two transistors with some control circuit.
Image


I am almost certain that these zig-zags are ESD protection structures. These are compulsory protection circuits that must be placed next to the pads of a silicon die.

Eke wrote:
① Confirm the connection (algorithm) data. If these data are zero (0) through three (3), then the waveform does not distort, even at TL=0.

② When con. = 4, set the TL of the second individual carrier so that it will be negative six (-6) [dB] or more.

③ When con. = 5 or 6, set the TL of the third individual carrier so that it will be negative nine and one half (-9.5) [dB] or more.

④ When con. = 7, set all TL’s to negative twelve (-12) or more.


This tells about the accumulator behaviour and lack of clamping and resolution. In some aspects, these chips were too cheap :(

Stef wrote:Thanks Sauraen for the precious and detailed informations ! The internal organization in shift register explain indeed the volatile BUSY time. I guess it will be complicated to find a good formula to calculate a perfect timing. Anyway because of this unpredictable aspect almost sound driver always pool the busy flag because writing the YM registers.


The YM3438 application notes PDF does contain a table with the length of BUSY time depending on the register. I have to compare it to my implementation (jt12_reg.v) but at the end we are doing the same thing: we have a circular shift register and we have to wait for the selected register to come out of it so we can insert the new value in its place. Note that in my implementation, the old value comes out and the new value in, so it takes a full 24-operator cycle to get the new value take effect. It is possible to discard the old value but it requires more logic, and if they were mean on the DAC, which is more important, I do not think they will extra logic for this.

Well, thanks for reading this long post. I will keep working on JT12 and let you know when completed.

User avatar
HardWareMan
Very interested
Posts: 647
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Re: New Documentation: An authoritative reference on the YM2612

Postby HardWareMan » Mon Feb 27, 2017 2:04 am

Hi and welcome!
jotego wrote:I am almost certain that these zig-zags are ESD protection structures. These are compulsory protection circuits that must be placed next to the pads of a silicon die.

Image
A lot of time is passed. Now I sure that analog output have only one transistor that can only source current. You may clearly see it.
Image
As for about this one's, it is strong buffer for clock. It feeds from input logic of CLK pin and have some kind divider or counter (notice: with 6 steps). Also there is some kind shift register right below it. I believe this is main sync circuit, that set starts of any process inside (such start of channel and operator in it).

Anyway, I can't be 100% sure until I make better die shots.

User avatar
Sauraen
Interested
Posts: 40
Joined: Sat Sep 19, 2015 2:44 pm
Contact:

Re: New Documentation: An authoritative reference on the YM2612

Postby Sauraen » Mon Feb 27, 2017 9:08 pm

HardWareMan is correct, those are large drive transistors, not ESD protection devices. The one between OUT and AVCC is the driver for the output pin, and the two in a pair near the "Control" label are indeed for driving the positive and negative clock lines throughout the chip. These are labeled in my annotated die shot with the blocks labeled.

The only sort of protection I've seen on the chip is some sort of resistor on the digital input pins. The YM2612 isn't CMOS so large protection transistors (really diodes) weren't required.

jotego
Newbie
Posts: 5
Joined: Sat Jan 28, 2017 8:30 am
Location: Valencia (Spain)
Contact:

Re: New Documentation: An authoritative reference on the YM2612

Postby jotego » Wed Mar 01, 2017 11:59 am

Sauraen wrote:The only sort of protection I've seen on the chip is some sort of resistor on the digital input pins. The YM2612 isn't CMOS so large protection transistors (really diodes) weren't required.


I see. ESD really became popular with CMOS processes.

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

Re: New Documentation: An authoritative reference on the YM2612

Postby Eke » Tue Mar 14, 2017 2:42 pm

Sauraen wrote: I would go with the LFO, but honestly I haven't found it yet.


Hi,

Recently doing some correction in YM2612 core, I was wondering if you ever figured out the LFO and how it works exactly, especially regarding Phase Modulation.

Some questions I have (based on current implementations):

1) how is LFO PM value calculated ?

MAME implementation uses an offset table which takes LFO step (0-31) and LFO depth (0-7) as X/Y then use the seven upper bits of the FNUM value as weights to compute an offset value :

for (i = 4 to 10) LFO_PM += (FNUM & (1<<i)) ? ((LFO_TAB[step][depth] << 1) >> (10 - i)) : 0

Exodus use similar table but uses the whole FNUM range (bits 0-10) to calculate LFO PM value and does the bitweight shifting differently:

for (i = 0 to 10) LFO_PM += (FNUM & (1<<i)) ? ((LFO_TAB[step][depth] << i) : 0
LFO_PM >> 9

See also this discussion: viewtopic.php?f=24&t=386&start=480

The difference is that MAME implementation right-shifts LFO table value for each weighted bit BEFORE adding them while Exodus first left-shift all table value, add them and THEN performs right-shift on the final sum. Result is similar but MAME implementation therefore limits itself to 7 upper bits (since right-shifted table values will always be 0 starting from bit3) while Exodus implementation provides additional bits of precision.

From hardware point of view, both implementations seem plausible so it's hard to figure which one is correct.

2) how and where exactly is LFO PM value applied ?

MAME applies the offset value on the whole BLOCK+FNUM register value, then recalculate BLOCK (which has been possibly impacted by LFO PM), Key-Code (which depends on FNUM and BLOCK) and Detune (which depends on Key Code) values before doing normal PG process on modified FNUM value (BLOCK shift, DETUNE add, etc). It's also notable that there is an additional bit of precision introduced here for some unknown reason (offset value is twice the one used in Exodus but bit0 is not used when adding to BLOCK/FNUM value and is instead injected during BLOCK shift).

Exodus directly applies the offset value on the FNUM value then recalculate Key-Code and Detune values before doing normal PG process.

Note that, while Key Code is recalculated in both implementations (and is therefore impacted by LFO PM) , Key Scale and EG rates (which depend on Key code value) are never recalculated and therefore not impacted by LFO PM.

From an hardware point of view, it seems odd that BLOCK shift value would be impacted, same goes for Key Code if Key Scale is not (unless key code is recalculated by both EG and PG blocks !). I guess it would be a matter of figuring where the LFO PM adder takes place, what it takes as inputs, if it is internal or external to PM block and where its output goes).

User avatar
Sauraen
Interested
Posts: 40
Joined: Sat Sep 19, 2015 2:44 pm
Contact:

Re: New Documentation: An authoritative reference on the YM2612

Postby Sauraen » Tue Mar 14, 2017 7:37 pm

Eke wrote:I was wondering if you ever figured out the LFO and how it works exactly, especially regarding Phase Modulation.


I never did a full reverse engineering of it, but here's what I have (from private messages to jotego):

Sauraen wrote:The LFO seems to have 3 sections:

[*] 7-bit linear prescaler. The test bit 0x21:1 goes into what looks like the carry-in or something similar; it could go into the reset, I can't quite tell with more detailed analysis. The 7-bit output (plus maybe carry-out) gets logiced together into 8 lines (evidently perform "== N" with N hardcoded for each line), and these go into a little selector unit which is also fed by the LFO Speed and LFO Enable bits. I can't quite see the output of this, but I do see there's some sort of feedback to the prescaler's reset. So this clearly seems like a divide-by-N prescaler. I can try to read the eight N's for you if you want, but you should be able to reverse engineer them from knowing what the LFO speeds are.
[*] 7-bit linear counter, with an 8-bit unit after the output (possibly inverts the output after each cycle to make a triangle wave?). Bits 1:6 of the output of this go to the EG, and stick into its pipeline at the same place where the LFO->Amplitude two bits go. (Elsewhere the operator LFO enable flag simply forces these two bits to zero for operators not affected by the LFO.) Some modified version of the 8-bit signal between the counter and the inverter unit thing goes to the third unit of the LFO.
[*] Highly complex unit which modifies the frequency data as it goes from the channel registers to the PG. The block bits bypass this, but all the frequency bits get modified by it. There's a bitslice portion corresponding to bits 0:6, and then what appears to be the same logic folded over to process bits 7:A. But the interesting part is that bits 4:A of the frequency data go into the bitslices 0:6. That is, the bitslice unit for bit 0 has bit 0 enter at the middle and leave (to the PG) at the bottom. But it also has bit 4 enter at the top. And so on through bit 6 having bit A enter at the top. It looks like the top portion is some sort of shifter for bits 4:A--the wires go diagonally so that bit 4 only gets used once, bit 5 gets used in bitslice 1 and 0, bit 6 gets used in bitslices 2:0, and so on so that bit A gets used in all of them. I'm guessing this whole unit is basically a multiplier, multiplying bits 4:A of the frequency value by bits 0:7 of the LFO state, and then adding the result to bits 0:6 of the frequency value (with carry up to the higher bits). It looks like, between the multiplied output and the adder, there's another shifter whose value is based on the the LFO->Frequency bits. But it looks like it's a bit more complex than I'm describing.


The upshot is that the LFO is definitely doing frequency modulation, not phase modulation.

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

Re: New Documentation: An authoritative reference on the YM2612

Postby Eke » Wed Mar 15, 2017 1:18 pm

Sauraen wrote:I never did a full reverse engineering of it, but here's what I have (from private messages to jotego):


Thanks, it still helps confirming a few stuff

[*] 7-bit linear prescaler. The test bit 0x21:1 goes into what looks like the carry-in or something similar; it could go into the reset, I can't quite tell with more detailed analysis. The 7-bit output (plus maybe carry-out) gets logiced together into 8 lines (evidently perform "== N" with N hardcoded for each line), and these go into a little selector unit which is also fed by the LFO Speed and LFO Enable bits. I can't quite see the output of this, but I do see there's some sort of feedback to the prescaler's reset. So this clearly seems like a divide-by-N prescaler.


This would be LFO clock generator which is divided from internal clock based on LFO speed bits. Presumably, LFO enable bit halts the LFO clock generator as well as Test register 0x21 bit1 (similarly to YM2151 test register described here: to http://www.msxarchive.nl/pub/msx/mirror ... ym2151.txt)

I can try to read the eight N's for you if you want, but you should be able to reverse engineer them from knowing what the LFO speeds are.


According to MAME implementation, values are {108, 77, 71, 67, 62, 44, 8, 5} "sample clocks" where sample clock is internal clock / 24.
From the value specified in YM2612 doc, assuming a 8Mhz input clock and 128 LFO clocks per period, 3.98 hz for speed 0 would give 8000000/6/24/3.98/128 = 109 samples between each LFO clock, which is one above MAME specified value. All other speed values give also one additional sample value (72.2 for speed 7 gives 8000000/6/24/72.2/128 = 6 samples)

[*] 7-bit linear counter, with an 8-bit unit after the output (possibly inverts the output after each cycle to make a triangle wave?). Bits 1:6 of the output of this go to the EG, and stick into its pipeline at the same place where the LFO->Amplitude two bits go. (Elsewhere the operator LFO enable flag simply forces these two bits to zero for operators not affected by the LFO.)


That would be 7-bit LFO step counter (which is incremented on each LFO clock and reset when LFO enable bit is cleared). LFO AM value indeed corresponds to LFO step counter bits 0:5 shifted left by one and XORed with inversion of bit 6 (to generate an inverted triangle waveform)

LFO AM sensitivity (2 bits) indicates to EG how much LFO AM value is shifted before adding to EG output


Some modified version of the 8-bit signal between the counter and the inverter unit thing goes to the third unit of the LFO.


This would be LFO PM step (0-31), which takes bits 2:6 of LFO step counter (0-127) and goes to LFO PM calcuation unit you describe below

[*] Highly complex unit which modifies the frequency data as it goes from the channel registers to the PG. The block bits bypass this, but all the frequency bits get modified by it.


This would be LFO PM calculation unit and this would confirm BLOCK calculation is not affected by LFO PM.
Any chance you have located the "Key Code" calculation unit ? This would be a simple unit with a few OR/AND/NOT gates, taking highest 4 bits of FNUM value as inputs and outputting a 2-bit value (LSB of 5-bit Key Code value, MSB being BLOCK bits). Since this value is used by both EG and PG unit, it's more likely to be external to these units. Whether it interfaces with original frequency bits or the output of LFO PM calculation would indicate if LFO PM really has an impact on Detune value (since it depends on Key code value) as it is currently done in emulator implementations and if EG rates should be impacted as well.

There's a bitslice portion corresponding to bits 0:6, and then what appears to be the same logic folded over to process bits 7:A. But the interesting part is that bits 4:A of the frequency data go into the bitslices 0:6. That is, the bitslice unit for bit 0 has bit 0 enter at the middle and leave (to the PG) at the bottom. But it also has bit 4 enter at the top. And so on through bit 6 having bit A enter at the top. It looks like the top portion is some sort of shifter for bits 4:A--the wires go diagonally so that bit 4 only gets used once, bit 5 gets used in bitslice 1 and 0, bit 6 gets used in bitslices 2:0, and so on so that bit A gets used in all of them. I'm guessing this whole unit is basically a multiplier, multiplying bits 4:A of the frequency value by bits 0:7 of the LFO state, and then adding the result to bits 0:6 of the frequency value (with carry up to the higher bits). It looks like, between the multiplied output and the adder, there's another shifter whose value is based on the the LFO->Frequency bits. But it looks like it's a bit more complex than I'm describing.


This seems to match with MAME implementation (more than Exodus implementation). If we look at LFO PM offset table used in MAME we can see the max offset value per FNUM bit is 96 (0x60) for when bit 10 is set so this would only require 7-bit addition/substraction (hence bitslices 0 to 6) with carry propagating on higher bits. For following FNUM bits, LFO PM offset are shifted by one, so max value would be :
0x30 (6-bits i.e bitslices 0 to 5) for bit 9 ,
0x18 (5-bits i.e bitslices 0 to 4) for bit 8,
... ,
0x03 (2-bits i.e bitslices 0 & 1) for bit 5
and finally 0x01 (1-bit i.e bitslice 0 only) for bit 4.

I just don't understand the extra bit precision added in MAME implementation: from the chip hardware point of view, this would mean that this unit would takes 11 bits of original Frequency (FNUM) value but output 12 bits and that frequency input of PG unit is actually 12 bit or more, not 11 (with MSBs corresponding to original FNUM and LSB being forced to zero when no LFO modulation is applied) .
Another solution is that LFO offset value is calculated as 7 bit (6.1 fixed point) value and the lowest bit is discarded when adding to FNUM value.
Would it be possible to confirm or deny this from looking at the die shot ?


Return to “Sound”

Who is online

Users browsing this forum: No registered users and 2 guests