mirror of
https://github.com/holub/mame
synced 2025-06-27 14:49:11 +03:00
AY8910_RESISTOR_OUTPUT now selects resistance calculation by simple saturation mosfet model in ay8910.c. Currently only two drivers use this: 1942 and popeye.
This commit is contained in:
parent
cb96fc035c
commit
1f49d873fb
@ -88,13 +88,13 @@
|
|||||||
*
|
*
|
||||||
* Whilst conducting, the FET operates in saturation mode:
|
* Whilst conducting, the FET operates in saturation mode:
|
||||||
*
|
*
|
||||||
* Id = Kn * (Vgs - Vtn)^2
|
* Id = Kn * (Vgs - Vth)^2
|
||||||
*
|
*
|
||||||
* Using Id = Vs / RD
|
* Using Id = Vs / RD
|
||||||
*
|
*
|
||||||
* Vs = Kn * RD * (Vg - Vs - Vtn)^2
|
* Vs = Kn * RD * (Vg - Vs - Vth)^2
|
||||||
*
|
*
|
||||||
* finally using Vg' = Vg - Vtn
|
* finally using Vg' = Vg - Vth
|
||||||
*
|
*
|
||||||
* Vs = Vg' + 1 / (2 * Kn * RD) - sqrt((Vg' + 1 / (2 * Kn * RD))^2 - Vg'^2)
|
* Vs = Vg' + 1 / (2 * Kn * RD) - sqrt((Vg' + 1 / (2 * Kn * RD))^2 - Vg'^2)
|
||||||
*
|
*
|
||||||
@ -386,14 +386,43 @@ static const ay8910_device::ay_ym_param ay8910_param =
|
|||||||
* RD was measured on a real chip to be 8m Ohm, RU was 0.8m Ohm.
|
* RD was measured on a real chip to be 8m Ohm, RU was 0.8m Ohm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static const ay8910_device::ay_ym_param ay8910_param =
|
static const ay8910_device::ay_ym_param ay8910_param =
|
||||||
{
|
{
|
||||||
800000, 8000000,
|
800000, 8000000,
|
||||||
16,
|
16,
|
||||||
{ 15950, 15350, 15090, 14760, 14275, 13620, 12890, 11370,
|
{ 15950, 15350, 15090, 14760, 14275, 13620, 12890, 11370,
|
||||||
10600, 8590, 7190, 5985, 4820, 3945, 3017, 2345 }
|
10600, 8590, 7190, 5985, 4820, 3945, 3017, 2345 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const ay8910_device::mosfet_param ay8910_mosfet_param =
|
||||||
|
{
|
||||||
|
1.465385778,
|
||||||
|
4.9,
|
||||||
|
16,
|
||||||
|
{
|
||||||
|
0.00076,
|
||||||
|
0.80536,
|
||||||
|
1.13106,
|
||||||
|
1.65952,
|
||||||
|
2.42261,
|
||||||
|
3.60536,
|
||||||
|
5.34893,
|
||||||
|
8.96871,
|
||||||
|
10.97202,
|
||||||
|
19.32370,
|
||||||
|
29.01935,
|
||||||
|
38.82026,
|
||||||
|
55.50539,
|
||||||
|
78.44395,
|
||||||
|
109.49257,
|
||||||
|
153.72985,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
* Inline
|
* Inline
|
||||||
@ -492,7 +521,7 @@ INLINE void build_single_table(double rl, const ay8910_device::ay_ym_param *par,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void build_resisor_table(const ay8910_device::ay_ym_param *par, INT32 *tab, int zero_is_off)
|
INLINE void build_resistor_table(const ay8910_device::ay_ym_param *par, INT32 *tab, int zero_is_off)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -507,6 +536,23 @@ INLINE void build_resisor_table(const ay8910_device::ay_ym_param *par, INT32 *ta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE void build_mosfet_resistor_table(const ay8910_device::mosfet_param &par, const double rd, INT32 *tab)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j=0; j < par.m_count; j++)
|
||||||
|
{
|
||||||
|
const double Vd = 5.0;
|
||||||
|
const double Vg = par.m_Vg - par.m_Vth;
|
||||||
|
const double kn = par.m_Kn[j] / 1.0e6;
|
||||||
|
const double p2 = 1.0 / (2.0 * kn * rd);
|
||||||
|
const double Vs = Vg + p2 - sqrt(p2 * p2 - Vg * Vg);
|
||||||
|
|
||||||
|
const double res = rd * ( Vd / Vs - 1.0);
|
||||||
|
tab[j] = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UINT16 ay8910_device::mix_3D()
|
UINT16 ay8910_device::mix_3D()
|
||||||
{
|
{
|
||||||
@ -782,10 +828,13 @@ void ay8910_device::build_mixer_table()
|
|||||||
|
|
||||||
if ((m_flags & AY8910_RESISTOR_OUTPUT) != 0)
|
if ((m_flags & AY8910_RESISTOR_OUTPUT) != 0)
|
||||||
{
|
{
|
||||||
for (chan=0; chan < AY8910_NUM_CHANNELS; chan++)
|
if (m_type != PSG_TYPE_AY)
|
||||||
|
fatalerror("AY8910_RESISTOR_OUTPUT currently only supported for AY8910 devices.");
|
||||||
|
|
||||||
|
for (chan=0; chan < AY8910_NUM_CHANNELS; chan++)
|
||||||
{
|
{
|
||||||
build_resisor_table(m_par, m_vol_table[chan], m_zero_is_off);
|
build_mosfet_resistor_table(ay8910_mosfet_param, m_res_load[chan], m_vol_table[chan]);
|
||||||
build_resisor_table(m_par_env, m_env_table[chan], 0);
|
build_mosfet_resistor_table(ay8910_mosfet_param, m_res_load[chan], m_vol_table[chan]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1075,6 +1124,7 @@ const device_type AY8910 = &device_creator<ay8910_device>;
|
|||||||
ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: device_t(mconfig, AY8910, "AY-3-8910A", tag, owner, clock, "ay8910", __FILE__),
|
: device_t(mconfig, AY8910, "AY-3-8910A", tag, owner, clock, "ay8910", __FILE__),
|
||||||
device_sound_interface(mconfig, *this),
|
device_sound_interface(mconfig, *this),
|
||||||
|
m_type(PSG_TYPE_AY),
|
||||||
m_streams(3),
|
m_streams(3),
|
||||||
m_ioports(2),
|
m_ioports(2),
|
||||||
m_ready(0),
|
m_ready(0),
|
||||||
@ -1116,6 +1166,7 @@ ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, co
|
|||||||
psg_type_t psg_type, int streams, int ioports, const char *shortname, const char *source)
|
psg_type_t psg_type, int streams, int ioports, const char *shortname, const char *source)
|
||||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||||
device_sound_interface(mconfig, *this),
|
device_sound_interface(mconfig, *this),
|
||||||
|
m_type(psg_type),
|
||||||
m_streams(streams),
|
m_streams(streams),
|
||||||
m_ioports(ioports),
|
m_ioports(ioports),
|
||||||
m_ready(0),
|
m_ready(0),
|
||||||
|
@ -133,7 +133,15 @@ public:
|
|||||||
int res_count;
|
int res_count;
|
||||||
double res[32];
|
double res[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mosfet_param
|
||||||
|
{
|
||||||
|
double m_Vth;
|
||||||
|
double m_Vg;
|
||||||
|
int m_count;
|
||||||
|
double m_Kn[32];
|
||||||
|
};
|
||||||
|
|
||||||
void ay8910_write_ym(int addr, int data);
|
void ay8910_write_ym(int addr, int data);
|
||||||
int ay8910_read_ym();
|
int ay8910_read_ym();
|
||||||
void ay8910_reset_ym();
|
void ay8910_reset_ym();
|
||||||
@ -154,6 +162,7 @@ private:
|
|||||||
void ay8910_statesave();
|
void ay8910_statesave();
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
|
psg_type_t m_type;
|
||||||
int m_streams;
|
int m_streams;
|
||||||
int m_ioports;
|
int m_ioports;
|
||||||
int m_ready;
|
int m_ready;
|
||||||
|
@ -84,6 +84,7 @@ static NETLIST_START(nl_1942)
|
|||||||
|
|
||||||
SOLVER(Solver, 48000)
|
SOLVER(Solver, 48000)
|
||||||
ANALOG_INPUT(V5, 5)
|
ANALOG_INPUT(V5, 5)
|
||||||
|
PARAM(Solver.ACCURACY, 1e-10)
|
||||||
|
|
||||||
/* AY 8910 internal resistors */
|
/* AY 8910 internal resistors */
|
||||||
|
|
||||||
@ -138,7 +139,9 @@ static NETLIST_START(nl_1942)
|
|||||||
|
|
||||||
NET_C(CC6.1, VR.2)
|
NET_C(CC6.1, VR.2)
|
||||||
NET_C(CC6.2, R1.1)
|
NET_C(CC6.2, R1.1)
|
||||||
NET_C(R1.2, GND)
|
CAP(CC3, 220e-6)
|
||||||
|
NET_C(R1.2, CC3.1)
|
||||||
|
NET_C(CC3.2, GND)
|
||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
@ -549,12 +552,15 @@ static MACHINE_CONFIG_START( 1942, _1942_state )
|
|||||||
|
|
||||||
MCFG_SOUND_ADD("ay1", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
MCFG_SOUND_ADD("ay1", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
||||||
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
|
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
|
||||||
|
MCFG_AY8910_RES_LOADS(10000.0, 10000.0, 10000.0)
|
||||||
|
|
||||||
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0)
|
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0)
|
||||||
MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 1)
|
MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 1)
|
||||||
MCFG_SOUND_ROUTE_EX(2, "snd_nl", 1.0, 2)
|
MCFG_SOUND_ROUTE_EX(2, "snd_nl", 1.0, 2)
|
||||||
|
|
||||||
MCFG_SOUND_ADD("ay2", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
MCFG_SOUND_ADD("ay2", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
||||||
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
|
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT)
|
||||||
|
MCFG_AY8910_RES_LOADS(10000.0, 10000.0, 10000.0)
|
||||||
|
|
||||||
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 3)
|
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 3)
|
||||||
MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 4)
|
MCFG_SOUND_ROUTE_EX(1, "snd_nl", 1.0, 4)
|
||||||
@ -565,7 +571,6 @@ static MACHINE_CONFIG_START( 1942, _1942_state )
|
|||||||
MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000)
|
MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000)
|
||||||
MCFG_NETLIST_SETUP(nl_1942)
|
MCFG_NETLIST_SETUP(nl_1942)
|
||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 5.0)
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 5.0)
|
||||||
|
|
||||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 0, "R_AY1_1.R")
|
MCFG_NETLIST_STREAM_INPUT("snd_nl", 0, "R_AY1_1.R")
|
||||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 1, "R_AY1_2.R")
|
MCFG_NETLIST_STREAM_INPUT("snd_nl", 1, "R_AY1_2.R")
|
||||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 2, "R_AY1_3.R")
|
MCFG_NETLIST_STREAM_INPUT("snd_nl", 2, "R_AY1_3.R")
|
||||||
@ -574,6 +579,7 @@ static MACHINE_CONFIG_START( 1942, _1942_state )
|
|||||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 5, "R_AY2_3.R")
|
MCFG_NETLIST_STREAM_INPUT("snd_nl", 5, "R_AY2_3.R")
|
||||||
|
|
||||||
MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "R1.1")
|
MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "R1.1")
|
||||||
|
//MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "VR.2")
|
||||||
MCFG_NETLIST_ANALOG_MULT_OFFSET(100000.0, 0.0)
|
MCFG_NETLIST_ANALOG_MULT_OFFSET(100000.0, 0.0)
|
||||||
|
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
@ -53,6 +53,7 @@ static NETLIST_START(nl_popeye)
|
|||||||
|
|
||||||
SOLVER(Solver, 48000)
|
SOLVER(Solver, 48000)
|
||||||
PARAM(Solver.ACCURACY, 1e-5)
|
PARAM(Solver.ACCURACY, 1e-5)
|
||||||
|
PARAM(Solver.LTE, 5e-2) // Default is not enough for paddle control
|
||||||
ANALOG_INPUT(V5, 5)
|
ANALOG_INPUT(V5, 5)
|
||||||
|
|
||||||
/* AY 8910 internal resistors */
|
/* AY 8910 internal resistors */
|
||||||
@ -481,6 +482,7 @@ static MACHINE_CONFIG_DERIVED( popeye, skyskipr )
|
|||||||
MCFG_SOUND_MODIFY("aysnd")
|
MCFG_SOUND_MODIFY("aysnd")
|
||||||
MCFG_SOUND_ROUTES_RESET()
|
MCFG_SOUND_ROUTES_RESET()
|
||||||
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT) /* Does Sky Skipper have the same filtering? */
|
MCFG_AY8910_OUTPUT_TYPE(AY8910_RESISTOR_OUTPUT) /* Does Sky Skipper have the same filtering? */
|
||||||
|
MCFG_AY8910_RES_LOADS(2000.0, 2000.0, 2000.0)
|
||||||
MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSW0"))
|
MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSW0"))
|
||||||
MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(popeye_state, popeye_portB_w))
|
MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(popeye_state, popeye_portB_w))
|
||||||
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0)
|
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user