diff options
| author | 2016-07-01 02:09:14 +0200 | |
|---|---|---|
| committer | 2016-07-01 02:09:14 +0200 | |
| commit | caafc0f7823054c21a67f096650b2f4a333469c3 (patch) | |
| tree | bff4849aa0c539fa0cc06ed630f83fd949e37ebc | |
| parent | 1f0dc8903f8b865107af2e74758b0ad042c2a8b5 (diff) | |
Netlist improvements:
- nltool now accepts -Ddefine=value to pass on to netlists
- improved option handling and added "dummy" options to add grouping and
examples in help output.
- improved --cmd=listdevices output
- Fix dynamic timestepping. This will work with breakout using real
capacitor modelling instead of delay devices. Really slow, but very
useful to calibrate timings.
- Fix an awful bug in timing for delay devices.
- Switched to clang 3.8 and made code compile with
-Weverything -Werror -Wno-old-style-cast -Wno-padded -Wno-weak-vtables
-Wno-missing-variable-declarations -Wno-conversion -Wno-c++98-compat
-Wno-float-equal -Wno-cast-align -Wno-global-constructors
-Wno-c++98-compat-pedantic -Wno-exit-time-destructors
-Wno-format-nonliteral -Wno-weak-template-vtables
This was a helpful exercise since it brought forward some
serious issues with implicit constructors.
[Couriersud]
39 files changed, 452 insertions, 288 deletions
diff --git a/nl_examples/cdelay.c b/nl_examples/cdelay.c index 927a7cfe0a4..d6d3f614478 100644 --- a/nl_examples/cdelay.c +++ b/nl_examples/cdelay.c @@ -17,8 +17,15 @@ NETLIST_START(perf) NETLIST_END() +#ifndef P_FREQ +#define P_FREQ 4800 +#endif -NETLIST_START(7400_astable) +#ifndef P_DTS +#define P_DTS 1 +#endif + +NETLIST_START(cap_delay) /* * delay circuit @@ -27,18 +34,20 @@ NETLIST_START(7400_astable) /* Standard stuff */ - SOLVER(Solver, 48000) + SOLVER(Solver, P_FREQ) PARAM(Solver.ACCURACY, 1e-20) + PARAM(Solver.DYNAMIC_TS, P_DTS) + PARAM(Solver.MIN_TIMESTEP, 1e-6) CLOCK(clk, 5000) TTL_7400_NAND(n1,clk,clk) - CAP(C, 1e-9) + CAP(C, 1e-6) NET_C(n1.Q, C.2) NET_C(GND, C.1) TTL_7400_NAND(n2,n1.Q, n1.Q) LOG(logclk, clk) LOG(logn1Q, C.2) - LOG(logn2Q, n2.Q) + LOG(logn2Q, n1.Q) NETLIST_END() diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index b924e052e50..0fa446aa897 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -676,11 +676,7 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre bool netlist_source_memregion_t::parse(netlist::setup_t &setup, const pstring &name) { - // FIXME: preprocessor should be a stream! memory_region *mem = downcast<netlist_mame_t &>(setup.netlist()).machine().root_device().memregion(m_name.cstr()); plib::pimemstream istrm(mem->base(),mem->bytes() ); - plib::pomemstream ostrm; - - plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm)); - return netlist::parser_t(istrm2, setup).parse(name); + return setup.parse_stream(istrm, name); } diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 7a5e88a5e4c..8b7bc4b2c12 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -14,14 +14,15 @@ SRC = .. #-fuse-ld=gold -Wpedantic -march=native -march=native -LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr +# LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr -CDEFS = -DPSTANDALONE=1 -DPTR64=1 #-Werror #CFLAGS = $(LTO) -g -O3 -std=c++98 -Doverride="" -march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra -Wno-long-long -Wno-unused-parameter -Wno-unused-result -Wno-variadic-macros -I.. #LDFLAGS = $(LTO) -g -O3 -std=c++98 -CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter -LDFLAGS = $(LTO) -g -O3 -std=c++11 -lpthread -ldl + +CFLAGS = $(CEXTRAFLAGS) $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter +LDFLAGS = $(LTO) -g -O3 -std=c++11 +LIBS = -lpthread -ldl CC = g++-5 LD = @g++-5 @@ -125,11 +126,11 @@ clean: nltool: $(OBJ)/prg/nltool.o $(OBJS) @echo Linking $@... - $(LD) -o $@ $(LDFLAGS) $^ $(LIBS) + @$(LD) -o $@ $(LDFLAGS) $^ $(LIBS) nlwav: $(OBJ)/prg/nlwav.o $(OBJS) @echo Linking $@... - $(LD) -o $@ $(LDFLAGS) $^ $(LIBS) + @$(LD) -o $@ $(LDFLAGS) $^ $(LIBS) #------------------------------------------------- # directories @@ -156,6 +157,17 @@ depend: .depend -include .depend #------------------------------------------------- +# Special targets +#------------------------------------------------- + +.PHONY: clang +clang: + $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables" + +# -Wno-old-style-cast +# FIX: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-old-style-cast -Wno-exit-time-destructors + +#------------------------------------------------- # generic rules #------------------------------------------------- @@ -163,11 +175,11 @@ $(OBJ)/%.o: $(SRC)/%.cpp @echo Compiling $<... @$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@ -$(OBJ)/%.pp: $(SRC)/%.cpp | $(OSPREBUILD) +$(OBJ)/%.pp: $(SRC)/%.cpp @echo Compiling $<... @$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@ -$(OBJ)/%.s: $(SRC)/%.cpp | $(OSPREBUILD) +$(OBJ)/%.s: $(SRC)/%.cpp @echo Compiling $<... @$(CC) $(CDEFS) $(CFLAGS) -S $< -o $@ diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index 701bcd8dbbc..3f41d6b9daf 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -71,7 +71,8 @@ namespace netlist { namespace devices { -void initialize_factory(factory_list_t &factory) + +static void initialize_factory(factory_list_t &factory) { ENTRY(R, RES, "R") ENTRY(POT, POT, "R") diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index 4fc78357e84..33b78ddf1b7 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -55,7 +55,7 @@ namespace netlist if (R > NL_FCONST(0.0)) { // We only need to update the net first if this is a time stepping net - if (1) // m_R.m_P.net().as_analog().solver().is_timestep()) + if ((1)) // m_R.m_P.net().as_analog().solver().is_timestep()) { m_R.update_dev(); m_R.set_R(R); diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index 8aa623ffd1e..5f45b330b61 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -10,9 +10,6 @@ #include "nlid_system.h" #include "analog/nld_twoterm.h" -#define R_OFF (1E20) -#define R_ON (m_RI.Value()) - namespace netlist { namespace devices diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 66d3a6ddaf4..e7b95549d47 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -159,7 +159,7 @@ namespace netlist { if (m_loadq) { - switch (m_cnt) + switch (m_cnt()) { case MAXCNT - 1: m_cnt = MAXCNT; diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 3775cc90902..6af7ef2eda9 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -162,7 +162,7 @@ namespace netlist { if (m_loadq) { - switch (m_cnt) + switch (m_cnt()) { case MAXCNT - 1: m_cnt = MAXCNT; diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 90364c58a6a..b692b60506a 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -133,7 +133,7 @@ namespace netlist const nl_double R = state ? m_RON.Value() : m_ROFF.Value(); // We only need to update the net first if this is a time stepping net - if (0) // m_R->m_P.net().as_analog().solver()->is_timestep()) + if ((0)) // m_R->m_P.net().as_analog().solver()->is_timestep()) { m_R.update_dev(); m_R.set_R(R); diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp index 22520b61882..be80b72fdce 100644 --- a/src/lib/netlist/devices/nld_truthtable.cpp +++ b/src/lib/netlist/devices/nld_truthtable.cpp @@ -229,7 +229,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_lea if (ign[i] == all_set) { int tign; - if (0) + if ((0)) { tign = get_ignored_simple(i); ign[i] = tign; diff --git a/src/lib/netlist/devices/nlid_cmos.h b/src/lib/netlist/devices/nlid_cmos.h index 74482c85046..758cafa3029 100644 --- a/src/lib/netlist/devices/nlid_cmos.h +++ b/src/lib/netlist/devices/nlid_cmos.h @@ -22,8 +22,8 @@ namespace netlist { } - NETLIB_UPDATEI() {}; - NETLIB_RESETI() {}; + NETLIB_UPDATEI() {} + NETLIB_RESETI() {} public: inline nl_double vdd() { return INPANALOG(m_vdd); } diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp index d622881abb4..95fff085b9e 100644 --- a/src/lib/netlist/macro/nlm_cd4xxx.cpp +++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp @@ -22,7 +22,7 @@ * */ -NETLIST_START(CD4001_DIP) +static NETLIST_START(CD4001_DIP) CD4001_NOR(s1) CD4001_NOR(s2) CD4001_NOR(s3) @@ -63,7 +63,7 @@ NETLIST_END() * This needs a cmos d-a/a-d proxy implementation. */ -NETLIST_START(CD4020_DIP) +static NETLIST_START(CD4020_DIP) CD4020(s1) DIPPINS( /* +--------------+ */ @@ -101,7 +101,7 @@ NETLIST_END() * */ -NETLIST_START(CD4066_DIP) +static NETLIST_START(CD4066_DIP) CD4066_GATE(A) CD4066_GATE(B) CD4066_GATE(C) @@ -127,7 +127,7 @@ NETLIST_START(CD4066_DIP) ) NETLIST_END() -NETLIST_START(CD4016_DIP) +static NETLIST_START(CD4016_DIP) CD4066_GATE(A) CD4066_GATE(B) CD4066_GATE(C) diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp index c3a932c0a35..e7571dfd910 100644 --- a/src/lib/netlist/macro/nlm_opamp.cpp +++ b/src/lib/netlist/macro/nlm_opamp.cpp @@ -9,7 +9,7 @@ * Generic layout with 4 opamps, VCC on pint 4 and GND on pin 11 */ -NETLIST_START(opamp_layout_4_4_11) +static NETLIST_START(opamp_layout_4_4_11) DIPPINS( /* +--------------+ */ A.OUT, /* |1 ++ 14| */ D.OUT, A.MINUS, /* |2 13| */ D.MINUS, @@ -28,7 +28,7 @@ NETLIST_END() * Generic layout with 2 opamps, VCC on pint 8 and GND on pin 4 */ -NETLIST_START(opamp_layout_2_8_4) +static NETLIST_START(opamp_layout_2_8_4) DIPPINS( /* +--------------+ */ A.OUT, /* |1 ++ 8| */ A.VCC, A.MINUS, /* |2 7| */ B.OUT, @@ -40,7 +40,7 @@ NETLIST_START(opamp_layout_2_8_4) NET_C(A.VCC, B.VCC) NETLIST_END() -NETLIST_START(MB3614_DIP) +static NETLIST_START(MB3614_DIP) OPAMP(A, "MB3614") OPAMP(B, "MB3614") OPAMP(C, "MB3614") @@ -50,7 +50,7 @@ NETLIST_START(MB3614_DIP) NETLIST_END() -NETLIST_START(LM324_DIP) +static NETLIST_START(LM324_DIP) OPAMP(A, "LM324") OPAMP(B, "LM324") OPAMP(C, "LM324") @@ -60,7 +60,7 @@ NETLIST_START(LM324_DIP) NETLIST_END() -NETLIST_START(LM358_DIP) +static NETLIST_START(LM358_DIP) OPAMP(A, "LM358") OPAMP(B, "LM358") diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp index 6fd73a29fe8..68c0ea57d36 100644 --- a/src/lib/netlist/macro/nlm_other.cpp +++ b/src/lib/netlist/macro/nlm_other.cpp @@ -21,7 +21,7 @@ * */ -NETLIST_START(MC14584B_DIP) +static NETLIST_START(MC14584B_DIP) MC14584B_GATE(s1) MC14584B_GATE(s2) MC14584B_GATE(s3) diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp index 314ba84062c..646ae44a86b 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.cpp +++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp @@ -24,7 +24,7 @@ * */ -NETLIST_START(TTL_7400_DIP) +static NETLIST_START(TTL_7400_DIP) TTL_7400_GATE(s1) TTL_7400_GATE(s2) TTL_7400_GATE(s3) @@ -62,7 +62,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7402_DIP) +static NETLIST_START(TTL_7402_DIP) TTL_7402_GATE(s1) TTL_7402_GATE(s2) TTL_7402_GATE(s3) @@ -98,7 +98,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7404_DIP) +static NETLIST_START(TTL_7404_DIP) TTL_7404_GATE(s1) TTL_7404_GATE(s2) TTL_7404_GATE(s3) @@ -139,7 +139,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7408_DIP) +static NETLIST_START(TTL_7408_DIP) TTL_7408_GATE(s1) TTL_7408_GATE(s2) TTL_7408_GATE(s3) @@ -177,7 +177,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7410_DIP) +static NETLIST_START(TTL_7410_DIP) TTL_7410_GATE(s1) TTL_7410_GATE(s2) TTL_7410_GATE(s3) @@ -214,7 +214,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7411_DIP) +static NETLIST_START(TTL_7411_DIP) TTL_7411_GATE(s1) TTL_7411_GATE(s2) TTL_7411_GATE(s3) @@ -240,7 +240,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7416_DIP) +static NETLIST_START(TTL_7416_DIP) TTL_7416_GATE(s1) TTL_7416_GATE(s2) TTL_7416_GATE(s3) @@ -281,7 +281,7 @@ NETLIST_END() * Naming conventions follow National Semiconductor datasheet * */ -NETLIST_START(TTL_7420_DIP) +static NETLIST_START(TTL_7420_DIP) TTL_7420_GATE(s1) TTL_7420_GATE(s2) @@ -323,7 +323,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7425_DIP) +static NETLIST_START(TTL_7425_DIP) TTL_7425_GATE(s1) TTL_7425_GATE(s2) @@ -361,7 +361,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7427_DIP) +static NETLIST_START(TTL_7427_DIP) TTL_7427_GATE(s1) TTL_7427_GATE(s2) TTL_7427_GATE(s3) @@ -402,7 +402,7 @@ NETLIST_END() * Naming conventions follow National Semiconductor datasheet */ -NETLIST_START(TTL_7430_DIP) +static NETLIST_START(TTL_7430_DIP) TTL_7430_GATE(s1) DUMMY_INPUT(GND) @@ -439,7 +439,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7432_DIP) +static NETLIST_START(TTL_7432_DIP) TTL_7432_GATE(s1) TTL_7432_GATE(s2) TTL_7432_GATE(s3) @@ -481,7 +481,7 @@ NETLIST_END() * Netlist currently does not model over currents (should it ever?) */ -NETLIST_START(TTL_7437_DIP) +static NETLIST_START(TTL_7437_DIP) TTL_7437_GATE(s1) TTL_7437_GATE(s2) TTL_7437_GATE(s3) @@ -519,7 +519,7 @@ NETLIST_END() * */ -NETLIST_START(TTL_7486_DIP) +static NETLIST_START(TTL_7486_DIP) TTL_7486_GATE(s1) TTL_7486_GATE(s2) TTL_7486_GATE(s3) diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index b08ce88eb02..d31c39f2eda 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -273,8 +273,9 @@ namespace netlist class fatalerror_e : public plib::pexception { public: - fatalerror_e(const pstring &text) : plib::pexception(text) { } - virtual ~fatalerror_e() throw() {} + explicit fatalerror_e(const pstring text) : plib::pexception(text) { } + fatalerror_e(const fatalerror_e &e) : plib::pexception(e) { } + virtual ~fatalerror_e() noexcept {} }; class logic_output_t; @@ -663,6 +664,7 @@ namespace netlist bool is_analog() const; void toggle_new_Q() { m_new_Q ^= 1; } + void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); } void push_to_queue(const netlist_time delay) NOEXCEPT; void reschedule_in_queue(const netlist_time delay) NOEXCEPT; @@ -711,7 +713,7 @@ namespace netlist public: logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); - virtual ~logic_net_t() { }; + virtual ~logic_net_t() { } netlist_sig_t Q() const { return m_cur_Q; } netlist_sig_t new_Q() const { return m_new_Q; } @@ -755,7 +757,7 @@ namespace netlist analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); - virtual ~analog_net_t() { }; + virtual ~analog_net_t() { } nl_double Q_Analog() const { return m_cur_Analog; } nl_double &Q_Analog_state_ptr() { return m_cur_Analog; } @@ -1139,11 +1141,11 @@ namespace netlist template<typename O, typename C> void save(O &owner, C &state, const pstring &stname) { - this->state().save_item((void *)&owner, state, pstring(owner.name()) + "." + stname); + this->state().save_item(static_cast<void *>(&owner), state, pstring(owner.name()) + "." + stname); } template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const int count) { - this->state().save_state_ptr((void *)&owner, pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state); + this->state().save_state_ptr(static_cast<void *>(&owner), pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state); } virtual void reset(); @@ -1160,13 +1162,6 @@ namespace netlist /* sole use is to manage lifetime of family objects */ std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache; - protected: - - // performance - nperfcount_t m_perf_out_processed; - nperfcount_t m_perf_inp_processed; - nperfcount_t m_perf_inp_active; - private: plib::state_manager_t m_state; /* mostly rw */ @@ -1185,6 +1180,11 @@ namespace netlist setup_t *m_setup; plib::plog_base<NL_DEBUG> m_log; plib::dynlib *m_lib; // external lib needs to be loaded as long as netlist exists + + // performance + nperfcount_t m_perf_out_processed; + nperfcount_t m_perf_inp_processed; + nperfcount_t m_perf_inp_active; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h index e163b637f4c..5923ebdd10c 100644 --- a/src/lib/netlist/nl_dice_compat.h +++ b/src/lib/netlist/nl_dice_compat.h @@ -105,7 +105,7 @@ public: }; #else -#define CHIP(n, t) TTL_ ## t ## DIP(n) +#define CHIP(n, t) TTL_ ## t ## _DIP(n) #define OHM(x) x #define K_OHM(x) RES_K(X) @@ -200,8 +200,8 @@ inline int CAPACITOR_tc_hl(const double c, const double r) * Vt = (VH-VL)*exp(-t/RC) * ln(Vt/(VH-VL))*RC = -t */ - static const double TIME_CONSTANT = -std::log(2.0 / (3.7-0.3)); - int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9); + static const double TIME_CONSTANT = -std::log(0.8 / (4.0-0.1)); + int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9); return ret; } @@ -211,14 +211,30 @@ inline int CAPACITOR_tc_lh(const double c, const double r) * Vt = (VH-VL)*(1-exp(-t/RC)) * -t=ln(1-Vt/(VH-VL))*RC */ - static const double TIME_CONSTANT = -std::log(1.0 - 0.8 / (3.7-0.3)); - int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9); + static const double TIME_CONSTANT = -std::log(1.0 - 2.0 / (4.0-0.1)); + int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9); return ret; } +#if 1 #define CHIP_CAPACITOR(name, pdesc) \ NETDEV_DELAY(name) \ NETDEV_PARAMI(name, L_TO_H, CAPACITOR_tc_lh((pdesc)->c, (pdesc)->r)) \ NETDEV_PARAMI(name, H_TO_L, CAPACITOR_tc_hl((pdesc)->c, (pdesc)->r)) +#elif 1 +// slow, very slow +#define CHIP_CAPACITOR(name, pdesc) \ + CAP(name ## _C, (pdesc)->c) \ + ALIAS(name.1, name ## _C.1 ) \ + ALIAS(name.2, name ## _C.1) \ + NET_C(GND, name ## _C.2) +#else +// fast, might work +#define CHIP_CAPACITOR(name, pdesc) \ + RES(name ## _C, RES_K(1000)) \ + ALIAS(name.1, name ## _C.1 ) \ + ALIAS(name.2, name ## _C.1) \ + NET_C(GND, name ## _C.2) +#endif #endif /* NL_DICE_COMPAT_H_ */ diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 99fb8962546..afa4545e3b7 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -223,8 +223,8 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) static_cast<param_str_t &>(param).initial(val); } break; - default: - log().fatal("Parameter is not supported {1} : {2}\n", name, val); + //default: + // log().fatal("Parameter is not supported {1} : {2}\n", name, val); } } if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) @@ -1002,6 +1002,23 @@ void setup_t::include(const pstring &netlist_name) log().fatal("unable to find {1} in source collection", netlist_name); } +bool setup_t::parse_stream(plib::pistream &istrm, const pstring &name) +{ + plib::pomemstream ostrm; + + plib::pimemstream istrm2(plib::ppreprocessor(&m_defines).process(istrm, ostrm)); + return parser_t(istrm2, *this).parse(name); +} + +void setup_t::register_define(pstring defstr) +{ + auto p = defstr.find("="); + if (p>0) + register_define(defstr.left(p), defstr.substr(p+1)); + else + register_define(defstr, "1"); +} + // ---------------------------------------------------------------------------------------- // base sources // ---------------------------------------------------------------------------------------- @@ -1009,28 +1026,19 @@ void setup_t::include(const pstring &netlist_name) bool source_string_t::parse(setup_t &setup, const pstring &name) { plib::pimemstream istrm(m_str.cstr(), m_str.len()); - plib::pomemstream ostrm; - - plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm)); - return parser_t(istrm2, setup).parse(name); + return setup.parse_stream(istrm, name); } bool source_mem_t::parse(setup_t &setup, const pstring &name) { plib::pimemstream istrm(m_str.cstr(), m_str.len()); - plib::pomemstream ostrm; - - plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm)); - return parser_t(istrm2, setup).parse(name); + return setup.parse_stream(istrm, name); } bool source_file_t::parse(setup_t &setup, const pstring &name) { plib::pifilestream istrm(m_filename); - plib::pomemstream ostrm; - - plib::pimemstream istrm2(plib::ppreprocessor().process(istrm, ostrm)); - return parser_t(istrm2, setup).parse(name); + return setup.parse_stream(istrm, name); } } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index a4e0c7ade05..85dc1eb4fd5 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -16,7 +16,9 @@ #include "plib/pstring.h" #include "plib/palloc.h" #include "plib/pfmtlog.h" +#include "plib/pstream.h" #include "plib/putil.h" +#include "plib/pparser.h" #include "nl_config.h" #include "nl_base.h" #include "nl_factory.h" @@ -156,6 +158,7 @@ namespace netlist virtual ~source_t() { } virtual bool parse(setup_t &setup, const pstring &name) = 0; + private: }; @@ -222,6 +225,8 @@ namespace netlist void include(const pstring &netlist_name); + bool parse_stream(plib::pistream &istrm, const pstring &name); + /* register a source */ void register_source(std::unique_ptr<source_t> &&src) @@ -229,6 +234,9 @@ namespace netlist m_sources.push_back(std::move(src)); } + void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); } + void register_define(pstring defstr); + factory_list_t &factory() { return m_factory; } const factory_list_t &factory() const { return m_factory; } @@ -251,6 +259,9 @@ namespace netlist void tt_factory_create(tt_desc &desc); + /* helper - also used by nltool */ + const pstring resolve_alias(const pstring &name) const; + protected: private: @@ -267,7 +278,6 @@ namespace netlist // helpers pstring objtype_as_str(device_object_t &in) const; - const pstring resolve_alias(const pstring &name) const; devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out); netlist_t &m_netlist; @@ -290,6 +300,7 @@ namespace netlist std::stack<pstring> m_namespace_stack; source_t::list_t m_sources; + std::vector<plib::ppreprocessor::define_t> m_defines; std::vector<pstring> m_lib; }; diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp index 557e285bf6b..f7a9117f503 100644 --- a/src/lib/netlist/plib/palloc.cpp +++ b/src/lib/netlist/plib/palloc.cpp @@ -15,7 +15,7 @@ namespace plib { // Exceptions //============================================================ -pexception::pexception(const pstring &text) +pexception::pexception(const pstring text) { m_text = text; fprintf(stderr, "%s\n", m_text.cstr()); diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index 8b49d4367b1..5b734785145 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -24,8 +24,10 @@ namespace plib { class pexception : public std::exception { public: - pexception(const pstring &text); - virtual ~pexception() throw() {} + explicit pexception(const pstring text); + pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; } + + virtual ~pexception() noexcept {} const pstring &text() { return m_text; } diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 79fa94da2aa..6fa7ac55776 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -277,7 +277,7 @@ public: error(proxy), fatal(proxy) {} - virtual ~plog_base() {}; + virtual ~plog_base() {} plog_channel<plog_level::DEBUG, debug_enabled> debug; plog_channel<plog_level::INFO> info; diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index e01169f5264..e6bc45d15eb 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -12,17 +12,18 @@ namespace plib { Options ***************************************************************************/ - option::option() - : m_short(""), m_long(""), m_help(""), m_has_argument(false) - {} - - option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument) - : m_short(ashort), m_long(along), m_help(help), m_has_argument(has_argument) + option_base::option_base(options &parent, pstring help) + : m_help(help) { parent.register_option(this); } - option::~option() + option_base::~option_base() + { + } + + option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument) + : option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument) { } @@ -56,6 +57,13 @@ namespace plib { return (err ? 1 : 0); } + int option_vec::parse(pstring argument) + { + bool err = false; + m_val.push_back(argument); + return (err ? 1 : 0); + } + options::options() { } @@ -75,7 +83,7 @@ namespace plib { m_opts.clear(); } - void options::register_option(option *opt) + void options::register_option(option_base *opt) { m_opts.push_back(opt); } @@ -96,11 +104,21 @@ namespace plib { auto v = pstring_vector_t(arg.substr(2),"="); opt = getopt_long(v[0]); has_equal_arg = (v.size() > 1); - if (has_equal_arg) opt_arg = v[1]; + if (has_equal_arg) + { + for (unsigned j = 1; j < v.size() - 1; j++) + opt_arg = opt_arg + v[j] + "="; + opt_arg += v[v.size()-1]; + } } else if (arg.startsWith("-")) { - opt = getopt_short(arg.substr(1)); + opt = getopt_short(arg.substr(1,1)); + if (arg.len() > 2) + { + has_equal_arg = true; + opt_arg = arg.substr(2); + } } else return i; @@ -131,21 +149,21 @@ namespace plib { return argc; } - pstring options::split_paragraphs(pstring text, unsigned width, unsigned ident, - unsigned firstline_ident) + pstring options::split_paragraphs(pstring text, unsigned width, unsigned indent, + unsigned firstline_indent) { auto paragraphs = pstring_vector_t(text,"\n"); pstring ret(""); for (auto &p : paragraphs) { - pstring line = pstring("").rpad(" ", firstline_ident); + pstring line = pstring("").rpad(" ", firstline_indent); for (auto &s : pstring_vector_t(p, " ")) { if (line.len() + s.len() > width) { ret += line + "\n"; - line = pstring("").rpad(" ", ident); + line = pstring("").rpad(" ", indent); } line += s + " "; } @@ -155,67 +173,91 @@ namespace plib { } pstring options::help(pstring description, pstring usage, - unsigned width, unsigned ident) + unsigned width, unsigned indent) { pstring ret; ret = split_paragraphs(description, width, 0, 0) + "\n"; - ret += "Usage:\t" + usage + "\n\nOptions:\n"; + ret += "Usage:\t" + usage + "\n\nOptions:\n\n"; - for (auto & opt : m_opts ) + for (auto & optbase : m_opts ) { - pstring line = ""; - if (opt->short_opt() != "") - line += " -" + opt->short_opt(); - if (opt->long_opt() != "") + if (auto opt = dynamic_cast<option *>(optbase)) { - if (line != "") - line += ", "; - else - line = " "; - line += "--" + opt->long_opt(); - if (opt->has_argument()) + pstring line = ""; + if (opt->short_opt() != "") + line += " -" + opt->short_opt(); + if (opt->long_opt() != "") { - line += "="; - option_str_limit *ol = dynamic_cast<option_str_limit *>(opt); - if (ol) + if (line != "") + line += ", "; + else + line = " "; + line += "--" + opt->long_opt(); + if (opt->has_argument()) { - for (auto &v : ol->limit()) + line += "="; + option_str_limit *ol = dynamic_cast<option_str_limit *>(opt); + if (ol) { - line += v + "|"; + for (auto &v : ol->limit()) + { + line += v + "|"; + } + line = line.left(line.len() - 1); } - line = line.left(line.len() - 1); + else + line += "Value"; } - else - line += "Value"; } + line = line.rpad(" ", indent - 2) + " "; + if (line.len() > indent) + { + //ret += "TestGroup abc\n def gef\nxyz\n\n" ; + ret += line + "\n"; + ret += split_paragraphs(opt->help(), width, indent, indent); + } + else + ret += split_paragraphs(line + opt->help(), width, indent, 0); } - line = line.rpad(" ", 20) + " "; - if (line.len() > 21) + else if (auto grp = dynamic_cast<option_group *>(optbase)) { - ret += line + "\n"; - ret += split_paragraphs(opt->help(), 72, 21, 21); + ret += "\n" + grp->group() + ":\n"; + if (grp->help() != "") ret += split_paragraphs(grp->help(), width, 4, 4) + "\n"; } - else - ret += split_paragraphs(line + opt->help(), 72, 21, 0); + } + pstring ex(""); + for (auto & optbase : m_opts ) + { + if (auto example = dynamic_cast<option_example *>(optbase)) + { + ex += "> " + example->example()+"\n\n"; + ex += split_paragraphs(example->help(), width, 4, 4) + "\n"; + } + } + if (ex.len() > 0) + { + ret += "\n\nExamples:\n\n" + ex; } return ret; } option *options::getopt_short(pstring arg) { - for (auto & opt : m_opts) + for (auto & optbase : m_opts) { - if (opt->short_opt() == arg) + auto opt = dynamic_cast<option *>(optbase); + if (opt && opt->short_opt() == arg) return opt; } return nullptr; } option *options::getopt_long(pstring arg) { - for (auto & opt : m_opts) + for (auto & optbase : m_opts) { - if (opt->long_opt() == arg) + auto opt = dynamic_cast<option *>(optbase); + if (opt && opt->long_opt() == arg) return opt; } return nullptr; diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index f9ac17832d3..3fac79b58ef 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -23,13 +23,44 @@ namespace plib { class options; -class option +class option_base { public: - option(); - option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument); + option_base(options &parent, pstring help); + virtual ~option_base(); + + pstring help() { return m_help; } +private: + pstring m_help; +}; + +class option_group : public option_base +{ +public: + option_group(options &parent, pstring group, pstring help) + : option_base(parent, help), m_group(group) { } - virtual ~option(); + pstring group() { return m_group; } +private: + pstring m_group; +}; + +class option_example : public option_base +{ +public: + option_example(options &parent, pstring group, pstring help) + : option_base(parent, help), m_example(group) { } + + pstring example() { return m_example; } +private: + pstring m_example; +}; + + +class option : public option_base +{ +public: + option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument); /* no_argument options will be called with "" argument */ @@ -37,12 +68,10 @@ public: pstring short_opt() { return m_short; } pstring long_opt() { return m_long; } - pstring help() { return m_help; } bool has_argument() { return m_has_argument ; } private: pstring m_short; pstring m_long; - pstring m_help; bool m_has_argument; }; @@ -105,6 +134,20 @@ private: double m_val; }; +class option_vec : public option +{ +public: + option_vec(options &parent, pstring ashort, pstring along, pstring help) + : option(parent, ashort, along, help, true) + {} + + virtual int parse(pstring argument) override; + + std::vector<pstring> operator ()() { return m_val; } +private: + std::vector<pstring> m_val; +}; + class options { public: @@ -114,22 +157,22 @@ public: ~options(); - void register_option(option *opt); + void register_option(option_base *opt); int parse(int argc, char *argv[]); pstring help(pstring description, pstring usage, - unsigned width = 72, unsigned ident = 20); + unsigned width = 72, unsigned indent = 20); pstring app() { return m_app; } private: - static pstring split_paragraphs(pstring text, unsigned width, unsigned ident, - unsigned firstline_ident); + static pstring split_paragraphs(pstring text, unsigned width, unsigned indent, + unsigned firstline_indent); option *getopt_short(pstring arg); option *getopt_long(pstring arg); - std::vector<option *> m_opts; + std::vector<option_base *> m_opts; pstring m_app; }; diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 6c0fa79d7e4..468fb90a1f6 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -253,7 +253,7 @@ void ptokenizer::error(const pstring &errs) // A simple preprocessor // ---------------------------------------------------------------------------------------- -ppreprocessor::ppreprocessor() +ppreprocessor::ppreprocessor(std::vector<define_t> *defines) : m_ifflag(0), m_level(0), m_lineno(0) { m_expr_sep.push_back("!"); @@ -268,6 +268,13 @@ ppreprocessor::ppreprocessor() m_expr_sep.push_back("\t"); m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); + if (defines != nullptr) + { + for (auto & p : *defines) + { + m_defines.insert({p.m_name, p}); + } + } } void ppreprocessor::error(const pstring &err) diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index acddc755434..30a00514840 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -158,7 +158,6 @@ public: struct define_t { - define_t() { }; define_t(const pstring &name, const pstring &replace) : m_name(name), m_replace(replace) {} @@ -166,7 +165,7 @@ public: pstring m_replace; }; - ppreprocessor(); + ppreprocessor(std::vector<define_t> *defines = nullptr); virtual ~ppreprocessor() {} template<class ISTR, class OSTR> diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 6fc423cac17..df6dd4d7901 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -62,7 +62,7 @@ public: public: using list_t = std::vector<callback_t *>; - virtual ~callback_t() { }; + virtual ~callback_t() { } virtual void register_state(state_manager_t &manager, const pstring &module) = 0; virtual void on_pre_save() = 0; diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp index 20573f5bfa5..c85f18c260a 100644 --- a/src/lib/netlist/plib/pstring.cpp +++ b/src/lib/netlist/plib/pstring.cpp @@ -22,30 +22,6 @@ pstr_t pstring_t<putf8_traits>::m_zero = pstr_t(0); template<> pstr_t pstring_t<pu8_traits>::m_zero = pstr_t(0); - -/* - * Uncomment the following to override defaults - */ - -#define IMMEDIATE_MODE (1) -//#define DEBUG_MODE (0) - -#ifdef MAME_DEBUG - #ifndef IMMEDIATE_MODE - #define IMMEDIATE_MODE (1) - #endif - #ifndef DEBUG_MODE - #define DEBUG_MODE (0) - #endif -#else - #ifndef IMMEDIATE_MODE - #define IMMEDIATE_MODE (1) - #endif - #ifndef DEBUG_MODE - #define DEBUG_MODE (0) - #endif -#endif - template<typename F> pstring_t<F>::~pstring_t() { @@ -117,29 +93,22 @@ void pstring_t<F>::pcopy(const mem_t *from, int size) } template<typename F> -const pstring_t<F> pstring_t<F>::substr(int start, int count) const +const pstring_t<F> pstring_t<F>::substr(unsigned start, unsigned count) const { pstring_t ret; - int alen = (int) len(); - if (start < 0) - start = 0; - if (start >= alen) + unsigned alen = len(); + if (start >= alen || count == 0) return ret; - if (count <0 || start + count > alen) + if (start + count > alen) count = alen - start; - const char *p = cstr(); - if (count <= 0) - ret.pcopy(p, 0); - else - { - // find start - for (int i=0; i<start; i++) - p += F::codelen(p); - const char *e = p; - for (int i=0; i<count; i++) - e += F::codelen(e); - ret.pcopy(p, e-p); - } + const mem_t *p = cstr(); + // find start + for (unsigned i=0; i<start; i++) + p += F::codelen(p); + const char *e = p; + for (unsigned i=0; i<count; i++) + e += F::codelen(e); + ret.pcopy(p, e-p); return ret; } @@ -446,9 +415,9 @@ int pstring_t<F>::find(const pstring_t &search, unsigned start) const { const unsigned tlen = len(); const unsigned slen = search.len(); - const char *s = search.cstr(); + const mem_t *s = search.cstr(); const unsigned startt = std::min(start, tlen); - const char *t = cstr(); + const mem_t *t = cstr(); for (std::size_t i=0; i<startt; i++) t += F::codelen(t); for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index ba5527d184e..2490186566e 100644 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -113,40 +113,41 @@ public: double as_double(bool *error = nullptr) const; long as_long(bool *error = nullptr) const; - /* - * everything below MAY not work for utf8. - * Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8 - */ - unsigned len() const { return F::len(m_ptr); } pstring_t& operator+=(const code_t c) { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(c, buf); pcat(buf); return *this; } - friend pstring_t operator+(const pstring_t &lhs, const mem_t rhs) { return pstring_t(lhs) += rhs; } + friend pstring_t operator+(const pstring_t &lhs, const code_t rhs) { return pstring_t(lhs) += rhs; } int find(const pstring_t &search, unsigned start = 0) const; int find(const mem_t *search, unsigned start = 0) const; - int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); }; + int find(const code_t search, unsigned start = 0) const { mem_t buf[F::MAXCODELEN+1] = { 0 }; F::encode(search, buf); return find(buf, start); } - const pstring_t substr(int start, int count = -1) const ; + const pstring_t substr(unsigned start, unsigned count) const ; + const pstring_t substr(unsigned start) const { if (start>=len()) return pstring_t(""); else return substr(start, len()-start); } const pstring_t left(unsigned count) const { return substr(0, count); } - const pstring_t right(unsigned count) const { return substr((int) len() - (int) count, count); } + const pstring_t right(unsigned count) const { if (len()<count) return pstring_t(*this); else return substr(len() - count, count); } int find_first_not_of(const pstring_t &no) const; int find_last_not_of(const pstring_t &no) const; - // FIXME: - code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); } - const pstring_t ltrim(const pstring_t &ws = " \t\n\r") const; const pstring_t rtrim(const pstring_t &ws = " \t\n\r") const; const pstring_t trim(const pstring_t &ws = " \t\n\r") const { return this->ltrim(ws).rtrim(ws); } const pstring_t rpad(const pstring_t &ws, const unsigned cnt) const; + /* + * everything below MAY not work for utf8. + * Example a=s.find(EUROSIGN); b=s.substr(a,1); will deliver invalid utf8 + */ + + // FIXME: + code_t code_at(const unsigned pos) const { return F::code(F::nthcode(m_ptr->str(),pos)); } + const pstring_t ucase() const; static void resetmem(); @@ -332,6 +333,8 @@ public: // construction with copy pstringbuffer(const char *string) {init(); if (string != nullptr) pcopy(string); } pstringbuffer(const pstring &string) {init(); pcopy(string); } + pstringbuffer(const pstringbuffer &stringb) {init(); pcopy(stringb); } + pstringbuffer(pstringbuffer &&b) : m_ptr(b.m_ptr), m_size(b.m_size), m_len(b.m_len) { b.m_ptr = nullptr; b.m_size = 0; b.m_len = 0; } // assignment operators pstringbuffer &operator=(const char *string) { pcopy(string); return *this; } diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 1163788b80f..fdfd5ed7a94 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -26,39 +26,56 @@ class tool_options_t : public plib::options public: tool_options_t() : plib::options(), - opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), - opt_name(*this, "n", "name", "", "netlist in file to run; default is first one"), - opt_logs(*this, "l", "logs", "", "colon separated list of terminals to log"), - opt_file(*this, "f", "file", "-", "file to process (default is stdin)"), - opt_type(*this, "y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle"), + opt_grp1(*this, "General options", "The following options apply to all commands."), opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static", "run|convert|listdevices|static"), - opt_inp(*this, "i", "input", "", "input file to process (default is none)"), + opt_file(*this, "f", "file", "-", "file to process (default is stdin)"), + opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."), opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"), opt_quiet(*this, "q", "quiet", "be quiet - no warnings"), opt_version(*this, "", "version", "display version and exit"), - opt_help(*this, "h", "help", "display help and exit") - {} + opt_help(*this, "h", "help", "display help and exit"), + opt_grp2(*this, "Options for run and static commands", "These options apply to run and static commands."), + opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"), + opt_grp3(*this, "Options for run command", "These options are only used by the run command."), + opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), + opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."), + opt_inp(*this, "i", "input", "", "input file to process (default is none)"), + opt_grp4(*this, "Options for convert command", "These options are only used by the convert command."), + opt_type(*this, "y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle"), - plib::option_double opt_ttr; - plib::option_str opt_name; - plib::option_str opt_logs; - plib::option_str opt_file; - plib::option_str_limit opt_type; + opt_ex1(*this, "nltool -c run -t 3.5 -f nl_examples/cdelay.c -n cap_delay", + "Run netlist \"cap_delay\" from file nl_examples/cdelay.c for 3.5 seconds"), + opt_ex2(*this, "nltool --cmd=listdevices", + "List all known devices.") + {} + + plib::option_group opt_grp1; plib::option_str_limit opt_cmd; - plib::option_str opt_inp; + plib::option_str opt_file; + plib::option_vec opt_defines; plib::option_bool opt_verb; plib::option_bool opt_quiet; plib::option_bool opt_version; plib::option_bool opt_help; + plib::option_group opt_grp2; + plib::option_str opt_name; + plib::option_group opt_grp3; + plib::option_double opt_ttr; + plib::option_vec opt_logs; + plib::option_str opt_inp; + plib::option_group opt_grp4; + plib::option_str_limit opt_type; + plib::option_example opt_ex1; + plib::option_example opt_ex2; }; -plib::pstdout pout_strm; -plib::pstderr perr_strm; +static plib::pstdout pout_strm; +static plib::pstderr perr_strm; -plib::pstream_fmt_writer_t pout(pout_strm); -plib::pstream_fmt_writer_t perr(perr_strm); +static plib::pstream_fmt_writer_t pout(pout_strm); +static plib::pstream_fmt_writer_t perr(perr_strm); -NETLIST_START(dummy) +static NETLIST_START(dummy) /* Standard stuff */ CLOCK(clk, 1000) // 1000 Hz @@ -75,7 +92,7 @@ class netlist_tool_t : public netlist::netlist_t public: netlist_tool_t(const pstring &aname) - : netlist::netlist_t(aname), m_opts(nullptr), m_setup(nullptr) + : netlist::netlist_t(aname), m_setup(nullptr) { } @@ -83,21 +100,26 @@ public: { if (m_setup != nullptr) plib::pfree(m_setup); - }; + } void init() { m_setup = plib::palloc<netlist::setup_t>(*this); } - void read_netlist(const pstring &filename, const pstring &name) + void read_netlist(const pstring &filename, const pstring &name, + const std::vector<pstring> &logs, + const std::vector<pstring> &defines) { // read the netlist ... + for (auto & d : defines) + m_setup->register_define(d); + m_setup->register_source(plib::make_unique_base<netlist::source_t, netlist::source_file_t>(filename)); m_setup->include(name); - log_setup(); + log_setup(logs); // start devices m_setup->start_devices(); @@ -106,11 +128,10 @@ public: this->reset(); } - void log_setup() + void log_setup(const std::vector<pstring> &logs) { log().debug("Creating dynamic logs ...\n"); - plib::pstring_vector_t ll(m_opts ? m_opts->opt_logs() : "" , ":"); - for (auto & log : ll) + for (auto & log : logs) { pstring name = "log_" + log; /*netlist_device_t *nc = */ m_setup->register_dev("LOG", name); @@ -120,8 +141,6 @@ public: netlist::setup_t &setup() { return *m_setup; } - tool_options_t *m_opts; - protected: void vlog(const plib::plog_level &l, const pstring &ls) const override @@ -136,6 +155,9 @@ private: }; +// FIXME: usage should go elsewhere +void usage(tool_options_t &opts); + void usage(tool_options_t &opts) { pout("{}\n", opts.help( @@ -208,13 +230,12 @@ static std::vector<input_t> read_input(const netlist::setup_t &setup, pstring fn static void run(tool_options_t &opts) { - netlist_tool_t nt("netlist"); plib::chrono::timer<plib::chrono::system_ticks> t; - //plib::perftime_t<plib::exact_ticks> t; - t.start(); - nt.m_opts = &opts; + netlist_tool_t nt("netlist"); + //plib::perftime_t<plib::exact_ticks> t; + nt.init(); if (!opts.opt_verb()) @@ -222,7 +243,9 @@ static void run(tool_options_t &opts) if (opts.opt_quiet()) nt.log().warning.set_enabled(false); - nt.read_netlist(opts.opt_file(), opts.opt_name()); + nt.read_netlist(opts.opt_file(), opts.opt_name(), + opts.opt_logs(), + opts.opt_defines()); std::vector<input_t> inps = read_input(nt.setup(), opts.opt_inp()); @@ -258,13 +281,14 @@ static void static_compile(tool_options_t &opts) { netlist_tool_t nt("netlist"); - nt.m_opts = &opts; nt.init(); nt.log().verbose.set_enabled(false); nt.log().warning.set_enabled(false); - nt.read_netlist(opts.opt_file(), opts.opt_name()); + nt.read_netlist(opts.opt_file(), opts.opt_name(), + opts.opt_logs(), + opts.opt_defines()); nt.solver()->create_solver_code(pout_strm); @@ -276,16 +300,22 @@ static void static_compile(tool_options_t &opts) listdevices - list all known devices -------------------------------------------------*/ -static void listdevices() +static void listdevices(tool_options_t &opts) { netlist_tool_t nt("netlist"); nt.init(); + if (!opts.opt_verb()) + nt.log().verbose.set_enabled(false); + if (opts.opt_quiet()) + nt.log().warning.set_enabled(false); + netlist::factory_list_t &list = nt.setup().factory(); nt.setup().register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>("dummy", &netlist_dummy)); nt.setup().include("dummy"); + nt.setup().start_devices(); nt.setup().resolve_inputs(); @@ -294,7 +324,7 @@ static void listdevices() for (auto & f : list) { pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name()); - pstring terms(""); + std::vector<pstring> terms; auto d = f->Create(nt.setup().netlist(), f->name() + "_lc"); // get the list of terminals ... @@ -305,7 +335,7 @@ static void listdevices() { pstring tn(t.second->name().substr(d->name().len()+1)); if (tn.find(".")<0) - terms += ", " + tn; + terms.push_back(tn); } } @@ -315,14 +345,23 @@ static void listdevices() { pstring tn(t.first.substr(d->name().len()+1)); if (tn.find(".")<0) - terms += ", " + tn; + { + terms.push_back(tn); + pstring resolved = nt.setup().resolve_alias(t.first); + if (resolved != t.first) + { + auto found = std::find(terms.begin(), terms.end(), resolved.substr(d->name().len()+1)); + if (found!=terms.end()) + terms.erase(found); + } + } } } if (f->param_desc().startsWith("+")) { out += "," + f->param_desc().substr(1); - terms = ""; + terms.clear(); } else if (f->param_desc() == "-") { @@ -334,8 +373,13 @@ static void listdevices() } out += ")"; printf("%s\n", out.cstr()); - if (terms != "") - printf("Terminals: %s\n", terms.substr(1).cstr()); + if (terms.size() > 0) + { + pstring t = ""; + for (auto & j : terms) + t += "," + j; + printf("Terminals: %s\n", t.substr(1).cstr()); + } devs.push_back(std::move(d)); } } @@ -390,7 +434,7 @@ int main(int argc, char *argv[]) pstring cmd = opts.opt_cmd(); if (cmd == "listdevices") - listdevices(); + listdevices(opts); else if (cmd == "run") run(opts); else if (cmd == "static") diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 1623bbe91dc..0937f70470d 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -126,7 +126,7 @@ private: }; -void convert(nlwav_options_t &opts) +static void convert(nlwav_options_t &opts) { plib::pofilestream fo(opts.opt_out()); if (fo.bad()) @@ -157,8 +157,8 @@ void convert(nlwav_options_t &opts) while(fin.readline(line)) { #if 1 - float t = 0.0; float v = 0.0; - sscanf(line.cstr(), "%f %f", &t, &v); + double t = 0.0; double v = 0.0; + sscanf(line.cstr(), "%lf %lf", &t, &v); while (t >= ct) { outsam += (ct - lt) * cursam; @@ -214,7 +214,7 @@ void convert(nlwav_options_t &opts) } -void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts) +static void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts) { fw("{}\n", opts.help("Convert netlist log files into wav files.\n", "nltool [options]").cstr()); diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index f58adf44103..e196649735e 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -126,8 +126,7 @@ public: , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0) , m_iterative_fail(*this, "m_iterative_fail", 0) , m_iterative_total(*this, "m_iterative_total", 0) - , m_last_step(*this, "m_last_step", netlist_time::quantum()) - , m_cur_ts(*this, "m_cur_ts", 0) + , m_last_step(*this, "m_last_step", netlist_time::zero()) , m_fb_sync(*this, "FB_sync") , m_Q_sync(*this, "Q_sync") , m_sort(sort) @@ -139,7 +138,7 @@ public: void setup(analog_net_t::list_t &nets) { vsetup(nets); } - const netlist_time solve_base(); + void solve_base(); const netlist_time solve(); @@ -149,7 +148,7 @@ public: void update_forced(); void update_after(const netlist_time &after) { - m_Q_sync.net().toggle_new_Q(); + m_Q_sync.net().force_queue_execution(); m_Q_sync.net().reschedule_in_queue(after); } @@ -177,7 +176,7 @@ protected: virtual void vsetup(analog_net_t::list_t &nets) = 0; virtual int vsolve_non_dynamic(const bool newton_raphson) = 0; - /* virtual */ netlist_time compute_next_timestep(); + netlist_time compute_next_timestep(const double cur_ts); /* virtual */ void add_term(int net_idx, terminal_t *term); template <typename T> @@ -204,11 +203,9 @@ protected: state_var<int> m_iterative_fail; state_var<int> m_iterative_total; - inline nl_double current_timestep() { return m_cur_ts; } private: state_var<netlist_time> m_last_step; - state_var<nl_double> m_cur_ts; std::vector<core_device_t *> m_step_devices; std::vector<core_device_t *> m_dynamic_devices; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index db695058abb..e4af64749e5 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -377,7 +377,7 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_back_subst( template <unsigned m_N, unsigned storage_N> -int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { nl_double new_V[storage_N]; // = { 0.0 }; diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index 7b99dc17e8b..cd2a749dec6 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -198,6 +198,8 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_timestep() } if (new_solver_timestep < m_params.m_min_timestep) new_solver_timestep = m_params.m_min_timestep; + if (new_solver_timestep > m_params.m_max_timestep) + new_solver_timestep = m_params.m_max_timestep; } //if (new_solver_timestep > 10.0 * hn) // new_solver_timestep = 10.0 * hn; @@ -566,7 +568,7 @@ void matrix_solver_direct_t<m_N, storage_N>::store( template <unsigned m_N, unsigned storage_N> -int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_direct_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { nl_double new_V[storage_N]; // = { 0.0 }; diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index 8fae5243b42..ffe59f93d21 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -219,7 +219,7 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_compute_x( template <unsigned m_N, unsigned storage_N> -int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { static const bool incremental = true; static unsigned cnt = 0; diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 986eabc16c5..33e94a207c3 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -227,7 +227,7 @@ void matrix_solver_w_t<m_N, storage_N>::LE_compute_x( template <unsigned m_N, unsigned storage_N> -int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { const auto iN = N(); diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 16ae8dab691..583ac904198 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -172,7 +172,8 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) log().debug("Added input\n"); } break; - default: + case terminal_t::OUTPUT: + case terminal_t::PARAM: log().fatal("unhandled element found\n"); break; } @@ -335,7 +336,7 @@ void matrix_solver_t::setup_matrix() } log().verbose("Number of mults/adds for {1}: {2}", name(), ops); - if (0) + if ((0)) for (unsigned k = 0; k < iN; k++) { pstring line = plib::pfmt("{1}")(k, "3"); @@ -390,7 +391,7 @@ void matrix_solver_t::update() NOEXCEPT if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero()) { - m_Q_sync.net().toggle_new_Q(); + m_Q_sync.net().force_queue_execution(); m_Q_sync.net().reschedule_in_queue(new_timestep); } } @@ -401,7 +402,7 @@ void matrix_solver_t::update_forced() if (m_params.m_dynamic && has_timestep_devices()) { - m_Q_sync.net().toggle_new_Q(); + m_Q_sync.net().force_queue_execution(); m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep)); } } @@ -413,7 +414,7 @@ void matrix_solver_t::step(const netlist_time &delta) m_step_devices[k]->step_time(dd); } -const netlist_time matrix_solver_t::solve_base() +void matrix_solver_t::solve_base() { m_stat_vsolver_calls++; if (has_dynamic_devices()) @@ -441,7 +442,6 @@ const netlist_time matrix_solver_t::solve_base() { this->vsolve_non_dynamic(false); } - return this->compute_next_timestep(); } const netlist_time matrix_solver_t::solve() @@ -451,18 +451,17 @@ const netlist_time matrix_solver_t::solve() // We are already up to date. Avoid oscillations. // FIXME: Make this a parameter! - if (delta < netlist_time::from_nsec(1)) // 20000 - return netlist_time::from_nsec(0); + if (delta < netlist_time::quantum()) + return netlist_time::zero(); /* update all terminals for new time step */ m_last_step = now; - m_cur_ts = delta.as_double(); - step(delta); - - const netlist_time next_time_step = solve_base(); + solve_base(); + const netlist_time next_time_step = compute_next_timestep(delta.as_double()); update_inputs(); + return next_time_step; } @@ -496,7 +495,7 @@ void matrix_solver_t::add_term(int k, terminal_t *term) } } -netlist_time matrix_solver_t::compute_next_timestep() +netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts) { nl_double new_solver_timestep = m_params.m_max_timestep; @@ -512,15 +511,15 @@ netlist_time matrix_solver_t::compute_next_timestep() terms_t *t = m_terms[k]; const nl_double DD_n = (n->Q_Analog() - t->m_last_V); - const nl_double hn = current_timestep(); + const nl_double hn = cur_ts; nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1); nl_double new_net_timestep; t->m_h_n_m_1 = hn; t->m_DD_n_m_1 = DD_n; - if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero - new_net_timestep = std::sqrt(m_params.m_lte / std::abs(NL_FCONST(0.5)*DD2)); + if (std::fabs(DD2) > NL_FCONST(1e-60)) // avoid div-by-zero + new_net_timestep = std::sqrt(m_params.m_lte / std::fabs(NL_FCONST(0.5)*DD2)); else new_net_timestep = m_params.m_max_timestep; @@ -534,7 +533,10 @@ netlist_time matrix_solver_t::compute_next_timestep() } //if (new_solver_timestep > 10.0 * hn) // new_solver_timestep = 10.0 * hn; - return netlist_time::from_double(new_solver_timestep); + /* + * FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere. + */ + return std::max(netlist_time::from_double(new_solver_timestep), netlist_time::quantum() * 2); } @@ -713,13 +715,15 @@ void NETLIB_NAME(solver)::post_start() if (m_params.m_dynamic) { - m_params.m_max_timestep *= NL_FCONST(1000.0); + m_params.m_max_timestep *= 1;//NL_FCONST(1000.0); } else { m_params.m_min_timestep = m_params.m_max_timestep; } + //m_params.m_max_timestep = std::max(m_params.m_max_timestep, m_params.m_max_timestep::) + // Override log statistics pstring p = plib::util::environment("NL_STATS"); if (p != "") diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h index 90bae5533eb..ca086d5346b 100644 --- a/src/lib/netlist/tools/nl_convert.h +++ b/src/lib/netlist/tools/nl_convert.h @@ -23,7 +23,7 @@ class nl_convert_base_t { public: - nl_convert_base_t() : out(m_buf) {}; + nl_convert_base_t() : out(m_buf) {} virtual ~nl_convert_base_t() { m_nets.clear(); @@ -143,7 +143,7 @@ class nl_convert_spice_t : public nl_convert_base_t { public: - nl_convert_spice_t() : nl_convert_base_t() {}; + nl_convert_spice_t() : nl_convert_base_t() {} ~nl_convert_spice_t() { } @@ -162,7 +162,7 @@ class nl_convert_eagle_t : public nl_convert_base_t { public: - nl_convert_eagle_t() : nl_convert_base_t() {}; + nl_convert_eagle_t() : nl_convert_base_t() {} ~nl_convert_eagle_t() { } diff --git a/src/mame/machine/nl_breakout.cpp b/src/mame/machine/nl_breakout.cpp index 189646385af..c374c169593 100644 --- a/src/mame/machine/nl_breakout.cpp +++ b/src/mame/machine/nl_breakout.cpp @@ -77,7 +77,7 @@ static Astable555Desc b2_555_desc(OHM(560.0), M_OHM(1.8), U_FARAD(0.1)); static Mono555Desc c9_555_desc(OHM(47000.0), U_FARAD(1.0)); // R33, C21 static CapacitorDesc c32_desc(U_FARAD(0.1)); -static CapacitorDesc c36_desc(N_FARAD(1.0)); //0.001uF = 1nF +static CapacitorDesc c36_desc(N_FARAD(1.0*.7)); //0.001uF = 1nF - determines horizontal gap between bricks static CapacitorDesc c37_desc(P_FARAD(330.0)); static Mono9602Desc n8_desc(K_OHM(33.0), U_FARAD(100.0), K_OHM(5.6), P_FARAD(0)); // No capacitor on 2nd 9602 @@ -96,8 +96,10 @@ CIRCUIT_LAYOUT( breakout ) SOLVER(Solver, 48000) PARAM(Solver.ACCURACY, 1e-6) PARAM(Solver.GS_THRESHOLD, 6) - // FIXME: PARALLEL Doesn't work in breakout. - PARAM(Solver.PARALLEL, 0) + PARAM(Solver.DYNAMIC_TS, 0) + //PARAM(Solver.LTE, 1e-10) + PARAM(Solver.MIN_TIMESTEP, 1e-8) + PARAM(Solver.ITERATIVE, "MAT_CR") #endif PARAM(NETLIST.USE_DEACTIVATE, 1) |
