iki.fi/o

Adlib / OPL2 / YM3812

This page is devoted to the classic PC soundcard, Adlib, and compatibles.

Reverse-engineering report

2008-04-20

Me and Matthew Gambrell reverse-engineered the YM3812/YMF262 ROM tables. These are the pictures we took:

ymf262ym3812ym3812_rom3_2ym3812_rom1_explainym3812_rom1_1 v2bymf262_rom1ymf262_idym3812_rom3_1ym3812_rom2_2ym3812_rom2_1ym3812_rom1_2ym3812_id2ym3812_id1

Adlib-DigiSnap

2000-03-06

Adlib-DigiSnap (ads.pdf) is a device that is capable of recording Adlib (OPL2/YM3812) digitally. Want to build one? Now you can! You will also need the PCB film and the MSDOS driver (with source code, also a newer version 2009/01/11 with everything for compiling it is here).

10 Comments »

  1. Hi Olli,

    many thanks for posting your reverse-engineering results! I have long been trying to reproduce the sounds generated by YM3812 exactly. I tapped the connection between this chip and its DAC on an old Soundblaster and performed measurements with the help of an FPGA (which was configured to do essentially the same job as your DigiSnap). I wrote a program which controls the YM3812 at register level, or alternatively computes a string of sample values, which should exactly match the measured values. Only recently I discovered what you have achieved. Knowing the contents of the exp and log-sin tables, I finally can indeed replicate the sample values of at least the simpler sounds bit-by-bit. The whole stuff isn’t quite ready for putting it online, but if you are interested, I will of course share what I have. Again, many thanks!

    Hellwig

    Comment by Hellwig Geisse — 2010-02-22 @ 10:06

  2. Hi Hellwig! Sounds like a neat setup. I had something similar in mind, but after the microscopy work, I have not found the time to work on it anymore… So me and Matthew put the tables online for people like you. :)

    Comment by Olli Niemitalo — 2010-02-27 @ 13:32

  3. rule!

    Comment by chrisjh — 2010-04-09 @ 23:37

  4. Hi Olli. I have also verified on real YMF262 OPL3 chip that the tables and formulas in your reverse engineering report are accurate. I might add that the gain (or actually attennuation) is just a sum of Total Level (TL) register and ADSR Envelope Generator output. And since the gain also goes through the 256-entry table, gain has 8 fractional bits, so 0×100 means 6dB attennuation and 0×080 means 3dB attennuation etc. Total Level register has 6 bits and 48dB range, so 3 bits are integer part and 3 bits fractional. From OPL4 FM part datasheet it is shown that ADSR envelope has 96dB range and 0.1875 dB resolution (yes it is a typo in the datasheet), it means the envelope is a 9-bit value, 4 integer bits and 5 fractional bits. Sustain Level register bits also match the same gain formula when shifted into right position.

    Thus, gain = (TotLev<<5) + (Envelope<<3);

    Envelope is a linear ramp for decay and release, but attack is exponential curve and I have not been able to figure out the exact formula for it yet. The values may come from the logsin or exp table that are indexed linearly. Current emulators just approximate it, it would be nice to get it right.

    I also found out the LFO table for tremolo effect, but it had been already figured out by Jarek Burczinsky in his YMF262 emulator, present in ScummVM, DosBox and MAME projects.

    Some day, I could make an upgrade to your DigiSnap to use only two 74HC595 chips and an 74HC14 Schmitt trigger inverter instead of five chips it now has, and minor upgrade to software to leave out data conversion to record YMF262 PCM data too. I think OPL2 and OPL3 used different clock edges to load data out pin. For now, I use my USB logic analyzer.

    Comment by Jani — 2010-05-14 @ 15:39

  5. Hello,

    I’ve been looking for how to convert a value in the -logsin table to true values with only the exp table. I’va been using the data from the OPLx decapsulated.

    The problem came from the ‘minus’ in the logsin. Thus it is not a logsin table but a log(1/sin) table.

    The output format to the DAC must be noted : (from the datasheet of the YM3014B) (-1 + mantissa (with 2^^0, 2^^-1, 2^^-2 …)) * 2^^-exp bits.

    So the data is in floating point format with 3 bits of exponent and 10 bits mantissa.

    Whene you have the -logsin value you have the 8 LSB to look for in the exp table (I’ll explain how) and the other bits that are the exp of the FP output.

    If LSB is not 0 you should convert it to a ‘positive’ value by taking 2^^8 complement (in fact it is as adding 1 to a negative number in [0..1[ range). It means that you are dividing by 2 the value (2^^(-x) = 2^^(1-x-1) = 2^^(1-x)/2)). Dividing by 2 is just adding 1 to the exponent (remember the 2^^minus in the YM3014B ?)

    If LSB is 0, the mantissa is 0 and the exponent is taken as is from the MSB.

    Off course don’t forget hidden 1 of the float format to have tha actual value.

    Comment by Jihef — 2010-06-27 @ 13:21

  6. I built one of these last night and it seems to work. But I’m using it to investigate the OPL3 chipset. This is interesting because it has 4 output channels rather than just 1 and each operator chain can be directed to any combination of output channels.

    The data I collected last night was very noisy, but I’ve just been looking at the datasheets for the chip and it looks to me that the CLK signal is inverted in the OPL3 as compared to the OPL2. (The falling edge of LOAD corresponds with a rising edge of CLK) This would mean that I’m loading the shift register at the same time that the data is changing.

    I built my device on a protoboard, so it’s easy for me to change. I’m going to use the last left over NAND gate to invert the clock and see if that fixes my problems.

    I was mightily impressed by the microscope work as well. Many thanks to you, Olli

    Comment by carbon14 — 2010-08-04 @ 13:12

  7. The clock signal is indeed the other way on the opl3. And using the last NAND gate sorts it out.

    I should point out that Jani had already said that in comment #4, I just wasn’t paying attention.

    Comment by carbon14 — 2010-08-05 @ 11:25

  8. Carbon14, IIRC, the clock edge is wrong regarding both data and load signals of OPL3. I never ran into any hardware problems with it though. I used about 2m of CAT5 cable so the signals were twisted with ground return.

    Now the question is did you modify/rewrote the software so it records raw PCM, instead of doing conversion from the YM3014 format?

    However I later bought an USB logic analyser so I don’t have to fiddle around with custom hardware or software, it just captures everything for later analysis while real-time analysis is not possible unless I write a plugin for that.

    Comment by Jani — 2010-08-06 @ 23:27

  9. Jani,

    I’ve been looking at Olli’s software today. I’ve been using the debugreader because I wasn’t certain that the OPL3 output was the same format as the YM3014 format. The YM3014 datasheet is explicit about it’s operation, but the YAC512 is much less so. Do you have details of the YAC512 format?

    Comment by carbon14 — 2010-08-09 @ 13:21

  10. Formats between OPL2 and OPL3 are different. OPL3 uses straight 16-bit offset binary PCM – the format is described both in YMF262 and YAC512 datasheets, available by googling.

    Value 0×8000 means silence 0, 0xFFFF means +32767 and 0×0000 means -32768. So to convert to signed 16-bit PCM what for example WAV format uses, just toggle the high bit with XOR if I recall correctly. As a guideline, a single operator outputting sine or square wave at full volume results in min/max amplitudes of +4084 and -4085 (yes there is a off-by-one artifact in the output because of the way the chip perhaps handles sign and magnitude internally, the negative sample values are just got by inverting the magnitude bits).

    Sampling rate is 49716 when rounded to nearest integer in case you are unsure what sounds the best.

    Comment by Jani — 2010-08-09 @ 21:03

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress - Hosted by SuniSoft oy