From: Shamus Hammons Date: Wed, 23 Apr 2014 13:34:20 +0000 (-0500) Subject: Thunder now works with NO samples! \o/ X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=thunder;a=commitdiff_plain;h=009359ef732411d9d978d137f1371647abc97261 Thunder now works with NO samples! \o/ --- diff --git a/makefile b/makefile index a382000..fdf79bc 100644 --- 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 index 0000000..b4f3f47 --- /dev/null +++ b/src/psg.cpp @@ -0,0 +1,209 @@ +// +// PSG handler +// +// This emulates the Rolling Thunder PSG (Namco CUS30) +// +// by James Hammons +// (C) 2014 Underground Software +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ----------------------------------------------------------- +// JLH 04/21/2014 Created this file. +// + +#include "psg.h" +#include +#include + + +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> 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> 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 index 0000000..c8b4452 --- /dev/null +++ b/src/psg.h @@ -0,0 +1,12 @@ +#ifndef __PSG_H__ +#define __PSG_H__ + +#include + +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__ + diff --git a/src/sound.cpp b/src/sound.cpp index 744eafa..3be7683 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -13,9 +13,13 @@ #include "sound.h" #include +#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; } } diff --git a/src/thunder.cpp b/src/thunder.cpp index d1ebfde..18cf8df 100644 --- a/src/thunder.cpp +++ b/src/thunder.cpp @@ -28,6 +28,7 @@ #include #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])