GBA.Unity/Assets/Iris/Iris.GBA/Sound.cs
2024-08-15 13:19:43 +08:00

352 lines
10 KiB
C#

using System;
using System.IO;
namespace Iris.GBA
{
internal sealed class Sound
{
internal enum Register
{
SOUND1CNT_L,
SOUND1CNT_H,
SOUND1CNT_X,
SOUND2CNT_L,
SOUND2CNT_H,
SOUND3CNT_L,
SOUND3CNT_H,
SOUND3CNT_X,
SOUND4CNT_L,
SOUND4CNT_H,
SOUNDCNT_L,
SOUNDCNT_H,
SOUNDCNT_X,
SOUNDBIAS,
WAVE_RAM0_L,
WAVE_RAM0_H,
WAVE_RAM1_L,
WAVE_RAM1_H,
WAVE_RAM2_L,
WAVE_RAM2_H,
WAVE_RAM3_L,
WAVE_RAM3_H,
FIFO_A_L,
FIFO_A_H,
FIFO_B_L,
FIFO_B_H
}
private UInt16 _SOUND1CNT_L;
private UInt16 _SOUND1CNT_H;
private UInt16 _SOUND1CNT_X;
private UInt16 _SOUND2CNT_L;
private UInt16 _SOUND2CNT_H;
private UInt16 _SOUND3CNT_L;
private UInt16 _SOUND3CNT_H;
private UInt16 _SOUND3CNT_X;
private UInt16 _SOUND4CNT_L;
private UInt16 _SOUND4CNT_H;
private UInt16 _SOUNDCNT_L;
private UInt16 _SOUNDCNT_H;
private UInt16 _SOUNDCNT_X;
private UInt16 _SOUNDBIAS;
private UInt16 _WAVE_RAM0_L;
private UInt16 _WAVE_RAM0_H;
private UInt16 _WAVE_RAM1_L;
private UInt16 _WAVE_RAM1_H;
private UInt16 _WAVE_RAM2_L;
private UInt16 _WAVE_RAM2_H;
private UInt16 _WAVE_RAM3_L;
private UInt16 _WAVE_RAM3_H;
private UInt16 _FIFO_A_L;
private UInt16 _FIFO_A_H;
private UInt16 _FIFO_B_L;
private UInt16 _FIFO_B_H;
internal void ResetState()
{
_SOUND1CNT_L = 0;
_SOUND1CNT_H = 0;
_SOUND1CNT_X = 0;
_SOUND2CNT_L = 0;
_SOUND2CNT_H = 0;
_SOUND3CNT_L = 0;
_SOUND3CNT_H = 0;
_SOUND3CNT_X = 0;
_SOUND4CNT_L = 0;
_SOUND4CNT_H = 0;
_SOUNDCNT_L = 0;
_SOUNDCNT_H = 0;
_SOUNDCNT_X = 0;
_SOUNDBIAS = 0;
_WAVE_RAM0_L = 0;
_WAVE_RAM0_H = 0;
_WAVE_RAM1_L = 0;
_WAVE_RAM1_H = 0;
_WAVE_RAM2_L = 0;
_WAVE_RAM2_H = 0;
_WAVE_RAM3_L = 0;
_WAVE_RAM3_H = 0;
_FIFO_A_L = 0;
_FIFO_A_H = 0;
_FIFO_B_L = 0;
_FIFO_B_H = 0;
}
internal void LoadState(BinaryReader reader)
{
_SOUND1CNT_L = reader.ReadUInt16();
_SOUND1CNT_H = reader.ReadUInt16();
_SOUND1CNT_X = reader.ReadUInt16();
_SOUND2CNT_L = reader.ReadUInt16();
_SOUND2CNT_H = reader.ReadUInt16();
_SOUND3CNT_L = reader.ReadUInt16();
_SOUND3CNT_H = reader.ReadUInt16();
_SOUND3CNT_X = reader.ReadUInt16();
_SOUND4CNT_L = reader.ReadUInt16();
_SOUND4CNT_H = reader.ReadUInt16();
_SOUNDCNT_L = reader.ReadUInt16();
_SOUNDCNT_H = reader.ReadUInt16();
_SOUNDCNT_X = reader.ReadUInt16();
_SOUNDBIAS = reader.ReadUInt16();
_WAVE_RAM0_L = reader.ReadUInt16();
_WAVE_RAM0_H = reader.ReadUInt16();
_WAVE_RAM1_L = reader.ReadUInt16();
_WAVE_RAM1_H = reader.ReadUInt16();
_WAVE_RAM2_L = reader.ReadUInt16();
_WAVE_RAM2_H = reader.ReadUInt16();
_WAVE_RAM3_L = reader.ReadUInt16();
_WAVE_RAM3_H = reader.ReadUInt16();
_FIFO_A_L = reader.ReadUInt16();
_FIFO_A_H = reader.ReadUInt16();
_FIFO_B_L = reader.ReadUInt16();
_FIFO_B_H = reader.ReadUInt16();
}
internal void SaveState(BinaryWriter writer)
{
writer.Write(_SOUND1CNT_L);
writer.Write(_SOUND1CNT_H);
writer.Write(_SOUND1CNT_X);
writer.Write(_SOUND2CNT_L);
writer.Write(_SOUND2CNT_H);
writer.Write(_SOUND3CNT_L);
writer.Write(_SOUND3CNT_H);
writer.Write(_SOUND3CNT_X);
writer.Write(_SOUND4CNT_L);
writer.Write(_SOUND4CNT_H);
writer.Write(_SOUNDCNT_L);
writer.Write(_SOUNDCNT_H);
writer.Write(_SOUNDCNT_X);
writer.Write(_SOUNDBIAS);
writer.Write(_WAVE_RAM0_L);
writer.Write(_WAVE_RAM0_H);
writer.Write(_WAVE_RAM1_L);
writer.Write(_WAVE_RAM1_H);
writer.Write(_WAVE_RAM2_L);
writer.Write(_WAVE_RAM2_H);
writer.Write(_WAVE_RAM3_L);
writer.Write(_WAVE_RAM3_H);
writer.Write(_FIFO_A_L);
writer.Write(_FIFO_A_H);
writer.Write(_FIFO_B_L);
writer.Write(_FIFO_B_H);
}
internal UInt16 ReadRegister(Register register)
{
return register switch
{
Register.SOUND1CNT_L => _SOUND1CNT_L,
Register.SOUND1CNT_H => _SOUND1CNT_H,
Register.SOUND1CNT_X => _SOUND1CNT_X,
Register.SOUND2CNT_L => _SOUND2CNT_L,
Register.SOUND2CNT_H => _SOUND2CNT_H,
Register.SOUND3CNT_L => _SOUND3CNT_L,
Register.SOUND3CNT_H => _SOUND3CNT_H,
Register.SOUND3CNT_X => _SOUND3CNT_X,
Register.SOUND4CNT_L => _SOUND4CNT_L,
Register.SOUND4CNT_H => _SOUND4CNT_H,
Register.SOUNDCNT_L => _SOUNDCNT_L,
Register.SOUNDCNT_H => _SOUNDCNT_H,
Register.SOUNDCNT_X => _SOUNDCNT_X,
Register.SOUNDBIAS => _SOUNDBIAS,
Register.WAVE_RAM0_L => _WAVE_RAM0_L,
Register.WAVE_RAM0_H => _WAVE_RAM0_H,
Register.WAVE_RAM1_L => _WAVE_RAM1_L,
Register.WAVE_RAM1_H => _WAVE_RAM1_H,
Register.WAVE_RAM2_L => _WAVE_RAM2_L,
Register.WAVE_RAM2_H => _WAVE_RAM2_H,
Register.WAVE_RAM3_L => _WAVE_RAM3_L,
Register.WAVE_RAM3_H => _WAVE_RAM3_H,
// should never happen
_ => throw new Exception("Iris.GBA.Sound: Register read error"),
};
}
internal void WriteRegister(Register register, UInt16 value, Memory.RegisterWriteMode mode)
{
switch (register)
{
case Register.SOUND1CNT_L:
Memory.WriteRegisterHelper(ref _SOUND1CNT_L, value, mode);
break;
case Register.SOUND1CNT_H:
Memory.WriteRegisterHelper(ref _SOUND1CNT_H, value, mode);
break;
case Register.SOUND1CNT_X:
Memory.WriteRegisterHelper(ref _SOUND1CNT_X, value, mode);
break;
case Register.SOUND2CNT_L:
Memory.WriteRegisterHelper(ref _SOUND2CNT_L, value, mode);
break;
case Register.SOUND2CNT_H:
Memory.WriteRegisterHelper(ref _SOUND2CNT_H, value, mode);
break;
case Register.SOUND3CNT_L:
Memory.WriteRegisterHelper(ref _SOUND3CNT_L, value, mode);
break;
case Register.SOUND3CNT_H:
Memory.WriteRegisterHelper(ref _SOUND3CNT_H, value, mode);
break;
case Register.SOUND3CNT_X:
Memory.WriteRegisterHelper(ref _SOUND3CNT_X, value, mode);
break;
case Register.SOUND4CNT_L:
Memory.WriteRegisterHelper(ref _SOUND4CNT_L, value, mode);
break;
case Register.SOUND4CNT_H:
Memory.WriteRegisterHelper(ref _SOUND4CNT_H, value, mode);
break;
case Register.SOUNDCNT_L:
Memory.WriteRegisterHelper(ref _SOUNDCNT_L, value, mode);
break;
case Register.SOUNDCNT_H:
Memory.WriteRegisterHelper(ref _SOUNDCNT_H, value, mode);
break;
case Register.SOUNDCNT_X:
Memory.WriteRegisterHelper(ref _SOUNDCNT_X, value, mode);
break;
case Register.SOUNDBIAS:
Memory.WriteRegisterHelper(ref _SOUNDBIAS, value, mode);
break;
case Register.WAVE_RAM0_L:
Memory.WriteRegisterHelper(ref _WAVE_RAM0_L, value, mode);
break;
case Register.WAVE_RAM0_H:
Memory.WriteRegisterHelper(ref _WAVE_RAM0_H, value, mode);
break;
case Register.WAVE_RAM1_L:
Memory.WriteRegisterHelper(ref _WAVE_RAM1_L, value, mode);
break;
case Register.WAVE_RAM1_H:
Memory.WriteRegisterHelper(ref _WAVE_RAM1_H, value, mode);
break;
case Register.WAVE_RAM2_L:
Memory.WriteRegisterHelper(ref _WAVE_RAM2_L, value, mode);
break;
case Register.WAVE_RAM2_H:
Memory.WriteRegisterHelper(ref _WAVE_RAM2_H, value, mode);
break;
case Register.WAVE_RAM3_L:
Memory.WriteRegisterHelper(ref _WAVE_RAM3_L, value, mode);
break;
case Register.WAVE_RAM3_H:
Memory.WriteRegisterHelper(ref _WAVE_RAM3_H, value, mode);
break;
case Register.FIFO_A_L:
Memory.WriteRegisterHelper(ref _FIFO_A_L, value, mode);
break;
case Register.FIFO_A_H:
Memory.WriteRegisterHelper(ref _FIFO_A_H, value, mode);
break;
case Register.FIFO_B_L:
Memory.WriteRegisterHelper(ref _FIFO_B_L, value, mode);
break;
case Register.FIFO_B_H:
Memory.WriteRegisterHelper(ref _FIFO_B_H, value, mode);
break;
// should never happen
default:
throw new Exception("Iris.GBA.Sound: Register write error");
}
}
}
}