commodore64: basic sound support, still no envelope generator so sounds will sometimes carry

This commit is contained in:
saxxonpike 2012-11-12 23:54:46 +00:00
parent d45fda78a4
commit e07919476c
5 changed files with 56 additions and 22 deletions

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
vic = new VicII(signal, Region.NTSC);
// initialize sid
sid = new Sid(Region.NTSC, 88200);
sid = new Sid(Region.NTSC, 44100); // we'll assume 44.1k for now until there's a better way
// initialize memory (this must be done AFTER all other chips are initialized)
string romPath = CoreInputComm.C64_FirmwaresPath;

View File

@ -78,7 +78,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
_frame++;
_islag = true;
const int cyclesPerFrame = (14318181 / 14 / 60);
int cyclesPerFrame = vic.cyclesPerFrame;
foreach (IMedia media in mediaAttached)
{

View File

@ -179,15 +179,15 @@ namespace BizHawk.Emulation.Computers.Commodore64
case 0x09:
case 0x10:
index = addr / 7;
PW[index] &= 0x0700;
PW[index] &= 0x0F00;
PW[index] |= val;
break;
case 0x03:
case 0x0A:
case 0x11:
index = addr / 7;
F[index] &= 0xFF;
F[index] |= (val & 0x07) << 8;
PW[index] &= 0xFF;
PW[index] |= (val & 0x0F) << 8;
break;
case 0x04:
case 0x0B:
@ -389,7 +389,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
int sawOutput;
int squOutput;
int noiseOutput;
int finalOutput = 0xFFF;
int finalOutput = 0x00000FFF;
bool outputEnabled = false;
// triangle waveform
@ -425,10 +425,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
else
{
if (regs.PW[index] >= ((waveClock[index] >> 12) & 0xFFF))
squOutput = 0xFFF;
else
squOutput = 0x000;
squOutput = (waveClock[index] >> 12) >= regs.PW[index] ? 0xFFF : 0x000;
}
finalOutput &= squOutput;
outputEnabled = true;
@ -437,6 +434,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
// noise waveform
if (regs.NOISE[index])
{
// shift register information is from reSID
int sr = regs.SR[index];
noiseOutput = sr & 0x100000 >> 9;
noiseOutput |= sr & 0x040000 >> 8;
@ -455,20 +453,25 @@ namespace BizHawk.Emulation.Computers.Commodore64
{
waveClock[index] = 0x000000;
outputEnabled = false;
regs.SR[index] = 0x7FFFFF;
}
else
{
// shift register for generating noise
if ((waveClock[index] & 0x7FFFF) == 0x00000)
if ((waveClock[index] & 0x100000) != 0)
ProcessShiftRegister(index);
// increment wave clock
waveClock[index] = (waveClock[index] + regs.F[index]) & 0xFFFFFF;
waveClock[index] = (waveClock[index] + regs.F[index]) & 0x00FFFFFF;
}
// process the envelope generator
//ProcessEnvelope(index);
// a little hack until we fix the envelope generator
outputEnabled = regs.GATE[index];
// write to internal reg
if (outputEnabled)
regs.OSC[index] = finalOutput;
@ -524,5 +527,19 @@ namespace BizHawk.Emulation.Computers.Commodore64
break;
}
}
private void WriteShiftRegister(int index, int sample)
{
regs.SR[index] &=
~((1 << 20) | (1 << 18) | (1 << 14) | (1 << 11) | (1 << 9) | (1 << 5) | (1 << 2) | (1 << 0)) |
((sample & 0x800) << 9) |
((sample & 0x400) << 8) |
((sample & 0x200) << 5) |
((sample & 0x100) << 3) |
((sample & 0x080) << 2) |
((sample & 0x040) >> 1) |
((sample & 0x020) >> 3) |
((sample & 0x010) >> 4);
}
}
}

View File

@ -25,6 +25,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
if (sampleBufferReadIndex == sampleBufferCapacity)
sampleBufferReadIndex = 0;
}
// catch the buffer up
sampleBufferReadIndex = sampleBufferIndex;
}
private void InitSound(int initSampleRate)
@ -36,8 +39,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void DiscardSamples()
{
sampleBuffer = new short[sampleBufferCapacity];
sampleBufferReadIndex = 0;
sampleBufferIndex = 0;
ResetBuffer();
}
public int MaxVolume
@ -51,6 +53,12 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
}
private void ResetBuffer()
{
sampleBufferReadIndex = 0;
sampleBufferIndex = 0;
}
private void SubmitSample()
{
if (sampleCounter == 0)
@ -58,16 +66,21 @@ namespace BizHawk.Emulation.Computers.Commodore64
short output;
output = Mix(regs.OSC[0], 0);
output = Mix(regs.OSC[1], output);
if (!regs.D3 && !regs.FILT[2])
// voice 3 can be disabled with a specific register, but
// when the filter is enabled, it still plays
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;
// run twice since the buffer expects stereo sound (I THINK)
for (int i = 0; i < 2; i++)
{
sampleCounter = cyclesPerSample;
sampleBuffer[sampleBufferIndex] = output;
sampleBufferIndex++;
if (sampleBufferIndex == sampleBufferCapacity)
sampleBufferIndex = 0;
}
}
sampleCounter--;
}

View File

@ -484,6 +484,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public byte[] colorMemory;
public int cycle;
public int cycleLeft;
public int cyclesPerFrame;
public bool dataForeground;
public bool displayEnabled;
public bool hBlank;
@ -655,6 +656,9 @@ namespace BizHawk.Emulation.Computers.Commodore64
// initialize screen
UpdateBorder();
UpdatePlotter();
// some helpful values
cyclesPerFrame = totalCycles * rasterTotalLines;
}
public byte Peek(int addr)