Fixed a small but important bug in netlist code. In addition, some more performance improvements.

This commit is contained in:
Couriersud 2013-10-08 22:48:32 +00:00
parent 24ceb02563
commit 43ed2d452b
5 changed files with 291 additions and 209 deletions

View File

@ -303,35 +303,69 @@ NETLIB_UPDATE(nic7486)
NETLIB_START(nic7448) NETLIB_START(nic7448)
{ {
register_input("A0", m_A0); register_subdevice(sub);
register_input("A1", m_A1);
register_input("A2", m_A2); //sub.m_state = 0;
register_input("A3", m_A3);
register_input(sub, "A0", sub.m_A0);
register_input(sub, "A1", sub.m_A1);
register_input(sub, "A2", sub.m_A2);
register_input(sub, "A3", sub.m_A3);
register_input("LTQ", m_LTQ); register_input("LTQ", m_LTQ);
register_input("BIQ", m_BIQ); register_input("BIQ", m_BIQ);
register_input("RBIQ",m_RBIQ); register_input(sub, "RBIQ",sub.m_RBIQ);
register_output("a", m_a); register_output(sub, "a", sub.m_a);
register_output("b", m_b); register_output(sub, "b", sub.m_b);
register_output("c", m_c); register_output(sub, "c", sub.m_c);
register_output("d", m_d); register_output(sub, "d", sub.m_d);
register_output("e", m_e); register_output(sub, "e", sub.m_e);
register_output("f", m_f); register_output(sub, "f", sub.m_f);
register_output("g", m_g); register_output(sub, "g", sub.m_g);
} }
NETLIB_UPDATE(nic7448) NETLIB_UPDATE(nic7448)
{ {
UINT8 v;
if (INPVAL(m_BIQ) && !INPVAL(m_LTQ)) if (INPVAL(m_BIQ) && !INPVAL(m_LTQ))
v = 8;
else
{ {
v = (INPVAL(m_A0) << 0) | (INPVAL(m_A1) << 1) | (INPVAL(m_A2) << 2) | (INPVAL(m_A3) << 3); sub.update_outputs(8);
if (!INPVAL(m_BIQ) || (!INPVAL(m_RBIQ) && (v==0)))
v = 15;
} }
else if (!INPVAL(m_BIQ))
{
sub.update_outputs(15);
}
if (!INPVAL(m_BIQ) || (INPVAL(m_BIQ) && !INPVAL(m_LTQ)))
{
sub.m_A0.inactivate();
sub.m_A1.inactivate();
sub.m_A2.inactivate();
sub.m_A3.inactivate();
sub.m_RBIQ.inactivate();
} else {
sub.m_RBIQ.activate();
sub.m_A3.activate();
sub.m_A2.activate();
sub.m_A1.activate();
sub.m_A0.activate();
sub.update();
}
}
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 = 15;
update_outputs(v);
}
NETLIB_FUNC_VOID(nic7448_sub, update_outputs, (UINT8 v))
{
assert(v<16); assert(v<16);
if (v != m_state) if (v != m_state)
{ {
@ -346,7 +380,7 @@ NETLIB_UPDATE(nic7448)
} }
} }
const UINT8 nic7448::tab7448[16][7] = const UINT8 nic7448_sub::tab7448[16][7] =
{ {
{ 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */ { 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */
{ 0, 1, 1, 0, 0, 0, 0 }, /* 01 */ { 0, 1, 1, 0, 0, 0, 0 }, /* 01 */
@ -391,40 +425,6 @@ INLINE void nic7474_newstate(const UINT8 state, ttl_output_t &Q, ttl_output_t &Q
QQ.setTo(!state, delay[!state]); QQ.setTo(!state, delay[!state]);
} }
#if 0
NETLIB_UPDATE(nic7474)
{
if (!INPVAL(m_preQ))
nic7474_newstate(1, m_Q, m_QQ);
else if (!INPVAL(m_clrQ))
nic7474_newstate(0, m_Q, m_QQ);
else if (!INP_LAST(m_clk) & INP(m_clk))
{
nic7474_newstate(INPVAL(m_D), m_Q, m_QQ);
m_clk.inactivate();
}
else
m_clk.set_state(INP_STATE_LH);
}
NETLIB_START(nic7474)
{
m_lastclk = 0;
register_input("CLK", m_clk, INP_STATE_LH);
register_input("D", m_D);
register_input("CLRQ", m_clrQ);
register_input("PREQ", m_preQ);
register_output("Q", m_Q);
register_output("QQ", m_QQ);
m_Q.initial(1);
m_QQ.initial(0);
}
#else
NETLIB_UPDATE(nic7474sub) NETLIB_UPDATE(nic7474sub)
{ {
//if (!INP_LAST(m_clk) & INP(m_clk)) //if (!INP_LAST(m_clk) & INP(m_clk))
@ -466,7 +466,6 @@ NETLIB_START(nic7474)
sub.m_Q.initial(1); sub.m_Q.initial(1);
sub.m_QQ.initial(0); sub.m_QQ.initial(0);
} }
#endif
NETLIB_START(nic7483) NETLIB_START(nic7483)
{ {
@ -552,9 +551,9 @@ NETLIB_FUNC_VOID(nic7490, update_outputs)
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(72)); m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
} }
#else #else
NETLIB_FUNC_VOID(nic7490, update_outputs) NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
{ {
static const netlist_time delay[4] = { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54), NLTIME_FROM_NS(72) }; 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++) for (int i=0; i<4; i++)
m_Q[i].setTo((m_cnt >> i) & 1, delay[i]); m_Q[i].setTo((m_cnt >> i) & 1, delay[i]);
@ -713,18 +712,11 @@ NETLIB_START(nic74107A)
INLINE void nic74107A_newstate(UINT8 state, ttl_output_t &Q, ttl_output_t &QQ) INLINE void nic74107A_newstate(UINT8 state, ttl_output_t &Q, ttl_output_t &QQ)
{ {
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
if (state != Q.new_Q()) if (state != Q.new_Q())
{ {
if (state) Q.setToNoCheck(state, delay[1-state]);
{ QQ.setToNoCheck(1-state, delay[state]);
Q.setToNoCheck(1, NLTIME_FROM_NS(40));
QQ.setToNoCheck(0, NLTIME_FROM_NS(25));
}
else
{
Q.setToNoCheck(0, NLTIME_FROM_NS(25));
QQ.setToNoCheck(1, NLTIME_FROM_NS(40));
}
} }
} }
@ -789,15 +781,16 @@ NETLIB_START(nic74153)
NETLIB_UPDATE(nic74153) NETLIB_UPDATE(nic74153)
{ {
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
if (!INPVAL(m_GA)) if (!INPVAL(m_GA))
{ {
UINT8 chan = (INPVAL(m_A) | (INPVAL(m_B)<<1)); UINT8 chan = (INPVAL(m_A) | (INPVAL(m_B)<<1));
UINT8 t = INPVAL(m_I[chan]); UINT8 t = INPVAL(m_I[chan]);
m_AY.setTo(t, t ? NLTIME_FROM_NS(18) : NLTIME_FROM_NS(23)); /* data to y only, FIXME */ m_AY.setTo(t, delay[t] ); /* data to y only, FIXME */
} }
else else
{ {
m_AY.setTo(0, NLTIME_FROM_NS(23)); m_AY.setTo(0, delay[0]);
} }
} }
@ -805,12 +798,15 @@ NETLIB_START(nic9316)
{ {
register_subdevice(sub); register_subdevice(sub);
sub.m_cnt = 0; sub.m_cnt = 0;
sub.m_loadq = 1;
sub.m_ent = 1;
register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_LH); register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_LH);
register_input("ENP", m_ENP); register_input("ENP", m_ENP);
register_input("ENT", sub.m_ENT); register_input("ENT", m_ENT);
register_input("CLRQ", m_CLRQ); register_input("CLRQ", m_CLRQ);
register_input("LOADQ", sub.m_LOADQ, net_input_t::INP_STATE_ACTIVE); register_input("LOADQ", m_LOADQ);
register_input(sub, "A", sub.m_A, net_input_t::INP_STATE_PASSIVE); register_input(sub, "A", sub.m_A, net_input_t::INP_STATE_PASSIVE);
register_input(sub, "B", sub.m_B, net_input_t::INP_STATE_PASSIVE); register_input(sub, "B", sub.m_B, net_input_t::INP_STATE_PASSIVE);
@ -825,85 +821,88 @@ NETLIB_START(nic9316)
} }
NETLIB_UPDATE(nic9316sub) NETLIB_UPDATE(nic9316_sub)
{ {
//if (!INP_LAST(m_clk) & INP(m_clk)) if (m_loadq)
{ {
if (INPVAL(m_LOADQ)) m_cnt = ( m_cnt + 1) & 0x0f;
{ update_outputs();
m_cnt = ( m_cnt + 1) & 0x0f;
update_outputs();
m_RC.setTo(m_cnt == 0x0f, NLTIME_FROM_NS(20));
}
else
{
m_cnt = (INPVAL_PASSIVE(m_D) << 3) | (INPVAL_PASSIVE(m_C) << 2) | (INPVAL_PASSIVE(m_B) << 1) | (INPVAL_PASSIVE(m_A) << 0);
update_outputs_all();
m_RC.setTo(INPVAL(m_ENT) & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
}
} }
else
{
m_cnt = (INPVAL_PASSIVE(m_D) << 3) | (INPVAL_PASSIVE(m_C) << 2) | (INPVAL_PASSIVE(m_B) << 1) | (INPVAL_PASSIVE(m_A) << 0);
update_outputs_all();
}
m_RC.setTo(m_ent & (m_cnt == 0x0f), NLTIME_FROM_NS(20));
} }
NETLIB_UPDATE(nic9316) NETLIB_UPDATE(nic9316)
{ {
if ((!INPVAL(sub.m_LOADQ) | (INPVAL(sub.m_ENT) & INPVAL(m_ENP))) & INPVAL(m_CLRQ)) sub.m_loadq = INPVAL(m_LOADQ);
sub.m_ent = INPVAL(m_ENT);
if ((!sub.m_loadq || (sub.m_ent && INPVAL(m_ENP))) && INPVAL(m_CLRQ))
{
sub.m_clk.activate_lh(); sub.m_clk.activate_lh();
}
else else
{ {
sub.m_clk.inactivate(); sub.m_clk.inactivate();
if (!INPVAL(m_CLRQ) & (sub.m_cnt>0)) if (!INPVAL(m_CLRQ) && (sub.m_cnt>0))
{ {
sub.m_cnt = 0; sub.m_cnt = 0;
sub.update_outputs(); sub.update_outputs();
sub.m_RC.setTo(0, NLTIME_FROM_NS(20)); sub.m_RC.setTo(0, NLTIME_FROM_NS(20));
} }
} }
sub.m_RC.setTo(INPVAL(sub.m_ENT) & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20)); sub.m_RC.setTo(sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
} }
NETLIB_FUNC_VOID(nic9316sub, update_outputs_all) NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
{ {
m_QA.setTo((m_cnt >> 0) & 1, NLTIME_FROM_NS(20)); const netlist_time out_delay = NLTIME_FROM_NS(20);
m_QB.setTo((m_cnt >> 1) & 1, NLTIME_FROM_NS(20)); m_QA.setTo((m_cnt >> 0) & 1, out_delay);
m_QC.setTo((m_cnt >> 2) & 1, NLTIME_FROM_NS(20)); m_QB.setTo((m_cnt >> 1) & 1, out_delay);
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(20)); m_QC.setTo((m_cnt >> 2) & 1, out_delay);
m_QD.setTo((m_cnt >> 3) & 1, out_delay);
} }
NETLIB_FUNC_VOID(nic9316sub, update_outputs) NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
{ {
#if 1 const netlist_time out_delay = NLTIME_FROM_NS(20);
m_QA.setTo((m_cnt >> 0) & 1, NLTIME_FROM_NS(20)); #if 0
m_QB.setTo((m_cnt >> 1) & 1, NLTIME_FROM_NS(20)); m_QA.setTo((m_cnt >> 0) & 1, out_delay);
m_QC.setTo((m_cnt >> 2) & 1, NLTIME_FROM_NS(20)); m_QB.setTo((m_cnt >> 1) & 1, out_delay);
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(20)); m_QC.setTo((m_cnt >> 2) & 1, out_delay);
m_QD.setTo((m_cnt >> 3) & 1, out_delay);
#else #else
if ((m_cnt & 1) == 1) if ((m_cnt & 1) == 1)
m_QA.setToNoCheck(1, NLTIME_FROM_NS(20)); m_QA.setToNoCheck(1, out_delay);
else else
{ {
m_QA.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QA.setToNoCheck(0, out_delay);
switch (m_cnt) switch (m_cnt)
{ {
case 0x00: case 0x00:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QC.setToNoCheck(0, out_delay);
m_QD.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QD.setToNoCheck(0, out_delay);
break; break;
case 0x02: case 0x02:
case 0x06: case 0x06:
case 0x0A: case 0x0A:
case 0x0E: case 0x0E:
m_QB.setToNoCheck(1, NLTIME_FROM_NS(20)); m_QB.setToNoCheck(1, out_delay);
break; break;
case 0x04: case 0x04:
case 0x0C: case 0x0C:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(1, NLTIME_FROM_NS(20)); m_QC.setToNoCheck(1, out_delay);
break; break;
case 0x08: case 0x08:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(0, NLTIME_FROM_NS(20)); m_QC.setToNoCheck(0, out_delay);
m_QD.setToNoCheck(1, NLTIME_FROM_NS(20)); m_QD.setToNoCheck(1, out_delay);
break; break;
} }

View File

@ -316,20 +316,6 @@ NETLIB_DEVICE(nic7450,
ttl_output_t m_Q; ttl_output_t m_Q;
); );
#if 0
NETLIB_DEVICE(nic7474,
ttl_input_t m_clk;
ttl_input_t m_D;
ttl_input_t m_clrQ;
ttl_input_t m_preQ;
net_sig_t m_lastclk;
ttl_output_t m_Q;
ttl_output_t m_QQ;
);
#else
NETLIB_SUBDEVICE(nic7474sub, NETLIB_SUBDEVICE(nic7474sub,
ttl_input_t m_clk; ttl_input_t m_clk;
@ -345,7 +331,6 @@ NETLIB_DEVICE(nic7474,
ttl_input_t m_clrQ; ttl_input_t m_clrQ;
ttl_input_t m_preQ; ttl_input_t m_preQ;
); );
#endif
NETLIB_DEVICE(nic7486, NETLIB_DEVICE(nic7486,
ttl_input_t m_I0; ttl_input_t m_I0;
@ -394,7 +379,6 @@ NETLIB_SUBDEVICE(nic7493ff,
UINT8 m_active; UINT8 m_active;
); );
#if 1
NETLIB_DEVICE(nic7493, NETLIB_DEVICE(nic7493,
ttl_input_t m_R1; ttl_input_t m_R1;
ttl_input_t m_R2; ttl_input_t m_R2;
@ -405,23 +389,6 @@ NETLIB_DEVICE(nic7493,
nic7493ff D; nic7493ff D;
); );
#else
NETLIB_DEVICE(nic7493,
ATTR_HOT void update_outputs();
ttl_input_t m_clk;
ttl_input_t m_R1;
ttl_input_t m_R2;
ttl_output_t m_QA;
ttl_output_t m_QB;
ttl_output_t m_QC;
ttl_output_t m_QD;
UINT8 m_cnt;
);
#endif
NETLIB_DEVICE(nic7490, NETLIB_DEVICE(nic7490,
ATTR_HOT void update_outputs(); ATTR_HOT void update_outputs();
@ -439,20 +406,20 @@ NETLIB_DEVICE(nic7490,
/* ripple-carry counter on low-high clock transition */ /* ripple-carry counter on low-high clock transition */
NETLIB_SUBDEVICE(nic9316sub, NETLIB_SUBDEVICE(nic9316_sub,
ATTR_HOT void update_outputs_all(); ATTR_HOT void update_outputs_all();
ATTR_HOT void update_outputs(); ATTR_HOT void update_outputs();
ttl_input_t m_clk; ttl_input_t m_clk;
ttl_input_t m_LOADQ;
ttl_input_t m_ENT;
ttl_input_t m_A; ttl_input_t m_A;
ttl_input_t m_B; ttl_input_t m_B;
ttl_input_t m_C; ttl_input_t m_C;
ttl_input_t m_D; ttl_input_t m_D;
UINT8 m_cnt; UINT8 m_cnt;
net_sig_t m_loadq;
net_sig_t m_ent;
ttl_output_t m_QA; ttl_output_t m_QA;
ttl_output_t m_QB; ttl_output_t m_QB;
@ -462,9 +429,11 @@ NETLIB_SUBDEVICE(nic9316sub,
); );
NETLIB_DEVICE(nic9316, NETLIB_DEVICE(nic9316,
nic9316sub sub; nic9316_sub sub;
ttl_input_t m_ENP; ttl_input_t m_ENP;
ttl_input_t m_ENT;
ttl_input_t m_CLRQ; ttl_input_t m_CLRQ;
ttl_input_t m_LOADQ;
); );
NETLIB_DEVICE(nic7483, NETLIB_DEVICE(nic7483,
@ -500,16 +469,15 @@ NETLIB_DEVICE(nic74153,
ttl_output_t m_AY; ttl_output_t m_AY;
); );
NETLIB_DEVICE(nic7448, NETLIB_SUBDEVICE(nic7448_sub,
ATTR_HOT void update_outputs(UINT8 v);
static const UINT8 tab7448[16][7]; static const UINT8 tab7448[16][7];
ttl_input_t m_A0; ttl_input_t m_A0;
ttl_input_t m_A1; ttl_input_t m_A1;
ttl_input_t m_A2; ttl_input_t m_A2;
ttl_input_t m_A3; ttl_input_t m_A3;
ttl_input_t m_LTQ;
ttl_input_t m_RBIQ; ttl_input_t m_RBIQ;
ttl_input_t m_BIQ;
UINT8 m_state; UINT8 m_state;
@ -522,6 +490,12 @@ NETLIB_DEVICE(nic7448,
ttl_output_t m_g; ttl_output_t m_g;
); );
NETLIB_DEVICE(nic7448,
nic7448_sub sub;
ttl_input_t m_LTQ;
ttl_input_t m_BIQ;
);
#endif #endif

View File

@ -53,6 +53,7 @@
#define VERBOSE (0) #define VERBOSE (0)
#define KEEP_STATISTICS (0) #define KEEP_STATISTICS (0)
#define FATAL_ERROR_AFTER_NS (0) //(1000)
#if (VERBOSE) #if (VERBOSE)
@ -140,7 +141,7 @@ public:
{ {
char *devname; char *devname;
net_device_t *dev; net_device_t *dev;
char paramfq[30]; char paramfq[300];
double val; double val;
skipws(); skipws();
@ -153,7 +154,7 @@ public:
strcpy(paramfq, devname); strcpy(paramfq, devname);
strcat(paramfq, ".CONST"); strcat(paramfq, ".CONST");
VERBOSE_OUT(("Parser: Const: %s %f\n", devname, val)); VERBOSE_OUT(("Parser: Const: %s %f\n", devname, val));
m_setup.find_param(paramfq).setTo(val); m_setup.find_param(paramfq).initial(val);
} }
void netdev_device(const char *dev_type) void netdev_device(const char *dev_type)
@ -181,6 +182,8 @@ public:
} }
if (cnt != dev->m_inputs.count() && !dev->variable_input_count()) if (cnt != dev->m_inputs.count() && !dev->variable_input_count())
fatalerror("netlist: input count mismatch for %s - expected %d found %d\n", devname, dev->m_inputs.count(), cnt); fatalerror("netlist: input count mismatch for %s - expected %d found %d\n", devname, dev->m_inputs.count(), cnt);
if (dev->variable_input_count())
VERBOSE_OUT(("variable inputs %s: %d\n", dev->name(), cnt));
check_char(')'); check_char(')');
} }
@ -230,7 +233,7 @@ private:
char *getname(char sep) char *getname(char sep)
{ {
static char buf[30]; char buf[300];
char *p1 = buf; char *p1 = buf;
while (*m_p != sep) while (*m_p != sep)
@ -242,7 +245,7 @@ private:
char *getname2(char sep1, char sep2) char *getname2(char sep1, char sep2)
{ {
static char buf[30]; char buf[300];
char *p1 = buf; char *p1 = buf;
while ((*m_p != sep1) && (*m_p != sep2)) while ((*m_p != sep1) && (*m_p != sep2))
@ -380,6 +383,14 @@ void netlist_base_t::set_clock_freq(UINT64 clockfreq)
VERBOSE_OUT(("Setting clock %lld and divisor %d\n", clockfreq, m_div)); VERBOSE_OUT(("Setting clock %lld and divisor %d\n", clockfreq, m_div));
} }
ATTR_HOT ATTR_ALIGN void netlist_base_t::update_time(const netlist_time t, INT32 &atime)
{
const netlist_time delta = t - m_time_ps + netlist_time::from_raw(m_rem);
m_time_ps = t;
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
}
ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime) ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
{ {
if (m_mainclock == NULL) if (m_mainclock == NULL)
@ -387,14 +398,18 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
while ( (atime > 0) && (m_queue.is_not_empty())) while ( (atime > 0) && (m_queue.is_not_empty()))
{ {
queue_t::entry_t &e = m_queue.pop(); queue_t::entry_t &e = m_queue.pop();
const netlist_time delta = e.time() - m_time_ps + netlist_time::from_raw(m_rem); update_time(e.time(), atime);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem); if (FATAL_ERROR_AFTER_NS)
m_time_ps = e.time(); printf("%s\n", e.object()->netdev()->name());
e.object()->update_devs(); e.object()->update_devs();
add_to_stat(m_perf_out_processed, 1); add_to_stat(m_perf_out_processed, 1);
if (FATAL_ERROR_AFTER_NS)
if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS))
fatalerror("Stopped");
} }
if (atime > 0) if (atime > 0)
@ -410,26 +425,25 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
{ {
while (m_queue.peek().time() > mainclock_Q.time()) while (m_queue.peek().time() > mainclock_Q.time())
{ {
const netlist_time delta = mainclock_Q.time() - m_time_ps + netlist_time::from_raw(m_rem); update_time(mainclock_Q.time(), atime);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = mainclock_Q.time();
m_mainclock->update(); m_mainclock->update();
mainclock_Q.update_devs(); mainclock_Q.update_devs();
} }
queue_t::entry_t &e = m_queue.pop(); queue_t::entry_t &e = m_queue.pop();
const netlist_time delta = e.time() - m_time_ps + netlist_time::from_raw(m_rem); update_time(e.time(), atime);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = e.time();
e.object()->update_devs(); e.object()->update_devs();
} else { } else {
const netlist_time delta = mainclock_Q.time() - m_time_ps + netlist_time::from_raw(m_rem); update_time(mainclock_Q.time(), atime);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = mainclock_Q.time();
m_mainclock->update(); m_mainclock->update();
mainclock_Q.update_devs(); mainclock_Q.update_devs();
} }
if (FATAL_ERROR_AFTER_NS)
if (time() > NLTIME_FROM_NS(FATAL_ERROR_AFTER_NS))
fatalerror("Stopped");
add_to_stat(m_perf_out_processed, 1); add_to_stat(m_perf_out_processed, 1);
} }
@ -658,14 +672,40 @@ void netlist_setup_t::resolve_inputs(void)
} }
} }
#if 1
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);
}
//m_netlist.m_queue.clear();
#else
/* make sure all outputs are triggered once */ /* make sure all outputs are triggered once */
for (tagmap_output_t::entry_t *entry = m_outputs.first(); entry != NULL; entry = m_outputs.next(entry)) for (tagmap_output_t::entry_t *entry = m_outputs.first(); entry != NULL; entry = m_outputs.next(entry))
{ {
net_output_t *out = entry->object(); net_output_t *out = entry->object();
out->update_devs_force(); //if (dynamic_cast<const netdev_clock *>(out->netdev()) == NULL )
INT32 time = 1000; {
m_netlist.process_list(time); out->update_devs_force();
INT32 time = 10000;
m_netlist.process_list(time);
}
} }
//m_netlist.m_queue.clear();
#endif
/* print all outputs */
for (tagmap_output_t::entry_t *entry = m_outputs.first(); entry != NULL; entry = m_outputs.next(entry))
{
ATTR_UNUSED net_output_t *out = entry->object();
VERBOSE_OUT(("%s %d\n", out->netdev()->name(), *out->Q_ptr()));
}
} }
void netlist_setup_t::parse(char *buf) void netlist_setup_t::parse(char *buf)
@ -748,7 +788,7 @@ void net_device_t::register_output(const char *name, net_output_t &port)
register_output(*this, name, port); register_output(*this, name, port);
} }
void net_device_t::register_input(net_core_device_t &dev, const char *name, net_input_t &inp, int type) void net_device_t::register_input(net_core_device_t &dev, const char *name, net_input_t &inp, net_input_t::net_input_state type)
{ {
astring temp = dev.name(); astring temp = dev.name();
temp.cat("."); temp.cat(".");
@ -758,7 +798,7 @@ void net_device_t::register_input(net_core_device_t &dev, const char *name, net_
m_setup->register_input(temp, &inp); m_setup->register_input(temp, &inp);
} }
void net_device_t::register_input(const char *name, net_input_t &inp, int type) void net_device_t::register_input(const char *name, net_input_t &inp, net_input_t::net_input_state type)
{ {
register_input(*this, name, inp, type); register_input(*this, name, inp, type);
} }
@ -792,7 +832,7 @@ void net_device_t::register_param(const char *name, net_param_t &param, double i
// net_input_t // net_input_t
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
ATTR_COLD void net_input_t::init(net_core_device_t *dev, int astate) ATTR_COLD void net_input_t::init(net_core_device_t *dev, net_input_state astate)
{ {
m_netdev = dev; m_netdev = dev;
m_state = astate; m_state = astate;
@ -808,12 +848,14 @@ ATTR_COLD void net_input_t::init(net_core_device_t *dev, int astate)
net_output_t::net_output_t(int atype) net_output_t::net_output_t(int atype)
: net_object_t(atype) : net_object_t(atype)
{ {
m_last_Q = 1; m_last_Q = 0;
m_Q = 0; m_Q = 0;
m_new_Q = m_Q; m_new_Q = m_Q;
m_active = 0; m_active = 0;
m_in_queue = 2; m_in_queue = 2;
m_num_cons = 0; m_num_cons = 0;
m_Q_analog = 0.0;
m_new_Q_analog = 0.0;
} }
ATTR_COLD void net_output_t::set_netdev(const net_core_device_t *dev) ATTR_COLD void net_output_t::set_netdev(const net_core_device_t *dev)
@ -822,7 +864,7 @@ ATTR_COLD void net_output_t::set_netdev(const net_core_device_t *dev)
m_netlist = dev->netlist(); m_netlist = dev->netlist();
} }
ATTR_HOT inline void net_output_t::update_dev(const net_input_t &inp, const UINT32 mask) ATTR_HOT 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)
{ {
@ -839,12 +881,12 @@ ATTR_HOT inline void net_output_t::update_dev(const net_input_t &inp, const UINT
ATTR_HOT inline void net_output_t::update_devs() ATTR_HOT inline void net_output_t::update_devs()
{ {
const UINT32 masks[4] = { 1, 5, 3, 1 }; const UINT8 masks[4] = { 1, 5, 3, 1 };
m_Q = m_new_Q; m_Q = m_new_Q;
m_Q_analog = m_new_Q_analog; m_Q_analog = m_new_Q_analog;
//UINT32 mask = 1 | ((m_last_Q & (m_Q ^ 1)) << 1) | (((m_last_Q ^ 1) & m_Q) << 2); //UINT32 mask = 1 | ((m_last_Q & (m_Q ^ 1)) << 1) | (((m_last_Q ^ 1) & m_Q) << 2);
const UINT32 mask = masks[ (m_last_Q << 1) | m_Q ]; const UINT8 mask = masks[ (m_last_Q << 1) | m_Q ];
switch (m_num_cons) switch (m_num_cons)
{ {
@ -885,6 +927,7 @@ ATTR_COLD void net_output_t::update_devs_force()
s++; s++;
} }
m_in_queue = 2; /* mark as taken ... */
m_last_Q = m_Q; m_last_Q = m_Q;
} }

View File

@ -117,7 +117,7 @@ ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &netlist) \
#define NETLIB_UPDATE(_chip) ATTR_HOT ATTR_ALIGN void _chip :: update(void) #define NETLIB_UPDATE(_chip) ATTR_HOT ATTR_ALIGN void _chip :: update(void)
#define NETLIB_START(_chip) ATTR_COLD ATTR_ALIGN void _chip :: start(void) #define NETLIB_START(_chip) ATTR_COLD ATTR_ALIGN void _chip :: start(void)
#define NETLIB_UPDATE_PARAM(_chip) ATTR_HOT ATTR_ALIGN void _chip :: update_param(void) #define NETLIB_UPDATE_PARAM(_chip) ATTR_HOT ATTR_ALIGN void _chip :: update_param(void)
#define NETLIB_FUNC_VOID(_chip, _name) ATTR_HOT ATTR_ALIGN inline void _chip :: _name (void) #define NETLIB_FUNC_VOID(_chip, _name, _params) ATTR_HOT ATTR_ALIGN inline void _chip :: _name _params
#define NETLIB_SIGNAL(_name, _num_input, _check) \ #define NETLIB_SIGNAL(_name, _num_input, _check) \
class _name : public net_signal_t<_num_input, _check> \ class _name : public net_signal_t<_num_input, _check> \
@ -288,12 +288,15 @@ private:
_ListClass *m_list; _ListClass *m_list;
}; };
#define SIZE ((1 << _Size) - 1) //#define SIZE ((1 << _Size) - 1)
template <class _QC, int _Size> template <class _QC, int _Size>
class netlist_timed_queue class netlist_timed_queue
{ {
public: public:
static const int SIZE = ((1 << _Size) - 1);
struct entry_t struct entry_t
{ {
public: public:
@ -306,8 +309,6 @@ public:
_QC m_object; _QC m_object;
}; };
//static const int SIZE = ((1 << _Size) - 1);
netlist_timed_queue() netlist_timed_queue()
{ {
clear(); clear();
@ -425,11 +426,11 @@ public:
}; };
net_input_t(const int atype) : net_object_t(atype), m_state(INP_STATE_ACTIVE) {} net_input_t(const int atype) : net_object_t(atype), m_state(INP_STATE_ACTIVE) {}
ATTR_COLD void init(net_core_device_t *dev,int astate = INP_STATE_ACTIVE); ATTR_COLD void init(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 net_output_t * RESTRICT output() const { return m_output; }
ATTR_HOT inline bool is_state(const net_input_state astate) { return (m_state & astate); } ATTR_HOT inline bool is_state(const net_input_state astate) { return (m_state == astate); }
ATTR_HOT inline UINT32 state() const { return m_state; } ATTR_HOT inline 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 inactivate();
@ -447,7 +448,7 @@ public:
#endif #endif
private: private:
UINT32 m_state; net_input_state m_state;
net_core_device_t * RESTRICT m_netdev; net_core_device_t * RESTRICT m_netdev;
net_output_t * RESTRICT m_output; net_output_t * RESTRICT m_output;
}; };
@ -527,7 +528,7 @@ public:
ATTR_COLD void register_con(net_input_t &inp); ATTR_COLD void register_con(net_input_t &inp);
ATTR_HOT void update_dev(const net_input_t &inp, const UINT32 mask); ATTR_HOT void update_dev(const net_input_t &inp, const UINT8 mask);
ATTR_HOT void update_devs(); ATTR_HOT void update_devs();
ATTR_COLD void update_devs_force(); ATTR_COLD void update_devs_force();
@ -670,9 +671,16 @@ public:
ATTR_HOT inline net_sig_t INPVAL_PASSIVE(logic_input_t &inp) ATTR_HOT inline net_sig_t INPVAL_PASSIVE(logic_input_t &inp)
{ {
net_sig_t ret; net_sig_t ret;
inp.activate(); net_input_t::net_input_state st = inp.state();
ret = inp.Q(); if (st == net_input_t::INP_STATE_PASSIVE)
inp.inactivate(); {
inp.activate();
ret = inp.Q();
inp.inactivate();
}
else
ret = inp.Q();
return ret; return ret;
} }
@ -730,8 +738,8 @@ public:
ATTR_COLD void register_output(const char *name, net_output_t &out); ATTR_COLD void register_output(const char *name, net_output_t &out);
ATTR_COLD void register_output(const net_core_device_t &dev, const char *name, net_output_t &out); ATTR_COLD void register_output(const net_core_device_t &dev, const char *name, net_output_t &out);
ATTR_COLD void register_input(const char *name, net_input_t &in, int state = net_input_t::INP_STATE_ACTIVE); ATTR_COLD void register_input(const char *name, net_input_t &in, net_input_t::net_input_state state = net_input_t::INP_STATE_ACTIVE);
ATTR_COLD void register_input(net_core_device_t &dev, const char *name, net_input_t &in, int state = net_input_t::INP_STATE_ACTIVE); ATTR_COLD void register_input(net_core_device_t &dev, const char *name, net_input_t &in, net_input_t::net_input_state state = net_input_t::INP_STATE_ACTIVE);
ATTR_COLD void register_link_internal(net_input_t &in, net_output_t &out); ATTR_COLD void register_link_internal(net_input_t &in, net_output_t &out);
ATTR_COLD void register_link_internal(net_core_device_t &dev, net_input_t &in, net_output_t &out); ATTR_COLD void register_link_internal(net_core_device_t &dev, net_input_t &in, net_output_t &out);
@ -752,7 +760,7 @@ private:
class net_param_t class net_param_t
{ {
public: public:
net_param_t() { } net_param_t() { m_param = 0.0; }
inline void setTo(const double param) { m_param = param; m_netdev->update_param(); } inline void setTo(const double param) { m_param = param; m_netdev->update_param(); }
inline void setTo(const int param) { m_param = param; m_netdev->update_param(); } inline void setTo(const int param) { m_param = param; m_netdev->update_param(); }
@ -796,29 +804,77 @@ public:
ATTR_HOT inline void update() ATTR_HOT inline void update()
{ {
static netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) }; static const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
for (int i=0; i< _numdev; i++) int pos = -1;
for (int i = 0; i< _numdev; i++)
{ {
m_i[i].activate(); m_i[i].activate();
if (INPVAL(m_i[i]) == _check) if (INPVAL(m_i[i]) == _check)
{ {
m_Q.setTo(!_check, times[_check]);// ? 15000 : 22000); m_Q.setTo(!_check, times[_check]);// ? 15000 : 22000);
for (int j = i + 1; j < _numdev; j++) pos = i;
m_i[j].inactivate(); break;
return;
} }
m_i[i].inactivate();
} }
m_Q.setTo(_check, times[1-_check]);// ? 22000 : 15000); if (pos >= 0)
for (int i = 0; i < _numdev; i++) {
m_i[i].activate(); for (int i = 0; i < _numdev; i++)
if (i != pos)
m_i[i].inactivate();
} else
m_Q.setTo(_check, times[1-_check]);// ? 22000 : 15000);
} }
protected: protected:
ttl_input_t m_i[8]; ttl_input_t m_i[_numdev];
ttl_output_t m_Q; ttl_output_t m_Q;
}; };
#if 0
template <>
class net_signal_t<2, 0> : public net_device_t
{
public:
net_signal_t()
: net_device_t() { }
ATTR_COLD void start()
{
register_output("Q", m_Q);
register_input("I1", m_i[0], net_input_t::INP_STATE_ACTIVE);
register_input("I2", m_i[1], net_input_t::INP_STATE_ACTIVE);
m_Q.initial(1);
}
ATTR_HOT inline void update()
{
static const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
static const UINT8 res_tab[4] = {1, 1, 1, 0 };
static const UINT8 ai1[4] = {0, 1, 0, 0 };
static const UINT8 ai2[4] = {1, 0, 1, 0 };
UINT8 inp = (INPVAL_PASSIVE(m_i[1]) << 1) | INPVAL_PASSIVE(m_i[0]);
UINT8 res = res_tab[inp];
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
if (ai1[inp])
m_i[0].inactivate();
else
m_i[0].activate();
if (ai2[inp])
m_i[1].inactivate();
else
m_i[1].activate();
}
protected:
ttl_input_t m_i[2];
ttl_output_t m_Q;
};
#endif
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// netlist_setup_t // netlist_setup_t
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -888,7 +944,7 @@ class netlist_base_t
{ {
public: public:
typedef netlist_timed_queue<net_output_t *, 9> queue_t; typedef netlist_timed_queue<net_output_t *, 11> queue_t;
netlist_base_t(); netlist_base_t();
virtual ~netlist_base_t(); virtual ~netlist_base_t();
@ -906,12 +962,14 @@ public:
netdev_mainclock *m_mainclock; netdev_mainclock *m_mainclock;
//FIXME:
queue_t m_queue;
protected: protected:
netlist_time m_time_ps; netlist_time m_time_ps;
UINT32 m_rem; UINT32 m_rem;
UINT32 m_div; UINT32 m_div;
queue_t m_queue;
// performance // performance
int m_perf_out_processed; int m_perf_out_processed;
@ -920,6 +978,8 @@ protected:
private: private:
ATTR_HOT void update_time(const netlist_time t, INT32 &atime);
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -1019,22 +1079,28 @@ ATTR_HOT inline void net_input_t::inactivate()
ATTR_HOT inline void net_input_t::activate() ATTR_HOT inline void net_input_t::activate()
{ {
if (m_state == INP_STATE_PASSIVE) if (m_state == INP_STATE_PASSIVE)
{
m_output->inc_active(); m_output->inc_active();
m_state = INP_STATE_ACTIVE; m_state = INP_STATE_ACTIVE;
}
} }
ATTR_HOT inline void net_input_t::activate_hl() ATTR_HOT inline void net_input_t::activate_hl()
{ {
if (m_state == INP_STATE_PASSIVE) if (m_state == INP_STATE_PASSIVE)
{
m_output->inc_active(); m_output->inc_active();
m_state = INP_STATE_HL; m_state = INP_STATE_HL;
}
} }
ATTR_HOT inline void net_input_t::activate_lh() ATTR_HOT inline void net_input_t::activate_lh()
{ {
if (m_state == INP_STATE_PASSIVE) if (m_state == INP_STATE_PASSIVE)
{
m_output->inc_active(); m_output->inc_active();
m_state = INP_STATE_LH; m_state = INP_STATE_LH;
}
} }

View File

@ -71,6 +71,7 @@ static NETLIST_START(pong_schematics)
NETDEV_TTL_CONST(high, 1) NETDEV_TTL_CONST(high, 1)
NETDEV_TTL_CONST(low, 0) NETDEV_TTL_CONST(low, 0)
NETDEV_MAINCLOCK(clk) NETDEV_MAINCLOCK(clk)
//NETDEV_CLOCK(clk)
NETDEV_PARAM(clk.FREQ, 7159000.0) NETDEV_PARAM(clk.FREQ, 7159000.0)
NETDEV_LOGIC_INPUT(SRST) NETDEV_LOGIC_INPUT(SRST)
NETDEV_ANALOG_INPUT(P1) NETDEV_ANALOG_INPUT(P1)
@ -373,6 +374,7 @@ static NETLIST_START(pong_schematics)
TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H) TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H)
NET_ALIAS(scoreFE, ic_e5c.Q) NET_ALIAS(scoreFE, ic_e5c.Q)
//TTL_7400_NAND(ic_c3d, 8H, 4H)
TTL_7400_NAND(ic_c3d, 4H, 8H) TTL_7400_NAND(ic_c3d, 4H, 8H)
TTL_7402_NOR(ic_d2b, ic_e4b.Q, ic_c3d.Q) TTL_7402_NOR(ic_d2b, ic_e4b.Q, ic_c3d.Q)
NET_ALIAS(scoreBC, ic_d2b.Q) NET_ALIAS(scoreBC, ic_d2b.Q)
@ -526,13 +528,11 @@ private:
while (pixels >= m_bitmap->width()) while (pixels >= m_bitmap->width())
{ {
for (int i = m_last_x ; i < m_bitmap->width() - 1; i++) m_bitmap->plot_box(m_last_x, m_last_y, m_bitmap->width() - 1 - m_last_x, 1, col);
m_bitmap->pix(m_last_y, i) = col;
pixels -= m_bitmap->width(); pixels -= m_bitmap->width();
m_last_x = 0; m_last_x = 0;
} }
for (int i = m_last_x ; i < pixels; i++) m_bitmap->plot_box(m_last_x, m_last_y, pixels - m_last_x, 1, col);
m_bitmap->pix(m_last_y, i) = col;
m_last_x = pixels; m_last_x = pixels;
} }
if (m_vid <= 0.34) if (m_vid <= 0.34)