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 ?