]> Shamusworld >> Repos - thunder/blobdiff - src/psg.cpp
Added save states; updated application icon.
[thunder] / src / psg.cpp
index b4f3f47c0f59da0724ac25583c921b0265d30716..21ceb90cebcf4dcc6d3990860f8349c405b0123b 100644 (file)
 // ---  ----------  -----------------------------------------------------------
 // JLH  04/21/2014  Created this file.
 //
+//
+// Notes:
+// ------
+// The emulator creates signed 16-bit samples.  Make sure there's enough room
+// in your buffer for them!
+//
 
 #include "psg.h"
 #include <stdio.h>
 #include <string.h>
-
+#include "fileio.h"
 
 struct Voice
 {
@@ -31,31 +37,37 @@ struct Voice
 
 static Voice voice[8];
 static uint8_t memory[0x200];
-//static 
 static uint32_t sampleRate = 44100;
+static uint32_t divisor;
 
-extern FILE * psg1;
-extern FILE * psg2;
+void PSGSaveState(FILE * file)
+{
+       size_t ignored = fwrite(memory, 1, 0x200, file);
+       ignored = fwrite(&voice, 1, sizeof(voice), file);
+}
 
+void PSGLoadState(FILE * file)
+{
+       size_t ignored = fread(memory, 1, 0x200, file);
+       ignored = fread(&voice, 1, sizeof(voice), file);
+}
 
 void InitPSG(uint32_t s/*=44100*/)
 {
        sampleRate = s;
+       divisor = (uint32_t)((float)s / 0.735); // Voodoo constant
 
+       // Noise generation will fail if the noise seeds aren't primed...
        for(int i=0; i<8; i++)
                voice[i].noiseSeed = 1;
 }
 
-
+//
+// Note that it doesn't wipe out the buffer passed in; if you want it wiped,
+// you have to wipe it yourself.  :-)
+//
 void UpdatePSG(uint8_t * buffer, int count)
 {
-/*
-if F == 44100, then counter++ for each sample.
-if F == 88200, then counter += 2 for each sample.
-if F == 22050, then counter += 0.5 for each sample.
-*/
-//     memset(buffer, 0, count * 2);
-
        // Recast buffer as int16, we're doing 16-bit sound here
        int16_t * p = (int16_t *)buffer;
 
@@ -68,18 +80,10 @@ if F == 22050, then counter += 0.5 for each sample.
 
                        for(int j=0; j<count; j++)
                        {
-//                             uint8_t pos = (voice[i].counter / (sampleRate * 2)) & 0x1F;
-// Where does 60000 come from? IDK. This would probably change depending on
-// the playback rate (currently, 44100). N.B.: 58800 is a hair too high in pitch!
-// 44100 / 60000 = 0.735
-// 192000 / 60000 = 3.2
-//                             uint8_t pos = (voice[i].counter / (60000)) & 0x1F;
-                               uint8_t pos = (voice[i].counter / (65536)) & 0x1F;
+                               uint8_t pos = (voice[i].counter / divisor) & 0x1F;
                                uint8_t sample = ((pos & 0x01) == 0
                                        ? memory[(voice[i].waveform * 16) + (pos / 2)] >> 4
                                        : memory[(voice[i].waveform * 16) + (pos / 2)]) & 0x0F;
-//                             p[j] += (((memory[(voice[i].waveform * 32) + pos] & 0x0F) - 8)
-//                                     * voice[i].leftVolume) << 5;
                                p[j] += ((sample - 8) * voice[i].leftVolume) << 5;
                                voice[i].counter += voice[i].frequency;
                        }
@@ -89,6 +93,10 @@ if F == 22050, then counter += 0.5 for each sample.
                        if ((voice[i].leftVolume == 0) || ((voice[i].frequency & 0xFF) == 0))
                                continue;
 
+                       // The hold stuff here is VOODOO
+                       // Need to figure out what's really going on here, what the clock
+                       // rate of this chip is. Also, some freqs can be > 255 according to
+                       // Rolling Thunder...
                        int16_t sample = (7 * voice[i].leftVolume) << 4;
                        int16_t noiseSign = 1;
                        int16_t hold = 1 << 1;
@@ -96,18 +104,6 @@ if F == 22050, then counter += 0.5 for each sample.
                        for(int j=0; j<count; j++)
                        {
                                p[j] += sample * noiseSign;
-#if 0
-if (i == 1)
-{
-       fputc(sample & 0xFF, psg1);
-       fputc((sample >> 8) & 0xFF , psg1);
-}
-else if (i == 3)
-{
-       fputc(sample & 0xFF, psg2);
-       fputc((sample >> 8) & 0xFF , psg2);
-}
-#endif
 
                                if (hold)
                                {
@@ -136,7 +132,6 @@ else if (i == 3)
        }
 }
 
-
 void WritePSG(uint16_t address, uint8_t data)
 {
        if ((address >= 0x100) && (address <= 0x13F))
@@ -153,11 +148,8 @@ void WritePSG(uint16_t address, uint8_t data)
                                break;
                        case 1:
                                voice[channel].waveform = data >> 4;
-                               voice[channel].frequency = ((data & 0x0F) << 16) 
+                               voice[channel].frequency = ((data & 0x0F) << 16)
                                        | (voice[channel].frequency & 0x0FFFF);
-#if 0
-printf("PSG: Setting waveform on channel %i to %i...\n", channel, voice[channel].waveform);
-#endif
                                break;
                        case 2:
                                voice[channel].frequency = (data << 8)
@@ -171,39 +163,15 @@ printf("PSG: Setting waveform on channel %i to %i...\n", channel, voice[channel]
                                voice[channel].rightVolume = data & 0x0F;
                                // Noise switch is channel # + 1 (wraps to zero)
                                voice[(channel + 1) & 0x07].noise = (data & 0x80 ? true : false);
-#if 0
-if (voice[(channel + 1) & 0x07].noise)
-{
-       uint8_t ch = (channel + 1) & 0x07;
-       printf("PSG: Setting noise on channel %i, vol=%i, freq=%i...\n", ch, voice[ch].leftVolume, voice[ch].frequency);
-}
-#endif
-#if 0
-if (data & 0x0F)
-{
-       printf("PSG: Setting right volume on channel %i: vol=%i...\n", channel, voice[channel].rightVolume);
-}
-#endif
                                break;
                        }
                }
-
-//             return;
        }
-#if 0
-       else
-               printf("PSG: Write to $%03X of $%02X...\n", address, data);
-#endif
-
-//if (address < 0x100)
-//     printf("PSG: Waveform byte[$%02X] = $%02X...\n", address, data);
 
        memory[address & 0x01FF] = data;
 }
 
-
 uint8_t ReadPSG(uint16_t address)
 {
        return memory[address & 0x01FF];
 }
-