SN76489 PSG --Timer Pulse Width Modulation

I have been working for the last few months on a VST emulation of the SN76489 PSG chip featured on the SEGA Master System and Megadrive/Genesis.
The Super PSG aka SPSG.
One of the things I have wanted to add is the ability to make pulse width modulation with only one channel of PSG...Similar to what have been done with the YM2149 in the Atari Scene.

For that, I have needed a native way to write data to the volume register at audio rate.
The Z80 (Master System CPU and Megadrive secondary CPU) Horizontal blank Interrupt could be handy as it can be as high as nearly 64┬Ás.
In order to write a square wave we have to write 0x0F to the volume register, last 1Hblank then 0x00, last 1 Hblank.
This gives us a nearly 7812.50 Hz as the highest frequency possible and virtually no limitation for the lowest.
Now we needed to sync the frequency as tight as possible to produce nearly the same pitch on the Tone Frequency register and the Timer Waveform...
Given a desirable frequency in Hz (frequency)
We do:
PSG frequency Register = Tn
Timer frequency number = Fn
Hbank Wave period = Hp

Tn=(Master Clock/(frequency*32))
      if(Tn >=1023)
            Tn =1023;
        if(Tn <=1)
            Tn =1;

        int ITn = (int) Tn;

        outputfrequency = (((clock / 16) / ITn) / 2);

Fn=(Master Clock/((frequency*Master Clock)/ 7812.5)
        if(Fn >=65535) // lets limit it to 16bit
         Fn =65535;
        if(Fn <=1)
         Fn =1;

        int IFn = (int) Fn;

        Hp= IFn*2;
        outputfrequency = (Master Clock / ((IFn/7812.5)* Master Clock));

This will gives us a playable range or nearly 1 Octave without major detuning for an NTSC, PAL Clock and more with a discrete under-clocked PSG (1Mhz - 4Mhz range)
The more you detune the tone or the timer frequency the more modulation you got.

Here is a test of this features in an emulator and then on the real hardware :)
Now the Sega PSG got is "SID" Sound!

No comments:

Post a Comment