--- /dev/null
+//
+// 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];
+}
+
#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);
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 };
{
// 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;
{
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;
snd_num = snd;
// SpawnMsg(MSHOWNUMS);
+ // Voice type sounds...
if (type == GAMESOUND)
{
// Will that do it??? Yes!!!
chan2_go = true;
}
}
+#if 0
else if (type == PSGSOUND)
{
if (snd_num & 0x10) // Second channel?
chan4_go = false; // No sound loaded, so don't do it!
}
}
+#endif
#if 0
else if (type == FMSOUND)
{
}
-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))
{
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;
{
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;
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++];
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;
}
}
#include <time.h>
#include "gui.h"
#include "log.h"
+#include "psg.h"
#include "screen.h"
#include "sound.h"
#include "v63701.h"
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...
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
}
}
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];
}
{
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;
}
else if (address == 0x2001)
{
-//printf("Writing $%02X to YM2151 register $%02X...\n", data, ymRegister);
YMWriteReg(0, ymRegister, data);
return;
}
}
+#if 0
//
// Load PSG samples from disk
//
}
}
}
-
-
-#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;
//
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
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; }
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
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;
#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");
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)
{
//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...
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])