commodore64: SID waveform data is now in a lookup table, increases performance and startup time
This commit is contained in:
parent
b4ed1fa822
commit
94beebdbde
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
public VoiceRegs()
|
public VoiceRegs()
|
||||||
{
|
{
|
||||||
Envelope = new EnvelopeGenerator();
|
Envelope = new EnvelopeGenerator();
|
||||||
Generator = new WaveformGenerator(WaveformCalculator.BuildTable());
|
Generator = new WaveformGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clock()
|
public void Clock()
|
||||||
|
@ -119,31 +119,35 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
case 0x07:
|
case 0x07:
|
||||||
case 0x0E:
|
case 0x0E:
|
||||||
index = addr / 7;
|
index = addr / 7;
|
||||||
Voices[index].Generator.WriteFreqLo(value);
|
Voices[index].Generator.Frequency &= 0xFF00;
|
||||||
|
Voices[index].Generator.Frequency |= value;
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
case 0x08:
|
case 0x08:
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
index = addr / 7;
|
index = addr / 7;
|
||||||
Voices[index].Generator.WriteFreqHi(value);
|
Voices[index].Generator.Frequency &= 0xFF;
|
||||||
|
Voices[index].Generator.Frequency |= (int)value << 8;
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
case 0x09:
|
case 0x09:
|
||||||
case 0x10:
|
case 0x10:
|
||||||
index = addr / 7;
|
index = addr / 7;
|
||||||
Voices[index].Generator.WritePWLo(value);
|
Voices[index].Generator.PulseWidth &= 0x0F00;
|
||||||
|
Voices[index].Generator.PulseWidth |= value;
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
case 0x11:
|
case 0x11:
|
||||||
index = addr / 7;
|
index = addr / 7;
|
||||||
Voices[index].Generator.WritePWHi(value);
|
Voices[index].Generator.PulseWidth &= 0xFF;
|
||||||
|
Voices[index].Generator.PulseWidth |= (int)(value & 0xF) << 8;
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
case 0x12:
|
case 0x12:
|
||||||
index = addr / 7;
|
index = addr / 7;
|
||||||
Voices[index].Generator.WriteControl(value);
|
Voices[index].Generator.Control = value;
|
||||||
Voices[index].Envelope.Gate = ((value & 0x01) != 0x00);
|
Voices[index].Envelope.Gate = ((value & 0x01) != 0x00);
|
||||||
break;
|
break;
|
||||||
case 0x05:
|
case 0x05:
|
||||||
|
@ -241,6 +245,13 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
voices[0].Clock();
|
voices[0].Clock();
|
||||||
voices[1].Clock();
|
voices[1].Clock();
|
||||||
voices[2].Clock();
|
voices[2].Clock();
|
||||||
|
|
||||||
|
// sync voices
|
||||||
|
voices[0].Generator.Synchronize(voices[1].Generator, voices[2].Generator);
|
||||||
|
voices[1].Generator.Synchronize(voices[2].Generator, voices[0].Generator);
|
||||||
|
voices[2].Generator.Synchronize(voices[0].Generator, voices[1].Generator);
|
||||||
|
|
||||||
|
// finalize sample and put into buffer
|
||||||
SubmitSample();
|
SubmitSample();
|
||||||
|
|
||||||
// query pots every 512 cycles
|
// query pots every 512 cycles
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,32 +9,33 @@ 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.
|
||||||
|
|
||||||
public class WaveformGenerator
|
public partial class WaveformGenerator
|
||||||
{
|
{
|
||||||
private int accumulator;
|
private int accumulator;
|
||||||
|
private byte control;
|
||||||
private int floatingOutputTtl;
|
private int floatingOutputTtl;
|
||||||
private int freq;
|
private int freq;
|
||||||
private short[][] modelWave;
|
|
||||||
private bool msbRising;
|
private bool msbRising;
|
||||||
private int noiseOutput;
|
private int noiseOutput;
|
||||||
private int noNoise;
|
|
||||||
private int noNoiseOrNoiseOutput;
|
|
||||||
private int noPulse;
|
|
||||||
private int pulseOutput;
|
private int pulseOutput;
|
||||||
private int pw;
|
private int pw;
|
||||||
private int ringMsbMask;
|
private int ringMsbMask;
|
||||||
private int shiftPipeline;
|
|
||||||
private int shiftRegister;
|
private int shiftRegister;
|
||||||
private int shiftRegisterReset;
|
private int shiftRegisterDelay;
|
||||||
|
private int shiftRegisterResetDelay;
|
||||||
private bool sync;
|
private bool sync;
|
||||||
private bool test;
|
private bool test;
|
||||||
private short[] wave;
|
private short[] wave;
|
||||||
private int waveform;
|
private int waveform;
|
||||||
private int waveformOutput;
|
private int waveformOutput;
|
||||||
|
|
||||||
public WaveformGenerator(short[][] newModelWave)
|
// these are temp values used to speed up calculation
|
||||||
|
private int noNoise;
|
||||||
|
private int noNoiseOrNoiseOutput;
|
||||||
|
private int noPulse;
|
||||||
|
|
||||||
|
public WaveformGenerator()
|
||||||
{
|
{
|
||||||
modelWave = newModelWave;
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,11 +43,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
{
|
{
|
||||||
if (test)
|
if (test)
|
||||||
{
|
{
|
||||||
if (shiftRegisterReset != 0 && --shiftRegisterReset == 0)
|
pulseOutput = 0xFFF;
|
||||||
|
if (shiftRegisterResetDelay != 0 && --shiftRegisterResetDelay == 0)
|
||||||
{
|
{
|
||||||
ResetShiftRegister();
|
ResetShiftRegister();
|
||||||
}
|
}
|
||||||
pulseOutput = 0xFFF;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -58,9 +59,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
|
|
||||||
if ((accumulatorBitsSet & 0x080000) != 0)
|
if ((accumulatorBitsSet & 0x080000) != 0)
|
||||||
{
|
{
|
||||||
shiftPipeline = 2;
|
shiftRegisterDelay = 2;
|
||||||
}
|
}
|
||||||
else if (shiftPipeline != 0 && --shiftPipeline == 0)
|
else if (shiftRegisterDelay != 0 && --shiftRegisterDelay == 0)
|
||||||
{
|
{
|
||||||
ClockShiftRegister();
|
ClockShiftRegister();
|
||||||
}
|
}
|
||||||
|
@ -71,7 +72,62 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
{
|
{
|
||||||
int bit0 = ((shiftRegister >> 22) ^ (shiftRegister >> 17)) & 0x1;
|
int bit0 = ((shiftRegister >> 22) ^ (shiftRegister >> 17)) & 0x1;
|
||||||
shiftRegister = ((shiftRegister << 1) | bit0) & 0x7FFFFF;
|
shiftRegister = ((shiftRegister << 1) | bit0) & 0x7FFFFF;
|
||||||
SetNoiseOutput();
|
UpdateNoiseOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte Control
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
control = value;
|
||||||
|
|
||||||
|
int waveformPrev = waveform;
|
||||||
|
bool testPrev = test;
|
||||||
|
waveform = (control >> 4) & 0x0F;
|
||||||
|
test = (control & 0x08) != 0;
|
||||||
|
sync = (control & 0x02) != 0;
|
||||||
|
|
||||||
|
wave = WaveformSamples[waveform & 0x7];
|
||||||
|
ringMsbMask = ((~control >> 5) & (control >> 2) & 0x1) << 23;
|
||||||
|
noNoise = (waveform & 0x8) != 0 ? 0x000 : 0xFFF;
|
||||||
|
noNoiseOrNoiseOutput = noNoise | noiseOutput;
|
||||||
|
noPulse = (waveform & 0x4) != 0 ? 0x000 : 0xFFF;
|
||||||
|
|
||||||
|
if (!testPrev && test)
|
||||||
|
{
|
||||||
|
accumulator = 0;
|
||||||
|
shiftRegisterDelay = 0;
|
||||||
|
shiftRegisterResetDelay = 0x8000;
|
||||||
|
}
|
||||||
|
else if (testPrev && !test)
|
||||||
|
{
|
||||||
|
int bit0 = (~shiftRegister >> 17) & 0x1;
|
||||||
|
shiftRegister = ((shiftRegister << 1) | bit0) & 0x7FFFFF;
|
||||||
|
UpdateNoiseOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waveform == 0 && waveformPrev != 0)
|
||||||
|
{
|
||||||
|
floatingOutputTtl = 0x28000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int Frequency
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
freq = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public short Output(WaveformGenerator ringModulator)
|
public short Output(WaveformGenerator ringModulator)
|
||||||
|
@ -96,47 +152,39 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
return (short)waveformOutput;
|
return (short)waveformOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadAccumulator()
|
public int PulseWidth
|
||||||
{
|
{
|
||||||
return accumulator;
|
get
|
||||||
|
{
|
||||||
|
return pw;
|
||||||
}
|
}
|
||||||
|
set
|
||||||
public int ReadFreq()
|
|
||||||
{
|
{
|
||||||
return freq;
|
pw = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte ReadOsc()
|
|
||||||
{
|
|
||||||
return (byte)(waveformOutput >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReadSync()
|
|
||||||
{
|
|
||||||
return sync;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReadTest()
|
|
||||||
{
|
|
||||||
return test;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
accumulator = 0;
|
control = 0;
|
||||||
|
waveform = 0;
|
||||||
freq = 0;
|
freq = 0;
|
||||||
pw = 0;
|
pw = 0;
|
||||||
msbRising = false;
|
accumulator = 0;
|
||||||
waveform = 0;
|
|
||||||
test = false;
|
test = false;
|
||||||
sync = false;
|
sync = false;
|
||||||
wave = modelWave[0];
|
|
||||||
|
msbRising = false;
|
||||||
|
wave = WaveformSamples[0];
|
||||||
ringMsbMask = 0;
|
ringMsbMask = 0;
|
||||||
|
|
||||||
noNoise = 0xFFF;
|
noNoise = 0xFFF;
|
||||||
noPulse = 0xFFF;
|
noPulse = 0xFFF;
|
||||||
pulseOutput = 0xFFF;
|
pulseOutput = 0xFFF;
|
||||||
|
|
||||||
ResetShiftRegister();
|
ResetShiftRegister();
|
||||||
shiftPipeline = 0;
|
|
||||||
|
shiftRegisterDelay = 0;
|
||||||
waveformOutput = 0;
|
waveformOutput = 0;
|
||||||
floatingOutputTtl = 0;
|
floatingOutputTtl = 0;
|
||||||
}
|
}
|
||||||
|
@ -144,11 +192,19 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
private void ResetShiftRegister()
|
private void ResetShiftRegister()
|
||||||
{
|
{
|
||||||
shiftRegister = 0x7FFFFF;
|
shiftRegister = 0x7FFFFF;
|
||||||
shiftRegisterReset = 0;
|
shiftRegisterResetDelay = 0;
|
||||||
SetNoiseOutput();
|
UpdateNoiseOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetNoiseOutput()
|
public void Synchronize(WaveformGenerator syncDest, WaveformGenerator syncSource)
|
||||||
|
{
|
||||||
|
if (msbRising && syncDest.sync && !(sync && syncSource.msbRising))
|
||||||
|
{
|
||||||
|
syncDest.accumulator = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateNoiseOutput()
|
||||||
{
|
{
|
||||||
noiseOutput =
|
noiseOutput =
|
||||||
((shiftRegister & 0x100000) >> 9) |
|
((shiftRegister & 0x100000) >> 9) |
|
||||||
|
@ -162,71 +218,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
||||||
noNoiseOrNoiseOutput = noNoise | noiseOutput;
|
noNoiseOrNoiseOutput = noNoise | noiseOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Synchronize(WaveformGenerator syncDest, WaveformGenerator syncSource)
|
|
||||||
{
|
|
||||||
if (msbRising && syncDest.sync && !(sync && syncSource.msbRising))
|
|
||||||
{
|
|
||||||
syncDest.accumulator = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteControl(byte control)
|
|
||||||
{
|
|
||||||
int waveformPrev = waveform;
|
|
||||||
bool testPrev = test;
|
|
||||||
waveform = (control >> 4) & 0x0F;
|
|
||||||
test = (control & 0x08) != 0;
|
|
||||||
sync = (control & 0x02) != 0;
|
|
||||||
|
|
||||||
wave = modelWave[waveform & 0x7];
|
|
||||||
ringMsbMask = ((~control >> 5) & (control >> 2) & 0x1) << 23;
|
|
||||||
noNoise = (waveform & 0x8) != 0 ? 0x000 : 0xFFF;
|
|
||||||
noNoiseOrNoiseOutput = noNoise | noiseOutput;
|
|
||||||
noPulse = (waveform & 0x4) != 0 ? 0x000 : 0xFFF;
|
|
||||||
|
|
||||||
if (!testPrev && test)
|
|
||||||
{
|
|
||||||
accumulator = 0;
|
|
||||||
shiftPipeline = 0;
|
|
||||||
shiftRegisterReset = 0x8000;
|
|
||||||
}
|
|
||||||
else if (testPrev && !test)
|
|
||||||
{
|
|
||||||
int bit0 = (~shiftRegister >> 17) & 0x1;
|
|
||||||
shiftRegister = ((shiftRegister << 1) | bit0) & 0x7FFFFF;
|
|
||||||
SetNoiseOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waveform == 0 && waveformPrev != 0)
|
|
||||||
{
|
|
||||||
floatingOutputTtl = 0x28000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteFreqLo(byte freqLo)
|
|
||||||
{
|
|
||||||
freq &= 0xFF00;
|
|
||||||
freq |= freqLo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteFreqHi(byte freqHi)
|
|
||||||
{
|
|
||||||
freq &= 0x00FF;
|
|
||||||
freq |= (int)(freqHi << 8) & 0xFF00;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WritePWLo(byte pwLo)
|
|
||||||
{
|
|
||||||
pw &= 0x0F00;
|
|
||||||
pw |= pwLo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WritePWHi(byte pwHi)
|
|
||||||
{
|
|
||||||
pw &= 0x00FF;
|
|
||||||
pw |= (int)(pwHi << 8) & 0x0F00;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteShiftRegister()
|
private void WriteShiftRegister()
|
||||||
{
|
{
|
||||||
shiftRegister &=
|
shiftRegister &=
|
||||||
|
|
Loading…
Reference in New Issue