mirror of
https://github.com/holub/mame
synced 2025-06-26 06:14:12 +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:
|
||||
*
|
||||
* Id = Kn * (Vgs - Vtn)^2
|
||||
* Id = Kn * (Vgs - Vth)^2
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
|
||||
static const ay8910_device::ay_ym_param ay8910_param =
|
||||
{
|
||||
800000, 8000000,
|
||||
16,
|
||||
{ 15950, 15350, 15090, 14760, 14275, 13620, 12890, 11370,
|
||||
10600, 8590, 7190, 5985, 4820, 3945, 3017, 2345 }
|
||||
800000, 8000000,
|
||||
16,
|
||||
{ 15950, 15350, 15090, 14760, 14275, 13620, 12890, 11370,
|
||||
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
|
||||
@ -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;
|
||||
|
||||
@ -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()
|
||||
{
|
||||
@ -782,10 +828,13 @@ void ay8910_device::build_mixer_table()
|
||||
|
||||
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_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]);
|
||||
build_mosfet_resistor_table(ay8910_mosfet_param, m_res_load[chan], m_vol_table[chan]);
|
||||
}
|
||||
}
|
||||
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)
|
||||
: device_t(mconfig, AY8910, "AY-3-8910A", tag, owner, clock, "ay8910", __FILE__),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_type(PSG_TYPE_AY),
|
||||
m_streams(3),
|
||||
m_ioports(2),
|
||||
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)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_type(psg_type),
|
||||
m_streams(streams),
|
||||
m_ioports(ioports),
|
||||
m_ready(0),
|
||||
|
@ -133,7 +133,15 @@ public:
|
||||
int res_count;
|
||||
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);
|
||||
int ay8910_read_ym();
|
||||
void ay8910_reset_ym();
|
||||
@ -154,6 +162,7 @@ private:
|
||||
void ay8910_statesave();
|
||||
|
||||
// internal state
|
||||
psg_type_t m_type;
|
||||
int m_streams;
|
||||
int m_ioports;
|
||||
int m_ready;
|
||||
|
@ -84,6 +84,7 @@ static NETLIST_START(nl_1942)
|
||||
|
||||
SOLVER(Solver, 48000)
|
||||
ANALOG_INPUT(V5, 5)
|
||||
PARAM(Solver.ACCURACY, 1e-10)
|
||||
|
||||
/* AY 8910 internal resistors */
|
||||
|
||||
@ -138,7 +139,9 @@ static NETLIST_START(nl_1942)
|
||||
|
||||
NET_C(CC6.1, VR.2)
|
||||
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()
|
||||
|
||||
@ -549,12 +552,15 @@ static MACHINE_CONFIG_START( 1942, _1942_state )
|
||||
|
||||
MCFG_SOUND_ADD("ay1", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
||||
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(1, "snd_nl", 1.0, 1)
|
||||
MCFG_SOUND_ROUTE_EX(2, "snd_nl", 1.0, 2)
|
||||
|
||||
MCFG_SOUND_ADD("ay2", AY8910, AUDIO_CLOCK) /* 1.5 MHz */
|
||||
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(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_NETLIST_SETUP(nl_1942)
|
||||
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", 1, "R_AY1_2.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_OUTPUT("snd_nl", 0, "R1.1")
|
||||
//MCFG_NETLIST_STREAM_OUTPUT("snd_nl", 0, "VR.2")
|
||||
MCFG_NETLIST_ANALOG_MULT_OFFSET(100000.0, 0.0)
|
||||
|
||||
MACHINE_CONFIG_END
|
||||
|
@ -53,6 +53,7 @@ static NETLIST_START(nl_popeye)
|
||||
|
||||
SOLVER(Solver, 48000)
|
||||
PARAM(Solver.ACCURACY, 1e-5)
|
||||
PARAM(Solver.LTE, 5e-2) // Default is not enough for paddle control
|
||||
ANALOG_INPUT(V5, 5)
|
||||
|
||||
/* AY 8910 internal resistors */
|
||||
@ -481,6 +482,7 @@ static MACHINE_CONFIG_DERIVED( popeye, skyskipr )
|
||||
MCFG_SOUND_MODIFY("aysnd")
|
||||
MCFG_SOUND_ROUTES_RESET()
|
||||
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_B_WRITE_CB(WRITE8(popeye_state, popeye_portB_w))
|
||||
MCFG_SOUND_ROUTE_EX(0, "snd_nl", 1.0, 0)
|
||||
|
Loading…
Reference in New Issue
Block a user