AxibugEmuOnline/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Sawtooth.cs
2024-07-03 18:22:22 +08:00

115 lines
2.3 KiB
C#

using System.IO;
namespace MyNes.Core
{
internal class VRC6Sawtooth
{
private byte AccumRate;
private int accumClock;
private byte accumulationRegister;
private int frequency;
private int freqTimer;
private int cycles;
private bool enabled;
internal int output;
internal bool Outputable;
internal void HardReset()
{
}
private void UpdateFrequency()
{
freqTimer = (frequency + 1) * 2;
}
internal void Write0(ref byte data)
{
AccumRate = (byte)(data & 0x3Fu);
}
internal void Write1(ref byte data)
{
frequency = (frequency & 0xF00) | data;
UpdateFrequency();
}
internal void Write2(ref byte data)
{
frequency = (frequency & 0xFF) | ((data & 0xF) << 8);
enabled = (data & 0x80) == 128;
UpdateFrequency();
}
internal void ClockSingle()
{
if (--cycles > 0)
{
return;
}
cycles = freqTimer;
if (enabled)
{
accumClock++;
switch (++accumClock)
{
case 2:
case 4:
case 6:
case 8:
case 10:
case 12:
accumulationRegister += AccumRate;
break;
case 14:
accumulationRegister = 0;
accumClock = 0;
break;
}
if (Outputable)
{
output = (accumulationRegister >> 3) & 0x1F;
}
else
{
output = 0;
}
}
else
{
output = 0;
}
}
internal void SaveState(ref BinaryWriter stream)
{
stream.Write(AccumRate);
stream.Write(accumClock);
stream.Write(accumulationRegister);
stream.Write(frequency);
stream.Write(freqTimer);
stream.Write(cycles);
stream.Write(enabled);
}
internal void LoadState(ref BinaryReader stream)
{
AccumRate = stream.ReadByte();
accumClock = stream.ReadInt32();
accumulationRegister = stream.ReadByte();
frequency = stream.ReadInt32();
freqTimer = stream.ReadInt32();
cycles = stream.ReadInt32();
enabled = stream.ReadBoolean();
}
}
}