diff --git a/src/emu/netlist/devices/nld_7400.c b/src/emu/netlist/devices/nld_7400.c index cb5d7f75faa..fb97746d448 100644 --- a/src/emu/netlist/devices/nld_7400.c +++ b/src/emu/netlist/devices/nld_7400.c @@ -6,7 +6,16 @@ #include "nld_7400.h" #if 0 -UINT32 nld_7400::m_outs[m_size]; +nld_7400::truthtable_t nld_7400::m_ttbl; + +const char *nld_7400::m_desc[] = { + "A,B,PQ,PA,PB|Q", + "0,X,X,X,X|1|22", + "X,0,X,X,X|1|22", + "1,1,X,X,X|0|15", + "" +}; + #endif NETLIB_START(7400_dip) @@ -18,19 +27,19 @@ NETLIB_START(7400_dip) register_subalias("1", m_1.m_i[0]); register_subalias("2", m_1.m_i[1]); - register_subalias("3", m_1.m_Q); + register_subalias("3", m_1.m_Q[0]); register_subalias("4", m_2.m_i[0]); register_subalias("5", m_2.m_i[1]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("12", m_4.m_i[0]); register_subalias("13", m_4.m_i[1]); - register_subalias("11", m_4.m_Q); + register_subalias("11", m_4.m_Q[0]); } NETLIB_UPDATE(7400_dip) diff --git a/src/emu/netlist/devices/nld_7400.h b/src/emu/netlist/devices/nld_7400.h index 0a86609e626..e39a485fd1a 100644 --- a/src/emu/netlist/devices/nld_7400.h +++ b/src/emu/netlist/devices/nld_7400.h @@ -43,27 +43,7 @@ NETLIB_SIGNAL(7400, 2, 0, 0); #else #include "nld_truthtable.h" -class nld_7400 : public nld_truthtable_t<2,1> - { - public: - nld_7400 () - : nld_truthtable_t<2,1>() - { - } - void start() - { - static const char *tt[] = { - "A,B,PQ,PA,PB|Q", - "0,X,X,X,X|1", - "X,0,X,X,X|1", - "1,1,X,X,X|0", - "" - }; - setup_tt(tt, m_outs); - } - private: - static UINT32 m_outs[m_size]; -}; +NETLIB_TRUTHTABLE(7400, 2, 1, 0); #endif diff --git a/src/emu/netlist/devices/nld_7402.c b/src/emu/netlist/devices/nld_7402.c index 3a01e083336..9c2bac7c50f 100644 --- a/src/emu/netlist/devices/nld_7402.c +++ b/src/emu/netlist/devices/nld_7402.c @@ -12,21 +12,21 @@ NETLIB_START(7402_dip) register_sub(m_3, "3"); register_sub(m_4, "4"); - register_subalias("1", m_1.m_Q); + register_subalias("1", m_1.m_Q[0]); register_subalias("2", m_1.m_i[0]); register_subalias("3", m_1.m_i[1]); - register_subalias("4", m_2.m_Q); + register_subalias("4", m_2.m_Q[0]); register_subalias("5", m_2.m_i[0]); register_subalias("6", m_2.m_i[1]); register_subalias("8", m_3.m_i[0]); register_subalias("9", m_3.m_i[1]); - register_subalias("10", m_3.m_Q); + register_subalias("10", m_3.m_Q[0]); register_subalias("11", m_4.m_i[0]); register_subalias("12", m_4.m_i[1]); - register_subalias("13", m_4.m_Q); + register_subalias("13", m_4.m_Q[0]); } NETLIB_UPDATE(7402_dip) diff --git a/src/emu/netlist/devices/nld_7408.c b/src/emu/netlist/devices/nld_7408.c index e57c96016e0..788d68af196 100644 --- a/src/emu/netlist/devices/nld_7408.c +++ b/src/emu/netlist/devices/nld_7408.c @@ -14,19 +14,19 @@ NETLIB_START(7408_dip) register_subalias("1", m_1.m_i[0]); register_subalias("2", m_1.m_i[1]); - register_subalias("3", m_1.m_Q); + register_subalias("3", m_1.m_Q[0]); register_subalias("4", m_2.m_i[0]); register_subalias("5", m_2.m_i[1]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("12", m_4.m_i[0]); register_subalias("13", m_4.m_i[1]); - register_subalias("11", m_4.m_Q); + register_subalias("11", m_4.m_Q[0]); } NETLIB_UPDATE(7408_dip) diff --git a/src/emu/netlist/devices/nld_7410.c b/src/emu/netlist/devices/nld_7410.c index 95f477a2b4a..6e68517fe58 100644 --- a/src/emu/netlist/devices/nld_7410.c +++ b/src/emu/netlist/devices/nld_7410.c @@ -16,14 +16,14 @@ NETLIB_START(7410_dip) register_subalias("3", m_2.m_i[0]); register_subalias("4", m_2.m_i[1]); register_subalias("5", m_2.m_i[2]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); register_subalias("11", m_3.m_i[2]); - register_subalias("12", m_1.m_Q); + register_subalias("12", m_1.m_Q[0]); register_subalias("13", m_1.m_i[2]); } diff --git a/src/emu/netlist/devices/nld_7411.c b/src/emu/netlist/devices/nld_7411.c index 8f449bfa13c..eefa0c7f81a 100644 --- a/src/emu/netlist/devices/nld_7411.c +++ b/src/emu/netlist/devices/nld_7411.c @@ -16,14 +16,14 @@ NETLIB_START(7411_dip) register_subalias("3", m_2.m_i[0]); register_subalias("4", m_2.m_i[1]); register_subalias("5", m_2.m_i[2]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); register_subalias("11", m_3.m_i[2]); - register_subalias("12", m_1.m_Q); + register_subalias("12", m_1.m_Q[0]); register_subalias("13", m_1.m_i[2]); } diff --git a/src/emu/netlist/devices/nld_7420.c b/src/emu/netlist/devices/nld_7420.c index b4bb3f77a1b..538b666643c 100644 --- a/src/emu/netlist/devices/nld_7420.c +++ b/src/emu/netlist/devices/nld_7420.c @@ -15,9 +15,9 @@ NETLIB_START(7420_dip) register_subalias("4", m_1.m_i[2]); register_subalias("5", m_1.m_i[3]); - register_subalias("6", m_1.m_Q); + register_subalias("6", m_1.m_Q[0]); - register_subalias("8", m_2.m_Q); + register_subalias("8", m_2.m_Q[0]); register_subalias("9", m_2.m_i[0]); register_subalias("10", m_2.m_i[1]); diff --git a/src/emu/netlist/devices/nld_7425.c b/src/emu/netlist/devices/nld_7425.c index 30262a1f181..b588dc9dc7b 100644 --- a/src/emu/netlist/devices/nld_7425.c +++ b/src/emu/netlist/devices/nld_7425.c @@ -17,9 +17,9 @@ NETLIB_START(7425_dip) register_subalias("4", m_1.m_i[2]); register_subalias("5", m_1.m_i[3]); - register_subalias("6", m_1.m_Q); + register_subalias("6", m_1.m_Q[0]); - register_subalias("8", m_2.m_Q); + register_subalias("8", m_2.m_Q[0]); register_subalias("9", m_2.m_i[0]); register_subalias("10", m_2.m_i[1]); diff --git a/src/emu/netlist/devices/nld_7427.c b/src/emu/netlist/devices/nld_7427.c index 49904334d07..0a5873dba9e 100644 --- a/src/emu/netlist/devices/nld_7427.c +++ b/src/emu/netlist/devices/nld_7427.c @@ -16,14 +16,14 @@ NETLIB_START(7427_dip) register_subalias("3", m_2.m_i[0]); register_subalias("4", m_2.m_i[1]); register_subalias("5", m_2.m_i[2]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); register_subalias("11", m_3.m_i[2]); - register_subalias("12", m_1.m_Q); + register_subalias("12", m_1.m_Q[0]); register_subalias("13", m_1.m_i[2]); } diff --git a/src/emu/netlist/devices/nld_7430.c b/src/emu/netlist/devices/nld_7430.c index b9079846325..6d481fdc74d 100644 --- a/src/emu/netlist/devices/nld_7430.c +++ b/src/emu/netlist/devices/nld_7430.c @@ -16,7 +16,7 @@ NETLIB_START(7430_dip) register_subalias("5", m_1.m_i[4]); register_subalias("6", m_1.m_i[5]); - register_subalias("8", m_1.m_Q); + register_subalias("8", m_1.m_Q[0]); register_subalias("11", m_1.m_i[6]); register_subalias("12", m_1.m_i[7]); diff --git a/src/emu/netlist/devices/nld_7432.c b/src/emu/netlist/devices/nld_7432.c index 57b1282095b..163b51a82d9 100644 --- a/src/emu/netlist/devices/nld_7432.c +++ b/src/emu/netlist/devices/nld_7432.c @@ -12,21 +12,21 @@ NETLIB_START(7432_dip) register_sub(m_3, "3"); register_sub(m_4, "4"); - register_subalias("1", m_1.m_Q); + register_subalias("1", m_1.m_Q[0]); register_subalias("2", m_1.m_i[0]); register_subalias("3", m_1.m_i[1]); - register_subalias("4", m_2.m_Q); + register_subalias("4", m_2.m_Q[0]); register_subalias("5", m_2.m_i[0]); register_subalias("6", m_2.m_i[1]); register_subalias("8", m_3.m_i[0]); register_subalias("9", m_3.m_i[1]); - register_subalias("10", m_3.m_Q); + register_subalias("10", m_3.m_Q[0]); register_subalias("11", m_4.m_i[0]); register_subalias("12", m_4.m_i[1]); - register_subalias("13", m_4.m_Q); + register_subalias("13", m_4.m_Q[0]); } NETLIB_UPDATE(7432_dip) diff --git a/src/emu/netlist/devices/nld_7437.c b/src/emu/netlist/devices/nld_7437.c index 76cba737301..8462cec3b1f 100644 --- a/src/emu/netlist/devices/nld_7437.c +++ b/src/emu/netlist/devices/nld_7437.c @@ -14,19 +14,19 @@ NETLIB_START(7437_dip) register_subalias("1", m_1.m_i[0]); register_subalias("2", m_1.m_i[1]); - register_subalias("3", m_1.m_Q); + register_subalias("3", m_1.m_Q[0]); register_subalias("4", m_2.m_i[0]); register_subalias("5", m_2.m_i[1]); - register_subalias("6", m_2.m_Q); + register_subalias("6", m_2.m_Q[0]); register_subalias("9", m_3.m_i[0]); register_subalias("10", m_3.m_i[1]); - register_subalias("8", m_3.m_Q); + register_subalias("8", m_3.m_Q[0]); register_subalias("12", m_4.m_i[0]); register_subalias("13", m_4.m_i[1]); - register_subalias("11", m_4.m_Q); + register_subalias("11", m_4.m_Q[0]); } NETLIB_UPDATE(7437_dip) diff --git a/src/emu/netlist/devices/nld_signal.h b/src/emu/netlist/devices/nld_signal.h index fc37aff6284..3284ed6fbde 100644 --- a/src/emu/netlist/devices/nld_signal.h +++ b/src/emu/netlist/devices/nld_signal.h @@ -39,7 +39,7 @@ public: { const char *sIN[8] = { "A", "B", "C", "D", "E", "F", "G", "H" }; - register_output("Q", m_Q); + register_output("Q", m_Q[0]); for (int i=0; i < _numdev; i++) { register_input(sIN[i], m_i[i]); @@ -49,7 +49,7 @@ public: ATTR_COLD void reset() { - m_Q.initial(1); + m_Q[0].initial(1); m_active = 1; } @@ -90,16 +90,16 @@ public: for (int j = i + 1; j < _numdev; j++) this->m_i[j].inactivate(); - OUTLOGIC(this->m_Q, _check ^ (1 ^ _invert), times[_check ^ (1 ^ _invert)]);// ? 15000 : 22000); + OUTLOGIC(this->m_Q[0], _check ^ (1 ^ _invert), times[_check ^ (1 ^ _invert)]);// ? 15000 : 22000); return; } } - OUTLOGIC(this->m_Q,_check ^ (_invert), times[_check ^ (_invert)]);// ? 22000 : 15000); + OUTLOGIC(this->m_Q[0],_check ^ (_invert), times[_check ^ (_invert)]);// ? 22000 : 15000); } public: netlist_ttl_input_t m_i[_numdev]; - netlist_ttl_output_t m_Q; + netlist_ttl_output_t m_Q[1]; INT32 m_active; }; @@ -114,7 +114,7 @@ public: ATTR_COLD void start() { - register_output("Q", m_Q); + register_output("Q", m_Q[0]); register_input("A", m_i[0]); register_input("B", m_i[1]); @@ -123,7 +123,7 @@ public: ATTR_COLD void reset() { - m_Q.initial(1); + m_Q[0].initial(1); m_active = 1; } @@ -171,12 +171,12 @@ public: res = _invert ^ _check; break; } - OUTLOGIC(m_Q, res, times[res]);// ? 22000 : 15000); + OUTLOGIC(m_Q[0], res, times[res]);// ? 22000 : 15000); } public: netlist_ttl_input_t m_i[2]; - netlist_ttl_output_t m_Q; + netlist_ttl_output_t m_Q[1]; INT32 m_active; }; diff --git a/src/emu/netlist/devices/nld_truthtable.h b/src/emu/netlist/devices/nld_truthtable.h index 1eb069d6612..f5904f0dfc2 100644 --- a/src/emu/netlist/devices/nld_truthtable.h +++ b/src/emu/netlist/devices/nld_truthtable.h @@ -10,23 +10,67 @@ #include "../nl_base.h" -template +#define NETLIB_TRUTHTABLE(_name, _nIN, _nOUT, _state) \ + class NETLIB_NAME(_name) : public nld_truthtable_t<_nIN, _nOUT, _state> \ + { \ + public: \ + NETLIB_NAME(_name)() \ + : nld_truthtable_t<_nIN, _nOUT, _state>(&m_ttbl, m_desc) { } \ + private: \ + static truthtable_t m_ttbl; \ + static const char *m_desc[]; \ + } + + +template class nld_truthtable_t : public netlist_device_t { public: - static const int m_size = (1 << (2 * m_NI + m_NO)); + static const int m_num_bits = m_NI + has_state * (m_NI + m_NO); + static const int m_size = (1 << (m_num_bits)); - nld_truthtable_t() - : netlist_device_t(), m_active(1) + struct truthtable_t + { + truthtable_t() : m_initialized(false) {} + UINT32 m_outs[m_size]; + UINT8 m_timing[m_size][m_NO]; + netlist_time m_timing_nt[16]; + bool m_initialized; + }; + + nld_truthtable_t(truthtable_t *ttbl, const char *desc[]) + : netlist_device_t(), m_last_state(0), m_active(1), m_ttp(ttbl), m_desc(desc) { } ATTR_COLD virtual void start() { + pstring ttline = pstring(m_desc[0]); + { + nl_util::pstring_list io = nl_util::split(ttline,"|"); + // checks + assert(io.count() == 2); + nl_util::pstring_list inout = nl_util::split(io[0], ","); + assert(inout.count() == m_num_bits); + nl_util::pstring_list out = nl_util::split(io[1], ","); + assert(out.count() == m_NO); + + for (int i=0; i < m_NI; i++) + { + register_input(inout[i], m_i[i]); + } + for (int i=0; i < m_NO; i++) + { + register_output(out[i], m_Q[i]); + } + } + setup_tt(); + // FIXME: save state } - ATTR_COLD void help(UINT32 outs[], int cur, nl_util::pstring_list list, UINT64 state, UINT64 ignore, UINT16 val) + ATTR_COLD void help(int cur, nl_util::pstring_list list, + UINT64 state, UINT64 ignore, UINT16 val, UINT8 timing_index[m_NO]) { pstring elem = list[cur]; int start = 0; @@ -54,69 +98,75 @@ public: const UINT64 nstate = state | (i << cur); const UINT64 nignore = ignore | (ign << cur); - if (cur < list.count() - 1) + if (cur < m_num_bits - 1) { - help(outs, cur + 1, list, nstate, nignore, val); + help(cur + 1, list, nstate, nignore, val, timing_index); } else { // cutoff previous inputs and outputs for ignore - outs[nstate] = val | ((nignore & ((1 << m_NI)-1)) << m_NO); + m_ttp->m_outs[nstate] = val | ((nignore & ((1 << m_NI)-1)) << m_NO); + for (int j=0; jm_timing[nstate][j] = timing_index[j]; } } } - ATTR_COLD void setup_tt(const char **truthtable, UINT32 outs[]) + ATTR_COLD void setup_tt() { + if (m_ttp->m_initialized) + return; + + const char **truthtable = m_desc; pstring ttline = pstring(truthtable[0]); truthtable++; - { - nl_util::pstring_list io = nl_util::split(ttline,"|"); - // checks - assert(io.count() == 2); - nl_util::pstring_list inout = nl_util::split(io[0], ","); - assert(inout.count() == 2 * m_NI + m_NO); - nl_util::pstring_list out = nl_util::split(io[1], ","); - assert(out.count() == m_NO); - - for (int i=0; i < m_NI; i++) - { - register_input(inout[i], m_i[i]); - } - for (int i=0; i < m_NO; i++) - { - register_output(out[i], m_Q[i]); - } - //save(NAME(m_active)); - ttline = pstring(truthtable[0]); - truthtable++; - } + ttline = pstring(truthtable[0]); + truthtable++; for (int j=0; j < m_size; j++) - outs[j] = -1; + m_ttp->m_outs[j] = -1; + + for (int j=0; j < 16; j++) + m_ttp->m_timing_nt[j] = netlist_time::zero; while (!ttline.equals("")) { nl_util::pstring_list io = nl_util::split(ttline,"|"); // checks - assert(io.count() == 2); + assert(io.count() == 3); nl_util::pstring_list inout = nl_util::split(io[0], ","); - assert(inout.count() == 2 * m_NI + m_NO); + assert(inout.count() == m_num_bits); nl_util::pstring_list out = nl_util::split(io[1], ","); assert(out.count() == m_NO); + nl_util::pstring_list times = nl_util::split(io[2], ","); + assert(times.count() == m_NO); UINT16 val = 0; + UINT8 tindex[m_NO]; for (int j=0; jm_timing_nt[k] != netlist_time::zero && m_ttp->m_timing_nt[k] != t) + k++; + m_ttp->m_timing_nt[k] = t; + tindex[j] = k; + } - help(outs, 0, inout, 0 , 0 , val); + help(0, inout, 0 , 0 , val, tindex); ttline = pstring(truthtable[0]); truthtable++; } for (int j=0; j < m_size; j++) - printf("%05x %04x %04x\n", j, outs[j] & ((1 << m_NO)-1), outs[j] >> m_NO); - m_ttp = outs; + printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1), + m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j][0]); + for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero; k++) + printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0); + + m_ttp->m_initialized = true; + } ATTR_COLD void reset() @@ -128,7 +178,7 @@ public: ATTR_HOT ATTR_ALIGN void update() { - const netlist_time times[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22)}; + //const netlist_time times[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22)}; // FIXME: this check is needed because update is called during startup as well if (UNEXPECTED(USE_DEACTIVE_DEVICE && m_active == 0)) @@ -141,17 +191,18 @@ public: state = state | (INPLOGIC(m_i[i]) << i); } - const UINT32 nstate = state | (m_last_state << m_NI); - const UINT32 out = m_ttp[nstate] & ((1 << m_NO) - 1); - const UINT32 ign = m_ttp[nstate] >> m_NO; + const UINT32 nstate = (has_state ? state | (m_last_state << m_NI) : state); + const UINT32 out = m_ttp->m_outs[nstate] & ((1 << m_NO) - 1); + const UINT32 ign = m_ttp->m_outs[nstate] >> m_NO; + if (has_state) m_last_state = (state << m_NO) | out; for (int i=0; i< m_NI; i++) if (ign & (1 << i)) m_i[i].inactivate(); for (int i=0; i> i) & 1, times[(out >> i) & 1]);// ? 22000 : 15000); - m_last_state = (state << m_NO) | out; +// OUTLOGIC(m_Q[i], (out >> i) & 1, times[(out >> i) & 1]);// ? 22000 : 15000); + OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[nstate][i]]);// ? 22000 : 15000); } @@ -175,13 +226,16 @@ public: } #endif -public: netlist_ttl_input_t m_i[m_NI]; netlist_ttl_output_t m_Q[m_NO]; - UINT32 *m_ttp; - INT32 m_active; +private: + UINT32 m_last_state; + INT32 m_active; + + truthtable_t *m_ttp; + const char **m_desc; }; #endif /* NLD_TRUTHTABLE_H_ */ diff --git a/src/emu/netlist/nl_time.h b/src/emu/netlist/nl_time.h index 2800e7f1434..1cd650cbfe5 100644 --- a/src/emu/netlist/nl_time.h +++ b/src/emu/netlist/nl_time.h @@ -40,6 +40,7 @@ public: ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right); ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right); ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right); + ATTR_HOT friend inline bool operator!=(const netlist_time &left, const netlist_time &right); ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; } ATTR_HOT inline const netlist_time &operator=(const double &right) { m_time = (INTERNALTYPE) ( right * (double) RESOLUTION); return *this; } @@ -111,5 +112,9 @@ ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &ri return (left.m_time >= right.m_time); } +ATTR_HOT inline bool operator!=(const netlist_time &left, const netlist_time &right) +{ + return (left.m_time != right.m_time); +} #endif /* NLTIME_H_ */