diff options
Diffstat (limited to 'src/lib')
73 files changed, 4225 insertions, 428 deletions
diff --git a/src/lib/formats/acorn_dsk.cpp b/src/lib/formats/acorn_dsk.cpp index b880b28018f..0c62a907864 100644 --- a/src/lib/formats/acorn_dsk.cpp +++ b/src/lib/formats/acorn_dsk.cpp @@ -412,8 +412,8 @@ int acorn_adfs_new_format::find_size(io_generic *io, uint32_t form_factor) if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; - // valid images will have map identifier Nick - if ((size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0)) { + // valid images will have map identifier Nick, Arthur D format still use Hugo + if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0 || memcmp(dform, "Hugo", 4) == 0)) { return i; } } diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 57d6f6a76f3..d587f691e56 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -48,6 +48,22 @@ namespace netlist * 2; opamp with first pole * 3: opamp with first pole + output limit * 4: opamp with input stage, first pole + output limit + * + * Type 1 parameters: + * FPF = frequency of first pole in Hz (ony used for open-loop gain) + * UGF = unity gain frequency in Hz (only used for open-loop gain) + * RI = input resistance in Ohms + * RO = output resistance in Ohms + * + * Type 3 parameters: + * VLH = high supply rail minus high output swing in V + * VLL = low output swing minus low supply rail in V + * FPF = frequency of first pole in Hz + * UGF = unity gain frequency (transition frequency) in Hz + * SLEW = unity gain slew rate in V/s + * RI = input resistance in Ohms + * RO = output resistance in Ohms + * DAB = quiescent supply current in A */ /* .model abc OPAMP(VLH=2.0 VLL=0.2 FPF=5 UGF=10k SLEW=0.6u RI=1000k RO=50 DAB=0.002) diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp index 3ddff27557d..089b11f8607 100644 --- a/src/lib/netlist/analog/nld_twoterm.cpp +++ b/src/lib/netlist/analog/nld_twoterm.cpp @@ -117,6 +117,27 @@ NETLIB_UPDATE(C) } // ---------------------------------------------------------------------------------------- +// nld_L +// ---------------------------------------------------------------------------------------- + +NETLIB_RESET(L) +{ + set(netlist().gmin(), 0.0, 5.0 / netlist().gmin()); + //set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN); +} + +NETLIB_UPDATE_PARAM(L) +{ + //step_time(1.0/48000.0); + //m_GParallel = netlist().gmin() / m_L(); +} + +NETLIB_UPDATE(L) +{ + NETLIB_NAME(twoterm)::update(); +} + +// ---------------------------------------------------------------------------------------- // nld_D // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h index b5de48ae1d8..f59b9e62594 100644 --- a/src/lib/netlist/analog/nld_twoterm.h +++ b/src/lib/netlist/analog/nld_twoterm.h @@ -40,34 +40,38 @@ // ----------------------------------------------------------------------------- #define RES(name, p_R) \ - NET_REGISTER_DEV(RES, name) \ + NET_REGISTER_DEV(RES, name) \ NETDEV_PARAMI(name, R, p_R) #define POT(name, p_R) \ - NET_REGISTER_DEV(POT, name) \ + NET_REGISTER_DEV(POT, name) \ NETDEV_PARAMI(name, R, p_R) /* Does not have pin 3 connected */ #define POT2(name, p_R) \ - NET_REGISTER_DEV(POT2, name) \ + NET_REGISTER_DEV(POT2, name) \ NETDEV_PARAMI(name, R, p_R) #define CAP(name, p_C) \ - NET_REGISTER_DEV(CAP, name) \ + NET_REGISTER_DEV(CAP, name) \ NETDEV_PARAMI(name, C, p_C) +#define IND(name, p_L) \ + NET_REGISTER_DEV(IND, name) \ + NETDEV_PARAMI(name, L, p_L) + /* Generic Diode */ -#define DIODE(name, model) \ - NET_REGISTER_DEV(DIODE, name) \ +#define DIODE(name, model) \ + NET_REGISTER_DEV(DIODE, name) \ NETDEV_PARAMI(name, MODEL, model) -#define VS(name, pV) \ - NET_REGISTER_DEV(VS, name) \ +#define VS(name, pV) \ + NET_REGISTER_DEV(VS, name) \ NETDEV_PARAMI(name, V, pV) -#define CS(name, pI) \ - NET_REGISTER_DEV(CS, name) \ +#define CS(name, pI) \ + NET_REGISTER_DEV(CS, name) \ NETDEV_PARAMI(name, I, pI) // ----------------------------------------------------------------------------- @@ -303,6 +307,43 @@ private: }; +// ----------------------------------------------------------------------------- +// nld_L +// ----------------------------------------------------------------------------- + +NETLIB_OBJECT_DERIVED(L, twoterm) +{ +public: + NETLIB_CONSTRUCTOR_DERIVED(L, twoterm) + , m_L(*this, "L", 1e-6) + , m_GParallel(0.0) + , m_G(0.0) + , m_I(0.0) + { + //register_term("1", m_P); + //register_term("2", m_N); + } + + NETLIB_TIMESTEP() + { + /* Gpar should support convergence */ + m_I = m_I + m_G * deltaV(); + m_G = step / m_L() + m_GParallel; + set(m_G, 0.0, m_I); + } + + param_double_t m_L; + +protected: + NETLIB_RESETI(); + NETLIB_UPDATEI(); + NETLIB_UPDATE_PARAMI(); + +private: + nl_double m_GParallel; + nl_double m_G; + nl_double m_I; +}; // ----------------------------------------------------------------------------- // A generic diode model to be used in other devices (Diode, BJT ...) diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 36bce299de5..171ba4cf5bb 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -66,32 +66,52 @@ NLOBJS := \ $(NLOBJ)/analog/nld_switches.o \ $(NLOBJ)/analog/nld_twoterm.o \ $(NLOBJ)/analog/nld_opamps.o \ + $(NLOBJ)/devices/nld_2102A.o \ + $(NLOBJ)/devices/nld_2716.o \ $(NLOBJ)/devices/nld_4020.o \ $(NLOBJ)/devices/nld_4066.o \ + $(NLOBJ)/devices/nld_4316.o \ $(NLOBJ)/devices/nld_7448.o \ $(NLOBJ)/devices/nld_7450.o \ + $(NLOBJ)/devices/nld_7473.o \ $(NLOBJ)/devices/nld_7474.o \ + $(NLOBJ)/devices/nld_7475.o \ $(NLOBJ)/devices/nld_7483.o \ + $(NLOBJ)/devices/nld_7485.o \ $(NLOBJ)/devices/nld_7490.o \ $(NLOBJ)/devices/nld_7493.o \ $(NLOBJ)/devices/nld_74107.o \ $(NLOBJ)/devices/nld_74123.o \ $(NLOBJ)/devices/nld_74153.o \ + $(NLOBJ)/devices/nld_74161.o \ + $(NLOBJ)/devices/nld_74165.o \ + $(NLOBJ)/devices/nld_74166.o \ + $(NLOBJ)/devices/nld_74174.o \ $(NLOBJ)/devices/nld_74175.o \ $(NLOBJ)/devices/nld_74192.o \ $(NLOBJ)/devices/nld_74193.o \ + $(NLOBJ)/devices/nld_74194.o \ $(NLOBJ)/devices/nld_74279.o \ + $(NLOBJ)/devices/nld_74365.o \ $(NLOBJ)/devices/nld_74ls629.o \ $(NLOBJ)/devices/nld_82S16.o \ + $(NLOBJ)/devices/nld_82S115.o \ + $(NLOBJ)/devices/nld_82S123.o \ + $(NLOBJ)/devices/nld_82S126.o \ $(NLOBJ)/devices/nld_9310.o \ $(NLOBJ)/devices/nld_9312.o \ $(NLOBJ)/devices/nld_9316.o \ + $(NLOBJ)/devices/nld_9322.o \ + $(NLOBJ)/devices/nld_am2847.o \ + $(NLOBJ)/devices/nld_dm9334.o \ $(NLOBJ)/devices/nld_mm5837.o \ $(NLOBJ)/devices/nld_ne555.o \ $(NLOBJ)/devices/nld_r2r_dac.o \ + $(NLOBJ)/devices/nld_tristate.o \ $(NLOBJ)/devices/nld_legacy.o \ $(NLOBJ)/devices/net_lib.o \ $(NLOBJ)/devices/nld_log.o \ + $(NLOBJ)/devices/nlid_proxy.o \ $(NLOBJ)/devices/nld_system.o \ $(NLOBJ)/devices/nld_truthtable.o \ $(NLOBJ)/macro/nlm_cd4xxx.o \ @@ -124,7 +144,7 @@ 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 $@... @@ -145,14 +165,14 @@ maketree: $(sort $(OBJDIRS)) .PHONY: clang mingw doc -clang: +clang: $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -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" -# -# FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors -# +# +# FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors +# -mingw: +mingw: $(MAKE) LDEXTRAFLAGS="-Wl,--subsystem,console" LIBS= MD=@mkdir.exe SHELL=sh.exe # @@ -191,7 +211,7 @@ $(OBJ)/%.o: $(SRC)/%.cpp @echo Compiling $<... @$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@ -$(OBJ)/%.pp: $(SRC)/%.cpp +$(OBJ)/%.pp: $(SRC)/%.cpp @echo Compiling $<... @$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@ diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index f70e229ddff..5250135feb8 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -34,6 +34,7 @@ NETLIST_START(bjt_models) NET_MODEL("2SA1015 PNP(Is=295.1E-18 Xti=3 Eg=1.11 Vaf=100 Bf=110 Xtb=1.5 Br=10.45 Rc=15 Cjc=66.2p Mjc=1.054 Vjc=.75 Fc=.5 Cje=5p Mje=.3333 Vje=.75 Tr=10n Tf=1.661n VCEO=45V ICrating=150M MFG=Toshiba)") NET_MODEL("2SC1815 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)") + NET_MODEL("2N3565 NPN(IS=5.911E-15 ISE=5.911E-15 ISC=0 XTI=3 BF=697.1 BR=1.297 IKF=0.01393 IKR=0 XTB=1.5 VAF=62.37 VAR=21.5 VJE=0.65 VJC=0.65 RE=0.15 RC=1.61 RB=10 CJE=4.973E-12 CJC=4.017E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.342 NC=2 MJE=0.4146 MJC=0.3174 TF=820.4E-12 TR=4.687E-9 ITF=0.35 VTF=4 XTF=7 EG=1.11 KF=1E-9 AF=1 VCEO=25 ICRATING=500m MFG=NSC)") NET_MODEL("2N3643 NPN(IS=14.34E-15 ISE=14.34E-15 ISC=0 XTI=3 BF=255.9 BR=6.092 IKF=0.2847 IKR=0 XTB=1.5 VAF=74.03 VAR=28 VJE=0.65 VJC=0.65 RE=0.1 RC=1 RB=10 CJE=22.01E-12 CJC=7.306E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.307 NC=2 MJE=0.377 MJC=0.3416 TF=411.1E-12 TR=46.91E-9 ITF=0.6 VTF=1.7 XTF=3 EG=1.11 KF=0 AF=1 VCEO=30 ICRATING=500m MFG=NSC)") NET_MODEL("2N3645 PNP(IS=650.6E-18 ISE=54.81E-15 ISC=0 XTI=3 BF=231.7 BR=3.563 IKF=1.079 IKR=0 XTB=1.5 VAF=115.7 VAR=35 VJE=0.65 VJC=0.65 RE=0.15 RC=0.715 RB=10 CJE=19.82E-12 CJC=14.76E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.829 NC=2 MJE=0.3357 MJC=0.5383 TF=603.7E-12 TR=111.3E-9 ITF=0.65 VTF=5 XTF=1.7 EG=1.11 KF=0 AF=1 VCEO=60 ICRATING=500m MFG=NSC)") // 3644 = 3645 Difference between 3644 and 3645 is voltage rating. 3644: VCBO=45, 3645: VCBO=60 @@ -49,10 +50,10 @@ NETLIST_START(bjt_models) NETLIST_END() NETLIST_START(family_models) - NET_MODEL("FAMILY _(TYPE=CUSTOM IVL=0.8 IVH=2.0 OVL=0.1 OVH=4.0 ORL=1.0 ORH=130.0)") + NET_MODEL("FAMILY _(TYPE=CUSTOM FV=5 IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130.0)") NET_MODEL("OPAMP _()") - NET_MODEL("74XXOC FAMILY(IVL=0.8 IVH=2.0 OVL=0.1 OVH=4.95 ORL=10.0 ORH=1.0e8)") + NET_MODEL("74XXOC FAMILY(FV=5 IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)") NET_MODEL("74XX FAMILY(TYPE=TTL)") NET_MODEL("CD4XXX FAMILY(TYPE=CD4XXX)") NETLIST_END() @@ -77,6 +78,7 @@ static void initialize_factory(factory_list_t &factory) ENTRY(POT, POT, "R") ENTRY(POT2, POT2, "R") ENTRY(C, CAP, "C") + ENTRY(L, IND, "L") ENTRY(D, DIODE, "MODEL") ENTRY(VCVS, VCVS, "-") ENTRY(VCCS, VCCS, "-") @@ -105,26 +107,45 @@ static void initialize_factory(factory_list_t &factory) ENTRY(switch1, SWITCH, "-") ENTRY(switch2, SWITCH2, "-") ENTRYX(nicRSFF, NETDEV_RSFF, "+S,R") - ENTRYX(nicDelay, NETDEV_DELAY, "-") + ENTRYX(nicDelay, NETDEV_DELAY, "-") + ENTRYX(2716, EPROM_2716, "+GQ,EPQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10") + ENTRYX(2102A, RAM_2102A, "+CEQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,RWQ,DI") ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,B,C,D") ENTRYX(7448, TTL_7448, "+A,B,C,D,LTQ,BIQ,RBIQ") + ENTRYX(7473, TTL_7473, "+CLK,J,K,CLRQ") + ENTRYX(7473A, TTL_7473A, "+CLK,J,K,CLRQ") ENTRYX(7474, TTL_7474, "+CLK,D,CLRQ,PREQ") + ENTRYX(7475, TTL_7475, "-") + ENTRYX(7477, TTL_7477, "-") ENTRYX(7483, TTL_7483, "+A1,A2,A3,A4,B1,B2,B3,B4,C0") + ENTRYX(7485, TTL_7485, "+A0,A1,A2,A3,B0,B1,B2,B3,LTIN,EQIN,GTIN") ENTRYX(7490, TTL_7490, "+A,B,R1,R2,R91,R92") ENTRYX(7493, TTL_7493, "+CLKA,CLKB,R1,R2") ENTRYX(74107, TTL_74107, "+CLK,J,K,CLRQ") ENTRYX(74107A, TTL_74107A, "+CLK,J,K,CLRQ") ENTRYX(74123, TTL_74123, "-") ENTRYX(74153, TTL_74153, "+C0,C1,C2,C3,A,B,G") - ENTRYX(74175, TTL_74175, "-") - ENTRYX(74192, TTL_74192, "-") - ENTRYX(74193, TTL_74193, "-") + ENTRYX(74161, TTL_74161, "+A,B,C,D,CLRQ,LOADQ,CLK,ENABLEP,ENABLET") + ENTRYX(74165, TTL_74165, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H") + ENTRYX(74166, TTL_74166, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H,CLRQ") + ENTRYX(74174, TTL_74174, "+CLK,D1,D2,D3,D4,D5,D6,CLRQ") + ENTRYX(74175, TTL_74175, "+CLK,D1,D2,D3,D4,CLRQ") + ENTRYX(74192, TTL_74192, "+A,B,C,D,CLEAR,LOADQ,CU,CD") + ENTRYX(74193, TTL_74193, "+A,B,C,D,CLEAR,LOADQ,CU,CD") + ENTRYX(74194, TTL_74194, "+CLK,S0,S1,SRIN,A,B,C,D,SLIN,CLRQ") + ENTRYX(74365, TTL_74365, "+G1Q,G2Q,A1,A2,A3,A4,A5,A6") //ENTRY(74279, TTL_74279, "-") // only dip available ENTRYX(SN74LS629, SN74LS629, "CAP") ENTRYX(82S16, TTL_82S16, "-") + ENTRYX(82S115, PROM_82S115, "+CE1Q,CE2,A0,A1,A2,A3,A4,A5,A6,A7,A8,STROBE") + ENTRYX(82S123, PROM_82S123, "+CEQ,A0,A1,A2,A3,A4") + ENTRYX(82S126, PROM_82S126, "+CE1Q,CE2Q,A0,A1,A2,A3,A4,A5,A6,A7") ENTRYX(9310, TTL_9310, "-") - ENTRYX(9312, TTL_9312, "-") + ENTRYX(9312, TTL_9312, "+A,B,C,D0,D1,D2,D3,D4,D5,D6,D7,G") ENTRYX(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D") + ENTRYX(9322, TTL_9322, "+SELECT,A1,B1,A2,B2,A3,B3,A4,B4,STROBE") + ENTRYX(9334, TTL_9334, "+CQ,EQ,D,A0,A1,A2") + ENTRYX(AM2847, TTL_AM2847, "+CP,INA,INB,INC,IND,RCA,RCB,RCC,RCD") ENTRYX(CD4020, CD4020, "") ENTRYX(CD4066_GATE, CD4066_GATE, "") /* entries with suffix WI are legacy only */ @@ -132,25 +153,46 @@ static void initialize_factory(factory_list_t &factory) //ENTRY(4066, CD_4066, "+A,B") ENTRYX(NE555, NE555, "-") ENTRYX(r2r_dac, R2R_DAC, "+VIN,R,N") + ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,D1,CEQ2,D2") + ENTRYX(tristate3, TTL_TRISTATE3, "-") + ENTRYX(2102A_dip, RAM_2102A_DIP, "-") + ENTRYX(2716_dip, EPROM_2716_DIP, "-") ENTRYX(4538_dip, CD4538_DIP, "-") ENTRYX(7448_dip, TTL_7448_DIP, "-") ENTRYX(7450_dip, TTL_7450_DIP, "-") + ENTRYX(7473_dip, TTL_7473_DIP, "-") + ENTRYX(7473A_dip, TTL_7473A_DIP, "-") ENTRYX(7474_dip, TTL_7474_DIP, "-") + ENTRYX(7475_dip, TTL_7475_DIP, "-") + ENTRYX(7477_dip, TTL_7477_DIP, "-") ENTRYX(7483_dip, TTL_7483_DIP, "-") + ENTRYX(7485_dip, TTL_7485_DIP, "-") ENTRYX(7490_dip, TTL_7490_DIP, "-") ENTRYX(7493_dip, TTL_7493_DIP, "-") ENTRYX(74107_dip, TTL_74107_DIP, "-") ENTRYX(74123_dip, TTL_74123_DIP, "-") ENTRYX(74153_dip, TTL_74153_DIP, "-") + ENTRYX(74161_dip, TTL_74161_DIP, "-") + ENTRYX(74165_dip, TTL_74165_DIP, "-") + ENTRYX(74166_dip, TTL_74166_DIP, "-") + ENTRYX(74174_dip, TTL_74174_DIP, "-") ENTRYX(74175_dip, TTL_74175_DIP, "-") ENTRYX(74192_dip, TTL_74192_DIP, "-") ENTRYX(74193_dip, TTL_74193_DIP, "-") + ENTRYX(74194_dip, TTL_74194_DIP, "-") ENTRYX(74279_dip, TTL_74279_DIP, "-") + ENTRYX(74365_dip, TTL_74365_DIP, "-") ENTRYX(82S16_dip, TTL_82S16_DIP, "-") + ENTRYX(82S115_dip, PROM_82S115_DIP, "-") + ENTRYX(82S123_dip, PROM_82S123_DIP, "-") + ENTRYX(82S126_dip, PROM_82S126_DIP, "-") ENTRYX(9602_dip, TTL_9602_DIP, "-") ENTRYX(9310_dip, TTL_9310_DIP, "-") ENTRYX(9312_dip, TTL_9312_DIP, "-") ENTRYX(9316_dip, TTL_9316_DIP, "-") + ENTRYX(9322_dip, TTL_9322_DIP, "-") + ENTRYX(9334_dip, TTL_9334_DIP, "-") + ENTRYX(AM2847_dip, TTL_AM2847_DIP, "-") ENTRYX(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2") ENTRYX(NE555_dip, NE555_DIP, "-") ENTRYX(MM5837_dip, MM5837_DIP, "-") diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index b87526bf391..c9c0b6b3917 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -14,32 +14,52 @@ #include "nl_base.h" #include "nld_system.h" +#include "nld_2102A.h" +#include "nld_2716.h" #include "nld_4020.h" #include "nld_4066.h" #include "nld_7448.h" #include "nld_7450.h" +#include "nld_7473.h" #include "nld_7474.h" +#include "nld_7475.h" #include "nld_7483.h" +#include "nld_7485.h" #include "nld_7490.h" #include "nld_7493.h" #include "nld_74107.h" #include "nld_74123.h" #include "nld_74153.h" +#include "nld_74161.h" +#include "nld_74165.h" +#include "nld_74166.h" +#include "nld_74174.h" #include "nld_74175.h" #include "nld_74192.h" #include "nld_74193.h" +#include "nld_74194.h" #include "nld_74279.h" +#include "nld_74365.h" #include "nld_74ls629.h" #include "nld_82S16.h" +#include "nld_82S115.h" +#include "nld_82S123.h" +#include "nld_82S126.h" #include "nld_9310.h" #include "nld_9312.h" #include "nld_9316.h" +#include "nld_9322.h" + +#include "nld_am2847.h" +#include "nld_dm9334.h" #include "nld_ne555.h" #include "nld_mm5837.h" #include "nld_r2r_dac.h" +#include "nld_tristate.h" + #include "nld_log.h" #include "macro/nlm_cd4xxx.h" diff --git a/src/lib/netlist/devices/nld_2102A.cpp b/src/lib/netlist/devices/nld_2102A.cpp new file mode 100644 index 00000000000..da8ffc3cc1d --- /dev/null +++ b/src/lib/netlist/devices/nld_2102A.cpp @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_2102A.cpp + * + */ + +#include "nld_2102A.h" + +#define ADDR2BYTE(a) ((a) >> 3) +#define ADDR2BIT(a) ((a) & 0x7) + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(2102A) + { + NETLIB_CONSTRUCTOR(2102A) + , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9" }}) + , m_CEQ(*this, "CEQ") + , m_RWQ(*this, "RWQ") + , m_DI(*this, "DI") + , m_DO(*this, "DO") + , m_ram(*this, "m_ram", 0) + , m_RAM(*this, "m_RAM", &m_ram[0]) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 10> m_A; + logic_input_t m_CEQ; + logic_input_t m_RWQ; + logic_input_t m_DI; + + logic_output_t m_DO; + + state_var<uint_fast8_t[128]> m_ram; // 1024x1 bits + param_ptr_t m_RAM; + }; + + NETLIB_OBJECT_DERIVED(2102A_dip, 2102A) + { + NETLIB_CONSTRUCTOR_DERIVED(2102A_dip, 2102A) + { + register_subalias("8", m_A[0]); + register_subalias("4", m_A[1]); + register_subalias("5", m_A[2]); + register_subalias("6", m_A[3]); + register_subalias("7", m_A[4]); + register_subalias("2", m_A[5]); + register_subalias("1", m_A[6]); + register_subalias("16", m_A[7]); + register_subalias("15", m_A[8]); + register_subalias("14", m_A[9]); + + register_subalias("13", m_CEQ); + register_subalias("3", m_RWQ); + + register_subalias("11", m_DI); + register_subalias("12", m_DO); + } + }; + + NETLIB_UPDATE(2102A) + { + netlist_time max_delay = NLTIME_FROM_NS(350); + + if (!m_CEQ()) + { + unsigned a = 0; + for (std::size_t i=0; i<10; i++) + { + a |= m_A[i]() << i; + } + const unsigned byte = ADDR2BYTE(a); + const unsigned bit = ADDR2BIT(a); + + if (!m_RWQ()) + { + m_ram[byte] &= ~(static_cast<uint_fast8_t>(1) << bit); + m_ram[byte] |= (static_cast<uint_fast8_t>(m_DI()) << bit); + } + + m_DO.push((m_ram[byte] >> bit) & 1, max_delay); + } + } + + NETLIB_RESET(2102A) + { + m_RAM.setTo(&m_ram[0]); + for (std::size_t i=0; i<128; i++) + m_ram[i] = 0; + } + + NETLIB_DEVICE_IMPL(2102A) + NETLIB_DEVICE_IMPL(2102A_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_2102A.h b/src/lib/netlist/devices/nld_2102A.h new file mode 100644 index 00000000000..bec20f9bd8c --- /dev/null +++ b/src/lib/netlist/devices/nld_2102A.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_2102A.h + * + * 2102: 1024 x 1-bit Static RAM + * + * +--------------+ + * A6 |1 ++ 16| A7 + * A5 |2 15| A8 + * RWQ |3 14| A9 + * A1 |4 82S16 13| CEQ + * A2 |5 12| DO + * A3 |6 11| DI + * A4 |7 10| VCC + * A0 |8 9| GND + * +--------------+ + * + * + * Naming conventions follow Intel datasheet + * + */ + +#ifndef NLD_2102A_H_ +#define NLD_2102A_H_ + +#include "nl_setup.h" + +#define RAM_2102A(name, cCEQ, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cRWQ, cDI) \ + NET_REGISTER_DEV(RAM_2102A, name) \ + NET_CONNECT(name, CEQ, cCEQ) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, A5, cA5) \ + NET_CONNECT(name, A6, cA6) \ + NET_CONNECT(name, A7, cA7) \ + NET_CONNECT(name, A8, cA8) \ + NET_CONNECT(name, A9, cA9) \ + NET_CONNECT(name, RWQ, cRWQ) \ + NET_CONNECT(name, DI, cDI) + +#define RAM_2102A_DIP(name) \ + NET_REGISTER_DEV(RAM_2102A_DIP, name) + +#endif /* NLD_2102A_H_ */ diff --git a/src/lib/netlist/devices/nld_2716.cpp b/src/lib/netlist/devices/nld_2716.cpp new file mode 100644 index 00000000000..7ba974b92da --- /dev/null +++ b/src/lib/netlist/devices/nld_2716.cpp @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_2716.cpp + * + */ + +#include "nld_2716.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(2716) + { + NETLIB_CONSTRUCTOR(2716) + , m_A(*this, {{ "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10" }}) + , m_GQ(*this, "GQ") + , m_EPQ(*this, "EPQ") + , m_D(*this, {{ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7" }}) + , m_last_EPQ(*this, "m_last_EPQ", 1) + , m_ROM(*this, "ROM") + { + } + + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 11> m_A; + logic_input_t m_GQ; + logic_input_t m_EPQ; + object_array_t<logic_output_t, 8> m_D; + + state_var<unsigned> m_last_EPQ; + + param_rom_t<uint8_t, 11, 8> m_ROM; // 16 Kbits, used as 2 Kbit x 8 + }; + + NETLIB_OBJECT_DERIVED(2716_dip, 2716) + { + NETLIB_CONSTRUCTOR_DERIVED(2716_dip, 2716) + { + register_subalias("8", m_A[0]); + register_subalias("7", m_A[1]); + register_subalias("6", m_A[2]); + register_subalias("5", m_A[3]); + register_subalias("4", m_A[4]); + register_subalias("3", m_A[5]); + register_subalias("2", m_A[6]); + register_subalias("1", m_A[7]); + register_subalias("23", m_A[8]); + register_subalias("22", m_A[9]); + register_subalias("19", m_A[10]); + + register_subalias("20", m_GQ); + register_subalias("18", m_EPQ); + + register_subalias("9", m_D[0]); + register_subalias("10", m_D[1]); + register_subalias("11", m_D[2]); + register_subalias("13", m_D[3]); + register_subalias("14", m_D[4]); + register_subalias("15", m_D[5]); + register_subalias("16", m_D[6]); + register_subalias("17", m_D[7]); + } + }; + + // FIXME: timing! + NETLIB_UPDATE(2716) + { + unsigned d = 0xff; + + netlist_time delay = NLTIME_FROM_NS(450); + if (!m_GQ() && !m_EPQ()) + { + unsigned a = 0; + for (std::size_t i=0; i<11; i++) + a |= (m_A[i]() << i); + + d = m_ROM[a]; + + if (m_last_EPQ) + delay = NLTIME_FROM_NS(120); + } + + m_last_EPQ = m_EPQ(); + + // FIXME: Outputs are tristate. This needs to be properly implemented + for (std::size_t i=0; i<8; i++) + m_D[i].push((d >> i) & 1, delay); + } + + NETLIB_DEVICE_IMPL(2716) + NETLIB_DEVICE_IMPL(2716_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_2716.h b/src/lib/netlist/devices/nld_2716.h new file mode 100644 index 00000000000..c96c726c11d --- /dev/null +++ b/src/lib/netlist/devices/nld_2716.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S126.h + * + * 2716: 16 Kbit (2Kb x 8) UV EPROM + * + * +----------------+ + * A7 |1 ++ 24| VCC + * A6 |2 23| A8 + * A5 |3 22| A9 + * A4 |4 2716 21| VPP + * A3 |5 20| GQ + * A2 |6 19| A10 + * A1 |7 18| EPQ + * A0 |8 17| D7 + * D0 |9 16| D6 + * D1 |10 15| D5 + * D2 |11 14| D4 + * VSS |12 13| D3 + * +----------------+ + * + * + * Naming conventions follow STMicro datasheet + * + */ + +#ifndef NLD_2716_H_ +#define NLD_2716_H_ + +#include "nl_setup.h" + +#define EPROM_2716(name, cGQ, cEPQ, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cA10) \ + NET_REGISTER_DEV(EPROM_2716, name) \ + NET_CONNECT(name, GQ, cGQ) \ + NET_CONNECT(name, EPQ, cEPQ) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, A5, cA5) \ + NET_CONNECT(name, A6, cA6) \ + NET_CONNECT(name, A7, cA7) \ + NET_CONNECT(name, A8, cA8) \ + NET_CONNECT(name, A9, cA9) \ + NET_CONNECT(name, A10, cA10) + +#define EPROM_2716_DIP(name) \ + NET_REGISTER_DEV(EPROM_2716_DIP, name) + +#endif /* NLD_2716_H_ */ diff --git a/src/lib/netlist/devices/nld_4066.h b/src/lib/netlist/devices/nld_4066.h index 570f9ecf16d..fdaa76d65f3 100644 --- a/src/lib/netlist/devices/nld_4066.h +++ b/src/lib/netlist/devices/nld_4066.h @@ -15,7 +15,7 @@ * VSS |7 8| INOUTC * +--------------+ * - * FIXME: These devices are slow (~125 ns). THis is currently not reflected + * FIXME: These devices are slow (~125 ns). This is currently not reflected * * Naming conventions follow National semiconductor datasheet * diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp new file mode 100644 index 00000000000..257ee0aac83 --- /dev/null +++ b/src/lib/netlist/devices/nld_4316.cpp @@ -0,0 +1,49 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + * nld_4316.c + * + */ + +#include <devices/nlid_cmos.h> +#include "analog/nld_twoterm.h" +#include "nld_4316.h" + +namespace netlist { namespace devices { + + NETLIB_OBJECT(CD4316_GATE) + { + NETLIB_CONSTRUCTOR(CD4316_GATE) + NETLIB_FAMILY("CD4XXX") + , m_supply(*this, "PS") + , m_R(*this, "R") + , m_S(*this, "S") + , m_E(*this, "E") + , m_base_r(*this, "BASER", 45.0) + { + } + + NETLIB_RESETI() { } + NETLIB_UPDATEI(); + + public: + NETLIB_SUB(vdd_vss) m_supply; + NETLIB_SUB(R) m_R; + + logic_input_t m_S, m_E; + param_double_t m_base_r; + }; + + NETLIB_UPDATE(CD4316_GATE) + { + m_R.update_dev(); + if (m_S() && !m_E()) + m_R.set_R(m_base_r()); + else + m_R.set_R(NL_FCONST(1.0) / netlist().gmin()); + m_R.m_P.schedule_after(NLTIME_FROM_NS(1)); + } + + NETLIB_DEVICE_IMPL(CD4316_GATE) + +} } // namesapce netlist::devices diff --git a/src/lib/netlist/devices/nld_4316.h b/src/lib/netlist/devices/nld_4316.h new file mode 100644 index 00000000000..8d8ec4f0ae0 --- /dev/null +++ b/src/lib/netlist/devices/nld_4316.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + * nld_4136.h + * + * CD4066: Quad Analog Switch with Level Translation + * + * +--------------+ + * 1Z |1 ++ 16| VCC + * 1Y |2 15| 1S + * 2Y |3 14| 4S + * 2Z |4 4066 13| 4Z + * 2S |5 12| 4Y + * 3S |6 11| 3Y + * /E |7 10| 3Z + * GND |8 9| VEE + * +--------------+ + * + * FIXME: These devices are slow (can be over 200 ns in HC types). This is currently not reflected + * + * Naming conventions follow Texas Instruments datasheet + * + */ + +#ifndef NLD_4316_H_ +#define NLD_4316_H_ + +#include "nl_setup.h" + +#define CD4316_GATE(name) \ + NET_REGISTER_DEV(CD4316_GATE, name) + +#endif /* NLD_4316_H_ */ diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp index a0ffcfc3fdd..a9006d55a75 100644 --- a/src/lib/netlist/devices/nld_74107.cpp +++ b/src/lib/netlist/devices/nld_74107.cpp @@ -11,6 +11,10 @@ namespace netlist { namespace devices { + + static const netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) }; + static const netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) }; + NETLIB_OBJECT(74107Asub) { NETLIB_CONSTRUCTOR(74107Asub) @@ -20,6 +24,7 @@ namespace netlist , m_Q1(*this, "m_Q1", 0) , m_Q2(*this, "m_Q2", 0) , m_F(*this, "m_F", 0) + , m_delay(delay_107A) { } @@ -38,6 +43,8 @@ namespace netlist void newstate(const netlist_sig_t state); + const netlist_time *m_delay; + }; NETLIB_OBJECT(74107A) @@ -67,8 +74,10 @@ namespace netlist NETLIB_OBJECT_DERIVED(74107, 74107A) { public: - NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A) { } - + NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A) + { + m_sub.m_delay = delay_107; + } }; NETLIB_OBJECT(74107_dip) @@ -119,10 +128,8 @@ namespace netlist inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state) { - const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) }; - - m_Q.push(state, delay[state]); - m_QQ.push(state ^ 1, delay[state ^ 1]); + m_Q.push(state, m_delay[state]); + m_QQ.push(state ^ 1, m_delay[state ^ 1]); } NETLIB_UPDATE(74107Asub) diff --git a/src/lib/netlist/devices/nld_74107.h b/src/lib/netlist/devices/nld_74107.h index ea73256e818..ed940f8170f 100644 --- a/src/lib/netlist/devices/nld_74107.h +++ b/src/lib/netlist/devices/nld_74107.h @@ -32,7 +32,9 @@ * * This is positive triggered, J and K * are latched during clock high and - * transferred when CLK falls. + * transferred when CLK falls. The + * datasheet requires J and K to be + * stable during clock high. * * Function table 107A * @@ -51,8 +53,11 @@ * * Naming conventions follow Texas instruments datasheet * - * FIXME: Currently, only the 107A is implemented. - * The 107 uses the same model. + * TODO: Currently, only the 107A is implemented. + * The 107 uses the same model, but different timings. + * The requirement that J and K must be stable during + * clock high indicates that the chip may exhibit undefined + * behaviour. * */ @@ -71,7 +76,7 @@ #define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \ TTL_74107A(name, cCLK, cJ, cK, cCLRQ) -#define TTL_74107_DIP(name) \ +#define TTL_74107_DIP(name) \ NET_REGISTER_DEV(TTL_74107_DIP, name) #endif /* NLD_74107_H_ */ diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index 0e36e2ed487..0bc1a60acb0 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -42,12 +42,14 @@ namespace netlist register_subalias("C", m_RN.m_R.m_N); register_subalias("RC", m_RN.m_R.m_P); - connect_late(m_RP_Q, m_RP.m_I); connect_late(m_RN_Q, m_RN.m_I); connect_late(m_RN.m_R.m_P, m_RP.m_R.m_N); connect_late(m_CV, m_RN.m_R.m_P); + + m_RP.m_RON.setTo(m_RI()); + m_RN.m_RON.setTo(m_RI()); } NETLIB_RESETI(); diff --git a/src/lib/netlist/devices/nld_74161.cpp b/src/lib/netlist/devices/nld_74161.cpp new file mode 100644 index 00000000000..d6e31f36417 --- /dev/null +++ b/src/lib/netlist/devices/nld_74161.cpp @@ -0,0 +1,133 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74161.cpp + * + */ + +#define MAXCNT 15 + +#include "nld_74161.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74161) + { + NETLIB_CONSTRUCTOR(74161) + , m_A(*this, "A") + , m_B(*this, "B") + , m_C(*this, "C") + , m_D(*this, "D") + , m_CLRQ(*this, "CLRQ") + , m_LOADQ(*this, "LOADQ") + , m_CLK(*this, "CLK") + , m_ENABLEP(*this, "ENABLEP") + , m_ENABLET(*this, "ENABLET") + , m_cnt(*this, "m_cnt", 0) + , m_last_CLK(*this, "m_last_CLK", 0) + , m_Q(*this, {{"QA", "QB", "QC", "QD"}}) + , m_RCO(*this, "RCO") + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + logic_input_t m_A; + logic_input_t m_B; + logic_input_t m_C; + logic_input_t m_D; + logic_input_t m_CLRQ; + logic_input_t m_LOADQ; + logic_input_t m_CLK; + logic_input_t m_ENABLEP; + logic_input_t m_ENABLET; + + state_var<unsigned> m_cnt; + state_var<unsigned> m_last_CLK; + + object_array_t<logic_output_t, 4> m_Q; + logic_output_t m_RCO; + }; + + NETLIB_OBJECT_DERIVED(74161_dip, 74161) + { + NETLIB_CONSTRUCTOR_DERIVED(74161_dip, 74161) + { + register_subalias("1", m_CLRQ); + register_subalias("2", m_CLK); + register_subalias("3", m_A); + register_subalias("4", m_B); + register_subalias("5", m_C); + register_subalias("6", m_D); + register_subalias("7", m_ENABLEP); + + register_subalias("9", m_LOADQ); + register_subalias("10", m_ENABLET); + register_subalias("11", m_Q[3]); + register_subalias("12", m_Q[2]); + register_subalias("13", m_Q[1]); + register_subalias("14", m_Q[0]); + register_subalias("15", m_RCO); + + } + }; + + NETLIB_RESET(74161) + { + m_cnt = 0; + m_last_CLK = 0; + } + + // FIXME: Timing + static const netlist_time delay[4] = + { + NLTIME_FROM_NS(40), + NLTIME_FROM_NS(40), + NLTIME_FROM_NS(40), + NLTIME_FROM_NS(40) + }; + + NETLIB_UPDATE(74161) + { + netlist_sig_t tRippleCarryOut = 0; + if (!m_CLRQ()) + { + m_cnt = 0; + } + else if (m_CLK() && !m_last_CLK) + { + if (!m_LOADQ()) + { + m_cnt = (m_D() << 3) | (m_C() << 2) + | (m_B() << 1) | (m_A() << 0); + } + else if (m_ENABLET() && m_ENABLEP()) + { + m_cnt++; + if (m_cnt > MAXCNT) + m_cnt = 0; + } + } + + if (m_ENABLET() && (m_cnt == MAXCNT)) + { + tRippleCarryOut = 1; + } + + m_last_CLK = m_CLK(); + + for (std::size_t i=0; i<4; i++) + m_Q[i].push((m_cnt >> i) & 1, delay[i]); + + m_RCO.push(tRippleCarryOut, NLTIME_FROM_NS(20)); //FIXME + } + + NETLIB_DEVICE_IMPL(74161) + NETLIB_DEVICE_IMPL(74161_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74161.h b/src/lib/netlist/devices/nld_74161.h new file mode 100644 index 00000000000..1a6b6b2ca87 --- /dev/null +++ b/src/lib/netlist/devices/nld_74161.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74161.h + * + * DM74161: Synchronous 4-Bit Binary Counter with Clock + * + * +--------------+ + * CLEAR |1 ++ 16| VCC + * CLK |2 15| RCO + * A |3 14| QA + * B |4 74161 13| QB + * C |5 12| QC + * D |6 11| QD + * ENABLEP |7 10| ENABLET + * GND |8 9| LOAD + * +--------------+ + * + * RCO: Ripple carry output + * + * Naming convention attempts to follow National Semiconductor datasheet + * + */ + +#ifndef NLD_74161_H_ +#define NLD_74161_H_ + +#include "nl_setup.h" + +#define TTL_74161(name, cA, cB, cC, cD, cCLRQ, cLOADQ, cCLK, cENABLEP, cENABLET) \ + NET_REGISTER_DEV(TTL_74161, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, CLRQ, cCLRQ) \ + NET_CONNECT(name, LOADQ, cLOADQ) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, ENABLEP, cENABLEP) \ + NET_CONNECT(name, ENABLET, cENABLET) + +#define TTL_74161_DIP(name) \ + NET_REGISTER_DEV(TTL_74161_DIP, name) + +#endif /* NLD_74161_H_ */ diff --git a/src/lib/netlist/devices/nld_74165.cpp b/src/lib/netlist/devices/nld_74165.cpp new file mode 100644 index 00000000000..bb263409bf9 --- /dev/null +++ b/src/lib/netlist/devices/nld_74165.cpp @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74165.cpp + * + */ + +#include "nld_74165.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74165) + { + NETLIB_CONSTRUCTOR(74165) + , m_DATA(*this, {{ "H", "G", "F", "E", "D", "C", "B", "A" }}) + , m_SER(*this, "SER") + , m_SH_LDQ(*this, "SH_LDQ") + , m_CLK(*this, "CLK") + , m_CLKINH(*this, "CLKINH") + , m_QH(*this, "QH") + , m_QHQ(*this, "QHQ") + , m_shifter(*this, "m_shifter", 0) + , m_last_CLK(*this, "m_last_CLK", 0) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 8> m_DATA; + logic_input_t m_SER; + logic_input_t m_SH_LDQ; + logic_input_t m_CLK; + logic_input_t m_CLKINH; + logic_output_t m_QH; + logic_output_t m_QHQ; + + state_var<unsigned> m_shifter; + state_var<unsigned> m_last_CLK; + }; + + NETLIB_OBJECT_DERIVED(74165_dip, 74165) + { + NETLIB_CONSTRUCTOR_DERIVED(74165_dip, 74165) + { + register_subalias("1", m_SH_LDQ); + register_subalias("2", m_CLK); + register_subalias("3", m_DATA[4]); + register_subalias("4", m_DATA[5]); + register_subalias("5", m_DATA[6]); + register_subalias("6", m_DATA[7]); + register_subalias("7", m_QHQ); + + register_subalias("9", m_QH); + register_subalias("10", m_SER); + register_subalias("11", m_DATA[0]); + register_subalias("12", m_DATA[1]); + register_subalias("13", m_DATA[2]); + register_subalias("14", m_DATA[3]); + register_subalias("15", m_CLKINH); + + } + }; + + NETLIB_RESET(74165) + { + m_shifter = 0; + m_last_CLK = 0; + } + + // FIXME: Timing + NETLIB_UPDATE(74165) + { + netlist_sig_t old_qh = m_QH.net().Q(); + netlist_sig_t qh = 0; + + if (!m_SH_LDQ()) + { + m_shifter = 0; + for (std::size_t i=0; i<8; i++) + m_shifter |= (m_DATA[i]() << i); + } + else if (!m_CLK() || m_CLKINH()) + { + qh = old_qh; + } + else if (!m_last_CLK) + { + unsigned high_bit = m_SER() ? 0x80 : 0; + m_shifter = high_bit | (m_shifter >> 1); + } + + qh = m_shifter & 1; + + m_last_CLK = m_CLK(); + + m_QH.push(qh, NLTIME_FROM_NS(20)); // FIXME: Timing + } + + NETLIB_DEVICE_IMPL(74165) + NETLIB_DEVICE_IMPL(74165_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74165.h b/src/lib/netlist/devices/nld_74165.h new file mode 100644 index 00000000000..30970f5a20e --- /dev/null +++ b/src/lib/netlist/devices/nld_74165.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74165.h + * + * 74165: Parallel-Load 8-Bit Shift Register + * + * +--------------+ + * SH/LDQ |1 ++ 16| VCC + * CLK |2 15| CLKINH + * E |3 14| D + * F |4 74165 13| C + * G |5 12| B + * H |6 11| A + * QHQ |7 10| SER + * GND |8 9| QH + * +--------------+ + * + * SH/LDQ: Shift / !Load + * CLKINH: Clock Inhibit + * SER: Serial In + * + * Naming convention attempts to follow NTE Electronics datasheet + * + */ + +#ifndef NLD_74165_H_ +#define NLD_74165_H_ + +#include "nl_setup.h" + +#define TTL_74165(name, cCLK, cCLKINH, cSH_LDQ, cSER, cA, cB, cC, cD, cE, cF, cG, cH) \ + NET_REGISTER_DEV(TTL_74165, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, CLKINH, cCLKINH) \ + NET_CONNECT(name, SH_LDQ, cSH_LDQ) \ + NET_CONNECT(name, SER, cSER) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, E, cE) \ + NET_CONNECT(name, F, cF) \ + NET_CONNECT(name, G, cG) \ + NET_CONNECT(name, H, cH) + +#define TTL_74165_DIP(name) \ + NET_REGISTER_DEV(TTL_74165_DIP, name) + +#endif /* NLD_74165_H_ */ diff --git a/src/lib/netlist/devices/nld_74166.cpp b/src/lib/netlist/devices/nld_74166.cpp new file mode 100644 index 00000000000..5cb7114ee0f --- /dev/null +++ b/src/lib/netlist/devices/nld_74166.cpp @@ -0,0 +1,127 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74166.cpp + * + */ + +#include "nld_74166.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74166) + { + NETLIB_CONSTRUCTOR(74166) + , m_DATA(*this, {{ "H", "G", "F", "E", "D", "C", "B", "A" }}) + , m_SER(*this, "SER") + , m_CLRQ(*this, "CLRQ") + , m_SH_LDQ(*this, "SH_LDQ") + , m_CLK(*this, "CLK") + , m_CLKINH(*this, "CLKINH") + , m_QH(*this, "QH") + , m_shifter(*this, "m_shifter", 0) + , m_last_CLRQ(*this, "m_last_CLRQ", 0) + , m_last_CLK(*this, "m_last_CLK", 0) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 8> m_DATA; + logic_input_t m_SER; + logic_input_t m_CLRQ; + logic_input_t m_SH_LDQ; + logic_input_t m_CLK; + logic_input_t m_CLKINH; + logic_output_t m_QH; + + state_var<unsigned> m_shifter; + state_var<unsigned> m_last_CLRQ; + state_var<unsigned> m_last_CLK; + }; + + NETLIB_OBJECT_DERIVED(74166_dip, 74166) + { + NETLIB_CONSTRUCTOR_DERIVED(74166_dip, 74166) + { + register_subalias("1", m_SER); + register_subalias("2", m_DATA[7]); + register_subalias("3", m_DATA[6]); + register_subalias("4", m_DATA[5]); + register_subalias("5", m_DATA[4]); + register_subalias("6", m_CLKINH); + register_subalias("7", m_CLK); + + register_subalias("9", m_CLRQ); + register_subalias("10", m_DATA[3]); + register_subalias("11", m_DATA[2]); + register_subalias("12", m_DATA[1]); + register_subalias("13", m_QH); + register_subalias("14", m_DATA[0]); + register_subalias("15", m_SH_LDQ); + + } + }; + + NETLIB_RESET(74166) + { + m_shifter = 0; + m_last_CLRQ = 0; + m_last_CLK = 0; + } + + NETLIB_UPDATE(74166) + { + netlist_sig_t old_qh = m_QH.net().Q(); + netlist_sig_t qh = 0; + + netlist_time delay = NLTIME_FROM_NS(26); + if (m_CLRQ()) + { + bool clear_unset = !m_last_CLRQ(); + if (clear_unset) + { + delay = NLTIME_FROM_NS(35); + } + + if (!m_CLK() || m_CLKINH()) + { + qh = old_qh; + } + else if (!m_last_CLK) + { + if (!m_SH_LDQ()) + { + m_shifter = 0; + for (std::size_t i=0; i<8; i++) + m_shifter |= (m_DATA[i]() << i); + } + else + { + unsigned high_bit = m_SER() ? 0x80 : 0; + m_shifter = high_bit | (m_shifter >> 1); + } + + qh = m_shifter & 1; + if (!qh && !clear_unset) + { + delay = NLTIME_FROM_NS(30); + } + } + } + + m_last_CLRQ = m_CLRQ(); + m_last_CLK = m_CLK(); + + m_QH.push(qh, delay); //FIXME + } + + NETLIB_DEVICE_IMPL(74166) + NETLIB_DEVICE_IMPL(74166_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74166.h b/src/lib/netlist/devices/nld_74166.h new file mode 100644 index 00000000000..bf5bbc8d0d8 --- /dev/null +++ b/src/lib/netlist/devices/nld_74166.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74166.h + * + * 74166: Parallel-Load 8-Bit Shift Register + * + * +--------------+ + * SER |1 ++ 16| VCC + * A |2 15| SH/LDQ + * B |3 14| H + * C |4 74166 13| QH + * D |5 12| G + * CLKINH |6 11| F + * CLK |7 10| E + * GND |8 9| CLRQ + * +--------------+ + * + * SH/LDQ: Shift / !Load + * CLKINH: Clock Inhibit + * SER: Serial In + * + * Naming convention attempts to follow Texas Instruments datasheet + * + */ + +#ifndef NLD_74166_H_ +#define NLD_74166_H_ + +#include "nl_setup.h" + +#define TTL_74166(name, cCLK, cCLKINH, cSH_LDQ, cSER, cA, cB, cC, cD, cE, cF, cG, cH, cCLRQ) \ + NET_REGISTER_DEV(TTL_74166, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, CLKINH, cCLKINH) \ + NET_CONNECT(name, SH_LDQ, cSH_LDQ) \ + NET_CONNECT(name, SER, cSER) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, E, cE) \ + NET_CONNECT(name, F, cF) \ + NET_CONNECT(name, G, cG) \ + NET_CONNECT(name, H, cH) \ + NET_CONNECT(name, CLRQ, cCLRQ) + +#define TTL_74166_DIP(name) \ + NET_REGISTER_DEV(TTL_74166_DIP, name) + +#endif /* NLD_74166_H_ */ diff --git a/src/lib/netlist/devices/nld_74174.cpp b/src/lib/netlist/devices/nld_74174.cpp new file mode 100644 index 00000000000..64698423435 --- /dev/null +++ b/src/lib/netlist/devices/nld_74174.cpp @@ -0,0 +1,140 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nld_74174.cpp + * + */ + +#include "nld_74174.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74174_sub) + { + NETLIB_CONSTRUCTOR(74174_sub) + , m_CLK(*this, "CLK") + , m_Q(*this, {{"Q1", "Q2", "Q3", "Q4", "Q5", "Q6"}}) + , m_clrq(*this, "m_clr", 0) + , m_data(*this, "m_data", 0) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + public: + logic_input_t m_CLK; + object_array_t<logic_output_t, 6> m_Q; + + state_var<netlist_sig_t> m_clrq; + state_var<unsigned> m_data; + }; + + NETLIB_OBJECT(74174) + { + NETLIB_CONSTRUCTOR(74174) + , m_sub(*this, "sub") + , m_D(*this, {{"D1", "D2", "D3", "D4", "D5", "D6"}}) + , m_CLRQ(*this, "CLRQ") + { + register_subalias("CLK", m_sub.m_CLK); + + register_subalias("Q1", m_sub.m_Q[0]); + register_subalias("Q2", m_sub.m_Q[1]); + register_subalias("Q3", m_sub.m_Q[2]); + register_subalias("Q4", m_sub.m_Q[3]); + register_subalias("Q5", m_sub.m_Q[4]); + register_subalias("Q6", m_sub.m_Q[5]); + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + NETLIB_SUB(74174_sub) m_sub; + object_array_t<logic_input_t, 6> m_D; + logic_input_t m_CLRQ; + }; + + NETLIB_OBJECT_DERIVED(74174_dip, 74174) + { + NETLIB_CONSTRUCTOR_DERIVED(74174_dip, 74174) + { + register_subalias("1", m_CLRQ); + register_subalias("9", m_sub.m_CLK); + + register_subalias("3", m_D[0]); + register_subalias("2", m_sub.m_Q[0]); + + register_subalias("4", m_D[1]); + register_subalias("5", m_sub.m_Q[1]); + + register_subalias("6", m_D[2]); + register_subalias("7", m_sub.m_Q[2]); + + register_subalias("11", m_D[3]); + register_subalias("10", m_sub.m_Q[3]); + + register_subalias("13", m_D[4]); + register_subalias("12", m_sub.m_Q[4]); + + register_subalias("14", m_D[5]); + register_subalias("15", m_sub.m_Q[5]); + } + }; + + NETLIB_RESET(74174_sub) + { + m_CLK.set_state(logic_t::STATE_INP_LH); + m_clrq = 0; + m_data = 0xFF; + } + + NETLIB_UPDATE(74174_sub) + { + if (m_clrq) + { + for (std::size_t i=0; i<6; i++) + { + netlist_sig_t d = (m_data >> i) & 1; + m_Q[i].push(d, NLTIME_FROM_NS(25)); + } + m_CLK.inactivate(); + } + } + + NETLIB_UPDATE(74174) + { + uint_fast8_t d = 0; + for (std::size_t i=0; i<6; i++) + { + d |= (m_D[i]() << i); + } + m_sub.m_clrq = m_CLRQ(); + if (!m_sub.m_clrq) + { + for (std::size_t i=0; i<6; i++) + { + m_sub.m_Q[i].push(0, NLTIME_FROM_NS(40)); + } + m_sub.m_data = 0; + } else if (d != m_sub.m_data) + { + m_sub.m_data = d; + m_sub.m_CLK.activate_lh(); + } + } + + + NETLIB_RESET(74174) + { + //m_sub.do_reset(); + } + + NETLIB_DEVICE_IMPL(74174) + NETLIB_DEVICE_IMPL(74174_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74174.h b/src/lib/netlist/devices/nld_74174.h new file mode 100644 index 00000000000..43125b6af96 --- /dev/null +++ b/src/lib/netlist/devices/nld_74174.h @@ -0,0 +1,56 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nld_74174.h + * + * DM74174: Hex D Flip-Flops with Clear + * + * +--------------+ + * CLR |1 ++ 16| VCC + * Q1 |2 15| Q6 + * D1 |3 14| D6 + * D2 |4 74174 13| D5 + * Q2 |5 12| Q5 + * D3 |6 11| D4 + * Q3 |7 10| Q4 + * GND |8 9| CLK + * +--------------+ + * + * +-----+-----+---++---+-----+ + * | CLR | CLK | D || Q | QQ | + * +=====+=====+===++===+=====+ + * | 0 | X | X || 0 | 1 | + * | 1 | R | 1 || 1 | 0 | + * | 1 | R | 0 || 0 | 1 | + * | 1 | 0 | X || Q0| Q0Q | + * +-----+-----+---++---+-----+ + * + * Q0 The output logic level of Q before the indicated input conditions were established + * + * R: 0 -> 1 + * + * Naming conventions follow National Semiconductor datasheet + * + */ + +#ifndef NLD_74174_H_ +#define NLD_74174_H_ + +#include "nl_setup.h" + +#define TTL_74174(name, cCLK, cD1, cD2, cD3, cD4, cD5, cD6, cCLRQ) \ + NET_REGISTER_DEV(TTL_74174, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, D2, cD2) \ + NET_CONNECT(name, D3, cD3) \ + NET_CONNECT(name, D4, cD4) \ + NET_CONNECT(name, D5, cD5) \ + NET_CONNECT(name, D6, cD6) \ + NET_CONNECT(name, CLRQ, cCLRQ) + +#define TTL_74174_DIP(name) \ + NET_REGISTER_DEV(TTL_74174_DIP, name) + + +#endif /* NLD_74174_H_ */ diff --git a/src/lib/netlist/devices/nld_74175.h b/src/lib/netlist/devices/nld_74175.h index 8b08060e520..27dd01a2360 100644 --- a/src/lib/netlist/devices/nld_74175.h +++ b/src/lib/netlist/devices/nld_74175.h @@ -38,8 +38,15 @@ #include "nl_setup.h" -#define TTL_74175(name) \ - NET_REGISTER_DEV(TTL_74175, name) +#define TTL_74175(name, cCLK, cD1, cD2, cD3, cD4, cCLRQ) \ + NET_REGISTER_DEV(TTL_74175, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, D2, cD2) \ + NET_CONNECT(name, D3, cD3) \ + NET_CONNECT(name, D4, cD4) \ + NET_CONNECT(name, CLRQ, cCLRQ) + #define TTL_74175_DIP(name) \ NET_REGISTER_DEV(TTL_74175_DIP, name) diff --git a/src/lib/netlist/devices/nld_74192.h b/src/lib/netlist/devices/nld_74192.h index fc5778044eb..8c82006fe6c 100644 --- a/src/lib/netlist/devices/nld_74192.h +++ b/src/lib/netlist/devices/nld_74192.h @@ -31,8 +31,16 @@ #include "nl_setup.h" -#define TTL_74192(name) \ - NET_REGISTER_DEV(TTL_74192, name) +#define TTL_74192(name, cA, cB, cC, cD, cCLEAR, cLOADQ, cCU, cCD) \ + NET_REGISTER_DEV(TTL_74192, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, CLEAR, cCLEAR) \ + NET_CONNECT(name, LOADQ, cLOADQ) \ + NET_CONNECT(name, CU, cCU) \ + NET_CONNECT(name, CD, cCD) #define TTL_74192_DIP(name) \ NET_REGISTER_DEV(TTL_74192_DIP, name) diff --git a/src/lib/netlist/devices/nld_74193.h b/src/lib/netlist/devices/nld_74193.h index fa2b8125092..53b6165e9f9 100644 --- a/src/lib/netlist/devices/nld_74193.h +++ b/src/lib/netlist/devices/nld_74193.h @@ -28,8 +28,16 @@ #include "nl_setup.h" -#define TTL_74193(name) \ - NET_REGISTER_DEV(TTL_74193, name) +#define TTL_74193(name, cA, cB, cC, cD, cCLEAR, cLOADQ, cCU, cCD) \ + NET_REGISTER_DEV(TTL_74193, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, CLEAR, cCLEAR) \ + NET_CONNECT(name, LOADQ, cLOADQ) \ + NET_CONNECT(name, CU, cCU) \ + NET_CONNECT(name, CD, cCD) #define TTL_74193_DIP(name) \ NET_REGISTER_DEV(TTL_74193_DIP, name) diff --git a/src/lib/netlist/devices/nld_74194.cpp b/src/lib/netlist/devices/nld_74194.cpp new file mode 100644 index 00000000000..e951e351e93 --- /dev/null +++ b/src/lib/netlist/devices/nld_74194.cpp @@ -0,0 +1,122 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74194.cpp + * + */ + +#include "nld_74194.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74194) + { + NETLIB_CONSTRUCTOR(74194) + , m_DATA(*this, {{"D", "C", "B", "A"}}) + , m_SLIN(*this, "SLIN") + , m_SRIN(*this, "SRIN") + , m_CLK(*this, "CLK") + , m_S0(*this, "S0") + , m_S1(*this, "S1") + , m_CLRQ(*this, "CLRQ") + , m_Q(*this, {{"QD", "QC", "QB", "QA"}}) + , m_last_CLK(*this, "m_last_CLK", 0) + , m_last_Q(*this, "m_last_Q", 0) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 4> m_DATA; + logic_input_t m_SLIN; + logic_input_t m_SRIN; + logic_input_t m_CLK; + logic_input_t m_S0; + logic_input_t m_S1; + logic_input_t m_CLRQ; + object_array_t<logic_output_t, 4> m_Q; + + state_var<unsigned> m_last_CLK; + state_var<unsigned> m_last_Q; + }; + + NETLIB_OBJECT_DERIVED(74194_dip, 74194) + { + NETLIB_CONSTRUCTOR_DERIVED(74194_dip, 74194) + { + register_subalias("1", m_CLRQ); + register_subalias("2", m_SRIN); + register_subalias("3", m_DATA[3]); + register_subalias("4", m_DATA[2]); + register_subalias("5", m_DATA[1]); + register_subalias("6", m_DATA[0]); + register_subalias("7", m_SLIN); + + register_subalias("9", m_S0); + register_subalias("10", m_S1); + register_subalias("11", m_CLK); + register_subalias("12", m_Q[0]); + register_subalias("13", m_Q[1]); + register_subalias("14", m_Q[2]); + register_subalias("15", m_Q[3]); + + } + }; + + NETLIB_RESET(74194) + { + m_last_CLK = 0; + m_last_Q = 0; + } + + // FIXME: Timing + NETLIB_UPDATE(74194) + { + unsigned q = m_last_Q; + + if (!m_CLRQ()) + { + q = 0; + } + else + { + if (!m_last_CLK && m_CLK()) + { + unsigned s = (m_S1() << 1) | m_S0(); + switch (s) + { + case 0: // LL: Keep old value + break; + case 1: // LH: Shift right + q >>= 1; + q |= m_SRIN() ? 8 : 0; + break; + case 2: + q <<= 1; + q |= m_SLIN() ? 1 : 0; + break; + case 3: + q = 0; + for (std::size_t i=0; i<4; i++) + q |= m_DATA[i]() << i; + break; + } + } + } + + m_last_Q = q; + m_last_CLK = m_CLK(); + + for (std::size_t i=0; i<4; i++) + m_Q[i].push((q >> i) & 1, NLTIME_FROM_NS(26)); // FIXME: Timing + } + + NETLIB_DEVICE_IMPL(74194) + NETLIB_DEVICE_IMPL(74194_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74194.h b/src/lib/netlist/devices/nld_74194.h new file mode 100644 index 00000000000..944d9537754 --- /dev/null +++ b/src/lib/netlist/devices/nld_74194.h @@ -0,0 +1,47 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74194.h + * + * 74194: Parallel-Load 8-Bit Shift Register + * + * +--------------+ + * CLRQ |1 ++ 16| VCC + * SRIN |2 15| QA + * A |3 14| QB + * B |4 74194 13| QC + * C |5 12| QD + * D |6 11| CLK + * SLIN |7 10| S1 + * GND |8 9| S0 + * +--------------+ + * + * CLR: Clear + * SRIN: Shift Right Serial Input + * SLIN: Shift Left Serial Input + * CLK: Clock + * + */ + +#ifndef NLD_74194_H_ +#define NLD_74194_H_ + +#include "nl_setup.h" + +#define TTL_74194(name, cCLK, cS0, cS1, cSRIN, cA, cB, cC, cD, cSLIN, cCLRQ) \ + NET_REGISTER_DEV(TTL_74194, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, S0, cS0) \ + NET_CONNECT(name, S1, cS1) \ + NET_CONNECT(name, SRIN, cSRIN) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, SLIN, cSLIN) \ + NET_CONNECT(name, CLRQ, cCLRQ) + +#define TTL_74194_DIP(name) \ + NET_REGISTER_DEV(TTL_74194_DIP, name) + +#endif /* NLD_74194_H_ */ diff --git a/src/lib/netlist/devices/nld_74365.cpp b/src/lib/netlist/devices/nld_74365.cpp new file mode 100644 index 00000000000..34eafb0856e --- /dev/null +++ b/src/lib/netlist/devices/nld_74365.cpp @@ -0,0 +1,74 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74365.cpp + * + */ + +#include "nld_74365.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74365) + { + NETLIB_CONSTRUCTOR(74365) + , m_G1Q(*this, "G1Q") + , m_G2Q(*this, "G2Q") + , m_A(*this, {{ "A1", "A2", "A3", "A4", "A5", "A6" }}) + , m_Y(*this, {{ "Y1", "Y2", "Y3", "Y4", "Y5", "Y6" }}) + { + } + + NETLIB_UPDATEI(); + + protected: + logic_input_t m_G1Q; + logic_input_t m_G2Q; + object_array_t<logic_input_t, 6> m_A; + object_array_t<logic_output_t, 6> m_Y; + }; + + NETLIB_OBJECT_DERIVED(74365_dip, 74365) + { + NETLIB_CONSTRUCTOR_DERIVED(74365_dip, 74365) + { + register_subalias("1", m_G1Q); + register_subalias("2", m_A[0]); + register_subalias("3", m_Y[0]); + register_subalias("4", m_A[1]); + register_subalias("5", m_Y[1]); + register_subalias("6", m_A[2]); + register_subalias("7", m_Y[2]); + + register_subalias("9", m_A[3]); + register_subalias("10", m_Y[3]); + register_subalias("11", m_A[4]); + register_subalias("12", m_Y[4]); + register_subalias("13", m_A[5]); + register_subalias("14", m_Y[5]); + register_subalias("15", m_G2Q); + + } + }; + + NETLIB_UPDATE(74365) + { + if (!m_G1Q() && !m_G2Q()) + { + for (std::size_t i=0; i<6; i++) + m_Y[i].push(m_A[i](), NLTIME_FROM_NS(20)); // FIXME: Correct timing + } + else + { + for (std::size_t i=0; i<6; i++) + m_Y[i].push(0, NLTIME_FROM_NS(20)); // FIXME: Correct timing + } + } + + NETLIB_DEVICE_IMPL(74365) + NETLIB_DEVICE_IMPL(74365_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74365.h b/src/lib/netlist/devices/nld_74365.h new file mode 100644 index 00000000000..2a7fb230e5e --- /dev/null +++ b/src/lib/netlist/devices/nld_74365.h @@ -0,0 +1,44 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_74365.h + * + * SN74365: Hex Bus Driver with 3-State Outputs + * + * +--------------+ + * G1Q |1 ++ 16| VCC + * A1 |2 15| G2Q + * Y1 |3 14| A6 + * A2 |4 74365 13| Y6 + * Y2 |5 12| A5 + * A3 |6 11| Y5 + * Y3 |7 10| A4 + * GND |8 9| Y4 + * +--------------+ + * + * Naming conventions follow Texas Instruments datasheet + * + * Note: Currently the netlist system does not support proper tristate output, so this + * is not a "real" bus driver, it simply outputs 0 if the chip is not enabled. + */ + +#ifndef NLD_74365_H_ +#define NLD_74365_H_ + +#include "nl_setup.h" + +#define TTL_74365(name, cG1Q, cG2Q, cA1, cA2, cA3, cA4, cA5, cA6) \ + NET_REGISTER_DEV(TTL_74365, name) \ + NET_CONNECT(name, G1Q, cG1Q) \ + NET_CONNECT(name, G2Q, cG2Q) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, A5, cA5) \ + NET_CONNECT(name, A6, cA6) + +#define TTL_74365_DIP(name) \ + NET_REGISTER_DEV(TTL_74365_DIP, name) + +#endif /* NLD_74365_H_ */ diff --git a/src/lib/netlist/devices/nld_7473.cpp b/src/lib/netlist/devices/nld_7473.cpp new file mode 100644 index 00000000000..fc73b97c201 --- /dev/null +++ b/src/lib/netlist/devices/nld_7473.cpp @@ -0,0 +1,150 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nld_7473.c + * + */ + +#include "nld_7473.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(7473) + { + NETLIB_CONSTRUCTOR(7473) + , m_CLK(*this, "CLK") + , m_J(*this, "J") + , m_K(*this, "K") + , m_CLRQ(*this, "CLRQ") + , m_last_CLK(*this, "m_last_CLK", 0) + , m_q(*this, "m_q", 0) + , m_Q(*this, "Q") + , m_QQ(*this, "QQ") + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + public: + logic_input_t m_CLK; + logic_input_t m_J; + logic_input_t m_K; + logic_input_t m_CLRQ; + + state_var<unsigned> m_last_CLK; + state_var<unsigned> m_q; + + logic_output_t m_Q; + logic_output_t m_QQ; + }; + + NETLIB_OBJECT_DERIVED(7473A, 7473) + { + public: + NETLIB_CONSTRUCTOR_DERIVED(7473A, 7473) { } + + }; + + NETLIB_OBJECT(7473_dip) + { + NETLIB_CONSTRUCTOR(7473_dip) + , m_1(*this, "1") + , m_2(*this, "2") + { + register_subalias("1", m_1.m_CLK); + register_subalias("2", m_1.m_CLRQ); + register_subalias("3", m_1.m_K); + //register_subalias("4", ); ==> VCC + register_subalias("5", m_2.m_CLK); + register_subalias("6", m_2.m_CLRQ); + register_subalias("7", m_2.m_J); + + register_subalias("8", m_2.m_QQ); + register_subalias("9", m_2.m_Q); + register_subalias("10", m_2.m_K); + //register_subalias("11", ); ==> VCC + register_subalias("12", m_2.m_Q); + register_subalias("13", m_1.m_QQ); + register_subalias("14", m_1.m_J); + } + + private: + NETLIB_SUB(7473) m_1; + NETLIB_SUB(7473) m_2; + }; + + NETLIB_OBJECT(7473A_dip) + { + NETLIB_CONSTRUCTOR(7473A_dip) + , m_1(*this, "1") + , m_2(*this, "2") + { + register_subalias("1", m_1.m_CLK); + register_subalias("2", m_1.m_CLRQ); + register_subalias("3", m_1.m_K); + //register_subalias("4", ); ==> VCC + register_subalias("5", m_2.m_CLK); + register_subalias("6", m_2.m_CLRQ); + register_subalias("7", m_2.m_J); + + register_subalias("8", m_2.m_QQ); + register_subalias("9", m_2.m_Q); + register_subalias("10", m_2.m_K); + //register_subalias("11", ); ==> VCC + register_subalias("12", m_2.m_Q); + register_subalias("13", m_1.m_QQ); + register_subalias("14", m_1.m_J); + } + + private: + NETLIB_SUB(7473A) m_1; + NETLIB_SUB(7473A) m_2; + }; + + NETLIB_RESET(7473) + { + m_last_CLK = 0; + } + + NETLIB_UPDATE(7473) + { + const auto JK = (m_J() << 1) | m_K(); + + if (m_CLRQ()) + { + if (!m_CLK() && m_last_CLK) + { + switch (JK) + { + case 1: // (!m_J) & m_K)) + m_q = 0; + break; + case 2: // (m_J) & !m_K)) + m_q = 1; + break; + case 3: // (m_J) & m_K)) + m_q ^= 1; + break; + default: + case 0: + break; + } + } + } + + m_last_CLK = m_CLK(); + + m_Q.push(m_q, NLTIME_FROM_NS(20)); // FIXME: timing + m_QQ.push(m_q ^ 1, NLTIME_FROM_NS(20)); // FIXME: timing + } + + NETLIB_DEVICE_IMPL(7473) + NETLIB_DEVICE_IMPL(7473A) + NETLIB_DEVICE_IMPL(7473_dip) + NETLIB_DEVICE_IMPL(7473A_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_7473.h b/src/lib/netlist/devices/nld_7473.h new file mode 100644 index 00000000000..344e768cc44 --- /dev/null +++ b/src/lib/netlist/devices/nld_7473.h @@ -0,0 +1,82 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nld_7473.h + * + * 7473: Dual Master-Slave J-K Flip-Flops with Clear and Complementary Outputs + * 7473A: Dual Negative-Edge-Triggered Master-Slave J-K Flip-Flops with Clear and Complementary Outputs + * + * +----------+ + * 1CLK |1 ++ 14| 1J + * 1CLRQ |2 13| 1QQ + * 1K |3 12| 1Q + * VCC |4 7473 11| GND + * 2CLK |5 10| 2K + * 2CLRQ |6 9| 2Q + * 2J |7 8| 2QQ + * +----------+ + * + * + * Function table 73 + * + * +-----+-----+-----+---++---+-----+ + * | CLRQ| CLK | J | K || Q | QQ | + * +=====+=====+=====+===++===+=====+ + * | 0 | X | X | X || 0 | 1 | + * | 1 | * | 0 | 0 || Q0| Q0Q | + * | 1 | * | 1 | 0 || 1 | 0 | + * | 1 | * | 0 | 1 || 0 | 1 | + * | 1 | * | 1 | 1 || TOGGLE | + * +-----+-----+-----+---++---+-----+ + * _ + * * = _| |_ + * + * This is positive triggered, J and K + * are latched during clock high and + * transferred when CLK falls. + * + * Function table 73A + * + * +-----+-----+-----+---++---+-----+ + * | CLRQ| CLK | J | K || Q | QQ | + * +=====+=====+=====+===++===+=====+ + * | 0 | X | X | X || 0 | 1 | + * | 1 | F | 0 | 0 || Q0| Q0Q | + * | 1 | F | 1 | 0 || 1 | 0 | + * | 1 | F | 0 | 1 || 0 | 1 | + * | 1 | F | 1 | 1 || TOGGLE | + * | 1 | 1 | X | X || Q0| Q0Q | + * +-----+-----+-----+---++---+-----+ + * + * THe 73A is negative triggered. + * + * Naming conventions follow Texas instruments datasheet + * + * FIXME: Currently, only the 73 is implemented. + * The 73A uses the same model. + * + */ + +#ifndef NLD_7473_H_ +#define NLD_7473_H_ + +#include "nl_setup.h" + +#define TTL_7473(name, cCLK, cJ, cK, cCLRQ) \ + NET_REGISTER_DEV(TTL_7473, name) \ + NET_CONNECT(name, CLK, cCLK) \ + NET_CONNECT(name, J, cJ) \ + NET_CONNECT(name, K, cK) \ + NET_CONNECT(name, CLRQ, cCLRQ) + +#define TTL_7473A(name, cCLK, cJ, cK, cCLRQ) \ + TTL_7473(name, cCLK, cJ, cK, cCLRQ) + +#define TTL_7473_DIP(name) \ + NET_REGISTER_DEV(TTL_7473_DIP, name) + + +#define TTL_7473A_DIP(name) \ + NET_REGISTER_DEV(TTL_7473A_DIP, name) + +#endif /* NLD_7473_H_ */ diff --git a/src/lib/netlist/devices/nld_7475.cpp b/src/lib/netlist/devices/nld_7475.cpp new file mode 100644 index 00000000000..3c26c1ce439 --- /dev/null +++ b/src/lib/netlist/devices/nld_7475.cpp @@ -0,0 +1,156 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_7475.cpp + * + * TODO: Correct timing for clock-induced state changes, rather than assuming timing is always due to data-induced state changes + */ + +#include "nld_7475.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(7477) + { + NETLIB_CONSTRUCTOR(7477) + , m_C1C2(*this, "C1C2") + , m_C3C4(*this, "C3C4") + , m_last_Q(*this, "m_last_Q", 0) + , m_D(*this, {{"D1", "D2", "D3", "D4"}}) + , m_Q(*this, {{"Q1", "Q2", "Q3", "Q4"}}) + { + register_subalias("Q1", m_Q[0]); + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + void update_outputs(std::size_t start, std::size_t end); + + public: + logic_input_t m_C1C2; + logic_input_t m_C3C4; + state_var<unsigned> m_last_Q; + object_array_t<logic_input_t, 4> m_D; + object_array_t<logic_output_t, 4> m_Q; + }; + + NETLIB_OBJECT_DERIVED(7475, 7477) + { + NETLIB_CONSTRUCTOR_DERIVED(7475, 7477) + , m_QQ(*this, {{"QQ1", "QQ2", "QQ3", "QQ4"}}) + { + } + + NETLIB_UPDATEI(); + + public: + object_array_t<logic_output_t, 4> m_QQ; + }; + + NETLIB_OBJECT_DERIVED(7475_dip, 7475) + { + NETLIB_CONSTRUCTOR_DERIVED(7475_dip, 7475) + { + register_subalias("1", m_QQ[0]); + register_subalias("2", m_D[0]); + register_subalias("3", m_D[1]); + register_subalias("4", m_C3C4); + //register_subalias("5", ); ==> VCC + register_subalias("6", m_D[2]); + register_subalias("7", m_D[3]); + register_subalias("8", m_QQ[3]); + + register_subalias("9", m_Q[3]); + register_subalias("10", m_Q[2]); + register_subalias("11", m_QQ[2]); + //register_subalias("12", ); ==> GND + register_subalias("13", m_C1C2); + register_subalias("14", m_QQ[1]); + register_subalias("15", m_Q[1]); + register_subalias("16", m_Q[0]); + } + }; + + NETLIB_OBJECT_DERIVED(7477_dip, 7477) + { + NETLIB_CONSTRUCTOR_DERIVED(7477_dip, 7477) + { + register_subalias("1", m_D[0]); + register_subalias("2", m_D[1]); + register_subalias("3", m_C3C4); + //register_subalias("4", ); ==> VCC + register_subalias("5", m_D[2]); + register_subalias("6", m_D[3]); + //register_subalias("7", ); ==> NC + + register_subalias("8", m_Q[3]); + register_subalias("9", m_Q[2]); + //register_subalias("10", ); ==> NC + //register_subalias("11", ); ==> GND + register_subalias("12", m_C1C2); + register_subalias("13", m_Q[1]); + register_subalias("14", m_Q[0]); + } + }; + + NETLIB_UPDATE(7475) + { + unsigned start_q = m_last_Q; + + NETLIB_PARENT_UPDATE(7477); + + for (std::size_t i=0; i<4; i++) + { + unsigned last_bit = (m_last_Q >> i) & 1; + unsigned start_bit = (start_q >> i) & 1; + if (last_bit != start_bit) + m_QQ[i].push(last_bit ^ 1, last_bit != 0 ? NLTIME_FROM_NS(15) : NLTIME_FROM_NS(40)); + } + } + + void NETLIB_NAME(7477)::update_outputs(std::size_t start, std::size_t end) + { + for (std::size_t i=start; i<end; i++) + { + netlist_sig_t d = m_D[i](); + if (d != ((m_last_Q >> i) & 1)) + m_Q[i].push(d, d != 0 ? NLTIME_FROM_NS(30) : NLTIME_FROM_NS(25)); + m_last_Q &= ~(1 << i); + m_last_Q |= d << i; + } + } + + NETLIB_RESET(7477) + { + m_last_Q = 0; + } + + NETLIB_UPDATE(7477) + { + netlist_sig_t c1c2 = m_C1C2(); + netlist_sig_t c3c4 = m_C3C4(); + if (c1c2 && c3c4) + { + update_outputs(0, 4); + } + else if (c1c2) + { + update_outputs(0, 2); + } + else if (c3c4) + { + update_outputs(2, 4); + } + + } + + NETLIB_DEVICE_IMPL(7475) + NETLIB_DEVICE_IMPL(7475_dip) + NETLIB_DEVICE_IMPL(7477) + NETLIB_DEVICE_IMPL(7477_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_7475.h b/src/lib/netlist/devices/nld_7475.h new file mode 100644 index 00000000000..5689d6aa1e8 --- /dev/null +++ b/src/lib/netlist/devices/nld_7475.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_7475.h + * + * 7475: 4-Bit Bistable Latches with Complementary Outputs + * 7477: 4-Bit Bistable Latches + * + * +----------+ +----------+ + * 1QQ |1 ++ 16| 1Q 1D |1 ++ 14| 1Q + * 1D |2 15| 2Q 2D |2 13| 2Q + * 2D |3 14| 2QQ 3C4C |3 12| 1C2C + * 3C4C |4 7475 13| 1C2C VCC |4 7477 11| GND + * VCC |5 12| GND 3D |5 10| NC + * 3D |6 11| 3QQ 4D |6 9| 3Q + * 4D |7 10| 3Q NC |7 8| 4Q + * 4QQ |8 9| 4Q +----------+ + * +----------+ + * + * + * Function table + * + * +---+---++---+-----+ + * | D | C || Q | QQ | + * +===+===++===+=====+ + * | 0 | 1 || 0 | 1 | + * | 1 | 1 || 1 | 0 | + * | X | 0 || Q0| Q0Q | + * +---+---++---+-----+ + * + * Naming conventions follow Texas instruments datasheet + * + */ + +#ifndef NLD_7475_H_ +#define NLD_7475_H_ + +#include "nl_setup.h" + +#define PARAMS_7475_7477(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) \ + NET_CONNECT(name, C1C2, cC1C2) \ + NET_CONNECT(name, C3C4, cC3C4) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, D2, cD2) \ + NET_CONNECT(name, D3, cD3) \ + NET_CONNECT(name, D4, cD4) + +#define TTL_7475(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) \ + NET_REGISTER_DEV(TTL_7475, name) \ + PARAMS_7475_7477(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) + +#define TTL_7477(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) \ + NET_REGISTER_DEV(TTL_7477, name) \ + PARAMS_7475_7477(name, cC1C2, cC3C4, cD1, cD2, cD3, cD4) + +#define TTL_7475_DIP(name) \ + NET_REGISTER_DEV(TTL_7475_DIP, name) + +#define TTL_7477_DIP(name) \ + NET_REGISTER_DEV(TTL_7477_DIP, name) + +#endif /* NLD_7475_H_ */ diff --git a/src/lib/netlist/devices/nld_7485.cpp b/src/lib/netlist/devices/nld_7485.cpp new file mode 100644 index 00000000000..ba51756cac1 --- /dev/null +++ b/src/lib/netlist/devices/nld_7485.cpp @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_7485.cpp + * + */ + +#include "nld_7485.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(7485) + { + NETLIB_CONSTRUCTOR(7485) + , m_A(*this, {{"A0", "A1", "A2", "A3"}}) + , m_B(*this, {{"B0", "B1", "B2", "B3"}}) + , m_LTIN(*this, "LTIN") + , m_EQIN(*this, "EQIN") + , m_GTIN(*this, "GTIN") + , m_LTOUT(*this, "LTOUT") + , m_EQOUT(*this, "EQOUT") + , m_GTOUT(*this, "GTOUT") + { + } + + NETLIB_UPDATEI(); + + void update_outputs(unsigned gt, unsigned lt, unsigned eq); + + protected: + object_array_t<logic_input_t, 4> m_A; + object_array_t<logic_input_t, 4> m_B; + logic_input_t m_LTIN; + logic_input_t m_EQIN; + logic_input_t m_GTIN; + logic_output_t m_LTOUT; + logic_output_t m_EQOUT; + logic_output_t m_GTOUT; + }; + + NETLIB_OBJECT_DERIVED(7485_dip, 7485) + { + NETLIB_CONSTRUCTOR_DERIVED(7485_dip, 7485) + { + register_subalias("1", m_B[3]); + register_subalias("2", m_LTIN); + register_subalias("3", m_EQIN); + register_subalias("4", m_GTIN); + register_subalias("5", m_GTOUT); + register_subalias("6", m_EQOUT); + register_subalias("7", m_LTOUT); + + register_subalias("9", m_B[0]); + register_subalias("10", m_A[0]); + register_subalias("11", m_B[1]); + register_subalias("12", m_A[1]); + register_subalias("13", m_A[2]); + register_subalias("14", m_B[2]); + register_subalias("15", m_A[3]); + + } + }; + + void NETLIB_NAME(7485)::update_outputs(unsigned gt, unsigned lt, unsigned eq) + { + m_GTOUT.push(gt, NLTIME_FROM_NS(23)); + m_LTOUT.push(lt, NLTIME_FROM_NS(23)); + m_EQOUT.push(eq, NLTIME_FROM_NS(23)); + } + + // FIXME: Timing + NETLIB_UPDATE(7485) + { + for (std::int_fast32_t i = 3; i >= 0; i--) + { + if (m_A[i]() > m_B[i]()) + { + update_outputs(1, 0, 0); + return; + } + else if (m_A[i]() < m_B[i]()) + { + update_outputs(0, 1, 0); + return; + } + } + + // must be == if we got here + if (m_EQIN()) + update_outputs(0, 0, 1); + else if (m_GTIN() && m_LTIN()) + update_outputs(0, 0, 0); + else if (m_GTIN()) + update_outputs(1, 0, 0); + else if (m_LTIN()) + update_outputs(0, 1, 0); + else + update_outputs(1, 1, 0); + } + + NETLIB_DEVICE_IMPL(7485) + NETLIB_DEVICE_IMPL(7485_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_7485.h b/src/lib/netlist/devices/nld_7485.h new file mode 100644 index 00000000000..77ff6b0d530 --- /dev/null +++ b/src/lib/netlist/devices/nld_7485.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_7485.h + * + * DM7485: 4-bit Magnitude Comparators + * + * +------------+ + * B3 |1 ++ 16| VCC + * LTIN |2 15| A3 + * EQIN |3 14| B2 + * GTIN |4 7485 13| A2 + * GTOUT |5 12| A1 + * EQOUT |6 11| B1 + * LTOUT |7 10| A0 + * GND |8 9| B0 + * +------------+ + * + * Naming convention attempts to follow Texas Instruments datasheet + * + */ + +#ifndef NLD_7485_H_ +#define NLD_7485_H_ + +#include "nl_setup.h" + +#define TTL_7485(name, cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, cLTIN, cEQIN, cGTIN) \ + NET_REGISTER_DEV(TTL_7485, name) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, B0, cB0) \ + NET_CONNECT(name, B1, cB1) \ + NET_CONNECT(name, B2, cB2) \ + NET_CONNECT(name, B3, cB3) \ + NET_CONNECT(name, LTIN, cLTIN) \ + NET_CONNECT(name, EQIN, cEQIN) \ + NET_CONNECT(name, GTIN, cGTIN) + +#define TTL_7485_DIP(name) \ + NET_REGISTER_DEV(TTL_7485_DIP, name) + +#endif /* NLD_7485_H_ */ diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp index 3d35f90eba6..9a34b9c5ca9 100644 --- a/src/lib/netlist/devices/nld_74ls629.cpp +++ b/src/lib/netlist/devices/nld_74ls629.cpp @@ -60,7 +60,7 @@ namespace netlist NETLIB_RESETI() { - m_enableq = 1; + m_enableq = 0; m_out = 0; m_inc = netlist_time::zero(); } diff --git a/src/lib/netlist/devices/nld_82S115.cpp b/src/lib/netlist/devices/nld_82S115.cpp new file mode 100644 index 00000000000..c01d013aec5 --- /dev/null +++ b/src/lib/netlist/devices/nld_82S115.cpp @@ -0,0 +1,112 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S115.cpp + * + */ + +#include "nld_82S115.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(82S115) + { + NETLIB_CONSTRUCTOR(82S115) + , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"}}) + , m_CE1Q(*this, "CE1Q") + , m_CE2(*this, "CE2") + , m_STROBE(*this, "STROBE") + , m_O(*this, {{"O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8"}}) + , m_last_O(*this, "m_last_O", 0) + , m_ROM(*this, "ROM") + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 9> m_A; + logic_input_t m_CE1Q; + logic_input_t m_CE2; + logic_input_t m_STROBE; + object_array_t<logic_output_t, 8> m_O; + + state_var<unsigned> m_last_O; + + param_rom_t<uint8_t, 9, 8> m_ROM; // 4096 bits, 512x8 + }; + + NETLIB_OBJECT_DERIVED(82S115_dip, 82S115) + { + NETLIB_CONSTRUCTOR_DERIVED(82S115_dip, 82S115) + { + register_subalias("21", m_A[0]); + register_subalias("22", m_A[1]); + register_subalias("23", m_A[2]); + register_subalias("1", m_A[3]); + register_subalias("2", m_A[4]); + register_subalias("3", m_A[5]); + register_subalias("4", m_A[6]); + register_subalias("5", m_A[7]); + register_subalias("6", m_A[8]); + + register_subalias("20", m_CE1Q); + register_subalias("19", m_CE2); + + // register_subalias("13", m_FE1); + // register_subalias("11", m_FE2); + + register_subalias("18", m_STROBE); + + register_subalias("7", m_O[0]); + register_subalias("8", m_O[1]); + register_subalias("9", m_O[2]); + register_subalias("10", m_O[3]); + register_subalias("14", m_O[4]); + register_subalias("15", m_O[5]); + register_subalias("16", m_O[6]); + register_subalias("17", m_O[7]); + } + }; + + NETLIB_RESET(82S115) + { + m_last_O = 0; + } + + // FIXME: timing! + NETLIB_UPDATE(82S115) + { + unsigned o = 0; + + if (!m_CE1Q() && m_CE2()) + { + if (m_STROBE()) + { + unsigned a = 0; + for (std::size_t i=0; i<9; i++) + a |= (m_A[i]() << i); + + o = m_ROM[a]; + } + else + { + o = m_last_O; + } + } + + m_last_O = o; + + // FIXME: Outputs are tristate. This needs to be properly implemented + for (std::size_t i=0; i<8; i++) + m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(40)); // FIXME: Timing + } + + NETLIB_DEVICE_IMPL(82S115) + NETLIB_DEVICE_IMPL(82S115_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_82S115.h b/src/lib/netlist/devices/nld_82S115.h new file mode 100644 index 00000000000..0c900e4dad7 --- /dev/null +++ b/src/lib/netlist/devices/nld_82S115.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S115.h + * + * 82S115: 4K-bit TTL bipolar PROM (512 x 8) + * + * +--------------+ + * A3 |1 ++ 24| VCC + * A4 |2 23| A2 + * A5 |3 22| A1 + * A6 |4 82S115 21| A0 + * A7 |5 20| CE1Q + * A8 |6 19| CE2 + * O1 |7 18| STROBE + * O2 |8 17| O8 + * O3 |9 16| O7 + * O4 |10 15| O6 + * FE2 |11 14| O5 + * GND |12 13| FE1 + * +--------------+ + * + * + * Naming conventions follow Signetics datasheet + * + */ + +#ifndef NLD_82S115_H_ +#define NLD_82S115_H_ + +#include "nl_setup.h" + +#define PROM_82S115(name, cCE1Q, cCE2, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cSTROBE) \ + NET_REGISTER_DEV(PROM_82S115, name) \ + NET_CONNECT(name, CE1Q, cCE1Q) \ + NET_CONNECT(name, CE2, cCE2) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, A5, cA5) \ + NET_CONNECT(name, A6, cA6) \ + NET_CONNECT(name, A7, cA7) \ + NET_CONNECT(name, A8, cA8) \ + NET_CONNECT(name, STROBE, cSTROBE) + +#define PROM_82S115_DIP(name) \ + NET_REGISTER_DEV(PROM_82S115_DIP, name) + +#endif /* NLD_82S115_H_ */ diff --git a/src/lib/netlist/devices/nld_82S123.cpp b/src/lib/netlist/devices/nld_82S123.cpp new file mode 100644 index 00000000000..f9e97174d4a --- /dev/null +++ b/src/lib/netlist/devices/nld_82S123.cpp @@ -0,0 +1,83 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S123.cpp + * + */ + +#include "nld_82S123.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(82S123) + { + NETLIB_CONSTRUCTOR(82S123) + , m_A(*this, {{"A0", "A1", "A2", "A3", "A4"}}) + , m_CEQ(*this, "CEQ") + , m_O(*this, {{"O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8"}}) + , m_ROM(*this, "ROM") + { + } + + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 5> m_A; + logic_input_t m_CEQ; + object_array_t<logic_output_t, 8> m_O; + + param_rom_t<uint8_t, 5, 8> m_ROM; // 256 bits, 32x8 + }; + + NETLIB_OBJECT_DERIVED(82S123_dip, 82S123) + { + NETLIB_CONSTRUCTOR_DERIVED(82S123_dip, 82S123) + { + register_subalias("1", m_O[0]); + register_subalias("2", m_O[1]); + register_subalias("3", m_O[2]); + register_subalias("4", m_O[3]); + register_subalias("5", m_O[4]); + register_subalias("6", m_O[5]); + register_subalias("7", m_O[6]); + register_subalias("8", m_O[7]); + + register_subalias("15", m_CEQ); + + register_subalias("10", m_A[0]); + register_subalias("11", m_A[1]); + register_subalias("12", m_A[2]); + register_subalias("13", m_A[3]); + register_subalias("14", m_A[4]); + } + }; + + // FIXME: timing! + NETLIB_UPDATE(82S123) + { + unsigned o = 0xff; + + netlist_time delay = NLTIME_FROM_NS(35); + if (!m_CEQ()) + { + unsigned a = 0; + for (std::size_t i=0; i<5; i++) + a |= (m_A[i]() << i); + + o = m_ROM[a]; + + delay = NLTIME_FROM_NS(50); + } + + // FIXME: Outputs are tristate. This needs to be properly implemented + for (std::size_t i=0; i<8; i++) + m_O[i].push((o >> i) & 1, delay); + } + + NETLIB_DEVICE_IMPL(82S123) + NETLIB_DEVICE_IMPL(82S123_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_82S123.h b/src/lib/netlist/devices/nld_82S123.h new file mode 100644 index 00000000000..a04e169ae93 --- /dev/null +++ b/src/lib/netlist/devices/nld_82S123.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S123.h + * + * 82S23: 256-bit (32x8) TTL bipolar PROM with open-collector outputs + * 82S123: 256-bit (32x8) TTL bipolar PROM with tri-state outputs + * + * +--------------+ + * O1 |1 ++ 16| VCC + * O2 |2 15| CEQ + * O3 |3 14| A4 + * O4 |4 82S123 13| A3 + * O5 |5 12| A2 + * O6 |6 11| A1 + * O7 |7 10| A0 + * GND |8 9| O8 + * +--------------+ + * + * + * Naming conventions follow Philips datasheet + * + */ + +#ifndef NLD_82S123_H_ +#define NLD_82S123_H_ + +#include "nl_setup.h" + +#define PROM_82S123(name, cCEQ, cA0, cA1, cA2, cA3, cA4) \ + NET_REGISTER_DEV(PROM_82S123, name) \ + NET_CONNECT(name, CEQ, cCEQ) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) + +#define PROM_82S123_DIP(name) \ + NET_REGISTER_DEV(PROM_82S123_DIP, name) + +#endif /* NLD_82S123_H_ */ diff --git a/src/lib/netlist/devices/nld_82S126.cpp b/src/lib/netlist/devices/nld_82S126.cpp new file mode 100644 index 00000000000..d3a86ce84ee --- /dev/null +++ b/src/lib/netlist/devices/nld_82S126.cpp @@ -0,0 +1,85 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S126.cpp + * + */ + +#include "nld_82S126.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(82S126) + { + NETLIB_CONSTRUCTOR(82S126) + , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }}) + , m_CE1Q(*this, "CE1Q") + , m_CE2Q(*this, "CE2Q") + , m_O(*this, {{"O1", "O2", "O3", "O4" }}) + , m_ROM(*this, "ROM") + { + } + + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 8> m_A; + logic_input_t m_CE1Q; + logic_input_t m_CE2Q; + object_array_t<logic_output_t, 4> m_O; + + param_rom_t<uint8_t, 8, 4> m_ROM; // 1024 bits, 32x32, used as 256x4 + }; + + NETLIB_OBJECT_DERIVED(82S126_dip, 82S126) + { + NETLIB_CONSTRUCTOR_DERIVED(82S126_dip, 82S126) + { + register_subalias("5", m_A[0]); + register_subalias("6", m_A[1]); + register_subalias("7", m_A[2]); + register_subalias("4", m_A[3]); + register_subalias("3", m_A[4]); + register_subalias("2", m_A[5]); + register_subalias("1", m_A[6]); + register_subalias("15", m_A[7]); + + register_subalias("13", m_CE1Q); + register_subalias("14", m_CE2Q); + + register_subalias("12", m_O[0]); + register_subalias("11", m_O[1]); + register_subalias("10", m_O[2]); + register_subalias("9", m_O[3]); + } + }; + + // FIXME: timing! + NETLIB_UPDATE(82S126) + { + unsigned o = 0xf; + + netlist_time delay = NLTIME_FROM_NS(25); + if (!m_CE1Q() && !m_CE2Q()) + { + unsigned a = 0; + for (std::size_t i=0; i<8; i++) + a |= (m_A[i]() << i); + + o = m_ROM[a]; + + delay = NLTIME_FROM_NS(50); + } + + // FIXME: Outputs are tristate. This needs to be properly implemented + for (std::size_t i=0; i<4; i++) + m_O[i].push((o >> i) & 1, delay); + } + + NETLIB_DEVICE_IMPL(82S126) + NETLIB_DEVICE_IMPL(82S126_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_82S126.h b/src/lib/netlist/devices/nld_82S126.h new file mode 100644 index 00000000000..27dd2217497 --- /dev/null +++ b/src/lib/netlist/devices/nld_82S126.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_82S126.h + * + * 82S126: 1K-bit TTL bipolar PROM + * + * +--------------+ + * A6 |1 ++ 16| VCC + * A5 |2 15| Q7 + * A4 |3 14| CE2Q + * A3 |4 82S126 13| CE1Q + * A0 |5 12| O1 + * A1 |6 11| O2 + * A2 |7 10| O3 + * GND |8 9| O4 + * +--------------+ + * + * + * Naming conventions follow Signetics datasheet + * + */ + +#ifndef NLD_82S126_H_ +#define NLD_82S126_H_ + +#include "nl_setup.h" + +#define PROM_82S126(name, cCE1Q, cCE2Q, cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7) \ + NET_REGISTER_DEV(PROM_82S126, name) \ + NET_CONNECT(name, CE1Q, cCE1Q) \ + NET_CONNECT(name, CE2Q, cCE2Q) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, A5, cA5) \ + NET_CONNECT(name, A6, cA6) \ + NET_CONNECT(name, A7, cA7) + +#define PROM_82S126_DIP(name) \ + NET_REGISTER_DEV(PROM_82S126_DIP, name) + +#endif /* NLD_82S126_H_ */ diff --git a/src/lib/netlist/devices/nld_9312.cpp b/src/lib/netlist/devices/nld_9312.cpp index af5f35d965c..2ad298f368a 100644 --- a/src/lib/netlist/devices/nld_9312.cpp +++ b/src/lib/netlist/devices/nld_9312.cpp @@ -28,8 +28,9 @@ namespace netlist namespace devices { #if (USE_TRUTHTABLE) - /* The truthtable implementation is a lot faster than + /* FIXME: The truthtable implementation is a lot faster than * the carefully crafted code :-( + * Convert this into a macro module. */ NETLIB_TRUTHTABLE(9312, 12, 2); #else diff --git a/src/lib/netlist/devices/nld_9312.h b/src/lib/netlist/devices/nld_9312.h index a787b38e604..98cc0d115c8 100644 --- a/src/lib/netlist/devices/nld_9312.h +++ b/src/lib/netlist/devices/nld_9312.h @@ -39,8 +39,20 @@ #include "nl_setup.h" -#define TTL_9312(name) \ - NET_REGISTER_DEV(TTL_9312, name) +#define TTL_9312(name, cA, cB, cC, cD0, cD1, cD2, cD3, cD4, cD5, cD6, cD7, cSTROBE) \ + NET_REGISTER_DEV(TTL_9312, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D0, cD0) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, D2, cD2) \ + NET_CONNECT(name, D3, cD3) \ + NET_CONNECT(name, D4, cD4) \ + NET_CONNECT(name, D5, cD5) \ + NET_CONNECT(name, D6, cD6) \ + NET_CONNECT(name, D7, cD7) \ + NET_CONNECT(name, G, cSTROBE) #define TTL_9312_DIP(name) \ NET_REGISTER_DEV(TTL_9312_DIP, name) diff --git a/src/lib/netlist/devices/nld_9316.h b/src/lib/netlist/devices/nld_9316.h index ab3fb46a2f5..b0be896a6bd 100644 --- a/src/lib/netlist/devices/nld_9316.h +++ b/src/lib/netlist/devices/nld_9316.h @@ -44,6 +44,8 @@ * * Naming conventions follow National Semiconductor datasheet * + * TODO: DM74161 is compatible to DM9316 (both asynchronous clear) + * DM74163 has asynchronous clear (on L to H transition of clock) */ #ifndef NLD_9316_H_ diff --git a/src/lib/netlist/devices/nld_9322.cpp b/src/lib/netlist/devices/nld_9322.cpp new file mode 100644 index 00000000000..881ec9e5355 --- /dev/null +++ b/src/lib/netlist/devices/nld_9322.cpp @@ -0,0 +1,114 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_9322.cpp + * + */ + +#include "nld_9322.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(9322_selector) + { + NETLIB_CONSTRUCTOR(9322_selector) + , m_A(*this, "A") + , m_B(*this, "B") + , m_Y(*this, "Y") + { + } + + void update_outputs(const netlist_sig_t strobe, const netlist_sig_t select); + + public: + logic_input_t m_A; + logic_input_t m_B; + logic_output_t m_Y; + }; + + // FIXME: Timing + void NETLIB_NAME(9322_selector)::update_outputs(const netlist_sig_t strobe, const netlist_sig_t select) + { + if (strobe) + m_Y.push(0, NLTIME_FROM_NS(21)); + else if (select) + m_Y.push(m_B(), NLTIME_FROM_NS(14)); + else + m_Y.push(m_A(), NLTIME_FROM_NS(14)); + } + + NETLIB_OBJECT(9322) + { + NETLIB_CONSTRUCTOR(9322) + , m_1(*this, "1") + , m_2(*this, "2") + , m_3(*this, "3") + , m_4(*this, "4") + , m_SELECT(*this, "SELECT") + , m_STROBE(*this, "STROBE") + { + register_subalias("A1", m_1.m_A); + register_subalias("B1", m_1.m_B); + register_subalias("Y1", m_1.m_Y); + register_subalias("A2", m_2.m_A); + register_subalias("B2", m_2.m_B); + register_subalias("Y2", m_2.m_Y); + register_subalias("A3", m_3.m_A); + register_subalias("B3", m_3.m_B); + register_subalias("Y3", m_3.m_Y); + register_subalias("A4", m_4.m_A); + register_subalias("B4", m_4.m_B); + register_subalias("Y4", m_4.m_Y); + } + + NETLIB_UPDATEI(); + + protected: + NETLIB_SUB(9322_selector) m_1; + NETLIB_SUB(9322_selector) m_2; + NETLIB_SUB(9322_selector) m_3; + NETLIB_SUB(9322_selector) m_4; + + logic_input_t m_SELECT; + logic_input_t m_STROBE; + }; + + NETLIB_OBJECT_DERIVED(9322_dip, 9322) + { + NETLIB_CONSTRUCTOR_DERIVED(9322_dip, 9322) + { + register_subalias("1", m_SELECT); + register_subalias("2", m_1.m_A); + register_subalias("3", m_1.m_B); + register_subalias("4", m_1.m_Y); + register_subalias("5", m_2.m_A); + register_subalias("6", m_2.m_B); + register_subalias("7", m_2.m_Y); + + register_subalias("9", m_3.m_Y); + register_subalias("10", m_3.m_B); + register_subalias("11", m_3.m_A); + register_subalias("12", m_4.m_Y); + register_subalias("13", m_4.m_B); + register_subalias("14", m_4.m_A); + register_subalias("15", m_STROBE); + } + }; + + NETLIB_UPDATE(9322) + { + const netlist_sig_t strobe = m_STROBE(); + const netlist_sig_t select = m_SELECT(); + m_1.update_outputs(strobe, select); + m_2.update_outputs(strobe, select); + m_3.update_outputs(strobe, select); + m_4.update_outputs(strobe, select); + } + + NETLIB_DEVICE_IMPL(9322) + NETLIB_DEVICE_IMPL(9322_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_9322.h b/src/lib/netlist/devices/nld_9322.h new file mode 100644 index 00000000000..08ec6efcd93 --- /dev/null +++ b/src/lib/netlist/devices/nld_9322.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_9322.h + * + * 9322: Quad 2-Line to 1-Line Data Selectors/Multiplexers + * + * +------------+ + * SELECT |1 ++ 16| VCC + * A1 |2 15| STROBE + * B1 |3 14| A4 + * Y1 |4 9322 13| B4 + * A2 |5 12| Y4 + * B2 |6 11| A3 + * Y2 |7 10| B3 + * GND |8 9| Y3 + * +------------+ + * + */ + +#ifndef NLD_9322_H_ +#define NLD_9322_H_ + +#include "nl_setup.h" + +#define TTL_9322(name, cSELECT, cA1, cB1, cA2, cB2, cA3, cB3, cA4, cB4, cSTROBE) \ + NET_REGISTER_DEV(TTL_9322, name) \ + NET_CONNECT(name, SELECT, cSELECT) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, B1, cB1) \ + NET_CONNECT(name, A2, cA2) \ + NET_CONNECT(name, B2, cB2) \ + NET_CONNECT(name, A3, cA3) \ + NET_CONNECT(name, B3, cB3) \ + NET_CONNECT(name, A4, cA4) \ + NET_CONNECT(name, B4, cB4) \ + NET_CONNECT(name, STROBE, cSTROBE) + +#define TTL_9322_DIP(name) \ + NET_REGISTER_DEV(TTL_9322_DIP, name) + +#endif /* NLD_9322_H_ */ diff --git a/src/lib/netlist/devices/nld_am2847.cpp b/src/lib/netlist/devices/nld_am2847.cpp new file mode 100644 index 00000000000..ec4eafc8dd6 --- /dev/null +++ b/src/lib/netlist/devices/nld_am2847.cpp @@ -0,0 +1,129 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_am2847.cpp + * + */ + +#include "nld_am2847.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(Am2847_shifter) + { + NETLIB_CONSTRUCTOR(Am2847_shifter) + , m_RC(*this, "RC") + , m_IN(*this, "IN") + , m_buffer(*this, "m_buffer", 0) + , m_OUT(*this, "OUT") + { + } + + public: + void shift(); + + logic_input_t m_RC; + logic_input_t m_IN; + + state_var<uint_fast16_t[5]> m_buffer; + + logic_output_t m_OUT; + }; + + NETLIB_OBJECT(AM2847) + { + NETLIB_CONSTRUCTOR(AM2847) + , m_A(*this, "A") + , m_B(*this, "B") + , m_C(*this, "C") + , m_D(*this, "D") + , m_CP(*this, "CP") + , m_last_CP(*this, "m_last_CP", 0) + { + register_subalias("OUTA", m_A.m_OUT); + register_subalias("OUTB", m_B.m_OUT); + register_subalias("OUTC", m_C.m_OUT); + register_subalias("OUTD", m_D.m_OUT); + register_subalias("INA", m_A.m_IN); + register_subalias("INB", m_B.m_IN); + register_subalias("INC", m_C.m_IN); + register_subalias("IND", m_D.m_IN); + register_subalias("RCA", m_A.m_RC); + register_subalias("RCB", m_B.m_RC); + register_subalias("RCC", m_C.m_RC); + register_subalias("RCD", m_D.m_RC); + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + NETLIB_SUB(Am2847_shifter) m_A; + NETLIB_SUB(Am2847_shifter) m_B; + NETLIB_SUB(Am2847_shifter) m_C; + NETLIB_SUB(Am2847_shifter) m_D; + logic_input_t m_CP; + + state_var<uint_fast32_t> m_last_CP; + }; + + NETLIB_OBJECT_DERIVED(AM2847_dip, AM2847) + { + NETLIB_CONSTRUCTOR_DERIVED(AM2847_dip, AM2847) + { + register_subalias("1", m_A.m_OUT); + register_subalias("2", m_A.m_RC); + register_subalias("3", m_A.m_IN); + register_subalias("4", m_B.m_OUT); + register_subalias("5", m_B.m_RC); + register_subalias("6", m_B.m_IN); + register_subalias("7", m_C.m_OUT); + + register_subalias("9", m_C.m_RC); + register_subalias("10", m_C.m_IN); + register_subalias("11", m_CP); + register_subalias("13", m_D.m_OUT); + register_subalias("14", m_D.m_RC); + register_subalias("15", m_D.m_IN); + + } + }; + + NETLIB_RESET(AM2847) + { + m_last_CP = 0; + } + + NETLIB_UPDATE(AM2847) + { + if (m_last_CP && !m_CP()) + { + m_A.shift(); + m_B.shift(); + m_C.shift(); + m_D.shift(); + } + m_last_CP = m_CP(); + } + + inline NETLIB_FUNC_VOID(Am2847_shifter, shift, (void)) + { + unsigned out = m_buffer[0] & 1; + uint_fast32_t in = (m_RC() ? out : m_IN()); + for (std::size_t i=0; i < 5; i++) + { + uint_fast16_t shift_in = (i == 4) ? in : m_buffer[i + 1]; + m_buffer[i] >>= 1; + m_buffer[i] |= shift_in << 15; + } + + m_OUT.push(out, NLTIME_FROM_NS(200)); + } + + NETLIB_DEVICE_IMPL(AM2847) + NETLIB_DEVICE_IMPL(AM2847_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_am2847.h b/src/lib/netlist/devices/nld_am2847.h new file mode 100644 index 00000000000..a820961ea2c --- /dev/null +++ b/src/lib/netlist/devices/nld_am2847.h @@ -0,0 +1,41 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_am2847.h + * + * Am2847: Quad 80-Bit Static Shift Register + * + * +--------------+ + * OUTA |1 ++ 16| VSS + * RCA |2 15| IND + * INA |3 14| RCD + * OUTB |4 Am2847 13| OUTD + * RCB |5 12| VGG + * INB |6 11| CP + * OUTC |7 10| INC + * VDD |8 9| RCC + * +--------------+ + * + */ + +#ifndef NLD_AM2847_H_ +#define NLD_AM2847_H_ + +#include "nl_setup.h" + +#define TTL_AM2847(name, cCP, cINA, cINB, cINC, cIND, cRCA, cRCB, cRCC, cRCD) \ + NET_REGISTER_DEV(TTL_AM2847, name) \ + NET_CONNECT(name, CP, cCP) \ + NET_CONNECT(name, INA, cINA) \ + NET_CONNECT(name, INB, cINB) \ + NET_CONNECT(name, INC, cINC) \ + NET_CONNECT(name, IND, cIND) \ + NET_CONNECT(name, RCA, cRCA) \ + NET_CONNECT(name, RCB, cRCB) \ + NET_CONNECT(name, RCC, cRCC) \ + NET_CONNECT(name, RCD, cRCD) + +#define TTL_AM2847_DIP(name) \ + NET_REGISTER_DEV(TTL_AM2847_DIP, name) + +#endif /* NLD_AM2847_H_ */ diff --git a/src/lib/netlist/devices/nld_dm9334.cpp b/src/lib/netlist/devices/nld_dm9334.cpp new file mode 100644 index 00000000000..c65a05d2014 --- /dev/null +++ b/src/lib/netlist/devices/nld_dm9334.cpp @@ -0,0 +1,149 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_dm9334.cpp + * + */ + +#include "nld_dm9334.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(9334) + { + NETLIB_CONSTRUCTOR(9334) + , m_CQ(*this, "CQ") + , m_EQ(*this, "EQ") + , m_D(*this, "D") + , m_A(*this, {{"A0", "A1", "A2"}}) + , m_Q(*this, {{"Q0", "Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "Q7"}}) + , m_last_CQ(*this, "m_last_CQ", 0) + , m_last_EQ(*this, "m_last_EQ", 0) + , m_last_D(*this, "m_last_D", 0) + , m_last_A(*this, "m_last_A", 0) + , m_last_Q(*this, "m_last_Q", 0) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + logic_input_t m_CQ; + logic_input_t m_EQ; + logic_input_t m_D; + object_array_t<logic_input_t, 3> m_A; + object_array_t<logic_output_t, 8> m_Q; + + state_var<unsigned> m_last_CQ; + state_var<unsigned> m_last_EQ; + state_var<unsigned> m_last_D; + state_var<unsigned> m_last_A; + state_var<unsigned> m_last_Q; + }; + + NETLIB_OBJECT_DERIVED(9334_dip, 9334) + { + NETLIB_CONSTRUCTOR_DERIVED(9334_dip, 9334) + { + register_subalias("1", m_A[0]); + register_subalias("2", m_A[1]); + register_subalias("3", m_A[2]); + register_subalias("4", m_Q[0]); + register_subalias("5", m_Q[1]); + register_subalias("6", m_Q[2]); + register_subalias("7", m_Q[3]); + + register_subalias("9", m_Q[4]); + register_subalias("10", m_Q[5]); + register_subalias("11", m_Q[6]); + register_subalias("12", m_Q[7]); + register_subalias("13", m_D); + register_subalias("14", m_EQ); + register_subalias("15", m_CQ); + + } + }; + + NETLIB_RESET(9334) + { + m_last_CQ = 0; + m_last_EQ = 0; + m_last_D = 0; + m_last_A = 0; + m_last_Q = 0; + } + + NETLIB_UPDATE(9334) + { + uint_fast8_t a = 0; + for (std::size_t i=0; i<3; i++) + { + a |= (m_A[i]() << i); + } + + netlist_time delay = NLTIME_FROM_NS(27); // Clear Low to High Level Output (not documented, making reasonable guess) + + if (a != m_last_A) + { + delay = NLTIME_FROM_NS(35); + } + else if (m_D() != m_last_D) + { + if (m_last_D) + { + delay = NLTIME_FROM_NS(28); + } + else + { + delay = NLTIME_FROM_NS(35); + } + } + else if (m_EQ() != m_last_EQ) + { + if (m_last_EQ) + { + delay = NLTIME_FROM_NS(27); + } + else + { + delay = NLTIME_FROM_NS(28); + } + } + + uint_fast8_t q = m_last_Q; + + if (!m_CQ()) + { + if (m_EQ()) + { + q = 0; + } + else + { + q = m_D() << a; + } + } + else if(!m_EQ()) + { + q &= ~(1 << a); + q |= (m_D() << a); + } + + m_last_CQ = m_CQ(); + m_last_EQ = m_EQ(); + m_last_D = m_D(); + m_last_A = a; + m_last_Q = q; + + for (std::size_t i=0; i<8; i++) + m_Q[i].push((q >> i) & 1, delay); + } + + NETLIB_DEVICE_IMPL(9334) + NETLIB_DEVICE_IMPL(9334_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_dm9334.h b/src/lib/netlist/devices/nld_dm9334.h new file mode 100644 index 00000000000..813ea225add --- /dev/null +++ b/src/lib/netlist/devices/nld_dm9334.h @@ -0,0 +1,82 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_DM9334.h + * + * DM9334: 8-Bit Addressable Latch + * + * +--------------+ + * A0 |1 ++ 16| VCC + * A1 |2 15| /C + * A2 |3 14| /E + * Q0 |4 DM9334 13| D + * Q1 |5 12| Q7 + * Q2 |6 11| Q6 + * Q3 |7 10| Q5 + * GND |8 9| Q4 + * +--------------+ + * + * +---+---++---++---+---+---++---+---+---+---+---+---+---+---+ + * | C | E || D || A0| A1| A2|| Q0| Q1| Q2| Q3| Q4| Q5| Q6| Q7| + * +===+===++===++===+===+===++===+===+===+===+===+===+===+===+ + * | 1 | 0 || X || X | X | X || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * +---+---++---++---+---+---++---+---+---+---+---+---+---+---+ + * | 1 | 1 || 0 || 0 | 0 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 0 | 0 | 0 || 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 0 || 0 | 0 | 1 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 0 | 0 | 1 || 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 0 || 0 | 1 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 0 | 1 | 0 || 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 0 || 0 | 1 | 1 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 0 | 1 | 1 || 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 0 || 1 | 0 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 1 | 0 | 0 || 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + * | 1 | 1 || 0 || 1 | 0 | 1 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 1 | 0 | 1 || 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | + * | 1 | 1 || 0 || 1 | 1 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 1 | 1 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + * | 1 | 1 || 0 || 1 | 1 | 1 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 1 | 1 || 1 || 1 | 1 | 1 || 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | + * +---+---++---++---+---+---++---+---+---+---+---+---+---+---+ + * | 0 | 0 || X || X | X | X || P | P | P | P | P | P | P | P | + * +---+---++---++---+---+---++---+---+---+---+---+---+---+---+ + * | 0 | 1 || 0 || 0 | 0 | 0 || 0 | P | P | P | P | P | P | P | + * | 0 | 1 || 1 || 0 | 0 | 0 || 1 | P | P | P | P | P | P | P | + * | 0 | 1 || 0 || 0 | 0 | 1 || P | 0 | P | P | P | P | P | P | + * | 0 | 1 || 1 || 0 | 0 | 1 || P | 1 | P | P | P | P | P | P | + * | 0 | 1 || 0 || 0 | 1 | 0 || P | P | 0 | P | P | P | P | P | + * | 0 | 1 || 1 || 0 | 1 | 0 || P | P | 1 | P | P | P | P | P | + * | 0 | 1 || 0 || 0 | 1 | 1 || P | P | P | 0 | P | P | P | P | + * | 0 | 1 || 1 || 0 | 1 | 1 || P | P | P | 1 | P | P | P | P | + * | 0 | 1 || 0 || 1 | 0 | 0 || P | P | P | P | 0 | P | P | P | + * | 0 | 1 || 1 || 1 | 0 | 0 || P | P | P | P | 1 | P | P | P | + * | 0 | 1 || 0 || 1 | 0 | 1 || P | P | P | P | P | 0 | P | P | + * | 0 | 1 || 1 || 1 | 0 | 1 || P | P | P | P | P | 1 | P | P | + * | 0 | 1 || 0 || 1 | 1 | 0 || P | P | P | P | P | P | 0 | P | + * | 0 | 1 || 1 || 1 | 1 | 0 || P | P | P | P | P | P | 1 | P | + * | 0 | 1 || 0 || 1 | 1 | 1 || P | P | P | P | P | P | P | 0 | + * | 0 | 1 || 1 || 1 | 1 | 1 || P | P | P | P | P | P | P | 1 | + * +---+---++---++---+---+---++---+---+---+---+---+---+---+---+ + * + * Naming convention attempts to follow Texas Instruments / National Semiconductor datasheet Literature Number SNOS382A + * + */ + +#ifndef NLD_DM9334_H_ +#define NLD_DM9334_H_ + +#include "nl_setup.h" + +#define TTL_9334(name, cCQ, cEQ, cD, cA0, cA1, cA2) \ + NET_REGISTER_DEV(TTL_9334, name) \ + NET_CONNECT(name, CQ, cCQ) \ + NET_CONNECT(name, EQ, cEQ) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, A0, cA0) \ + NET_CONNECT(name, A1, cA1) \ + NET_CONNECT(name, A2, cA2) + +#define TTL_9334_DIP(name) \ + NET_REGISTER_DEV(TTL_9334_DIP, name) + +#endif /* NLD_DM9334_H_ */ diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index e3369e514e5..836e744fc6a 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -86,38 +86,6 @@ namespace netlist { } - // ---------------------------------------------------------------------------------------- - // nld_d_to_a_proxy - // ---------------------------------------------------------------------------------------- - - void nld_d_to_a_proxy::reset() - { - //m_Q.initial(0.0); - m_last_state = -1; - m_RV.do_reset(); - m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices(); - m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0); - } - - NETLIB_UPDATE(d_to_a_proxy) - { - const int state = static_cast<int>(m_I()); - if (state != m_last_state) - { - m_last_state = state; - const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low; - const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V; - - // We only need to update the net first if this is a time stepping net - if (m_is_timestep) - { - m_RV.update_dev(); - } - m_RV.set(NL_FCONST(1.0) / R, V, 0.0); - m_RV.m_P.schedule_after(NLTIME_FROM_NS(1)); - } - } - // ----------------------------------------------------------------------------- // nld_res_sw diff --git a/src/lib/netlist/devices/nld_tristate.cpp b/src/lib/netlist/devices/nld_tristate.cpp new file mode 100644 index 00000000000..db21468685e --- /dev/null +++ b/src/lib/netlist/devices/nld_tristate.cpp @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_tristate.cpp + * + */ + +#include "nld_tristate.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(tristate) + { + NETLIB_CONSTRUCTOR(tristate) + , m_CEQ(*this, {{ "CEQ1", "CEQ2" }}) + , m_D(*this, {{ "D1", "D2" }}) + , m_Q(*this, "Q") + { + } + + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 2> m_CEQ; + object_array_t<logic_input_t, 2> m_D; + logic_output_t m_Q; + }; + + NETLIB_OBJECT(tristate3) + { + NETLIB_CONSTRUCTOR(tristate3) + , m_CEQ(*this, {{ "CEQ1", "CEQ2", "CEQ3" }} ) + , m_D(*this, {{ "D1", "D2", "D3" }} ) + , m_Q(*this, "Q") + { + } + + NETLIB_UPDATEI(); + + protected: + object_array_t<logic_input_t, 3> m_CEQ; + object_array_t<logic_input_t, 3> m_D; + logic_output_t m_Q; + }; + + NETLIB_UPDATE(tristate) + { + unsigned q = 0; + if (!m_CEQ[0]()) + q |= m_D[0](); + if (!m_CEQ[1]()) + q |= m_D[1](); + + m_Q.push(q, NLTIME_FROM_NS(1)); + } + + NETLIB_UPDATE(tristate3) + { + unsigned q = 0; + if (!m_CEQ[0]()) + q |= m_D[0](); + if (!m_CEQ[1]()) + q |= m_D[1](); + if (!m_CEQ[2]()) + q |= m_D[2](); + + m_Q.push(q, NLTIME_FROM_NS(1)); + } + + NETLIB_DEVICE_IMPL(tristate) + NETLIB_DEVICE_IMPL(tristate3) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_tristate.h b/src/lib/netlist/devices/nld_tristate.h new file mode 100644 index 00000000000..604ae7f03fd --- /dev/null +++ b/src/lib/netlist/devices/nld_tristate.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + * nld_tristate.h + * + * tristate: Hack to merge two tri-stated outputs together + * + */ + +#ifndef NLD_TRISTATE_H_ +#define NLD_TRISTATE_H_ + +#include "nl_setup.h" + +#define TTL_TRISTATE(name, cCEQ1, cD1, cCEQ2, cD2) \ + NET_REGISTER_DEV(TTL_TRISTATE, name) \ + NET_CONNECT(name, CEQ1, cCEQ1) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, CEQ2, cCEQ2) \ + NET_CONNECT(name, D2, cD2) + +#define TTL_TRISTATE3(name, cCEQ1, cD1, cCEQ2, cD2, cCEQ3, cD3) \ + NET_REGISTER_DEV(TTL_TRISTATE3, name) \ + NET_CONNECT(name, CEQ1, cCEQ1) \ + NET_CONNECT(name, D1, cD1) \ + NET_CONNECT(name, CEQ2, cCEQ2) \ + NET_CONNECT(name, D2, cD2) \ + NET_CONNECT(name, CEQ3, cCEQ3) \ + NET_CONNECT(name, D3, cD3) + +#endif /* NLD_TRISTATE_H_ */ diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h index 759d19cf0c9..6fcd746578f 100644 --- a/src/lib/netlist/devices/nld_truthtable.h +++ b/src/lib/netlist/devices/nld_truthtable.h @@ -23,7 +23,7 @@ public: \ template <class C> \ NETLIB_NAME(cname)(C &owner, const pstring &name) \ - : nld_truthtable_t<nIN, nOUT>(owner, name, nullptr, &m_ttbl, m_desc) { } \ + : nld_truthtable_t<nIN, nOUT>(owner, name, family_TTL(), &m_ttbl, m_desc) { } \ private: \ static truthtable_t m_ttbl; \ static const char *m_desc[]; \ diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp new file mode 100644 index 00000000000..6ecad8656a2 --- /dev/null +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -0,0 +1,101 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nlid_proxy.cpp + * + */ + +//#include <memory> +#include "nlid_proxy.h" +#include "solver/nld_solver.h" +//#include "plib/pstream.h" +//#include "plib/pfmtlog.h" +//#include "nld_log.h" + +namespace netlist +{ + namespace devices + { + + // ---------------------------------------------------------------------------------------- + // nld_d_to_a_proxy + // ---------------------------------------------------------------------------------------- + + nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied) + : nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P) + , m_GNDHack(*this, "_Q") + , m_RV(*this, "RV") + , m_last_state(*this, "m_last_var", -1) + , m_is_timestep(false) + { + const char *power_syms[3][2] ={ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}}; + //register_sub(m_RV); + //register_term("1", m_RV.m_P); + //register_term("2", m_RV.m_N); + + register_subalias("Q", m_RV.m_P); + + connect_late(m_RV.m_N, m_GNDHack); + bool f = false; + for (int i = 0; i < 3; i++) + { + pstring devname = out_proxied->device().name(); + auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0], detail::device_object_t::type_t::INPUT, false); + auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1], detail::device_object_t::type_t::INPUT, false); + if (tp != nullptr && tn != nullptr) + { + /* alternative logic */ + f = true; + } + } + if (!f) + netlist().log().warning("D/A Proxy: Found no valid combination of power terminals on device {1}", out_proxied->device().name()); + else + netlist().log().warning("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name()); +#if (0) + printf("%s %s\n", out_proxied->name().cstr(), out_proxied->device().name().cstr()); + auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::type_t::OUTPUT, false); + if (x) printf("==> %s\n", x->name().cstr()); +#endif + } + + + void nld_d_to_a_proxy::reset() + { + // FIXME: Variable voltage + double supply_V = logic_family().fixed_V(); + if (supply_V == 0.0) supply_V = 5.0; + + //m_Q.initial(0.0); + m_last_state = -1; + m_RV.do_reset(); + m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices(); + m_RV.set(NL_FCONST(1.0) / logic_family().R_low(), + logic_family().low_V(0.0, supply_V), 0.0); + } + + NETLIB_UPDATE(d_to_a_proxy) + { + const int state = static_cast<int>(m_I()); + if (state != m_last_state) + { + // FIXME: Variable voltage + double supply_V = logic_family().fixed_V(); + if (supply_V == 0.0) supply_V = 5.0; + m_last_state = state; + const nl_double R = state ? logic_family().R_high() : logic_family().R_low(); + const nl_double V = state ? logic_family().high_V(0.0, supply_V) : logic_family().low_V(0.0, supply_V); + + // We only need to update the net first if this is a time stepping net + if (m_is_timestep) + { + m_RV.update_dev(); + } + m_RV.set(NL_FCONST(1.0) / R, V, 0.0); + m_RV.m_P.schedule_after(NLTIME_FROM_NS(1)); + } + } + + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h new file mode 100644 index 00000000000..bcda8fa4e2a --- /dev/null +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -0,0 +1,184 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * nlid_proxy.h + * + * netlist proxy devices + * + * This file contains internal headers + */ + +#ifndef NLID_PROXY_H_ +#define NLID_PROXY_H_ + +#include <vector> + +#include "nl_setup.h" +#include "nl_base.h" +#include "nl_factory.h" +#include "analog/nld_twoterm.h" + +namespace netlist +{ + namespace devices + { + + // ----------------------------------------------------------------------------- + // nld_base_proxy + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(base_proxy) + { + public: + nld_base_proxy(netlist_t &anetlist, const pstring &name, + logic_t *inout_proxied, detail::core_terminal_t *proxy_inout) + : device_t(anetlist, name) + { + m_logic_family = inout_proxied->logic_family(); + m_term_proxied = inout_proxied; + m_proxy_term = proxy_inout; + } + + virtual ~nld_base_proxy() {} + + logic_t &term_proxied() const { return *m_term_proxied; } + detail::core_terminal_t &proxy_term() const { return *m_proxy_term; } + + protected: + const logic_family_desc_t *m_logic_family; + + virtual const logic_family_desc_t &logic_family() const + { + return *m_logic_family; + } + + private: + logic_t *m_term_proxied; + detail::core_terminal_t *m_proxy_term; + }; + + // ----------------------------------------------------------------------------- + // nld_a_to_d_proxy + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy) + { + public: + nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied) + : nld_base_proxy(anetlist, name, in_proxied, &m_I) + , m_I(*this, "I") + , m_Q(*this, "Q") + { + } + + virtual ~nld_a_to_d_proxy() {} + + analog_input_t m_I; + logic_output_t m_Q; + + protected: + + NETLIB_RESETI() { } + + NETLIB_UPDATEI() + { + nl_assert(m_logic_family != nullptr); + // FIXME: Variable supply voltage! + double supply_V = logic_family().fixed_V(); + if (supply_V == 0.0) supply_V = 5.0; + + if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V)) + m_Q.push(1, NLTIME_FROM_NS(1)); + else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V)) + m_Q.push(0, NLTIME_FROM_NS(1)); + else + { + // do nothing + } + } + private: + }; + + // ----------------------------------------------------------------------------- + // nld_base_d_to_a_proxy + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy) + { + public: + virtual ~nld_base_d_to_a_proxy() {} + + virtual logic_input_t &in() { return m_I; } + + protected: + nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, + logic_output_t *out_proxied, detail::core_terminal_t &proxy_out) + : nld_base_proxy(anetlist, name, out_proxied, &proxy_out) + , m_I(*this, "I") + { + } + + logic_input_t m_I; + + private: + }; + + NETLIB_OBJECT_DERIVED(d_to_a_proxy, base_d_to_a_proxy) + { + public: + nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied); + virtual ~nld_d_to_a_proxy() {} + + protected: + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + private: + analog_output_t m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd + NETLIB_SUB(twoterm) m_RV; + state_var<int> m_last_state; + bool m_is_timestep; + }; + + + class factory_lib_entry_t : public base_factory_t + { + P_PREVENT_COPYING(factory_lib_entry_t) + public: + + factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname, + const pstring &def_param) + : base_factory_t(name, classname, def_param), m_setup(setup) { } + + class wrapper : public device_t + { + public: + wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name) + : device_t(anetlist, name), m_devname(devname) + { + anetlist.setup().namespace_push(name); + anetlist.setup().include(m_devname); + anetlist.setup().namespace_pop(); + } + protected: + NETLIB_RESETI() { } + NETLIB_UPDATEI() { } + + pstring m_devname; + }; + + plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override + { + return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name); + } + + private: + setup_t &m_setup; + }; + + + } //namespace devices +} // namespace netlist + +#endif /* NLD_PROXY_H_ */ diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index f16dc42b298..89251264fa7 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -413,171 +413,6 @@ namespace netlist state_var<netlist_sig_t> m_last_state; }; - // ----------------------------------------------------------------------------- - // nld_base_proxy - // ----------------------------------------------------------------------------- - - NETLIB_OBJECT(base_proxy) - { - public: - nld_base_proxy(netlist_t &anetlist, const pstring &name, - logic_t *inout_proxied, detail::core_terminal_t *proxy_inout) - : device_t(anetlist, name) - { - m_logic_family = inout_proxied->logic_family(); - m_term_proxied = inout_proxied; - m_proxy_term = proxy_inout; - } - - virtual ~nld_base_proxy() {} - - logic_t &term_proxied() const { return *m_term_proxied; } - detail::core_terminal_t &proxy_term() const { return *m_proxy_term; } - - protected: - - virtual const logic_family_desc_t &logic_family() const - { - return *m_logic_family; - } - - private: - const logic_family_desc_t *m_logic_family; - logic_t *m_term_proxied; - detail::core_terminal_t *m_proxy_term; - }; - - // ----------------------------------------------------------------------------- - // nld_a_to_d_proxy - // ----------------------------------------------------------------------------- - - NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy) - { - public: - nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied) - : nld_base_proxy(anetlist, name, in_proxied, &m_I) - , m_I(*this, "I") - , m_Q(*this, "Q") - { - } - - virtual ~nld_a_to_d_proxy() {} - - analog_input_t m_I; - logic_output_t m_Q; - - protected: - - NETLIB_RESETI() { } - - NETLIB_UPDATEI() - { - if (m_I.Q_Analog() > logic_family().m_high_thresh_V) - m_Q.push(1, NLTIME_FROM_NS(1)); - else if (m_I.Q_Analog() < logic_family().m_low_thresh_V) - m_Q.push(0, NLTIME_FROM_NS(1)); - else - { - // do nothing - } - } - private: - }; - - // ----------------------------------------------------------------------------- - // nld_base_d_to_a_proxy - // ----------------------------------------------------------------------------- - - NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy) - { - public: - virtual ~nld_base_d_to_a_proxy() {} - - virtual logic_input_t &in() { return m_I; } - - protected: - nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, - logic_output_t *out_proxied, detail::core_terminal_t &proxy_out) - : nld_base_proxy(anetlist, name, out_proxied, &proxy_out) - , m_I(*this, "I") - { - } - - logic_input_t m_I; - - private: - }; - - NETLIB_OBJECT_DERIVED(d_to_a_proxy, base_d_to_a_proxy) - { - public: - nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied) - : nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P) - , m_GNDHack(*this, "_Q") - , m_RV(*this, "RV") - , m_last_state(*this, "m_last_var", -1) - , m_is_timestep(false) - { - //register_sub(m_RV); - //register_term("1", m_RV.m_P); - //register_term("2", m_RV.m_N); - - register_subalias("Q", m_RV.m_P); - - connect_late(m_RV.m_N, m_GNDHack); - } - - virtual ~nld_d_to_a_proxy() {} - - protected: - - NETLIB_RESETI(); - NETLIB_UPDATEI(); - - private: - analog_output_t m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd - NETLIB_SUB(twoterm) m_RV; - state_var<int> m_last_state; - bool m_is_timestep; - }; - - - class factory_lib_entry_t : public base_factory_t - { - P_PREVENT_COPYING(factory_lib_entry_t) - public: - - factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname, - const pstring &def_param) - : base_factory_t(name, classname, def_param), m_setup(setup) { } - - class wrapper : public device_t - { - public: - wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name) - : device_t(anetlist, name), m_devname(devname) - { - anetlist.setup().namespace_push(name); - anetlist.setup().include(m_devname); - anetlist.setup().namespace_pop(); - } - protected: - NETLIB_RESETI() { } - NETLIB_UPDATEI() { } - - pstring m_devname; - }; - - plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override - { - return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name); - } - - private: - setup_t &m_setup; - }; - - } //namespace devices } // namespace netlist diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp index 95fff085b9e..d169e2790f5 100644 --- a/src/lib/netlist/macro/nlm_cd4xxx.cpp +++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp @@ -6,6 +6,7 @@ #include "devices/nld_system.h" #include "devices/nld_4020.h" #include "devices/nld_4066.h" +#include "devices/nld_4316.h" /* * CD4001BC: Quad 2-Input NOR Buffered B Series Gate @@ -31,14 +32,14 @@ static NETLIST_START(CD4001_DIP) DUMMY_INPUT(VSS) DUMMY_INPUT(VDD) - DIPPINS( /* +--------------+ */ - s1.A, /* A1 |1 ++ 14| VCC */ VSS.I, - s1.B, /* B1 |2 13| A6 */ s4.B, - s1.Q, /* A2 |3 12| Y6 */ s4.A, - s2.Q, /* Y2 |4 4001 11| A5 */ s4.Q, - s2.A, /* A3 |5 10| Y5 */ s3.Q, - s2.B, /* Y3 |6 9| A4 */ s3.B, - VDD.I, /* GND |7 8| Y4 */ s3.A + DIPPINS( /* +--------------+ */ + s1.A, /* A1 |1 ++ 14| VCC */ VSS.I, + s1.B, /* B1 |2 13| A6 */ s4.B, + s1.Q, /* A2 |3 12| Y6 */ s4.A, + s2.Q, /* Y2 |4 4001 11| A5 */ s4.Q, + s2.A, /* A3 |5 10| Y5 */ s3.Q, + s2.B, /* Y3 |6 9| A4 */ s3.B, + VDD.I, /* GND |7 8| Y4 */ s3.A /* +--------------+ */ ) @@ -115,14 +116,14 @@ static NETLIST_START(CD4066_DIP) PARAM(C.BASER, 270.0) PARAM(D.BASER, 270.0) - DIPPINS( /* +--------------+ */ - A.R.1, /* INOUTA |1 ++ 14| VDD */ A.PS.VDD, - A.R.2, /* OUTINA |2 13| CONTROLA */ A.CTL, - B.R.1, /* OUTINB |3 12| CONTROLD */ D.CTL, - B.R.2, /* INOUTB |4 4066 11| INOUTD */ D.R.1, - B.CTL, /* CONTROLB |5 10| OUTIND */ D.R.2, - C.CTL, /* CONTROLC |6 9| OUTINC */ C.R.1, - A.PS.VSS, /* VSS |7 8| INOUTC */ C.R.2 + DIPPINS( /* +--------------+ */ + A.R.1, /* INOUTA |1 ++ 14| VDD */ A.PS.VDD, + A.R.2, /* OUTINA |2 13| CONTROLA */ A.CTL, + B.R.1, /* OUTINB |3 12| CONTROLD */ D.CTL, + B.R.2, /* INOUTB |4 4066 11| INOUTD */ D.R.1, + B.CTL, /* CONTROLB |5 10| OUTIND */ D.R.2, + C.CTL, /* CONTROLC |6 9| OUTINC */ C.R.1, + A.PS.VSS, /* VSS |7 8| INOUTC */ C.R.2 /* +--------------+ */ ) NETLIST_END() @@ -141,18 +142,47 @@ static NETLIST_START(CD4016_DIP) PARAM(C.BASER, 1000.0) PARAM(D.BASER, 1000.0) - DIPPINS( /* +--------------+ */ - A.R.1, /* INOUTA |1 ++ 14| VDD */ A.PS.VDD, - A.R.2, /* OUTINA |2 13| CONTROLA */ A.CTL, - B.R.1, /* OUTINB |3 12| CONTROLD */ D.CTL, - B.R.2, /* INOUTB |4 4016 11| INOUTD */ D.R.1, - B.CTL, /* CONTROLB |5 10| OUTIND */ D.R.2, - C.CTL, /* CONTROLC |6 9| OUTINC */ C.R.1, - A.PS.VSS, /* VSS |7 8| INOUTC */ C.R.2 + DIPPINS( /* +--------------+ */ + A.R.1, /* INOUTA |1 ++ 14| VDD */ A.PS.VDD, + A.R.2, /* OUTINA |2 13| CONTROLA */ A.CTL, + B.R.1, /* OUTINB |3 12| CONTROLD */ D.CTL, + B.R.2, /* INOUTB |4 4016 11| INOUTD */ D.R.1, + B.CTL, /* CONTROLB |5 10| OUTIND */ D.R.2, + C.CTL, /* CONTROLC |6 9| OUTINC */ C.R.1, + A.PS.VSS, /* VSS |7 8| INOUTC */ C.R.2 /* +--------------+ */ ) NETLIST_END() +static NETLIST_START(CD4316_DIP) + CD4316_GATE(A) + CD4316_GATE(B) + CD4316_GATE(C) + CD4316_GATE(D) + + NET_C(A.E, B.E, C.E, D.E) + NET_C(A.PS.VDD, B.PS.VDD, C.PS.VDD, D.PS.VDD) + NET_C(A.PS.VSS, B.PS.VSS, C.PS.VSS, D.PS.VSS) + + PARAM(A.BASER, 45.0) + PARAM(B.BASER, 45.0) + PARAM(C.BASER, 45.0) + PARAM(D.BASER, 45.0) + + DIPPINS( /* +--------------+ */ + A.R.2, /* 1Z |1 ++ 16| VCC */ A.PS.VDD, + A.R.1, /* 1Y |2 15| 1S */ A.S, + B.R.1, /* 2Y |3 14| 4S */ D.S, + B.R.2, /* 2Z |4 4316 13| 4Z */ D.R.2, + B.S, /* 2S |5 12| 4Y */ D.R.1, + C.S, /* 3S |6 11| 3Y */ C.R.1, + A.E, /* /E |7 10| 3Z */ C.R.2, + A.PS.VSS, /* GND |8 9| VEE */ VEE + /* +--------------+ */ + ) + +NETLIST_END() + NETLIST_START(CD4XXX_lib) TRUTHTABLE_START(CD4001_NOR, 2, 1, "") @@ -169,5 +199,6 @@ NETLIST_START(CD4XXX_lib) LOCAL_LIB_ENTRY(CD4020_DIP) LOCAL_LIB_ENTRY(CD4016_DIP) LOCAL_LIB_ENTRY(CD4066_DIP) + LOCAL_LIB_ENTRY(CD4316_DIP) NETLIST_END() diff --git a/src/lib/netlist/macro/nlm_cd4xxx.h b/src/lib/netlist/macro/nlm_cd4xxx.h index acc47f45d21..de10ff7a64d 100644 --- a/src/lib/netlist/macro/nlm_cd4xxx.h +++ b/src/lib/netlist/macro/nlm_cd4xxx.h @@ -41,6 +41,9 @@ #define CD4016_DIP(name) \ NET_REGISTER_DEV(CD4016_DIP, name) +#define CD4316_DIP(name) \ + NET_REGISTER_DEV(CD4016_DIP, name) + /* ---------------------------------------------------------------------------- * External declarations * ---------------------------------------------------------------------------*/ diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp index e7571dfd910..08dc5f60b27 100644 --- a/src/lib/netlist/macro/nlm_opamp.cpp +++ b/src/lib/netlist/macro/nlm_opamp.cpp @@ -6,18 +6,18 @@ #include "devices/nld_system.h" /* - * Generic layout with 4 opamps, VCC on pint 4 and GND on pin 11 + * Generic layout with 4 opamps, VCC on pin 4 and GND on pin 11 */ static NETLIST_START(opamp_layout_4_4_11) - DIPPINS( /* +--------------+ */ - A.OUT, /* |1 ++ 14| */ D.OUT, - A.MINUS, /* |2 13| */ D.MINUS, - A.PLUS, /* |3 12| */ D.PLUS, - A.VCC, /* |4 11| */ A.GND, - B.PLUS, /* |5 10| */ C.PLUS, - B.MINUS, /* |6 9| */ C.MINUS, - B.OUT, /* |7 8| */ C.OUT + DIPPINS( /* +--------------+ */ + A.OUT, /* |1 ++ 14| */ D.OUT, + A.MINUS, /* |2 13| */ D.MINUS, + A.PLUS, /* |3 12| */ D.PLUS, + A.VCC, /* |4 11| */ A.GND, + B.PLUS, /* |5 10| */ C.PLUS, + B.MINUS, /* |6 9| */ C.MINUS, + B.OUT, /* |7 8| */ C.OUT /* +--------------+ */ ) NET_C(A.GND, B.GND, C.GND, D.GND) @@ -25,21 +25,100 @@ static NETLIST_START(opamp_layout_4_4_11) NETLIST_END() /* - * Generic layout with 2 opamps, VCC on pint 8 and GND on pin 4 + * Generic layout with 2 opamps, VCC on pin 8 and GND on pin 4 */ static NETLIST_START(opamp_layout_2_8_4) - DIPPINS( /* +--------------+ */ - A.OUT, /* |1 ++ 8| */ A.VCC, - A.MINUS, /* |2 7| */ B.OUT, - A.PLUS, /* |3 6| */ B.MINUS, - A.GND, /* |4 5| */ B.PLUS + DIPPINS( /* +--------------+ */ + A.OUT, /* |1 ++ 8| */ A.VCC, + A.MINUS, /* |2 7| */ B.OUT, + A.PLUS, /* |3 6| */ B.MINUS, + A.GND, /* |4 5| */ B.PLUS /* +--------------+ */ ) NET_C(A.GND, B.GND) NET_C(A.VCC, B.VCC) NETLIST_END() +/* + * Generic layout with 2 opamps, VCC+ on pins 9/13, VCC- on pin 4 and compensation + */ + +static NETLIST_START(opamp_layout_2_13_9_4) + DIPPINS( /* +--------------+ */ + A.MINUS, /* |1 ++ 14| */ A.N2, + A.PLUS, /* |2 13| */ A.VCC, + A.N1, /* |3 12| */ A.OUT, + A.GND, /* |4 11| */ NC, + B.N1, /* |5 10| */ B.OUT, + B.PLUS, /* |6 9| */ B.VCC, + B.MINUS /* |7 8| */ B.N2 + /* +--------------+ */ + ) + NET_C(A.GND, B.GND) +NETLIST_END() + +/* + * Generic layout with 1 opamp, VCC+ on pin 7, VCC- on pin 4 and compensation + */ + +static NETLIST_START(opamp_layout_1_7_4) + DIPPINS( /* +--------------+ */ + OFFSET.N1, /* |1 ++ 8| */ NC, + MINUS, /* |2 7| */ VCC.PLUS, + PLUS, /* |3 6| */ OUT, + VCC.MINUS, /* |4 5| */ OFFSET.N2 + /* +--------------+ */ + ) + NET_C(A.GND, VCC.MINUS) + NET_C(A.VCC, VCC.PLUS) + NET_C(A.MINUS, MINUS) + NET_C(A.PLUS, PLUS) + NET_C(A.OUT, OUT) +NETLIST_END() + +/* + * Generic layout with 1 opamp, VCC+ on pin 8, VCC- on pin 5 and compensation + */ + +static NETLIST_START(opamp_layout_1_8_5) + DIPPINS( /* +--------------+ */ + NC.1, /* |1 10| */ NC.3, + OFFSET.N1, /* |2 9| */ NC.2, + MINUS, /* |3 8| */ VCC.PLUS, + PLUS, /* |4 7| */ OUT, + VCC.MINUS, /* |5 6| */ OFFSET.N2 + /* +--------------+ */ + ) + NET_C(A.GND, VCC.MINUS) + NET_C(A.VCC, VCC.PLUS) + NET_C(A.MINUS, MINUS) + NET_C(A.PLUS, PLUS) + NET_C(A.OUT, OUT) +NETLIST_END() + +/* + * Generic layout with 1 opamp, VCC+ on pin 11, VCC- on pin 6 and compensation + */ + +static NETLIST_START(opamp_layout_1_11_6) + DIPPINS( /* +--------------+ */ + NC.1, /* |1 ++ 14| */ NC.7, + NC.2, /* |2 13| */ NC.6, + OFFSET.N1, /* |3 12| */ NC.5, + MINUS, /* |4 11| */ VCC.PLUS, + PLUS, /* |5 10| */ OUT, + VCC.MINUS, /* |6 9| */ OFFSET.N2, + NC.3, /* |7 8| */ NC.4 + /* +--------------+ */ + ) + NET_C(A.GND, VCC.MINUS) + NET_C(A.VCC, VCC.PLUS) + NET_C(A.MINUS, MINUS) + NET_C(A.PLUS, PLUS) + NET_C(A.OUT, OUT) +NETLIST_END() + static NETLIST_START(MB3614_DIP) OPAMP(A, "MB3614") OPAMP(B, "MB3614") @@ -68,17 +147,67 @@ static NETLIST_START(LM358_DIP) NETLIST_END() +static NETLIST_START(UA741_DIP8) + OPAMP(A, "UA741") + + INCLUDE(opamp_layout_1_7_4) + +NETLIST_END() + +static NETLIST_START(UA741_DIP10) + OPAMP(A, "UA741") + + INCLUDE(opamp_layout_1_8_5) + +NETLIST_END() + +static NETLIST_START(UA741_DIP14) + OPAMP(A, "UA741") + + INCLUDE(opamp_layout_1_11_6) + +NETLIST_END() + +static NETLIST_START(LM747_DIP) + OPAMP(A, "LM747") + OPAMP(B, "LM747") + + INCLUDE(opamp_layout_2_13_9_4) + NET_C(A.VCC, B.VCC) + +NETLIST_END() + +static NETLIST_START(LM747A_DIP) + OPAMP(A, "LM747A") + OPAMP(B, "LM747A") + + INCLUDE(opamp_layout_2_13_9_4) + NET_C(A.VCC, B.VCC) + +NETLIST_END() + NETLIST_START(OPAMP_lib) LOCAL_LIB_ENTRY(opamp_layout_4_4_11) LOCAL_LIB_ENTRY(opamp_layout_2_8_4) + LOCAL_LIB_ENTRY(opamp_layout_2_13_9_4) + LOCAL_LIB_ENTRY(opamp_layout_1_7_4) + LOCAL_LIB_ENTRY(opamp_layout_1_8_5) + LOCAL_LIB_ENTRY(opamp_layout_1_11_6) NET_MODEL("LM324 OPAMP(TYPE=3 VLH=2.0 VLL=0.2 FPF=5 UGF=500k SLEW=0.3M RI=1000k RO=50 DAB=0.00075)") NET_MODEL("LM358 OPAMP(TYPE=3 VLH=2.0 VLL=0.2 FPF=5 UGF=500k SLEW=0.3M RI=1000k RO=50 DAB=0.001)") NET_MODEL("MB3614 OPAMP(TYPE=3 VLH=1.4 VLL=0.02 FPF=2 UGF=500k SLEW=0.6M RI=1000k RO=50 DAB=0.0002)") + NET_MODEL("UA741 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=75 DAB=0.0017)") + NET_MODEL("LM747 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=50 DAB=0.0017)") + NET_MODEL("LM747A OPAMP(TYPE=3 VLH=2.0 VLL=2.0 FPF=5 UGF=1000k SLEW=0.7M RI=6000k RO=50 DAB=0.0015)") LOCAL_LIB_ENTRY(MB3614_DIP) LOCAL_LIB_ENTRY(LM324_DIP) LOCAL_LIB_ENTRY(LM358_DIP) - + LOCAL_LIB_ENTRY(UA741_DIP8) + LOCAL_LIB_ENTRY(UA741_DIP10) + LOCAL_LIB_ENTRY(UA741_DIP14) + LOCAL_LIB_ENTRY(LM747_DIP) + LOCAL_LIB_ENTRY(LM747A_DIP) NETLIST_END() diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp index 68c0ea57d36..84a3af4dc04 100644 --- a/src/lib/netlist/macro/nlm_other.cpp +++ b/src/lib/netlist/macro/nlm_other.cpp @@ -36,7 +36,7 @@ static NETLIST_START(MC14584B_DIP) s1.A, /* A1 |1 ++ 14| VCC */ VCC.I, s1.Q, /* Y1 |2 13| A6 */ s6.A, s2.A, /* A2 |3 12| Y6 */ s6.Q, - s2.Q, /* Y2 |4 7416 11| A5 */ s5.A, + s2.Q, /* Y2 |4 MC14584B 11| A5 */ s5.A, s3.A, /* A3 |5 10| Y5 */ s5.Q, s3.Q, /* Y3 |6 9| A4 */ s4.A, GND.I, /* GND |7 8| Y4 */ s4.Q @@ -49,7 +49,8 @@ NETLIST_START(otheric_lib) TT_HEAD(" A | Q ") TT_LINE(" 0 | 1 |100") TT_LINE(" 1 | 0 |100") - TT_FAMILY("FAMILY(IVL=2.1 IVH=2.7 OVL=0.05 OVH=4.95 ORL=10.0 ORH=10.0)") + // 2.1V negative going and 2.7V positive going at 5V + TT_FAMILY("FAMILY(FV=0 IVL=0.42 IVH=0.54 OVL=0.05 OVH=0.05 ORL=10.0 ORH=10.0)") TRUTHTABLE_END() LOCAL_LIB_ENTRY(MC14584B_DIP) diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp index 646ae44a86b..2120d88eb3f 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.cpp +++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp @@ -540,6 +540,44 @@ static NETLIST_START(TTL_7486_DIP) ) NETLIST_END() +/* + * DM74260: Dual 5-Input NOR Gates + * _________ + * Y = A+B+C+D+E + * +---+---+---+---+---++---+ + * | A | B | B | B | B || Y | + * +===+===+===+===+===++===+ + * | 0 | 0 | 0 | 0 | 0 || 1 | + * | 0 | 0 | 0 | 0 | 1 || 0 | + * | 0 | 0 | 0 | 1 | 0 || 0 | + * | 0 | 0 | 1 | 0 | 0 || 0 | + * | 0 | 1 | 0 | 0 | 0 || 0 | + * | 1 | 0 | 0 | 0 | 0 || 0 | + * +---+---+---+---+---++---+ + * + * Naming conventions follow Texas Instruments datasheet + * + */ + +static NETLIST_START(TTL_74260_DIP) + TTL_74260_GATE(s1) + TTL_74260_GATE(s2) + + DUMMY_INPUT(GND) + DUMMY_INPUT(VCC) + + DIPPINS( /* +--------------+ */ + s1.C, /* C1 |1 ++ 14| VCC */ VCC.I, + s1.D, /* D1 |2 13| B1 */ s1.B, + s1.E, /* E1 |3 12| A1 */ s1.A, + s2.E, /* E2 |4 74260 11| D2 */ s2.D, + s1.Q, /* Y1 |5 10| C2 */ s2.C, + s2.Q, /* Y2 |6 9| B2 */ s2.B, + GND.I, /* GND |7 8| A2 */ s2.A + /* +--------------+ */ + ) +NETLIST_END() + NETLIST_START(TTL74XX_lib) TRUTHTABLE_START(TTL_7400_GATE, 2, 1, "") @@ -788,6 +826,28 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() + TRUTHTABLE_START(TTL_74260_GATE, 5, 1, "") + TT_HEAD("A,B,C,D,E|Q ") + TT_LINE("0,0,0,0,0|1|10") + TT_LINE("X,X,X,X,1|0|12") + TT_LINE("X,X,X,1,X|0|12") + TT_LINE("X,X,1,X,X|0|12") + TT_LINE("X,1,X,X,X|0|12") + TT_LINE("1,X,X,X,X|0|12") + TT_FAMILY("74XX") + TRUTHTABLE_END() + + TRUTHTABLE_START(TTL_74260_NOR, 5, 1, "A,B,C,D,E") + TT_HEAD("A,B,C,D,E|Q ") + TT_LINE("0,0,0,0,0|1|10") + TT_LINE("X,X,X,X,1|0|12") + TT_LINE("X,X,X,1,X|0|12") + TT_LINE("X,X,1,X,X|0|12") + TT_LINE("X,1,X,X,X|0|12") + TT_LINE("1,X,X,X,X|0|12") + TT_FAMILY("74XX") + TRUTHTABLE_END() + LOCAL_LIB_ENTRY(TTL_7400_DIP) LOCAL_LIB_ENTRY(TTL_7402_DIP) LOCAL_LIB_ENTRY(TTL_7404_DIP) @@ -802,4 +862,5 @@ NETLIST_START(TTL74XX_lib) LOCAL_LIB_ENTRY(TTL_7432_DIP) LOCAL_LIB_ENTRY(TTL_7437_DIP) LOCAL_LIB_ENTRY(TTL_7486_DIP) + LOCAL_LIB_ENTRY(TTL_74260_DIP) NETLIST_END() diff --git a/src/lib/netlist/macro/nlm_ttl74xx.h b/src/lib/netlist/macro/nlm_ttl74xx.h index 54b9dfa6e44..44b3db63bd3 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.h +++ b/src/lib/netlist/macro/nlm_ttl74xx.h @@ -185,6 +185,21 @@ #define TTL_7486_DIP(name) \ NET_REGISTER_DEV(TTL_7486_DIP, name) + +#define TTL_74260_GATE(name) \ + NET_REGISTER_DEV(TTL_74260_GATE, name) + +#define TTL_74260_NOR(name, cA, cB, cC, cD, cE) \ + NET_REGISTER_DEV(TTL_74260_NOR, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, C, cC) \ + NET_CONNECT(name, D, cD) \ + NET_CONNECT(name, E, cE) + +#define TTL_74260_DIP(name) \ + NET_REGISTER_DEV(TTL_74260_DIP, name) + /* ---------------------------------------------------------------------------- * External declarations * ---------------------------------------------------------------------------*/ diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index d8a01612e25..76ce59db5ac 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -15,6 +15,7 @@ #include "nl_base.h" #include "devices/nlid_system.h" +#include "devices/nlid_proxy.h" namespace netlist { @@ -57,11 +58,12 @@ class logic_family_ttl_t : public logic_family_desc_t public: logic_family_ttl_t() : logic_family_desc_t() { - m_low_thresh_V = 0.8; - m_high_thresh_V = 2.0; + m_fixed_V = 5.0; + m_low_thresh_PCNT = 0.8 / 5.0; + m_high_thresh_PCNT = 2.0 / 5.0; // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_V = 0.1; - m_high_V = 4.0; + m_low_VO = 0.1; + m_high_VO = 1.0; // 4.0 m_R_low = 1.0; m_R_high = 130.0; } @@ -76,11 +78,12 @@ class logic_family_cd4xxx_t : public logic_family_desc_t public: logic_family_cd4xxx_t() : logic_family_desc_t() { - m_low_thresh_V = 0.8; - m_high_thresh_V = 2.0; + m_fixed_V = 0.0; + m_low_thresh_PCNT = 1.5 / 5.0; + m_high_thresh_PCNT = 3.5 / 5.0; // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_V = 0.05; - m_high_V = 4.95; + m_low_VO = 0.05; + m_high_VO = 0.05; // 4.95 m_R_low = 10.0; m_R_high = 10.0; } @@ -464,26 +467,7 @@ void netlist_t::print_stats() const } } -// ---------------------------------------------------------------------------------------- -// Parameters ... -// ---------------------------------------------------------------------------------------- -template <typename C, param_t::param_type_t T> -param_template_t<C, T>::param_template_t(device_t &device, const pstring name, const C val) -: param_t(T, device, device.name() + "." + name) -, m_param(val) -{ - /* pstrings not yet supported, these need special logic */ - if (T != param_t::STRING && T != param_t::MODEL) - netlist().save(*this, m_param, "m_param"); - device.setup().register_and_set_param(device.name() + "." + name, *this); -} - -template class param_template_t<double, param_t::DOUBLE>; -template class param_template_t<int, param_t::INTEGER>; -template class param_template_t<bool, param_t::LOGIC>; -template class param_template_t<pstring, param_t::STRING>; -template class param_template_t<pstring, param_t::MODEL>; // ---------------------------------------------------------------------------------------- // core_device_t @@ -904,13 +888,21 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname) } // ---------------------------------------------------------------------------------------- -// param_t & friends +// Parameters ... // ---------------------------------------------------------------------------------------- param_t::param_t(const param_type_t atype, device_t &device, const pstring &name) - : device_object_t(device, name, PARAM) + : device_object_t(device, device.name() + "." + name, PARAM) , m_param_type(atype) { + device.setup().register_param(this->name(), *this); +} + +void param_t::update_param() +{ + device().update_param(); + if (device().needs_update_after_param_change()) + device().update_dev(); } const pstring param_model_t::model_type() @@ -920,6 +912,39 @@ const pstring param_model_t::model_type() return m_map["COREMODEL"]; } +param_str_t::param_str_t(device_t &device, const pstring name, const pstring val) +: param_t(param_t::STRING, device, name) +{ + m_param = device.setup().get_initial_param_val(this->name(),val); +} + +param_double_t::param_double_t(device_t &device, const pstring name, const double val) +: param_t(param_t::DOUBLE, device, name) +{ + m_param = device.setup().get_initial_param_val(this->name(),val); + netlist().save(*this, m_param, "m_param"); +} + +param_int_t::param_int_t(device_t &device, const pstring name, const int val) +: param_t(param_t::INTEGER, device, name) +{ + m_param = device.setup().get_initial_param_val(this->name(),val); + netlist().save(*this, m_param, "m_param"); +} + +param_logic_t::param_logic_t(device_t &device, const pstring name, const bool val) +: param_t(param_t::LOGIC, device, name) +{ + m_param = device.setup().get_initial_param_val(this->name(),val); + netlist().save(*this, m_param, "m_param"); +} + +param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val) +: param_t(param_t::POINTER, device, name) +{ + m_param = val; //device.setup().get_initial_param_val(this->name(),val); + //netlist().save(*this, m_param, "m_param"); +} const pstring param_model_t::model_value_str(const pstring &entity) { @@ -935,6 +960,12 @@ nl_double param_model_t::model_value(const pstring &entity) return netlist().setup().model_value(m_map, entity); } +std::unique_ptr<plib::pistream> param_data_t::stream() +{ + return device().netlist().setup().get_data_stream(Value()); +} + + namespace devices { diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 55b1ef009b6..f72665c62bc 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -21,6 +21,7 @@ #include "plib/pdynlib.h" #include "plib/pstate.h" #include "plib/pfmtlog.h" +#include "plib/pstream.h" // ---------------------------------------------------------------------------------------- // Type definitions @@ -125,6 +126,7 @@ class NETLIB_NAME(name) : public device_t #define NETLIB_SUBXX(chip) std::unique_ptr< nld_ ## chip > #define NETLIB_UPDATE(chip) void NETLIB_NAME(chip) :: update(void) NL_NOEXCEPT +#define NETLIB_PARENT_UPDATE(chip) NETLIB_NAME(chip) :: update(); #define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void) @@ -226,12 +228,21 @@ namespace netlist virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; - nl_double m_low_thresh_V; //!< low input threshhold. If the input voltage is below this value, a "0" input is signalled - nl_double m_high_thresh_V; //!< high input threshhold. If the input voltage is above this value, a "0" input is signalled - nl_double m_low_V; //!< low output voltage. This voltage is output if the ouput is "0" - nl_double m_high_V; //!< high output voltage. This voltage is output if the ouput is "1" - nl_double m_R_low; //!< low output resistance. Value of series resistor used for low output - nl_double m_R_high; //!< high output resistance. Value of series resistor used for high output + double fixed_V() const { return m_fixed_V; } + double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; } + double high_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_high_thresh_PCNT; } + double low_V(const double VN, const double VP) const { return VN + m_low_VO; } + double high_V(const double VN, const double VP) const { return VP - m_high_VO; } + double R_low() const { return m_R_low; } + double R_high() const { return m_R_high; } + + double m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */ + double m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled + double m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled + double m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0" + double m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1" + double m_R_low; //!< low output resistance. Value of series resistor used for low output + double m_R_high; //!< high output resistance. Value of series resistor used for high output }; /*! Base class for devices, terminals, outputs and inputs which support @@ -828,11 +839,11 @@ namespace netlist public: enum param_type_t { - MODEL, STRING, DOUBLE, INTEGER, - LOGIC + LOGIC, + POINTER // Special-case which is always initialized at MAME startup time }; param_t(const param_type_t atype, device_t &device, const pstring &name); @@ -840,36 +851,85 @@ namespace netlist param_type_t param_type() const { return m_param_type; } + protected: + void update_param(); + + template<typename C> + void set(C &p, const C v) + { + if (p != v) + { + p = v; + update_param(); + } + } + private: const param_type_t m_param_type; }; - template <typename C, param_t::param_type_t T> - class param_template_t : public param_t + class param_ptr_t final: public param_t { - P_PREVENT_COPYING(param_template_t) public: - param_template_t(device_t &device, const pstring name, const C val); + param_ptr_t(device_t &device, const pstring name, std::uint8_t* val); + std::uint8_t * operator()() const { return m_param; } + void setTo(std::uint8_t *param) { set(m_param, param); } + private: + std::uint8_t* m_param; + }; - const C operator()() const { return Value(); } + class param_logic_t final: public param_t + { + public: + param_logic_t(device_t &device, const pstring name, const bool val); + bool operator()() const { return m_param; } + void setTo(const bool ¶m) { set(m_param, param); } + private: + bool m_param; + }; - void setTo(const C ¶m); - void initial(const C &val) { m_param = val; } + class param_int_t final: public param_t + { + public: + param_int_t(device_t &device, const pstring name, const int val); + int operator()() const { return m_param; } + void setTo(const int ¶m) { set(m_param, param); } + private: + int m_param; + }; + class param_double_t final: public param_t + { + public: + param_double_t(device_t &device, const pstring name, const double val); + double operator()() const { return m_param; } + void setTo(const double ¶m) { set(m_param, param); } + private: + double m_param; + }; + + class param_str_t : public param_t + { + public: + param_str_t(device_t &device, const pstring name, const pstring val); + const pstring operator()() const { return Value(); } + void setTo(const pstring ¶m) + { + if (m_param != param) + { + m_param = param; + changed(); + update_param(); + } + } protected: - C Value() const { return m_param; } virtual void changed() { } - C m_param; + pstring Value() const { return m_param; } private: + pstring m_param; }; - using param_double_t = param_template_t<nl_double, param_t::DOUBLE>; - using param_int_t = param_template_t<int, param_t::INTEGER>; - using param_str_t = param_template_t<pstring, param_t::STRING>; - - using param_logic_t = param_template_t<bool, param_t::LOGIC>; - - class param_model_t : public param_str_t + class param_model_t final : public param_str_t { public: param_model_t(device_t &device, const pstring name, const pstring val) @@ -880,12 +940,41 @@ namespace netlist const pstring model_value_str(const pstring &entity); const pstring model_type(); protected: - void changed() override + virtual void changed() override { m_map.clear(); } + private: + model_map_t m_map; + }; + + class param_data_t : public param_str_t + { + public: + param_data_t(device_t &device, const pstring name) + : param_str_t(device, name, "") { } + std::unique_ptr<plib::pistream> stream(); + protected: + virtual void changed() override { } + }; + + template <typename ST, std::size_t AW, std::size_t DW> + class param_rom_t final: public param_data_t + { + public: + + param_rom_t(device_t &device, const pstring name) + : param_data_t(device, name) + { + stream()->read(&m_data[0],1<<AW); + } + + const ST & operator[] (std::size_t n) { return m_data[n]; } + + protected: + virtual void changed() override { - m_map.clear(); + stream()->read(&m_data[0],1<<AW); } private: - model_map_t m_map; + ST m_data[1 << AW]; }; // ----------------------------------------------------------------------------- @@ -1208,19 +1297,6 @@ namespace netlist // inline implementations // ----------------------------------------------------------------------------- - template <class C, param_t::param_type_t T> - inline void param_template_t<C, T>::setTo(const C ¶m) - { - if (m_param != param) - { - m_param = param; - changed(); - device().update_param(); - if (device().needs_update_after_param_change()) - device().update_dev(); - } - } - inline bool detail::core_terminal_t::is_logic() const noexcept { return dynamic_cast<const logic_t *>(this) != nullptr; diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 4965e7b9746..14598d2dccf 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -124,8 +124,8 @@ namespace netlist { #if NL_KEEP_STATISTICS -using nperftime_t = plib::timer<plib::exact_ticks, true>; -using nperfcount_t = plib::counter<true>; +using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, true>; +using nperfcount_t = plib::chrono::counter<true>; #else using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, false>; using nperfcount_t = plib::chrono::counter<false>; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 274daba019c..06cef2a0947 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -18,6 +18,7 @@ #include "devices/net_lib.h" #include "devices/nld_truthtable.h" #include "devices/nlid_system.h" +#include "devices/nlid_proxy.h" #include "analog/nld_twoterm.h" #include "solver/nld_solver.h" @@ -191,42 +192,45 @@ pstring setup_t::objtype_as_str(detail::device_object_t &in) const return "Error"; } -void setup_t::register_and_set_param(pstring name, param_t ¶m) +pstring setup_t::get_initial_param_val(const pstring name, const pstring def) +{ + auto i = m_param_values.find(name); + if (i != m_param_values.end()) + return i->second; + else + return def; +} + +double setup_t::get_initial_param_val(const pstring name, const double def) { auto i = m_param_values.find(name); if (i != m_param_values.end()) { - const pstring val = i->second; - log().debug("Found parameter ... {1} : {1}\n", name, val); - switch (param.param_type()) - { - case param_t::DOUBLE: - { - double vald = 0; - if (sscanf(val.cstr(), "%lf", &vald) != 1) - log().fatal("Invalid number conversion {1} : {2}\n", name, val); - static_cast<param_double_t &>(param).initial(vald); - } - break; - case param_t::INTEGER: - case param_t::LOGIC: - { - double vald = 0; - if (sscanf(val.cstr(), "%lf", &vald) != 1) - log().fatal("Invalid number conversion {1} : {2}\n", name, val); - static_cast<param_int_t &>(param).initial(static_cast<int>(vald)); - } - break; - case param_t::STRING: - case param_t::MODEL: - { - static_cast<param_str_t &>(param).initial(val); - } - break; - //default: - // log().fatal("Parameter is not supported {1} : {2}\n", name, val); - } + double vald = 0; + if (sscanf(i->second.cstr(), "%lf", &vald) != 1) + log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); + return vald; } + else + return def; +} + +int setup_t::get_initial_param_val(const pstring name, const int def) +{ + auto i = m_param_values.find(name); + if (i != m_param_values.end()) + { + double vald = 0; + if (sscanf(i->second.cstr(), "%lf", &vald) != 1) + log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); + return static_cast<int>(vald); + } + else + return def; +} + +void setup_t::register_param(pstring name, param_t ¶m) +{ if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) log().fatal("Error adding parameter {1} to parameter list\n", name); } @@ -517,6 +521,7 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t & } else if (inp.is_logic()) { + netlist().log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), pstring(inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?"), term.name()); logic_input_t &incast = dynamic_cast<logic_input_t &>(inp); log().debug("connect_terminal_input: connecting proxy\n"); pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt); @@ -849,10 +854,11 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model) auto ret = plib::make_unique_base<logic_family_desc_t, logic_family_std_proxy_t>(); - ret->m_low_thresh_V = setup_t::model_value(map, "IVL"); - ret->m_high_thresh_V = setup_t::model_value(map, "IVH"); - ret->m_low_V = setup_t::model_value(map, "OVL"); - ret->m_high_V = setup_t::model_value(map, "OVH"); + ret->m_fixed_V = setup_t::model_value(map, "FV"); + ret->m_low_thresh_PCNT = setup_t::model_value(map, "IVL"); + ret->m_high_thresh_PCNT = setup_t::model_value(map, "IVH"); + ret->m_low_VO = setup_t::model_value(map, "OVL"); + ret->m_high_VO = setup_t::model_value(map, "OVH"); ret->m_R_low = setup_t::model_value(map, "ORL"); ret->m_R_high = setup_t::model_value(map, "ORH"); @@ -971,12 +977,28 @@ void setup_t::include(const pstring &netlist_name) { for (auto &source : m_sources) { - if (source->parse(*this, netlist_name)) + if (source->parse(netlist_name)) return; } log().fatal("unable to find {1} in source collection", netlist_name); } +std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring name) +{ + for (auto &source : m_sources) + { + if (source->type() == source_t::DATA) + { + auto strm = source->stream(name); + if (strm) + return strm; + } + } + log().fatal("unable to find data named {1} in source collection", name); + return std::unique_ptr<plib::pistream>(nullptr); +} + + bool setup_t::parse_stream(plib::pistream &istrm, const pstring &name) { plib::pomemstream ostrm; @@ -998,22 +1020,27 @@ void setup_t::register_define(pstring defstr) // base sources // ---------------------------------------------------------------------------------------- -bool source_string_t::parse(setup_t &setup, const pstring &name) +bool source_t::parse(const pstring &name) +{ + if (m_type != SOURCE) + return false; + else + return m_setup.parse_stream(*stream(name), name); +} + +std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name) { - plib::pimemstream istrm(m_str.cstr(), m_str.len()); - return setup.parse_stream(istrm, name); + return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len()); } -bool source_mem_t::parse(setup_t &setup, const pstring &name) +std::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name) { - plib::pimemstream istrm(m_str.cstr(), m_str.len()); - return setup.parse_stream(istrm, name); + return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len()); } -bool source_file_t::parse(setup_t &setup, const pstring &name) +std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name) { - plib::pifilestream istrm(m_filename); - return setup.parse_stream(istrm, name); + return plib::make_unique_base<plib::pistream, plib::pifilestream>(m_filename); } } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index aec2da2dcd8..e560a3b9f79 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -67,7 +67,7 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \ #define NETLIST_END() } #define LOCAL_SOURCE(name) \ - setup.register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>(# name, &NETLIST_NAME(name))); + setup.register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>(setup, # name, &NETLIST_NAME(name))); #define LOCAL_LIB_ENTRY(name) \ LOCAL_SOURCE(name) \ @@ -149,16 +149,28 @@ namespace netlist class source_t { public: + enum type_t + { + SOURCE, + DATA + }; + using list_t = std::vector<std::unique_ptr<source_t>>; - source_t() + source_t(setup_t &setup, const type_t type = SOURCE) + : m_setup(setup), m_type(type) {} virtual ~source_t() { } - virtual bool parse(setup_t &setup, const pstring &name) = 0; + virtual bool parse(const pstring &name); + virtual std::unique_ptr<plib::pistream> stream(const pstring &name) = 0; + setup_t &setup() { return m_setup; } + type_t type() const { return m_type; } private: + setup_t &m_setup; + const type_t m_type; }; // ---------------------------------------------------------------------------------------- @@ -181,7 +193,10 @@ namespace netlist pstring build_fqn(const pstring &obj_name) const; - void register_and_set_param(pstring name, param_t ¶m); + void register_param(pstring name, param_t ¶m); + pstring get_initial_param_val(const pstring name, const pstring def); + double get_initial_param_val(const pstring name, const double def); + int get_initial_param_val(const pstring name, const int def); void register_term(detail::core_terminal_t &obj); @@ -223,6 +238,7 @@ namespace netlist /* parse a source */ void include(const pstring &netlist_name); + std::unique_ptr<plib::pistream> get_data_stream(const pstring name); bool parse_stream(plib::pistream &istrm, const pstring &name); @@ -265,10 +281,12 @@ namespace netlist std::unordered_map<pstring, pstring> m_param_values; std::unordered_map<pstring, detail::core_terminal_t *> m_terminals; + /* needed by proxy */ + detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true); + private: detail::core_terminal_t *find_terminal(const pstring &outname_in, bool required = true); - detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true); void merge_nets(detail::net_t &thisnet, detail::net_t &othernet); @@ -307,12 +325,12 @@ namespace netlist { public: - source_string_t(const pstring &source) - : source_t(), m_str(source) + source_string_t(setup_t &setup, const pstring &source) + : source_t(setup), m_str(source) { } - bool parse(setup_t &setup, const pstring &name) override; + virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_str; @@ -322,12 +340,12 @@ namespace netlist { public: - source_file_t(const pstring &filename) - : source_t(), m_filename(filename) + source_file_t(setup_t &setup, const pstring &filename) + : source_t(setup), m_filename(filename) { } - bool parse(setup_t &setup, const pstring &name) override; + virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_filename; @@ -336,12 +354,12 @@ namespace netlist class source_mem_t : public source_t { public: - source_mem_t(const char *mem) - : source_t(), m_str(mem) + source_mem_t(setup_t &setup, const char *mem) + : source_t(setup), m_str(mem) { } - bool parse(setup_t &setup, const pstring &name) override; + virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override; private: pstring m_str; @@ -350,23 +368,29 @@ namespace netlist class source_proc_t : public source_t { public: - source_proc_t(pstring name, void (*setup_func)(setup_t &)) - : source_t(), + source_proc_t(setup_t &setup, pstring name, void (*setup_func)(setup_t &)) + : source_t(setup), m_setup_func(setup_func), m_setup_func_name(name) { } - bool parse(setup_t &setup, const pstring &name) override + virtual bool parse(const pstring &name) override { if (name == m_setup_func_name) { - m_setup_func(setup); + m_setup_func(setup()); return true; } else return false; } + + virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override + { + std::unique_ptr<plib::pistream> p(nullptr); + return p; + } private: void (*m_setup_func)(setup_t &); pstring m_setup_func_name; diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index b095a081f81..fbfa3a50c5c 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -30,6 +30,7 @@ public: opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static", "run|convert|listdevices|static"), 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_rfolders(*this, "r", "rom", "where to look for files"), 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"), @@ -53,6 +54,7 @@ public: plib::option_str_limit opt_cmd; plib::option_str opt_file; plib::option_vec opt_defines; + plib::option_vec opt_rfolders; plib::option_bool opt_verb; plib::option_bool opt_quiet; plib::option_bool opt_version; @@ -87,6 +89,36 @@ NETLIST_END() CORE IMPLEMENTATION ***************************************************************************/ +class netlist_data_folder_t : public netlist::source_t +{ +public: + netlist_data_folder_t(netlist::setup_t &setup, + pstring folder) + : netlist::source_t(setup, netlist::source_t::DATA) + , m_folder(folder) + { + } + + virtual std::unique_ptr<plib::pistream> stream(const pstring &file) override + { + pstring name = m_folder + "/" + file; + try + { + auto strm = plib::make_unique_base<plib::pistream, plib::pifilestream>(name); + return strm; + } + catch (plib::pexception e) + { + + } + return std::unique_ptr<plib::pistream>(nullptr); + } + +private: + pstring m_folder; +}; + + class netlist_tool_t : public netlist::netlist_t { public: @@ -109,15 +141,19 @@ public: void read_netlist(const pstring &filename, const pstring &name, const std::vector<pstring> &logs, - const std::vector<pstring> &defines) + const std::vector<pstring> &defines, + const std::vector<pstring> &roms) { // read the netlist ... for (auto & d : defines) m_setup->register_define(d); + for (auto & r : roms) + m_setup->register_source(plib::make_unique_base<netlist::source_t, netlist_data_folder_t>(*m_setup, r)); + m_setup->register_source(plib::make_unique_base<netlist::source_t, - netlist::source_file_t>(filename)); + netlist::source_file_t>(*m_setup, filename)); m_setup->include(name); log_setup(logs); @@ -189,8 +225,8 @@ struct input_t { switch (m_param->param_type()) { - case netlist::param_t::MODEL: case netlist::param_t::STRING: + case netlist::param_t::POINTER: throw netlist::nl_exception(plib::pfmt("param {1} is not numeric\n")(m_param->name())); case netlist::param_t::DOUBLE: static_cast<netlist::param_double_t*>(m_param)->setTo(m_value); @@ -246,7 +282,7 @@ static void run(tool_options_t &opts) nt.read_netlist(opts.opt_file(), opts.opt_name(), opts.opt_logs(), - opts.opt_defines()); + opts.opt_defines(), opts.opt_rfolders()); std::vector<input_t> inps = read_input(nt.setup(), opts.opt_inp()); @@ -289,7 +325,7 @@ static void static_compile(tool_options_t &opts) nt.read_netlist(opts.opt_file(), opts.opt_name(), opts.opt_logs(), - opts.opt_defines()); + opts.opt_defines(), opts.opt_rfolders()); nt.solver()->create_solver_code(pout_strm); @@ -313,7 +349,7 @@ static void listdevices(tool_options_t &opts) 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)); + netlist::source_proc_t>(nt.setup(), "dummy", &netlist_dummy)); nt.setup().include("dummy"); |