Slightly improved performance on netlist components.
This commit is contained in:
parent
2ef28b9430
commit
d91cdfc26e
@ -65,6 +65,16 @@ NETLIB_UPDATE(netdev_analog_input)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(netdev_log)
|
||||
{
|
||||
register_input("I", m_I);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(netdev_log)
|
||||
{
|
||||
printf("%s: %d %d\n", name(), (UINT32) (netlist().time().as_raw() / 1000000), INPVAL(m_I));
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(netdev_clock)
|
||||
{
|
||||
register_output("Q", m_Q);
|
||||
@ -110,7 +120,7 @@ NETLIB_CONSTRUCTOR(nicMultiSwitch)
|
||||
NETLIB_UPDATE(nicMultiSwitch)
|
||||
{
|
||||
assert(m_position<8);
|
||||
m_Q.setToPS(INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
|
||||
m_Q.setTo(INPANALOG(m_I[m_position]), NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(nicMultiSwitch)
|
||||
@ -147,7 +157,7 @@ NETLIB_UPDATE(nicMixer8)
|
||||
{
|
||||
r += m_w[i] * INPANALOG(m_I[i]);
|
||||
}
|
||||
m_Q.setToPS(r, NLTIME_IMMEDIATE);
|
||||
m_Q.setTo(r, NLTIME_IMMEDIATE);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(nicMixer8)
|
||||
@ -263,12 +273,12 @@ NETLIB_UPDATE(nicNE555N_MSTABLE)
|
||||
}
|
||||
|
||||
m_Q.setToNoCheckPS(m_VS.Value() * 0.7, NLTIME_FROM_NS(100));
|
||||
m_THRESHOLD_OUT.setToPS(m_VS.Value(), NLTIME_FROM_US(time ));
|
||||
m_THRESHOLD_OUT.setTo(m_VS.Value(), NLTIME_FROM_US(time ));
|
||||
}
|
||||
else if (m_last && !out)
|
||||
{
|
||||
m_Q.setToNoCheckPS(0.25, NLTIME_FROM_NS(100));
|
||||
m_THRESHOLD_OUT.setToPS(0.0, NLTIME_FROM_NS(1));
|
||||
m_THRESHOLD_OUT.setTo(0.0, NLTIME_FROM_NS(1));
|
||||
}
|
||||
m_last = out;
|
||||
}
|
||||
@ -302,9 +312,8 @@ NETLIB_UPDATE(nic7486)
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic7448)
|
||||
, sub(setup, "sub")
|
||||
{
|
||||
register_subdevice(sub);
|
||||
|
||||
sub.m_state = 0;
|
||||
|
||||
register_input(sub, "A0", sub.m_A0);
|
||||
@ -419,7 +428,7 @@ NETLIB_UPDATE(nic7450)
|
||||
|
||||
INLINE void nic7474_newstate(const UINT8 state, ttl_output_t &Q, ttl_output_t &QQ)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) };
|
||||
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]);
|
||||
@ -452,8 +461,8 @@ NETLIB_UPDATE(nic7474)
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic7474)
|
||||
, sub(setup, "sub")
|
||||
{
|
||||
register_subdevice(sub);
|
||||
|
||||
register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_LH);
|
||||
register_input("D", m_D);
|
||||
@ -563,14 +572,13 @@ NETLIB_FUNC_VOID(nic7490, update_outputs, (void))
|
||||
//m_QD.setToPS((m_cnt >> 3) & 1, delay[3]);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
#if !USE_OLD7493
|
||||
NETLIB_CONSTRUCTOR(nic7493)
|
||||
, A(setup, "A")
|
||||
, B(setup, "B")
|
||||
, C(setup, "C")
|
||||
, D(setup, "D")
|
||||
{
|
||||
register_subdevice(A);
|
||||
register_subdevice(B);
|
||||
register_subdevice(C);
|
||||
register_subdevice(D);
|
||||
|
||||
register_input(A, "CLKA", A.m_I, net_input_t::INP_STATE_HL);
|
||||
register_input(B, "CLKB", B.m_I, net_input_t::INP_STATE_HL);
|
||||
register_input("R1", m_R1);
|
||||
@ -624,7 +632,8 @@ NETLIB_CONSTRUCTOR(nic7493)
|
||||
{
|
||||
m_cnt = 0;
|
||||
|
||||
register_input("CLK", m_clk, net_input_t::INP_STATE_HL);
|
||||
register_input("CLKA", m_CLK, net_input_t::INP_STATE_HL);
|
||||
register_input("CLKB", m_CLKB, net_input_t::INP_STATE_HL);
|
||||
register_input("R1", m_R1);
|
||||
register_input("R2", m_R2);
|
||||
|
||||
@ -645,50 +654,54 @@ NETLIB_UPDATE(nic7493)
|
||||
if (m_cnt > 0)
|
||||
{
|
||||
m_cnt = 0;
|
||||
m_QA.setTo(0, 40000);
|
||||
m_QB.setTo(0, 40000);
|
||||
m_QC.setTo(0, 40000);
|
||||
m_QD.setTo(0, 40000);
|
||||
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));
|
||||
}
|
||||
//m_CLK.inactivate();
|
||||
}
|
||||
//else if (old_clk & !m_lastclk)
|
||||
else if (INPVAL_LAST(m_clk) & !INPVAL(m_clk))
|
||||
{
|
||||
m_cnt++;
|
||||
m_cnt &= 0x0f;
|
||||
update_outputs();
|
||||
else {
|
||||
//m_CLK.activate_hl();
|
||||
if (INPVAL_LAST(m_CLK) & !INPVAL(m_CLK))
|
||||
{
|
||||
m_cnt++;
|
||||
m_cnt &= 0x0f;
|
||||
update_outputs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_FUNC_VOID(nic7493, update_outputs)
|
||||
NETLIB_FUNC_VOID(nic7493, update_outputs, (void))
|
||||
{
|
||||
if (m_cnt & 1)
|
||||
m_QA.setToNoCheck(1, 16000);
|
||||
m_QA.setToNoCheck(1, NLTIME_FROM_NS(16));
|
||||
else
|
||||
{
|
||||
m_QA.setToNoCheck(0, 16000);
|
||||
m_QA.setToNoCheck(0, NLTIME_FROM_NS(16));
|
||||
switch (m_cnt)
|
||||
{
|
||||
case 0x00:
|
||||
m_QB.setToNoCheck(0, 34000);
|
||||
m_QC.setToNoCheck(0, 48000);
|
||||
m_QD.setToNoCheck(0, 70000);
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
m_QC.setToNoCheck(0, NLTIME_FROM_NS(48));
|
||||
m_QD.setToNoCheck(0, NLTIME_FROM_NS(70));
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x06:
|
||||
case 0x0A:
|
||||
case 0x0E:
|
||||
m_QB.setToNoCheck(1, 34000);
|
||||
m_QB.setToNoCheck(1, NLTIME_FROM_NS(34));
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x0C:
|
||||
m_QB.setToNoCheck(0, 34000);
|
||||
m_QC.setToNoCheck(1, 48000);
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
m_QC.setToNoCheck(1, NLTIME_FROM_NS(48));
|
||||
break;
|
||||
case 0x08:
|
||||
m_QB.setToNoCheck(0, 34000);
|
||||
m_QC.setToNoCheck(0, 48000);
|
||||
m_QD.setToNoCheck(1, 70000);
|
||||
m_QB.setToNoCheck(0, NLTIME_FROM_NS(34));
|
||||
m_QC.setToNoCheck(0, NLTIME_FROM_NS(48));
|
||||
m_QD.setToNoCheck(1, NLTIME_FROM_NS(70));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -696,9 +709,8 @@ NETLIB_FUNC_VOID(nic7493, update_outputs)
|
||||
#endif
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic74107A)
|
||||
, sub(setup, "sub")
|
||||
{
|
||||
register_subdevice(sub);
|
||||
|
||||
register_input(sub, "CLK", sub.m_clk, net_input_t::INP_STATE_HL);
|
||||
register_input("J", m_J);
|
||||
register_input("K", m_K);
|
||||
@ -713,16 +725,20 @@ NETLIB_CONSTRUCTOR(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 1
|
||||
Q.setTo(state, delay[1-state]);
|
||||
QQ.setTo(1-state, delay[state]);
|
||||
#else
|
||||
if (state != Q.new_Q())
|
||||
{
|
||||
Q.setToNoCheck(state, delay[1-state]);
|
||||
QQ.setToNoCheck(1-state, delay[state]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(nic74107Asub)
|
||||
{
|
||||
//if (INPVAL_LAST(m_clk) & !INPVAL(m_clk))
|
||||
{
|
||||
nic74107A_newstate((!m_Q.new_Q() & m_Q1) | (m_Q.new_Q() & m_Q2) | m_F, m_Q, m_QQ);
|
||||
if (!m_Q1)
|
||||
@ -795,8 +811,8 @@ NETLIB_UPDATE(nic74153)
|
||||
}
|
||||
|
||||
NETLIB_CONSTRUCTOR(nic9316)
|
||||
, sub(setup, "sub")
|
||||
{
|
||||
register_subdevice(sub);
|
||||
sub.m_cnt = 0;
|
||||
sub.m_loadq = 1;
|
||||
sub.m_ent = 1;
|
||||
@ -841,18 +857,19 @@ NETLIB_UPDATE(nic9316)
|
||||
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))
|
||||
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));
|
||||
return;
|
||||
}
|
||||
}
|
||||
sub.m_RC.setTo(sub.m_ent & (sub.m_cnt == 0x0f), NLTIME_FROM_NS(20));
|
||||
@ -870,7 +887,7 @@ NETLIB_FUNC_VOID(nic9316_sub, update_outputs_all, (void))
|
||||
NETLIB_FUNC_VOID(nic9316_sub, update_outputs, (void))
|
||||
{
|
||||
const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||
#if 0
|
||||
#if 1
|
||||
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);
|
||||
@ -918,6 +935,7 @@ static const net_device_t_base_factory *netregistry[] =
|
||||
ENTRY(netdev_analog_const, NETDEV_ANALOG_CONST)
|
||||
ENTRY(netdev_logic_input, NETDEV_LOGIC_INPUT)
|
||||
ENTRY(netdev_analog_input, NETDEV_ANALOG_INPUT)
|
||||
ENTRY(netdev_log, NETDEV_LOG)
|
||||
ENTRY(netdev_clock, NETDEV_CLOCK)
|
||||
ENTRY(netdev_mainclock, NETDEV_MAINCLOCK)
|
||||
ENTRY(netdev_callback, NETDEV_CALLBACK)
|
||||
@ -957,6 +975,7 @@ net_device_t *net_create_device_by_classname(const char *classname, netlist_setu
|
||||
p++;
|
||||
}
|
||||
fatalerror("Class %s required for IC %s not found!\n", classname, icname);
|
||||
return NULL; // appease code analysis
|
||||
}
|
||||
|
||||
net_device_t *net_create_device_by_name(const char *name, netlist_setup_t &setup, const char *icname)
|
||||
@ -969,4 +988,5 @@ net_device_t *net_create_device_by_name(const char *name, netlist_setup_t &setup
|
||||
p++;
|
||||
}
|
||||
fatalerror("Class %s required for IC %s not found!\n", name, icname);
|
||||
return NULL; // appease code analysis
|
||||
}
|
||||
|
@ -50,11 +50,15 @@
|
||||
|
||||
#include "netlist.h"
|
||||
|
||||
// this is a bad hack
|
||||
|
||||
#define USE_OLD7493 (1)
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Special chips
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#define NETDEV_MAINCLOCK(_name) \
|
||||
#define NETDEV_MAINCLOCK(_name) \
|
||||
NET_REGISTER_DEV(netdev_mainclock, _name)
|
||||
#define NETDEV_CLOCK(_name) \
|
||||
NET_REGISTER_DEV(netdev_clock, _name)
|
||||
@ -78,6 +82,11 @@
|
||||
NET_CONNECT(_name, S, _S) \
|
||||
NET_CONNECT(_name, R, _R)
|
||||
|
||||
#define NETDEV_LOG(_name, _I) \
|
||||
NET_REGISTER_DEV(netdev_log, _name) \
|
||||
NET_CONNECT(_name, I, _I)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// TTL Logic chips
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -213,6 +222,7 @@
|
||||
NET_CONNECT(_name, I1, _I1) \
|
||||
NET_CONNECT(_name, I2, _I2) \
|
||||
NET_CONNECT(_name, I3, _I3)
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Special support devices ...
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -225,7 +235,9 @@ NETLIB_DEVICE(netdev_analog_input,
|
||||
analog_output_t m_Q;
|
||||
);
|
||||
|
||||
|
||||
NETLIB_DEVICE(netdev_log,
|
||||
ttl_input_t m_I;
|
||||
);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -295,13 +307,13 @@ NETLIB_DEVICE_WITH_PARAMS(nicNE555N_MSTABLE,
|
||||
net_param_t m_VL;
|
||||
);
|
||||
|
||||
NETLIB_SIGNAL(nic7400, 2, 0)
|
||||
NETLIB_SIGNAL(nic7402, 2, 1)
|
||||
NETLIB_SIGNAL(nic7410, 3, 0)
|
||||
NETLIB_SIGNAL(nic7420, 4, 0)
|
||||
NETLIB_SIGNAL(nic7425, 4, 1)
|
||||
NETLIB_SIGNAL(nic7427, 3, 1)
|
||||
NETLIB_SIGNAL(nic7430, 8, 0)
|
||||
NETLIB_SIGNAL(nic7400, 2, 0, 0)
|
||||
NETLIB_SIGNAL(nic7402, 2, 1, 0)
|
||||
NETLIB_SIGNAL(nic7410, 3, 0, 0)
|
||||
NETLIB_SIGNAL(nic7420, 4, 0, 0)
|
||||
NETLIB_SIGNAL(nic7425, 4, 1, 0)
|
||||
NETLIB_SIGNAL(nic7427, 3, 1, 0)
|
||||
NETLIB_SIGNAL(nic7430, 8, 0, 0)
|
||||
|
||||
NETLIB_DEVICE(nic7404,
|
||||
ttl_input_t m_I;
|
||||
@ -379,14 +391,28 @@ NETLIB_SUBDEVICE(nic7493ff,
|
||||
);
|
||||
|
||||
NETLIB_DEVICE(nic7493,
|
||||
ttl_input_t m_R1;
|
||||
ttl_input_t m_R2;
|
||||
#if !USE_OLD7493
|
||||
ttl_input_t m_R1;
|
||||
ttl_input_t m_R2;
|
||||
|
||||
nic7493ff A;
|
||||
nic7493ff B;
|
||||
nic7493ff C;
|
||||
nic7493ff D;
|
||||
#else
|
||||
ttl_input_t m_CLK;
|
||||
ttl_input_t m_CLKB; /* dummy ! */
|
||||
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;
|
||||
ATTR_HOT void update_outputs();
|
||||
#endif
|
||||
);
|
||||
|
||||
NETLIB_DEVICE(nic7490,
|
||||
|
@ -51,7 +51,7 @@
|
||||
// DEBUGGING
|
||||
//============================================================
|
||||
|
||||
#define VERBOSE (1)
|
||||
#define VERBOSE (0)
|
||||
#define KEEP_STATISTICS (0)
|
||||
#define FATAL_ERROR_AFTER_NS (0) //(1000)
|
||||
|
||||
@ -292,7 +292,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_a_to_d
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -362,6 +361,17 @@ NETLIB_UPDATE_PARAM(netdev_analog_const)
|
||||
m_Q.initial(m_const.Value());
|
||||
}
|
||||
|
||||
inline NETLIB_UPDATE_PARAM(netdev_mainclock)
|
||||
{
|
||||
m_inc = netlist_time::from_hz(m_freq.Value()*2);
|
||||
}
|
||||
|
||||
inline NETLIB_UPDATE(netdev_mainclock)
|
||||
{
|
||||
*m_Q.new_Q_ptr() = !m_Q.new_Q();
|
||||
m_Q.set_time(m_netlist.time() + m_inc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_base_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -371,7 +381,7 @@ netlist_base_t::netlist_base_t()
|
||||
: m_mainclock(NULL),
|
||||
m_time_ps(NLTIME_FROM_MS(0)),
|
||||
m_rem(0),
|
||||
m_div(1024)
|
||||
m_div(NETLIST_DIV)
|
||||
{
|
||||
}
|
||||
|
||||
@ -382,15 +392,28 @@ netlist_base_t::~netlist_base_t()
|
||||
void netlist_base_t::set_clock_freq(UINT64 clockfreq)
|
||||
{
|
||||
m_div = netlist_time::from_hz(clockfreq).as_raw();
|
||||
m_rem = 0;
|
||||
assert_always(m_div == NETLIST_DIV, "netlist: illegal clock!");
|
||||
VERBOSE_OUT(("Setting clock %" I64FMT "d and divisor %d\n", clockfreq, m_div));
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_base_t::update_time(const netlist_time t, INT32 &atime)
|
||||
ATTR_HOT ATTR_ALIGN inline 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);
|
||||
if (NETLIST_DIV_BITS == 0)
|
||||
{
|
||||
const netlist_time delta = t - m_time_ps;
|
||||
|
||||
m_time_ps = t;
|
||||
atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
|
||||
m_time_ps = t;
|
||||
atime -= (delta.as_raw() >> NETLIST_DIV_BITS);
|
||||
} else {
|
||||
const netlist_time delta = t - m_time_ps + netlist_time::from_raw(m_rem);
|
||||
m_time_ps = t;
|
||||
m_rem = delta.as_raw() & NETLIST_MASK;
|
||||
atime -= (delta.as_raw() >> NETLIST_DIV_BITS);
|
||||
|
||||
// The folling is suitable for non-power of 2 m_divs ...
|
||||
// atime -= divu_64x32_rem(delta.as_raw(), m_div, &m_rem);
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_base_t::process_list(INT32 &atime)
|
||||
@ -543,17 +566,26 @@ void netlist_setup_t::register_alias(const char *alias, const char *out)
|
||||
fatalerror("Error adding alias %s to alias list\n", alias);
|
||||
}
|
||||
|
||||
void netlist_setup_t::register_output(const char *name, net_output_t *out)
|
||||
void netlist_setup_t::register_output(net_core_device_t &dev, net_core_device_t &upd_dev, const char *name, net_output_t &out)
|
||||
{
|
||||
VERBOSE_OUT(("out %s\n", name));
|
||||
if (!(m_outputs.add(name, out, false)==TMERR_NONE))
|
||||
astring temp = dev.name();
|
||||
temp.cat(".");
|
||||
temp.cat(name);
|
||||
out.set_netdev(&upd_dev);
|
||||
if (!(m_outputs.add(temp, &out, false)==TMERR_NONE))
|
||||
fatalerror("Error adding output %s to output list\n", name);
|
||||
}
|
||||
|
||||
void netlist_setup_t::register_input(const char *name, net_input_t *inp)
|
||||
void netlist_setup_t::register_input(net_device_t &dev, net_core_device_t &upd_dev, const char *name, net_input_t &inp, net_input_t::net_input_state type)
|
||||
{
|
||||
VERBOSE_OUT(("input %s\n", name));
|
||||
if (!(m_inputs.add(name, inp, false) == TMERR_NONE))
|
||||
astring temp = dev.name();
|
||||
temp.cat(".");
|
||||
temp.cat(name);
|
||||
inp.init(&upd_dev, type);
|
||||
dev.m_inputs.add(core_strdup(temp.cstr()));
|
||||
if (!(m_inputs.add(temp, &inp, false) == TMERR_NONE))
|
||||
fatalerror("Error adding input %s to input list\n", name);
|
||||
}
|
||||
|
||||
@ -733,8 +765,10 @@ void netlist_setup_t::print_stats()
|
||||
// net_core_device_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
net_core_device_t::net_core_device_t()
|
||||
net_core_device_t::net_core_device_t(netlist_setup_t &setup, const char *name)
|
||||
: net_object_t(DEVICE)
|
||||
, m_netlist(setup.netlist())
|
||||
, m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -742,60 +776,35 @@ net_core_device_t::~net_core_device_t()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ATTR_COLD void net_core_device_t::init_core(netlist_base_t *anetlist, const char *name)
|
||||
{
|
||||
m_netlist = anetlist;
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
|
||||
ATTR_COLD void net_core_device_t::register_subdevice(net_core_device_t &subdev)
|
||||
{
|
||||
m_subdevs.add(&subdev);
|
||||
subdev.init_core(m_netlist, this->name());
|
||||
//subdev.start();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// net_device_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
net_device_t::net_device_t(netlist_setup_t &setup, const char *name)
|
||||
: net_core_device_t(),
|
||||
: net_core_device_t(setup, name),
|
||||
m_setup(setup),
|
||||
m_variable_input_count(false)
|
||||
{
|
||||
init_core(&setup.netlist(), name);
|
||||
}
|
||||
|
||||
net_device_t::~net_device_t()
|
||||
{
|
||||
}
|
||||
|
||||
void net_device_t::register_output(const net_core_device_t &dev, const char *name, net_output_t &port)
|
||||
void net_device_t::register_output(net_core_device_t &dev, const char *name, net_output_t &port)
|
||||
{
|
||||
astring temp = dev.name();
|
||||
temp.cat(".");
|
||||
temp.cat(name);
|
||||
port.set_netdev(&dev);
|
||||
m_setup.register_output(temp, &port);
|
||||
m_setup.register_output(*this, dev, name, port);
|
||||
}
|
||||
|
||||
void net_device_t::register_output(const char *name, net_output_t &port)
|
||||
{
|
||||
register_output(*this, name, port);
|
||||
m_setup.register_output(*this,*this,name, port);
|
||||
}
|
||||
|
||||
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(".");
|
||||
temp.cat(name);
|
||||
inp.init(&dev, type);
|
||||
m_inputs.add(core_strdup(temp.cstr()));
|
||||
m_setup.register_input(temp, &inp);
|
||||
m_setup.register_input(*this, dev, name, inp, type);
|
||||
}
|
||||
|
||||
void net_device_t::register_input(const char *name, net_input_t &inp, net_input_t::net_input_state type)
|
||||
@ -858,10 +867,10 @@ net_output_t::net_output_t(int atype)
|
||||
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(net_core_device_t *dev)
|
||||
{
|
||||
m_netdev = dev;
|
||||
m_netlist = dev->netlist();
|
||||
m_netlist = &dev->netlist();
|
||||
}
|
||||
|
||||
ATTR_HOT inline void net_output_t::update_dev(const net_input_t &inp, const UINT8 mask)
|
||||
@ -881,6 +890,7 @@ 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 UINT8 masks[4] = { 1, 5, 3, 1 };
|
||||
m_Q = m_new_Q;
|
||||
m_Q_analog = m_new_Q_analog;
|
||||
@ -901,8 +911,6 @@ ATTR_HOT inline void net_output_t::update_devs()
|
||||
update_dev(*m_cons[i], mask);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
m_in_queue = 2; /* mark as taken ... */
|
||||
|
@ -57,7 +57,17 @@
|
||||
|
||||
#define USE_DELEGATES (1)
|
||||
|
||||
#define NETLIST_CLOCK (U64(1000000000))
|
||||
// Next if enabled adds 20% performance ... but is not guaranteed to be absolutely timing correct.
|
||||
#define USE_DEACTIVE_DEVICE (0)
|
||||
|
||||
// Use nano-second resolution - Sufficient for now
|
||||
//#define NETLIST_INTERNAL_RES (U64(1000000000))
|
||||
//#define NETLIST_DIV_BITS (0)
|
||||
#define NETLIST_INTERNAL_RES (U64(1000000000000))
|
||||
#define NETLIST_DIV_BITS (12)
|
||||
#define NETLIST_DIV (U64(1) << NETLIST_DIV_BITS)
|
||||
#define NETLIST_MASK (NETLIST_DIV-1)
|
||||
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES / NETLIST_DIV)
|
||||
|
||||
#define NLTIME_FROM_NS(_t) netlist_time::from_ns(_t)
|
||||
#define NLTIME_FROM_US(_t) netlist_time::from_us(_t)
|
||||
@ -122,12 +132,12 @@ ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &netlist) \
|
||||
#define NETLIB_UPDATE_PARAM(_chip) ATTR_HOT ATTR_ALIGN void _chip :: update_param(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> \
|
||||
#define NETLIB_SIGNAL(_name, _num_input, _check, _invert) \
|
||||
class _name : public net_signal_t<_num_input, _check, _invert> \
|
||||
{ \
|
||||
public: \
|
||||
_name (netlist_setup_t &setup, const char *name) \
|
||||
: net_signal_t<_num_input, _check>(setup, name) { } \
|
||||
_name (netlist_setup_t &setup, const char *name) \
|
||||
: net_signal_t<_num_input, _check, _invert>(setup, name) { } \
|
||||
};
|
||||
|
||||
#define NETLIB_DEVICE(_name, _priv) \
|
||||
@ -144,7 +154,9 @@ ATTR_COLD void NETLIST_NAME(_name)(netlist_setup_t &netlist) \
|
||||
class _name : public net_core_device_t \
|
||||
{ \
|
||||
public: \
|
||||
_name () : net_core_device_t() { } \
|
||||
_name (netlist_setup_t &setup, const char *name) \
|
||||
: net_core_device_t(setup, name) \
|
||||
{ } \
|
||||
ATTR_HOT void update(); \
|
||||
/*protected:*/ \
|
||||
_priv \
|
||||
@ -194,26 +206,26 @@ public:
|
||||
|
||||
typedef UINT64 INTERNALTYPE;
|
||||
|
||||
static const INTERNALTYPE RESOLUTION = U64(1024000000000);
|
||||
static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
|
||||
|
||||
inline netlist_time() : m_time(0) {}
|
||||
|
||||
friend netlist_time operator-(const netlist_time &left, const netlist_time &right);
|
||||
friend netlist_time operator+(const netlist_time &left, const netlist_time &right);
|
||||
friend netlist_time operator*(const netlist_time &left, const UINT64 factor);
|
||||
friend bool operator>(const netlist_time &left, const netlist_time &right);
|
||||
friend bool operator<(const netlist_time &left, const netlist_time &right);
|
||||
friend bool operator>=(const netlist_time &left, const netlist_time &right);
|
||||
friend bool operator<=(const netlist_time &left, const netlist_time &right);
|
||||
friend inline netlist_time operator-(const netlist_time &left, const netlist_time &right);
|
||||
friend inline netlist_time operator+(const netlist_time &left, const netlist_time &right);
|
||||
friend inline netlist_time operator*(const netlist_time &left, const UINT64 factor);
|
||||
friend inline bool operator>(const netlist_time &left, const netlist_time &right);
|
||||
friend inline bool operator<(const netlist_time &left, const netlist_time &right);
|
||||
friend inline bool operator>=(const netlist_time &left, const netlist_time &right);
|
||||
friend inline bool operator<=(const netlist_time &left, const netlist_time &right);
|
||||
|
||||
ATTR_HOT inline netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
|
||||
ATTR_HOT inline netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
|
||||
|
||||
ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; }
|
||||
|
||||
ATTR_HOT static inline const netlist_time from_ns(const int ns) { return netlist_time((UINT64) ns * RESOLUTION / U64(1000000000)); }
|
||||
ATTR_HOT static inline const netlist_time from_us(const int us) { return netlist_time((UINT64) us * RESOLUTION / U64(1000000)); }
|
||||
ATTR_HOT static inline const netlist_time from_ms(const int ms) { return netlist_time((UINT64) ms * RESOLUTION / U64(1000)); }
|
||||
ATTR_HOT static inline const netlist_time from_ns(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); }
|
||||
ATTR_HOT static inline const netlist_time from_us(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); }
|
||||
ATTR_HOT static inline const netlist_time from_ms(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); }
|
||||
ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); }
|
||||
ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
|
||||
|
||||
@ -319,18 +331,43 @@ public:
|
||||
clear();
|
||||
}
|
||||
|
||||
ATTR_HOT inline bool is_empty() { return ((m_start & SIZE) == (m_end & SIZE)); }
|
||||
ATTR_HOT inline bool is_not_empty() { return ((m_start & SIZE) != (m_end & SIZE)); }
|
||||
ATTR_HOT bool is_empty() { return ((m_start & SIZE) == (m_end & SIZE)); }
|
||||
ATTR_HOT bool is_not_empty() { return ((m_start & SIZE) != (m_end & SIZE)); }
|
||||
|
||||
ATTR_HOT inline void push(const entry_t &e);
|
||||
ATTR_HOT void push(const entry_t &e)
|
||||
{
|
||||
const netlist_time &t = e.time();
|
||||
|
||||
ATTR_HOT inline entry_t &pop()
|
||||
if (is_empty() || (t <= item(m_end - 1).time()))
|
||||
{
|
||||
set_item(m_end, e);
|
||||
m_end++;
|
||||
}
|
||||
else if (t >= item(m_start).time())
|
||||
{
|
||||
m_start--;
|
||||
set_item(m_start, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
register UINT32 i = m_end;
|
||||
m_end++;
|
||||
while ((t > item(i-1).time()))
|
||||
{
|
||||
set_item(i, item(i-1));
|
||||
i--;
|
||||
}
|
||||
set_item(i, e);
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_HOT entry_t &pop()
|
||||
{
|
||||
m_end--;
|
||||
return item(m_end);
|
||||
}
|
||||
|
||||
ATTR_HOT inline entry_t &peek()
|
||||
ATTR_HOT entry_t &peek()
|
||||
{
|
||||
return item(m_end-1);
|
||||
}
|
||||
@ -348,33 +385,7 @@ private:
|
||||
entry_t m_list[SIZE + 1];
|
||||
};
|
||||
|
||||
template <class _QC, int _Size>
|
||||
ATTR_HOT ATTR_ALIGN inline void netlist_timed_queue<_QC, _Size>::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++;
|
||||
}
|
||||
else if (t >= item(m_start).time())
|
||||
{
|
||||
m_start--;
|
||||
set_item(m_start, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
register UINT32 i = m_end;
|
||||
m_end++;
|
||||
while ((t > item(i-1).time()))
|
||||
{
|
||||
set_item(i, item(i-1));
|
||||
i--;
|
||||
}
|
||||
set_item(i, e);
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// forward definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -522,7 +533,7 @@ public:
|
||||
{
|
||||
case SIGNAL_DIGITAL: return m_Q ? m_high_V : m_low_V;
|
||||
case SIGNAL_ANALOG: return m_Q_analog;
|
||||
default: assert(true);
|
||||
default: assert(true); break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -539,12 +550,13 @@ public:
|
||||
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() { m_active--; }
|
||||
ATTR_HOT inline void dec_active();
|
||||
|
||||
ATTR_HOT inline int active_count() { return m_active; }
|
||||
ATTR_HOT inline netlist_time time() { return m_time; }
|
||||
ATTR_HOT inline void set_time(netlist_time ntime) { m_time = ntime; }
|
||||
|
||||
ATTR_COLD void set_netdev(const net_core_device_t *dev);
|
||||
ATTR_COLD void set_netdev(net_core_device_t *dev);
|
||||
|
||||
protected:
|
||||
|
||||
@ -585,7 +597,7 @@ protected:
|
||||
|
||||
netlist_time m_time;
|
||||
UINT8 m_in_queue;
|
||||
UINT8 m_active;
|
||||
int m_active;
|
||||
|
||||
net_sig_t m_Q;
|
||||
net_sig_t m_new_Q;
|
||||
@ -598,7 +610,7 @@ protected:
|
||||
int m_num_cons;
|
||||
net_input_t *m_cons[48];
|
||||
|
||||
const net_core_device_t *m_netdev;
|
||||
net_core_device_t *m_netdev;
|
||||
double m_low_V;
|
||||
double m_high_V;
|
||||
|
||||
@ -646,7 +658,7 @@ public:
|
||||
: 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 setToPS(const double val, const netlist_time &delay) { set_Q_Analog(val,delay); }
|
||||
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); }
|
||||
};
|
||||
|
||||
@ -658,12 +670,10 @@ class net_core_device_t : public net_object_t
|
||||
{
|
||||
public:
|
||||
|
||||
net_core_device_t();
|
||||
net_core_device_t(netlist_setup_t &setup, const char *name);
|
||||
|
||||
virtual ~net_core_device_t();
|
||||
|
||||
ATTR_COLD void init_core(netlist_base_t *anetlist, const char *name);
|
||||
|
||||
ATTR_COLD const char *name() const { return m_name; }
|
||||
|
||||
ATTR_HOT inline void update_device() { update(); }
|
||||
@ -698,11 +708,13 @@ public:
|
||||
|
||||
ATTR_HOT inline double INPANALOG(const analog_input_t &inp) { return inp.Q_Analog(); }
|
||||
|
||||
ATTR_HOT inline netlist_base_t *netlist() const { return m_netlist; }
|
||||
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; }
|
||||
|
||||
net_list_t<net_core_device_t *, 20> m_subdevs;
|
||||
ATTR_HOT virtual void inc_active() { }
|
||||
|
||||
ATTR_HOT virtual void dec_active() { }
|
||||
|
||||
/* stats */
|
||||
osd_ticks_t total_time;
|
||||
@ -710,9 +722,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD void register_subdevice(net_core_device_t &subdev);
|
||||
|
||||
netlist_base_t *m_netlist;
|
||||
netlist_base_t &m_netlist;
|
||||
|
||||
private:
|
||||
|
||||
@ -731,12 +741,14 @@ public:
|
||||
|
||||
virtual ~net_device_t();
|
||||
|
||||
virtual void update() { }
|
||||
|
||||
ATTR_COLD const netlist_setup_t &setup() const { return m_setup; }
|
||||
|
||||
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
|
||||
|
||||
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(net_core_device_t &dev, const char *name, net_output_t &out);
|
||||
|
||||
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);
|
||||
@ -783,12 +795,12 @@ private:
|
||||
// net_signal_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <int _numdev, int _check>
|
||||
class net_signal_t : public net_device_t
|
||||
template <int _numdev>
|
||||
class net_signal_base_t : public net_device_t
|
||||
{
|
||||
public:
|
||||
net_signal_t(netlist_setup_t &setup, const char *name)
|
||||
: net_device_t(setup, name)
|
||||
net_signal_base_t(netlist_setup_t &setup, const char *name)
|
||||
: net_device_t(setup, name), m_active(1)
|
||||
{
|
||||
const char *sIN[8] = { "I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8" };
|
||||
|
||||
@ -800,17 +812,83 @@ public:
|
||||
m_Q.initial(1);
|
||||
}
|
||||
|
||||
ATTR_HOT inline void update()
|
||||
#if (USE_DEACTIVE_DEVICE)
|
||||
ATTR_HOT void inc_active()
|
||||
{
|
||||
if (m_active == 0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
m_active++;
|
||||
}
|
||||
|
||||
ATTR_HOT void dec_active()
|
||||
{
|
||||
m_active--;
|
||||
if (m_active == 0)
|
||||
{
|
||||
for (int i = 0; i< _numdev; i++)
|
||||
m_i[i].inactivate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
ttl_input_t m_i[_numdev];
|
||||
ttl_output_t m_Q;
|
||||
INT8 m_active;
|
||||
};
|
||||
|
||||
|
||||
template <int _numdev, UINT8 _check, UINT8 _invert>
|
||||
class net_signal_t : public net_device_t
|
||||
{
|
||||
public:
|
||||
net_signal_t(netlist_setup_t &setup, const char *name)
|
||||
: net_device_t(setup, name), m_active(1)
|
||||
{
|
||||
const char *sIN[8] = { "I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8" };
|
||||
|
||||
register_output("Q", m_Q);
|
||||
for (int i=0; i < _numdev; i++)
|
||||
{
|
||||
register_input(sIN[i], m_i[i], net_input_t::INP_STATE_ACTIVE);
|
||||
}
|
||||
m_Q.initial(1);
|
||||
}
|
||||
|
||||
#if (USE_DEACTIVE_DEVICE)
|
||||
ATTR_HOT void inc_active()
|
||||
{
|
||||
if (m_active == 0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
m_active++;
|
||||
}
|
||||
|
||||
ATTR_HOT void dec_active()
|
||||
{
|
||||
m_active--;
|
||||
if (m_active == 0)
|
||||
{
|
||||
for (int i = 0; i< _numdev; i++)
|
||||
m_i[i].inactivate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void update()
|
||||
{
|
||||
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)
|
||||
this->m_i[i].activate();
|
||||
if (INPVAL(this->m_i[i]) == _check)
|
||||
{
|
||||
m_Q.setTo(!_check, times[_check]);// ? 15000 : 22000);
|
||||
this->m_Q.setTo(_check ^ (1 ^ _invert), times[_check]);// ? 15000 : 22000);
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
@ -819,58 +897,145 @@ public:
|
||||
{
|
||||
for (int i = 0; i < _numdev; i++)
|
||||
if (i != pos)
|
||||
m_i[i].inactivate();
|
||||
this->m_i[i].inactivate();
|
||||
} else
|
||||
m_Q.setTo(_check, times[1-_check]);// ? 22000 : 15000);
|
||||
this->m_Q.setTo(_check ^ (_invert), times[1-_check]);// ? 22000 : 15000);
|
||||
}
|
||||
|
||||
protected:
|
||||
public:
|
||||
ttl_input_t m_i[_numdev];
|
||||
ttl_output_t m_Q;
|
||||
INT8 m_active;
|
||||
};
|
||||
|
||||
#if 0
|
||||
template <>
|
||||
class net_signal_t<2, 0> : public net_device_t
|
||||
#if 1
|
||||
template <UINT8 _check, UINT8 _invert>
|
||||
class xx_net_signal_t: public net_device_t
|
||||
{
|
||||
public:
|
||||
net_signal_t()
|
||||
: net_device_t() { }
|
||||
xx_net_signal_t(netlist_setup_t &setup, const char *name)
|
||||
: net_device_t(setup, name), m_active(1)
|
||||
{
|
||||
const char *sIN[2] = { "I1", "I2" };
|
||||
|
||||
ATTR_COLD void start()
|
||||
register_output("Q", m_Q);
|
||||
for (int i=0; i < 2; i++)
|
||||
{
|
||||
register_input(sIN[i], m_i[i], net_input_t::INP_STATE_ACTIVE);
|
||||
}
|
||||
m_Q.initial(1);
|
||||
}
|
||||
|
||||
#if (USE_DEACTIVE_DEVICE)
|
||||
ATTR_HOT void inc_active()
|
||||
{
|
||||
if (m_active == 0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
m_active++;
|
||||
}
|
||||
|
||||
ATTR_HOT void dec_active()
|
||||
{
|
||||
m_active--;
|
||||
if (m_active == 0)
|
||||
{
|
||||
m_i[0].inactivate();
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void update()
|
||||
{
|
||||
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);
|
||||
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
|
||||
//const UINT8 res_tab[4] = {1, 1, 1, 0 };
|
||||
//const UINT8 ai1[4] = {0, 1, 0, 0 };
|
||||
//const UINT8 ai2[4] = {1, 0, 1, 0 };
|
||||
|
||||
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
|
||||
UINT8 res = _invert ^ 1 ^_check;
|
||||
m_i[0].activate();
|
||||
if (INPVAL(m_i[0]) ^ _check)
|
||||
{
|
||||
m_i[1].activate();
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
{
|
||||
res = _invert ^ _check;
|
||||
}
|
||||
else
|
||||
m_i[0].inactivate();
|
||||
} else {
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
|
||||
}
|
||||
|
||||
protected:
|
||||
public:
|
||||
ttl_input_t m_i[2];
|
||||
ttl_output_t m_Q;
|
||||
INT8 m_active;
|
||||
|
||||
};
|
||||
|
||||
template <UINT8 _check, UINT8 _invert>
|
||||
class net_signal_t<2, _check, _invert> : public xx_net_signal_t<_check, _invert>
|
||||
{
|
||||
public:
|
||||
net_signal_t(netlist_setup_t &setup, const char *name)
|
||||
: xx_net_signal_t<_check, _invert>(setup, name) { }
|
||||
};
|
||||
|
||||
// The following did not improve performance
|
||||
#if 0
|
||||
template <UINT8 _check, UINT8 _invert>
|
||||
class net_signal_t<3, _check, _invert> : public net_signal_base_t<3>
|
||||
{
|
||||
public:
|
||||
net_signal_t(netlist_setup_t &setup, const char *name)
|
||||
: net_signal_base_t<3>(setup, name)
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void update()
|
||||
{
|
||||
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
|
||||
//const UINT8 res_tab[4] = {1, 1, 1, 0 };
|
||||
//const UINT8 ai1[4] = {0, 1, 0, 0 };
|
||||
//const UINT8 ai2[4] = {1, 0, 1, 0 };
|
||||
|
||||
UINT8 res = _invert ^ 1 ^_check;
|
||||
m_i[0].activate();
|
||||
if (INPVAL(m_i[0]) ^ _check)
|
||||
{
|
||||
m_i[1].activate();
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
{
|
||||
m_i[2].activate();
|
||||
if (INPVAL(m_i[2]) ^ _check)
|
||||
{
|
||||
res = _invert ^ _check;
|
||||
}
|
||||
else
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (INPVAL(m_i[2]) ^ _check)
|
||||
m_i[2].inactivate();
|
||||
m_i[0].inactivate();
|
||||
}
|
||||
} else {
|
||||
if (INPVAL(m_i[1]) ^ _check)
|
||||
m_i[1].inactivate();
|
||||
}
|
||||
m_Q.setTo(res, times[1 - res]);// ? 22000 : 15000);
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -895,8 +1060,8 @@ public:
|
||||
net_device_t *register_dev(net_device_t *dev);
|
||||
void remove_dev(const char *name);
|
||||
|
||||
void register_output(const char *name, net_output_t *out);
|
||||
void register_input(const char *name, net_input_t *inp);
|
||||
void register_output(net_core_device_t &dev, net_core_device_t &upd_dev, const char *name, net_output_t &out);
|
||||
void register_input(net_device_t &dev, net_core_device_t &upd_dev, const char *name, net_input_t &inp, net_input_t::net_input_state type);
|
||||
void register_alias(const char *alias, const char *out);
|
||||
void register_param(const char *sname, net_param_t *param);
|
||||
|
||||
@ -999,18 +1164,6 @@ 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.new_Q_ptr() = !m_Q.new_Q();
|
||||
m_Q.set_time(m_netlist->time() + m_inc);
|
||||
//m_Q.setToNoCheckPS(!m_Q.new_Q(), m_inc );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netdev_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -1113,9 +1266,19 @@ ATTR_HOT inline void net_output_t::push_to_queue(const netlist_time &delay)
|
||||
ATTR_HOT inline void net_output_t::inc_active()
|
||||
{
|
||||
m_active++;
|
||||
|
||||
#if USE_DEACTIVE_DEVICE
|
||||
if (m_active == 1 && m_in_queue > 0)
|
||||
{
|
||||
m_last_Q = m_Q;
|
||||
m_netdev->inc_active();
|
||||
m_Q = m_new_Q;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_active == 1 && m_in_queue == 0)
|
||||
{
|
||||
if (m_time >= m_netlist->time())
|
||||
if (m_time > m_netlist->time())
|
||||
{
|
||||
m_in_queue = 1; /* pending */
|
||||
m_netlist->push_to_queue(this, m_time);
|
||||
@ -1129,6 +1292,17 @@ ATTR_HOT inline void net_output_t::inc_active()
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_HOT inline void net_output_t::dec_active()
|
||||
{
|
||||
m_active--;
|
||||
#if (USE_DEACTIVE_DEVICE)
|
||||
if (m_active == 0)
|
||||
m_netdev->dec_active();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ATTR_HOT inline net_sig_t logic_input_t::Q() const { return output()->Q(); }
|
||||
ATTR_HOT inline net_sig_t logic_input_t::last_Q() const { return output()->last_Q(); }
|
||||
|
@ -70,9 +70,28 @@ enum input_changed_enum
|
||||
static NETLIST_START(pong_schematics)
|
||||
NETDEV_TTL_CONST(high, 1)
|
||||
NETDEV_TTL_CONST(low, 0)
|
||||
#if 1
|
||||
#if 0
|
||||
/* this is the clock circuit in schematics. */
|
||||
NETDEV_MAINCLOCK(xclk)
|
||||
//NETDEV_CLOCK(clk)
|
||||
NETDEV_PARAM(xclk.FREQ, 7159000.0*2)
|
||||
TTL_74107(ic_f6a, xclk, high, high, high)
|
||||
NET_ALIAS(clk, ic_f6a.Q)
|
||||
#else
|
||||
/* abstracting this, performance increases by 80%
|
||||
* No surprise, the clock is extremely expensive */
|
||||
NETDEV_MAINCLOCK(clk)
|
||||
//NETDEV_CLOCK(clk)
|
||||
NETDEV_PARAM(clk.FREQ, 7159000.0)
|
||||
#endif
|
||||
#else
|
||||
// benchmarking ...
|
||||
NETDEV_TTL_CONST(clk, 0)
|
||||
NETDEV_MAINCLOCK(xclk)
|
||||
NETDEV_PARAM(xclk.FREQ, 7159000.0*2)
|
||||
#endif
|
||||
|
||||
NETDEV_LOGIC_INPUT(SRST)
|
||||
NETDEV_ANALOG_INPUT(P1)
|
||||
NETDEV_ANALOG_INPUT(P2)
|
||||
@ -179,6 +198,9 @@ static NETLIST_START(pong_schematics)
|
||||
TTL_7400_NAND(ic_e1c, ic_f1.QC, ic_f1.QD)
|
||||
TTL_7493(ic_f1, ic_e1d.Q, ic_f1.QA, rstspeed, rstspeed)
|
||||
|
||||
//NETDEV_LOG(LOG2, ic_f1.QC)
|
||||
//NETDEV_LOG(LOG3, ic_f1.QD)
|
||||
|
||||
TTL_7402_NOR(ic_g1d, ic_f1.QC, ic_f1.QD)
|
||||
TTL_7400_NAND(ic_h1a, ic_g1d.Q, ic_g1d.Q)
|
||||
TTL_7400_NAND(ic_h1d, ic_e1c.Q, ic_h1a.Q)
|
||||
@ -189,6 +211,11 @@ static NETLIST_START(pong_schematics)
|
||||
|
||||
TTL_74107(ic_h2a, ic_g1c.Q, ic_h2b.Q, low, ic_h1b.Q)
|
||||
TTL_74107(ic_h2b, ic_g1c.Q, high, move, ic_h1c.Q)
|
||||
|
||||
//NETDEV_LOG(LOG2, ic_h2a)
|
||||
//NETDEV_LOG(LOG3, ic_h2b)
|
||||
|
||||
|
||||
TTL_7400_NAND(ic_h4a, ic_h2b.Q, ic_h2a.Q)
|
||||
NET_ALIAS(move, ic_h4a.Q)
|
||||
|
||||
@ -196,6 +223,8 @@ static NETLIST_START(pong_schematics)
|
||||
TTL_7404_INVERT(ic_d1a, ic_c1d.Q)
|
||||
TTL_7474(ic_h3b, ic_d1a.Q, ic_h3b.QQ, hit1Q, hit2Q)
|
||||
|
||||
//NETDEV_LOG(LOG1, move)
|
||||
|
||||
TTL_7400_NAND(ic_h4d, ic_h3b.Q, move)
|
||||
TTL_7400_NAND(ic_h4b, ic_h3b.QQ, move)
|
||||
TTL_7400_NAND(ic_h4c, ic_h4d.Q, ic_h4b.Q)
|
||||
@ -374,8 +403,8 @@ 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_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)
|
||||
|
||||
@ -418,7 +447,6 @@ static NETLIST_START(pong_schematics)
|
||||
NETDEV_PARAM(videomix.R1, RES_K(1))
|
||||
NETDEV_PARAM(videomix.R2, RES_K(1.2))
|
||||
NETDEV_PARAM(videomix.R3, RES_K(22))
|
||||
|
||||
NETLIST_END
|
||||
|
||||
static NETLIST_START(pong)
|
||||
@ -513,6 +541,8 @@ private:
|
||||
const netlist_time vsync_min_time = netlist_time::from_us(50); /* usec */
|
||||
const int vsync_min_pulses = 4;
|
||||
|
||||
bitmap_rgb32 *bm = m_bitmap[m_cur_bm];
|
||||
|
||||
UINT64 clocks = m_maincpu->total_cycles(); // m_maincpu->attotime_to_cycles(m_maincpu->local_time());
|
||||
int pw = NETLIST_CLOCK / ((UINT64)MASTER_CLOCK) / HRES_MULT;
|
||||
netlist_time time = clock_period * (clocks - m_last_clock);
|
||||
@ -520,19 +550,19 @@ private:
|
||||
//UINT64 clocks = m_maincpu->netlist().time().as_raw() >> 10; // m_maincpu->attotime_to_cycles(m_maincpu->local_time());
|
||||
//int pw = (NETLIST_INTERNAL_CLOCK / ((UINT64)MASTER_CLOCK) / HRES_MULT) >> 8;
|
||||
|
||||
if (m_last_y < m_bitmap->height())
|
||||
if (m_last_y < bm->height())
|
||||
{
|
||||
int colv = (int) (m_vid / 3.5 * 255.0);
|
||||
rgb_t col = MAKE_RGB(colv, colv, colv);
|
||||
int pixels = (clocks - m_line_clock) / pw;
|
||||
|
||||
while (pixels >= m_bitmap->width())
|
||||
while (pixels >= bm->width())
|
||||
{
|
||||
m_bitmap->plot_box(m_last_x, m_last_y, m_bitmap->width() - 1 - m_last_x, 1, col);
|
||||
pixels -= m_bitmap->width();
|
||||
bm->plot_box(m_last_x, m_last_y, bm->width() - 1 - m_last_x, 1, col);
|
||||
pixels -= bm->width();
|
||||
m_last_x = 0;
|
||||
}
|
||||
m_bitmap->plot_box(m_last_x, m_last_y, pixels - m_last_x, 1, col);
|
||||
bm->plot_box(m_last_x, m_last_y, pixels - m_last_x, 1, col);
|
||||
m_last_x = pixels;
|
||||
}
|
||||
if (m_vid <= 0.34)
|
||||
@ -544,6 +574,8 @@ private:
|
||||
{
|
||||
m_vsync_cnt = 0;
|
||||
m_last_y = 0;
|
||||
// toggle bitmap
|
||||
m_cur_bm ^= 1;
|
||||
attoseconds_t new_refresh = DOUBLE_TO_ATTOSECONDS((double) (clocks - m_vsync_clock) / (double) NETLIST_CLOCK);
|
||||
if (new_refresh != m_refresh)
|
||||
{
|
||||
@ -575,12 +607,15 @@ private:
|
||||
UINT64 m_vsync_clock;
|
||||
attoseconds_t m_refresh;
|
||||
int m_vsync_cnt;
|
||||
bitmap_rgb32 *m_bitmap;
|
||||
bitmap_rgb32 *m_bitmap[2];
|
||||
int m_cur_bm;
|
||||
};
|
||||
|
||||
void pong_state::machine_start()
|
||||
{
|
||||
m_bitmap = auto_bitmap_rgb32_alloc(machine(),H_TOTAL * HRES_MULT,V_TOTAL);
|
||||
m_bitmap[0] = auto_bitmap_rgb32_alloc(machine(),H_TOTAL * HRES_MULT,V_TOTAL);
|
||||
m_bitmap[1] = auto_bitmap_rgb32_alloc(machine(),H_TOTAL * HRES_MULT,V_TOTAL);
|
||||
m_cur_bm = 0;
|
||||
|
||||
m_maincpu->setup().register_callback("sound_cb", net_output_delegate(&pong_state::sound_cb, "pong_state::sound_cb", this));
|
||||
m_maincpu->setup().register_callback("video_cb", net_output_delegate(&pong_state::video_cb, "pong_state::video_cb", this));
|
||||
@ -599,7 +634,7 @@ void pong_state::video_start()
|
||||
|
||||
UINT32 pong_state::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
copybitmap(bitmap, *m_bitmap, 0, 0, 0, 0, cliprect);
|
||||
copybitmap(bitmap, *m_bitmap[!m_cur_bm], 0, 0, 0, 0, cliprect);
|
||||
//m_bitmap->fill(MAKE_RGB(0,0,0));
|
||||
return 0;
|
||||
}
|
||||
@ -631,8 +666,8 @@ 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->setToPS(pad, NLTIME_FROM_NS(0)); break;
|
||||
case IC_PADDLE2: m_p_V1->setToPS(pad, NLTIME_FROM_NS(0)); break;
|
||||
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;
|
||||
}
|
||||
printf("%d %f\n", newval, (float) pad);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user