using System.IO; namespace MyNes.Core { internal class VRC6Pulse { private int dutyForm; private int dutyStep; private bool enabled = true; internal bool Outputable; private bool mode; private byte volume; private int freqTimer; private int frequency; private int cycles; internal int output; internal void HardReset() { dutyForm = 0; dutyStep = 15; enabled = true; mode = false; output = 0; } internal void Write0(ref byte data) { mode = (data & 0x80) == 128; dutyForm = (data & 0x70) >> 4; volume = (byte)(data & 0xFu); } internal void Write1(ref byte data) { frequency = (frequency & 0xF00) | data; } internal void Write2(ref byte data) { frequency = (frequency & 0xFF) | ((data & 0xF) << 8); enabled = (data & 0x80) == 128; } internal void ClockSingle() { if (--cycles > 0) { return; } cycles = (frequency << 1) + 2; if (!enabled) { return; } if (mode) { output = volume; return; } dutyStep--; if (dutyStep < 0) { dutyStep = 15; } if (dutyStep <= dutyForm) { if (Outputable) { output = volume; } else { output = 0; } } else { output = 0; } } internal void SaveState(ref BinaryWriter stream) { stream.Write(dutyForm); stream.Write(dutyStep); stream.Write(enabled); stream.Write(mode); stream.Write(volume); stream.Write(freqTimer); stream.Write(frequency); stream.Write(cycles); } internal void LoadState(ref BinaryReader stream) { dutyForm = stream.ReadInt32(); dutyStep = stream.ReadInt32(); enabled = stream.ReadBoolean(); mode = stream.ReadBoolean(); volume = stream.ReadByte(); freqTimer = stream.ReadInt32(); frequency = stream.ReadInt32(); cycles = stream.ReadInt32(); } } }