mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
Netlist: ongoing cleanup
- simplified classes - separated logic and analog inputs/outputs.
This commit is contained in:
parent
1a4b917d7e
commit
708fd81c72
@ -72,7 +72,7 @@ NETLIB_CONSTRUCTOR(netdev_log)
|
||||
|
||||
NETLIB_UPDATE(netdev_log)
|
||||
{
|
||||
printf("%s: %d %d\n", name(), (UINT32) (netlist().time().as_raw() / 1000000), INPVAL(m_I));
|
||||
printf("%s: %d %d\n", name(), (UINT32) (netlist().time().as_raw() / 1000000), INPLOGIC(m_I));
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(netdev_clock)
|
||||
@ -94,18 +94,8 @@ NETLIB_UPDATE_PARAM(netdev_clock)
|
||||
|
||||
NETLIB_UPDATE(netdev_clock)
|
||||
{
|
||||
m_Q.setToNoCheck(!m_Q.new_Q(), m_inc );
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(netdev_mainclock)
|
||||
{
|
||||
m_inc = netlist_time::from_hz(m_freq.Value()*2);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(netdev_mainclock)
|
||||
{
|
||||
*m_Q.new_Q_ptr() = !m_Q.new_Q();
|
||||
m_Q.set_time(m_netlist.time() + m_inc);
|
||||
//m_Q.setToNoCheck(!m_Q.new_Q(), m_inc );
|
||||
OUTLOGIC(m_Q, !m_Q.new_Q(), m_inc );
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nicMultiSwitch)
|
||||
@ -120,7 +110,7 @@ NETLIB_CONSTRUCTOR(nicMultiSwitch)
|
||||
{
|
||||
register_input(sIN[i], m_I[i]);
|
||||
//register_link_internal(m_I[i], m_low);
|
||||
m_I[i].set_output( GETINPPTR(m_low));
|
||||
m_I[i].set_output(m_low);
|
||||
}
|
||||
register_param("POS", m_POS);
|
||||
register_output("Q", m_Q);
|
||||
@ -131,7 +121,7 @@ NETLIB_CONSTRUCTOR(nicMultiSwitch)
|
||||
NETLIB_UPDATE(nicMultiSwitch)
|
||||
{
|
||||
assert(m_position<8);
|
||||
m_Q.setTo(INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
|
||||
OUTANALOG(m_Q, INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(nicMultiSwitch)
|
||||
@ -151,7 +141,7 @@ NETLIB_CONSTRUCTOR(nicMixer8)
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
register_input(sI[i], m_I[i]);
|
||||
m_I[i].set_output(GETINPPTR(m_low));
|
||||
m_I[i].set_output(m_low);
|
||||
register_param(sR[i], m_R[i], 1e12);
|
||||
}
|
||||
register_output("Q", m_Q);
|
||||
@ -168,7 +158,7 @@ NETLIB_UPDATE(nicMixer8)
|
||||
{
|
||||
r += m_w[i] * INPANALOG(m_I[i]);
|
||||
}
|
||||
m_Q.setTo(r, NLTIME_IMMEDIATE);
|
||||
OUTANALOG(m_Q, r, NLTIME_IMMEDIATE);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(nicMixer8)
|
||||
@ -198,15 +188,15 @@ NETLIB_CONSTRUCTOR(nicRSFF)
|
||||
|
||||
NETLIB_UPDATE(nicRSFF)
|
||||
{
|
||||
if (INPVAL(m_S))
|
||||
if (INPLOGIC(m_S))
|
||||
{
|
||||
m_Q.set();
|
||||
m_QQ.clear();
|
||||
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(10));
|
||||
OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(10));
|
||||
}
|
||||
else if (INPVAL(m_R))
|
||||
else if (INPLOGIC(m_R))
|
||||
{
|
||||
m_Q.clear();
|
||||
m_QQ.set();
|
||||
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10));
|
||||
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +212,7 @@ NETLIB_CONSTRUCTOR(nicNE555N_MSTABLE)
|
||||
register_param("VS", m_VS, 5.0);
|
||||
register_param("VL", m_VL, 0.0 *5.0);
|
||||
|
||||
m_THRESHOLD_OUT.set_netdev(this);
|
||||
m_THRESHOLD_OUT.init_terminal(this);
|
||||
register_link_internal(m_THRESHOLD, m_THRESHOLD_OUT, net_input_t::INP_STATE_ACTIVE);
|
||||
|
||||
m_Q.initial(5.0 * 0.4);
|
||||
@ -283,13 +273,13 @@ NETLIB_UPDATE(nicNE555N_MSTABLE)
|
||||
time = 10.0;
|
||||
}
|
||||
|
||||
m_Q.setToNoCheckPS(m_VS.Value() * 0.7, NLTIME_FROM_NS(100));
|
||||
m_THRESHOLD_OUT.setTo(m_VS.Value(), NLTIME_FROM_US(time ));
|
||||
OUTANALOG(m_Q, m_VS.Value() * 0.7, NLTIME_FROM_NS(100));
|
||||
OUTANALOG(m_THRESHOLD_OUT, m_VS.Value(), NLTIME_FROM_US(time ));
|
||||
}
|
||||
else if (m_last && !out)
|
||||
{
|
||||
m_Q.setToNoCheckPS(0.25, NLTIME_FROM_NS(100));
|
||||
m_THRESHOLD_OUT.setTo(0.0, NLTIME_FROM_NS(1));
|
||||
OUTANALOG(m_Q, 0.25, NLTIME_FROM_NS(100));
|
||||
OUTANALOG(m_THRESHOLD_OUT, 0.0, NLTIME_FROM_NS(1));
|
||||
}
|
||||
m_last = out;
|
||||
}
|
||||
@ -304,8 +294,8 @@ NETLIB_CONSTRUCTOR(nic7404)
|
||||
NETLIB_UPDATE(nic7404)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22) };
|
||||
UINT8 t = (INPVAL(m_I)) ^ 1;
|
||||
m_Q.setTo(t, delay[t]);
|
||||
UINT8 t = (INPLOGIC(m_I)) ^ 1;
|
||||
OUTLOGIC(m_Q, t, delay[t]);
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic7486)
|
||||
@ -318,8 +308,8 @@ NETLIB_CONSTRUCTOR(nic7486)
|
||||
NETLIB_UPDATE(nic7486)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22) };
|
||||
UINT8 t = INPVAL(m_I0) ^ INPVAL(m_I1);
|
||||
m_Q.setTo(t, delay[t]);
|
||||
UINT8 t = INPLOGIC(m_I0) ^ INPLOGIC(m_I1);
|
||||
OUTLOGIC(m_Q, t, delay[t]);
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic7448)
|
||||
@ -347,16 +337,16 @@ NETLIB_CONSTRUCTOR(nic7448)
|
||||
NETLIB_UPDATE(nic7448)
|
||||
{
|
||||
|
||||
if (INPVAL(m_BIQ) && !INPVAL(m_LTQ))
|
||||
if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))
|
||||
{
|
||||
sub.update_outputs(8);
|
||||
}
|
||||
else if (!INPVAL(m_BIQ))
|
||||
else if (!INPLOGIC(m_BIQ))
|
||||
{
|
||||
sub.update_outputs(15);
|
||||
}
|
||||
|
||||
if (!INPVAL(m_BIQ) || (INPVAL(m_BIQ) && !INPVAL(m_LTQ)))
|
||||
if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)))
|
||||
{
|
||||
sub.m_A0.inactivate();
|
||||
sub.m_A1.inactivate();
|
||||
@ -378,8 +368,8 @@ NETLIB_UPDATE(nic7448_sub)
|
||||
{
|
||||
UINT8 v;
|
||||
|
||||
v = (INPVAL(m_A0) << 0) | (INPVAL(m_A1) << 1) | (INPVAL(m_A2) << 2) | (INPVAL(m_A3) << 3);
|
||||
if ((!INPVAL(m_RBIQ) && (v==0)))
|
||||
v = (INPLOGIC(m_A0) << 0) | (INPLOGIC(m_A1) << 1) | (INPLOGIC(m_A2) << 2) | (INPLOGIC(m_A3) << 3);
|
||||
if ((!INPLOGIC(m_RBIQ) && (v==0)))
|
||||
v = 15;
|
||||
update_outputs(v);
|
||||
}
|
||||
@ -389,13 +379,13 @@ NETLIB_FUNC_VOID(nic7448_sub, update_outputs, (UINT8 v))
|
||||
assert(v<16);
|
||||
if (v != m_state)
|
||||
{
|
||||
m_a.setTo(tab7448[v][0], NLTIME_FROM_NS(100));
|
||||
m_b.setTo(tab7448[v][1], NLTIME_FROM_NS(100));
|
||||
m_c.setTo(tab7448[v][2], NLTIME_FROM_NS(100));
|
||||
m_d.setTo(tab7448[v][3], NLTIME_FROM_NS(100));
|
||||
m_e.setTo(tab7448[v][4], NLTIME_FROM_NS(100));
|
||||
m_f.setTo(tab7448[v][5], NLTIME_FROM_NS(100));
|
||||
m_g.setTo(tab7448[v][6], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_a, tab7448[v][0], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_b, tab7448[v][1], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_c, tab7448[v][2], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_d, tab7448[v][3], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_e, tab7448[v][4], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_f, tab7448[v][5], NLTIME_FROM_NS(100));
|
||||
OUTLOGIC(m_g, tab7448[v][6], NLTIME_FROM_NS(100));
|
||||
m_state = v;
|
||||
}
|
||||
}
|
||||
@ -431,11 +421,11 @@ NETLIB_CONSTRUCTOR(nic7450)
|
||||
|
||||
NETLIB_UPDATE(nic7450)
|
||||
{
|
||||
UINT8 t1 = INPVAL(m_I0) & INPVAL(m_I1);
|
||||
UINT8 t2 = INPVAL(m_I2) & INPVAL(m_I3);
|
||||
UINT8 t1 = INPLOGIC(m_I0) & INPLOGIC(m_I1);
|
||||
UINT8 t2 = INPLOGIC(m_I2) & INPLOGIC(m_I3);
|
||||
#if 0
|
||||
UINT8 t = (t1 | t2) ^ 1;
|
||||
m_Q.setTo(t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15));
|
||||
OUTLOGIC(m_Q, t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15));
|
||||
#else
|
||||
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
|
||||
|
||||
@ -464,46 +454,46 @@ NETLIB_UPDATE(nic7450)
|
||||
m_I3.inactivate();
|
||||
}
|
||||
}
|
||||
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
|
||||
OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE void nic7474_newstate(const UINT8 state, ttl_output_t &Q, ttl_output_t &QQ)
|
||||
ATTR_HOT inline void nic7474sub::newstate(const UINT8 state)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) };
|
||||
//printf("%s %d %d %d\n", "7474", state, Q.Q(), QQ.Q());
|
||||
Q.setTo(state, delay[state]);
|
||||
QQ.setTo(!state, delay[!state]);
|
||||
OUTLOGIC(m_Q, state, delay[state]);
|
||||
OUTLOGIC(m_QQ, !state, delay[!state]);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7474sub)
|
||||
{
|
||||
//if (!INP_LAST(m_clk) & INP(m_clk))
|
||||
{
|
||||
nic7474_newstate(m_nextD, m_Q, m_QQ);
|
||||
newstate(m_nextD);
|
||||
m_clk.inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7474)
|
||||
{
|
||||
if (!INPVAL(m_preQ))
|
||||
if (!INPLOGIC(m_preQ))
|
||||
{
|
||||
nic7474_newstate(1, sub.m_Q, sub.m_QQ);
|
||||
sub.newstate(1);
|
||||
sub.m_clk.inactivate();
|
||||
m_D.inactivate();
|
||||
}
|
||||
else if (!INPVAL(m_clrQ))
|
||||
else if (!INPLOGIC(m_clrQ))
|
||||
{
|
||||
nic7474_newstate(0, sub.m_Q, sub.m_QQ);
|
||||
sub.newstate(0);
|
||||
sub.m_clk.inactivate();
|
||||
m_D.inactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_D.activate();
|
||||
sub.m_nextD = INPVAL(m_D);
|
||||
sub.m_nextD = INPLOGIC(m_D);
|
||||
sub.m_clk.activate_lh();
|
||||
}
|
||||
}
|
||||
@ -547,19 +537,19 @@ NETLIB_CONSTRUCTOR(nic7483)
|
||||
|
||||
NETLIB_UPDATE(nic7483)
|
||||
{
|
||||
UINT8 a = (INPVAL(m_A1) << 0) | (INPVAL(m_A2) << 1) | (INPVAL(m_A3) << 2) | (INPVAL(m_A4) << 3);
|
||||
UINT8 b = (INPVAL(m_B1) << 0) | (INPVAL(m_B2) << 1) | (INPVAL(m_B3) << 2) | (INPVAL(m_B4) << 3);
|
||||
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
|
||||
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
|
||||
|
||||
UINT8 r = a + b + INPVAL(m_CI);
|
||||
UINT8 r = a + b + INPLOGIC(m_CI);
|
||||
|
||||
if (r != m_lastr)
|
||||
{
|
||||
m_lastr = r;
|
||||
m_SA.setTo((r >> 0) & 1, NLTIME_FROM_NS(23));
|
||||
m_SB.setTo((r >> 1) & 1, NLTIME_FROM_NS(23));
|
||||
m_SC.setTo((r >> 2) & 1, NLTIME_FROM_NS(23));
|
||||
m_SD.setTo((r >> 3) & 1, NLTIME_FROM_NS(23));
|
||||
m_CO.setTo((r >> 4) & 1, NLTIME_FROM_NS(23));
|
||||
OUTLOGIC(m_SA, (r >> 0) & 1, NLTIME_FROM_NS(23));
|
||||
OUTLOGIC(m_SB, (r >> 1) & 1, NLTIME_FROM_NS(23));
|
||||
OUTLOGIC(m_SC, (r >> 2) & 1, NLTIME_FROM_NS(23));
|
||||
OUTLOGIC(m_SD, (r >> 3) & 1, NLTIME_FROM_NS(23));
|
||||
OUTLOGIC(m_CO, (r >> 4) & 1, NLTIME_FROM_NS(23));
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,17 +571,17 @@ NETLIB_CONSTRUCTOR(nic7490)
|
||||
|
||||
NETLIB_UPDATE(nic7490)
|
||||
{
|
||||
if (INPVAL(m_R91) & INPVAL(m_R92))
|
||||
if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
|
||||
{
|
||||
m_cnt = 9;
|
||||
update_outputs();
|
||||
}
|
||||
else if (INPVAL(m_R1) & INPVAL(m_R2))
|
||||
else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
|
||||
{
|
||||
m_cnt = 0;
|
||||
update_outputs();
|
||||
}
|
||||
else if (INPVAL_LAST(m_clk) & !INPVAL(m_clk))
|
||||
else if (INP_HL(m_clk))
|
||||
{
|
||||
m_cnt++;
|
||||
if (m_cnt >= 10)
|
||||
@ -602,22 +592,17 @@ NETLIB_UPDATE(nic7490)
|
||||
#if 0
|
||||
NETLIB_FUNC_VOID(nic7490, update_outputs)
|
||||
{
|
||||
m_QA.setTo((m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
|
||||
m_QB.setTo((m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
|
||||
m_QC.setTo((m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
|
||||
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
|
||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, NLTIME_FROM_NS(18));
|
||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, NLTIME_FROM_NS(36));
|
||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, NLTIME_FROM_NS(54));
|
||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
|
||||
}
|
||||
#else
|
||||
NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
|
||||
{
|
||||
const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) };
|
||||
for (int i=0; i<4; i++)
|
||||
m_Q[i].setTo((m_cnt >> i) & 1, delay[i]);
|
||||
|
||||
//m_QA.setToPS((m_cnt >> 0) & 1, delay[0]);
|
||||
//m_QB.setToPS((m_cnt >> 1) & 1, delay[1]);
|
||||
//m_QC.setToPS((m_cnt >> 2) & 1, delay[2]);
|
||||
//m_QD.setToPS((m_cnt >> 3) & 1, delay[3]);
|
||||
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
|
||||
}
|
||||
#endif
|
||||
#if !USE_OLD7493
|
||||
@ -646,12 +631,12 @@ NETLIB_CONSTRUCTOR(nic7493)
|
||||
NETLIB_UPDATE(nic7493ff)
|
||||
{
|
||||
if (m_reset == 0)
|
||||
m_Q.setTo(!m_Q.new_Q(), NLTIME_FROM_NS(18));
|
||||
OUTLOGIC(m_Q, !m_Q.new_Q(), NLTIME_FROM_NS(18));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic7493)
|
||||
{
|
||||
net_sig_t r = INPVAL(m_R1) & INPVAL(m_R2);
|
||||
net_sig_t r = INPLOGIC(m_R1) & INPLOGIC(m_R2);
|
||||
|
||||
if (r)
|
||||
{
|
||||
@ -659,10 +644,10 @@ NETLIB_UPDATE(nic7493)
|
||||
A.m_reset = B.m_reset = C.m_reset = D.m_reset = 1;
|
||||
A.m_I.inactivate();
|
||||
B.m_I.inactivate();
|
||||
A.m_Q.setTo(0, NLTIME_FROM_NS(40));
|
||||
B.m_Q.setTo(0, NLTIME_FROM_NS(40));
|
||||
C.m_Q.setTo(0, NLTIME_FROM_NS(40));
|
||||
D.m_Q.setTo(0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(A.m_Q, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(B.m_Q, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(C.m_Q, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(D.m_Q, 0, NLTIME_FROM_NS(40));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -692,25 +677,25 @@ NETLIB_CONSTRUCTOR(nic7493)
|
||||
NETLIB_UPDATE(nic7493)
|
||||
{
|
||||
//UINT8 old_clk = m_lastclk;
|
||||
//m_lastclk = INPVAL(m_clk);
|
||||
//m_lastclk = INPLOGIC(m_clk);
|
||||
|
||||
//printf("%s %d %d %d %d %d %d\n", name(), m_cnt, old_clk, m_QA.Q(), m_QB.Q(), m_QC.Q(), m_QD.Q());
|
||||
if (INPVAL(m_R1) & INPVAL(m_R2))
|
||||
if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
|
||||
{
|
||||
if (m_cnt > 0)
|
||||
{
|
||||
m_cnt = 0;
|
||||
m_QA.setTo(0, NLTIME_FROM_NS(40));
|
||||
m_QB.setTo(0, NLTIME_FROM_NS(40));
|
||||
m_QC.setTo(0, NLTIME_FROM_NS(40));
|
||||
m_QD.setTo(0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(m_QA, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(m_QB, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(m_QC, 0, NLTIME_FROM_NS(40));
|
||||
OUTLOGIC(m_QD, 0, NLTIME_FROM_NS(40));
|
||||
}
|
||||
m_CLK.inactivate();
|
||||
}
|
||||
//else if (old_clk & !m_lastclk)
|
||||
else {
|
||||
m_CLK.activate_hl();
|
||||
if (INPVAL_LAST(m_CLK) & !INPVAL(m_CLK))
|
||||
if (INP_HL(m_CLK))
|
||||
{
|
||||
m_cnt++;
|
||||
m_cnt &= 0x0f;
|
||||
@ -722,32 +707,32 @@ NETLIB_UPDATE(nic7493)
|
||||
NETLIB_FUNC_VOID(nic7493, update_outputs, (void))
|
||||
{
|
||||
if (m_cnt & 1)
|
||||
m_QA.setToNoCheck(1, NLTIME_FROM_NS(16));
|
||||
OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(16));
|
||||
else
|
||||
{
|
||||
m_QA.setToNoCheck(0, NLTIME_FROM_NS(16));
|
||||
OUTLOGIC(m_QA, 0, NLTIME_FROM_NS(16));
|
||||
switch (m_cnt)
|
||||
{
|
||||
case 0x00:
|
||||
m_QD.setToNoCheck(0, NLTIME_FROM_NS(70));
|
||||
m_QC.setToNoCheck(0, NLTIME_FROM_NS(48));
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
OUTLOGIC(m_QD, 0, NLTIME_FROM_NS(70));
|
||||
OUTLOGIC(m_QC, 0, NLTIME_FROM_NS(48));
|
||||
OUTLOGIC(m_QB, 0, NLTIME_FROM_NS(34));
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x06:
|
||||
case 0x0A:
|
||||
case 0x0E:
|
||||
m_QB.setToNoCheck(1, NLTIME_FROM_NS(34));
|
||||
OUTLOGIC(m_QB, 1, NLTIME_FROM_NS(34));
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x0C:
|
||||
m_QC.setToNoCheck(1, NLTIME_FROM_NS(48));
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
OUTLOGIC(m_QC, 1, NLTIME_FROM_NS(48));
|
||||
OUTLOGIC(m_QB, 0, NLTIME_FROM_NS(34));
|
||||
break;
|
||||
case 0x08:
|
||||
m_QD.setToNoCheck(1, NLTIME_FROM_NS(70));
|
||||
m_QC.setToNoCheck(0, NLTIME_FROM_NS(48));
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
OUTLOGIC(m_QD, 1, NLTIME_FROM_NS(70));
|
||||
OUTLOGIC(m_QC, 0, NLTIME_FROM_NS(48));
|
||||
OUTLOGIC(m_QB, 0, NLTIME_FROM_NS(34));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -768,12 +753,12 @@ NETLIB_CONSTRUCTOR(nic74107A)
|
||||
sub.m_QQ.initial(1);
|
||||
}
|
||||
|
||||
INLINE void nic74107A_newstate(UINT8 state, ttl_output_t &Q, ttl_output_t &QQ)
|
||||
ATTR_HOT inline void nic74107Asub::newstate(const net_sig_t state)
|
||||
{
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
|
||||
#if 1
|
||||
Q.setTo(state, delay[1-state]);
|
||||
QQ.setTo(1-state, delay[state]);
|
||||
OUTLOGIC(m_Q, state, delay[state ^ 1]);
|
||||
OUTLOGIC(m_QQ, state ^ 1, delay[state]);
|
||||
#else
|
||||
if (state != Q.new_Q())
|
||||
{
|
||||
@ -787,7 +772,7 @@ NETLIB_UPDATE(nic74107Asub)
|
||||
{
|
||||
{
|
||||
net_sig_t t = m_Q.new_Q();
|
||||
nic74107A_newstate((!t & m_Q1) | (t & m_Q2) | m_F, m_Q, m_QQ);
|
||||
newstate((!t & m_Q1) | (t & m_Q2) | m_F);
|
||||
if (!m_Q1)
|
||||
m_clk.inactivate();
|
||||
}
|
||||
@ -795,19 +780,19 @@ NETLIB_UPDATE(nic74107Asub)
|
||||
|
||||
NETLIB_UPDATE(nic74107A)
|
||||
{
|
||||
if (INPVAL(m_J) & INPVAL(m_K))
|
||||
if (INPLOGIC(m_J) & INPLOGIC(m_K))
|
||||
{
|
||||
sub.m_Q1 = 1;
|
||||
sub.m_Q2 = 0;
|
||||
sub.m_F = 0;
|
||||
}
|
||||
else if (!INPVAL(m_J) & INPVAL(m_K))
|
||||
else if (!INPLOGIC(m_J) & INPLOGIC(m_K))
|
||||
{
|
||||
sub.m_Q1 = 0;
|
||||
sub.m_Q2 = 0;
|
||||
sub.m_F = 0;
|
||||
}
|
||||
else if (INPVAL(m_J) & !INPVAL(m_K))
|
||||
else if (INPLOGIC(m_J) & !INPLOGIC(m_K))
|
||||
{
|
||||
sub.m_Q1 = 0;
|
||||
sub.m_Q2 = 0;
|
||||
@ -820,13 +805,15 @@ NETLIB_UPDATE(nic74107A)
|
||||
sub.m_F = 0;
|
||||
sub.m_clk.inactivate();
|
||||
}
|
||||
if (!INPVAL(m_clrQ))
|
||||
if (!INPLOGIC(m_clrQ))
|
||||
{
|
||||
sub.m_clk.inactivate();
|
||||
nic74107A_newstate(0, sub.m_Q, sub.m_QQ);
|
||||
sub.newstate(0);
|
||||
}
|
||||
if (!sub.m_Q2 && INPVAL(m_clrQ))
|
||||
else if (!sub.m_Q2)
|
||||
sub.m_clk.activate_hl();
|
||||
//if (!sub.m_Q2 & INPLOGIC(m_clrQ))
|
||||
// sub.m_clk.activate_hl();
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic74153)
|
||||
@ -845,15 +832,15 @@ NETLIB_CONSTRUCTOR(nic74153)
|
||||
NETLIB_UPDATE(nic74153)
|
||||
{
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
|
||||
if (!INPVAL(m_GA))
|
||||
if (!INPLOGIC(m_GA))
|
||||
{
|
||||
UINT8 chan = (INPVAL(m_A) | (INPVAL(m_B)<<1));
|
||||
UINT8 t = INPVAL(m_I[chan]);
|
||||
m_AY.setTo(t, delay[t] ); /* data to y only, FIXME */
|
||||
UINT8 chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
|
||||
UINT8 t = INPLOGIC(m_I[chan]);
|
||||
OUTLOGIC(m_AY, t, delay[t] ); /* data to y only, FIXME */
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AY.setTo(0, delay[0]);
|
||||
OUTLOGIC(m_AY, 0, delay[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -893,19 +880,19 @@ NETLIB_UPDATE(nic9316_sub)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cnt = (INPVAL_PASSIVE(m_D) << 3) | (INPVAL_PASSIVE(m_C) << 2) | (INPVAL_PASSIVE(m_B) << 1) | (INPVAL_PASSIVE(m_A) << 0);
|
||||
m_cnt = (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
||||
update_outputs_all();
|
||||
}
|
||||
m_RC.setTo(m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||
OUTLOGIC(m_RC, m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic9316)
|
||||
{
|
||||
sub.m_loadq = INPVAL(m_LOADQ);
|
||||
sub.m_ent = INPVAL(m_ENT);
|
||||
const net_sig_t clrq = INPVAL(m_CLRQ);
|
||||
sub.m_loadq = INPLOGIC(m_LOADQ);
|
||||
sub.m_ent = INPLOGIC(m_ENT);
|
||||
const net_sig_t clrq = INPLOGIC(m_CLRQ);
|
||||
|
||||
if ((!sub.m_loadq || (sub.m_ent & INPVAL(m_ENP))) & clrq)
|
||||
if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
|
||||
{
|
||||
sub.m_clk.activate_lh();
|
||||
}
|
||||
@ -916,58 +903,58 @@ NETLIB_UPDATE(nic9316)
|
||||
{
|
||||
sub.m_cnt = 0;
|
||||
sub.update_outputs();
|
||||
sub.m_RC.setTo(0, NLTIME_FROM_NS(20));
|
||||
OUTLOGIC(sub.m_RC, 0, NLTIME_FROM_NS(20));
|
||||
return;
|
||||
}
|
||||
}
|
||||
sub.m_RC.setTo(sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||
}
|
||||
|
||||
NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
|
||||
{
|
||||
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||
m_QA.setTo((m_cnt >> 0) & 1, out_delay);
|
||||
m_QB.setTo((m_cnt >> 1) & 1, out_delay);
|
||||
m_QC.setTo((m_cnt >> 2) & 1, out_delay);
|
||||
m_QD.setTo((m_cnt >> 3) & 1, out_delay);
|
||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
||||
}
|
||||
|
||||
NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
|
||||
{
|
||||
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||
#if 0
|
||||
m_QA.setTo((m_cnt >> 0) & 1, out_delay);
|
||||
m_QB.setTo((m_cnt >> 1) & 1, out_delay);
|
||||
m_QC.setTo((m_cnt >> 2) & 1, out_delay);
|
||||
m_QD.setTo((m_cnt >> 3) & 1, out_delay);
|
||||
OUTLOGIC(m_QA, (m_cnt >> 0) & 1, out_delay);
|
||||
OUTLOGIC(m_QB, (m_cnt >> 1) & 1, out_delay);
|
||||
OUTLOGIC(m_QC, (m_cnt >> 2) & 1, out_delay);
|
||||
OUTLOGIC(m_QD, (m_cnt >> 3) & 1, out_delay);
|
||||
#else
|
||||
if ((m_cnt & 1) == 1)
|
||||
m_QA.setToNoCheck(1, out_delay);
|
||||
OUTLOGIC(m_QA, 1, out_delay);
|
||||
else
|
||||
{
|
||||
m_QA.setToNoCheck(0, out_delay);
|
||||
OUTLOGIC(m_QA, 0, out_delay);
|
||||
switch (m_cnt)
|
||||
{
|
||||
case 0x00:
|
||||
m_QB.setToNoCheck(0, out_delay);
|
||||
m_QC.setToNoCheck(0, out_delay);
|
||||
m_QD.setToNoCheck(0, out_delay);
|
||||
OUTLOGIC(m_QB, 0, out_delay);
|
||||
OUTLOGIC(m_QC, 0, out_delay);
|
||||
OUTLOGIC(m_QD, 0, out_delay);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x06:
|
||||
case 0x0A:
|
||||
case 0x0E:
|
||||
m_QB.setToNoCheck(1, out_delay);
|
||||
OUTLOGIC(m_QB, 1, out_delay);
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x0C:
|
||||
m_QB.setToNoCheck(0, out_delay);
|
||||
m_QC.setToNoCheck(1, out_delay);
|
||||
OUTLOGIC(m_QB, 0, out_delay);
|
||||
OUTLOGIC(m_QC, 1, out_delay);
|
||||
break;
|
||||
case 0x08:
|
||||
m_QB.setToNoCheck(0, out_delay);
|
||||
m_QC.setToNoCheck(0, out_delay);
|
||||
m_QD.setToNoCheck(1, out_delay);
|
||||
OUTLOGIC(m_QB, 0, out_delay);
|
||||
OUTLOGIC(m_QC, 0, out_delay);
|
||||
OUTLOGIC(m_QD, 1, out_delay);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -986,7 +973,7 @@ static const net_device_t_base_factory *netregistry[] =
|
||||
ENTRY(netdev_log, NETDEV_LOG)
|
||||
ENTRY(netdev_clock, NETDEV_CLOCK)
|
||||
ENTRY(netdev_mainclock, NETDEV_MAINCLOCK)
|
||||
ENTRY(netdev_callback, NETDEV_CALLBACK)
|
||||
ENTRY(netdev_analog_callback,NETDEV_CALLBACK)
|
||||
ENTRY(nicMultiSwitch, NETDEV_SWITCH2)
|
||||
ENTRY(nicRSFF, NETDEV_RSFF)
|
||||
ENTRY(nicMixer8, NETDEV_MIXER)
|
||||
|
@ -66,7 +66,7 @@
|
||||
#define NETDEV_ANALOG_INPUT(_name) \
|
||||
NET_REGISTER_DEV(netdev_analog_input, _name)
|
||||
#define NETDEV_CALLBACK(_name, _IN) \
|
||||
NET_REGISTER_DEV(netdev_callback, _name) \
|
||||
NET_REGISTER_DEV(netdev_analog_callback, _name) \
|
||||
NET_CONNECT(_name, IN, _IN)
|
||||
#define NETDEV_SWITCH2(_name, _i1, _i2) \
|
||||
NET_REGISTER_DEV(nicMultiSwitch, _name) \
|
||||
@ -333,6 +333,8 @@ NETLIB_SUBDEVICE(nic7474sub,
|
||||
UINT8 m_nextD;
|
||||
ttl_output_t m_Q;
|
||||
ttl_output_t m_QQ;
|
||||
|
||||
ATTR_HOT inline void newstate(const UINT8 state);
|
||||
);
|
||||
|
||||
NETLIB_DEVICE(nic7474,
|
||||
@ -357,13 +359,16 @@ NETLIB_DEVICE(nic7486,
|
||||
NETLIB_SUBDEVICE(nic74107Asub,
|
||||
ttl_input_t m_clk;
|
||||
|
||||
UINT8 m_Q1;
|
||||
UINT8 m_Q2;
|
||||
UINT8 m_F;
|
||||
|
||||
ttl_output_t m_Q;
|
||||
ttl_output_t m_QQ;
|
||||
|
||||
|
||||
net_sig_t m_Q1;
|
||||
net_sig_t m_Q2;
|
||||
net_sig_t m_F;
|
||||
|
||||
ATTR_HOT void newstate(const net_sig_t state);
|
||||
|
||||
);
|
||||
|
||||
NETLIB_DEVICE(nic74107A,
|
||||
|
@ -78,57 +78,8 @@
|
||||
#define end_timing(v) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_timed_queue
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_timed_queue::push(const entry_t &e)
|
||||
{
|
||||
const netlist_time &t = e.time();
|
||||
/* no real speedup */
|
||||
#if 0
|
||||
if (is_empty() || (t <= item(m_end - 1).time()))
|
||||
{
|
||||
set_item(m_end, e);
|
||||
m_end++;
|
||||
inc_stat(m_prof_end);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int i = m_end;
|
||||
m_end++;
|
||||
while ((i>0) && (t > item(i-1).time()) )
|
||||
{
|
||||
set_item(i, item(i-1));
|
||||
inc_stat(m_prof_sortmove);
|
||||
i--;
|
||||
}
|
||||
set_item(i, e);
|
||||
inc_stat(m_prof_sort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const netlist_time netlist_time::zero = netlist_time::from_raw(0);
|
||||
|
||||
ATTR_HOT ATTR_ALIGN const net_sig_t net_core_device_t::INPVAL_PASSIVE(logic_input_t &inp)
|
||||
{
|
||||
net_sig_t ret;
|
||||
const net_input_t::net_input_state st = inp.state();
|
||||
if (st == net_input_t::INP_STATE_PASSIVE)
|
||||
{
|
||||
inp.activate();
|
||||
ret = inp.Q();
|
||||
inp.inactivate();
|
||||
}
|
||||
else
|
||||
ret = inp.Q();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// A netlist parser
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -342,6 +293,35 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_timed_queue
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_timed_queue::push(const entry_t &e)
|
||||
{
|
||||
const netlist_time &t = e.time();
|
||||
if (is_empty() || (t <= item(m_end - 1).time()))
|
||||
{
|
||||
set_item(m_end, e);
|
||||
m_end++;
|
||||
inc_stat(m_prof_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = m_end;
|
||||
m_end++;
|
||||
while ((i>0) && (t > item(i-1).time()) )
|
||||
{
|
||||
set_item(i, item(i-1));
|
||||
inc_stat(m_prof_sortmove);
|
||||
i--;
|
||||
}
|
||||
set_item(i, e);
|
||||
inc_stat(m_prof_sort);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_a_to_d
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -355,24 +335,55 @@ public:
|
||||
assert(in_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
||||
m_I.m_high_thresh_V = in_proxied.m_high_thresh_V;
|
||||
m_I.m_low_thresh_V = in_proxied.m_low_thresh_V;
|
||||
m_I.init(this);
|
||||
m_I.init_input(this);
|
||||
|
||||
m_Q.set_netdev(this);
|
||||
m_Q.init_terminal(this);
|
||||
m_Q.initial(1);
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void update()
|
||||
{
|
||||
if (m_I.Q_Analog() > m_I.m_high_thresh_V)
|
||||
m_Q.setTo(1, NLTIME_FROM_NS(1));
|
||||
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
|
||||
else if (m_I.Q_Analog() < m_I.m_low_thresh_V)
|
||||
m_Q.setTo(0, NLTIME_FROM_NS(1));
|
||||
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
analog_input_t m_I;
|
||||
ttl_output_t m_Q;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_d_to_a
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netdev_d_to_a_proxy : public net_device_t
|
||||
{
|
||||
public:
|
||||
netdev_d_to_a_proxy(netlist_setup_t &setup, const char *name, net_output_t &out_proxied)
|
||||
: net_device_t(setup, name)
|
||||
{
|
||||
m_low_V = out_proxied.m_low_V;
|
||||
m_high_V = out_proxied.m_high_V;
|
||||
assert(out_proxied.object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
||||
m_I.init_input(this);
|
||||
m_Q.init_terminal(this);
|
||||
m_Q.initial(0);
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void update()
|
||||
{
|
||||
OUTANALOG(m_Q, INPLOGIC(m_I) ? m_high_V : m_low_V, NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
ttl_input_t m_I;
|
||||
analog_output_t m_Q;
|
||||
|
||||
private:
|
||||
double m_low_V;
|
||||
double m_high_V;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_const
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -389,7 +400,7 @@ NETLIB_UPDATE(netdev_ttl_const)
|
||||
|
||||
NETLIB_UPDATE_PARAM(netdev_ttl_const)
|
||||
{
|
||||
m_Q.setTo(m_const.ValueInt(), NLTIME_IMMEDIATE);
|
||||
OUTLOGIC(m_Q, m_const.ValueInt(), NLTIME_IMMEDIATE);
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(netdev_analog_const)
|
||||
@ -412,6 +423,13 @@ NETLIB_UPDATE_PARAM(netdev_analog_const)
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
NETLIB_UPDATE(netdev_analog_callback)
|
||||
{
|
||||
// FIXME: Remove after device cleanup
|
||||
if (!m_callback.isnull())
|
||||
m_callback(INPANALOG(m_in));
|
||||
}
|
||||
|
||||
netlist_base_t::netlist_base_t()
|
||||
: m_mainclock(NULL),
|
||||
m_time_ps(NLTIME_FROM_MS(0)),
|
||||
@ -478,17 +496,16 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
|
||||
atime = 0;
|
||||
}
|
||||
} else {
|
||||
net_output_t &mainclock_Q = m_mainclock->m_Q;
|
||||
while (atime > 0)
|
||||
{
|
||||
if (m_queue.is_not_empty())
|
||||
{
|
||||
while (m_queue.peek().time() > mainclock_Q.time())
|
||||
while (m_queue.peek().time() > m_mainclock->m_Q.time())
|
||||
{
|
||||
update_time(mainclock_Q.time(), atime);
|
||||
update_time(m_mainclock->m_Q.time(), atime);
|
||||
|
||||
m_mainclock->update();
|
||||
mainclock_Q.update_devs();
|
||||
m_mainclock->m_Q.update_devs();
|
||||
|
||||
}
|
||||
const queue_t::entry_t &e = m_queue.pop();
|
||||
@ -498,10 +515,10 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
|
||||
e.object().update_devs();
|
||||
|
||||
} else {
|
||||
update_time(mainclock_Q.time(), atime);
|
||||
update_time(m_mainclock->m_Q.time(), atime);
|
||||
|
||||
m_mainclock->update();
|
||||
mainclock_Q.update_devs();
|
||||
m_mainclock->m_Q.update_devs();
|
||||
}
|
||||
if (FATAL_ERROR_AFTER_NS)
|
||||
if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS))
|
||||
@ -516,8 +533,6 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
|
||||
atime = 0;
|
||||
}
|
||||
}
|
||||
//if (KEEP_STATISTICS)
|
||||
// printf("%d\n", m_perf_out_processed);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -582,8 +597,8 @@ void netlist_setup_t::remove_dev(const char *name)
|
||||
|
||||
temp.cat(".");
|
||||
|
||||
remove_start_with<tagmap_input_t>(m_inputs, temp);
|
||||
remove_start_with<tagmap_output_t>(m_outputs, temp);
|
||||
//remove_start_with<tagmap_input_t>(m_inputs, temp);
|
||||
remove_start_with<tagmap_terminal_t>(m_terminals, temp);
|
||||
remove_start_with<tagmap_param_t>(m_params, temp);
|
||||
remove_start_with<tagmap_astring_t>(m_links, temp);
|
||||
m_devices.remove(name);
|
||||
@ -591,7 +606,7 @@ void netlist_setup_t::remove_dev(const char *name)
|
||||
|
||||
void netlist_setup_t::register_callback(const char *devname, net_output_delegate delegate)
|
||||
{
|
||||
netdev_callback *dev = (netdev_callback *) m_devices.find(devname);
|
||||
netdev_analog_callback *dev = (netdev_analog_callback *) m_devices.find(devname);
|
||||
if (dev == NULL)
|
||||
fatalerror("did not find device %s\n", devname);
|
||||
dev->register_callback(delegate);
|
||||
@ -609,8 +624,8 @@ void netlist_setup_t::register_output(net_core_device_t &dev, net_core_device_t
|
||||
astring temp = dev.name();
|
||||
temp.cat(".");
|
||||
temp.cat(name);
|
||||
out.set_netdev(&upd_dev);
|
||||
if (!(m_outputs.add(temp, &out, false)==TMERR_NONE))
|
||||
out.init_terminal(&upd_dev);
|
||||
if (!(m_terminals.add(temp, &out, false)==TMERR_NONE))
|
||||
fatalerror("Error adding output %s to output list\n", name);
|
||||
}
|
||||
|
||||
@ -620,9 +635,9 @@ void netlist_setup_t::register_input(net_device_t &dev, net_core_device_t &upd_d
|
||||
astring temp = dev.name();
|
||||
temp.cat(".");
|
||||
temp.cat(name);
|
||||
inp.init(&upd_dev, type);
|
||||
inp.init_input(&upd_dev, type);
|
||||
dev.m_inputs.add(core_strdup(temp.cstr()));
|
||||
if (!(m_inputs.add(temp, &inp, false) == TMERR_NONE))
|
||||
if (!(m_terminals.add(temp, &inp, false) == TMERR_NONE))
|
||||
fatalerror("Error adding input %s to input list\n", name);
|
||||
}
|
||||
|
||||
@ -654,9 +669,8 @@ const char *netlist_setup_t::resolve_alias(const char *name) const
|
||||
|
||||
net_output_t *netlist_setup_t::find_output_exact(const char *outname_in)
|
||||
{
|
||||
net_output_t *ret = m_outputs.find(outname_in);
|
||||
|
||||
return ret;
|
||||
net_terminal_t *term = m_terminals.find(outname_in);
|
||||
return dynamic_cast<net_output_t *>(term);
|
||||
}
|
||||
|
||||
net_output_t &netlist_setup_t::find_output(const char *outname_in)
|
||||
@ -698,7 +712,7 @@ void netlist_setup_t::resolve_inputs(void)
|
||||
{
|
||||
const astring *sout = entry->object();
|
||||
astring sin = entry->tag();
|
||||
net_input_t *in = m_inputs.find(sin);
|
||||
net_input_t *in = dynamic_cast<net_input_t *>(m_terminals.find(sin));
|
||||
|
||||
if (in == NULL)
|
||||
fatalerror("Unable to find %s\n", sin.cstr());
|
||||
@ -707,26 +721,33 @@ void netlist_setup_t::resolve_inputs(void)
|
||||
if (out.object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_ANALOG
|
||||
&& in->object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_DIGITAL)
|
||||
{
|
||||
// fatalerror("connecting analog output %s with %s\n", out.netdev()->name(), in->netdev()->name());
|
||||
// fatalerror("connecting analog output %s with %s\n", out.netdev()->name(), in->netdev()->name());
|
||||
netdev_a_to_d_proxy *proxy = new netdev_a_to_d_proxy(*this, "abc", *in);
|
||||
in->set_output(proxy->GETINPPTR(proxy->m_Q));
|
||||
//Next check would not work with dynamic activation
|
||||
//if (in->state() != net_input_t::INP_STATE_PASSIVE)
|
||||
proxy->m_Q.register_con(*in);
|
||||
proxy->m_I.set_output(&out);
|
||||
//if (proxy->m_I.state() != net_input_t::INP_STATE_PASSIVE)
|
||||
out.register_con(proxy->m_I);
|
||||
|
||||
in->set_output(proxy->m_Q);
|
||||
proxy->m_Q.register_con(*in);
|
||||
proxy->m_I.set_output(out);
|
||||
out.register_con(proxy->m_I);
|
||||
|
||||
}
|
||||
else if (out.object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_DIGITAL
|
||||
&& in->object_type(net_output_t::SIGNAL_MASK) == net_output_t::SIGNAL_ANALOG)
|
||||
{
|
||||
//printf("here 1\n");
|
||||
netdev_d_to_a_proxy *proxy = new netdev_d_to_a_proxy(*this, "abc", out);
|
||||
|
||||
in->set_output(proxy->m_Q);
|
||||
proxy->m_Q.register_con(*in);
|
||||
proxy->m_I.set_output(out);
|
||||
out.register_con(proxy->m_I);
|
||||
//printf("here 2\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
in->set_output(out.netdev()->GETINPPTR(out));
|
||||
|
||||
//Next check would not work with dynamic activation
|
||||
//if (in->state() != net_input_t::INP_STATE_PASSIVE)
|
||||
out.register_con(*in);
|
||||
in->set_output(out);
|
||||
out.register_con(*in);
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure params are set now .. */
|
||||
for (tagmap_param_t::entry_t *entry = m_params.first(); entry != NULL; entry = m_params.next(entry))
|
||||
{
|
||||
@ -747,12 +768,8 @@ void netlist_setup_t::resolve_inputs(void)
|
||||
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||
{
|
||||
net_device_t *dev = entry->object();
|
||||
dev->update_device();
|
||||
//INT32 time = 10000;
|
||||
//m_netlist.process_list(time);
|
||||
dev->update();
|
||||
}
|
||||
//m_netlist.m_queue.clear();
|
||||
|
||||
|
||||
#else
|
||||
/* make sure all outputs are triggered once */
|
||||
@ -770,10 +787,11 @@ void netlist_setup_t::resolve_inputs(void)
|
||||
#endif
|
||||
|
||||
/* print all outputs */
|
||||
for (tagmap_output_t::entry_t *entry = m_outputs.first(); entry != NULL; entry = m_outputs.next(entry))
|
||||
for (tagmap_terminal_t::entry_t *entry = m_terminals.first(); entry != NULL; entry = m_terminals.next(entry))
|
||||
{
|
||||
ATTR_UNUSED net_output_t *out = entry->object();
|
||||
VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr()));
|
||||
ATTR_UNUSED net_output_t *out = dynamic_cast<net_output_t *>(entry->object());
|
||||
if (out != NULL)
|
||||
VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr()));
|
||||
}
|
||||
|
||||
|
||||
@ -821,6 +839,20 @@ net_core_device_t::~net_core_device_t()
|
||||
// net_device_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_HOT ATTR_ALIGN const net_sig_t net_core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp)
|
||||
{
|
||||
net_sig_t ret;
|
||||
if (inp.state() == net_input_t::INP_STATE_PASSIVE)
|
||||
{
|
||||
inp.activate();
|
||||
ret = inp.Q();
|
||||
inp.inactivate();
|
||||
}
|
||||
else
|
||||
ret = inp.Q();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
net_device_t::net_device_t(netlist_setup_t &setup, const char *name)
|
||||
: net_core_device_t(setup, name),
|
||||
@ -855,8 +887,8 @@ void net_device_t::register_input(const char *name, net_input_t &inp, net_input_
|
||||
|
||||
void net_device_t::register_link_internal(net_core_device_t &dev, net_input_t &in, net_output_t &out, net_input_t::net_input_state aState)
|
||||
{
|
||||
in.set_output(GETINPPTR(out));
|
||||
in.init(&dev, aState);
|
||||
in.set_output(out);
|
||||
in.init_input(&dev, aState);
|
||||
//if (in.state() != net_input_t::INP_STATE_PASSIVE)
|
||||
out.register_con(in);
|
||||
}
|
||||
@ -878,13 +910,23 @@ void net_device_t::register_param(const char *name, net_param_t ¶m, double i
|
||||
register_param(*this,name, param, initialVal);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_terminal_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_COLD void net_terminal_t::init_terminal(net_core_device_t *dev)
|
||||
{
|
||||
m_netdev = dev;
|
||||
m_netlist = &dev->netlist();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_COLD void net_input_t::init(net_core_device_t *dev, net_input_state astate)
|
||||
ATTR_COLD void net_input_t::init_input(net_core_device_t *dev, net_input_state astate)
|
||||
{
|
||||
m_netdev = dev;
|
||||
init_terminal(dev);
|
||||
m_state = astate;
|
||||
#if USE_DELEGATES
|
||||
h = net_update_delegate(&net_core_device_t::update, "update", dev);
|
||||
@ -896,7 +938,7 @@ ATTR_COLD void net_input_t::init(net_core_device_t *dev, net_input_state astate)
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
net_output_t::net_output_t(int atype)
|
||||
: net_object_t(atype)
|
||||
: net_terminal_t(atype)
|
||||
{
|
||||
m_last_Q = 0;
|
||||
m_Q = 0;
|
||||
@ -906,23 +948,18 @@ net_output_t::net_output_t(int atype)
|
||||
m_num_cons = 0;
|
||||
m_Q_analog = 0.0;
|
||||
m_new_Q_analog = 0.0;
|
||||
//m_cons = global_alloc_array(net_input_t *, OUTPUT_MAX_CONNECTIONS);
|
||||
}
|
||||
|
||||
ATTR_COLD void net_output_t::set_netdev(net_core_device_t *dev)
|
||||
ATTR_HOT inline void net_output_t::update_dev(const net_input_t *inp, const UINT32 mask)
|
||||
{
|
||||
m_netdev = dev;
|
||||
m_netlist = &dev->netlist();
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN inline void net_output_t::update_dev(const net_input_t &inp, const UINT8 mask)
|
||||
{
|
||||
if (((inp.state() & mask) != 0))
|
||||
if ((inp->state() & mask) != 0)
|
||||
{
|
||||
ATTR_UNUSED net_core_device_t *netdev = inp.netdev();
|
||||
ATTR_UNUSED net_core_device_t *netdev = inp->netdev();
|
||||
begin_timing(netdev->total_time);
|
||||
inc_stat(netdev->stat_count);
|
||||
#if USE_DELEGATES
|
||||
inp.h();
|
||||
inp->h();
|
||||
#else
|
||||
netdev->update();
|
||||
#endif
|
||||
@ -930,45 +967,41 @@ ATTR_HOT ATTR_ALIGN inline void net_output_t::update_dev(const net_input_t &inp,
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN inline void net_output_t::update_devs()
|
||||
ATTR_HOT inline void net_output_t::update_devs()
|
||||
{
|
||||
|
||||
assert(m_num_cons != 0);
|
||||
|
||||
const UINT8 masks[4] = { 1, 5, 3, 1 };
|
||||
const UINT32 masks[4] = { 1, 5, 3, 1 };
|
||||
m_Q = m_new_Q;
|
||||
m_Q_analog = m_new_Q_analog;
|
||||
m_in_queue = 2; /* mark as taken ... */
|
||||
|
||||
//if (m_last_Q == m_Q)
|
||||
//printf("%s\n", m_netdev->name());
|
||||
//UINT32 mask = 1 | ((m_last_Q & (m_Q ^ 1)) << 1) | (((m_last_Q ^ 1) & m_Q) << 2);
|
||||
const UINT8 mask = masks[ (m_last_Q << 1) | m_Q ];
|
||||
const UINT32 mask = masks[ (m_last_Q << 1) | m_Q ];
|
||||
|
||||
switch (m_num_cons)
|
||||
{
|
||||
case 2:
|
||||
update_dev(*m_cons[1], mask);
|
||||
update_dev(m_cons[1], mask);
|
||||
case 1:
|
||||
update_dev(*m_cons[0], mask);
|
||||
update_dev(m_cons[0], mask);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
for (int i=0; i < m_num_cons; i++)
|
||||
update_dev(*m_cons[i], mask);
|
||||
update_dev(m_cons[i], mask);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_last_Q = m_Q;
|
||||
|
||||
}
|
||||
|
||||
ATTR_COLD void net_output_t::register_con(net_input_t &input)
|
||||
{
|
||||
int i;
|
||||
if (m_num_cons >= ARRAY_LENGTH(m_cons))
|
||||
fatalerror("Connections exceeded for %s\n", m_netdev->name());
|
||||
if (m_num_cons >= OUTPUT_MAX_CONNECTIONS)
|
||||
fatalerror("Connections exceeded for %s\n", netdev()->name());
|
||||
|
||||
/* keep similar devices together */
|
||||
for (i = 0; i < m_num_cons; i++)
|
||||
@ -984,19 +1017,10 @@ ATTR_COLD void net_output_t::register_con(net_input_t &input)
|
||||
m_active++;
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(netdev_callback)
|
||||
{
|
||||
// FIXME: Remove after device cleanup
|
||||
if (!m_callback.isnull())
|
||||
m_callback(INPANALOG(m_in));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_device
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
const device_type NETLIST = &device_creator<netlist_mame_device>;
|
||||
|
||||
netlist_mame_device::netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
@ -1065,11 +1089,13 @@ void netlist_mame_device::device_timer(emu_timer &timer, device_timer_id id, int
|
||||
|
||||
void netlist_mame_device::save_state()
|
||||
{
|
||||
#if 0
|
||||
for (netlist_setup_t::tagmap_output_t::entry_t *entry = m_setup->m_outputs.first(); entry != NULL; entry = m_setup->m_outputs.next(entry))
|
||||
{
|
||||
save_item(*entry->object()->Q_ptr(), entry->tag().cstr(), 0);
|
||||
save_item(*entry->object()->new_Q_ptr(), entry->tag().cstr(), 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
UINT64 netlist_mame_device::execute_clocks_to_cycles(UINT64 clocks) const
|
||||
|
@ -60,6 +60,8 @@
|
||||
// Next if enabled adds 20% performance ... but is not guaranteed to be absolutely timing correct.
|
||||
#define USE_DEACTIVE_DEVICE (0)
|
||||
|
||||
#define OUTPUT_MAX_CONNECTIONS (48)
|
||||
|
||||
// Use nano-second resolution - Sufficient for now
|
||||
//#define NETLIST_INTERNAL_RES (U64(1000000000))
|
||||
//#define NETLIST_DIV_BITS (0)
|
||||
@ -194,6 +196,7 @@ typedef delegate<void ()> net_update_delegate;
|
||||
|
||||
typedef UINT8 net_sig_t;
|
||||
|
||||
|
||||
typedef delegate<void (const double)> net_output_delegate;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -327,16 +330,18 @@ public:
|
||||
|
||||
static const int SIZE = ((1 << 11) - 1);
|
||||
|
||||
typedef net_output_t element_t;
|
||||
|
||||
struct entry_t
|
||||
{
|
||||
public:
|
||||
inline entry_t() {}
|
||||
inline entry_t(const netlist_time atime, net_output_t &elem) : m_time(atime), m_object(&elem) {}
|
||||
inline entry_t(const netlist_time atime, element_t &elem) : m_time(atime), m_object(&elem) {}
|
||||
ATTR_HOT inline const netlist_time &time() const { return m_time; }
|
||||
ATTR_HOT inline net_output_t & object() const { return *m_object; }
|
||||
ATTR_HOT inline element_t & object() const { return *m_object; }
|
||||
private:
|
||||
netlist_time m_time;
|
||||
net_output_t *m_object;
|
||||
element_t *m_object;
|
||||
};
|
||||
|
||||
netlist_timed_queue()
|
||||
@ -344,8 +349,8 @@ public:
|
||||
clear();
|
||||
}
|
||||
|
||||
ATTR_HOT inline bool is_empty() { return (m_end == 0); }
|
||||
ATTR_HOT inline bool is_not_empty() { return (m_end != 0); }
|
||||
ATTR_HOT inline bool is_empty() const { return (m_end == 0); }
|
||||
ATTR_HOT inline bool is_not_empty() const { return (m_end != 0); }
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void push(const entry_t &e);
|
||||
|
||||
@ -391,7 +396,10 @@ public:
|
||||
OUTPUT = 1,
|
||||
DEVICE = 2,
|
||||
PARAM = 3,
|
||||
TYPE_MASK = 0x03,
|
||||
TERMINAL = 4,
|
||||
NET_ANALOG = 5,
|
||||
NET_DIGITAL = 6,
|
||||
TYPE_MASK = 0x0f,
|
||||
SIGNAL_DIGITAL = 0x00,
|
||||
SIGNAL_ANALOG = 0x10,
|
||||
SIGNAL_MASK = 0x10,
|
||||
@ -400,6 +408,8 @@ public:
|
||||
net_object_t(int atype)
|
||||
: m_objtype(atype) {}
|
||||
|
||||
virtual ~net_object_t() {}
|
||||
|
||||
ATTR_HOT inline int object_type() const { return m_objtype; }
|
||||
ATTR_HOT inline int object_type(const UINT32 mask) const { return m_objtype & mask; }
|
||||
|
||||
@ -407,13 +417,31 @@ private:
|
||||
int m_objtype;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_terminal_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class net_terminal_t : public net_object_t
|
||||
{
|
||||
public:
|
||||
|
||||
net_terminal_t(const int atype) : net_object_t(atype) {}
|
||||
|
||||
ATTR_COLD void init_terminal(net_core_device_t *dev);
|
||||
ATTR_HOT inline net_core_device_t * RESTRICT netdev() const { return m_netdev; }
|
||||
ATTR_HOT inline netlist_base_t * RESTRICT netlist() const { return m_netlist; }
|
||||
|
||||
private:
|
||||
net_core_device_t * RESTRICT m_netdev;
|
||||
netlist_base_t * RESTRICT m_netlist;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class net_input_t : public net_object_t
|
||||
class net_input_t : public net_terminal_t
|
||||
{
|
||||
public:
|
||||
|
||||
@ -424,21 +452,23 @@ public:
|
||||
INP_STATE_LH = 4,
|
||||
};
|
||||
|
||||
net_input_t(const int atype) : net_object_t(atype), m_state(INP_STATE_ACTIVE) {}
|
||||
ATTR_COLD void init(net_core_device_t *dev, net_input_state astate = INP_STATE_ACTIVE);
|
||||
ATTR_COLD net_input_t(const int atype)
|
||||
: net_terminal_t(atype)
|
||||
, m_state(INP_STATE_ACTIVE)
|
||||
{}
|
||||
|
||||
ATTR_COLD void init_input(net_core_device_t *dev, net_input_state astate = INP_STATE_ACTIVE);
|
||||
|
||||
ATTR_HOT inline net_output_t * RESTRICT output() const { return m_output; }
|
||||
ATTR_HOT inline const bool is_state(const net_input_state astate) { return (m_state == astate); }
|
||||
ATTR_HOT inline const bool is_state(const net_input_state astate) const { return (m_state == astate); }
|
||||
ATTR_HOT inline const net_input_state state() const { return m_state; }
|
||||
|
||||
ATTR_COLD void set_output(net_output_t *aout) { m_output = aout; }
|
||||
ATTR_COLD void set_output(net_output_t &aout) { m_output = &aout; }
|
||||
ATTR_HOT inline void inactivate();
|
||||
ATTR_HOT inline void activate();
|
||||
ATTR_HOT inline void activate_hl();
|
||||
ATTR_HOT inline void activate_lh();
|
||||
|
||||
ATTR_HOT inline net_core_device_t * RESTRICT netdev() const { return m_netdev; }
|
||||
|
||||
double m_low_thresh_V;
|
||||
double m_high_thresh_V;
|
||||
|
||||
@ -448,7 +478,6 @@ public:
|
||||
|
||||
private:
|
||||
net_input_state m_state;
|
||||
net_core_device_t * RESTRICT m_netdev;
|
||||
net_output_t * RESTRICT m_output;
|
||||
};
|
||||
|
||||
@ -492,46 +521,33 @@ public:
|
||||
|
||||
//#define INPVAL(_x) (_x).Q()
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_output_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class net_output_t : public net_object_t
|
||||
class netdev_mainclock;
|
||||
|
||||
class net_output_t : public net_terminal_t
|
||||
{
|
||||
public:
|
||||
|
||||
net_output_t(int atype);
|
||||
|
||||
friend const net_sig_t logic_input_t::Q() const;
|
||||
friend const double analog_input_t::Q_Analog() const;
|
||||
friend const bool analog_input_t::is_highz() const;
|
||||
friend class netdev_mainclock;
|
||||
|
||||
ATTR_HOT inline const net_sig_t last_Q() const { return m_last_Q; }
|
||||
ATTR_HOT inline const net_sig_t new_Q() const { return m_new_Q; }
|
||||
|
||||
ATTR_HOT inline const double Q_Analog() const
|
||||
{
|
||||
switch (object_type(SIGNAL_MASK))
|
||||
{
|
||||
case SIGNAL_DIGITAL: return m_Q ? m_high_V : m_low_V;
|
||||
case SIGNAL_ANALOG: return m_Q_analog;
|
||||
default: assert(true); break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline net_sig_t *Q_ptr() { return &m_Q; }
|
||||
inline net_sig_t *new_Q_ptr() { return &m_new_Q; }
|
||||
//ATTR_HOT inline net_sig_t *Q_ptr() { return &m_Q; }
|
||||
//ATTR_HOT inline net_sig_t *new_Q_ptr() { return &m_new_Q; }
|
||||
|
||||
ATTR_COLD void register_con(net_input_t &inp);
|
||||
|
||||
ATTR_HOT void update_dev(const net_input_t &inp, const UINT8 mask);
|
||||
ATTR_HOT void update_devs();
|
||||
|
||||
ATTR_HOT inline const net_core_device_t *netdev() const { return m_netdev; }
|
||||
|
||||
ATTR_HOT inline void inc_active();
|
||||
ATTR_HOT inline void dec_active();
|
||||
|
||||
@ -539,66 +555,48 @@ public:
|
||||
ATTR_HOT inline const netlist_time time() const { return m_time; }
|
||||
ATTR_HOT inline void set_time(const netlist_time ntime) { m_time = ntime; }
|
||||
|
||||
ATTR_COLD void set_netdev(net_core_device_t *dev);
|
||||
double m_low_V;
|
||||
double m_high_V;
|
||||
|
||||
protected:
|
||||
|
||||
/* prohibit use in device functions
|
||||
* current (pending) state can be inquired using new_Q()
|
||||
*/
|
||||
ATTR_HOT inline const net_sig_t Q() const { return m_Q; }
|
||||
ATTR_HOT inline const net_sig_t Q() const
|
||||
{
|
||||
assert(object_type(SIGNAL_MASK) == SIGNAL_DIGITAL);
|
||||
return m_Q;
|
||||
}
|
||||
ATTR_HOT inline const double Q_Analog() const
|
||||
{
|
||||
assert(object_type(SIGNAL_MASK) == SIGNAL_ANALOG);
|
||||
return m_Q_analog;
|
||||
}
|
||||
|
||||
ATTR_HOT inline void push_to_queue(const netlist_time &delay);
|
||||
|
||||
ATTR_HOT inline void set_Q(const net_sig_t newQ, const netlist_time &delay)
|
||||
{
|
||||
if (newQ != m_new_Q)
|
||||
{
|
||||
m_new_Q = newQ;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
}
|
||||
ATTR_HOT inline void set_Q_NoCheck(const net_sig_t val, const netlist_time &delay)
|
||||
{
|
||||
m_new_Q = val;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
|
||||
ATTR_HOT inline void set_Q_Analog(const double newQ, const netlist_time &delay)
|
||||
{
|
||||
if (newQ != m_new_Q_analog)
|
||||
{
|
||||
m_new_Q_analog = newQ;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
}
|
||||
ATTR_HOT inline void set_Q_NoCheck_Analog(const double val, const netlist_time &delay)
|
||||
{
|
||||
m_new_Q_analog = val;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
|
||||
netlist_time m_time;
|
||||
UINT8 m_in_queue;
|
||||
int m_active;
|
||||
|
||||
net_sig_t m_last_Q;
|
||||
net_sig_t m_Q;
|
||||
net_sig_t m_new_Q;
|
||||
|
||||
double m_Q_analog;
|
||||
double m_new_Q_analog;
|
||||
|
||||
int m_num_cons;
|
||||
private:
|
||||
ATTR_HOT void update_dev(const net_input_t *inp, const UINT32 mask);
|
||||
|
||||
net_input_t *m_cons[48];
|
||||
netlist_time m_time;
|
||||
|
||||
double m_low_V;
|
||||
double m_high_V;
|
||||
INT32 m_active;
|
||||
|
||||
net_core_device_t *m_netdev;
|
||||
netlist_base_t *m_netlist;
|
||||
UINT32 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
|
||||
|
||||
UINT32 m_num_cons;
|
||||
net_input_t *m_cons[OUTPUT_MAX_CONNECTIONS];
|
||||
};
|
||||
|
||||
|
||||
class logic_output_t : public net_output_t
|
||||
{
|
||||
public:
|
||||
@ -612,10 +610,16 @@ public:
|
||||
}
|
||||
|
||||
ATTR_COLD void initial(const net_sig_t val) { m_Q = val; m_new_Q = val; m_last_Q = !val; }
|
||||
ATTR_HOT inline void clear() { set_Q(0, netlist_time::zero); }
|
||||
ATTR_HOT inline void set() { set_Q(1, netlist_time::zero); }
|
||||
ATTR_HOT inline void setTo(const UINT8 val, const netlist_time &delay) { set_Q(val, delay); }
|
||||
ATTR_HOT inline void setToNoCheck(const UINT8 val, const netlist_time &delay) { set_Q_NoCheck(val, delay); }
|
||||
|
||||
ATTR_HOT inline void set_Q(const net_sig_t newQ, const netlist_time &delay)
|
||||
{
|
||||
if (EXPECTED(newQ != m_new_Q))
|
||||
{
|
||||
m_new_Q = newQ;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_COLD inline void set_levels(const double low, const double high)
|
||||
{
|
||||
m_low_V = low;
|
||||
@ -640,9 +644,17 @@ public:
|
||||
analog_output_t()
|
||||
: net_output_t(OUTPUT | SIGNAL_ANALOG) { }
|
||||
|
||||
ATTR_COLD void initial(double val) { m_Q_analog = val; m_new_Q_analog = val; }
|
||||
ATTR_HOT inline void setTo(const double val, const netlist_time &delay) { set_Q_Analog(val,delay); }
|
||||
ATTR_HOT inline void setToNoCheckPS(const double val, const netlist_time &delay) { set_Q_NoCheck_Analog(val,delay); }
|
||||
ATTR_COLD void initial(const double val) { m_Q_analog = val; m_new_Q_analog = val; }
|
||||
|
||||
ATTR_HOT inline void set_Q(const double newQ, const netlist_time &delay)
|
||||
{
|
||||
if (newQ != m_new_Q_analog)
|
||||
{
|
||||
m_new_Q_analog = newQ;
|
||||
push_to_queue(delay);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -659,35 +671,49 @@ public:
|
||||
|
||||
ATTR_COLD const char *name() const { return m_name; }
|
||||
|
||||
ATTR_HOT inline void update_device() { update(); }
|
||||
|
||||
ATTR_HOT virtual void update_param() {}
|
||||
|
||||
ATTR_HOT virtual void update() { }
|
||||
|
||||
ATTR_HOT const net_sig_t INPVAL_PASSIVE(logic_input_t &inp);
|
||||
ATTR_HOT const net_sig_t INPLOGIC_PASSIVE(logic_input_t &inp);
|
||||
|
||||
ATTR_HOT inline const net_sig_t INPVAL(const logic_input_t &inp)
|
||||
ATTR_HOT inline const net_sig_t INPLOGIC(const logic_input_t &inp) const
|
||||
{
|
||||
assert(inp.state() != net_input_t::INP_STATE_PASSIVE);
|
||||
return inp.Q();
|
||||
}
|
||||
|
||||
ATTR_HOT inline const net_sig_t INPVAL_LAST(const logic_input_t &inp) { return inp.last_Q(); }
|
||||
ATTR_HOT inline void OUTLOGIC(logic_output_t &out, const net_sig_t val, const netlist_time &delay)
|
||||
{
|
||||
out.set_Q(val, delay);
|
||||
}
|
||||
|
||||
ATTR_HOT inline const double INPANALOG(const analog_input_t &inp) { return inp.Q_Analog(); }
|
||||
ATTR_HOT inline bool INP_HL(const logic_input_t &inp) const
|
||||
{
|
||||
return ((inp.last_Q() & !inp.Q()) == 1);
|
||||
}
|
||||
|
||||
ATTR_HOT inline bool INP_LH(const logic_input_t &inp) const
|
||||
{
|
||||
return ((!inp.last_Q() & inp.Q()) == 1);
|
||||
}
|
||||
|
||||
ATTR_HOT inline const double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); }
|
||||
|
||||
ATTR_HOT inline void OUTANALOG(analog_output_t &out, const double val, const netlist_time &delay)
|
||||
{
|
||||
out.set_Q(val, delay);
|
||||
}
|
||||
|
||||
ATTR_HOT inline netlist_base_t &netlist() const { return m_netlist; }
|
||||
|
||||
ATTR_COLD inline net_output_t * GETINPPTR(net_output_t &out) const { return &out; }
|
||||
|
||||
ATTR_HOT virtual void inc_active() { }
|
||||
|
||||
ATTR_HOT virtual void dec_active() { /*printf("DeActivate %s\n", m_name);*/ }
|
||||
|
||||
/* stats */
|
||||
osd_ticks_t total_time;
|
||||
volatile INT32 stat_count;
|
||||
INT32 stat_count;
|
||||
|
||||
protected:
|
||||
|
||||
@ -855,9 +881,9 @@ public:
|
||||
for (int i = 0; i< _numdev; i++)
|
||||
{
|
||||
this->m_i[i].activate();
|
||||
if (INPVAL(this->m_i[i]) == _check)
|
||||
if (INPLOGIC(this->m_i[i]) == _check)
|
||||
{
|
||||
this->m_Q.setTo(_check ^ (1 ^ _invert), times[_check]);// ? 15000 : 22000);
|
||||
OUTLOGIC(this->m_Q, _check ^ (1 ^ _invert), times[_check]);// ? 15000 : 22000);
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
@ -868,7 +894,7 @@ public:
|
||||
if (i != pos)
|
||||
this->m_i[i].inactivate();
|
||||
} else
|
||||
this->m_Q.setTo(_check ^ (_invert), times[1-_check]);// ? 22000 : 15000);
|
||||
OUTLOGIC(this->m_Q,_check ^ (_invert), times[1-_check]);// ? 22000 : 15000);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -923,10 +949,10 @@ public:
|
||||
|
||||
UINT8 res = _invert ^ 1 ^_check;
|
||||
m_i[0].activate();
|
||||
if (INPVAL(m_i[0]) ^ _check)
|
||||
if (INPLOGIC(m_i[0]) ^ _check)
|
||||
{
|
||||
m_i[1].activate();
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
if (INPLOGIC(m_i[1]) ^ _check)
|
||||
{
|
||||
res = _invert ^ _check;
|
||||
}
|
||||
@ -934,10 +960,10 @@ public:
|
||||
m_i[0].inactivate();
|
||||
} else {
|
||||
m_i[1].activate();
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
if (INPLOGIC(m_i[1]) ^ _check)
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
|
||||
OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -975,13 +1001,13 @@ public:
|
||||
|
||||
UINT8 res = _invert ^ 1 ^_check;
|
||||
m_i[0].activate();
|
||||
if (INPVAL(m_i[0]) ^ _check)
|
||||
if (INPLOGIC(m_i[0]) ^ _check)
|
||||
{
|
||||
m_i[1].activate();
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
if (INPLOGIC(m_i[1]) ^ _check)
|
||||
{
|
||||
m_i[2].activate();
|
||||
if (INPVAL(m_i[2]) ^ _check)
|
||||
if (INPLOGIC(m_i[2]) ^ _check)
|
||||
{
|
||||
res = _invert ^ _check;
|
||||
}
|
||||
@ -990,12 +1016,12 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (INPVAL(m_i[2]) ^ _check)
|
||||
if (INPLOGIC(m_i[2]) ^ _check)
|
||||
m_i[2].inactivate();
|
||||
m_i[0].inactivate();
|
||||
}
|
||||
} else {
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
if (INPLOGIC(m_i[1]) ^ _check)
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
|
||||
@ -1015,9 +1041,11 @@ public:
|
||||
|
||||
typedef tagmap_t<net_device_t *, 393> tagmap_devices_t;
|
||||
typedef tagmap_t<astring *, 393> tagmap_astring_t;
|
||||
typedef tagmap_t<net_output_t *, 393> tagmap_output_t;
|
||||
typedef tagmap_t<net_input_t *, 393> tagmap_input_t;
|
||||
typedef tagmap_t<net_param_t *, 393> tagmap_param_t;
|
||||
typedef tagmap_t<net_terminal_t *, 393> tagmap_terminal_t;
|
||||
|
||||
//typedef tagmap_t<net_output_t *, 393> tagmap_output_t;
|
||||
//typedef tagmap_t<net_input_t *, 393> tagmap_input_t;
|
||||
|
||||
netlist_setup_t(netlist_base_t &netlist);
|
||||
~netlist_setup_t();
|
||||
@ -1044,7 +1072,7 @@ public:
|
||||
void resolve_inputs(void);
|
||||
|
||||
/* not ideal, but needed for save_state */
|
||||
tagmap_output_t m_outputs;
|
||||
tagmap_terminal_t m_terminals;
|
||||
|
||||
void print_stats();
|
||||
|
||||
@ -1056,7 +1084,7 @@ private:
|
||||
|
||||
tagmap_devices_t m_devices;
|
||||
tagmap_astring_t m_alias;
|
||||
tagmap_input_t m_inputs;
|
||||
//tagmap_input_t m_inputs;
|
||||
tagmap_param_t m_params;
|
||||
tagmap_astring_t m_links;
|
||||
|
||||
@ -1088,7 +1116,7 @@ public:
|
||||
|
||||
ATTR_HOT void process_list(INT32 &atime);
|
||||
|
||||
ATTR_HOT inline const netlist_time &time() { return m_time_ps; }
|
||||
ATTR_HOT inline const netlist_time &time() const { return m_time_ps; }
|
||||
|
||||
ATTR_COLD void set_mainclock_dev(netdev_mainclock *dev) { m_mainclock = dev; }
|
||||
|
||||
@ -1133,14 +1161,25 @@ inline NETLIB_CONSTRUCTOR(netdev_mainclock)
|
||||
|
||||
}
|
||||
|
||||
inline NETLIB_UPDATE_PARAM(netdev_mainclock)
|
||||
{
|
||||
m_inc = netlist_time::from_hz(m_freq.Value()*2);
|
||||
}
|
||||
|
||||
inline NETLIB_UPDATE(netdev_mainclock)
|
||||
{
|
||||
m_Q.m_new_Q = !m_Q.m_new_Q;
|
||||
m_Q.set_time(m_netlist.time() + m_inc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netdev_callback : public net_device_t
|
||||
class netdev_analog_callback : public net_device_t
|
||||
{
|
||||
public:
|
||||
netdev_callback(netlist_setup_t &setup, const char *name)
|
||||
netdev_analog_callback(netlist_setup_t &setup, const char *name)
|
||||
: net_device_t(setup, name)
|
||||
{
|
||||
register_input("IN", m_in);
|
||||
@ -1223,12 +1262,12 @@ ATTR_HOT inline void net_input_t::activate_lh()
|
||||
|
||||
ATTR_HOT inline void net_output_t::push_to_queue(const netlist_time &delay)
|
||||
{
|
||||
m_time = m_netlist->time() + delay;
|
||||
m_in_queue = 0; /* not queued */
|
||||
if (m_active > 0)
|
||||
m_time = netlist()->time() + delay;
|
||||
m_in_queue = (m_active > 0) ? 1 : 0; /* queued ? */
|
||||
if (m_in_queue)
|
||||
{
|
||||
m_in_queue = 1; /* pending */
|
||||
m_netlist->push_to_queue(*this, m_time);
|
||||
//m_in_queue = 1; /* pending */
|
||||
netlist()->push_to_queue(*this, m_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1240,17 +1279,17 @@ ATTR_HOT inline void net_output_t::inc_active()
|
||||
if (m_active == 1 && m_in_queue > 0)
|
||||
{
|
||||
m_last_Q = m_Q;
|
||||
m_netdev->inc_active();
|
||||
netdev()->inc_active();
|
||||
m_Q = m_new_Q;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_active == 1 && m_in_queue == 0)
|
||||
if (EXPECTED(m_active == 1 && m_in_queue == 0))
|
||||
{
|
||||
if (m_time > m_netlist->time())
|
||||
if (EXPECTED(m_time > netlist()->time()))
|
||||
{
|
||||
m_in_queue = 1; /* pending */
|
||||
m_netlist->push_to_queue(*this, m_time);
|
||||
netlist()->push_to_queue(*this, m_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1266,17 +1305,32 @@ ATTR_HOT inline void net_output_t::dec_active()
|
||||
m_active--;
|
||||
#if (USE_DEACTIVE_DEVICE)
|
||||
if (m_active == 0)
|
||||
m_netdev->dec_active();
|
||||
netdev()->dec_active();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ATTR_HOT inline const net_sig_t logic_input_t::Q() const { return output()->Q(); }
|
||||
ATTR_HOT inline const net_sig_t logic_input_t::last_Q() const { return output()->last_Q(); }
|
||||
ATTR_HOT inline const double analog_input_t::Q_Analog() const { return output()->Q_Analog(); }
|
||||
ATTR_HOT inline const bool analog_input_t::is_highz() const { return output()->Q_Analog() == NETLIST_HIGHIMP_V; }
|
||||
ATTR_HOT inline const net_sig_t logic_input_t::Q() const
|
||||
{
|
||||
return output()->Q();
|
||||
}
|
||||
|
||||
ATTR_HOT inline const net_sig_t logic_input_t::last_Q() const
|
||||
{
|
||||
return output()->last_Q();
|
||||
}
|
||||
|
||||
ATTR_HOT inline const double analog_input_t::Q_Analog() const
|
||||
{
|
||||
return output()->Q_Analog();
|
||||
}
|
||||
|
||||
ATTR_HOT inline const bool analog_input_t::is_highz() const
|
||||
{
|
||||
return output()->Q_Analog() == NETLIST_HIGHIMP_V;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_dev class factory
|
||||
@ -1488,6 +1542,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type NETLIST;
|
||||
|
||||
|
@ -96,7 +96,7 @@ static NETLIST_START(pong_schematics)
|
||||
TTL_74107(ic_f6a, xclk, high, high, high)
|
||||
NET_ALIAS(clk, ic_f6a.Q)
|
||||
#else
|
||||
/* abstracting this, performance increases by 80%
|
||||
/* abstracting this, performance increases by 40%
|
||||
* No surprise, the clock is extremely expensive */
|
||||
NETDEV_MAINCLOCK(clk)
|
||||
//NETDEV_CLOCK(clk)
|
||||
@ -593,10 +593,10 @@ INPUT_CHANGED_MEMBER(pong_state::input_changed)
|
||||
double pad = vA + (vB - vA)*PRE_R / (Req + PRE_R);
|
||||
switch (numpad)
|
||||
{
|
||||
case IC_PADDLE1: m_p_V0->setTo(pad, NLTIME_FROM_NS(0)); break;
|
||||
case IC_PADDLE2: m_p_V1->setTo(pad, NLTIME_FROM_NS(0)); break;
|
||||
case IC_PADDLE1: m_p_V0->set_Q(pad, NLTIME_FROM_NS(0)); break;
|
||||
case IC_PADDLE2: m_p_V1->set_Q(pad, NLTIME_FROM_NS(0)); break;
|
||||
}
|
||||
printf("%d %f\n", newval, (float) pad);
|
||||
//printf("%d %f\n", newval, (float) pad);
|
||||
break;
|
||||
}
|
||||
case IC_SWITCH:
|
||||
@ -604,7 +604,7 @@ INPUT_CHANGED_MEMBER(pong_state::input_changed)
|
||||
m_sw1b->setTo(newval ? 1 : 0);
|
||||
break;
|
||||
case IC_COIN:
|
||||
m_srst->setTo(newval & 1, NLTIME_FROM_US(500));
|
||||
m_srst->set_Q(newval & 1, NLTIME_FROM_US(500));
|
||||
break;
|
||||
case IC_VR1:
|
||||
case IC_VR2:
|
||||
|
Loading…
Reference in New Issue
Block a user