From b4ed1fa8223c24c777ad04e4f18a2afac15eb740 Mon Sep 17 00:00:00 2001 From: saxxonpike Date: Thu, 15 Nov 2012 03:34:28 +0000 Subject: [PATCH] commodore64: remove DCfilter until crashes can be isolated, functional changes to SID implementation for speed --- .../Computers/Commodore64/C64.core.cs | 6 + .../Computers/Commodore64/C64.cs | 2 +- .../Computers/Commodore64/Sid.cs | 115 ++------ .../Commodore64/SidEnvelopeGenerator.cs | 262 ++++++++++-------- .../Computers/Commodore64/SidSoundProvider.cs | 2 +- .../Commodore64/SidWaveformCalculator.cs | 2 +- .../Commodore64/SidWaveformGenerator.cs | 2 +- 7 files changed, 188 insertions(+), 203 deletions(-) diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs index 9fd2955e6c..ee0c4ade09 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.core.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.core.cs @@ -35,6 +35,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 public VicII vic; public ChipSignals signal; + // sid stuff + //private Emulation.Sound.Utilities.DCFilter sidDCFilter; + private SidSyncSoundProvider syncSid; + public void HardReset() { // initalize cpu @@ -57,6 +61,8 @@ namespace BizHawk.Emulation.Computers.Commodore64 // initialize sid sid = new Sid(Region.NTSC, 44100); // we'll assume 44.1k for now until there's a better way + syncSid = new SidSyncSoundProvider(sid); + //sidDCFilter = new Emulation.Sound.Utilities.DCFilter(sid, 2205); // initialize memory (this must be done AFTER all other chips are initialized) string romPath = CoreInputComm.C64_FirmwaresPath; diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs index 1c4619dd7d..5cecb6be53 100644 --- a/BizHawk.Emulation/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs @@ -45,7 +45,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 } /*TODO*/ - public ISyncSoundProvider SyncSoundProvider { get { return new SidSyncSoundProvider(sid); ; } } + public ISyncSoundProvider SyncSoundProvider { get { return syncSid; ; } } public bool StartAsyncSound() { return true; } //TODO public void EndAsyncSound() { } //TODO public bool DeterministicEmulation { get; set; } //TODO diff --git a/BizHawk.Emulation/Computers/Commodore64/Sid.cs b/BizHawk.Emulation/Computers/Commodore64/Sid.cs index aceecdfa8c..45de979130 100644 --- a/BizHawk.Emulation/Computers/Commodore64/Sid.cs +++ b/BizHawk.Emulation/Computers/Commodore64/Sid.cs @@ -12,33 +12,30 @@ namespace BizHawk.Emulation.Computers.Commodore64 public class VoiceRegs { - private EnvelopeGenerator envelope; - private WaveformGenerator generator; - private WaveformGenerator syncSource; + public EnvelopeGenerator Envelope; + public WaveformGenerator Generator; + public WaveformGenerator SyncSource; - private short outputEnvLatch; - private short outputWaveLatch; + public int EnvelopeLatch; + public int GeneratorLatch; public VoiceRegs() { - envelope = new EnvelopeGenerator(); - generator = new WaveformGenerator(WaveformCalculator.BuildTable()); + Envelope = new EnvelopeGenerator(); + Generator = new WaveformGenerator(WaveformCalculator.BuildTable()); } public void Clock() { - generator.Clock(); - envelope.Clock(); - - outputWaveLatch = generator.Output(syncSource); - outputEnvLatch = envelope.Output(); + Generator.Clock(); + GeneratorLatch = Generator.Output(SyncSource); + Envelope.Clock(); + EnvelopeLatch = Envelope.Output; } public short Output() { - int sample = outputWaveLatch; - int velocity = outputEnvLatch; - int result = (sample * velocity) >> 4; + int result = (GeneratorLatch * EnvelopeLatch) >> 4; result -= 32768; if (result > 32767) result = 32767; @@ -47,66 +44,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 return (short)result; } - public byte ReadEnv() - { - return (byte)(outputEnvLatch >> 4); - } - - public int ReadFreq() - { - return generator.ReadFreq(); - } - - public byte ReadOsc() - { - return (byte)(outputWaveLatch >> 4); - } - public void Reset() { - generator.Reset(); - envelope.Reset(); - } - - public void SetSyncSource(VoiceRegs source) - { - syncSource = source.generator; - } - - public void WriteAttackDecay(byte val) - { - envelope.WriteAttackDecay(val); - } - - public void WriteControl(byte val) - { - generator.WriteControl(val); - envelope.WriteControl(val); - } - - public void WriteFreqLo(byte val) - { - generator.WriteFreqLo(val); - } - - public void WriteFreqHi(byte val) - { - generator.WriteFreqHi(val); - } - - public void WritePWLo(byte val) - { - generator.WritePWLo(val); - } - - public void WritePWHi(byte val) - { - generator.WritePWHi(val); - } - - public void WriteSustainRelease(byte val) - { - envelope.WriteSustainRelease(val); + Generator.Reset(); + Envelope.Reset(); } } @@ -133,9 +74,9 @@ namespace BizHawk.Emulation.Computers.Commodore64 Voices[1] = new VoiceRegs(); Voices[2] = new VoiceRegs(); - Voices[0].SetSyncSource(Voices[2]); - Voices[1].SetSyncSource(Voices[0]); - Voices[2].SetSyncSource(Voices[1]); + Voices[0].SyncSource = Voices[2].Generator; + Voices[1].SyncSource = Voices[0].Generator; + Voices[2].SyncSource = Voices[1].Generator; } public byte this[int addr] @@ -144,7 +85,6 @@ namespace BizHawk.Emulation.Computers.Commodore64 get { int result; - int index; addr &= 0x1F; switch (addr) @@ -156,10 +96,10 @@ namespace BizHawk.Emulation.Computers.Commodore64 result = POTY; break; case 0x1B: - result = Voices[2].ReadOsc(); + result = Voices[2].GeneratorLatch >> 4; break; case 0x1C: - result = Voices[2].ReadEnv(); + result = Voices[2].EnvelopeLatch; break; default: result = 0; @@ -179,43 +119,46 @@ namespace BizHawk.Emulation.Computers.Commodore64 case 0x07: case 0x0E: index = addr / 7; - Voices[index].WriteFreqLo(value); + Voices[index].Generator.WriteFreqLo(value); break; case 0x01: case 0x08: case 0x0F: index = addr / 7; - Voices[index].WriteFreqHi(value); + Voices[index].Generator.WriteFreqHi(value); break; case 0x02: case 0x09: case 0x10: index = addr / 7; - Voices[index].WritePWLo(value); + Voices[index].Generator.WritePWLo(value); break; case 0x03: case 0x0A: case 0x11: index = addr / 7; - Voices[index].WritePWHi(value); + Voices[index].Generator.WritePWHi(value); break; case 0x04: case 0x0B: case 0x12: index = addr / 7; - Voices[index].WriteControl(value); + Voices[index].Generator.WriteControl(value); + Voices[index].Envelope.Gate = ((value & 0x01) != 0x00); break; case 0x05: case 0x0C: case 0x13: index = addr / 7; - Voices[index].WriteAttackDecay(value); + Voices[index].Envelope.Attack = (value >> 4); + Voices[index].Envelope.Decay = (value & 0xF); break; case 0x06: case 0x0D: case 0x14: index = addr / 7; - Voices[index].WriteSustainRelease(value); + Voices[index].Envelope.Sustain = (value >> 4); + Voices[index].Envelope.Release = (value & 0xF); break; case 0x15: FC &= 0x7F8; diff --git a/BizHawk.Emulation/Computers/Commodore64/SidEnvelopeGenerator.cs b/BizHawk.Emulation/Computers/Commodore64/SidEnvelopeGenerator.cs index d9e88a4dcc..f84876b7fc 100644 --- a/BizHawk.Emulation/Computers/Commodore64/SidEnvelopeGenerator.cs +++ b/BizHawk.Emulation/Computers/Commodore64/SidEnvelopeGenerator.cs @@ -7,15 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64 { // constants for the EnvelopeGenerator and calculation - // methods come from the libsidplayfp residfp library. + // methods are based from the libsidplayfp residfp library. - class EnvelopeGenerator + public class EnvelopeGenerator { enum State { - Attack, DecaySustain, Release + Attack, Decay, Release } + // value table for the envelope shift register static int[] adsrTable = new int[] { 0x7F00, 0x0006, 0x003C, 0x0330, @@ -27,11 +28,11 @@ namespace BizHawk.Emulation.Computers.Commodore64 int attack; int decay; byte envelopeCounter; - bool envelopePipeline; + bool envelopeProcessEnabled; int exponentialCounter; int exponentialCounterPeriod; + bool freeze; bool gate; - bool holdZero; int lfsr; int rate; int release; @@ -43,13 +44,27 @@ namespace BizHawk.Emulation.Computers.Commodore64 Reset(); } + public int Attack + { + get + { + return attack; + } + set + { + attack = value; + if (state == State.Attack) + rate = adsrTable[attack]; + } + } + public void Clock() { - if (envelopePipeline) + if (envelopeProcessEnabled) { - --envelopeCounter; - envelopePipeline = false; - SetExponentialCounter(); + envelopeProcessEnabled = false; + envelopeCounter--; + UpdateExponentialCounter(); } if (lfsr != rate) @@ -64,144 +79,165 @@ namespace BizHawk.Emulation.Computers.Commodore64 if ((state == State.Attack) || (++exponentialCounter == exponentialCounterPeriod)) { exponentialCounter = 0; - if (holdZero) + if (!freeze) { - return; - } + switch (state) + { + case State.Attack: + ++envelopeCounter; + if (envelopeCounter == 0xFF) + { + state = State.Decay; + rate = adsrTable[decay]; + } + break; + case State.Decay: + if (envelopeCounter == ((sustain << 4) | sustain)) + { + return; + } + if (exponentialCounterPeriod != 1) + { + envelopeProcessEnabled = true; + return; + } + envelopeCounter--; + break; + case State.Release: + if (exponentialCounterPeriod != 1) + { + envelopeProcessEnabled = true; + return; + } + envelopeCounter--; + break; + } - switch (state) - { - case State.Attack: - ++envelopeCounter; - if (envelopeCounter == 0xFF) - { - state = State.DecaySustain; - rate = adsrTable[decay]; - } - break; - case State.DecaySustain: - if (envelopeCounter == ((sustain << 4) | sustain)) - { - return; - } - if (exponentialCounterPeriod != 1) - { - envelopePipeline = true; - return; - } - --envelopeCounter; - break; - case State.Release: - if (exponentialCounterPeriod != 1) - { - envelopePipeline = true; - return; - } - --envelopeCounter; - break; + UpdateExponentialCounter(); } - - SetExponentialCounter(); } } - public short Output() + public int Decay { - return envelopeCounter; + get + { + return decay; + } + set + { + decay = value; + if (state == State.Decay) + rate = adsrTable[decay]; + } } - public byte ReadEnv() + public bool Gate { - return envelopeCounter; + get + { + return gate; + } + set + { + bool gateThis = value; + + if (!gate && gateThis) + { + state = State.Attack; + rate = adsrTable[attack]; + freeze = false; + envelopeProcessEnabled = false; + } + else if (gate && !gateThis) + { + state = State.Release; + rate = adsrTable[release]; + } + + gate = gateThis; + } + } + + public short Output + { + get + { + return envelopeCounter; + } + } + + public int Release + { + get + { + return release; + } + set + { + release = value; + if (state == State.Release) + rate = adsrTable[release]; + } } public void Reset() { - envelopeCounter = 0; - envelopePipeline = false; attack = 0; decay = 0; sustain = 0; release = 0; gate = false; - lfsr = 0x7FFF; + + envelopeCounter = 0; + envelopeProcessEnabled = false; exponentialCounter = 0; exponentialCounterPeriod = 1; + + lfsr = 0x7FFF; state = State.Release; rate = adsrTable[release]; - holdZero = true; + freeze = true; } - private void SetExponentialCounter() + public int Sustain + { + get + { + return sustain; + } + set + { + sustain = value; + } + } + + private void UpdateExponentialCounter() { switch (envelopeCounter) { - case 0xFF: + case 0x00: exponentialCounterPeriod = 1; - break; - case 0x5D: - exponentialCounterPeriod = 2; - break; - case 0x36: - exponentialCounterPeriod = 4; - break; - case 0x1A: - exponentialCounterPeriod = 8; - break; - case 0x0E: - exponentialCounterPeriod = 16; + freeze = true; break; case 0x06: exponentialCounterPeriod = 30; break; - case 0x00: - exponentialCounterPeriod = 1; - holdZero = true; + case 0x0E: + exponentialCounterPeriod = 16; + break; + case 0x1A: + exponentialCounterPeriod = 8; + break; + case 0x36: + exponentialCounterPeriod = 4; + break; + case 0x5D: + exponentialCounterPeriod = 2; + break; + case 0xFF: + exponentialCounterPeriod = 1; break; - } - } - - public void WriteAttackDecay(byte attackDecay) - { - attack = (attackDecay >> 4) & 0x0F; - decay = attackDecay & 0x0F; - if (state == State.Attack) - { - rate = adsrTable[attack]; - } - else if (state == State.DecaySustain) - { - rate = adsrTable[decay]; - } - } - - public void WriteControl(byte control) - { - bool gateNext = ((control & 0x01) != 0); - - if (!gate && gateNext) - { - state = State.Attack; - rate = adsrTable[attack]; - holdZero = false; - envelopePipeline = false; - } - else if (gate && !gateNext) - { - state = State.Release; - rate = adsrTable[release]; - } - - gate = gateNext; - } - - public void WriteSustainRelease(byte sustainRelease) - { - sustain = (sustainRelease >> 4) & 0x0F; - release = sustainRelease & 0x0F; - if (state == State.Release) - { - rate = adsrTable[release]; } } } diff --git a/BizHawk.Emulation/Computers/Commodore64/SidSoundProvider.cs b/BizHawk.Emulation/Computers/Commodore64/SidSoundProvider.cs index 1070b9b54f..301b031fe6 100644 --- a/BizHawk.Emulation/Computers/Commodore64/SidSoundProvider.cs +++ b/BizHawk.Emulation/Computers/Commodore64/SidSoundProvider.cs @@ -85,7 +85,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 mixer += voices[2].Output(); // the mixer is very loud at this point, let's make it quieter - mixer /= 6; + mixer /= 8; if (mixer > 32767) mixer = 326767; diff --git a/BizHawk.Emulation/Computers/Commodore64/SidWaveformCalculator.cs b/BizHawk.Emulation/Computers/Commodore64/SidWaveformCalculator.cs index c30db3194e..303a101fb8 100644 --- a/BizHawk.Emulation/Computers/Commodore64/SidWaveformCalculator.cs +++ b/BizHawk.Emulation/Computers/Commodore64/SidWaveformCalculator.cs @@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // constants for the WaveformCalculator and calculation // methods come from the libsidplayfp residfp library. - static class WaveformCalculator + public static class WaveformCalculator { struct CombinedWaveformConfig { diff --git a/BizHawk.Emulation/Computers/Commodore64/SidWaveformGenerator.cs b/BizHawk.Emulation/Computers/Commodore64/SidWaveformGenerator.cs index 07424d6302..3a49c5e7c4 100644 --- a/BizHawk.Emulation/Computers/Commodore64/SidWaveformGenerator.cs +++ b/BizHawk.Emulation/Computers/Commodore64/SidWaveformGenerator.cs @@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Computers.Commodore64 // constants for the WaveformGenerator and calculation // methods come from the libsidplayfp residfp library. - class WaveformGenerator + public class WaveformGenerator { private int accumulator; private int floatingOutputTtl;