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 VicII vic;
public ChipSignals signal; public ChipSignals signal;
// sid stuff
//private Emulation.Sound.Utilities.DCFilter sidDCFilter;
private SidSyncSoundProvider syncSid;
public void HardReset() public void HardReset()
{ {
// initalize cpu // initalize cpu
@ -57,6 +61,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
// initialize sid // initialize sid
sid = new Sid(Region.NTSC, 44100); // we'll assume 44.1k for now until there's a better way 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) // initialize memory (this must be done AFTER all other chips are initialized)
string romPath = CoreInputComm.C64_FirmwaresPath; string romPath = CoreInputComm.C64_FirmwaresPath;

View File

@ -45,7 +45,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
} }
/*TODO*/ /*TODO*/
public ISyncSoundProvider SyncSoundProvider { get { return new SidSyncSoundProvider(sid); ; } } public ISyncSoundProvider SyncSoundProvider { get { return syncSid; ; } }
public bool StartAsyncSound() { return true; } //TODO public bool StartAsyncSound() { return true; } //TODO
public void EndAsyncSound() { } //TODO public void EndAsyncSound() { } //TODO
public bool DeterministicEmulation { get; set; } //TODO public bool DeterministicEmulation { get; set; } //TODO

View File

@ -12,33 +12,30 @@ namespace BizHawk.Emulation.Computers.Commodore64
public class VoiceRegs public class VoiceRegs
{ {
private EnvelopeGenerator envelope; public EnvelopeGenerator Envelope;
private WaveformGenerator generator; public WaveformGenerator Generator;
private WaveformGenerator syncSource; public WaveformGenerator SyncSource;
private short outputEnvLatch; public int EnvelopeLatch;
private short outputWaveLatch; public int GeneratorLatch;
public VoiceRegs() public VoiceRegs()
{ {
envelope = new EnvelopeGenerator(); Envelope = new EnvelopeGenerator();
generator = new WaveformGenerator(WaveformCalculator.BuildTable()); Generator = new WaveformGenerator(WaveformCalculator.BuildTable());
} }
public void Clock() public void Clock()
{ {
generator.Clock(); Generator.Clock();
envelope.Clock(); GeneratorLatch = Generator.Output(SyncSource);
Envelope.Clock();
outputWaveLatch = generator.Output(syncSource); EnvelopeLatch = Envelope.Output;
outputEnvLatch = envelope.Output();
} }
public short Output() public short Output()
{ {
int sample = outputWaveLatch; int result = (GeneratorLatch * EnvelopeLatch) >> 4;
int velocity = outputEnvLatch;
int result = (sample * velocity) >> 4;
result -= 32768; result -= 32768;
if (result > 32767) if (result > 32767)
result = 32767; result = 32767;
@ -47,66 +44,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
return (short)result; 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() public void Reset()
{ {
generator.Reset(); Generator.Reset();
envelope.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);
} }
} }
@ -133,9 +74,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
Voices[1] = new VoiceRegs(); Voices[1] = new VoiceRegs();
Voices[2] = new VoiceRegs(); Voices[2] = new VoiceRegs();
Voices[0].SetSyncSource(Voices[2]); Voices[0].SyncSource = Voices[2].Generator;
Voices[1].SetSyncSource(Voices[0]); Voices[1].SyncSource = Voices[0].Generator;
Voices[2].SetSyncSource(Voices[1]); Voices[2].SyncSource = Voices[1].Generator;
} }
public byte this[int addr] public byte this[int addr]
@ -144,7 +85,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
get get
{ {
int result; int result;
int index;
addr &= 0x1F; addr &= 0x1F;
switch (addr) switch (addr)
@ -156,10 +96,10 @@ namespace BizHawk.Emulation.Computers.Commodore64
result = POTY; result = POTY;
break; break;
case 0x1B: case 0x1B:
result = Voices[2].ReadOsc(); result = Voices[2].GeneratorLatch >> 4;
break; break;
case 0x1C: case 0x1C:
result = Voices[2].ReadEnv(); result = Voices[2].EnvelopeLatch;
break; break;
default: default:
result = 0; result = 0;
@ -179,43 +119,46 @@ namespace BizHawk.Emulation.Computers.Commodore64
case 0x07: case 0x07:
case 0x0E: case 0x0E:
index = addr / 7; index = addr / 7;
Voices[index].WriteFreqLo(value); Voices[index].Generator.WriteFreqLo(value);
break; break;
case 0x01: case 0x01:
case 0x08: case 0x08:
case 0x0F: case 0x0F:
index = addr / 7; index = addr / 7;
Voices[index].WriteFreqHi(value); Voices[index].Generator.WriteFreqHi(value);
break; break;
case 0x02: case 0x02:
case 0x09: case 0x09:
case 0x10: case 0x10:
index = addr / 7; index = addr / 7;
Voices[index].WritePWLo(value); Voices[index].Generator.WritePWLo(value);
break; break;
case 0x03: case 0x03:
case 0x0A: case 0x0A:
case 0x11: case 0x11:
index = addr / 7; index = addr / 7;
Voices[index].WritePWHi(value); Voices[index].Generator.WritePWHi(value);
break; break;
case 0x04: case 0x04:
case 0x0B: case 0x0B:
case 0x12: case 0x12:
index = addr / 7; index = addr / 7;
Voices[index].WriteControl(value); Voices[index].Generator.WriteControl(value);
Voices[index].Envelope.Gate = ((value & 0x01) != 0x00);
break; break;
case 0x05: case 0x05:
case 0x0C: case 0x0C:
case 0x13: case 0x13:
index = addr / 7; index = addr / 7;
Voices[index].WriteAttackDecay(value); Voices[index].Envelope.Attack = (value >> 4);
Voices[index].Envelope.Decay = (value & 0xF);
break; break;
case 0x06: case 0x06:
case 0x0D: case 0x0D:
case 0x14: case 0x14:
index = addr / 7; index = addr / 7;
Voices[index].WriteSustainRelease(value); Voices[index].Envelope.Sustain = (value >> 4);
Voices[index].Envelope.Release = (value & 0xF);
break; break;
case 0x15: case 0x15:
FC &= 0x7F8; FC &= 0x7F8;

View File

@ -7,15 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
// constants for the EnvelopeGenerator and calculation // 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 enum State
{ {
Attack, DecaySustain, Release Attack, Decay, Release
} }
// value table for the envelope shift register
static int[] adsrTable = new int[] static int[] adsrTable = new int[]
{ {
0x7F00, 0x0006, 0x003C, 0x0330, 0x7F00, 0x0006, 0x003C, 0x0330,
@ -27,11 +28,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
int attack; int attack;
int decay; int decay;
byte envelopeCounter; byte envelopeCounter;
bool envelopePipeline; bool envelopeProcessEnabled;
int exponentialCounter; int exponentialCounter;
int exponentialCounterPeriod; int exponentialCounterPeriod;
bool freeze;
bool gate; bool gate;
bool holdZero;
int lfsr; int lfsr;
int rate; int rate;
int release; int release;
@ -43,13 +44,27 @@ namespace BizHawk.Emulation.Computers.Commodore64
Reset(); Reset();
} }
public int Attack
{
get
{
return attack;
}
set
{
attack = value;
if (state == State.Attack)
rate = adsrTable[attack];
}
}
public void Clock() public void Clock()
{ {
if (envelopePipeline) if (envelopeProcessEnabled)
{ {
--envelopeCounter; envelopeProcessEnabled = false;
envelopePipeline = false; envelopeCounter--;
SetExponentialCounter(); UpdateExponentialCounter();
} }
if (lfsr != rate) if (lfsr != rate)
@ -64,144 +79,165 @@ namespace BizHawk.Emulation.Computers.Commodore64
if ((state == State.Attack) || (++exponentialCounter == exponentialCounterPeriod)) if ((state == State.Attack) || (++exponentialCounter == exponentialCounterPeriod))
{ {
exponentialCounter = 0; exponentialCounter = 0;
if (holdZero) if (!freeze)
{ {
return;
}
switch (state) switch (state)
{ {
case State.Attack: case State.Attack:
++envelopeCounter; ++envelopeCounter;
if (envelopeCounter == 0xFF) if (envelopeCounter == 0xFF)
{ {
state = State.DecaySustain; state = State.Decay;
rate = adsrTable[decay]; rate = adsrTable[decay];
} }
break; break;
case State.DecaySustain: case State.Decay:
if (envelopeCounter == ((sustain << 4) | sustain)) if (envelopeCounter == ((sustain << 4) | sustain))
{ {
return; return;
} }
if (exponentialCounterPeriod != 1) if (exponentialCounterPeriod != 1)
{ {
envelopePipeline = true; envelopeProcessEnabled = true;
return; return;
} }
--envelopeCounter; envelopeCounter--;
break; break;
case State.Release: case State.Release:
if (exponentialCounterPeriod != 1) if (exponentialCounterPeriod != 1)
{ {
envelopePipeline = true; envelopeProcessEnabled = true;
return; return;
} }
--envelopeCounter; envelopeCounter--;
break; break;
} }
SetExponentialCounter(); UpdateExponentialCounter();
}
} }
} }
public short Output() public int Decay
{
get
{
return decay;
}
set
{
decay = value;
if (state == State.Decay)
rate = adsrTable[decay];
}
}
public bool Gate
{
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; return envelopeCounter;
} }
}
public byte ReadEnv() public int Release
{ {
return envelopeCounter; get
{
return release;
}
set
{
release = value;
if (state == State.Release)
rate = adsrTable[release];
}
} }
public void Reset() public void Reset()
{ {
envelopeCounter = 0;
envelopePipeline = false;
attack = 0; attack = 0;
decay = 0; decay = 0;
sustain = 0; sustain = 0;
release = 0; release = 0;
gate = false; gate = false;
lfsr = 0x7FFF;
envelopeCounter = 0;
envelopeProcessEnabled = false;
exponentialCounter = 0; exponentialCounter = 0;
exponentialCounterPeriod = 1; exponentialCounterPeriod = 1;
lfsr = 0x7FFF;
state = State.Release; state = State.Release;
rate = adsrTable[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) switch (envelopeCounter)
{ {
case 0xFF: case 0x00:
exponentialCounterPeriod = 1; exponentialCounterPeriod = 1;
break; freeze = true;
case 0x5D:
exponentialCounterPeriod = 2;
break;
case 0x36:
exponentialCounterPeriod = 4;
break;
case 0x1A:
exponentialCounterPeriod = 8;
break;
case 0x0E:
exponentialCounterPeriod = 16;
break; break;
case 0x06: case 0x06:
exponentialCounterPeriod = 30; exponentialCounterPeriod = 30;
break; break;
case 0x00: case 0x0E:
exponentialCounterPeriod = 1; exponentialCounterPeriod = 16;
holdZero = true; break;
case 0x1A:
exponentialCounterPeriod = 8;
break;
case 0x36:
exponentialCounterPeriod = 4;
break;
case 0x5D:
exponentialCounterPeriod = 2;
break;
case 0xFF:
exponentialCounterPeriod = 1;
break; 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(); mixer += voices[2].Output();
// the mixer is very loud at this point, let's make it quieter // the mixer is very loud at this point, let's make it quieter
mixer /= 6; mixer /= 8;
if (mixer > 32767) if (mixer > 32767)
mixer = 326767; mixer = 326767;

View File

@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
// constants for the WaveformCalculator and calculation // constants for the WaveformCalculator and calculation
// methods come from the libsidplayfp residfp library. // methods come from the libsidplayfp residfp library.
static class WaveformCalculator public static class WaveformCalculator
{ {
struct CombinedWaveformConfig struct CombinedWaveformConfig
{ {

View File

@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
// constants for the WaveformGenerator and calculation // constants for the WaveformGenerator and calculation
// methods come from the libsidplayfp residfp library. // methods come from the libsidplayfp residfp library.
class WaveformGenerator public class WaveformGenerator
{ {
private int accumulator; private int accumulator;
private int floatingOutputTtl; private int floatingOutputTtl;