commodore64: remove DCfilter until crashes can be isolated, functional changes to SID implementation for speed

This commit is contained in:
saxxonpike 2012-11-15 03:34:28 +00:00
parent 0223225388
commit b4ed1fa822
7 changed files with 188 additions and 203 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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];
}
}
}

View File

@ -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;

View File

@ -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
{

View File

@ -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;