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);
// 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;

View File

@ -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)

View File

@ -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--;
}
}
}