commodore64: remove DCfilter until crashes can be isolated, functional changes to SID implementation for speed
This commit is contained in:
parent
0223225388
commit
b4ed1fa822
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue