commodore64: oscillator mixing implemented. Fixed triangle waveform.
This commit is contained in:
parent
2a4a4bbc57
commit
52bb5e34e5
|
@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
vic = new VicII(signal, Region.NTSC);
|
||||
|
||||
// initialize sid
|
||||
sid = new Sid();
|
||||
sid = new Sid(Region.NTSC, 88200);
|
||||
|
||||
// initialize memory (this must be done AFTER all other chips are initialized)
|
||||
string romPath = CoreInputComm.C64_FirmwaresPath;
|
||||
|
|
|
@ -271,6 +271,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
public Func<int> ReadPotY;
|
||||
|
||||
public int clock;
|
||||
public int cyclesPerSample;
|
||||
public bool[] envEnable = new bool[3];
|
||||
public int[] envExpCounter = new int[3];
|
||||
public int[] envRate = new int[3];
|
||||
|
@ -281,10 +282,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
public SidRegs regs;
|
||||
public int[] waveClock = new int[3];
|
||||
|
||||
public Sid()
|
||||
public Sid(Region newRegion, int sampleRate)
|
||||
{
|
||||
ReadPotX = DummyReadPot;
|
||||
ReadPotY = DummyReadPot;
|
||||
switch (newRegion)
|
||||
{
|
||||
case Region.NTSC:
|
||||
cyclesPerSample = 14318181 / 14 / sampleRate;
|
||||
break;
|
||||
case Region.PAL:
|
||||
cyclesPerSample = 14318181 / 18 / sampleRate;
|
||||
break;
|
||||
}
|
||||
InitSound(sampleRate);
|
||||
HardReset();
|
||||
}
|
||||
|
||||
|
@ -298,6 +309,18 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
regs = new SidRegs();
|
||||
}
|
||||
|
||||
private short Mix(int input, short mixSource)
|
||||
{
|
||||
input &= 0xFFF;
|
||||
input -= 0x800;
|
||||
input += mixSource;
|
||||
if (input > 32767)
|
||||
input = 32767;
|
||||
else if (input < -32768)
|
||||
input = -32768;
|
||||
return (short)input;
|
||||
}
|
||||
|
||||
public byte Peek(int addr)
|
||||
{
|
||||
return regs[addr & 0x1F];
|
||||
|
@ -312,6 +335,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
ProcessVoice(1);
|
||||
ProcessVoice(2);
|
||||
|
||||
SubmitSample();
|
||||
|
||||
// query pots every 512 cycles
|
||||
if ((clock & 0x1FF) == 0x000)
|
||||
{
|
||||
|
@ -364,19 +389,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
int sawOutput;
|
||||
int squOutput;
|
||||
int noiseOutput;
|
||||
int finalOutput = 0xFFFFFF;
|
||||
int finalOutput = 0xFFF;
|
||||
bool outputEnabled = false;
|
||||
|
||||
// triangle waveform
|
||||
if (regs.TRI[index])
|
||||
{
|
||||
triOutput = waveClock[index] >> 12;
|
||||
triOutput = (waveClock[index] >> 12) & 0xFFF;
|
||||
if (regs.SYNC[index])
|
||||
triOutput ^= regs.OSC[syncIndex[index]] & 0x800;
|
||||
|
||||
if ((triOutput & 0x800) != 0x000)
|
||||
triOutput &= 0xFFF;
|
||||
triOutput ^= 0x7FF;
|
||||
|
||||
triOutput &= 0x7FF;
|
||||
triOutput <<= 1;
|
||||
finalOutput &= triOutput;
|
||||
outputEnabled = true;
|
||||
|
@ -385,7 +411,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
// saw waveform
|
||||
if (regs.SAW[index])
|
||||
{
|
||||
sawOutput = waveClock[index] >> 12;
|
||||
sawOutput = (waveClock[index] >> 12) & 0xFFF;
|
||||
finalOutput &= sawOutput;
|
||||
outputEnabled = true;
|
||||
}
|
||||
|
@ -399,7 +425,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
}
|
||||
else
|
||||
{
|
||||
if (regs.PW[index] >= (waveClock[index] >> 12))
|
||||
if (regs.PW[index] >= ((waveClock[index] >> 12) & 0xFFF))
|
||||
squOutput = 0xFFF;
|
||||
else
|
||||
squOutput = 0x000;
|
||||
|
@ -447,7 +473,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
if (outputEnabled)
|
||||
regs.OSC[index] = finalOutput;
|
||||
else
|
||||
regs.OSC[index] = 0x000000;
|
||||
regs.OSC[index] = 0x000;
|
||||
}
|
||||
|
||||
public byte Read(ushort addr)
|
||||
|
|
|
@ -7,12 +7,37 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
{
|
||||
public partial class Sid : ISoundProvider
|
||||
{
|
||||
private short[] sampleBuffer;
|
||||
private int sampleBufferCapacity;
|
||||
private int sampleBufferIndex;
|
||||
private int sampleBufferReadIndex;
|
||||
private int sampleCounter;
|
||||
|
||||
public void GetSamples(short[] samples)
|
||||
{
|
||||
int count = samples.Length;
|
||||
int copied = 0;
|
||||
|
||||
while ((sampleBufferIndex != sampleBufferReadIndex) && (copied < count))
|
||||
{
|
||||
samples[copied] = sampleBuffer[sampleBufferReadIndex++];
|
||||
copied++;
|
||||
if (sampleBufferReadIndex == sampleBufferCapacity)
|
||||
sampleBufferReadIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitSound(int initSampleRate)
|
||||
{
|
||||
sampleBufferCapacity = initSampleRate;
|
||||
DiscardSamples();
|
||||
}
|
||||
|
||||
public void DiscardSamples()
|
||||
{
|
||||
sampleBuffer = new short[sampleBufferCapacity];
|
||||
sampleBufferReadIndex = 0;
|
||||
sampleBufferIndex = 0;
|
||||
}
|
||||
|
||||
public int MaxVolume
|
||||
|
@ -25,5 +50,26 @@ namespace BizHawk.Emulation.Computers.Commodore64
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void SubmitSample()
|
||||
{
|
||||
if (sampleCounter == 0)
|
||||
{
|
||||
short output;
|
||||
output = Mix(regs.OSC[0], 0);
|
||||
output = Mix(regs.OSC[1], output);
|
||||
if (!regs.D3 && !regs.FILT[2])
|
||||
output = Mix(regs.OSC[2], output);
|
||||
|
||||
// disable sound for now...
|
||||
output = 0;
|
||||
sampleCounter = cyclesPerSample;
|
||||
sampleBuffer[sampleBufferIndex] = output;
|
||||
sampleBufferIndex++;
|
||||
if (sampleBufferIndex == sampleBufferCapacity)
|
||||
sampleBufferIndex = 0;
|
||||
}
|
||||
sampleCounter--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue