mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
Added truthtable implementations to a number of devices.
The combination of device activation, usage of GCC PMF extensions and truthtables brings breakout to 95% speed up from about 75%. Fixed NE555 initial state. [Couriersud]
This commit is contained in:
parent
1ef199200c
commit
e8acdc9b96
@ -9,16 +9,6 @@
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7400::truthtable_t nld_7400::m_ttbl;
|
||||
|
||||
#if 0
|
||||
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",
|
||||
""
|
||||
};
|
||||
#else
|
||||
const char *nld_7400::m_desc[] = {
|
||||
"A , B | Q ",
|
||||
"0,X|1|22",
|
||||
@ -26,7 +16,6 @@ const char *nld_7400::m_desc[] = {
|
||||
"1,1|0|15",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -7,6 +7,18 @@
|
||||
|
||||
#include "nld_7402.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7402::truthtable_t nld_7402::m_ttbl;
|
||||
const char *nld_7402::m_desc[] = {
|
||||
"A , B | Q ",
|
||||
"0,0|1|22",
|
||||
"X,1|0|15",
|
||||
"1,X|0|15",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
NETLIB_START(7402_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -43,7 +43,12 @@
|
||||
NET_REGISTER_DEV(7402_dip, _name)
|
||||
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7402, 2, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7402, 2, 1, 0);
|
||||
#endif
|
||||
|
||||
NETLIB_DEVICE(7402_dip,
|
||||
|
||||
|
@ -7,6 +7,18 @@
|
||||
|
||||
#include "nld_7408.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7408::truthtable_t nld_7408::m_ttbl;
|
||||
const char *nld_7408::m_desc[] = {
|
||||
"A , B | Q ",
|
||||
"X,0|0|15",
|
||||
"0,X|0|15",
|
||||
"1,1|1|22",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
NETLIB_START(7408_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -39,7 +39,12 @@
|
||||
NET_CONNECT(_name, A, _A) \
|
||||
NET_CONNECT(_name, B, _B)
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7408, 2, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7408, 2, 0, 1);
|
||||
#endif
|
||||
|
||||
#define TTL_7408_DIP(_name) \
|
||||
NET_REGISTER_DEV(7408_dip, _name)
|
||||
|
@ -7,6 +7,20 @@
|
||||
|
||||
#include "nld_7410.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7410::truthtable_t nld_7410::m_ttbl;
|
||||
const char *nld_7410::m_desc[] = {
|
||||
"A,B,C|Q",
|
||||
"0,X,X|1|22",
|
||||
"X,0,X|1|22",
|
||||
"X,X,0|1|22",
|
||||
"1,1,1|0|15",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
NETLIB_START(7410_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -40,7 +40,12 @@
|
||||
NET_CONNECT(_name, B, _I2) \
|
||||
NET_CONNECT(_name, C, _I3)
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7410, 3, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7410, 3, 0, 0);
|
||||
#endif
|
||||
|
||||
#define TTL_7410_DIP(_name) \
|
||||
NET_REGISTER_DEV(7410_dip, _name)
|
||||
|
@ -7,6 +7,18 @@
|
||||
|
||||
#include "nld_7411.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7411::truthtable_t nld_7411::m_ttbl;
|
||||
const char *nld_7411::m_desc[] = {
|
||||
"A,B,C|Q",
|
||||
"0,X,X|0|15",
|
||||
"X,0,X|0|15",
|
||||
"X,X,0|0|15",
|
||||
"1,1,1|1|22",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
NETLIB_START(7411_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -40,7 +40,12 @@
|
||||
NET_CONNECT(_name, B, _I2) \
|
||||
NET_CONNECT(_name, C, _I3)
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7411, 3, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7411, 3, 0, 1);
|
||||
#endif
|
||||
|
||||
#define TTL_7411_DIP(_name) \
|
||||
NET_REGISTER_DEV(7411_dip, _name)
|
||||
|
@ -7,6 +7,19 @@
|
||||
|
||||
#include "nld_7420.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7420::truthtable_t nld_7420::m_ttbl;
|
||||
const char *nld_7420::m_desc[] = {
|
||||
"A,B,C,D|Q",
|
||||
"0,X,X,X|1|22",
|
||||
"X,0,X,X|1|22",
|
||||
"X,X,0,X|1|22",
|
||||
"X,X,X,0|1|22",
|
||||
"1,1,1,1|0|15",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
NETLIB_START(7420_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -43,7 +43,12 @@
|
||||
NET_CONNECT(_name, D, _I4)
|
||||
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7420, 4, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7420, 4, 0, 0);
|
||||
#endif
|
||||
|
||||
#define TTL_7420_DIP(_name) \
|
||||
NET_REGISTER_DEV(7420_dip, _name)
|
||||
|
@ -7,6 +7,20 @@
|
||||
|
||||
#include "nld_7427.h"
|
||||
|
||||
#include "nld_7402.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7427::truthtable_t nld_7427::m_ttbl;
|
||||
const char *nld_7427::m_desc[] = {
|
||||
"A,B,C|Q ",
|
||||
"0,0,0|1|22",
|
||||
"1,X,X|0|15",
|
||||
"X,1,X|0|15",
|
||||
"X,X,1|0|15",
|
||||
""
|
||||
};
|
||||
#endif
|
||||
|
||||
NETLIB_START(7427_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -40,7 +40,12 @@
|
||||
NET_CONNECT(_name, B, _I2) \
|
||||
NET_CONNECT(_name, C, _I3)
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7427, 3, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7427, 3, 1, 0);
|
||||
#endif
|
||||
|
||||
#define TTL_7427_DIP(_name) \
|
||||
NET_REGISTER_DEV(7427_dip, _name)
|
||||
|
@ -8,7 +8,9 @@
|
||||
#include "nld_74279.h"
|
||||
|
||||
nld_74279A::truthtable_t nld_74279A::m_ttbl;
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl;
|
||||
|
||||
#if 0
|
||||
const char *nld_74279A::m_desc[] = {
|
||||
"S,R,PQ,PS,PR|Q",
|
||||
"0,0,X,X,X|1|22",
|
||||
@ -19,7 +21,6 @@ const char *nld_74279A::m_desc[] = {
|
||||
""
|
||||
};
|
||||
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl;
|
||||
|
||||
const char *nld_74279B::m_desc[] = {
|
||||
"S1,S2,R,PQ,PS1,PS2,PR|Q",
|
||||
@ -32,6 +33,29 @@ const char *nld_74279B::m_desc[] = {
|
||||
"1,1,1,1,X,X,X|1|22",
|
||||
""
|
||||
};
|
||||
#else
|
||||
const char *nld_74279A::m_desc[] = {
|
||||
"S,R,_Q|Q",
|
||||
"0,X,X|1|22",
|
||||
"1,0,X|0|27",
|
||||
"1,1,0|0|27", //15
|
||||
"1,1,1|1|22",
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
const char *nld_74279B::m_desc[] = {
|
||||
"S1,S2,R,_Q|Q",
|
||||
"0,X,X,X|1|22",
|
||||
"X,0,X,X|1|22",
|
||||
"1,1,0,X|0|27",
|
||||
"1,1,1,0|0|27", // 15
|
||||
"1,1,1,1|1|22",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
NETLIB_START(74279_dip)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
/*
|
||||
* nld_74279.h
|
||||
*
|
||||
* DM74279: Triple 3-Input NAND Gates
|
||||
* DM74279: Quad S-R Latch
|
||||
*
|
||||
* +--------------+
|
||||
* 1R |1 ++ 16| VCC
|
||||
@ -38,9 +38,13 @@
|
||||
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
#if 0
|
||||
NETLIB_TRUTHTABLE(74279A, 2, 1, 1);
|
||||
NETLIB_TRUTHTABLE(74279B, 3, 1, 1);
|
||||
|
||||
#else
|
||||
NETLIB_TRUTHTABLE(74279A, 3, 1, 0);
|
||||
NETLIB_TRUTHTABLE(74279B, 4, 1, 0);
|
||||
#endif
|
||||
#define TTL_74279_DIP(_name) \
|
||||
NET_REGISTER_DEV(74279_dip, _name)
|
||||
|
||||
|
@ -7,6 +7,25 @@
|
||||
|
||||
#include "nld_7430.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7430::truthtable_t nld_7430::m_ttbl;
|
||||
const char *nld_7430::m_desc[] = {
|
||||
"A,B,C,D,E,F,G,H|Q ",
|
||||
"0,X,X,X,X,X,X,X|1|22",
|
||||
"X,0,X,X,X,X,X,X|1|22",
|
||||
"X,X,0,X,X,X,X,X|1|22",
|
||||
"X,X,X,0,X,X,X,X|1|22",
|
||||
"X,X,X,X,0,X,X,X|1|22",
|
||||
"X,X,X,X,X,0,X,X|1|22",
|
||||
"X,X,X,X,X,X,0,X|1|22",
|
||||
"X,X,X,X,X,X,X,0|1|22",
|
||||
"1,1,1,1,1,1,1,1|0|15",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
NETLIB_START(7430_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -51,7 +51,12 @@
|
||||
NET_CONNECT(_name, H, _I8)
|
||||
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7430, 8, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7430, 8, 0, 0);
|
||||
#endif
|
||||
|
||||
#define TTL_7430_DIP(_name) \
|
||||
NET_REGISTER_DEV(7430_dip, _name)
|
||||
|
@ -7,6 +7,18 @@
|
||||
|
||||
#include "nld_7432.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_7432::truthtable_t nld_7432::m_ttbl;
|
||||
const char *nld_7432::m_desc[] = {
|
||||
"A,B|Q ",
|
||||
"1,X|1|22",
|
||||
"0,1|1|22",
|
||||
"0,0|0|15",
|
||||
""
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
NETLIB_START(7432_dip)
|
||||
{
|
||||
register_sub("1", m_1);
|
||||
|
@ -43,7 +43,12 @@
|
||||
NET_REGISTER_DEV(7432_dip, _name)
|
||||
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
NETLIB_TRUTHTABLE(7432, 2, 1, 0);
|
||||
#else
|
||||
NETLIB_SIGNAL(7432, 2, 1, 1);
|
||||
#endif
|
||||
|
||||
NETLIB_DEVICE(7432_dip,
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
#include "nld_9312.h"
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#if (1 && USE_TRUTHTABLE)
|
||||
nld_9312::truthtable_t nld_9312::m_ttbl;
|
||||
|
||||
/* FIXME: Data changes are propagating faster than changing selects A,B,C
|
||||
@ -57,25 +57,26 @@ const char *nld_9312::m_desc[] = {
|
||||
NETLIB_UPDATE(9312)
|
||||
{
|
||||
const UINT8 G = INPLOGIC(m_G);
|
||||
if ((m_last_G ^ G) == 1)
|
||||
if (G)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
|
||||
OUTLOGIC(m_Y, !G, delay[!G]);
|
||||
OUTLOGIC(m_YQ, G, delay[G]);
|
||||
if (G)
|
||||
OUTLOGIC(m_Y, 0, delay[0]);
|
||||
OUTLOGIC(m_YQ, 1, delay[1]);
|
||||
|
||||
m_A.inactivate();
|
||||
m_B.inactivate();
|
||||
m_C.inactivate();
|
||||
m_last_G = G;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_last_G)
|
||||
{
|
||||
m_A.inactivate();
|
||||
m_B.inactivate();
|
||||
m_C.inactivate();
|
||||
} else {
|
||||
m_last_G = G;
|
||||
m_A.activate();
|
||||
m_B.activate();
|
||||
m_C.activate();
|
||||
}
|
||||
m_last_G = G;
|
||||
}
|
||||
if (!G)
|
||||
{
|
||||
static const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
|
||||
const UINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
|
||||
if (m_last_chan != chan)
|
||||
@ -125,7 +126,7 @@ NETLIB_START(9312_dip)
|
||||
{
|
||||
register_sub("1", m_sub);
|
||||
|
||||
#if (USE_TRUTHTABLE)
|
||||
#if (1 && USE_TRUTHTABLE)
|
||||
|
||||
register_subalias("13", m_sub.m_i[0]);
|
||||
register_subalias("12", m_sub.m_i[1]);
|
||||
|
@ -43,6 +43,10 @@
|
||||
NET_REGISTER_DEV(9312, _name)
|
||||
#if (USE_TRUTHTABLE)
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
/* The truthtable implementation is a lot faster than
|
||||
* the carefully crafted code :-(
|
||||
*/
|
||||
NETLIB_TRUTHTABLE(9312, 12, 2, 0);
|
||||
#else
|
||||
|
||||
|
@ -60,7 +60,7 @@ NETLIB_RESET(NE555)
|
||||
m_R3.set_R(5000);
|
||||
m_RDIS.set_R(R_OFF);
|
||||
|
||||
m_last_out = false;
|
||||
m_last_out = true;
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(NE555)
|
||||
|
@ -24,6 +24,35 @@
|
||||
}
|
||||
|
||||
|
||||
static inline UINT32 remove_first_bit(UINT32 v)
|
||||
{
|
||||
for (int i=0; i<32; i++)
|
||||
if (v & (1<<i))
|
||||
return v & ~(1<<i);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline int count_bits(UINT32 v)
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i=0; i<32; i++)
|
||||
if (v & (1<<i))
|
||||
ret++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline UINT32 set_bits(UINT32 v, UINT32 b)
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
for (int i=0; i<32; i++)
|
||||
if (v & (1<<i))
|
||||
{
|
||||
ret |= ((b&1)<<i);
|
||||
b = b >> 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<int m_NI, int m_NO, int has_state>
|
||||
class nld_truthtable_t : public netlist_device_t
|
||||
{
|
||||
@ -36,7 +65,7 @@ public:
|
||||
{
|
||||
truthtable_t() : m_initialized(false) {}
|
||||
UINT32 m_outs[m_size];
|
||||
UINT8 m_timing[m_size][m_NO];
|
||||
UINT8 m_timing[m_size * m_NO];
|
||||
netlist_time m_timing_nt[16];
|
||||
bool m_initialized;
|
||||
};
|
||||
@ -49,22 +78,37 @@ public:
|
||||
ATTR_COLD virtual void start()
|
||||
{
|
||||
pstring ttline = pstring(m_desc[0]);
|
||||
{
|
||||
nl_util::pstring_list io = nl_util::split(ttline,"|");
|
||||
// checks
|
||||
nl_assert_always(io.count() == 2, "too many '|'");
|
||||
nl_util::pstring_list inout = nl_util::split(io[0], ",");
|
||||
nl_assert_always(inout.count() == m_num_bits, "bitcount wrong");
|
||||
nl_util::pstring_list out = nl_util::split(io[1], ",");
|
||||
nl_assert_always(out.count() == m_NO, "output count wrong");
|
||||
|
||||
for (int i=0; i < m_NI; i++)
|
||||
{
|
||||
register_input(inout[i].trim(), m_i[i]);
|
||||
}
|
||||
nl_util::pstring_list io = nl_util::split(ttline,"|");
|
||||
// checks
|
||||
nl_assert_always(io.count() == 2, "too many '|'");
|
||||
nl_util::pstring_list inout = nl_util::split(io[0], ",");
|
||||
nl_assert_always(inout.count() == m_num_bits, "bitcount wrong");
|
||||
nl_util::pstring_list out = nl_util::split(io[1], ",");
|
||||
nl_assert_always(out.count() == m_NO, "output count wrong");
|
||||
|
||||
for (int i=0; i < m_NI; i++)
|
||||
{
|
||||
inout[i] = inout[i].trim();
|
||||
register_input(inout[i], m_i[i]);
|
||||
}
|
||||
for (int i=0; i < m_NO; i++)
|
||||
{
|
||||
out[i] = out[i].trim();
|
||||
register_output(out[i], m_Q[i]);
|
||||
}
|
||||
{
|
||||
// Connect output "Q" to input "_Q" if this exists
|
||||
// This enables timed state without having explicit state ....
|
||||
for (int i=0; i < m_NO; i++)
|
||||
{
|
||||
register_output(out[i].trim(), m_Q[i]);
|
||||
pstring tmp = "_" + out[i];
|
||||
const int idx = inout.indexof(tmp);
|
||||
if (idx>=0)
|
||||
{
|
||||
//printf("connecting %s %d\n", out[i].cstr(), idx);
|
||||
connect(m_Q[i], m_i[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_ign = 0;
|
||||
@ -73,12 +117,11 @@ public:
|
||||
}
|
||||
|
||||
ATTR_COLD void help(int cur, nl_util::pstring_list list,
|
||||
UINT64 state, UINT64 ignore, UINT16 val, UINT8 timing_index[m_NO])
|
||||
UINT64 state,UINT16 val, UINT8 timing_index[m_NO])
|
||||
{
|
||||
pstring elem = list[cur].trim();
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
int ign = 0;
|
||||
|
||||
if (elem.equals("0"))
|
||||
{
|
||||
@ -94,25 +137,23 @@ public:
|
||||
{
|
||||
start = 0;
|
||||
end = 1;
|
||||
ign = 1;
|
||||
}
|
||||
else
|
||||
nl_assert_always(false, "unknown input value (not 0, 1, or X)");
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
const UINT64 nstate = state | (i << cur);
|
||||
const UINT64 nignore = ignore | (ign << cur);
|
||||
|
||||
if (cur < m_num_bits - 1)
|
||||
{
|
||||
help(cur + 1, list, nstate, nignore, val, timing_index);
|
||||
help(cur + 1, list, nstate, val, timing_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// cutoff previous inputs and outputs for ignore
|
||||
m_ttp->m_outs[nstate] = val | ((nignore & ((1 << m_NI)-1)) << m_NO);
|
||||
m_ttp->m_outs[nstate] = val;
|
||||
for (int j=0; j<m_NO; j++)
|
||||
m_ttp->m_timing[nstate][j] = timing_index[j];
|
||||
m_ttp->m_timing[nstate * m_NO + j] = timing_index[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,11 +204,72 @@ public:
|
||||
tindex[j] = k;
|
||||
}
|
||||
|
||||
help(0, inout, 0 , 0 , val, tindex);
|
||||
help(0, inout, 0 , val, tindex);
|
||||
ttline = pstring(truthtable[0]);
|
||||
truthtable++;
|
||||
}
|
||||
|
||||
// ((nignore & ((1 << m_NI)-1)) << m_NO)
|
||||
|
||||
// determine ignore
|
||||
UINT32 ign[m_size];
|
||||
|
||||
for (int i=0; i<m_size; i++)
|
||||
{
|
||||
#if 1
|
||||
UINT32 m_enable = 0;
|
||||
for (int j=0; j<m_size; j++)
|
||||
{
|
||||
if (m_ttp->m_outs[j] != m_ttp->m_outs[i])
|
||||
{
|
||||
m_enable |= (i ^ j);
|
||||
}
|
||||
}
|
||||
ign[i] = m_enable ^ (m_size - 1);
|
||||
#else
|
||||
// this doesn't work in all cases and is dog slow
|
||||
UINT32 nign = 0;
|
||||
for (int j=0; j<m_NI; j++)
|
||||
{
|
||||
if (m_ttp->m_outs[i] == m_ttp->m_outs[i ^ (1 << j)])
|
||||
nign |= (1<<j);
|
||||
}
|
||||
/* Check all permutations of ign
|
||||
*/
|
||||
int t[1<<count_bits(nign)];
|
||||
|
||||
for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
|
||||
{
|
||||
UINT32 tign = set_bits(nign, j);
|
||||
t[j] = 0;
|
||||
for (UINT32 k=0; k<(1<<count_bits(tign)); k++)
|
||||
{
|
||||
UINT32 b=set_bits(tign, k);
|
||||
if (m_ttp->m_outs[i] != m_ttp->m_outs[(i & ~tign) | b])
|
||||
t[j] = 1;
|
||||
}
|
||||
//printf("x %d %d\n", j, tign);
|
||||
}
|
||||
UINT32 jb=0;
|
||||
UINT32 jm=0;
|
||||
for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
|
||||
{
|
||||
int nb = count_bits(j);
|
||||
if ((t[j] == 0)&& (nb>jb))
|
||||
{
|
||||
jb = nb;
|
||||
jm = j;
|
||||
}
|
||||
}
|
||||
ign[i] = set_bits(nign, jm);
|
||||
#endif
|
||||
}
|
||||
for (int i=0; i<m_size; i++)
|
||||
{
|
||||
m_ttp->m_outs[i] |= (ign[i] << m_NO);
|
||||
}
|
||||
#if 0
|
||||
printf("%s\n", name().cstr());
|
||||
for (int j=0; j < m_size; j++)
|
||||
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]);
|
||||
@ -217,14 +319,15 @@ public:
|
||||
if (m_ign & (1 << i))
|
||||
m_i[i].inactivate();
|
||||
|
||||
const UINT32 timebase = nstate * m_NO;
|
||||
if (doOUT)
|
||||
{
|
||||
for (int i = 0; i < m_NO; i++)
|
||||
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[nstate][i]]);
|
||||
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < m_NO; i++)
|
||||
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[nstate][i]]);
|
||||
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -386,8 +386,12 @@ ATTR_COLD void netlist_core_device_t::init(netlist_base_t &anetlist, const pstri
|
||||
|
||||
#if USE_PMFDELEGATES
|
||||
void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update;
|
||||
#if NO_USE_PMFCONVERSION
|
||||
static_update = pFunc;
|
||||
#else
|
||||
static_update = reinterpret_cast<net_update_delegate>((this->*pFunc));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -1019,7 +1023,10 @@ ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, co
|
||||
return atof(tmp.cstr()) * factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr());
|
||||
return defval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,8 +173,12 @@
|
||||
class netlist_core_device_t;
|
||||
|
||||
#if USE_PMFDELEGATES
|
||||
#if NO_USE_PMFCONVERSION
|
||||
typedef void (netlist_core_device_t::*net_update_delegate)();
|
||||
#else
|
||||
typedef void (*net_update_delegate)(netlist_core_device_t *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// MACROS / netlist devices
|
||||
@ -972,7 +976,11 @@ public:
|
||||
begin_timing(stat_total_time);
|
||||
inc_stat(stat_update_count);
|
||||
#if USE_PMFDELEGATES
|
||||
#if NO_USE_PMFCONVERSION
|
||||
(this->*static_update)();
|
||||
#else
|
||||
static_update(this);
|
||||
#endif
|
||||
#else
|
||||
update();
|
||||
#endif
|
||||
|
@ -23,13 +23,28 @@
|
||||
|
||||
/*
|
||||
* The next options needs -Wno-pmf-conversions to compile and gcc
|
||||
* This is intended for non-mame usage.
|
||||
* There is quite some significant speed-up of up to 20% involved.
|
||||
* NO_USE_PMFCONVERSION is for illustrative purposes only. Using PMFs
|
||||
* has some overhead in comparison to calling a virtual function.
|
||||
*
|
||||
* To get a performance increase we need the GCC extension.
|
||||
*
|
||||
*/
|
||||
#define USE_PMFDELEGATES (0)
|
||||
|
||||
#if (USE_PMFDELEGATES)
|
||||
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
||||
#ifndef USE_PMFDELEGATES
|
||||
#if defined(__clang__)
|
||||
#define USE_PMFDELEGATES (0)
|
||||
#define NO_USE_PMFCONVERSION (1)
|
||||
#else
|
||||
#if defined(__GNUC__)
|
||||
#define USE_PMFDELEGATES (1)
|
||||
#define NO_USE_PMFCONVERSION (0)
|
||||
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
||||
#else
|
||||
#define USE_PMFDELEGATES (0)
|
||||
#define NO_USE_PMFCONVERSION (1)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -44,7 +59,7 @@
|
||||
// moved to parameter NETLIST.USE_DEACTIVATE
|
||||
// #define USE_DEACTIVE_DEVICE (0)
|
||||
|
||||
#define USE_TRUTHTABLE (0)
|
||||
#define USE_TRUTHTABLE (1)
|
||||
|
||||
// The following adds about 10% performance ...
|
||||
|
||||
|
@ -114,7 +114,7 @@ CIRCUIT_LAYOUT( breakout )
|
||||
// FIXME: PARALLEL Doesn't work in breakout.
|
||||
PARAM(Solver.PARALLEL, 0)
|
||||
#endif
|
||||
//PARAM(NETLIST.USE_DEACTIVATE, 1)
|
||||
PARAM(NETLIST.USE_DEACTIVATE, 1)
|
||||
|
||||
// DIPSWITCH - Free game
|
||||
SWITCH(S1_1)
|
||||
|
@ -14,6 +14,7 @@ NETLIST_START(pong_fast)
|
||||
PARAM(Solver.PARALLEL, 0) // Don't do parallel solvers
|
||||
PARAM(Solver.ACCURACY, 1e-4) // works and is sufficient
|
||||
PARAM(Solver.LTE, 1e-4) // Default is not enough for paddle control if using LTE
|
||||
PARAM(NETLIST.USE_DEACTIVATE, 1)
|
||||
|
||||
ANALOG_INPUT(V5, 5)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user