// license:CC0 // copyright-holders:Vas Crabb #include "netlist/devices/net_lib.h" #ifndef __PLIB_PREPROCESSOR__ #define NOISE(_name) \ NET_REGISTER_DEV(NOISE, _name) #endif /* Couriersud, 2013-05-26 * * Vas left the following commit comment: * It doesn't work quite right yet. The "Hammer" and "Pest" sounds * are generated by free-running 555/556 timers and gated with LM324 * applifiers. For whatever reason, the netlist system produces a kind of * buzzing from the "Hammer" circuit when it's supposed to be suppressed, * and it doesn't think the pest sound should be suppressed completely so * you can always hear it at a low level in the background. * * I modelled the LM324 sub-circuit using LTSpice and a National Semiconductor * spice model. * This model confirms that the two sounds are always audible. There is also a * quantitative explanation: The LM324 sub-circuit is an inverting amplifier with * Vout = max(Vx - V555, 0) * Vx is either 5V or ~1.4V, depending on the state of the 7404 output. This * causes max. amplitude to be 0 to 5 for Vx=5V or 1.4V for VX=1.4V. * * Further comments: * The "Cheese" circuit is a bit weird - either they're using the * base-emitter junction of a 2SC945 as a signal diode, or there's an error * in the schematic (collector is shown unconnected). * * This looks like a noise generating circuit. Amplification is ~100. The open * collector of the transistor will create the noise. Currently, there is no * support for noise in the resistor, diode or transistor models so currently * there is nothing to amplify currently. */ static NETLIST_START(cheekyms_schematics) // Shared chips TTL_7404_DIP(IC1) LM324_DIP(IC5) NET_C(IC1.14, IC5.4, I_V5.Q) NET_C(IC1.7, IC5.11, GND) // shut the netlist parser up about unconnected inputs NET_C(I_V5.Q, IC1.11, IC1.13) // Mute RES(R1, RES_K(10)) CAP(C10, CAP_U(10)) QBJT_EB(Q1, "2SC945") NET_C(IC1.2, R1.1) NET_C(R1.2, C10.1, Q1.B) NET_C(C10.2, Q1.E, GND) // Cheese #if 0 // RDUMMY will ensure the circuit does not become singular. RES(RDUMMY, RES_M(1000)) NET_C(RDUMMY.1, GND) NET_C(RDUMMY.2, Q2.C) QBJT_EB(Q2, "2SC945") #else // Use a simple noise generating macro device based on a current source // to simulate the noise across B-E NOISE(Q2) #endif RES(R2, RES_M(1)) RES(R3, RES_K(1)) RES(R4, RES_K(100)) RES(R5, RES_K(1)) RES(R6, RES_K(100)) RES(R7, RES_K(1)) RES(R8, RES_M(1)) RES(R9, RES_K(10)) RES(R10, RES_K(10)) RES(R11, RES_K(10)) RES(R12, RES_K(100)) CAP(C8, CAP_U(0.1)) CAP(C9, CAP_U(0.1)) CAP(C11, CAP_U(0.1)) NET_C(R2.1, I_VPLUS.Q) NET_C(R2.2, C8.1, Q2.E) NET_C(R3.1, C8.2) NET_C(R3.2, R4.1, IC5.10) NET_C(R5.2, R6.1, IC5.9) NET_C(R6.2, C9.1, IC5.8) NET_C(R7.1, C9.2) NET_C(R7.2, R8.1, IC5.13) NET_C(R8.2, C11.1, IC5.14) NET_C(R10.2, IC1.4) NET_C(R9.1, R10.1, IC5.12) NET_C(R9.2, I_V5.Q) NET_C(R11.1, R12.1, C11.2) NET_C(R4.2, R5.1, R11.2, Q2.B, GND) // Music RES(R13, RES_K(100)) // Mouse RES(R14, RES_K(4.7)) RES(R15, RES_K(1)) RES(R16, RES_K(68)) RES(R17, RES_K(100)) CAP(C12, CAP_U(0.01)) CAP(C13, CAP_U(10)) DIODE(D4, "1S1588") NE555(IC4_1) // one half of a 556 (other half does coin & extra) NET_C(D4.K, R14.1, IC4_1.RESET) NET_C(D4.A, R14.2, C13.1, IC4_1.CONT) NET_C(R15.1, IC4_1.VCC, I_V5.Q) NET_C(R15.2, R16.1, IC4_1.DISCH) NET_C(R16.2, C12.1, IC4_1.TRIG, IC4_1.THRESH) NET_C(C13.2, C12.2, IC4_1.GND, GND) NET_C(R17.1, IC4_1.OUT) // Hammer RES(R18, RES_K(1)) RES(R19, RES_K(150)) RES(R20, RES_K(10)) RES(R21, RES_K(100)) RES(R22, RES_K(100)) RES(R23, RES_M(1)) RES(R24, RES_K(51)) CAP(C14, CAP_U(0.01)) CAP(C15, CAP_U(0.01)) CAP(C16, CAP_U(0.1)) DIODE(D5, "1S1588") DIODE(D6, "1S1588") NE555(IC6_1) // one half of a 556 (other half does pest) NET_C(R18.1, R23.1, IC6_1.RESET, IC6_1.VCC, I_V5.Q) NET_C(R18.2, R19.1, IC6_1.DISCH) NET_C(R19.2, C14.1, IC6_1.TRIG, IC6_1.THRESH) NET_C(R20.1, IC6_1.OUT) NET_C(R20.2, R21.1, C15.1) NET_C(R21.2, R22.1, IC5.6) NET_C(R22.2, R24.1, IC5.7) NET_C(D5.K, IC1.6) NET_C(D5.A, D6.K) NET_C(R23.2, C16.1, D6.A, IC5.5) NET_C(C14.2, C15.2, C16.2, IC6_1.GND, GND) // Pest RES(R25, RES_K(20)) RES(R26, RES_K(10)) RES(R27, 220) RES(R28, RES_K(100)) RES(R29, RES_K(4.7)) RES(R30, RES_K(1)) RES(R31, RES_K(68)) RES(R32, RES_K(100)) RES(R33, RES_K(100)) RES(R34, RES_K(51)) RES(R35, RES_M(1)) CAP(C17, CAP_U(2.2)) CAP(C18, CAP_U(10)) CAP(C19, CAP_U(0.01)) CAP(C20, CAP_U(0.22)) DIODE(D7, "1S1588") DIODE(D8, "1S1588") DIODE(D9, "1S1588") NE555(IC3) NE555(IC6_2) // one half of a 556 (other half does hammer) NET_C(R25.1, R29.1, R30.1, R35.2, IC3.RESET, IC3.VCC, IC6_2.RESET, IC6_2.VCC, I_V5.Q) NET_C(R25.2, R26.1, IC3.DISCH) NET_C(R26.2, C17.1, IC3.TRIG, IC3.THRESH) NET_C(R27.1, R28.1, IC3.OUT) NET_C(R27.2, D7.K) NET_C(R28.2, R29.2, C18.1, D7.A, IC6_2.CONT) NET_C(R30.2, R31.1, IC6_2.DISCH) NET_C(R31.2, C19.1, IC6_2.TRIG, IC6_2.THRESH) NET_C(R32.1, IC6_2.OUT) NET_C(R32.2, R33.1, IC5.2) NET_C(R33.2, R34.1, IC5.1) NET_C(D8.K, IC1.8) NET_C(D8.A, D9.K) NET_C(R35.1, C20.1, D9.A, IC5.3) NET_C(C17.2, C18.2, C19.2, C20.2, IC3.GND, IC6_2.GND, GND) // Mouse dies RES(R36, RES_K(1)) RES(R37, RES_K(33)) RES(R38, 560) RES(R39, RES_K(100)) CAP(C21, CAP_U(0.01)) CAP(C22, CAP_U(47)) NE555(IC2_2) // one half of a 556 (other half does pest dies) NET_C(R38.1, IC2_2.RESET) NET_C(R38.2, C22.1, IC2_2.CONT) NET_C(R36.1, IC2_2.VCC, I_V5.Q) NET_C(R36.2, R37.1, IC2_2.DISCH) NET_C(R37.2, C21.1, IC2_2.TRIG, IC2_2.THRESH) NET_C(C22.2, C21.2, IC2_2.GND, GND) NET_C(R39.1, IC2_2.OUT) // Pest dies RES(R40, RES_K(1)) RES(R41, RES_K(47)) RES(R42, RES_K(100)) CAP(C23, CAP_U(0.033)) NE555(IC2_1) // one half of a 556 (other half does mouse dies) NET_C(R40.1, IC2_1.VCC, I_V5.Q) NET_C(R40.2, R41.1, IC2_1.DISCH) NET_C(R41.2, C23.1, IC2_1.TRIG, IC2_1.THRESH) NET_C(C23.2, IC2_1.GND, GND) NET_C(R42.1, IC2_1.OUT) // Coin & extra RES(R44, RES_K(1)) RES(R45, RES_K(47)) RES(R46, RES_K(100)) CAP(C24, CAP_U(0.01)) NE555(IC4_2) // one half of a 556 (other half does mouse) NET_C(R44.1, IC4_2.VCC, I_V5.Q) NET_C(R44.2, R45.1, IC4_2.DISCH) NET_C(R45.2, C24.1, IC4_2.TRIG, IC4_2.THRESH) NET_C(C24.2, IC4_2.GND, GND) NET_C(R46.1, IC4_2.OUT) // Mixdown RES(R43, RES_K(10)) POT(VR1, RES_K(1)) NET_C(R12.2, R13.2, R17.2, R24.2, R34.2, R39.2, R42.2, R43.1, Q1.C) NET_C(R46.2, R43.2, VR1.1) NET_C(VR1.3, GND) NETLIST_END() /* simple noise generator to replace BJT E-B one * */ static NETLIST_START(NOISE) CS(FC, 0) PARAM(FC.FUNC, "0.0000001 * rand()") ALIAS(E, FC.P) ALIAS(B, FC.N) NETLIST_END() NETLIST_START(cheekyms) SOLVER(Solver, 48000) PARAM(Solver.ACCURACY, 1e-10) PARAM(Solver.NR_LOOPS, 300) PARAM(Solver.METHOD, "MAT_CR") PARAM(Solver.PARALLEL, 0) PARAM(Solver.DYNAMIC_TS, 0) PARAM(Solver.DYNAMIC_LTE, 5e-4) PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 20e-6) LOCAL_LIB_ENTRY(NOISE) LOCAL_SOURCE(cheekyms_schematics) ANALOG_INPUT(I_V5, 5) ANALOG_INPUT(I_VPLUS, 12.9) // very approximate - 15V dropped by three diodes and filtered INCLUDE(cheekyms_schematics) LOGIC_INPUT(I_MUTE, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_CHEESE, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_MUSIC, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_MOUSE, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_HAMMER, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_PEST, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_MOUSE_DIES, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_PEST_DIES, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) LOGIC_INPUT(I_COIN_EXTRA, 1, "74XX") // FIXME: need 74LS family model (half the sink capability) NET_C(I_MUTE.Q, IC1.1) NET_C(I_CHEESE.Q, IC1.3) NET_C(I_MUSIC.Q, R13.1) NET_C(I_MOUSE.Q, IC4_1.RESET) NET_C(I_HAMMER.Q, IC1.5) NET_C(I_PEST.Q, IC1.9) NET_C(I_MOUSE_DIES.Q, IC2_2.RESET) NET_C(I_PEST_DIES.Q, IC2_1.RESET) NET_C(I_COIN_EXTRA.Q, IC4_2.RESET) NET_C(I_V5, I_MUTE.VCC, I_CHEESE.VCC, I_MUSIC.VCC, I_MOUSE.VCC, I_HAMMER.VCC, I_PEST.VCC, I_MOUSE_DIES.VCC, I_PEST_DIES.VCC, I_COIN_EXTRA.VCC) NET_C(GND, I_MUTE.GND, I_CHEESE.GND, I_MUSIC.GND, I_MOUSE.GND, I_HAMMER.GND, I_PEST.GND, I_MOUSE_DIES.GND, I_PEST_DIES.GND, I_COIN_EXTRA.GND) NETLIST_END()