201 lines
7.2 KiB
C#
201 lines
7.2 KiB
C#
using System.IO;
|
|
|
|
namespace MAME.Core
|
|
{
|
|
public unsafe class Iremga20
|
|
{
|
|
public struct IremGA20_channel_def
|
|
{
|
|
public int rate;
|
|
public int size;
|
|
public int start;
|
|
public int pos;
|
|
public int frac;
|
|
public int end;
|
|
public int volume;
|
|
public int pan;
|
|
public int effect;
|
|
public int play;
|
|
};
|
|
public struct IremGA20_chip_def
|
|
{
|
|
public ushort[] regs;
|
|
public IremGA20_channel_def[] channel;
|
|
};
|
|
public static IremGA20_chip_def chip;
|
|
public static byte[] iremrom;
|
|
public static void iremga20_update(int offset, int length)
|
|
{
|
|
int[] rate = new int[4], pos = new int[4], frac = new int[4], end = new int[4], vol = new int[4], play = new int[4];
|
|
int i, sampleout;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
rate[i] = chip.channel[i].rate;
|
|
pos[i] = chip.channel[i].pos;
|
|
frac[i] = chip.channel[i].frac;
|
|
end[i] = chip.channel[i].end - 0x20;
|
|
vol[i] = chip.channel[i].volume;
|
|
play[i] = chip.channel[i].play;
|
|
}
|
|
i = length;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
sampleout = 0;
|
|
if (play[0] != 0)
|
|
{
|
|
sampleout += (iremrom[pos[0]] - 0x80) * vol[0];
|
|
frac[0] += rate[0];
|
|
pos[0] += frac[0] >> 24;
|
|
frac[0] &= 0xffffff;
|
|
play[0] = pos[0] < end[0] ? 1 : 0;
|
|
}
|
|
if (play[1] != 0)
|
|
{
|
|
sampleout += (iremrom[pos[1]] - 0x80) * vol[1];
|
|
frac[1] += rate[1];
|
|
pos[1] += frac[1] >> 24;
|
|
frac[1] &= 0xffffff;
|
|
play[1] = pos[1] < end[1] ? 1 : 0;
|
|
}
|
|
if (play[2] != 0)
|
|
{
|
|
sampleout += (iremrom[pos[2]] - 0x80) * vol[2];
|
|
frac[2] += rate[2];
|
|
pos[2] += frac[2] >> 24;
|
|
frac[2] &= 0xffffff;
|
|
play[2] = pos[2] < end[2] ? 1 : 0;
|
|
}
|
|
if (play[3] != 0)
|
|
{
|
|
sampleout += (iremrom[pos[3]] - 0x80) * vol[3];
|
|
frac[3] += rate[3];
|
|
pos[3] += frac[3] >> 24;
|
|
frac[3] &= 0xffffff;
|
|
play[3] = pos[3] < end[3] ? 1 : 0;
|
|
}
|
|
sampleout >>= 2;
|
|
Sound.iremga20stream.streamoutput_Ptrs[0][offset + i] = sampleout;
|
|
Sound.iremga20stream.streamoutput_Ptrs[1][offset + i] = sampleout;
|
|
}
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
chip.channel[i].pos = pos[i];
|
|
chip.channel[i].frac = frac[i];
|
|
chip.channel[i].play = play[i];
|
|
}
|
|
}
|
|
public static void irem_ga20_w(int offset, ushort data)
|
|
{
|
|
int channel;
|
|
Sound.iremga20stream.stream_update();
|
|
channel = offset >> 3;
|
|
chip.regs[offset] = data;
|
|
switch (offset & 0x7)
|
|
{
|
|
case 0:
|
|
chip.channel[channel].start = ((chip.channel[channel].start) & 0xff000) | (data << 4);
|
|
break;
|
|
case 1:
|
|
chip.channel[channel].start = ((chip.channel[channel].start) & 0x00ff0) | (data << 12);
|
|
break;
|
|
case 2:
|
|
chip.channel[channel].end = ((chip.channel[channel].end) & 0xff000) | (data << 4);
|
|
break;
|
|
case 3:
|
|
chip.channel[channel].end = ((chip.channel[channel].end) & 0x00ff0) | (data << 12);
|
|
break;
|
|
case 4:
|
|
chip.channel[channel].rate = 0x1000000 / (256 - data);
|
|
break;
|
|
case 5:
|
|
chip.channel[channel].volume = (data * 0x100) / (data + 10);
|
|
break;
|
|
case 6:
|
|
chip.channel[channel].play = data;
|
|
chip.channel[channel].pos = chip.channel[channel].start;
|
|
chip.channel[channel].frac = 0;
|
|
break;
|
|
}
|
|
}
|
|
public static ushort irem_ga20_r(int offset)
|
|
{
|
|
int channel;
|
|
ushort result;
|
|
Sound.iremga20stream.stream_update();
|
|
channel = offset >> 3;
|
|
switch (offset & 0x7)
|
|
{
|
|
case 7:
|
|
result = (ushort)(chip.channel[channel].play != 0 ? 1 : 0);
|
|
break;
|
|
default:
|
|
result = 0;
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
public static void iremga20_reset()
|
|
{
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
chip.channel[i].rate = 0;
|
|
chip.channel[i].size = 0;
|
|
chip.channel[i].start = 0;
|
|
chip.channel[i].pos = 0;
|
|
chip.channel[i].frac = 0;
|
|
chip.channel[i].end = 0;
|
|
chip.channel[i].volume = 0;
|
|
chip.channel[i].pan = 0;
|
|
chip.channel[i].effect = 0;
|
|
chip.channel[i].play = 0;
|
|
}
|
|
}
|
|
public static void iremga20_start()
|
|
{
|
|
int i;
|
|
chip.regs = new ushort[0x40];
|
|
chip.channel = new IremGA20_channel_def[4];
|
|
iremga20_reset();
|
|
for (i = 0; i < 0x40; i++)
|
|
{
|
|
chip.regs[i] = 0;
|
|
}
|
|
}
|
|
public static void SaveStateBinary(BinaryWriter writer)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
writer.Write(chip.channel[i].rate);
|
|
writer.Write(chip.channel[i].size);
|
|
writer.Write(chip.channel[i].start);
|
|
writer.Write(chip.channel[i].pos);
|
|
writer.Write(chip.channel[i].frac);
|
|
writer.Write(chip.channel[i].end);
|
|
writer.Write(chip.channel[i].volume);
|
|
writer.Write(chip.channel[i].pan);
|
|
writer.Write(chip.channel[i].effect);
|
|
writer.Write(chip.channel[i].play);
|
|
}
|
|
}
|
|
public static void LoadStateBinary(BinaryReader reader)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
chip.channel[i].rate = reader.ReadInt32();
|
|
chip.channel[i].size = reader.ReadInt32();
|
|
chip.channel[i].start = reader.ReadInt32();
|
|
chip.channel[i].pos = reader.ReadInt32();
|
|
chip.channel[i].frac = reader.ReadInt32();
|
|
chip.channel[i].end = reader.ReadInt32();
|
|
chip.channel[i].volume = reader.ReadInt32();
|
|
chip.channel[i].pan = reader.ReadInt32();
|
|
chip.channel[i].effect = reader.ReadInt32();
|
|
chip.channel[i].play = reader.ReadInt32();
|
|
}
|
|
}
|
|
}
|
|
}
|