// license:CC0 // copyright-holders:Aaron Giles,Couriersud #ifndef MAME_AUDIO_NL_CINEMAT_COMMON_H #define MAME_AUDIO_NL_CINEMAT_COMMON_H // // Misc common devices used by Cinematronics games. // // Eventually these should be included in the core. // // Known problems/issues: // // * There are 5 different models of the CA3080 presented here. // More analysis on the pros/cons of each should be done. // // * The TL182 analog switch is cobbled together from a pair of // CD4066 gates and a pair of inverters on the inputs. This // seems to work but perhaps should be properly added as a // system model. // // * The 2N6426 Darlington transistors are not properly emulated. // Currently they are modeled as a pair of 2N3904s. A pspice // model ported into the netlist schema creates a very poor // balance with the background noise in Space Wars/Barrier. // #include "netlist/devices/net_lib.h" // // Direct mappings // // AMI S2688 is compatible with MM5837 #define AMI_S2688 MM5837_DIP // LM555/566 is compatible with NE555/566 #define LM555_DIP NE555_DIP #define LM566_DIP NE566_DIP // alias LS devices to real devices #define TTL_74LS00_DIP TTL_7400_DIP #define TTL_74LS02_DIP TTL_7402_DIP // Quad 2-input Nor Gate #define TTL_74S04_DIP TTL_7404_DIP // Hex Inverting Gates #define TTL_74LS04_DIP TTL_7404_DIP // Hex Inverting Gates #define TTL_74LS08_DIP TTL_7408_DIP // Quad 2-Input AND Gates #define TTL_74LS21_DIP TTL_7421_DIP // Dual 4-Input AND Gates #define TTL_74LS74_DIP TTL_7474_DIP // Dual D Flip Flop #define TTL_74LS75_DIP TTL_7475_DIP // 4-Bit Bistable Latches with Complementary Outputs #define TTL_74LS86_DIP TTL_7486_DIP // Quad 2-Input Exclusive-OR Gates #define TTL_74LS107_DIP TTL_74107_DIP #define TTL_74S113_DIP TTL_74113_DIP #define TTL_74S113A_DIP TTL_74113A_DIP #define TTL_74LS123_DIP TTL_74123_DIP #define TTL_74LS125_DIP TTL_74125_DIP #define TTL_74LS157_DIP TTL_74157_DIP #define TTL_74LS163_DIP TTL_74163_DIP #define TTL_74LS164_DIP TTL_74164_DIP #define TTL_74LS191_DIP TTL_74191_DIP #define TTL_74LS259_DIP TTL_9334_DIP // Seems to be pin-compatible #define TTL_74LS377_DIP TTL_74377_DIP #define TTL_74LS393_DIP TTL_74393_DIP // // Diode models // #define D_1N914(name) DIODE(name, "1N914") #define D_1N914B(name) DIODE(name, "1N914") #define D_1N5236B(name) ZDIODE(name, "1N5236B") #define D_1N5240(name) ZDIODE(name, "1N5240") #define D_1N5240B(name) ZDIODE(name, "1N5240B") // // Transistor models // #define Q_2N3904(name) QBJT_EB(name, "2N3904") #define Q_2N3906(name) QBJT_EB(name, "2N3906") #define Q_2N6107(name) QBJT_EB(name, "2N6107") #define Q_2N6292(name) QBJT_EB(name, "2N6292") #define Q_2N5210(name) QBJT_EB(name, "2N5210") // // 556 is just two 555s in one package // #define NE556_DIP(name) SUBMODEL(_NE556_DIP, name) #define LM556_DIP NE556_DIP static NETLIST_START(_NE556_DIP) NE555(A) NE555(B) NET_C(A.GND, B.GND) NET_C(A.VCC, B.VCC) DIPPINS( /* +--------------+ */ A.DISCH, /* 1DISCH |1 ++ 14| VCC */ A.VCC, A.THRESH, /* 1THRES |2 13| 2DISCH */ B.DISCH, A.CONT, /* 1CONT |3 12| 2THRES */ B.THRESH, A.RESET, /* 1RESET |4 NE556 11| 2CONT */ B.CONT, A.OUT, /* 1OUT |5 10| 2RESET */ B.RESET, A.TRIG, /* 1TRIG |6 9| 2OUT */ B.OUT, A.GND, /* GND |7 8| 2TRIG */ B.TRIG /* +--------------+ */ ) NETLIST_END() // // TL182 analog switch // #define TL182_DIP(name) SUBMODEL(_TL182_DIP, name) static NETLIST_START(_TL182_DIP) CD4066_GATE(A) CD4066_GATE(B) NET_C(A.VDD, B.VDD) NET_C(A.VSS, B.VSS) PARAM(A.BASER, 270.0) PARAM(B.BASER, 270.0) RES(VR, 100) NC_PIN(NC) TTL_7406_GATE(AINV) TTL_7406_GATE(BINV) NET_C(AINV.VCC, BINV.VCC, A.VDD) NET_C(AINV.GND, BINV.GND, A.VSS) NET_C(AINV.Y, A.CTL) NET_C(BINV.Y, B.CTL) DIPPINS( /* +--------------+ */ A.R.1, /* 1S |1 ++ 14| 2S */ B.R.1, A.R.2, /* 1D |2 13| 2D */ B.R.2, NC.I, /* NC |3 12| NC */ NC.I, NC.I, /* NC |4 TL182 11| NC */ NC.I, AINV.A, /* 1A |5 10| 2A */ BINV.A, VR.1, /* VCC |6 9| VEE */ VR.2, A.VDD, /* VLL |7 8| VREF */ A.VSS /* +--------------+ */ ) NETLIST_END() // // 2N6426, Darlington transistor // #define Q_2N6426(name) SUBMODEL(_Q_2N6426, name) #if 0 // // This model causes the background noise level to domainate all other sounds in spacewar? // // Model dervied from https://www.onsemi.com/support/design-resources/models?rpn=2N6284 static NETLIST_START(_Q_2N6426) QBJT_EB(Q1, "NPN(IS=1.73583e-11 BF=831.056 NF=1.05532 VAF=957.147 IKF=0.101183 ISE=1.65383e-10 NE=1.59909 BR=2.763 NR=1.03428 VAR=4.18534 IKR=0.0674174 ISC=1.00007e-13 NC=2.00765 RB=22.2759 IRB=0.208089 RBM=22.2759 RE=0.0002 RC=0.001 XTB=2.12676 XTI=1.82449 EG=1.05 CJE=2.62709e-10 VJE=0.95 MJE=0.23 TF=1e-09 XTF=1 VTF=10 ITF=0.01 CJC=3.59851e-10 VJC=0.845279 MJC=0.23 XCJC=0.9 FC=0.5 TR=1e-07 PTF=0 KF=0 AF=1)") QBJT_EB(Q2, "NPN(IS=1.73583e-11 BF=831.056 NF=1.05532 VAF=957.147 IKF=0.101183 ISE=1.65383e-10 NE=1.59909 BR=2.763 NR=1.03428 VAR=4.18534 IKR=0.0674174 ISC=1.00007e-13 NC=2.00765 RB=22.2759 IRB=0.208089 RBM=22.2759 RE=0.0002 RC=0.001 XTB=2.12676 XTI=1.82449 EG=1.05 CJE=2.62709e-10 VJE=0.95 MJE=0.23 TF=1e-09 XTF=1 VTF=10 ITF=0.01 CJC=0 VJC=0.845279 MJC=0.23 XCJC=0.9 FC=0.5 TR=1e-07 PTF=0 KF=0 AF=1)") // NPN DIODE(D1, "D(IS=1e-12 RS=10.8089 N=1.00809 XTI=3.00809 CJO=0 VJ=0.75 M=0.33 FC=0.5)") RES(R1, RES_K(8)) RES(R2, 50) ALIAS(B, Q1.B) ALIAS(C, Q1.C) ALIAS(E, Q2.E) NET_C(Q1.C, Q2.C, D1.K) NET_C(Q1.B, R1.1) NET_C(Q2.E, D1.A, R2.2) NET_C(Q1.E, Q2.B, R1.2, R2.1) NETLIST_END() #else // super brain-dead model I threw together from a pair of 2N3904 static NETLIST_START(_Q_2N6426) QBJT_EB(Q1, "NPN") QBJT_EB(Q2, "NPN") ALIAS(B, Q1.B) ALIAS(C, Q1.C) ALIAS(E, Q2.E) NET_C(Q1.C, Q2.C) NET_C(Q1.E, Q2.B) NETLIST_END() #endif // // LM3900, quad op-amp // #define LM3900_DIP(name) SUBMODEL(_LM3900_DIP, name) static NETLIST_START(_LM3900_DIP) LM3900(A) LM3900(B) LM3900(C) LM3900(D) NET_C(A.VCC, B.VCC, C.VCC, D.VCC) NET_C(A.GND, B.GND, C.GND, D.GND) DIPPINS( /* +--------------+ */ A.PLUS, /* 1IN+ |1 ++ 14| VCC */ A.VCC, B.PLUS, /* 2IN+ |2 13| 3IN+ */ C.PLUS, B.MINUS, /* 2IN- |3 12| 4IN+ */ D.PLUS, B.OUT, /* 2OUT |4 LM3900 11| 4IN- */ D.MINUS, A.OUT, /* 1OUT |5 10| 4OUT */ D.OUT, A.MINUS, /* 1IN- |6 9| 3OUT */ C.OUT, A.GND, /* GND |7 8| 3IN- */ C.MINUS /* +--------------+ */ ) NETLIST_END() // ************************************************* // EQUIVALENT SUBSTITUTE FOR CA3080 IS NTE996 // (SAME 8-PIN DIP PINOUT) // ************************************************* // // CA3080 OPERATIONAL TRANSCONDUCTANCE AMPLIFIER // // SPICE (SIMULATION PROGRAM WITH INTEGRATED CIRCUIT EMPHASIS) // SUBCIRCUIT // // CONNECTIONS: // INVERTING INPUT // | NON-INVERTING INPUT // | | NEGATIVE POWER SUPPLY // | | | I BIAS // | | | | OUTPUT // | | | | | POSITIVE POWER SUPPLY // | | | | | | //.SUBCKT CA3080 2 3 4 5 6 7 // // DIP mappings use the submodels below for CA3080 // #define CA3080_FAST_DIP(name) SUBMODEL(_CA3080_FAST_DIP, name) #define CA3080_SLOW_DIP(name) SUBMODEL(_CA3080_SLOW_DIP, name) // // Default to the fast model unless otherwise directed // #ifndef CA3080_DIP #define CA3080_DIP CA3080_FAST_DIP #endif // // Fast model: works well for most cases in Cinematronics games, // except when used in a network with multiple CA3080's, due to // the presence of an AFUNC. // static NETLIST_START(_CA3080_FAST_DIP) ALIAS(2, F.A0) // - ALIAS(3, F.A1) // + ALIAS(4, F.A2) // V- ALIAS(5, RIABC.1) // IB ALIAS(6, VO.OP) // FIXME ALIAS(7, F.A4) // V+ RES(RI, 26000) NET_C(RI.1, F.A0) NET_C(RI.2, F.A1) // Delivers I0 AFUNC(F, 5, "max(-0.5e-3, min(0.5e-3, 19.2 * (A3 - A2) * A0))") RES(RIABC, 1) NET_C(RIABC.2, F.A2) NET_C(RIABC.1, F.A3) // IB VCCS(VO, 1) ANALOG_INPUT(XGND, 0) NET_C(XGND, VO.IN, VO.ON) // FIXME: assume symmetric supply NET_C(F.Q, VO.IP) NETLIST_END() // // Slow model: derived from // https://github.com/xxv/gedasymbols/blob/master/www/user/john_doty/models/opamp/ca3080.mod // // This seems to produce reasonable results as a slow drop-in // replacement for the fast model above in solarq, but is quite // slow. One advantage is that it works in a network with multiple // CA3080's. // static NETLIST_START(_CA3080_SLOW_DIP) // // These items are common to several models // #define CA3080_D(name) DIODE(name, "D(IS=2p RS=5 BV=40 CJO=3p TT=6n)") #define CA3080_NPN(name) QBJT_EB(name, "NPN(IS=21.48f XTI=3 EG=1.11 VAF=80 BF=550 ISE=50f NE=1.5 IKF=10m XTB=1.5 BR=.1 ISC=10f NC=2 IKR=3m RC=10 CJC=800f MJC=.3333 VJC=.75 FC=.5 CJE=1.3p MJE=.3333 VJE=.75 TR=30n TF=400P ITF=30m XTF=1 VTF=10 CJS=5.8P MJS=.3333 VJS=.75)") #define CA3080_PNP(name) QBJT_EB(name, "PNP(IS=50f XTI=3 EG=1.11 VAF=80 BF=100 ISE=130f NE=1.5 IKF=1m XTB=1.5 BR=1 ISC=0 NC=2 IKR=0 RC=0 CJC=4p MJC=.3333 VJC=.75 FC=.5 CJE=1.4p MJE=.3333 VJE=.75 TR=500n TF=23n ITF=.1 XTF=1 VTF=10 CJS=5.5P MJS=.3333 VJS=.75)") CA3080_D(D1) CA3080_D(D2) CA3080_NPN(Q1) CA3080_PNP(Q2) CA3080_PNP(Q3) CA3080_NPN(Q4) CA3080_NPN(Q5) CA3080_PNP(Q6) CA3080_PNP(Q7) CA3080_PNP(Q8) CA3080_PNP(Q9) CA3080_NPN(Q10) CA3080_NPN(Q11) CA3080_NPN(Q12) CA3080_NPN(Q13) CA3080_PNP(Q14) CA3080_PNP(Q15) ALIAS(2, Q10.B) // N1 ALIAS(3, Q5.B) // N28 ALIAS(4, Q1.E) // N13 ALIAS(5, Q1.B) // N11 ALIAS(6, Q6.C) // N30 ALIAS(7, Q8.E) // N8 NET_C(Q8.E, Q9.E, Q14.E, Q15.E) // N8 NET_C(Q1.B, Q1.C, Q4.B) // N11 NET_C(Q1.E, Q4.E, Q11.E, Q12.E) // N13 NET_C(Q6.C, Q7.C, Q13.C) // N30 NET_C(Q3.B, Q10.C, Q14.C, D1.A) // N1N13 NET_C(Q2.E, Q14.B, Q15.C, Q15.B) // N1N15 NET_C(Q2.B, Q3.E, D1.K) // N1N17 NET_C(Q2.C, Q3.C, Q11.C, Q13.B) // N1N22 NET_C(Q5.C, Q6.B, Q9.C, D2.A) // N1N32 NET_C(Q6.E, Q7.B, D2.K) // N1N34 NET_C(Q7.E, Q8.C, Q8.B, Q9.B) // N1N36 NET_C(Q4.C, Q5.E, Q10.E) // N1N52 NET_C(Q11.B, Q12.C, Q12.B, Q13.E) // N1N44 NETLIST_END() // // List of local models to include to make MAME happy // #define CINEMAT_LOCAL_MODELS \ LOCAL_SOURCE(_NE556_DIP) \ LOCAL_SOURCE(_TL182_DIP) \ LOCAL_SOURCE(_Q_2N6426) \ LOCAL_SOURCE(_LM3900_DIP) \ LOCAL_SOURCE(_CA3080_FAST_DIP) \ LOCAL_SOURCE(_CA3080_SLOW_DIP) \ #endif // MAME_AUDIO_NL_CINEMAT_COMMON_H