158 lines
3.2 KiB
C#
158 lines
3.2 KiB
C#
|
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();
|
||
|
}
|
||
|
}
|
||
|
}
|