]> Shamusworld >> Repos - thunder/commitdiff
Thunder now works with NO samples! \o/
authorShamus Hammons <jlhamm@acm.org>
Wed, 23 Apr 2014 13:34:20 +0000 (08:34 -0500)
committerShamus Hammons <jlhamm@acm.org>
Wed, 23 Apr 2014 13:34:20 +0000 (08:34 -0500)
makefile
src/psg.cpp [new file with mode: 0644]
src/psg.h [new file with mode: 0644]
src/sound.cpp
src/thunder.cpp

index a3820002c2ea730d8056fe7c06b3d9ec390860d8..fdf79bca85a29cf4a8cfc85ee1932b5138ae170b 100644 (file)
--- a/makefile
+++ b/makefile
@@ -61,6 +61,7 @@ OBJS = \
        obj/gui.o        \
        obj/icon-64x64.o \
        obj/log.o        \
+       obj/psg.o        \
        obj/resource.o   \
        obj/screen.o     \
        obj/sound.o      \
diff --git a/src/psg.cpp b/src/psg.cpp
new file mode 100644 (file)
index 0000000..b4f3f47
--- /dev/null
@@ -0,0 +1,209 @@
+//
+// PSG handler
+//
+// This emulates the Rolling Thunder PSG (Namco CUS30)
+//
+// by James Hammons
+// (C) 2014 Underground Software
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// Who  When        What
+// ---  ----------  -----------------------------------------------------------
+// JLH  04/21/2014  Created this file.
+//
+
+#include "psg.h"
+#include <stdio.h>
+#include <string.h>
+
+
+struct Voice
+{
+       uint8_t leftVolume;
+       uint8_t rightVolume;
+       uint8_t waveform;
+       uint32_t frequency;
+       uint32_t counter;
+       bool noise;
+       uint32_t noiseSeed;
+};
+
+static Voice voice[8];
+static uint8_t memory[0x200];
+//static 
+static uint32_t sampleRate = 44100;
+
+extern FILE * psg1;
+extern FILE * psg2;
+
+
+void InitPSG(uint32_t s/*=44100*/)
+{
+       sampleRate = s;
+
+       for(int i=0; i<8; i++)
+               voice[i].noiseSeed = 1;
+}
+
+
+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;
+
+       for(int i=0; i<8; i++)
+       {
+               if (!voice[i].noise)
+               {
+                       if ((voice[i].leftVolume == 0) || (voice[i].frequency == 0))
+                               continue;
+
+                       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 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;
+                       }
+               }
+               else
+               {
+                       if ((voice[i].leftVolume == 0) || ((voice[i].frequency & 0xFF) == 0))
+                               continue;
+
+                       int16_t sample = (7 * voice[i].leftVolume) << 4;
+                       int16_t noiseSign = 1;
+                       int16_t hold = 1 << 1;
+
+                       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)
+                               {
+                                       hold--;
+                                       continue;
+                               }
+
+                               hold = 1 << 1;
+
+                               voice[i].counter += (voice[i].frequency & 0xFF) << 4;
+                               int c = voice[i].counter >> 12;
+                               voice[i].counter &= 0xFFF;
+
+                               for(; c>0; c--)
+                               {
+                                       if ((voice[i].noiseSeed + 1) & 0x02)
+                                               noiseSign *= -1;
+
+                                       if (voice[i].noiseSeed & 0x01)
+                                               voice[i].noiseSeed ^= 0x28000;
+
+                                       voice[i].noiseSeed >>= 1;
+                               }
+                       }
+               }
+       }
+}
+
+
+void WritePSG(uint16_t address, uint8_t data)
+{
+       if ((address >= 0x100) && (address <= 0x13F))
+       {
+               uint8_t channel = (address - 0x100) / 8;
+               uint8_t knob = (address - 0x100) - (channel * 8);
+
+               if (channel < 8)
+               {
+                       switch (knob)
+                       {
+                       case 0:
+                               voice[channel].leftVolume = data & 0x0F;
+                               break;
+                       case 1:
+                               voice[channel].waveform = data >> 4;
+                               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)
+                                       | (voice[channel].frequency & 0xF00FF);
+                               break;
+                       case 3:
+                               voice[channel].frequency = data
+                                       | (voice[channel].frequency & 0xFFF00);
+                               break;
+                       case 4:
+                               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];
+}
+
diff --git a/src/psg.h b/src/psg.h
new file mode 100644 (file)
index 0000000..c8b4452
--- /dev/null
+++ b/src/psg.h
@@ -0,0 +1,12 @@
+#ifndef __PSG_H__
+#define __PSG_H__
+
+#include <stdint.h>
+
+void InitPSG(uint32_t s = 44100);
+void UpdatePSG(uint8_t * buffer, int count);
+void WritePSG(uint16_t address, uint8_t data);
+uint8_t ReadPSG(uint16_t address);
+
+#endif // __PSG_H__
+
index 744eafaca7df547f422fbb06b38e8dace7763b5a..3be768305629b37a3d8e8d7d8ff38e67ede1297d 100644 (file)
 
 #include "sound.h"
 #include <SDL2/SDL.h>
+#include "psg.h"
 #include "resource.h"
 #include "ym2151.h"
 
+
+#define SAMPLE_RATE 48000
+
 // Function prototypes
 void SoundFunc(void *, Uint8 *, int);
 
@@ -23,24 +27,24 @@ void SoundFunc(void *, Uint8 *, int);
 extern uint8_t voice_rom[];                    // PCM data pointer
 
 static bool soundInitialized = false;
-const float sampleBase = 44010.0/6000.0;  // Btwn 5512.5 and 6000
+const float sampleBase = (float)SAMPLE_RATE/6000.0;  // Voice is between 5512.5 and 6000 Hz
 bool snd_go = false;
-bool chan1_go = false, chan2_go = false, chan3_go = false;
-bool chan4_go = false, chan5_go = false, chan6_go = false;
-uint8_t * sndp1, * sndp2, * sndp3, * sndp4, * sndp5, * sndp6;
+bool chan1_go = false, chan2_go = false;//, chan3_go = false;
+bool /*chan4_go = false, chan5_go = false,*/ chan6_go = false;
+uint8_t * sndp1, * sndp2, /* sndp3, * sndp4, * sndp5,*/ * sndp6;
 uint32_t rom_pos, end_pos;
 uint32_t spos1, end_pos1;
 uint32_t spos2, end_pos2;
-uint32_t spos3, end_pos3;
-uint32_t spos4, end_pos4;
-uint32_t spos5, end_pos5;
+//uint32_t spos3, end_pos3;
+//uint32_t spos4, end_pos4;
+//uint32_t spos5, end_pos5;
 uint32_t spos6, end_pos6;
 float sample1;
-uint8_t prevSamp1;
-int8_t delta_x1;
+int16_t prevSamp1;
+//int8_t delta_x1;
 float sample2;
-uint8_t prevSamp2;
-int8_t delta_x2;
+int16_t prevSamp2;
+//int8_t delta_x2;
 uint16_t snd_num;
 uint8_t * snd_array[3] = { sunknown, scya, scamera }; // From RESOURCE.H
 uint32_t snd_lens[3]   = { sunknownlen, scyalen, scameralen };
@@ -50,14 +54,16 @@ void InitSound(void)
 {
        // params 1, 4 & 5 are useless
 //     if (YMInit(1, 3579580, 22050, 16, 512))//, (SAMPLE **)sbp))
-       if (YMInit(1, 3579580, 44100, 16, 512))
+       if (YMInit(1, 3579580, SAMPLE_RATE, 16, 512))
        {
                printf("SOUND: Could not init YM2151 emulator!\n");
                return;// -1;
        }
 
+       InitPSG(SAMPLE_RATE);
+
        SDL_AudioSpec desired, obtained;
-       desired.freq = 44100;
+       desired.freq = SAMPLE_RATE;
        desired.format = AUDIO_S16;
        desired.channels = 1;
        desired.samples = 1024;
@@ -81,10 +87,10 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
 {
        extern uint32_t psg_lens[16];
        extern uint8_t * psg_adrs[16];
-       extern uint32_t voc_lens[32];
-       extern uint8_t * voc_adrs[32];
-       extern uint32_t fm_lens[14];
-       extern uint8_t * fm_adrs[14];
+//     extern uint32_t voc_lens[32];
+//     extern uint8_t * voc_adrs[32];
+//     extern uint32_t fm_lens[14];
+//     extern uint8_t * fm_adrs[14];
 
        if (!soundInitialized)
                return;
@@ -92,6 +98,7 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
        snd_num = snd;
 //     SpawnMsg(MSHOWNUMS);
 
+       // Voice type sounds...
        if (type == GAMESOUND)
        {
                // Will that do it???  Yes!!!
@@ -131,6 +138,7 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
                        chan2_go = true;
                }
        }
+#if 0
        else if (type == PSGSOUND)
        {
                if (snd_num & 0x10)                                                             // Second channel?
@@ -154,6 +162,7 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
                                chan4_go = false;                                               // No sound loaded, so don't do it!
                }
        }
+#endif
 #if 0
        else if (type == FMSOUND)
        {
@@ -176,25 +185,22 @@ void SpawnSound(int type, int snd, int channel/* = 0*/)
 }
 
 
-void SoundFunc(void * userdata, Uint8 * buff, int num)
+void SoundFunc(void * userdata, Uint8 * buffer, int num)
 {
        static bool psg1go = false, psg2go = false;
        // Length / 2 is because it's set up for 16-bit samples
 //     YM2151UpdateOne(buffer, length / 2);
        // Have to go into ym2151.cpp and change this manually back to 8 bit
-       YM2151UpdateOne(buff, num / 2);
+       YM2151UpdateOne(buffer, num / 2);
 //     return;
+       UpdatePSG(buffer, num / 2);
 
        // 0-22 different sounds...
-       uint16_t cnt = 0, sample;
+       uint16_t cnt = 0;//, sample;
        uint8_t start_samp1, end_samp1, start_samp2, end_samp2;
-       uint8_t samp1 = 128, samp2 = 128, samp3 = 128,
-               samp4 = 128, samp5 = 128, samp6 = 128;                  // Zero samples...
+       int16_t samp1 = 0, samp2 = 0, samp6 = 0;                        // Zero samples...
 
-       // Kill sound...
-//     memset(buff, 128, num);
-
-       if (!(chan1_go || chan2_go || chan3_go || chan4_go /*|| chan5_go*/ || chan6_go))
+       if (!(chan1_go || chan2_go /*|| chan3_go || chan4_go || chan5_go*/ || chan6_go))
                return;
 
        while (cnt != (num / 2))
@@ -203,16 +209,17 @@ void SoundFunc(void * userdata, Uint8 * buff, int num)
                {
                        if (sample1 < 1)
                        {
-                               samp1 = voice_rom[spos1++];
+                               uint8_t voiceSample = voice_rom[spos1++];
+                               samp1 = ((int16_t)voiceSample - 128) * 160;
 
                                // Kill channel 1 if done...
-                               if (samp1 == 0xFF)
+                               if (voiceSample == 0xFF)
                                {
                                        chan1_go = false;
-                                       samp1 = 128;
+                                       samp1 = 0;
                                }
                                // RLE compression...
-                               else if (samp1 == 0x00)
+                               else if (voiceSample == 0x00)
                                {
                                        // # of repeats
                                        sample1 += (float)voice_rom[spos1++] * sampleBase;
@@ -235,14 +242,16 @@ void SoundFunc(void * userdata, Uint8 * buff, int num)
                {
                        if (sample2 < 1)
                        {
-                               samp2 = voice_rom[spos2++];
+                               uint8_t voiceSample = voice_rom[spos2++];
+                               samp2 = ((int16_t)voiceSample - 128) * 160;
+//                             samp2 = voice_rom[spos2++];
 
-                               if (samp2 == 0xFF)
+                               if (voiceSample == 0xFF)
                                {
                                        chan2_go = false;
                                        samp2 = 128;                                    // Kill channel 2 if done...
                                }
-                               else if (samp2 == 0x00)                         // RLE compression...
+                               else if (voiceSample == 0x00)                           // RLE compression...
                                {
                                        sample2 += (float)voice_rom[spos2++] * sampleBase;      // # of repeats
                                        samp2   = prevSamp2;
@@ -257,30 +266,31 @@ void SoundFunc(void * userdata, Uint8 * buff, int num)
                        sample2 -= 1.0;
                }
 
+#if 0
                if (chan3_go)
                {
-                       samp3 = (psg1go ? sndp3[spos3++] : sndp3[spos3]);
+                       samp3 = ((psg1go ? sndp3[spos3++] : sndp3[spos3]) - 128) * 160;
                        psg1go = !psg1go;
 
                        if (spos3 == end_pos3)
                        {
                                chan3_go = false;
-                               samp3 = 128; // Kill channel 3 if done...
+                               samp3 = 0; // Kill channel 3 if done...
                        }
                }
 
                if (chan4_go)
                {
-                       samp4 = (psg2go ? sndp4[spos4++] : sndp4[spos4]);
+                       samp4 = ((psg2go ? sndp4[spos4++] : sndp4[spos4]) - 128) * 160;
                        psg2go = !psg2go;
 
                        if (spos4 == end_pos4)
                        {
                                chan4_go = false;
-                               samp4 = 128; // Kill channel 4 if done...
+                               samp4 = 0; // Kill channel 4 if done...
                        }
                }
-#if 0
+
                if (chan5_go)
                {
                        samp5 = sndp5[spos5++];
@@ -299,20 +309,25 @@ void SoundFunc(void * userdata, Uint8 * buff, int num)
                        if (spos6 == end_pos6)
                        {
                                chan6_go = false;
-                               samp6 = 128;            // Kill channel 6...
+                               samp6 = 0;              // Kill channel 6...
                        }
                }
 
                // Mix 'em...
 //             sample = samp1 + samp2 + samp3 + samp4 + samp5 + samp6 - 640;
-               sample = samp1 + samp2 + samp3 + samp4 + samp6 - (5 * 128);
+               int32_t sample = samp1 + samp2 + samp6;
+               sample += ((int16_t *)buffer)[cnt];
 
                // If it overflowed, clip it
-               if (sample & 0xFF00)
+//             if (sample & 0xFFFF0000)
 //                     sample = (sample & 0x8000 ? 0x00 : 0xFF);
-                       sample = (sample & 0x8000 ? 0x0000 : 0xFFFF);
+//                     sample = (sample & 0x80000000 ? 0x0000 : 0xFFFF);
+               if (sample > 32767)
+                       sample = 32767;
+               else if (sample < -32767)
+                       sample = -32767;
 
-               ((uint16_t *)buff)[cnt++] += sample << 7;
+               ((int16_t *)buffer)[cnt++] = (int16_t)sample;
        }
 }
 
index d1ebfde22f9e07fbac870ff4c933170210cba2cf..18cf8df7b3b212602b1fbc5e44c958949f8cd0ac 100644 (file)
@@ -28,6 +28,7 @@
 #include <time.h>
 #include "gui.h"
 #include "log.h"
+#include "psg.h"
 #include "screen.h"
 #include "sound.h"
 #include "v63701.h"
@@ -73,13 +74,14 @@ using namespace std;
 
 SDL_Surface * screen;
 
-uint8_t * gram, * grom;                                // Allocate RAM & ROM pointers
-uint8_t gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000];        // Actual memory
-uint8_t grom3[0x8000], grom4[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
-uint8_t chr_rom[0x60000];                      // Character ROM pointer
+uint8_t * gram, * grom;                        // Allocate RAM & ROM pointers
+// Actual memory
+uint8_t gram1[0x10000], gram2[0x10000], grom1[0x10000], grom2[0x10000];
+uint8_t grom3[0x8000], data_rom[0x40000], spr_rom[0x80000], voice_rom[0x20000];
+uint8_t chr_rom[0x60000];              // Character ROM pointer
 uint8_t mcuMem[0x10000];               // 64K for MCU
 
-V6809REGS cpu1, cpu2;
+V6809REGS cpu1, cpu2;                  // CPU execution contexts
 V63701REGS mcu;
 
 bool trace1 = false;                   // ditto...
@@ -97,188 +99,153 @@ bool refresh2 = true;
 
 uint32_t psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 uint8_t * psg_adrs[16];
-//uint32_t voc_lens[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-//                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-//uint8_t * voc_adrs[32];
-//uint32_t fm_lens[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-//uint8_t * fm_adrs[14];
 
 Byte input1, input2, input3, input4, input5;
 
 fstream tr;                                                    // Tracelog hook
 uint16_t pcx;                                          // Where we at?
 
+// Function prototypes
+uint8_t MCUReadMemory(uint16_t address);
+void MCUWriteMemory(uint16_t address, uint8_t data);
+
 
 //
-// Read a byte from memory (without touching PC. Not a Fetch!)
+// Read a byte from memory
 //
 uint8_t RdMem(uint16_t addr)
 {
        uint8_t b;
 
-       // $4000-4300 is RAM shared with the microcontroller...
-
        if (addr < 0x8000)
        {
                // Memory shared with MCU (CPU #1 only! CPU #2 does not)
                if ((addr >= 0x4000) && (addr <= 0x43FF))
                        return mcuMem[addr - 0x3000];
+//             if ((addr >= 0x4000) && (addr <= 0x41FF))
+//                     return MCUReadMemory(addr - 0x3000);
+//             if ((addr >= 0x4200) && (addr <= 0x43FF))
+//                     return mcuMem[addr - 0x3000];
 
-               if (addr > 0x5FFF)
-                       b = data_rom[banksw1 + (addr - 0x6000)];        // Get char data
+               if (addr >= 0x6000)
+                       return data_rom[banksw1 + (addr - 0x6000)];     // Get char data
                else
-                       b = gram1[addr];
+                       return gram1[addr];
        }
-       else
-               b = grom1[addr];
 
-       return b;
+       return grom1[addr];
 }
 
 
 //
 // Write a byte to memory
 //
-void WrMem(uint16_t addr, uint8_t b)
+void WrMem(uint16_t address, uint8_t data)
 {
        extern bool disasm;
        extern bool charbase;   // Needed for screen. Extern it in it??
 #if 0
-       if (addr == 0x4182)
+       if (address == 0x4182)
        {
                WriteLog("\nWriteMem: CPU #1 writing $%02X to $4182!\n\n", b);
        }
 #endif
 #if 0
-if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380))
-       printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, addr);
+if (((address >= 0x4180) && (address <= 0x4191)) || (address == 0x4380))
+       printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, address);
 #endif
 
-       if (addr == 0x6000)
-               SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
-       if (addr == 0x6400)
-               SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
-       if (addr == 0x6800)
-               banksw1 = (uint32_t)b << 13;                                            // Set char data bankswitch base address
-       if (addr > 0x4284 && addr < 0x42A5 && b)
-               SpawnSound(PSGSOUND, addr - 0x4285);                    // Do PSG sound on chans 2, 3
-#if 0
-       if (addr == 0x4380)
-       {
-               SpawnSound(FMSOUND, b);                                                 // Do FM sound on channel 4
-               if (b == 12)
-                       game_over_switch = 240;                                         // Set game over delay...
-       }
-#endif
-//     if (addr < 0x423D || addr > 0x425C)                                     // Protect writes to DSWs
-//if (addr == 0x4191)
+       if (address == 0x6000)
+{
+//printf("Spawning VOICE channel #1: $6000=$%02X, $6200=$%02X\n", b, gram1[0x6200]);
+               SpawnSound(GAMESOUND, gram1[0x6200], 0);        // Do voice chan 1
+}
+       if (address == 0x6400)
+{
+//printf("Spawning VOICE channel #2: $6400=$%02X, $6600=$%02X\n", b, gram1[0x6600]);
+               SpawnSound(GAMESOUND, gram1[0x6600], 1);        // Do voice chan 2
+}
+       if (address == 0x6800)
+               banksw1 = (uint32_t)data << 13;                         // Set char data bankswitch base address
+       if (address > 0x4284 && address < 0x42A5 && data)
+               SpawnSound(PSGSOUND, address - 0x4285);         // Do PSG sound on chans 2, 3
+
+//if ((address >= 0x4284) && (address < 0x42A5))
 //{
-//     printf("V6809: Writing %02X to $4191...\n", b);
+//     printf("WrMem: Wrote $%02X to PSG address $%04X...\n", data, address);
 //}
        // Memory shared with MCU (CPU #1 only! CPU #2 does not)
-       if ((addr >= 0x4000) && (addr <= 0x43FF))
-               mcuMem[addr - 0x3000] = b;
+       if ((address >= 0x4000) && (address <= 0x43FF))
+               mcuMem[address - 0x3000] = data;
+//     if ((address >= 0x4000) && (address <= 0x41FF))
+//             MCUWriteMemory(address - 0x3000, data);
+//     if ((address >= 0x4200) && (address <= 0x43FF))
+//             mcuMem[address - 0x3000] = data;
        else
-               gram1[addr] = b;
+               gram1[address] = data;
 
-       if (addr == 0x8800)
-               charbase = false;                                                               // Char banksw1
-       if (addr == 0x8C00)
-               charbase = true;                                                                // Char banksw2
-       if (addr == 0x8400)                                                                     // Frame go strobe? VBlank acknowledge?
+       if (address == 0x8800)
+               charbase = false;                                                       // Char banksw1
+       if (address == 0x8C00)
+               charbase = true;                                                        // Char banksw2
+       if (address == 0x8400)                                                          // Frame go strobe? VBlank acknowledge?
        {
-               if (refresh_++ == 1)                                                            // 30 Hz...
-               {
-                       BlitChar(screen, chr_rom, gram1);
-                       refresh_ = (refresh2 ? 1 : 0);                          // 60/30 Hz...
-               }
+               BlitChar(screen, chr_rom, gram1);
 
                // IRQ Ack (may also be frame go...
                ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
 #if 1
        if (disasm)
-               WriteLog("WriteMem: CPU #1 Acknowledging IRQ...\n", b);
+               WriteLog("WriteMem: CPU #1 Acknowledging IRQ...\n", data);
 #endif
        }
 }
 
 
 //
-// Read a byte from memory (without touching PC. Not a Fetch!) (2nd processor)
+// Read a byte from memory (2nd processor)
 //
-uint8_t RdMemB(uint16_t addr)
+uint8_t RdMemB(uint16_t address)
 {
-       uint8_t b;
-
-       if (addr < 0x8000)
+       if (address < 0x8000)
        {
-               if (addr < 0x2000)
-                       b = gram1[addr + 0x4000];
-               if (addr > 0x1FFF && addr < 0x6000)
-                       b = gram1[addr - 0x2000];
-               if (addr > 0x5FFF)
-                       b = grom3[banksw2 + (addr - 0x6000)];
+               if (address < 0x2000)
+                       return gram1[address + 0x4000];
+               else if ((address >= 0x2000) && (address < 0x6000))
+                       return gram1[address - 0x2000];
+               else if (address >= 0x6000)
+                       return grom3[banksw2 + (address - 0x6000)];
        }
-       else
-               b = grom2[addr];
 
-       return b;
+       return grom2[address];
 }
 
 
 //
 // Write a byte to memory (2nd processor)
 //
-void WrMemB(uint16_t addr, uint8_t b)
+void WrMemB(uint16_t address, uint8_t data)
 {
        extern bool disasm;
        extern bool charbase;
 
-#if 0
-       if (addr == 0x0182)
-       {
-               WriteLog("\nWriteMem: CPU #2 writing $%02X to $0182 ($4182)!\n\n", b);
-       }
-#endif
-#if 0
-if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
-       printf("WriteMem: CPU #2 writing $%02X to $%04X...\n", b, addr);
-#endif
+       // Set sprite data bank switch
+       if (address == 0xD803)
+               banksw2 = (uint32_t)(data & 0x03) << 13;
 
-#if 0
-       if (addr == 0x6000)
-               SpawnSound(GAMESOUND, gram1[0x6200], 0);                // Do voice chan 1
-       if (addr == 0x6400)
-               SpawnSound(GAMESOUND, gram1[0x6600], 1);                // Do voice chan 2
-       if (addr > 0x0284 && addr < 0x02A5 && b)
-               SpawnSound(PSGSOUND, addr - 0x0285);                    // Do PSG sound on chans 2, 3
-#endif
-       if (addr == 0xD803)
-               banksw2 = (uint32_t)(b & 0x03) << 13;                           // Set sprite data bank switch
-#if 0
-       if (addr == 0x0380)
-       {
-               SpawnSound(FMSOUND, b);                                                 // Do FM sound on chan 4
-               if (b == 12)
-                       game_over_switch = 240;                                         // Set game over delay...
-       }
-#endif
-//     if (addr < 0x023D || addr > 0x025C)                                     // Protect writes against DSWs
-       {
-               if (addr < 0x2000)
-                       gram1[addr + 0x4000] = b;
-               if (addr > 0x1FFF && addr < 0x6000)
-                       gram1[addr - 0x2000] = b;
-//             if (addr > 0x5FFF)
-//                     gram1[addr] = b;
-       }
-       if (addr == 0x8800)
+       if (address < 0x2000)
+               gram1[address + 0x4000] = data;
+
+       if ((address >= 0x2000) && (address < 0x6000))
+               gram1[address - 0x2000] = data;
+
+       if (address == 0x8800)
        {
                // IRQ Ack (may also be frame go...)
                ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ);
 #if 1
        if (disasm)
-               WriteLog("WriteMem: CPU #2 Acknowledging IRQ...\n", b);
+               WriteLog("WriteMem: CPU #2 Acknowledging IRQ...\n", data);
 #endif
        }
 }
@@ -287,41 +254,22 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380))
 uint8_t MCUReadMemory(uint16_t address)
 {
        if (address < 0x20)
-       {
-//             printf("V63701 read $%02X from $%02X...\n", memory[address], address);
                return InternalRegisterRead(address);
-       }
+       else if ((address >= 0x1000) && (address <= 0x113F))
+//     else if ((address >= 0x1000) && (address <= 0x11FF))
+               return ReadPSG(address - 0x1000);
        else if ((address >= 0x2000) && (address <= 0x2001))
-       {
-//             return 0;       //for now
                return YMReadReg(0);
-       }
        // Various joystick + buttons; all are active low.
        else if (address == 0x2020)
-       {
-//printf("MCURead: Returning $%02X from $2020...\n", input1.byte);
                return input1.byte;
-       }
        else if (address == 0x2021)
-       {
-//extern bool V63701LogGo;
-//if (input2.byte == 0xDF)
-//     V63701LogGo = true;
-
-//printf("MCURead: Returning $%02X from $2021...\n", input2.byte);
                return input2.byte;
-       }
        // This is DSW1 & 2. All switch settings are active low.
        else if (address == 0x2030)
-       {
-//printf("MCURead: Returning $%02X from $2030...\n", input4.byte);
                return input4.byte;
-       }
        else if (address == 0x2031)
-       {
-//printf("MCURead: Returning $%02X from $2031...\n", input5.byte);
                return input5.byte;
-       }
 
        return mcuMem[address];
 }
@@ -331,31 +279,20 @@ void MCUWriteMemory(uint16_t address, uint8_t data)
 {
        static uint8_t ymRegister;
 
-#if 1
        if (address < 0x20)
        {
-//             printf("V63701 wrote $%02X to $%02X...\n", data, address);
                InternalRegisterWrite(address, data);
                return;
        }
-#endif
-
-//if (address == 0x1191)
-//{
-//     printf("V63701: Writing $%02X to $1191...\n", data);
-//}
-#if 0
-       // Translate local reads @ $1000-$13FF to $4000-$43FF in shared RAM
-       if ((address >= 0x1000) && (address <= 0x13FF))
+       else if (((address >= 0x4000) && (address <= 0xBFFF))
+               || (address >= 0xF000))
+               return;
+       else if ((address >= 0x1000) && (address <= 0x113F))
+//     else if ((address >= 0x1000) && (address <= 0x11FF))
        {
-               gram1[0x3000 + address] = data;
+               WritePSG(address - 0x1000, data);
                return;
        }
-#endif
-
-       if (((address >= 0x4000) && (address <= 0xBFFF))
-               || (address >= 0xF000))
-               return;
        else if (address == 0x2000)
        {
                ymRegister = data;
@@ -363,7 +300,6 @@ void MCUWriteMemory(uint16_t address, uint8_t data)
        }
        else if (address == 0x2001)
        {
-//printf("Writing $%02X to YM2151 register $%02X...\n", data, ymRegister);
                YMWriteReg(0, ymRegister, data);
                return;
        }
@@ -587,6 +523,7 @@ uint32_t GetWAVLength(fstream & file)
 }
 
 
+#if 0
 //
 // Load PSG samples from disk
 //
@@ -626,48 +563,8 @@ void LoadPSGs(void)
                }
        }
 }
-
-
-#if 0
-//
-// Load FM samples from disk
-//
-void LoadFMs(void)
-{
-       char file[200];
-       char ch;
-       uint32_t len;
-
-       for(int i=0; i<14; i++)
-       {
-               fstream fp;
-
-               fm_adrs[i] = NULL;                                              // Zero out pointer
-               sprintf(file, "./sounds/fm%i.wav", i);  // Create filename
-               fp.open(file, ios::binary | ios::in);   // Attempt to open it...
-
-               if (!fp)
-                       continue;
-
-               len = GetWAVLength(fp);                                 // Get WAV length...
-               fm_adrs[i] = new uint8_t[len];                  // Attempt to allocate space...
-
-               if (fm_adrs[i] != NULL)
-               {
-                       for(int j=0; j<(signed)len; j++)
-                       {
-                               fp.get(ch);
-                               fm_adrs[i][j] = ch;                                     // & load it in...
-                       }
-
-                       fm_lens[i] = len;
-                       printf("Found sample file: %s\t[Length: %u]\n", file, len);
-               }
-
-               fp.close();
-       }
-}
 #endif
+FILE * psg1, * psg2;
 
 
 //
@@ -691,7 +588,7 @@ extern bool disasm; // From 'V6809.CPP'
        uint16_t debounce = 0;                // Key de-bounce counter
        uint16_t fire_debounce = 0;           // Fire button debounce counter
        uint8_t x;                           // General placeholder...
-       bool active = true;                                             // Program running flag
+//     bool active = true;                                             // Program running flag
 
        SDL_Event event;                                                                // SDL "event"
        extern uint8_t palette[768];                                    // Screen physical palette
@@ -729,9 +626,6 @@ extern bool disasm; // From 'V6809.CPP'
        if (!LoadImg(ROM3, grom3, 0, 0x8000))      // Load 3rd ROM into its own space
        { cout << "Could not open file '" << ROM3 << "'!" << endl;  return -1; }
 
-//     if (!LoadImg(ROM4, grom4, 0, 0x8000))      // Load 4rd ROM into its own space
-//     { cout << "Could not open file '" << ROM4 << "'!" << endl;  return -1; }
-
        if (!LoadImg(ROM17, data_rom, 0,       0x10000))  // Load 17th ROM
        { cout << "Could not open file '" << ROM17 << "'!" << endl;  return -1; }
 
@@ -787,9 +681,9 @@ extern bool disasm; // From 'V6809.CPP'
        if (!LoadImg(ROM4, mcuMem, 0x4000, 0x8000))             // Load 4th ROM
        { cout << "Could not open file '" << ROM4 << "'!" << endl;  return -1; }
 
-       // Load samples if they're there...
-       LoadPSGs();
-//     LoadFMs();
+// Now emulated! :-D
+       // Load PSG samples if they're there...
+//     LoadPSGs();
 
        // Set up V6809 execution contexts
 
@@ -808,10 +702,10 @@ extern bool disasm;       // From 'V6809.CPP'
        mcu.WrMem = MCUWriteMemory;
        mcu.cpuFlags |= V63701_ASSERT_LINE_RESET;
 
-       uint32_t my_clock = 0;
+//     uint32_t my_clock = 0;
        running = true;                                                         // Set running status...
-       trace1 = false;
-       SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
+//     trace1 = false;
+//     SetRefreshRate(refresh2);                                       // Tell GUI our refresh rate
 
        // Set all inputs to inactive...
        input1.byte = input2.byte = input3.byte = input4.byte = input5.byte = 0xFF;
@@ -826,7 +720,6 @@ extern bool disasm; // From 'V6809.CPP'
 #endif
        banksw1 = 0;                   // Will this work?
        banksw2 = 0;
-//        iclock = 0;                // Reset instr clock #1...
        InitGUI();                 // Reset # of coins
 
 WriteLog("About to set up screen...\n");
@@ -835,30 +728,16 @@ WriteLog("About to set up screen...\n");
        oldTicks = SDL_GetTicks();
 
 WriteLog("About to set up audio...\n");
-#if 0
-       // This crap SHOULD be in sound.cpp (not yet created)...
-       SDL_AudioSpec desired, obtained;
-       desired.freq = 22050;
-       desired.format = AUDIO_U8;
-       desired.channels = 1;
-       desired.samples = 600;
-       desired.callback = SoundFunc;
-       desired.userdata = NULL;
-       // Also, should check to see if it got the hardware it needed, correct sample size, etc.
-       if (SDL_OpenAudio(&desired, &obtained) < 0)
-       {
-               cout << "Couldn't open audio: " << SDL_GetError() << endl;
-               return -1;
-       }
-
-       SDL_PauseAudio(0);                                                      // Get that audio going!
-#else
        InitSound();
-#endif
 
 memset(scrBuffer, 0xFF, VIRTUAL_SCREEN_WIDTH*VIRTUAL_SCREEN_HEIGHT*sizeof(uint32_t));
 RenderScreenBuffer();
 
+#if 1
+psg1 = fopen("psgchan1.raw", "wb");
+psg2 = fopen("psgchan3.raw", "wb");
+#endif
+
 WriteLog("About to enter main loop...\n");
        while (running)
        {
@@ -881,16 +760,6 @@ WriteLog("About to enter main loop...\n");
 //gram1[0x423D] = 1;
                //gram1[0x423D] = self_test;                    // Reset DSW1-1
 //             gram1[0x4268] = 0;                                              // Reset Video test
-//             gram1[0x427A] = 0;  gram1[0x427C] = 0;
-               //gram1[0x427B] = 0;  gram1[0x427D] = 0;
-//             gram1[0x427E] = 0;//  gram1[0x427F] = 0;
-//             gram1[0x4280] = 0;//  gram1[0x4281] = 0;
-               //gram1[0x4276] = 0;
-//             gram1[0x426A] = 0;
-               //gram1[0x4278] = 0;
-//             gram1[0x426C] = 0;
-//             gram1[0x4262] = 0;  gram1[0x4260] = 0;
-               //gram1[0x4247] = 0;
 
                // SDL key handling...
 
@@ -1298,11 +1167,16 @@ WriteLog("About to enter main loop...\n");
 
        SDL_Quit();
 
+#if 1
+fclose(psg1);
+fclose(psg2);
+#endif
+#if 0
        // Deallocate sounds if they were loaded
        for(int i=0; i<16; i++)
                if (psg_adrs[i])
                        delete[] psg_adrs[i];
-
+#endif
 #if 0
        for(int i=0; i<14; i++)
                if (fm_adrs[i])