AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/Taitosnd.cs

226 lines
8.5 KiB
C#

using System.IO;
namespace MAME.Core
{
public class Taitosnd
{
public static byte TC0140SYT_PORT01_FULL, TC0140SYT_PORT23_FULL, TC0140SYT_PORT01_FULL_MASTER, TC0140SYT_PORT23_FULL_MASTER;
public struct TC0140SYT
{
public byte[] slavedata;
public byte[] masterdata;
public byte mainmode;
public byte submode;
public byte status;
public byte nmi_enabled;
public byte nmi_req;
}
public static TC0140SYT tc0140syt;
public static void taitosnd_start()
{
tc0140syt = new TC0140SYT();
tc0140syt.slavedata = new byte[4];
tc0140syt.masterdata = new byte[4];
tc0140syt.mainmode = 0;
tc0140syt.submode = 0;
tc0140syt.status = 0;
tc0140syt.nmi_enabled = 0;
tc0140syt.nmi_req = 0;
TC0140SYT_PORT01_FULL = 0x01;
TC0140SYT_PORT23_FULL = 0x02;
TC0140SYT_PORT01_FULL_MASTER = 0x04;
TC0140SYT_PORT23_FULL_MASTER = 0x08;
}
public static void Interrupt_Controller()
{
if ((tc0140syt.nmi_req != 0) && (tc0140syt.nmi_enabled != 0))
{
Cpuint.cpunum_set_input_line(1, (int)LineState.INPUT_LINE_NMI, LineState.PULSE_LINE);
tc0140syt.nmi_req = 0;
}
}
public static void taitosound_port_w(int offset, byte data)
{
data &= 0x0f;
tc0140syt.mainmode = data;
}
public static void taitosound_comm_w(int offset, byte data)
{
data &= 0x0f; /*this is important, otherwise ballbros won't work*/
switch (tc0140syt.mainmode)
{
case 0x00: // mode #0
tc0140syt.slavedata[tc0140syt.mainmode++] = data;
break;
case 0x01: // mode #1
tc0140syt.slavedata[tc0140syt.mainmode++] = data;
tc0140syt.status |= TC0140SYT_PORT01_FULL;
tc0140syt.nmi_req = 1;
break;
case 0x02: // mode #2
tc0140syt.slavedata[tc0140syt.mainmode++] = data;
break;
case 0x03: // mode #3
tc0140syt.slavedata[tc0140syt.mainmode++] = data;
tc0140syt.status |= TC0140SYT_PORT23_FULL;
tc0140syt.nmi_req = 1;
break;
case 0x04: // port status
/* this does a hi-lo transition to reset the sound cpu */
if (data != 0)
{
Cpuint.cpunum_set_input_line(1, (int)LineState.INPUT_LINE_RESET, LineState.ASSERT_LINE);
}
else
{
Cpuint.cpunum_set_input_line(1, (int)LineState.INPUT_LINE_RESET, LineState.CLEAR_LINE);
Cpuexec.cpu_spin(); /* otherwise no sound in driftout */
}
break;
default:
break;
}
}
public static byte taitosound_comm_r(int offset)
{
byte result;
switch (tc0140syt.mainmode)
{
case 0x00: // mode #0
result = tc0140syt.masterdata[tc0140syt.mainmode++];
break;
case 0x01: // mode #1
tc0140syt.status &= (byte)(~TC0140SYT_PORT01_FULL_MASTER);
result = tc0140syt.masterdata[tc0140syt.mainmode++];
break;
case 0x02: // mode #2
result = tc0140syt.masterdata[tc0140syt.mainmode++];
break;
case 0x03: // mode #3
tc0140syt.status &= (byte)(~TC0140SYT_PORT23_FULL_MASTER);
result = tc0140syt.masterdata[tc0140syt.mainmode++];
break;
case 0x04: // port status
result = tc0140syt.status;
break;
default:
result = 0;
break;
}
return result;
}
public static void taitosound_slave_port_w(byte data)
{
data &= 0x0f;
tc0140syt.submode = data;
}
public static void taitosound_slave_comm_w(byte data)
{
data &= 0x0f;
switch (tc0140syt.submode)
{
case 0x00: // mode #0
tc0140syt.masterdata[tc0140syt.submode++] = data;
break;
case 0x01: // mode #1
tc0140syt.masterdata[tc0140syt.submode++] = data;
tc0140syt.status |= TC0140SYT_PORT01_FULL_MASTER;
Cpuexec.cpu_spin(); /* writing should take longer than emulated, so spin */
break;
case 0x02: // mode #2
tc0140syt.masterdata[tc0140syt.submode++] = data;
break;
case 0x03: // mode #3
tc0140syt.masterdata[tc0140syt.submode++] = data;
tc0140syt.status |= TC0140SYT_PORT23_FULL_MASTER;
Cpuexec.cpu_spin(); /* writing should take longer than emulated, so spin */
break;
case 0x04: // port status
break;
case 0x05: // nmi disable
tc0140syt.nmi_enabled = 0;
break;
case 0x06: // nmi enable
tc0140syt.nmi_enabled = 1;
break;
default:
break;
}
Interrupt_Controller();
}
public static byte taitosound_slave_comm_r()
{
byte res = 0;
switch (tc0140syt.submode)
{
case 0x00: // mode #0
res = tc0140syt.slavedata[tc0140syt.submode++];
break;
case 0x01: // mode #1
tc0140syt.status &= unchecked((byte)(~0x01));
res = tc0140syt.slavedata[tc0140syt.submode++];
break;
case 0x02: // mode #2
res = tc0140syt.slavedata[tc0140syt.submode++];
break;
case 0x03: // mode #3
tc0140syt.status &= unchecked((byte)(~0x02));
res = tc0140syt.slavedata[tc0140syt.submode++];
break;
case 0x04: // port status
res = tc0140syt.status;
break;
default:
res = 0;
break;
}
Interrupt_Controller();
return res;
}
public static void taitosound_port16_msb_w(ushort data)
{
//if (ACCESSING_BITS_8_15)
taitosound_port_w(0, (byte)(data >> 8));
}
public static void taitosound_port16_msb_w1(byte data)
{
//if (ACCESSING_BITS_8_15)
taitosound_port_w(0, data);
}
public static void taitosound_comm16_msb_w(ushort data)
{
//if (ACCESSING_BITS_8_15)
taitosound_comm_w(0, (byte)(data >> 8));
}
public static void taitosound_comm16_msb_w1(byte data)
{
//if (ACCESSING_BITS_8_15)
taitosound_comm_w(0, data);
}
public static ushort taitosound_comm16_msb_r()
{
return (ushort)(taitosound_comm_r(0) << 8);
}
public static void SaveStateBinary(BinaryWriter writer)
{
writer.Write(tc0140syt.slavedata, 0, 4);
writer.Write(tc0140syt.masterdata, 0, 4);
writer.Write(tc0140syt.mainmode);
writer.Write(tc0140syt.submode);
writer.Write(tc0140syt.status);
writer.Write(tc0140syt.nmi_enabled);
writer.Write(tc0140syt.nmi_req);
}
public static void LoadStateBinary(BinaryReader reader)
{
tc0140syt.slavedata = reader.ReadBytes(4);
tc0140syt.masterdata = reader.ReadBytes(4);
tc0140syt.mainmode = reader.ReadByte();
tc0140syt.submode = reader.ReadByte();
tc0140syt.status = reader.ReadByte();
tc0140syt.nmi_enabled = reader.ReadByte();
tc0140syt.nmi_req = reader.ReadByte();
}
}
}