Commodore64: Split Sid classes into three files, up from one. Fixed border timing in TimingBuilder. Renamed Sync class to SaveState.

This commit is contained in:
saxxonpike 2013-08-26 19:22:04 +00:00
parent ba25e7045f
commit 6fdc7284bd
32 changed files with 657 additions and 637 deletions

View File

@ -155,7 +155,8 @@
<Compile Include="Computers\Commodore64\MOS\Port.cs" /> <Compile Include="Computers\Commodore64\MOS\Port.cs" />
<Compile Include="Computers\Commodore64\MOS\SerialPort.cs" /> <Compile Include="Computers\Commodore64\MOS\SerialPort.cs" />
<Compile Include="Computers\Commodore64\MOS\Sid.cs" /> <Compile Include="Computers\Commodore64\MOS\Sid.cs" />
<Compile Include="Computers\Commodore64\MOS\Timer.cs" /> <Compile Include="Computers\Commodore64\MOS\Sid.Envelope.cs" />
<Compile Include="Computers\Commodore64\MOS\Sid.Voice.cs" />
<Compile Include="Computers\Commodore64\MOS\UserPort.cs" /> <Compile Include="Computers\Commodore64\MOS\UserPort.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.cs" /> <Compile Include="Computers\Commodore64\MOS\Vic.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.Parse.cs" /> <Compile Include="Computers\Commodore64\MOS\Vic.Parse.cs" />
@ -165,7 +166,7 @@
<Compile Include="Computers\Commodore64\MOS\Vic.State.cs" /> <Compile Include="Computers\Commodore64\MOS\Vic.State.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.TimingBuilder.cs" /> <Compile Include="Computers\Commodore64\MOS\Vic.TimingBuilder.cs" />
<Compile Include="Computers\Commodore64\MOS\Vic.VideoProvider.cs" /> <Compile Include="Computers\Commodore64\MOS\Vic.VideoProvider.cs" />
<Compile Include="Computers\Commodore64\Sync.cs" /> <Compile Include="Computers\Commodore64\SaveState.cs" />
<Compile Include="Computers\Commodore64\Tape\VIC1530.cs" /> <Compile Include="Computers\Commodore64\Tape\VIC1530.cs" />
<Compile Include="Consoles\Atari\2600\Atari2600.cs" /> <Compile Include="Consoles\Atari\2600\Atari2600.cs" />
<Compile Include="Consoles\Atari\2600\Atari2600.Core.cs" /> <Compile Include="Consoles\Atari\2600\Atari2600.Core.cs" />

View File

@ -197,7 +197,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
ser.BeginSection("motherboard"); ser.BeginSection("motherboard");
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
ser.EndSection(); ser.EndSection();
ser.BeginSection("cartridge"); ser.BeginSection("cartridge");

View File

@ -236,7 +236,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.Cartridge
public virtual void SyncState(Serializer ser) public virtual void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public bool Valid public bool Valid

View File

@ -14,6 +14,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public bool OutputData() { return Data; } public bool OutputData() { return Data; }
public bool OutputSense() { return Sense; } public bool OutputSense() { return Sense; }
virtual public bool Sense { get { return true; } } virtual public bool Sense { get { return true; } }
virtual public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } virtual public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -28,6 +28,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public bool SP { get { return true; } } public bool SP { get { return true; } }
public void Clock() { } public void Clock() { }
public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -33,6 +33,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public bool Port5 { get { return (Port & 0x20) != 0; } } public bool Port5 { get { return (Port & 0x20) != 0; } }
public bool Port6 { get { return (Port & 0x40) != 0; } } public bool Port6 { get { return (Port & 0x40) != 0; } }
public bool Port7 { get { return (Port & 0x80) != 0; } } public bool Port7 { get { return (Port & 0x80) != 0; } }
public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -15,6 +15,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public bool OutputGame() { return Game; } public bool OutputGame() { return Game; }
public bool OutputIRQ() { return IRQ; } public bool OutputIRQ() { return IRQ; }
public bool OutputNMI() { return NMI; } public bool OutputNMI() { return NMI; }
virtual public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } virtual public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -11,6 +11,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public int OutputData() { return Data; } public int OutputData() { return Data; }
public int OutputPot() { return Pot; } public int OutputPot() { return Pot; }
virtual public int Pot { get { return 0xFF; } } virtual public int Pot { get { return 0xFF; } }
virtual public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } virtual public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -13,6 +13,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public int OutputRow() { return Row; } public int OutputRow() { return Row; }
virtual public bool Restore { get { return true; } } virtual public bool Restore { get { return true; } }
virtual public int Row { get { return 0xFF; } } virtual public int Row { get { return 0xFF; } }
virtual public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } virtual public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -38,6 +38,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
memory[addr & addressMask] = val & dataMask; memory[addr & addressMask] = val & dataMask;
} }
public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -28,6 +28,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
return memory[addr & addressMask]; return memory[addr & addressMask];
} }
public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -18,6 +18,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.Experimental.Chips.Internals
public bool OutputData() { return Data; } public bool OutputData() { return Data; }
public bool OutputSRQ() { return SRQ; } public bool OutputSRQ() { return SRQ; }
virtual public bool SRQ { get { return true; } } virtual public bool SRQ { get { return true; } }
virtual public void SyncState(Serializer ser) { Sync.SyncObject(ser, this); } virtual public void SyncState(Serializer ser) { SaveState.SyncObject(ser, this); }
} }
} }

View File

@ -3,7 +3,7 @@ using BizHawk.Emulation.Computers.Commodore64.Cartridge;
namespace BizHawk.Emulation.Computers.Commodore64.MOS namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
public class CartridgePort sealed public class CartridgePort
{ {
public Func<bool> ReadIRQ; public Func<bool> ReadIRQ;
public Func<bool> ReadNMI; public Func<bool> ReadNMI;
@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -11,19 +11,19 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
} }
public bool ReadDataInputBuffer() virtual public bool ReadDataInputBuffer()
{ {
return true; return true;
} }
public bool ReadSenseBuffer() virtual public bool ReadSenseBuffer()
{ {
return true; return true;
} }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -38,7 +38,7 @@
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public void Write(int addr, byte val) public void Write(int addr, byte val)

View File

@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -45,7 +45,7 @@
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public void Write(int addr, byte val) public void Write(int addr, byte val)

View File

@ -142,7 +142,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
cpu.SyncState(ser); cpu.SyncState(ser);
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public void Write(ushort addr, byte val) public void Write(ushort addr, byte val)

View File

@ -546,7 +546,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public void Write(int addr, byte val) public void Write(int addr, byte val)

View File

@ -282,7 +282,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public byte VicRead(int addr) public byte VicRead(int addr)

View File

@ -38,7 +38,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
@ -78,7 +78,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -5,7 +5,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
// the functions on this port are at the point of // the functions on this port are at the point of
// view of an external device. // view of an external device.
public class SerialPort sealed public class SerialPort
{ {
public Func<bool> ReadAtnOut; public Func<bool> ReadAtnOut;
public Func<bool> ReadClockOut; public Func<bool> ReadClockOut;
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
public bool WriteClockIn() public bool WriteClockIn()

View File

@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
sealed public partial class Sid
{
sealed class Envelope
{
const int stateAttack = 0;
const int stateDecay = 1;
const int stateRelease = 2;
int attack;
int decay;
bool delay;
int envCounter;
int expCounter;
int expPeriod;
bool freeze;
int lfsr;
bool gate;
int rate;
int release;
int state;
int sustain;
static int[] adsrTable = new int[]
{
0x7F00, 0x0006, 0x003C, 0x0330,
0x20C0, 0x6755, 0x3800, 0x500E,
0x1212, 0x0222, 0x1848, 0x59B8,
0x3840, 0x77E2, 0x7625, 0x0A93
};
static int[] expCounterTable = new int[]
{
0xFF, 0x5D, 0x36, 0x1A, 0x0E, 0x06, 0x00
};
static int[] expPeriodTable = new int[]
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x1E, 0x01
};
static int[] sustainTable = new int[]
{
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};
public Envelope()
{
HardReset();
}
public void ExecutePhase2()
{
{
if (!delay)
{
envCounter--;
delay = true;
UpdateExpCounter();
}
if (lfsr != rate)
{
int feedback = ((lfsr >> 14) ^ (lfsr >> 13)) & 0x1;
lfsr = ((lfsr << 1) & 0x7FFF) | feedback;
return;
}
lfsr = 0x7FFF;
if (state == stateAttack || ++expCounter == expPeriod)
{
expCounter = 0;
if (freeze)
return;
switch (state)
{
case stateAttack:
envCounter++;
if (envCounter == 0xFF)
{
state = stateDecay;
rate = adsrTable[decay];
}
break;
case stateDecay:
if (envCounter == sustainTable[sustain])
{
return;
}
if (expPeriod != 1)
{
delay = false;
return;
}
envCounter--;
break;
case stateRelease:
if (expPeriod != 1)
{
delay = false;
return;
}
envCounter--;
break;
}
envCounter &= 0xFF;
UpdateExpCounter();
}
}
}
public void HardReset()
{
attack = 0;
decay = 0;
delay = true;
envCounter = 0;
expCounter = 0;
expPeriod = expPeriodTable[0];
freeze = false;
gate = false;
lfsr = 0x7FFF;
rate = adsrTable[release];
release = 0;
state = stateRelease;
sustain = 0;
}
private void UpdateExpCounter()
{
{
for (int i = 0; i < 7; i++)
{
if (envCounter == expCounterTable[i])
expPeriod = expPeriodTable[i];
}
if (envCounter == 0)
freeze = true;
}
}
// ------------------------------------
public int Attack
{
get
{
return attack;
}
set
{
attack = (value & 0xF);
if (state == stateAttack)
rate = adsrTable[attack];
}
}
public int Decay
{
get
{
return decay;
}
set
{
decay = (value & 0xF);
if (state == stateDecay)
rate = adsrTable[decay];
}
}
public bool Gate
{
get
{
return gate;
}
set
{
bool nextGate = value;
if (nextGate && !gate)
{
state = stateAttack;
rate = adsrTable[attack];
delay = true;
freeze = false;
}
else if (!nextGate && gate)
{
state = stateRelease;
rate = adsrTable[release];
}
gate = nextGate;
}
}
public int Level
{
get
{
return envCounter;
}
}
public int Release
{
get
{
return release;
}
set
{
release = (value & 0xF);
if (state == stateRelease)
rate = adsrTable[release];
}
}
public int Sustain
{
get
{
return sustain;
}
set
{
sustain = (value & 0xF);
}
}
// ------------------------------------
public void SyncState(Serializer ser)
{
SaveState.SyncObject(ser, this);
}
// ------------------------------------
}
}
}

View File

@ -0,0 +1,344 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
sealed public partial class Sid
{
sealed class Voice
{
int accBits;
int accNext;
int accumulator;
bool controlTestPrev;
int controlWavePrev;
int delay;
int floatOutputTTL;
int frequency;
bool msbRising;
int noise;
int noNoise;
int noNoiseOrNoise;
int noPulse;
int output;
int pulse;
int pulseWidth;
bool ringMod;
int ringMsbMask;
int shiftRegister;
int shiftRegisterReset;
bool sync;
bool test;
int[] wave;
int waveform;
int waveformIndex;
int[][] waveTable;
public Voice(int[][] newWaveTable)
{
waveTable = newWaveTable;
HardReset();
}
public void HardReset()
{
accumulator = 0;
delay = 0;
floatOutputTTL = 0;
frequency = 0;
msbRising = false;
noNoise = 0xFFF;
noPulse = 0xFFF;
output = 0x000;
pulse = 0xFFF;
pulseWidth = 0;
ringMsbMask = 0;
sync = false;
test = false;
wave = waveTable[0];
waveform = 0;
ResetShiftReg();
}
public void ExecutePhase2()
{
{
if (test)
{
if (shiftRegisterReset != 0 && --shiftRegisterReset == 0)
{
ResetShiftReg();
}
pulse = 0xFFF;
}
else
{
accNext = (accumulator + frequency) & 0xFFFFFF;
accBits = ~accumulator & accNext;
accumulator = accNext;
msbRising = ((accBits & 0x800000) != 0);
if ((accBits & 0x080000) != 0)
delay = 2;
else if (delay != 0 && --delay == 0)
ClockShiftReg();
}
}
}
// ------------------------------------
private void ClockShiftReg()
{
{
shiftRegister = ((shiftRegister << 1) |
(((shiftRegister >> 22) ^ (shiftRegister >> 17)) & 0x1)
) & 0x7FFFFF;
SetNoise();
}
}
private void ResetShiftReg()
{
{
shiftRegister = 0x7FFFFF;
shiftRegisterReset = 0;
SetNoise();
}
}
private void SetNoise()
{
{
noise =
((shiftRegister & 0x100000) >> 9) |
((shiftRegister & 0x040000) >> 8) |
((shiftRegister & 0x004000) >> 5) |
((shiftRegister & 0x000800) >> 3) |
((shiftRegister & 0x000200) >> 2) |
((shiftRegister & 0x000020) << 1) |
((shiftRegister & 0x000004) << 3) |
((shiftRegister & 0x000001) << 4);
noNoiseOrNoise = noNoise | noise;
}
}
private void WriteShiftReg()
{
{
output &=
0xBB5DA |
((output & 0x800) << 9) |
((output & 0x400) << 8) |
((output & 0x200) << 5) |
((output & 0x100) << 3) |
((output & 0x040) >> 1) |
((output & 0x020) >> 3) |
((output & 0x010) >> 4);
noise &= output;
noNoiseOrNoise = noNoise | noise;
}
}
// ------------------------------------
public int Control
{
set
{
controlWavePrev = waveform;
controlTestPrev = test;
sync = ((value & 0x02) != 0);
ringMod = ((value & 0x04) != 0);
test = ((value & 0x08) != 0);
waveform = (value >> 4) & 0x0F;
wave = waveTable[waveform & 0x07];
ringMsbMask = ((~value >> 5) & (value >> 2) & 0x1) << 23;
noNoise = ((waveform & 0x8) != 0) ? 0x000 : 0xFFF;
noNoiseOrNoise = noNoise | noise;
noPulse = ((waveform & 0x4) != 0) ? 0x000 : 0xFFF;
if (!controlTestPrev && test)
{
accumulator = 0;
delay = 0;
shiftRegisterReset = 0x8000;
}
else if (controlTestPrev && !test)
{
shiftRegister = ((shiftRegister << 1) |
((~shiftRegister >> 17) & 0x1)
) & 0x7FFFFF;
SetNoise();
}
if (waveform == 0 && controlWavePrev != 0)
floatOutputTTL = 0x28000;
}
}
public int Frequency
{
get
{
return frequency;
}
set
{
frequency = value;
}
}
public int FrequencyLo
{
get
{
return (frequency & 0xFF);
}
set
{
frequency &= 0xFF00;
frequency |= value & 0x00FF;
}
}
public int FrequencyHi
{
get
{
return (frequency >> 8);
}
set
{
frequency &= 0x00FF;
frequency |= (value & 0x00FF) << 8;
}
}
public int Oscillator
{
get
{
return output;
}
}
public int Output(Voice ringModSource)
{
{
if (waveform != 0)
{
waveformIndex = (accumulator ^ (ringModSource.accumulator & ringMsbMask)) >> 12;
output = wave[waveformIndex] & (noPulse | pulse) & noNoiseOrNoise;
if (waveform > 8)
WriteShiftReg();
}
else
{
if (floatOutputTTL != 0 && --floatOutputTTL == 0)
output = 0x000;
}
pulse = ((accumulator >> 12) >= pulseWidth) ? 0xFFF : 0x000;
return output;
}
}
public int PulseWidth
{
get
{
return pulseWidth;
}
set
{
pulseWidth = value;
}
}
public int PulseWidthLo
{
get
{
return (pulseWidth & 0xFF);
}
set
{
pulseWidth &= 0x0F00;
pulseWidth |= value & 0x00FF;
}
}
public int PulseWidthHi
{
get
{
return (pulseWidth >> 8);
}
set
{
pulseWidth &= 0x00FF;
pulseWidth |= (value & 0x000F) << 8;
}
}
public bool RingMod
{
get
{
return ringMod;
}
}
public bool Sync
{
get
{
return sync;
}
}
public void Synchronize(Voice target, Voice source)
{
if (msbRising && target.sync && !(sync && source.msbRising))
target.accumulator = 0;
}
public bool Test
{
get
{
return test;
}
}
public int Waveform
{
get
{
return waveform;
}
}
// ------------------------------------
public void SyncState(Serializer ser)
{
SaveState.SyncObject(ser, this);
if (ser.IsReader)
wave = waveTable[waveform];
}
}
}
}

View File

@ -6,579 +6,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
// ------------------------------------ // ------------------------------------
sealed class Envelope
{
const int stateAttack = 0;
const int stateDecay = 1;
const int stateRelease = 2;
int attack;
int decay;
bool delay;
int envCounter;
int expCounter;
int expPeriod;
bool freeze;
int lfsr;
bool gate;
int rate;
int release;
int state;
int sustain;
static int[] adsrTable = new int[]
{
0x7F00, 0x0006, 0x003C, 0x0330,
0x20C0, 0x6755, 0x3800, 0x500E,
0x1212, 0x0222, 0x1848, 0x59B8,
0x3840, 0x77E2, 0x7625, 0x0A93
};
static int[] expCounterTable = new int[]
{
0xFF, 0x5D, 0x36, 0x1A, 0x0E, 0x06, 0x00
};
static int[] expPeriodTable = new int[]
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x1E, 0x01
};
static int[] sustainTable = new int[]
{
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};
public Envelope()
{
HardReset();
}
public void ExecutePhase2()
{
{
if (!delay)
{
envCounter--;
delay = true;
UpdateExpCounter();
}
if (lfsr != rate)
{
int feedback = ((lfsr >> 14) ^ (lfsr >> 13)) & 0x1;
lfsr = ((lfsr << 1) & 0x7FFF) | feedback;
return;
}
lfsr = 0x7FFF;
if (state == stateAttack || ++expCounter == expPeriod)
{
expCounter = 0;
if (freeze)
return;
switch (state)
{
case stateAttack:
envCounter++;
if (envCounter == 0xFF)
{
state = stateDecay;
rate = adsrTable[decay];
}
break;
case stateDecay:
if (envCounter == sustainTable[sustain])
{
return;
}
if (expPeriod != 1)
{
delay = false;
return;
}
envCounter--;
break;
case stateRelease:
if (expPeriod != 1)
{
delay = false;
return;
}
envCounter--;
break;
}
envCounter &= 0xFF;
UpdateExpCounter();
}
}
}
public void HardReset()
{
attack = 0;
decay = 0;
delay = true;
envCounter = 0;
expCounter = 0;
expPeriod = expPeriodTable[0];
freeze = false;
gate = false;
lfsr = 0x7FFF;
rate = adsrTable[release];
release = 0;
state = stateRelease;
sustain = 0;
}
private void UpdateExpCounter()
{
{
for (int i = 0; i < 7; i++)
{
if (envCounter == expCounterTable[i])
expPeriod = expPeriodTable[i];
}
if (envCounter == 0)
freeze = true;
}
}
// ------------------------------------
public int Attack
{
get
{
return attack;
}
set
{
attack = (value & 0xF);
if (state == stateAttack)
rate = adsrTable[attack];
}
}
public int Decay
{
get
{
return decay;
}
set
{
decay = (value & 0xF);
if (state == stateDecay)
rate = adsrTable[decay];
}
}
public bool Gate
{
get
{
return gate;
}
set
{
bool nextGate = value;
if (nextGate && !gate)
{
state = stateAttack;
rate = adsrTable[attack];
delay = true;
freeze = false;
}
else if (!nextGate && gate)
{
state = stateRelease;
rate = adsrTable[release];
}
gate = nextGate;
}
}
public int Level
{
get
{
return envCounter;
}
}
public int Release
{
get
{
return release;
}
set
{
release = (value & 0xF);
if (state == stateRelease)
rate = adsrTable[release];
}
}
public int Sustain
{
get
{
return sustain;
}
set
{
sustain = (value & 0xF);
}
}
// ------------------------------------
public void SyncState(Serializer ser)
{
Sync.SyncObject(ser, this);
}
// ------------------------------------
}
sealed class Voice
{
int accBits;
int accNext;
int accumulator;
bool controlTestPrev;
int controlWavePrev;
int delay;
int floatOutputTTL;
int frequency;
bool msbRising;
int noise;
int noNoise;
int noNoiseOrNoise;
int noPulse;
int output;
int pulse;
int pulseWidth;
bool ringMod;
int ringMsbMask;
int shiftRegister;
int shiftRegisterReset;
bool sync;
bool test;
int[] wave;
int waveform;
int waveformIndex;
int[][] waveTable;
public Voice(int[][] newWaveTable)
{
waveTable = newWaveTable;
HardReset();
}
public void HardReset()
{
accumulator = 0;
delay = 0;
floatOutputTTL = 0;
frequency = 0;
msbRising = false;
noNoise = 0xFFF;
noPulse = 0xFFF;
output = 0x000;
pulse = 0xFFF;
pulseWidth = 0;
ringMsbMask = 0;
sync = false;
test = false;
wave = waveTable[0];
waveform = 0;
ResetShiftReg();
}
public void ExecutePhase2()
{
{
if (test)
{
if (shiftRegisterReset != 0 && --shiftRegisterReset == 0)
{
ResetShiftReg();
}
pulse = 0xFFF;
}
else
{
accNext = (accumulator + frequency) & 0xFFFFFF;
accBits = ~accumulator & accNext;
accumulator = accNext;
msbRising = ((accBits & 0x800000) != 0);
if ((accBits & 0x080000) != 0)
delay = 2;
else if (delay != 0 && --delay == 0)
ClockShiftReg();
}
}
}
// ------------------------------------
private void ClockShiftReg()
{
{
shiftRegister = ((shiftRegister << 1) |
(((shiftRegister >> 22) ^ (shiftRegister >> 17)) & 0x1)
) & 0x7FFFFF;
SetNoise();
}
}
private void ResetShiftReg()
{
{
shiftRegister = 0x7FFFFF;
shiftRegisterReset = 0;
SetNoise();
}
}
private void SetNoise()
{
{
noise =
((shiftRegister & 0x100000) >> 9) |
((shiftRegister & 0x040000) >> 8) |
((shiftRegister & 0x004000) >> 5) |
((shiftRegister & 0x000800) >> 3) |
((shiftRegister & 0x000200) >> 2) |
((shiftRegister & 0x000020) << 1) |
((shiftRegister & 0x000004) << 3) |
((shiftRegister & 0x000001) << 4);
noNoiseOrNoise = noNoise | noise;
}
}
private void WriteShiftReg()
{
{
output &=
0xBB5DA |
((output & 0x800) << 9) |
((output & 0x400) << 8) |
((output & 0x200) << 5) |
((output & 0x100) << 3) |
((output & 0x040) >> 1) |
((output & 0x020) >> 3) |
((output & 0x010) >> 4);
noise &= output;
noNoiseOrNoise = noNoise | noise;
}
}
// ------------------------------------
public int Control
{
set
{
controlWavePrev = waveform;
controlTestPrev = test;
sync = ((value & 0x02) != 0);
ringMod = ((value & 0x04) != 0);
test = ((value & 0x08) != 0);
waveform = (value >> 4) & 0x0F;
wave = waveTable[waveform & 0x07];
ringMsbMask = ((~value >> 5) & (value >> 2) & 0x1) << 23;
noNoise = ((waveform & 0x8) != 0) ? 0x000 : 0xFFF;
noNoiseOrNoise = noNoise | noise;
noPulse = ((waveform & 0x4) != 0) ? 0x000 : 0xFFF;
if (!controlTestPrev && test)
{
accumulator = 0;
delay = 0;
shiftRegisterReset = 0x8000;
}
else if (controlTestPrev && !test)
{
shiftRegister = ((shiftRegister << 1) |
((~shiftRegister >> 17) & 0x1)
) & 0x7FFFFF;
SetNoise();
}
if (waveform == 0 && controlWavePrev != 0)
floatOutputTTL = 0x28000;
}
}
public int Frequency
{
get
{
return frequency;
}
set
{
frequency = value;
}
}
public int FrequencyLo
{
get
{
return (frequency & 0xFF);
}
set
{
frequency &= 0xFF00;
frequency |= value & 0x00FF;
}
}
public int FrequencyHi
{
get
{
return (frequency >> 8);
}
set
{
frequency &= 0x00FF;
frequency |= (value & 0x00FF) << 8;
}
}
public int Oscillator
{
get
{
return output;
}
}
public int Output(Voice ringModSource)
{
{
if (waveform != 0)
{
waveformIndex = (accumulator ^ (ringModSource.accumulator & ringMsbMask)) >> 12;
output = wave[waveformIndex] & (noPulse | pulse) & noNoiseOrNoise;
if (waveform > 8)
WriteShiftReg();
}
else
{
if (floatOutputTTL != 0 && --floatOutputTTL == 0)
output = 0x000;
}
pulse = ((accumulator >> 12) >= pulseWidth) ? 0xFFF : 0x000;
return output;
}
}
public int PulseWidth
{
get
{
return pulseWidth;
}
set
{
pulseWidth = value;
}
}
public int PulseWidthLo
{
get
{
return (pulseWidth & 0xFF);
}
set
{
pulseWidth &= 0x0F00;
pulseWidth |= value & 0x00FF;
}
}
public int PulseWidthHi
{
get
{
return (pulseWidth >> 8);
}
set
{
pulseWidth &= 0x00FF;
pulseWidth |= (value & 0x000F) << 8;
}
}
public bool RingMod
{
get
{
return ringMod;
}
}
public bool Sync
{
get
{
return sync;
}
}
public void Synchronize(Voice target, Voice source)
{
if (msbRising && target.sync && !(sync && source.msbRising))
target.accumulator = 0;
}
public bool Test
{
get
{
return test;
}
}
public int Waveform
{
get
{
return waveform;
}
}
// ------------------------------------
public void SyncState(Serializer ser)
{
BizHawk.Emulation.Computers.Commodore64.Sync.SyncObject(ser, this);
if (ser.IsReader)
wave = waveTable[waveform];
}
}
// ------------------------------------ // ------------------------------------
@ -930,7 +357,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
ser.BeginSection("env0"); ser.BeginSection("env0");
envelopes[0].SyncState(ser); envelopes[0].SyncState(ser);
ser.EndSection(); ser.EndSection();

View File

@ -1,5 +0,0 @@
using System;
namespace BizHawk.Emulation.Computers.Commodore64.MOS
{
}

View File

@ -14,59 +14,59 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
} }
public void HardReset() virtual public void HardReset()
{ {
// note: this will not disconnect any attached media // note: this will not disconnect any attached media
} }
public bool ReadAtn() virtual public bool ReadAtn()
{ {
return true; return true;
} }
public bool ReadCounter1Buffer() virtual public bool ReadCounter1Buffer()
{ {
return true; return true;
} }
public bool ReadCounter2Buffer() virtual public bool ReadCounter2Buffer()
{ {
return true; return true;
} }
public byte ReadData() virtual public byte ReadData()
{ {
return 0xFF; return 0xFF;
} }
public bool ReadFlag2() virtual public bool ReadFlag2()
{ {
return true; return true;
} }
public bool ReadPA2() virtual public bool ReadPA2()
{ {
return true; return true;
} }
public bool ReadReset() virtual public bool ReadReset()
{ {
return true; return true;
} }
public bool ReadSerial1Buffer() virtual public bool ReadSerial1Buffer()
{ {
return true; return true;
} }
public bool ReadSerial2Buffer() virtual public bool ReadSerial2Buffer()
{ {
return true; return true;
} }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
} }
} }
} }

View File

@ -7,7 +7,7 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
sealed public partial class Vic sealed public partial class Vic
{ {
class Sprite sealed class Sprite
{ {
public bool collideData; public bool collideData;
public bool collideSprite; public bool collideSprite;

View File

@ -196,11 +196,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
Sync.SyncObject(ser, this); SaveState.SyncObject(ser, this);
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
ser.BeginSection("sprite" + i.ToString()); ser.BeginSection("sprite" + i.ToString());
Sync.SyncObject(ser, sprites[i]); SaveState.SyncObject(ser, sprites[i]);
ser.EndSection(); ser.EndSection();
} }
} }

View File

@ -7,6 +7,11 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
{ {
sealed public partial class Vic sealed public partial class Vic
{ {
const int BORDER_LEFT_38 = 0x01F;
const int BORDER_LEFT_40 = 0x018;
const int BORDER_RIGHT_38 = 0x14F;
const int BORDER_RIGHT_40 = 0x158;
static int[] TimingBuilder_Cycle14Act = new int[] static int[] TimingBuilder_Cycle14Act = new int[]
{ {
pipelineUpdateVc, 0, pipelineUpdateVc, 0,
@ -45,17 +50,17 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
result[i] |= pipelineHoldX; result[i] |= pipelineHoldX;
// pipeline border checks // pipeline border checks
if (timing[i] == 0x018) if (timing[i] == (BORDER_LEFT_40 & 0xFFC))
result[i] |= pipelineChkBrdL1; result[i] |= pipelineChkBrdL1;
if (timing[i] == 0x01C) if (timing[i] == (BORDER_LEFT_38 & 0xFFC))
result[i] |= pipelineChkBrdL0; result[i] |= pipelineChkBrdL0;
if (timing[i] == 0x14C) if (timing[i] == (BORDER_RIGHT_38 & 0xFFC))
result[i] |= pipelineChkBrdR0; result[i] |= pipelineChkBrdR0;
if (timing[i] == 0x158) if (timing[i] == (BORDER_RIGHT_40 & 0xFFC))
result[i] |= pipelineChkBrdR1; result[i] |= pipelineChkBrdR1;
if (timing[i] == (hblankStart & 0xFFD)) if (timing[i] == (hblankStart & 0xFFC))
result[i] |= pipelineHBlankR; result[i] |= pipelineHBlankR;
if (timing[i] == (hblankEnd & 0xFFD)) if (timing[i] == (hblankEnd & 0xFFC))
result[i] |= pipelineHBlankL; result[i] |= pipelineHBlankL;
} }

View File

@ -173,8 +173,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
} }
private void UpdateBorder() private void UpdateBorder()
{
{ {
borderL = columnSelect ? 0x018 : 0x01F; borderL = columnSelect ? 0x018 : 0x01F;
borderR = columnSelect ? 0x158 : 0x14F; borderR = columnSelect ? 0x158 : 0x14F;
@ -183,7 +181,6 @@ namespace BizHawk.Emulation.Computers.Commodore64.MOS
borderT = rowSelect ? 0x033 : 0x037; borderT = rowSelect ? 0x033 : 0x037;
borderB = rowSelect ? 0x0FB : 0x0F7; borderB = rowSelect ? 0x0FB : 0x0F7;
} }
}
private void UpdatePins() private void UpdatePins()
{ {

View File

@ -8,7 +8,7 @@ using System.Text;
namespace BizHawk.Emulation.Computers.Commodore64 namespace BizHawk.Emulation.Computers.Commodore64
{ {
static class Sync static class SaveState
{ {
static public void SyncObject(Serializer ser, object obj) static public void SyncObject(Serializer ser, object obj)
{ {