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)
{
register_input("A0", m_A0);
register_input("A1", m_A1);
register_input("A2", m_A2);
register_input("A3", m_A3);
register_subdevice(sub);
//sub.m_state = 0;
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("BIQ", m_BIQ);
register_input("RBIQ",m_RBIQ);
register_input(sub, "RBIQ",sub.m_RBIQ);
register_output("a", m_a);
register_output("b", m_b);
register_output("c", m_c);
register_output("d", m_d);
register_output("e", m_e);
register_output("f", m_f);
register_output("g", m_g);
register_output(sub, "a", sub.m_a);
register_output(sub, "b", sub.m_b);
register_output(sub, "c", sub.m_c);
register_output(sub, "d", sub.m_d);
register_output(sub, "e", sub.m_e);
register_output(sub, "f", sub.m_f);
register_output(sub, "g", sub.m_g);
}
NETLIB_UPDATE(nic7448)
{
UINT8 v;
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);
if (!INPVAL(m_BIQ) || (!INPVAL(m_RBIQ) && (v==0)))
v = 15;
sub.update_outputs(8);
}
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);
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 ! */
{ 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]);
}
#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)
{
//if (!INP_LAST(m_clk) & INP(m_clk))
@ -466,7 +466,6 @@ NETLIB_START(nic7474)
sub.m_Q.initial(1);
sub.m_QQ.initial(0);
}
#endif
NETLIB_START(nic7483)
{
@ -552,9 +551,9 @@ NETLIB_FUNC_VOID(nic7490, update_outputs)
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(72));
}
#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++)
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)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
if (state != Q.new_Q())
{
if (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));
}
Q.setToNoCheck(state, delay[1-state]);
QQ.setToNoCheck(1-state, delay[state]);
}
}
@ -789,15 +781,16 @@ NETLIB_START(nic74153)
NETLIB_UPDATE(nic74153)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
if (!INPVAL(m_GA))
{
UINT8 chan = (INPVAL(m_A) | (INPVAL(m_B)<<1));
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
{
m_AY.setTo(0, NLTIME_FROM_NS(23));
m_AY.setTo(0, delay[0]);
}
}
@ -805,12 +798,15 @@ NETLIB_START(nic9316)
{
register_subdevice(sub);
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("ENP", m_ENP);
register_input("ENT", sub.m_ENT);
register_input("ENT", m_ENT);
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, "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_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));
}
m_cnt = ( m_cnt + 1) & 0x0f;
update_outputs();
}
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)
{
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();
}
else
{
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.update_outputs();
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));
m_QB.setTo((m_cnt >> 1) & 1, NLTIME_FROM_NS(20));
m_QC.setTo((m_cnt >> 2) & 1, NLTIME_FROM_NS(20));
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(20));
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);
}
NETLIB_FUNC_VOID(nic9316sub, update_outputs)
NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
{
#if 1
m_QA.setTo((m_cnt >> 0) & 1, NLTIME_FROM_NS(20));
m_QB.setTo((m_cnt >> 1) & 1, NLTIME_FROM_NS(20));
m_QC.setTo((m_cnt >> 2) & 1, NLTIME_FROM_NS(20));
m_QD.setTo((m_cnt >> 3) & 1, NLTIME_FROM_NS(20));
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);
#else
if ((m_cnt & 1) == 1)
m_QA.setToNoCheck(1, NLTIME_FROM_NS(20));
m_QA.setToNoCheck(1, out_delay);
else
{
m_QA.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QA.setToNoCheck(0, out_delay);
switch (m_cnt)
{
case 0x00:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QC.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QD.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(0, out_delay);
m_QD.setToNoCheck(0, out_delay);
break;
case 0x02:
case 0x06:
case 0x0A:
case 0x0E:
m_QB.setToNoCheck(1, NLTIME_FROM_NS(20));
m_QB.setToNoCheck(1, out_delay);
break;
case 0x04:
case 0x0C:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QC.setToNoCheck(1, NLTIME_FROM_NS(20));
m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(1, out_delay);
break;
case 0x08:
m_QB.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QC.setToNoCheck(0, NLTIME_FROM_NS(20));
m_QD.setToNoCheck(1, NLTIME_FROM_NS(20));
m_QB.setToNoCheck(0, out_delay);
m_QC.setToNoCheck(0, out_delay);
m_QD.setToNoCheck(1, out_delay);
break;
}

View File

@ -316,20 +316,6 @@ NETLIB_DEVICE(nic7450,
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,
ttl_input_t m_clk;
@ -345,7 +331,6 @@ NETLIB_DEVICE(nic7474,
ttl_input_t m_clrQ;
ttl_input_t m_preQ;
);
#endif
NETLIB_DEVICE(nic7486,
ttl_input_t m_I0;
@ -394,7 +379,6 @@ NETLIB_SUBDEVICE(nic7493ff,
UINT8 m_active;
);
#if 1
NETLIB_DEVICE(nic7493,
ttl_input_t m_R1;
ttl_input_t m_R2;
@ -405,23 +389,6 @@ NETLIB_DEVICE(nic7493,
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,
ATTR_HOT void update_outputs();
@ -439,20 +406,20 @@ NETLIB_DEVICE(nic7490,
/* 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();
ttl_input_t m_clk;
ttl_input_t m_LOADQ;
ttl_input_t m_ENT;
ttl_input_t m_A;
ttl_input_t m_B;
ttl_input_t m_C;
ttl_input_t m_D;
UINT8 m_cnt;
net_sig_t m_loadq;
net_sig_t m_ent;
ttl_output_t m_QA;
ttl_output_t m_QB;
@ -462,9 +429,11 @@ NETLIB_SUBDEVICE(nic9316sub,
);
NETLIB_DEVICE(nic9316,
nic9316sub sub;
nic9316_sub sub;
ttl_input_t m_ENP;
ttl_input_t m_ENT;
ttl_input_t m_CLRQ;
ttl_input_t m_LOADQ;
);
NETLIB_DEVICE(nic7483,
@ -500,16 +469,15 @@ NETLIB_DEVICE(nic74153,
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];
ttl_input_t m_A0;
ttl_input_t m_A1;
ttl_input_t m_A2;
ttl_input_t m_A3;
ttl_input_t m_LTQ;
ttl_input_t m_RBIQ;
ttl_input_t m_BIQ;
UINT8 m_state;
@ -522,6 +490,12 @@ NETLIB_DEVICE(nic7448,
ttl_output_t m_g;
);
NETLIB_DEVICE(nic7448,
nic7448_sub sub;
ttl_input_t m_LTQ;
ttl_input_t m_BIQ;
);
#endif

View File

@ -53,6 +53,7 @@
#define VERBOSE (0)
#define KEEP_STATISTICS (0)
#define FATAL_ERROR_AFTER_NS (0) //(1000)
#if (VERBOSE)
@ -140,7 +141,7 @@ public:
{
char *devname;
net_device_t *dev;
char paramfq[30];
char paramfq[300];
double val;
skipws();
@ -153,7 +154,7 @@ public:
strcpy(paramfq, devname);
strcat(paramfq, ".CONST");
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)
@ -181,6 +182,8 @@ public:
}
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);
if (dev->variable_input_count())
VERBOSE_OUT(("variable inputs %s: %d\n", dev->name(), cnt));
check_char(')');
}
@ -230,7 +233,7 @@ private:
char *getname(char sep)
{
static char buf[30];
char buf[300];
char *p1 = buf;
while (*m_p != sep)
@ -242,7 +245,7 @@ private:
char *getname2(char sep1, char sep2)
{
static char buf[30];
char buf[300];
char *p1 = buf;
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));
}
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)
{
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()))
{
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();
if (FATAL_ERROR_AFTER_NS)
printf("%s\n", e.object()->netdev()->name());
e.object()->update_devs();
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)
@ -410,26 +425,25 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
{
while (m_queue.peek().time() > mainclock_Q.time())
{
const netlist_time delta = mainclock_Q.time() - m_time_ps + netlist_time::from_raw(m_rem);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = mainclock_Q.time();
update_time(mainclock_Q.time(), atime);
m_mainclock->update();
mainclock_Q.update_devs();
}
queue_t::entry_t &e = m_queue.pop();
const netlist_time delta = e.time() - m_time_ps + netlist_time::from_raw(m_rem);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = e.time();
update_time(e.time(), atime);
e.object()->update_devs();
} else {
const netlist_time delta = mainclock_Q.time() - m_time_ps + netlist_time::from_raw(m_rem);
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
m_time_ps = mainclock_Q.time();
update_time(mainclock_Q.time(), atime);
m_mainclock->update();
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);
}
@ -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 */
for (tagmap_output_t::entry_t *entry = m_outputs.first(); entry != NULL; entry = m_outputs.next(entry))
{
net_output_t *out = entry->object();
out->update_devs_force();
INT32 time = 1000;
m_netlist.process_list(time);
//if (dynamic_cast<const netdev_clock *>(out->netdev()) == NULL )
{
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)
@ -748,7 +788,7 @@ void net_device_t::register_output(const char *name, net_output_t &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();
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);
}
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);
}
@ -792,7 +832,7 @@ void net_device_t::register_param(const char *name, net_param_t &param, double i
// 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_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_object_t(atype)
{
m_last_Q = 1;
m_last_Q = 0;
m_Q = 0;
m_new_Q = m_Q;
m_active = 0;
m_in_queue = 2;
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)
@ -822,7 +864,7 @@ ATTR_COLD void net_output_t::set_netdev(const net_core_device_t *dev)
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)
{
@ -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()
{
const UINT32 masks[4] = { 1, 5, 3, 1 };
const UINT8 masks[4] = { 1, 5, 3, 1 };
m_Q = m_new_Q;
m_Q_analog = m_new_Q_analog;
//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)
{
@ -885,6 +927,7 @@ ATTR_COLD void net_output_t::update_devs_force()
s++;
}
m_in_queue = 2; /* mark as taken ... */
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_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_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) \
class _name : public net_signal_t<_num_input, _check> \
@ -288,12 +288,15 @@ private:
_ListClass *m_list;
};
#define SIZE ((1 << _Size) - 1)
//#define SIZE ((1 << _Size) - 1)
template <class _QC, int _Size>
class netlist_timed_queue
{
public:
static const int SIZE = ((1 << _Size) - 1);
struct entry_t
{
public:
@ -306,8 +309,6 @@ public:
_QC m_object;
};
//static const int SIZE = ((1 << _Size) - 1);
netlist_timed_queue()
{
clear();
@ -425,11 +426,11 @@ public:
};
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 bool is_state(const net_input_state astate) { return (m_state & astate); }
ATTR_HOT inline UINT32 state() const { return m_state; }
ATTR_HOT inline bool is_state(const net_input_state astate) { return (m_state == astate); }
ATTR_HOT inline net_input_state state() const { return m_state; }
ATTR_COLD void set_output(net_output_t *aout) { m_output = aout; }
ATTR_HOT inline void inactivate();
@ -447,7 +448,7 @@ public:
#endif
private:
UINT32 m_state;
net_input_state m_state;
net_core_device_t * RESTRICT m_netdev;
net_output_t * RESTRICT m_output;
};
@ -527,7 +528,7 @@ public:
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_COLD void update_devs_force();
@ -670,9 +671,16 @@ public:
ATTR_HOT inline net_sig_t INPVAL_PASSIVE(logic_input_t &inp)
{
net_sig_t ret;
inp.activate();
ret = inp.Q();
inp.inactivate();
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;
}
@ -730,8 +738,8 @@ public:
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_input(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, 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, 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_core_device_t &dev, net_input_t &in, net_output_t &out);
@ -752,7 +760,7 @@ private:
class net_param_t
{
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 int param) { m_param = param; m_netdev->update_param(); }
@ -796,29 +804,77 @@ public:
ATTR_HOT inline void update()
{
static netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
for (int i=0; i< _numdev; i++)
static const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
int pos = -1;
for (int i = 0; i< _numdev; i++)
{
m_i[i].activate();
if (INPVAL(m_i[i]) == _check)
{
m_Q.setTo(!_check, times[_check]);// ? 15000 : 22000);
for (int j = i + 1; j < _numdev; j++)
m_i[j].inactivate();
return;
pos = i;
break;
}
m_i[i].inactivate();
}
m_Q.setTo(_check, times[1-_check]);// ? 22000 : 15000);
for (int i = 0; i < _numdev; i++)
m_i[i].activate();
if (pos >= 0)
{
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:
ttl_input_t m_i[8];
ttl_input_t m_i[_numdev];
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
// ----------------------------------------------------------------------------------------
@ -888,7 +944,7 @@ class netlist_base_t
{
public:
typedef netlist_timed_queue<net_output_t *, 9> queue_t;
typedef netlist_timed_queue<net_output_t *, 11> queue_t;
netlist_base_t();
virtual ~netlist_base_t();
@ -906,12 +962,14 @@ public:
netdev_mainclock *m_mainclock;
//FIXME:
queue_t m_queue;
protected:
netlist_time m_time_ps;
UINT32 m_rem;
UINT32 m_div;
queue_t m_queue;
// performance
int m_perf_out_processed;
@ -920,6 +978,8 @@ protected:
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()
{
if (m_state == INP_STATE_PASSIVE)
{
m_output->inc_active();
m_state = INP_STATE_ACTIVE;
m_state = INP_STATE_ACTIVE;
}
}
ATTR_HOT inline void net_input_t::activate_hl()
{
if (m_state == INP_STATE_PASSIVE)
{
m_output->inc_active();
m_state = INP_STATE_HL;
m_state = INP_STATE_HL;
}
}
ATTR_HOT inline void net_input_t::activate_lh()
{
if (m_state == INP_STATE_PASSIVE)
{
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(low, 0)
NETDEV_MAINCLOCK(clk)
//NETDEV_CLOCK(clk)
NETDEV_PARAM(clk.FREQ, 7159000.0)
NETDEV_LOGIC_INPUT(SRST)
NETDEV_ANALOG_INPUT(P1)
@ -373,6 +374,7 @@ static NETLIST_START(pong_schematics)
TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H)
NET_ALIAS(scoreFE, ic_e5c.Q)
//TTL_7400_NAND(ic_c3d, 8H, 4H)
TTL_7400_NAND(ic_c3d, 4H, 8H)
TTL_7402_NOR(ic_d2b, ic_e4b.Q, ic_c3d.Q)
NET_ALIAS(scoreBC, ic_d2b.Q)
@ -526,13 +528,11 @@ private:
while (pixels >= m_bitmap->width())
{
for (int i = m_last_x ; i < m_bitmap->width() - 1; i++)
m_bitmap->pix(m_last_y, i) = col;
m_bitmap->plot_box(m_last_x, m_last_y, m_bitmap->width() - 1 - m_last_x, 1, col);
pixels -= m_bitmap->width();
m_last_x = 0;
}
for (int i = m_last_x ; i < pixels; i++)
m_bitmap->pix(m_last_y, i) = col;
m_bitmap->plot_box(m_last_x, m_last_y, pixels - m_last_x, 1, col);
m_last_x = pixels;
}
if (m_vid <= 0.34)