Wednesday, 5 August 2020

YM3812

I had one old broken Sound Blaster ISA card and decided to pull the music chip from it to see if it worked. This was the Yamaha YM3812 or otherwise known as OPL2. It's the same chip that was used in Adlib cards. Pretty much everyone who played DOS games back in the day knew the sound of this chip.


This chip has a rather peculiar sample format, it's 13 bit floating point with 10 bits for mantissa and 3 bits for exponent. The chip requires 3.58 MHz input, uses 8 data bits and one address bit. I used a cheap FPGA board to generate the clock for the chip and fed the digital samples back to the FPGA. I converted the floating point number into regular 16-bit integer and used a software delta-sigma modulator running at 50 MHz to convert back to analog signal.


The chip contrary to the datasheets 16 bits seemed to be output 18 bits during a single SYNC cycle (SYNC is cyan in the above image, CLK is yellow). First 5 extra bits were irrelevant. According to the datasheet only first 3 bits were supposed to be irrelevant. It also appears this chips seemed to work fine with 3.3 V where in the datasheet the minimum voltage was listed as 4.5 V. Operating it with 3.3 V was convenient as my FPGA supplied this voltage and could also only accept 3.3 V logic.


The above is the signal directly measured from the 1-bit digital FPGA pin which is sigma-delta modulated (1st order) digital-to-analog conversion of the signal generated by the YM3812 chip. The sampling frequency is just so high (50 MHz) that it looks very good analog signal when low pass filtered.

Taking a running average (a kind of low pass filter) of the delta-sigma modulated signal yields an analog signal. The higher the "oversampling" rate, the more faithful the filtered signal is to the original (up to some high frequency cutoff).

Second order delta-sigma modulation shapes the noise in order to improve the signal-to-noise ratio even further at the expense of the S/N at the higher frequencies.

Looking at the spectrum, one can easily see that the quantization noise slope is much steeper for higher order delta-sigma modulations and thus can yield better signal fidelity at lower frequencies. The low frequency peak's "skirt" is due to finite sampling. The signal is actually just a delta-peak in frequency space and has no skirt (other than some vanishingly small one related to the phase noise of the digital clock, but that's another story and not relevant for this context). 
DSM is of course not limited to just 1-bit, but one can use it to improve the SNR of n-bit converters as well if they are capable of operating fast enough relatively to the signal of interest. The image is from 4-bit converter modulated by 2nd order DSM.


The effect of higher order DSMs on quantization noise.

Below, 1-bit 1st order DSM and 4-bit 2nd order DSM demonstration code in Matlab.

out = 0;
int = 0;
for x = 1:length(t)
    int = int + sin(pi*t(x)) - out(x);
    if int > 0
        out(x+1) = 1;
    else
        out(x+1) = -1;
    end
end

%%

out2 = 0;
int1 = 0;
int2 = 0;
for x = 1:length(t)
    int1 = int1 + 6*sin(pi*t(x)) - out2(x);
    int2 = int2 + int1 - out2(x);
    out2(x+1) = round(int2);
end

Saturday, 1 August 2020

EGA to PVM

I bought an EGA display card for ISA recently. EGA games run without scan doubling so they looked a bit different originally on real EGA monitor when compared to VGA monitor and I hadn't actually ever seen this so I figured I'd try. Unfortunately I don't have an EGA monitor or CGA monitor (low resolution EGA is compatible with CGA-monitors) and they are quite difficult to come by. EGA as well as CGA uses digital TTL signals instead of analog RGB like VGA monitors. VGA monitors are also incompatible with CGA and EGA timings so I would have to figure something out.



I do have a PVM capable of displaying NTSC signals (basically a TV), including RGB input and since most EGA games are running in the low resolution mode with NTSC compatible timing, I figured it might be relatively easy to botch something up. PVM only accepts CSYNC so I would have to convert VSYNC and HSYNC. Unfortunately they need to be inverted so I had to use an active logic circuit for that instead of just something passive. Luckily the logic is quite simple. Another thing is that TTL levels are too high for PVM, but simply placing 1 kohm resistor in series divides the voltage down sufficiently (into 75 ohm input). Maybe this division is even a bit too much, but it's what I had at hand. Below is the schematic I used.



Unfortunately the CGA/EGA color brown is handled in a "nonlinear" fashing and would require a bit more logic to display it correctly. Here it instead of being brown looks more yellow. However, the other 15 colors are fine.


This is how it would look with the correct shade of brown.


My botched board is maybe a bit nasty, but it works fine.