using System.IO; namespace MyNes.Core; internal class Namcot106Chnl { private Namcot106 namcot; private int freqTimer; private int frequency; public int output; public int output_av; public int clocks; private int cycles; private int InstrumentLength; private byte InstrumentAddress; private int startPoint; private int endPoint; private int readPoint; public int volume; private bool freez; public bool Enabled { get; set; } public Namcot106Chnl(Namcot106 namcot) { this.namcot = namcot; } public void HardReset() { } private void UpdateFrequency() { if (frequency > 0) { freqTimer = 983040 * (namcot.enabledChannels + 1) / frequency; freez = false; } else { freez = true; output_av = 0; } } private void UpdatePlaybackParameters() { startPoint = InstrumentAddress; endPoint = InstrumentAddress + 4 * (8 - InstrumentLength); readPoint = InstrumentAddress; } public void WriteA(ref byte data) { frequency = (frequency & 0xFFFF00) | data; UpdateFrequency(); } public void WriteB(ref byte data) { frequency = (frequency & 0xFF00FF) | (data << 8); UpdateFrequency(); } public void WriteC(ref byte data) { frequency = (frequency & 0xFFFF) | ((data & 3) << 12); InstrumentLength = (data >> 2) & 7; UpdateFrequency(); UpdatePlaybackParameters(); } public void WriteD(ref byte data) { InstrumentAddress = data; UpdatePlaybackParameters(); } public void WriteE(ref byte data) { volume = data & 0xF; } public void ClockSingle() { if (freez || --cycles > 0) { return; } cycles = freqTimer; if (readPoint >= startPoint && readPoint <= endPoint) { if (Enabled && !freez) { if ((readPoint & 1) == 0) { output_av += (namcot.EXRAM[readPoint] & 0xF) * volume; } else { output_av += ((namcot.EXRAM[readPoint] >> 4) & 0xF) * volume; } } readPoint++; } else { readPoint = startPoint; } clocks++; } public void SaveState(BinaryWriter stream) { stream.Write(freqTimer); stream.Write(frequency); stream.Write(output); stream.Write(cycles); stream.Write(InstrumentLength); stream.Write(InstrumentAddress); stream.Write(startPoint); stream.Write(endPoint); stream.Write(readPoint); stream.Write(volume); stream.Write(freez); } public void LoadState(BinaryReader stream) { freqTimer = stream.ReadInt32(); frequency = stream.ReadInt32(); output = stream.ReadByte(); cycles = stream.ReadInt32(); InstrumentLength = stream.ReadInt32(); InstrumentAddress = stream.ReadByte(); startPoint = stream.ReadInt32(); endPoint = stream.ReadInt32(); readPoint = stream.ReadInt32(); volume = stream.ReadInt32(); freez = stream.ReadBoolean(); } }