commodore64: oscillator mixing implemented. Fixed triangle waveform.

This commit is contained in:
saxxonpike 2012-11-12 20:58:07 +00:00
parent 2a4a4bbc57
commit 52bb5e34e5
3 changed files with 80 additions and 8 deletions

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
vic = new VicII(signal, Region.NTSC); vic = new VicII(signal, Region.NTSC);
// initialize sid // initialize sid
sid = new Sid(); sid = new Sid(Region.NTSC, 88200);
// 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

@ -271,6 +271,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public Func<int> ReadPotY; public Func<int> ReadPotY;
public int clock; public int clock;
public int cyclesPerSample;
public bool[] envEnable = new bool[3]; public bool[] envEnable = new bool[3];
public int[] envExpCounter = new int[3]; public int[] envExpCounter = new int[3];
public int[] envRate = new int[3]; public int[] envRate = new int[3];
@ -281,10 +282,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
public SidRegs regs; public SidRegs regs;
public int[] waveClock = new int[3]; public int[] waveClock = new int[3];
public Sid() public Sid(Region newRegion, int sampleRate)
{ {
ReadPotX = DummyReadPot; ReadPotX = DummyReadPot;
ReadPotY = DummyReadPot; ReadPotY = DummyReadPot;
switch (newRegion)
{
case Region.NTSC:
cyclesPerSample = 14318181 / 14 / sampleRate;
break;
case Region.PAL:
cyclesPerSample = 14318181 / 18 / sampleRate;
break;
}
InitSound(sampleRate);
HardReset(); HardReset();
} }
@ -298,6 +309,18 @@ namespace BizHawk.Emulation.Computers.Commodore64
regs = new SidRegs(); 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) public byte Peek(int addr)
{ {
return regs[addr & 0x1F]; return regs[addr & 0x1F];
@ -312,6 +335,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
ProcessVoice(1); ProcessVoice(1);
ProcessVoice(2); ProcessVoice(2);
SubmitSample();
// query pots every 512 cycles // query pots every 512 cycles
if ((clock & 0x1FF) == 0x000) if ((clock & 0x1FF) == 0x000)
{ {
@ -364,19 +389,20 @@ namespace BizHawk.Emulation.Computers.Commodore64
int sawOutput; int sawOutput;
int squOutput; int squOutput;
int noiseOutput; int noiseOutput;
int finalOutput = 0xFFFFFF; int finalOutput = 0xFFF;
bool outputEnabled = false; bool outputEnabled = false;
// triangle waveform // triangle waveform
if (regs.TRI[index]) if (regs.TRI[index])
{ {
triOutput = waveClock[index] >> 12; triOutput = (waveClock[index] >> 12) & 0xFFF;
if (regs.SYNC[index]) if (regs.SYNC[index])
triOutput ^= regs.OSC[syncIndex[index]] & 0x800; triOutput ^= regs.OSC[syncIndex[index]] & 0x800;
if ((triOutput & 0x800) != 0x000) if ((triOutput & 0x800) != 0x000)
triOutput &= 0xFFF; triOutput ^= 0x7FF;
triOutput &= 0x7FF;
triOutput <<= 1; triOutput <<= 1;
finalOutput &= triOutput; finalOutput &= triOutput;
outputEnabled = true; outputEnabled = true;
@ -385,7 +411,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
// saw waveform // saw waveform
if (regs.SAW[index]) if (regs.SAW[index])
{ {
sawOutput = waveClock[index] >> 12; sawOutput = (waveClock[index] >> 12) & 0xFFF;
finalOutput &= sawOutput; finalOutput &= sawOutput;
outputEnabled = true; outputEnabled = true;
} }
@ -399,7 +425,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
} }
else else
{ {
if (regs.PW[index] >= (waveClock[index] >> 12)) if (regs.PW[index] >= ((waveClock[index] >> 12) & 0xFFF))
squOutput = 0xFFF; squOutput = 0xFFF;
else else
squOutput = 0x000; squOutput = 0x000;
@ -447,7 +473,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
if (outputEnabled) if (outputEnabled)
regs.OSC[index] = finalOutput; regs.OSC[index] = finalOutput;
else else
regs.OSC[index] = 0x000000; regs.OSC[index] = 0x000;
} }
public byte Read(ushort addr) public byte Read(ushort addr)

View File

@ -7,12 +7,37 @@ namespace BizHawk.Emulation.Computers.Commodore64
{ {
public partial class Sid : ISoundProvider 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) 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() public void DiscardSamples()
{ {
sampleBuffer = new short[sampleBufferCapacity];
sampleBufferReadIndex = 0;
sampleBufferIndex = 0;
} }
public int MaxVolume 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--;
}
} }
} }