summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/sound/discrete.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/sound/discrete.h')
-rw-r--r--trunk/src/emu/sound/discrete.h4746
1 files changed, 4746 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/discrete.h b/trunk/src/emu/sound/discrete.h
new file mode 100644
index 00000000000..7df8b90ce68
--- /dev/null
+++ b/trunk/src/emu/sound/discrete.h
@@ -0,0 +1,4746 @@
+#pragma once
+
+#ifndef __DISCRETE_H__
+#define __DISCRETE_H__
+
+#include "machine/rescap.h"
+
+/***********************************************************************
+ *
+ * MAME - Discrete sound system emulation library
+ *
+ * Written by Keith Wilkins (mame@esplexo.co.uk)
+ *
+ * (c) K.Wilkins 2000
+ *
+ * Coding started in November 2000
+ *
+ * Additions/bugfix February 2003 - D.Renaud, F.Palazzolo, K.Wilkins
+ * Discrete parallel tasks 2009 - Couriersud
+ *
+ ***********************************************************************
+ *
+ * For free text books on electronic theory check out:
+ * http://www.ibiblio.org/obp/electricCircuits/
+ * For a free circuit simulator:
+ * http://qucs.sourceforge.net/index.html
+ * For a free waveform editor to view DISCRETE_WAVLOG dumps:
+ * http://audacity.sourceforge.net/
+ * http://www.sonicvisualiser.org/
+ *
+ ***********************************************************************
+ *
+ * Currently only one instance of a discrete sound system is supported.
+ * If more then one instance is required in the future, then a chip #
+ * will have to be added to the read/writes and the discrete inputs
+ * modified to match. This functionality should never be needed.
+ * There is no real need to run more then 1 discrete system.
+ *
+ * If a clock is specified in the machine driver setup, then this is
+ * used for the simulation sample rate. Otherwise it will default to
+ * run at the audio sample rate.
+ *
+ * Unused/Unconnected input nodes should be set to NODE_NC (No Connect)
+ *
+ * Each node can have many inputs from either constants or other
+ * nodes within the system.
+ *
+ * It should be remembered that the discrete sound system emulation
+ * does not do individual device emulation, but instead does a function
+ * emulation. So you will need to convert the schematic design into
+ * a logic block representation.
+ *
+ * There is the possibility to support multiple outputs per module.
+ * In this case, NODE_XXX is the default output. Alternative outputs may
+ * be accessed by using NODE_XXX_YY where 00<=Y<08.
+ *
+ * You may also access nodes with a macros:
+ *
+ * NODE_XXX = NODE_SUB(NODE_XXX, 0)
+ * NODE_XXX = NODE_XXX_00
+ * NODE_XXX = NODE(XXX)
+ * NODE_XXX_YY = NODE_SUB(NODE_XXX, YY)
+ *
+ * One node point may feed a number of inputs, for example you could
+ * connect the output of a DISCRETE_SINEWAVE to the AMPLITUDE input
+ * of another DISCRETE_SINEWAVE to amplitude modulate its output and
+ * also connect it to the frequency input of another to frequency
+ * modulate its output, the combinations are endless....
+ *
+ * Consider the circuit below:
+ *
+ * .--------. .----------. .-------.
+ * | | | | | |
+ * | SQUARE | Enable| SINEWAVE | | |
+ * | WAVE |-+---------->| 2000Hz |---------------->| |
+ * | | | | | | ADDER |-->OUT
+ * | NODE11 | | | NODE12 | | |
+ * '--------' | '----------' .->| |
+ * | | |NODE20 |
+ * | .------. .---------. | '-------'
+ * | |Logic | | | | ^
+ * | | INV | Enable | SINEWVE | | |
+ * '->| ERT |------------->| 4000Hz |--' .-------.
+ * | | | | | |
+ * |NODE13| | NODE14 | | INPUT |
+ * '------' '---------' | |
+ * |NODE01 |
+ * '-------'
+ *
+ * This should give you an alternating two tone sound switching
+ * between the 2000Hz and 4000Hz sine waves at the frequency of the
+ * square wave, with the memory mapped enable signal mapped onto NODE07
+ * so discrete_sound_w(NODE_01,1) will enable the sound, and
+ * discrete_sound_w(NODE_01,0) will disable the sound.
+ *
+ * DISCRETE_SOUND_START(test_interface)
+ * DISCRETE_INPUT_LOGIC(NODE_01)
+ * DISCRETE_SQUAREWFIX(NODE_11, 1, 0.5, 1, 50, 1.0/2, 0) // Output 0:1
+ * DISCRETE_SINEWAVE(NODE_12, NODE_11, 2000, 10000, 0, 0)
+ * DISCRETE_LOGIC_INVERT(NODE_13, NODE_11)
+ * DISCRETE_SINEWAVE(NODE_14, NODE_13, 4000, 10000, 0, 0)
+ * DISCRETE_ADDER2(NODE_20, NODE_01, NODE_12, NODE_14)
+ * DISCRETE_OUTPUT(NODE_20, 1)
+ * DISCRETE_SOUND_END
+ *
+ * To aid simulation speed it is preferable to use the enable/disable
+ * inputs to a block rather than setting the output amplitude to zero
+ *
+ * Feedback loops are allowed BUT they will always feedback one time
+ * step later, the loop over the netlist is only performed once per
+ * deltaT so feedback occurs in the next deltaT step. This is not
+ * the perfect solution but saves repeatedly traversing the netlist
+ * until all nodes have settled.
+ *
+ * The best way to work out your system is generally to use a pen and
+ * paper to draw a logical block diagram like the one above, it helps
+ * to understand the system ,map the inputs and outputs and to work
+ * out your node numbering scheme.
+ *
+ * Node numbers NODE_01 to NODE_299 are defined at present.
+ *
+ * It is recommended to put all Inputs at the start of the interface.
+ * That way they are updated first.
+ *
+ * Each sound effects final node should come after all nodes that
+ * create it. The final mixing of all sound effects should come
+ * at the end of the interface.
+ *
+ ***********************************************************************
+ *
+ * x_time - ANTI-ALIASING features.
+ *
+ * Certain modules make use of x_time. This is a feature that passes
+ * information between modules about how long in the current sample, the
+ * switch in state happened. This is a decimal value of the % of the
+ * full sample period that it has been in the new state.
+ * 0 means it has been at the same state the whole sample.
+ *
+ * Example: Here is the output of a clock source with x_time on the
+ * output. The square wave is the real world waveform we
+ * want. The ^'s are the sample point. The numbers under
+ * the ^'s are the node output with the logic state left of
+ * the decimal and the x_time to the right. Under that is
+ * what the node's anti-aliased output energy would be.
+ * Note: the example is not 4x sampling so the energy
+ * does not provide an accurate representation of the
+ * original waveform. This is intentional so it fits
+ * in this header file.
+ * 1 ____ ____ ____ ____ ____ ____ ____ ____
+ * 0 ___ ____ ____ ____ ____ ____ ____ ____ __
+ * ^....^....^....^....^....^....^....^....^....^....^....^....^
+ * x_time 0.2 1.4 0.6 1.8 1.2 0.4 1.6 0.8 0.2 1.4 0.6
+ * energy 0.8 0.4 0.4 0.8 0.2 0.6 0.6 0.2 0.8 0.4 0.4
+ *
+ * Some modules will just pass the x_time onto another module.
+ *
+ * Modules that process x_time will keep track of the node's previous
+ * state so they can calculate the actual energy at the sample time.
+ *
+ * Example: Say we have a 555 module that outputs a clock with x_time
+ * that is connected to a counter. The output of the counter
+ * is connected to DAC_R1.
+ * In this case the counter module continues counting dependant
+ * on the integer portion of the 555 output. But it also
+ * passes the decimal portion as the x_time.
+ * The DAC_R1 then uses this info to anti-alias its output.
+ * Consider the following counter outputs vs DAC_R1
+ * calculations. The count changes from 9 to 10. It has
+ * been at the new state for 75% of the sample.
+ *
+ * counter binary x_time -- DAC_R1 bit energy --
+ * out count D3 D2 D1 D0
+ * 9.0 1001 0.0 1.0 0.0 0.0 1.0
+ * 10.75 1010 0.75 1.0 0.0 0.75 0.25
+ * 10.0 1010 0.0 1.0 0.0 1.0 0.0
+ *
+ * The DAC_R1 uses these energy calculations to scale the
+ * voltages created on each of its resistors. This
+ * anti-aliases the waveform no mater what the resistor
+ * weighting is.
+ *
+ ***********************************************************************
+ *
+ * LIST OF CURRENTLY IMPLEMENTED DISCRETE BLOCKS
+ * ---------------------------------------------
+ *
+ * DISCRETE_SOUND_START(STRUCTURENAME)
+ * DISCRETE_SOUND_END
+ *
+ * DISCRETE_ADJUSTMENT(NODE,MIN,MAX,LOGLIN,TAG)
+ * DISCRETE_ADJUSTMENTX(NODE,MIN,MAX,LOGLIN,TAG,PMIN,PMAX)
+ * DISCRETE_CONSTANT(NODE,CONST0)
+ * DISCRETE_INPUT_DATA(NODE)
+ * DISCRETE_INPUTX_DATA(NODE,GAIN,OFFSET,INIT)
+ * DISCRETE_INPUT_LOGIC(NODE)
+ * DISCRETE_INPUTX_LOGIC(NODE,GAIN,OFFSET,INIT)
+ * DISCRETE_INPUT_NOT(NODE)
+ * DISCRETE_INPUTX_NOT(NODE,GAIN,OFFSET,INIT)
+ * DISCRETE_INPUT_PULSE(NODE,INIT)
+ * DISCRETE_INPUT_STREAM(NODE, NUM)
+ * DISCRETE_INPUTX_STREAM(NODE,NUM, GAIN,OFFSET)
+ *
+ * DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MIN,MAX,DIR,INIT0,CLKTYPE)
+ * DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK,CLKTYPE)
+ * DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB)
+ * DISCRETE_NOISE(NODE,ENAB,FREQ,AMP,BIAS)
+ * DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE)
+ * DISCRETE_SAWTOOTHWAVE(NODE,ENAB,FREQ,AMP,BIAS,GRADIENT,PHASE)
+ * DISCRETE_SINEWAVE(NODE,ENAB,FREQ,AMP,BIAS,PHASE)
+ * DISCRETE_SQUAREWAVE(NODE,ENAB,FREQ,AMP,DUTY,BIAS,PHASE)
+ * DISCRETE_SQUAREWFIX(NODE,ENAB,FREQ,AMP,DUTY,BIAS,PHASE)
+ * DISCRETE_SQUAREWAVE2(NODE,ENAB,AMPL,T_OFF,T_ON,BIAS,TSHIFT)
+ * DISCRETE_TRIANGLEWAVE(NODE,ENAB,FREQ,AMP,BIAS,PHASE)
+ *
+ * DISCRETE_INVERTER_OSC(NODE,ENAB,MOD,RCHARGE,RP,C,R2,INFO)
+ * DISCRETE_OP_AMP_OSCILLATOR(NODE,ENAB,INFO)
+ * DISCRETE_OP_AMP_VCO1(NODE,ENAB,VMOD1,INFO)
+ * DISCRETE_OP_AMP_VCO2(NODE,ENAB,VMOD1,VMOD2,INFO)
+ * DISCRETE_SCHMITT_OSCILLATOR(NODE,ENAB,INP0,AMPL,TABLE)
+ *
+ * DISCRETE_ADDER2(NODE,ENAB,IN0,IN1)
+ * DISCRETE_ADDER3(NODE,ENAB,IN0,IN1,IN2)
+ * DISCRETE_ADDER4(NODE,ENAB,IN0,IN1,IN2,IN3)
+ * DISCRETE_CLAMP(NODE,IN0,MIN,MAX)
+ * DISCRETE_DIVIDE(NODE,ENAB,IN0,IN1)
+ * DISCRETE_GAIN(NODE,IN0,GAIN)
+ * DISCRETE_INVERT(NODE,IN0)
+ * DISCRETE_LOOKUP_TABLE(NODE,ADDR,SIZE,TABLE)
+ * DISCRETE_MULTIPLY(NODE,ENAB,IN0,IN1)
+ * DISCRETE_MULTADD(NODE,INP0,INP1,INP2)
+ * DISCRETE_ONESHOT(NODE,TRIG,AMPL,WIDTH,TYPE)
+ * DISCRETE_ONESHOTR(NODE,RESET,TRIG,AMPL,WIDTH,TYPE)
+ * DISCRETE_ONOFF(NODE,ENAB,INP0)
+ * DISCRETE_RAMP(NODE,ENAB,RAMP,GRAD,MIN,MAX,CLAMP)
+ * DISCRETE_SAMPLHOLD(NODE,INP0,CLOCK,CLKTYPE)
+ * DISCRETE_SWITCH(NODE,ENAB,SWITCH,INP0,INP1)
+ * DISCRETE_ASWITCH(NODE,CTRL,INP,THRESHOLD)
+ * DISCRETE_TRANSFORM2(NODE,INP0,INP1,FUNCT)
+ * DISCRETE_TRANSFORM3(NODE,INP0,INP1,INP2,FUNCT)
+ * DISCRETE_TRANSFORM4(NODE,INP0,INP1,INP2,INP3,FUNCT)
+ * DISCRETE_TRANSFORM5(NODE,INP0,INP1,INP2,INP3,INP4,FUNCT)
+ *
+ * DISCRETE_COMP_ADDER(NODE,DATA,TABLE)
+ * DISCRETE_DAC_R1(NODE,DATA,VDATA,LADDER)
+ * DISCRETE_DIODE_MIXER2(NODE,IN0,IN1,TABLE)
+ * DISCRETE_DIODE_MIXER3(NODE,IN0,IN1,IN2,TABLE)
+ * DISCRETE_DIODE_MIXER4(NODE,IN0,IN1,IN2,IN3,TABLE)
+ * DISCRETE_INTEGRATE(NODE,TRG0,TRG1,INFO)
+ * DISCRETE_MIXER2(NODE,ENAB,IN0,IN1,INFO)
+ * DISCRETE_MIXER3(NODE,ENAB,IN0,IN1,IN2,INFO)
+ * DISCRETE_MIXER4(NODE,ENAB,IN0,IN1,IN2,IN3,INFO)
+ * DISCRETE_MIXER5(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,INFO)
+ * DISCRETE_MIXER6(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,INFO)
+ * DISCRETE_MIXER7(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO)
+ * DISCRETE_MIXER8(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO)
+ * DISCRETE_OP_AMP(NODE,ENAB,IN0,IN1,INFO)
+ * DISCRETE_OP_AMP_ONESHOT(NODE,TRIG,INFO)
+ * DISCRETE_OP_AMP_TRIG_VCA(NODE,TRG0,TRG1,TRG2,IN0,IN1,INFO)
+ *
+ * DISCRETE_BIT_DECODE(NODE,INP,BIT_N,VOUT)
+ * DISCRETE_BITS_DECODE(NODE,INP,BIT_FROM,BIT_TO,VOUT)
+ *
+ * DISCRETE_LOGIC_INVERT(NODE,INP0)
+ * DISCRETE_LOGIC_AND(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_AND3(NODE,INP0,INP1,INP2)
+ * DISCRETE_LOGIC_AND4(NODE,INP0,INP1,INP2,INP3)
+ * DISCRETE_LOGIC_NAND(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_NAND3(NODE,INP0,INP1,INP2)
+ * DISCRETE_LOGIC_NAND4(NODE,INP0,INP1,INP2,INP3)
+ * DISCRETE_LOGIC_OR(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_OR3(NODE,INP0,INP1,INP2)
+ * DISCRETE_LOGIC_OR4(NODE,INP0,INP1,INP2,INP3)
+ * DISCRETE_LOGIC_NOR(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_NOR3(NODE,INP0,INP1,INP2)
+ * DISCRETE_LOGIC_NOR4(NODE,INP0,INP1,INP2,INP3)
+ * DISCRETE_LOGIC_XOR(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_XNOR(NODE,INP0,INP1)
+ * DISCRETE_LOGIC_DFLIPFLOP(NODE,RESET,SET,CLK,INP)
+ * DISCRETE_LOGIC_JKFLIPFLOP(NODE,RESET,SET,CLK,J,K)
+ * DISCRETE_LOGIC_SHIFT(NODE,INP0,RESET,CLK,SIZE,OPTIONS)
+ * DISCRETE_MULTIPLEX2(NODE,ADDR,INP0,INP1)
+ * DISCRETE_MULTIPLEX4(NODE,ADDR,INP0,INP1,INP2,INP3)
+ * DISCRETE_MULTIPLEX8(NODE,ADDR,INP0,INP1,INP2,INP3,INP4,INP5,INP6,INP7)
+ * DISCRETE_XTIME_BUFFER(NODE,IN0,LOW,HIGH)
+ * DISCRETE_XTIME_INVERTER(NODE,IN0,LOW,HIGH)
+ * DISCRETE_XTIME_AND(NODE,IN0,IN1,LOW,HIGH)
+ * DISCRETE_XTIME_NAND(NODE,IN0,IN1,LOW,HIGH)
+ * DISCRETE_XTIME_OR(NODE,IN0,IN1,LOW,HIGH)
+ * DISCRETE_XTIME_NOR(NODE,IN0,IN1,LOW,HIGH)
+ * DISCRETE_XTIME_XOR(NODE,IN0,IN1,LOW,HIGH)
+ * DISCRETE_XTIME_XNOR(NODE,IN0,IN1,LOW,HIGH)
+ *
+ * DISCRETE_FILTER1(NODE,ENAB,INP0,FREQ,TYPE)
+ * DISCRETE_FILTER2(NODE,ENAB,INP0,FREQ,DAMP,TYPE)
+ *
+ * DISCRETE_CRFILTER(NODE,IN0,RVAL,CVAL)
+ * DISCRETE_CRFILTER_VREF(NODE,IN0,RVAL,CVAL,VREF)
+ * DISCRETE_OP_AMP_FILTER(NODE,ENAB,INP0,INP1,TYPE,INFO)
+ * DISCRETE_RC_CIRCUIT_1(NODE,INP0,INP1,RVAL,CVAL)
+ * DISCRETE_RCDISC(NODE,ENAB,IN0,RVAL,CVAL)
+ * DISCRETE_RCDISC2(NODE,SWITCH,INP0,RVAL0,INP1,RVAL1,CVAL)
+ * DISCRETE_RCDISC3(NODE,ENAB,INP0,RVAL0,RVAL1,CVAL, DJV)
+ * DISCRETE_RCDISC4(NODE,ENAB,INP0,RVAL0,RVAL1,RVAL2,CVAL,VP,TYPE)
+ * DISCRETE_RCDISC5(NODE,ENAB,IN0,RVAL,CVAL)
+ * DISCRETE_RCINTEGRATE(NODE,INP0,RVAL0,RVAL1,RVAL2,CVAL,vP,TYPE)
+ * DISCRETE_RCDISC_MODULATED(NODE,INP0,INP1,RVAL0,RVAL1,RVAL2,RVAL3,CVAL,VP)
+ * DISCRETE_RCFILTER(NODE,IN0,RVAL,CVAL)
+ * DISCRETE_RCFILTER_VREF(NODE,IN0,RVAL,CVAL,VREF)
+ *
+ * DISCRETE_555_ASTABLE(NODE,RESET,R1,R2,C,OPTIONS)
+ * DISCRETE_555_ASTABLE_CV(NODE,RESET,R1,R2,C,CTRLV,OPTIONS)
+ * DISCRETE_555_MSTABLE(NODE,RESET,TRIG,R,C,OPTIONS)
+ * DISCRETE_555_CC(NODE,RESET,VIN,R,C,RBIAS,RGND,RDIS,OPTIONS)
+ * DISCRETE_555_VCO1(NODE,RESET,VIN,OPTIONS)
+ * DISCRETE_555_VCO1_CV(NODE,RESET,VIN,CTRLV,OPTIONS)
+ * DISCRETE_566(NODE,VMOD,R,C,VPOS,VNEG,VCHARGE,OPTIONS)
+ * DISCRETE_74LS624(NODE,ENAB,VMOD,VRNG,C,R_FREQ_IN,C_FREQ_IN,R_RNG_IN,OUTTYPE)
+ *
+ * DISCRETE_CUSTOM1(NODE,IN0,INFO)
+ * DISCRETE_CUSTOM2(NODE,IN0,IN1,INFO)
+ * DISCRETE_CUSTOM3(NODE,IN0,IN1,IN2,INFO)
+ * DISCRETE_CUSTOM4(NODE,IN0,IN1,IN2,IN3,INFO)
+ * DISCRETE_CUSTOM5(NODE,IN0,IN1,IN2,IN3,IN4,INFO)
+ * DISCRETE_CUSTOM6(NODE,IN0,IN1,IN2,IN3,IN4,IN5,INFO)
+ * DISCRETE_CUSTOM7(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO)
+ * DISCRETE_CUSTOM8(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO)
+ * DISCRETE_CUSTOM9(NODE,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,INFO)
+ *
+ * DISCRETE_CSVLOG1(NODE1)
+ * DISCRETE_CSVLOG2(NODE1,NODE2)
+ * DISCRETE_CSVLOG3(NODE1,NODE2,NODE3)
+ * DISCRETE_CSVLOG4(NODE1,NODE2,NODE3,NODE4)
+ * DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5)
+ * DISCRETE_WAVLOG1(NODE1,GAIN1)
+ * DISCRETE_WAVLOG2(NODE1,GAIN1,NODE2,GAIN2)
+ * DISCRETE_OUTPUT(OPNODE,GAIN)
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_inp.c
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_ADJUSTMENT - Adjustable constant set by the UI [~] menu.
+ *
+ * .----------.
+ * | |
+ * | ADJUST.. |--------> Netlist node
+ * | |
+ * '----------'
+ * Declaration syntax
+ *
+ * DISCRETE_ADJUSTMENT(name of node,
+ * static minimum value the node can take,
+ * static maximum value the node can take,
+ * log/linear scale 0=Linear !0=Logarithmic,
+ * port tag name of the adjuster)
+ *
+ * Note: When using DISC_LOGADJ, the min/max values must be > 0.
+ * If they are <=0, they will be forced to 1.
+ * Min can be a higher value then max.
+ * Min/max is just how the slider is displayed.
+ *
+ * Example config line
+ *
+ * DISCRETE_ADJUSTMENT(NODE_01,0.0,5.0,DISC_LINADJ,0,"pot")
+ *
+ * Define an adjustment slider that takes a 0-100 input from input
+ * port "pot", scaling between 0.0 and 5.0. Adjustment scaling is Linear.
+ *
+ * DISC_LOGADJ 1.0
+ * DISC_LINADJ 0.0
+ *
+ * EXAMPLES: see Hit Me, Fire Truck
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_CONSTANT - Single output, fixed at compile time.
+ * This is usefull as a placeholder for
+ * incomplete circuits.
+ *
+ * .----------.
+ * | |
+ * | CONSTANT |--------> Netlist node
+ * | |
+ * '----------'
+ * Declaration syntax
+ *
+ * DISCRETE_CONSTANT(name of node, constant value)
+ *
+ * Example config line
+ *
+ * DISCRETE_CONSTANT(NODE_01, 100)
+ *
+ * Define a node that has a constant value of 100
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_INPUT_DATA - accepts 8-bit data. Value at reset is 0.
+ * DISCRETE_INPUT_LOGIC - 0 if data=0; 1 if data=1. Value at reset is 0.
+ * DISCRETE_INPUT_NOT - 0 if data=1; 1 if data=0. Value at reset is 1.
+ *
+ * DISCRETE_INPUTX_xx - same as above, but will modify the value by the
+ * given GAIN and OFFSET. At reset the value will
+ * be INIT modified by GAIN and OFFSET.
+ *
+ * DISCRETE_INPUT_PULSE - Same as normal input node but the netlist
+ * node output returns to INIT after a single
+ * cycle of sound output. To allow for scenarios
+ * whereby the register write pulse is used as
+ * a reset to a system.
+ *
+ * .----------.
+ * -----\| |
+ * discrete_sound_w data | INPUT(A) |----> Netlist node
+ * Write -----/| |
+ * '----------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_INPUT_DATA (name of node)
+ * DISCRETE_INPUT_LOGIC (name of node)
+ * DISCRETE_INPUT_NOT (name of node)
+ * DISCRETE_INPUTX_DATA (name of node, gain, offset, initial value)
+ * DISCRETE_INPUTX_LOGIC(name of node, gain, offset, initial value)
+ * DISCRETE_INPUTX_NOT (name of node, gain, offset, initial value)
+ * DISCRETE_INPUT_PULSE (name of node, default value)
+ *
+ * Can be written to with: discrete_sound_w(NODE_xx, data);
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_INPUT_STREAM(NODE,NUM) - Accepts stream input NUM
+ * DISCRETE_INPUTX_STREAM(NODE,NUM,GAIN,OFFSET) - Accepts a stream input and
+ * applies a gain and offset.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_INPUT_STREAM (name of node, stream number, )
+ * DISCRETE_INPUTX_STREAM(name of node, stream nubmer, gain, offset)
+ *
+ * Note: The discrete system is floating point based. So when routing a stream
+ * set it's gain to 100% and then use DISCRETE_INPUTX_STREAM to adjust
+ * it if needed.
+ * If you need to access a stream from a discrete task, the stream node
+ * must be part of that task. If a given stream is used in two tasks or
+ * a task and the main task, you must declare two stream nodes acccessing the
+ * same stream input NUM.
+ *
+ * EXAMPLES: see scramble, frogger
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_wav.c
+ * Generic modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_COUNTER - up/down counter.
+ *
+ * This counter counts up/down from MIN to MAX. When the enable is low, the output
+ * is held at it's last value. When reset is high, the reset value is loaded
+ * into the output. The counter can be clocked internally or externally. It also
+ * supports x_time used by the clock modules to pass on anti-aliasing info.
+ *
+ * Declaration syntax
+ *
+ * where: direction: DISC_COUNT_DOWN = 0 = down
+ * DISC_COUNT_UP = 1 = up
+ *
+ * clock type: DISC_CLK_ON_F_EDGE - toggle on falling edge.
+ * DISC_CLK_ON_R_EDGE - toggle on rising edge.
+ * DISC_CLK_BY_COUNT - toggle specified number of times.
+ * DISC_CLK_IS_FREQ - internally clock at this frequency.
+ *
+ * x_time options: you can also | these x_time features to the basic
+ * types above if needed, or use separately with 7492.
+ * DISC_OUT_IS_ENERGY - This will uses the x_time to
+ * anti-alias the count. Might be
+ * usefull if not connected to other
+ * modules.
+ * DISC_OUT_HAS_XTIME - This will generate x_time if
+ * being used with DISC_CLK_IS_FREQ.
+ * It will pass x_time for the
+ * other clock types.
+ *
+ * DISCRETE_COUNTER(name of node,
+ * enable node or static value,
+ * reset node or static value, (reset when TRUE)
+ * clock node or static value,
+ * min count static value,
+ * max count static value,
+ * direction node or static value,
+ * reset value node or static value,
+ * clock type static value)
+ *
+ * DISCRETE_COUNTER_7492(name of node,
+ * enable node or static value,
+ * reset node or static value,
+ * clock node or static value,
+ * clock type static value)
+ *
+ * Note: A 7492 counter outputs a special bit pattern on its /6 stage.
+ * A 7492 clocks on the falling edge,
+ * so it is not recommended to use DISC_CLK_ON_R_EDGE for a 7492.
+ * This module emulates the /6 stage only.
+ * Use another DISCRETE_COUNTER for the /2 stage.
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LFSR_NOISE - Noise waveform generator node, generates
+ * psuedo random digital stream at the requested
+ * clock frequency.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LFSR_NOISE(name of node,
+ * enable node or static value,
+ * reset node or static value,
+ * clock node or static value,
+ * amplitude node or static value,
+ * forced infeed bit to shift reg,
+ * bias node or static value,
+ * LFSR noise descriptor structure)
+ *
+ * discrete_lfsr_desc = {clock type, (see DISCRETE_COUNTER),
+ * bitlength, reset_value,
+ * feedback_bitsel0, feedback_bitsel1,
+ * feedback_function0, feedback_function1, feedback_function2,
+ * feedback_function2_mask, flags, output_bit}
+ *
+ * flags: DISC_LFSR_FLAG_OUT_INVERT - invert output
+ * DISC_LFSR_FLAG_RESET_TYPE_L - reset when LOW (Defalut)
+ * DISC_LFSR_FLAG_RESET_TYPE_H - reset when HIGH
+ * DISC_LFSR_FLAG_OUTPUT_F0 - output is result of F0
+ * DISC_LFSR_FLAG_OUTPUT_SR_SN1 - output shift register to sub-node output #1
+ *
+ * The diagram below outlines the structure of the LFSR model.
+ *
+ * .-------.
+ * FEED | |
+ * ----->| F1 |<--------------------------------------------.
+ * | | |
+ * '-------' BS - Bit Select |
+ * | Fx - Programmable Function |
+ * | .-------. PI - Programmable Inversion |
+ * | | | |
+ * | .---- | SR>>1 |<--------. |
+ * | | | | | |
+ * V V '-------' | .---- |
+ * .------. +->| BS |--. .------. |
+ * BITMASK | | .-------------. | '----' '-| | |
+ * ------->| F2 |-+->| Shift Reg |--+ | F0 |--'
+ * | | | '-------------' | .----. .-| |
+ * '------' | ^ '->| BS |--' '------'
+ * | | '----'
+ * CLOCK | RESET VAL
+ * ----> | .----. .----.
+ * '----------------------| BS |--| PI |--->OUTPUT
+ * '----' '----'
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_NOISE - Noise waveform generator node, generates
+ * random noise of the chosen frequency.
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * FREQUENCY -1------>| NOISE |----> Netlist node
+ * | |
+ * AMPLITUDE -2------>| |
+ * | |
+ * BIAS -3------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_NOISE(name of node,
+ * enable node or static value,
+ * frequency node or static value,
+ * amplitude node or static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_NOISE(NODE_03,1,5000,NODE_01,0)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_NOTE - Note generator. This takes a chosen clock, and
+ * clocks an up counter that is preloaded with the data
+ * value at every max 1 count. Every time max 1 count
+ * is reached, the output counts up one and rolls over
+ * to 0 at max 2 count.
+ * When the data value is the same as max count 1, the
+ * counter no longer counts.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_NOTE(name of node,
+ * enable node or static value,
+ * clock node or static value,
+ * data node or static value,
+ * max 1 count static value,
+ * max 2 count static value,
+ * clock type (see DISCRETE_COUNTER))
+ *
+ * EXAMPLES: see Polaris, Blockade
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SAWTOOTHWAVE - Saw tooth shape waveform generator, rapid
+ * rise and then graduated fall
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * FREQUENCY -1------>| |
+ * | |
+ * AMPLITUDE -2------>| SAWTOOTH |----> Netlist Node
+ * | WAVE |
+ * BIAS -3------>| |
+ * | |
+ * GRADIENT -4------>| |
+ * | |
+ * PHASE -5------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SAWTOOTHWAVE(name of node,
+ * enable node or static value,
+ * frequency node or static value,
+ * amplitude node or static value,
+ * dc bias value for waveform,
+ * gradient of wave ==0 //// !=0 \\\\,
+ * starting phase value in degrees)
+ *
+ * Example config line
+ *
+ * DISCRETE_SAWTOOTHWAVE(NODE_03,1,5000,NODE_01,0,0,90)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SINEWAVE - Sinewave waveform generator node, has four
+ * input nodes FREQUENCY, AMPLITUDE, ENABLE and
+ * PHASE, if a node is not connected it will
+ * default to the initialised value in the macro
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * FREQUENCY -1------>| |
+ * | SINEWAVE |----> Netlist node
+ * AMPLITUDE -2------>| |
+ * | |
+ * BIAS -3------>| |
+ * | |
+ * PHASE -4------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SINEWAVE (name of node,
+ * enable node or static value,
+ * frequency node or static value,
+ * amplitude node or static value,
+ * dc bias value for waveform,
+ * starting phase value in degrees)
+ *
+ * Example config line
+ *
+ * DISCRETE_SINEWAVE(NODE_03,NODE_01,NODE_02,10000,5000.0,90)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SQUAREWAVE - Squarewave waveform generator node.
+ * DISCRETE_SQUAREWFIX Waveform is defined by frequency and duty
+ * cycle.
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * FREQUENCY -1------>| |
+ * | |
+ * AMPLITUDE -2------>| SQUAREWAVE |----> Netlist node
+ * | |
+ * DUTY CYCLE -3------>| |
+ * | |
+ * BIAS -4------>| |
+ * | |
+ * PHASE -5------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SQUAREWAVE(name of node,
+ * enable node or static value,
+ * frequency node or static value,
+ * amplitude node or static value,
+ * duty cycle node or static value,
+ * dc bias value for waveform,
+ * starting phase value in degrees)
+ *
+ * Example config line
+ *
+ * DISCRETE_SQUAREWAVE(NODE_03,NODE_01,NODE_02,100,50,0,90)
+ *
+ * NOTE: DISCRETE_SQUAREWFIX is used the same as DISCRETE_SQUAREWAVE.
+ * BUT... It does not stay in sync when you change the freq or
+ * duty values while enabled. This should be used only
+ * when these values are stable while the wave is enabled.
+ * It takes up less CPU time then DISCRETE_SQUAREWAVE and
+ * should be used whenever possible.
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SQUAREWAVE2 - Squarewave waveform generator node.
+ * Waveform is defined by it's off/on time
+ * periods.
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * AMPLITUDE -1------>| |
+ * | |
+ * OFF TIME -2------>| SQUAREWAVE |----> Netlist node
+ * | |
+ * ON TIME -3------>| |
+ * | |
+ * BIAS -4------>| |
+ * | |
+ * TIME SHIFT -5------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SQUAREWAVE2(name of node,
+ * enable node or static value,
+ * amplitude node or static value,
+ * off time node or static value in seconds,
+ * on time node or static value in seconds,
+ * dc bias value for waveform,
+ * starting phase value in seconds)
+ *
+ * Example config line
+ *
+ * DISCRETE_SQUAREWAVE2(NODE_03,NODE_01,NODE_02,0.01,0.001,0.0,0.001)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_TRIANGLEW - Triagular waveform generator, generates
+ * equal ramp up/down at chosen frequency
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | |
+ * FREQUENCY -1------>| TRIANGLE |----> Netlist node
+ * | WAVE |
+ * AMPLITUDE -2------>| |
+ * | |
+ * BIAS -3------>| |
+ * | |
+ * PHASE -4------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_TRIANGLEWAVE(name of node,
+ * enable node or static value,
+ * frequency node or static value,
+ * amplitude node or static value,
+ * dc bias value for waveform,
+ * starting phase value in degrees)
+ *
+ * Example config line
+ *
+ * DISCRETE_TRIANGLEWAVE(NODE_03,1,5000,NODE_01,0.0,0.0)
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_wav.c
+ * Component specific modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP_OSCILLATOR - Various single power supply op-amp oscillator circuits
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP_OSCILLATOR(name of node,
+ * enable node or static value,
+ * address of dss_op_amp_osc_context structure)
+ *
+ * discrete_op_amp_osc_info = {type, r1, r2, r3, r4, r5, r6, r7, r8, c, vP}
+ *
+ * Note: Set all unused components to 0.
+ * _OUT_SQW can also be replaced with
+ * _OUT_ENERGY, _OUT_LOGIC_X, _OUT_COUNT_F_X, _OUT_COUNT_R_X
+ *
+ * Types:
+ *
+ * DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Op Amp Oscillator circuit.
+ *
+ * vP >-.
+ * | c
+ * Z .---||----+-------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * Z r1 | |
+ * Z | |\ |
+ * | | | \ | |\
+ * '-----+---|- \ | r3 | \
+ * | >-+----ZZZZ----|- \
+ * |+ / | >--+-----> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * .---| / .--|+ / |
+ * | |/ r5 | | / |
+ * vP >-. | vP >--ZZZZ---+ |/ |
+ * | Z | |
+ * Z Z r2 | r4 |
+ * Z 1k Z '--ZZZZ---+
+ * Z | |
+ * |\ | r6 | |
+ * Enable >---| >-+-ZZZZ---+-----------------------------'
+ * |/ O.C.
+ *
+ * Note: R1 - R5 can be nodes.
+ *
+ * EXAMPLES: see Polaris, Amazing Maze
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Op Amp Oscillator circuit.
+ *
+ * .-------------------------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * |
+ * | r1
+ * +------ZZZZ-----.
+ * | |
+ * | r5 |
+ * +--ZZZZ---|>|---.
+ * | |
+ * | r6 |
+ * +--ZZZZ---|<|---.
+ * | |
+ * | |\ |
+ * | r2 | \ |
+ * +---ZZZZ--|- \ |
+ * | | >-+-------> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * --- c |+ / |
+ * --- .---| / |
+ * | | |/ |
+ * gnd | |
+ * | r3 |
+ * +--ZZZZ---'
+ * |
+ * Z
+ * Z r4
+ * Z
+ * |
+ * ^
+ * vP
+ *
+ * Note: All values are static.
+ *
+ * EXAMPLES: see Space Walk, Blue Shark
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP_VCOn - Various single power supply op-amp VCO circuits
+ * (n = 1 or 2)
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP_VCOn(name of node,
+ * enable node or static value,
+ * modulation voltage 1 node or static value,
+ * modulation voltage 2 node or static value, [optional]
+ * address of dss_op_amp_osc_context structure)
+ *
+ * discrete_op_amp_osc_info = {type, r1, r2, r3, r4, r5, r6, r7, r8, c, vP}
+ *
+ * Note: Set all unused components to 0.
+ * _OUT_SQW can also be replaced with
+ * _OUT_ENERGY, _OUT_LOGIC_X, _OUT_COUNT_F_X, _OUT_COUNT_R_X
+ *
+ * Types:
+ *
+ * DISC_OP_AMP_OSCILLATOR_VCO_1
+ * Basic Op Amp Voltage Controlled Oscillator circuit.
+ * Note that this circuit has only 1 modulation voltage.
+ * So it is used only with DISCRETE_OP_AMP_VCO1.
+ *
+ * c
+ * .------------------------+---||----+---------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * | | |
+ * | | |\ |
+ * | r1 | | \ | |\
+ * | vMod1 >--+--ZZZZ-------+---|- \ | | \
+ * | | | >-+------------|- \
+ * | | r2 |+ / | >--+-------> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * Z '--ZZZZ--+--------| / .--|+ / |
+ * Z r6 | |/ r4 | | / |
+ * Z Z vP/2 >--ZZZZ---+ |/ |
+ * | Z r5 | |
+ * .----. Z | r3 |
+ * | sw |<--------. | '--ZZZZ---+
+ * '----' | gnd |
+ * | | |
+ * gnd '----------------------------------------'
+ *
+ * Notes: The 'sw' block can be a transistor or 4066 switch. It connects
+ * r6 to ground when 'sw' is high.
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Op Amp Voltage Controlled Oscillator circuit.
+ * When disabled, c discharges and sqw out goes high.
+ *
+ * .---------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * c |
+ * r6 .---||----+
+ * vP >--ZZZZ---. | | r5 |\
+ * | | |\ | vP >--ZZZZ-. | \
+ * r7 | r1 | | \ | '-|- \
+ * vMod1 >--ZZZZ---+--ZZZZ-------+---|- \ | r3 | >--+-------> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * | | >-+----ZZZZ----+--|+ / |
+ * r8 | r2 .----. |+ / | | / |
+ * vMod2 >--ZZZZ---+--ZZZZ---| sw |--| / | |/ |
+ * '----' |/ | |
+ * ^ ^ | r4 |
+ * | | '--ZZZZ---+
+ * | | |
+ * Enable >---------' | |
+ * '--------------------------------'
+ *
+ * EXAMPLES: see Polaris
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Op Amp Voltage Controlled Oscillator circuit.
+ * Note that this circuit has only 1 modulation voltage.
+ * So it is used only with DISCRETE_OP_AMP_VCO1.
+ * When vMod1 goes to 0V, the oscillator is disabled.
+ * c fully charges and the sqw out goes low.
+ *
+ * .---------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * |
+ * | r4
+ * c | .--ZZZZ--.
+ * .---||----+ | |
+ * | | r5 | |\ |
+ * | |\ | vP >--ZZZZ-+ | \ |
+ * r1 | | \ | '-|+ \ |
+ * vMod1 >--ZZZZ-----------------+---|- \ | r3 | >--+-------> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * | >-+----ZZZZ-------|- / |
+ * r2 |+ / | / |
+ * vP >--ZZZZ-----------------+---| / |/ |
+ * | |/ |
+ * r6 .----. | |
+ * vP >--ZZZZ-----|-sw-|------' |
+ * '----' |
+ * ^ |
+ * | |
+ * '-----------------------------------------'
+ *
+ * EXAMPLES: see Double Play
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Op Amp Voltage Controlled Oscillator circuit.
+ *
+ *
+ * c
+ * r7 .---||----+---------------------------> DISC_OP_AMP_OSCILLATOR_OUT_CAP
+ * vP >--ZZZZ---. | |
+ * | | |\ |
+ * r1 | | | \ | |\
+ * vMod1 >--ZZZZ---+---------+---|- \ | r3 | \
+ * | | >-+----ZZZZ----|- \
+ * r6 | |+ / | >--+-------> DISC_OP_AMP_OSCILLATOR_OUT_SQW
+ * vMod2 >--ZZZZ---' .---| / .--|+ / |
+ * | |/ r5 | | / |
+ * vP >-. | vP >--ZZZZ---+ |/ |
+ * | Z | |
+ * Z Z r2 | r4 |
+ * Z 1k Z '--ZZZZ---+
+ * Z | |
+ * |\ | r8 | |
+ * Enable >---| >-+-ZZZZ---+-----------------------------'
+ * |/ O.C.
+ *
+ * EXAMPLES: see Space Encounter, Blue Shark
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SCHMITT_OSCILLATOR - Schmitt Inverter gate oscillator
+ *
+ * rFeedback
+ * .---ZZZ----. .--< Amplitude
+ * | | |
+ * | |\ | .------. |
+ * rIn | | \ | 0/1 | AND/ | .-.
+ * INP0 >---ZZZ--+--|S >o---+----->|NAND/ |--->|*|-----> Netlist Node
+ * | | / | OR/ | '-'
+ * | |/ .->| NOR |
+ * --- | '------'
+ * --- C |
+ * | ^
+ * gnd Enable
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SCHMITT_OSCILLATOR(name of node,
+ * enable node or static value,
+ * Input 0 node or static value,
+ * Amplitude node or static value,
+ * address of discrete_schmitt_osc_desc structure)
+ *
+ * discrete_schmitt_osc_desc = {rIn, rFeedback, c, trshRise, trshFall, vGate, options}
+ *
+ * Note: trshRise, trshFall, vGate can be replaced with one of these common types:
+ * DEFAULT_7414_VALUES or DEFAULT_74LS14_VALUES (the LS makes a difference)
+ * eg: {rIn, rFeedback, c, DEFAULT_7414_VALUES, options}
+ *
+ * Where:
+ * trshRise is the voltage level that triggers the gate input to go high (vGate) on rise.
+ * trshFall is the voltage level that triggers the gate input to go low (0V) on fall.
+ * vGate is the output high voltage of the gate that gets fedback through rFeedback.
+ *
+ * Input Options:
+ * DISC_SCHMITT_OSC_IN_IS_LOGIC (DEFAULT)
+ * DISC_SCHMITT_OSC_IN_IS_VOLTAGE
+ *
+ * Enable Options: (ORed with input options)
+ * DISC_SCHMITT_OSC_ENAB_IS_AND (DEFAULT)
+ * DISC_SCHMITT_OSC_ENAB_IS_NAND
+ * DISC_SCHMITT_OSC_ENAB_IS_OR
+ * DISC_SCHMITT_OSC_ENAB_IS_NOR
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_INVERTER_OSC - Inverter gate oscillator circuits
+ *
+ * TYPE 1/3
+ * .----------------------------> Netlist Node (Type 3)
+ * |
+ * |\ | |\ |\
+ * | \ | | \ | \
+ * +--| >o--+--|-->o--+--| >o--+--------> Netlist Node (Type 1)
+ * | | / | / | | / |
+ * | |/ |/ | |/ |
+ * Z | |
+ * Z RP --- |
+ * Z --- C |
+ * | | R1 |
+ * '-------------------+----ZZZ--'
+ *
+ * TYPE 2
+ *
+ * |\ |\
+ * | \ | \
+ * +--| >o--+--|-->o--+-------> Netlist Node
+ * | | / | | / |
+ * | |/ | |/ |
+ * Z Z |
+ * Z RP Z R1 ---
+ * Z Z --- C
+ * | | |
+ * '---------+---------'
+ *
+ *
+ * TYPE 4 / see vicdual
+ *
+ * |\ |\
+ * | \ | \
+ * Enable >-+-----+--|>o-+--|-->o--+-------> Netlist Node
+ * | | / | | / |
+ * | |/ | |/ |
+ * Z Z |
+ * Z RP Z R1 ---
+ * Z Z --- C
+ * | D | |
+ * '------|>|---+---------'
+ * |
+ * Mod >-----ZZZ------'
+ * R2
+ *
+ * TYPE 5 / see vicdual
+ * Diode will cause inverted input behaviour and inverted output
+ *
+ * |\ |\
+ * | \ | \
+ * Enable >-+-----+--|>o-+--|-->o--+-------> Netlist Node
+ * | | / | | / |
+ * | |/ | |/ |
+ * Z Z |
+ * Z RP Z R1 ---
+ * Z Z --- C
+ * | D | |
+ * '------|<|---+---------'
+ * |
+ * Mod >-----ZZZ------'
+ * R2
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_INVERTER_OSC( name of node,
+ * enable node or static value,
+ * modulation node or static value (0 when not used),
+ * R1 static value,
+ * RP static value
+ * C static value,
+ * R2 static value (0 when not used),
+ * address of discrete_inverter_osc_desc structure)
+ *
+ * discrete_inverter_osc_desc = {vB, vOutLow, vOutHigh, vInRise, vInFall, clamp, options}
+ *
+ * Where
+ * vB Supply Voltage
+ * vOutLow Low Output voltage
+ * vOutHigh High Output voltage
+ * vInRise voltage that triggers the gate input to go high (vGate) on rise
+ * vInFall voltage that triggers the gate input to go low (0V) on fall
+ * clamp internal diode clamp: [-clamp ... vb+clamp] if clamp>= 0
+ * options bitmaped options
+ *
+ * There is a macro DEFAULT_CD40XX_VALUES(_vB) which may be used to initialize the
+ * structure with .... = { 5, DEFAULT_CD40XX_VALUES(5), DISC_OSC_INVERTER_IS_TYPE1}
+ *
+ * The parameters are used to construct a input/output transfer function.
+ *
+ * Option Values
+ *
+ * DISC_OSC_INVERTER_IS_TYPE1
+ * DISC_OSC_INVERTER_IS_TYPE2
+ * DISC_OSC_INVERTER_IS_TYPE3
+ * DISC_OSC_INVERTER_IS_TYPE4
+ * DISC_OSC_INVERTER_OUT_IS_LOGIC
+ *
+ * EXAMPLES: see dkong
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_wav.c
+ * Not yet implemented
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_ADSR_ENV - Attack Decay Sustain Release envelope generator
+ *
+ * Note: Not yet implemented.
+ *
+ * .------------.
+ * | |
+ * ENABLE -0------>| |
+ * | /\__ |
+ * TRIGGER -1------>| / \ |----> Netlist node
+ * | ADSR |
+ * GAIN -2------>| Env |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_ADSR_ENV (name of node,
+ * enable node or static value,
+ * envelope gain node or static value,
+ * envelope descriptor struct)
+ *
+ * Example config line
+ *
+ * DISCRETE_ADSR_ENV(NODE_3,1,NODE_21,1.0,&adsrdesc)
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_mth.c
+ * Generic modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_ADDER - Node addition function, available in three
+ * lovely flavours, ADDER2,ADDER3,ADDER4
+ * that perform a summation of incoming nodes
+ *
+ * .------------.
+ * | |
+ * INPUT0 -0------>| |
+ * | |
+ * INPUT1 -1------>| | |
+ * | -+- |----> Netlist node
+ * INPUT2 -2------>| | |
+ * | |
+ * INPUT3 -3------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_ADDERx (name of node,
+ * (x=2/3/4) enable node or static value,
+ * input0 node or static value,
+ * input1 node or static value,
+ * input2 node or static value, [optional]
+ * input3 node or static value) [optional]
+ *
+ * Example config line
+ *
+ * DISCRETE_ADDER2(NODE_03,1,NODE_12,-2000)
+ *
+ * Always enabled, subtracts 2000 from the output of NODE_12
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_CLAMP - Force a signal to stay within bounds MIN/MAX
+ *
+ * .------------.
+ * | |
+ * INP0 -0------>| |
+ * | |
+ * MIN -1------>| CLAMP |----> Netlist node
+ * | |
+ * MAX -2------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_CLAMP(name of node,
+ * input node,
+ * minimum node or static value,
+ * maximum node or static value),
+ *
+ * Example config line
+ *
+ * DISCRETE_CLAMP(NODE_9,NODE_10,2.0,10.0)
+ *
+ * Force the value on the node output, to be within the MIN/MAX
+ * boundary. In this example the output is clamped to the range
+ * of 2.0 to 10.0 inclusive.
+ *
+ * EXAMPLES: Sprint 8
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_DIVIDE - Node division function
+ *
+ * .------------.
+ * | |
+ * ENAB -0------>| |
+ * | o |
+ * INPUT1 -1------>| --- |----> Netlist node
+ * | o |
+ * INPUT2 -2------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_DIVIDE (name of node,
+ * enable node or static value,
+ * input0 node or static value,
+ * input1 node or static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_DIVIDE(NODE_03,1.0,NODE_12,50.0)
+ *
+ * Always enabled, divides the input NODE_12 by 50.0. Note that a
+ * divide by zero condition will give a LARGE number output, it
+ * will not stall the machine or simulation. It will also attempt
+ * to write a divide by zero error to the Mame log if enabled.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_BIT_DECODE - Decode a bit from value
+ * DISCRETE_BITS_DECODE - Decode a range of bits from value
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_BIT_DECODE(name of node,
+ * input0 node or static value,
+ * bit number static value,
+ * output voltage (logic high) static value)
+ *
+ * Note: This module can decode x_time from counters, etc.
+ * If you set the output voltage to 0, then 0/1 with x_time will be output.
+ * Otherwise it will be used as energy based on the output voltage.
+ *
+ * Example config lines
+ *
+ * DISCRETE_BIT_DECODE(NODE_03,7,0,5)
+ *
+ * Node output is 5
+ *
+ * DISCRETE_BIT_DECODE(NODE_03,7,3,5)
+ *
+ * Node output is 0
+ *
+ * if the range variant is used, you may access the bits (up to 8)
+ * by using NODE_SUB, i.e.
+ *
+ * DISCRETE_BITS_DECODE(NODE_03,5,0,4,5)
+ *
+ * NODE_SUB(NODE_03, 0) = 5
+ * NODE_SUB(NODE_03, 1) = 0
+ * NODE_SUB(NODE_03, 2) = 5
+ * NODE_SUB(NODE_03, 3) = 0
+ * NODE_SUB(NODE_03, 4) = 0
+ *
+ * EXAMPLES: galaxian, dkong, mario
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LOGIC_INVERT - Logic invertor
+ * DISCRETE_LOGIC_AND - Logic AND gate (3 & 4 input also available)
+ * DISCRETE_LOGIC_NAND - Logic NAND gate (3 & 4 input also available)
+ * DISCRETE_LOGIC_OR - Logic OR gate (3 & 4 input also available)
+ * DISCRETE_LOGIC_NOR - Logic NOR gate (3 & 4 input also available)
+ * DISCRETE_LOGIC_XOR - Logic XOR gate
+ * DISCRETE_LOGIC_XNOR - Logic NXOR gate
+ *
+ * .------------.
+ * | |
+ * INPUT0 -0------>| |
+ * | LOGIC |
+ * [INPUT1] -1------>| FUNCTION |----> Netlist node
+ * | !&|^ |
+ * [INPUT2] -2------>| |
+ * | |
+ * [INPUT3] -3------>| |
+ * | |
+ * [] - Optional '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LOGIC_XXXn(name of node,
+ * (X=INV/AND/etc)
+ * (n=Blank/2/3) input0 node or static value,
+ * [input1 node or static value],
+ * [input2 node or static value],
+ * [input3 node or static value])
+ *
+ * Example config lines
+ *
+ * DISCRETE_LOGIC_INVERT(NODE_03,NODE_12)
+ * DISCRETE_LOGIC_AND(NODE_03,NODE_12,NODE_13)
+ * DISCRETE_LOGIC_NOR4(NODE_03,NODE_12,NODE_13,NODE_14,NODE_15)
+ *
+ * Node output is always either 0.0 or 1.0 any input value !=0.0 is
+ * taken as a logic 1.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_XTIME_BUFFER
+ * DISCRETE_XTIME_INVERTER
+ * DISCRETE_XTIME_AND
+ * DISCRETE_XTIME_NAND
+ * DISCRETE_XTIME_OR
+ * DISCRETE_XTIME_NOR
+ * DISCRETE_XTIME_XOR
+ * DISCRETE_XTIME_XNOR
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_XTIME_xxx(name of node,
+ * (xxx=INV/AND/etc)
+ * input0 node or static value,
+ * [input1 node or static value],
+ * logic Low voltage (static value),
+ * logic High voltage (static value))
+ *
+ * These modules all take 0/1 with x_time data and perform the logic
+ * while keeping and using the x_time anti-alaising data.
+ * If both logic Low and High are set to 0, the 0/1 + x_time data
+ * will be output. Otherwise the Low/High voltages will be used
+ * to convert the x_time to energy.
+ *
+ * EXAMPLES: see Mario Bros.; Donkey Kong Jr
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LOGIC_DFLIPFLOP - Standard D-type flip-flop.
+ * Changes on rising edge of clock.
+ *
+ * /SET -2 ------------.
+ * v
+ * .-----o------.
+ * | |
+ * DATA -4 ----->| |
+ * | FLIPFLOP |
+ * | Q|----> Netlist node
+ * | |
+ * CLOCK -3 ----->| |
+ * | |
+ * '-----o------'
+ * ^
+ * /RESET -1 ------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LOGIC_DFLIPFLOP(name of node,
+ * reset node or static value,
+ * set node or static value,
+ * clock node,
+ * data node or static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_LOGIC_DFLIPFLOP(NODE_7,NODE_17,0,NODE_13,1)
+ *
+ * A flip-flop that clocks a logic 1 through on the rising edge of
+ * NODE_13. A logic 1 on NODE_17 resets the output to 0.
+ *
+ * EXAMPLES: see Hit Me, Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LOGIC_JKFLIPFLOP - Standard JK-type flip-flop.
+ * Changes on falling edge of clock.
+ *
+ * /SET -2 ------------.
+ * v
+ * .-----o------.
+ * | |
+ * J -4 ----->| |
+ * | FLIPFLOP |
+ * CLOCK -3 ----->| Q|----> Netlist node
+ * | |
+ * K -5 ----->| |
+ * | |
+ * '-----o------'
+ * ^
+ * /RESET -1 ------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LOGIC_JKFLIPFLOP(name of node,
+ * reset node or static value,
+ * set node or static value,
+ * clock node,
+ * J node or static value,
+ * K node or static value)
+ *
+ * EXAMPLES: see Amazing Maze
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LOOKUP_TABLE - returns the value in a table
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LOOKUP_TABLE(name of node,
+ * address node,
+ * size of table static value,
+ * address of table of double values)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_MULTIPLEX - 1 of 2/4/8 multiplexer
+ *
+ * .-------------.
+ * Input 0 >-----|>-<. |
+ * | \ |
+ * Input 1 >-----|>- \ |
+ * | \ |
+ * Input 2 >-----|>- |\ |
+ * | | \ |
+ * Input 3 >-----|>- | o-->|------> Netlist Node
+ * | | |
+ * Input 4 >-----|>- | |
+ * | | |
+ * Input 5 >-----|>- '------|----< Address
+ * | | (0 shown)
+ * Input 6 >-----|>- |
+ * | |
+ * Input 7 >-----|>- |
+ * '-------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_MULTIPLEXx(name of node,
+ * (x=2/4/8) address node,
+ * input 0 node or static value,
+ * input 1 node or static value, ...)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_LOGIC_SHIFT - shift register
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_LOGIC_SHIFT(name of node,
+ * input node,
+ * reset node or static value,
+ * clock node or static value,
+ * size static value,
+ * options static value)
+ *
+ * Options:
+ * reset type: DISC_LOGIC_SHIFT__RESET_L
+ * DISC_LOGIC_SHIFT__RESET_H
+ * shift type: DISC_LOGIC_SHIFT__LEFT
+ * DISC_LOGIC_SHIFT__RIGHT
+ * clock type: DISC_CLK_ON_F_EDGE - toggle on falling edge.
+ * DISC_CLK_ON_R_EDGE - toggle on rising edge.
+ * DISC_CLK_BY_COUNT - toggle specified number of times.
+ * DISC_CLK_IS_FREQ - internally clock at this frequency.
+ *
+ * EXAMPLES: see Sky Raider
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_GAIN - Node multiplication function output is equal
+ * DISCRETE_MULTIPLY to INPUT0 * INPUT1
+ * DISCRETE_MULTADD to (INPUT0 * INPUT1) + INPUT 2
+ *
+ * .------------.
+ * | |
+ * INPUT0 -1------>| \|/ |
+ * | -+- |----> Netlist node
+ * INPUT1 -2------>| /|\ |
+ * | |
+ * INPUT2 -3------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_MULTIPLY (name of node,
+ * input0 node or static value,
+ * input1 node or static value)
+ *
+ * DISCRETE_MULTADD (name of node,
+ * input0 node or static value,
+ * input1 node or static value,
+ * input2 node or static value)
+ *
+ * DISCRETE_GAIN (name of node,
+ * input0 node or static value,
+ * static value for gain)
+ * Example config line
+ *
+ * DISCRETE_GAIN(NODE_03,NODE_12,112.0)
+ *
+ * Always enabled, multiplies the input NODE_12 by 112.0
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_ONESHOT - Monostable multivibrator, no reset
+ * DISCRETE_ONESHOTR - Monostable multivibrator, with reset
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_ONESHOT (name of node,
+ * trigger node,
+ * amplitude node or static value,
+ * width (in seconds) node or static value,
+ * type of oneshot static value)
+ *
+ * DISCRETE_ONESHOTR (name of node,
+ * reset node or static value,
+ * trigger node,
+ * amplitude node or static value,
+ * width (in seconds) node or static value,
+ * type of oneshot static value)
+ *
+ * Types:
+ *
+ * DISC_ONESHOT_FEDGE 0x00 - trigger on falling edge (DEFAULT)
+ * DISC_ONESHOT_REDGE 0x01 - trigger on rising edge
+ *
+ * DISC_ONESHOT_NORETRIG 0x00 - non-retriggerable (DEFAULT)
+ * DISC_ONESHOT_RETRIG 0x02 - retriggerable
+ *
+ * DISC_OUT_ACTIVE_LOW 0x04 - output active low
+ * DISC_OUT_ACTIVE_HIGH 0x00 - output active high (DEFAULT)
+ *
+ * NOTE: A width of 0 seconds will output a pulse of 1 sample.
+ * This is useful for a guaranteed minimun pulse, regardless
+ * of the sample rate.
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RAMP - Ramp up/down circuit with clamps & reset
+ *
+ * .------------.
+ * | |
+ * ENAB -0------>| FREE/CLAMP |
+ * | |
+ * RAMP -1------>| FW/REV |
+ * | |
+ * GRAD -2------>| Grad/sec |
+ * | |----> Netlist node
+ * START -3------>| Start clamp|
+ * | |
+ * END -4------>| End clamp |
+ * | |
+ * CLAMP -5------>| off clamp |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RAMP(name of node,
+ * enable,
+ * ramp forward/reverse node (or value),
+ * gradient node (or static value),
+ * start node or static value,
+ * end node or static value,
+ * clamp node or static value when disabled)
+ *
+ * Example config line
+ *
+ * DISCRETE_RAMP(NODE_9,NODE_10,NODE_11,10.0,-10.0,10.0,0)
+ *
+ * Node10 when not zero will allow ramp to operate, when 0 then output
+ * is clamped to clamp value specified. Node11 ramp when 0 change
+ * gradient from start to end. 1 is reverse. Output is clamped to max-
+ * min values. Gradient is specified in change/second.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SAMPHOLD - Sample & Hold circuit
+ *
+ * .------------.
+ * | |
+ * ENAB -0------>| |
+ * | |
+ * INP0 -1------>| SAMPLE |
+ * | & |----> Netlist node
+ * CLOCK -2------>| HOLD |
+ * | |
+ * CLKTYPE -3------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SAMPHOLD(name of node,
+ * enable,
+ * input node,
+ * clock node or static value,
+ * input clock type)
+ *
+ * Example config line
+ *
+ * DISCRETE_SAMPHOLD(NODE_9,1,NODE_11,NODE_12,DISC_SAMPHOLD_REDGE)
+ *
+ * Node9 will sample the input node 11 on the rising edge (REDGE) of
+ * the input clock signal of node 12.
+ *
+ * DISC_SAMPHOLD_REDGE - Rising edge clock
+ * DISC_SAMPHOLD_FEDGE - Falling edge clock
+ * DISC_SAMPHOLD_HLATCH - Output is latched whilst clock is high
+ * DISC_SAMPHOLD_LLATCH - Output is latched whilst clock is low
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SWITCH - Node switch function, output node is switched
+ * by switch input to take one node/contst or
+ * other. Can be nodes or constants.
+ *
+ * SWITCH -0--------------.
+ * V
+ * .------------.
+ * | | |
+ * INPUT0 -1------}|----o |
+ * | .--- |----> Netlist node
+ * INPUT1 -2------>|----o / |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SWITCH (name of node,
+ * enable node or static value,
+ * switch node or static value,
+ * input0 node or static value,
+ * input1 node or static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_SWITCH(NODE_03,1,NODE_10,NODE_90,5.0)
+ *
+ * Always enabled, NODE_10 switches output to be either NODE_90 or
+ * constant value 5.0. Switch==0 inp0=output else inp1=output
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_ASWITCH - Node switch function, output node is same
+ * as input when CTRL is above threshold.
+ *
+ * CTRL -0--------------.
+ * V
+ * .------------.
+ * | | |
+ * INPUT0 -1------ |----- . --- |----> Netlist node
+ * | |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_ASWITCH (name of node,
+ * ctrl node or static value,
+ * input node or static value,
+ * threshold satic value )
+ *
+ * Example config line
+ *
+ * DISCRETE_ASWITCH(NODE_03,NODE_10,NODE_90, 2.73)
+ *
+ * Always enabled, NODE_10 switches output to be either NODE_90 or
+ * constant value 0.0. Ctrl>2.73 output=NODE_90 else output=0
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_TRANSFORMn - Node arithmatic logic (postfix arithmatic)
+ * (n=2,3,4,5)
+ * .------------.
+ * | |
+ * INPUT0 -0------>| |
+ * | |
+ * INPUT1 -1------>| Postfix |
+ * | stack |----> Netlist node
+ * INPUT2 -2------>| maths |
+ * | |
+ * INPUT3 -3------>| |
+ * | |
+ * INPUT4 -4------>| |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_TRANSFORMn(name of node,
+ * input0 node or static value,
+ * input1 node or static value,
+ * input2 node or static value, [optional]
+ * input3 node or static value, [optional]
+ * input4 node or static value, [optional]
+ * maths string)
+ *
+ * Example config line
+ *
+ * DISCRETE_TRANSFORM4(NODE_12,NODE_22,50.0,120.0,33.33,"01*2+3/")
+ *
+ * Arithmetic uses stack based arithmetic similar to Forth, the maths
+ * has 5 registers 0-4 and various arithmetic operations. The math
+ * string is processed from left to right in the following manner:
+ * 0 - Push input 0 to stack
+ * 1 - Push input 1 to stack
+ * 2 - Push input 2 to stack
+ * 3 - Push input 3 to stack
+ * 4 - Push input 4 to stack
+ * - - Pop two values from stack, subtract and push result to stack
+ * + - Pop two values from stack, add and push result to stack
+ * / - Pop two values from stack, divide and push result to stack
+ * * - Pop two values from stack, multiply and push result to stack
+ * a - Pop one value from stack, multiply -1 if less than 0 and push result to stack
+ * i - Pop one value from stack, multiply -1 and push result to stack
+ * ! - Pop one value from stack, logical invert, push result to stack
+ * = - Pop two values from stack, logical = and push result to stack
+ * > - Pop two values from stack, logical > and push result to stack
+ * < - Pop two values from stack, logical < and push result to stack
+ * & - Pop two values from stack, binary AND and push result to stack
+ * | - Pop two values from stack, binary OR and push result to stack
+ * ^ - Pop two values from stack, binary XOR and push result to stack
+ * P - Push a duplicate of the last stack value back on the stack
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_mth.c
+ * Component specific modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_COMP_ADDER - Selecatable parallel component adder.
+ * The total netlist out will be the parallel sum of all
+ * components with their corresponding data bit = 1.
+ * Set cDefault to 0 if not used.
+ *
+ * common >---cDefault---.
+ * data&0x01 >-----c[0]-----+
+ * data&0x02 >-----c[1]-----+
+ * data&0x04 >-----c[2]-----+
+ * data&0x08 >-----c[3]-----+-----> netlist node
+ * data&0x10 >-----c[4]-----+
+ * data&0x20 >-----c[5]-----+
+ * data&0x40 >-----c[6]-----+
+ * data&0x80 >-----c[7]-----'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_COMP_ADDER(name of node,
+ * data node (static value is useless),
+ * address of discrete_comp_adder_table structure)
+ *
+ * discrete_comp_adder_table = {type, cDefault, length, c{}}
+ * note: length can be a maximum of 8
+ *
+ * Circuit Types:
+ * DISC_COMP_P_CAPACITOR - parallel capacitors
+ * DISC_COMP_P_RESISTOR - parallel resistors
+ *
+ * EXAMPLES: see Hit Me
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_DAC_R1 - R1 ladder DAC with cap smoothing and external bias
+ *
+ * rBias
+ * data&0x01 >--/\R[0]/\--+-----/\/\----< vBias
+ * data&0x02 >--/\R[1]/\--|
+ * data&0x04 >--/\R[2]/\--|
+ * data&0x08 >--/\R[3]/\--|
+ * data&0x10 >--/\R[4]/\--|
+ * data&0x20 >--/\R[5]/\--|
+ * data&0x40 >--/\R[6]/\--|
+ * data&0x80 >--/\R[7]/\--+-------------+-----> Netlist node
+ * | |
+ * Z ---
+ * Z rGnd --- cFilter
+ * | |
+ * gnd gnd
+ *
+ * NOTES: rBias and vBias are used together. If not needed they should
+ * be set to 0. If used, they should both have valid values.
+ * rGnd and cFilter should be 0 if not needed.
+ * A resistor value should be properly set for each resistor
+ * up to the ladder length. Remember 0 is a short circuit.
+ * The data node is bit mapped to the ladder. valid int 0-255.
+ * TTL logic 0 is actually 0.2V but 0V is used. The other parts
+ * have a tolerance that more then makes up for this.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_DAC_R1(name of node,
+ * data node (static value is useless),
+ * vData static value (voltage when a bit is on ),
+ * address of discrete_dac_r1_ladder structure)
+ *
+ * discrete_dac_r1_ladder = {ladderLength, r{}, vBias, rBias, rGnd, cFilter}
+ *
+ * Note: Resistors in the ladder that are set to 0, will be handled like they
+ * are out of circuit. So the bit selecting them will have no effect
+ * on the DAC output voltage.
+ *
+ * x_time - this modules automatically handles any non-integer value
+ * on the data input as x_time.
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug, Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_DIODE_MIXER - mixes inputs through diodes
+ *
+ *
+ * input 0 >----|>|---.
+ * |
+ * input 1 >----|>|---+----------> Netlist Node
+ * |
+ * input 2 >----|>|---+
+ * |
+ * input 3 >----|>|---+--/\/\/\--.
+ * |
+ * gnd
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_DIODE_MIXERx(name of node,
+ * (x = 2/3/4) input 0 node,
+ * input 1 node,
+ * ...,
+ * address of v_junction table)
+ *
+ * v_junction table can be set to NULL if you want all diodes to
+ * default to a 0.5V drop. Otherwise use a
+ * table of doubles to specify juntion voltages.
+ *
+ * EXAMPLES: see dkong
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_INTEGRATE - Various Integration circuits
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_INTEGRATE(name of node,
+ * trigger 0 node or static value,
+ * trigger 1 node or static value,
+ * address of discrete_integrate_info)
+ *
+ * discrete_integrate_info = {type, r1, r2, r3, c, v1, vP, f0, f1, f2}
+ *
+ * Note: Set all unused components to 0.
+ * These are all single supply circuits going from gnd(0V) to vP(B+),
+ * so be sure to specify the vP power source.
+ *
+ * Types:
+ *
+ * DISC_INTEGRATE_OP_AMP_1
+ *
+ * v1 >----+-------.
+ * | | c
+ * Z Z .---||----.
+ * Z r1 Z r2 | |
+ * Z Z | |\ |
+ * | | | | \ |
+ * +--------------+--|- \ |
+ * | | | >--+----> Netlist Node
+ * / +---------|+ /
+ * |/ | | /
+ * Trig0 >--| NPN Z |/
+ * |\ Z r3
+ * > Z
+ * | |
+ * gnd gnd
+ *
+ *
+ * EXAMPLES: see Tank8
+ *
+ * --------------------------------------------------
+ *
+ * DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON
+ *
+ * c
+ * .---||----.
+ * | |
+ * | |\ |
+ * r1 | | \ |
+ * v1 >----ZZZZ--------+--|- \ |
+ * | >--+----> Netlist Node
+ * r2 .--|+ /
+ * Trig0 >----ZZZZ--------' | /
+ * |/
+ *
+ * Note: Trig0 is voltage level, not logic.
+ * No functions are used so set them to 0, or DISC_OP_AMP_TRIGGER_FUNCTION_NONE.
+ * You can also use DISCRETE_OP_AMP with type DISC_OP_AMP_IS_NORTON to emulate this.
+ *
+ * EXAMPLES: see Double Play
+ *
+ * --------------------------------------------------
+ *
+ * DISC_INTEGRATE_OP_AMP_2 | DISC_OP_AMP_IS_NORTON
+ *
+ * c
+ * .---||----.
+ * r1a | |
+ * v1 >----ZZZZ---. | |\ |
+ * .----. | r1b Diode | | \ |
+ * | F0 |--+--ZZZZ----|>|--+--|- \ |
+ * '----' | >--+----> Netlist Node
+ * r2a r2b .--|+ /
+ * v1 >----ZZZZ---+--ZZZZ---------+ | /
+ * .----. | | |/
+ * | F1 |--' |
+ * '----' |
+ * r3a r3b Diode |
+ * v1 >----ZZZZ---+--ZZZZ----|>|--'
+ * .----. |
+ * | F2 |--'
+ * '----'
+ *
+ * Note: For an explanation of the functions and trigger inputs,
+ * see DISCRETE_OP_AMP_TRIG_VCA below.
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_MIXER - Mixes multiple input signals.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_MIXERx(name of node,
+ * (x = 2 to 8) enable node or static value,
+ * input 0 node,
+ * input 1 node,
+ * input 2 node, (if used)
+ * input 3 node, (if used)
+ * input 4 node, (if used)
+ * input 5 node, (if used)
+ * input 6 node, (if used)
+ * input 7 node, (if used)
+ * address of discrete_mixer_info structure)
+ *
+ * discrete_mixer_desc = {type, r{}, r_node{}, c{}, rI, rF, cF, cAmp, vRef, gain}
+ *
+ * Note: Set all unused components to 0.
+ * If an rNode is not used it should also be set to 0.
+ *
+ * Types:
+ *
+ * DISC_MIXER_IS_RESISTOR
+ *
+ * rNode[0] r[0] c[0]
+ * IN0 >--zzzz-----zzzz----||---.
+ * |
+ * rNode[1] r[1] c[1] |
+ * IN1 >--zzzz-----zzzz----||---+--------.
+ * . . . . | | cAmp
+ * . . . . | Z<------||---------> Netlist Node
+ * . . . . | Z
+ * . rNode[7] r[7] c[7] | Z rF
+ * IN7 >--zzzz-----zzzz----||---+ |
+ * | |
+ * --- |
+ * cF --- |
+ * | |
+ * gnd gnd
+ *
+ * Note: The variable resistor is used in it's full volume position.
+ * MAME's built in volume is used for adjustment.
+ *
+ * EXAMPLES: see Polaris, Super Bug
+ *
+ * --------------------------------------------------
+ *
+ * DISC_MIXER_IS_OP_AMP
+ *
+ * cF
+ * .----||---.
+ * | |
+ * rNode[0] r[0] c[0] | rF |
+ * IN0 >--zzzz------zzzz----||---. +---ZZZZ--+
+ * | | |
+ * rNode[1] r[1] c[1] | rI | |\ |
+ * IN1 >--zzzz------zzzz----||---+--zzzz--+ | \ |
+ * . . . . | '--|- \ | cAmp
+ * . . . . | | >--+---||-----> Netlist Node
+ * . . . . | .--|+ /
+ * . rNode[7] r[7] c[7] | | | /
+ * IN7 >--zzzz------zzzz----||---' | |/
+ * |
+ * vRef >----------------------------------'
+ *
+ * Note: rI is not always used and should then be 0.
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP - Various op-amp circuits
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP(name of node,
+ * enable node or static value,
+ * input 0 node or static value,
+ * input 1 node or static value,
+ * address of discrete_op_amp_info structure)
+ *
+ * discrete_op_amp_info = {type, r1, r2, r3, r4, c, vN, vP}
+ *
+ * Note: Set all unused components to 0.
+ *
+ * Types:
+ *
+ * DISC_OP_AMP_IS_NORTON
+ *
+ * c
+ * .----||---.
+ * | |
+ * r3 | r4 | vP = B+
+ * vP >---ZZZZ------+---ZZZZ--+ vN = B-
+ * | |
+ * r1 | |\ | Note: r2 must always be used
+ * IN0 >---ZZZZ------+ | \ |
+ * '--|- \ |
+ * r2 | >--+-----> Netlist Node
+ * IN1 >---ZZZZ---------|+ /
+ * | /
+ * |/
+ *
+ * EXAMPLES: see Space Encounter
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP_ONESHOT - Various op-amp one shot circuits
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP_ONESHOT(name of node,
+ * trigger node (voltage level),
+ * address of discrete_op_amp_1sht_info structure)
+ *
+ * discrete_op_amp_1sht_info = {type, r1, r2, r3, r4, r5, c1, c2, vN, vP}
+ *
+ * Types:
+ *
+ * DISC_OP_AMP_1SHT_1 | DISC_OP_AMP_IS_NORTON
+ *
+ * c1 .---|>|---.
+ * gnd >----||---+---+ |
+ * | | r4 | vP = B+
+ * Z '---ZZZZ--+ vN = B-
+ * Z r3 |
+ * Z |\ | Note: all components must be used
+ * r1 | | \ | The oneshot is cancelled when TRIG goes low
+ * vP >---ZZZZ--+------|- \ |
+ * | >--+-----> Netlist Node
+ * c2 r2 .--|+ / |
+ * TRIG >--||---ZZZZ--+ | / |
+ * | |/ |
+ * | r5 |
+ * '---ZZZZ--'
+ *
+ *
+ * EXAMPLES: see Space Encounter
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP_TRIG_VCA - Triggered Norton op amp voltage controlled amplifier.
+ * This means the cap is rapidly charged through r5 when F2=1.
+ * Then it discharges through r6+r7 when F2=0.
+ * This voltage controls the amplitude.
+ * While the diagram looks complex, usually only parts of it are used.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP_TRIG_VCA(name of node,
+ * trigger 0 node or static value,
+ * trigger 1 node or static value,
+ * trigger 2 node or static value,
+ * input 0 node or static value,
+ * input 1 node or static value,
+ * address of discrete_op_amp_tvca_info structure)
+ *
+ * discrete_op_amp_tvca_info = { r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, c1, c2, c3, c4, v1, v2, v3, vP, f0, f1, f2, f3, f4, f5}
+ *
+ * Note: Set all unused components to 0.
+ * Set all unused functions to DISC_OP_AMP_TRIGGER_FUNCTION_NONE
+ * Set all unused nodes to NODE_NC.
+ * If function F3 is not used then set r6=0 and use only r7.
+ * r2 = r2a + r2b. r3 = r3a + r3b.
+ * vP is the op-amp B+.
+ *
+ * r2a
+ * IN0 >----ZZZZ-----. r1 c4
+ * .----. | vP >------ZZZZ---+---||----.
+ * | F0 |----+ | |
+ * '----' | r2b | r4 |
+ * r3a '---------------ZZZZ---+---ZZZZ--+
+ * IN1 >----ZZZZ---. | |
+ * .----. | r3b | |\ |
+ * | F1 |--+-----------------ZZZZ---+ | \ |
+ * '----' '--|- \ |
+ * .----. diode r6 r7 | >--+----> Netlist Node
+ * | F2 |--+--|>|--+--ZZZZ---+--ZZZZ-+-|+ /
+ * '----' | | | | | /
+ * | --- .----. | |/
+ * r5 | --- c1 | F3 | |
+ * v1 >----ZZZZ---' | '----' |
+ * gnd |
+ * |
+ * .----. diode r9 |
+ * | F4 |--+--|>|-----------+---ZZZZ-+
+ * '----' | c2 | |
+ * r8 | gnd >---||---' |
+ * v2 >----ZZZZ---' |
+ * .----. diode r11 |
+ * | F5 |--+--|>|-----------+---ZZZZ-'
+ * '----' | c3 |
+ * r10 | gnd >---||---'
+ * v3 >----ZZZZ---'
+ *
+ * Function types:
+ *
+ * Trigger 0, 1 and 2 are used for the functions F0 - F5.
+ * When the output of the function is 0, then the connection is held at 0V or gnd.
+ * When the output of the function is 1, then the function is an open circuit.
+ *
+ * DISC_OP_AMP_TRIGGER_FUNCTION_NONE - Not used, cicuit open.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG0 - Gnd when trigger 0 is 0.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG0_INV - Gnd when trigger 0 is 1.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG1 - Gnd when trigger 1 is 0.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG1_INV - Gnd when trigger 1 is 1.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG2 - Gnd when trigger 2 is 0.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG2_INV - Gnd when trigger 2 is 1.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG01_AND - Gnd when trigger 0 or 1 are 0.
+ * DISC_OP_AMP_TRIGGER_FUNCTION_TRG01_NAND - Gnd when trigger 0 and 1 are 1.
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_flt.c
+ * Generic modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_FILTER1
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_FILTER1(name of node,
+ * enable node or static value,
+ * input node,
+ * filter center frequency static value,
+ * filter type static value)
+ *
+ * Filter types: DISC_FILTER_LOWPASS,
+ * DISC_FILTER_HIGHPASS
+ * DISC_FILTER_BANDPASS
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_FILTER2
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_FILTER2(name of node,
+ * enable node or static value,
+ * input node,
+ * filter center frequency static value,
+ * damp static value,
+ * filter type static value)
+ *
+ * Filter types: DISC_FILTER_LOWPASS,
+ * DISC_FILTER_HIGHPASS
+ * DISC_FILTER_BANDPASS
+ *
+ * Note: Damp = 1/Q
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_flt.c
+ * Component specific modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_CRFILTER - Simple single pole CR filter network (vRef = 0)
+ * DISCRETE_CRFILTER_VREF - Same but referenced to vRef not 0V
+ *
+ * .------------.
+ * | |
+ * | CR FILTER |
+ * | |
+ * INPUT1 -0------}| --| |-+-- |
+ * | C | |----} Netlist node
+ * RVAL -1------}| Z |
+ * | Z R |
+ * CVAL -2------}| | |
+ * | vRef |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_CRFILTER(name of node,
+ * input node (or value)
+ * resistor node or static value in OHMS
+ * capacitor node or static value in FARADS)
+ *
+ * DISCRETE_CRFILTER_VREF(name of node,
+ * input node (or value)
+ * resistor value in OHMS
+ * capacitor value in FARADS,
+ * vRef node or static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_CRFILTER(NODE_11,NODE_10,100,CAP_U(1))
+ *
+ * Defines a CR filter with a 100R & 1uF network
+ * the input is fed from NODE_10.
+ *
+ * This can be also thought of as a high pass filter with a 3dB cutoff
+ * at:
+ * 1
+ * Fcuttoff = --------------
+ * 2*Pi*RVAL*CVAL
+ *
+ * (3dB cutoff is where the output power has dropped by 3dB ie Half)
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_OP_AMP_FILTER - Various Op Amp Filters.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OP_AMP_FILTER(name of node,
+ * enable node or static value,
+ * input 1 node or static value,
+ * input 2 node or static value,
+ * type static value,
+ * address of discrete_op_amp_filt_info)
+ *
+ * discrete_op_amp_filt_info = {r1, r2, r3, r4, rF, c1, c2, c3, vRef, vP, vN}
+ *
+ * Note: Set all unused components to 0.
+ * vP and vN are the +/- op-amp power supplies.
+ * vRef is 0 if Gnd.
+ *
+ * Types:
+ *
+ * DISC_OP_AMP_FILTER_IS_LOW_PASS_1
+ * First Order Low Pass Filter
+ *
+ * c1
+ * .-------||---------.
+ * | |
+ * r1 | rF |
+ * IN0 >--ZZZZ--. +------ZZZZ--------+
+ * | | |
+ * r2 | | |\ |
+ * IN1 >--ZZZZ--+------+--------+ | \ |
+ * | '--|- \ |
+ * r3 | | >--+----------> Netlist Node
+ * vRef >--ZZZZ--' .--|+ /
+ * | | /
+ * vRef >-----------------------' |/
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_LOW_PASS_1_A
+ * First Order Low Pass Filter
+ *
+ * c1
+ * .-------||---------.
+ * | |
+ * r1 | rF |
+ * IN0 >--ZZZZ--. +------ZZZZ--------+
+ * | | |
+ * r2 | | |\ |
+ * VP >--ZZZZ--+------+--------+ | \ |
+ * | '--|- \ |
+ * r3 | | >--+----------> Netlist Node
+ * VN >--ZZZZ--' .--|+ /
+ * | | /
+ * IN1 >------------------------' |/
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_HIGH_PASS_1
+ * First Order High Pass Filter
+ *
+ * r1 rF
+ * IN0 >--ZZZZ--. .------ZZZZ--------.
+ * | | |
+ * r2 | c1 | |\ |
+ * IN1 >--ZZZZ--+--||--+--------+ | \ |
+ * | '--|- \ |
+ * r3 | | >--+----------> Netlist Node
+ * vRef >--ZZZZ--' .--|+ /
+ * | | /
+ * vRef >-----------------------' |/
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_BAND_PASS_1
+ * First Order Band Pass Filter
+ *
+ * c1
+ * .-------||---------.
+ * | |
+ * r1 | rF |
+ * IN0 >--ZZZZ--. +------ZZZZ--------+
+ * | | |
+ * r2 | c2 | |\ |
+ * IN1 >--ZZZZ--+--||--+--------+ | \ |
+ * | '--|- \ |
+ * r3 | | >--+----------> Netlist Node
+ * vRef >--ZZZZ--' .--|+ /
+ * | | /
+ * vRef >-----------------------' |/
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_BAND_PASS_1M
+ * Single Pole Multiple Feedback Band Pass Filter
+ *
+ * c1
+ * .--||----+---------.
+ * | | |
+ * r1 | Z |
+ * IN0 >--ZZZZ--. | Z rF |
+ * | | Z |
+ * r2 | | c2 | |\ |
+ * IN1 >--ZZZZ--+------+--||----+ | \ |
+ * | '--|- \ |
+ * r3 | | >--+----------> Netlist Node
+ * vRef >--ZZZZ--' .--|+ /
+ * | | /
+ * vRef >-----------------------' |/
+ *
+ * EXAMPLES: see Tank 8, Atari Baseball, Monte Carlo
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON
+ * Single Pole Multiple Feedback Band Pass Filter
+ *
+ * c1
+ * .--||----+---------.
+ * | | |
+ * | Z |
+ * | Z rF |
+ * | Z |
+ * r1 | c2 | |\ |
+ * IN0 >--ZZZZ--+------+--||----+ | \ |
+ * | '--|- \ |
+ * r2 | | >--+----------> Netlist Node
+ * vRef >--ZZZZ--' .--|+ /
+ * r3 | | /
+ * vP >-----------ZZZZ--------' |/
+ *
+ * EXAMPLES: see Space Encounter
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_HIGH_PASS_0 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton High Pass Filter
+ *
+ * rF
+ * r1 = r1a + r1b .--ZZZZ---.
+ * | |
+ * r1a c1 r1b | |\ |
+ * IN1 >--ZZZZ---||---ZZZZ------+ | \ |
+ * '--|- \ |
+ * | >--+----------> Netlist Node
+ * .--|+ /
+ * r4 | | /
+ * vRef >------------ZZZZ-------' |/
+ *
+ * EXAMPLES: see Polaris
+ *
+ * --------------------------------------------------
+ *
+ * DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON
+ * Basic Norton Band Pass Filter
+ *
+ * rF
+ * r3 = r3a + r3b .--ZZZZ---.
+ * | |
+ * r1 r2 r3a c3 r3b | |\ |
+ * IN1 >---ZZZZ--+--ZZZZ--+--ZZZZ---||----ZZZZ---+ | \ |
+ * | | '--|- \ |
+ * --- --- | >--+---> Netlist Node
+ * --- c1 --- c2 .--|+ /
+ * | | | | /
+ * gnd gnd | |/
+ * r4 |
+ * vRef >--------------------------------ZZZZ----'
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_SALLEN_KEY_FILTER - Sallen key low pass filter
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_SALLEN_KEY_FILTER(name of node,
+ * enable node or static value,
+ * input node or static value,
+ * type static value,
+ * address of discrete_op_amp_filt_info)
+ *
+ * discrete_op_amp_filt_info = {r1, r2, r3, r4, rF, c1, c2, c3, vRef, vP, vN}
+ *
+ * Note: Set all unused components to 0.
+ *
+ * Types:
+ *
+ * DISC_SALLEN_KEY_LOWPASS
+ *
+ * .---------.
+ * | |
+ * | |\ |
+ * | | \ |
+ * `--|- \ |
+ * R1 R2 | >--+----> Netlist Node
+ * IN >---ZZZZ--+--ZZZZ--+------|+ / |
+ * | | | / |
+ * --- --- |/ |
+ * --- C1 --- C2 |
+ * | | |
+ * | gnd |
+ * | |
+ * `----------------------'
+ *
+ * EXAMPLES: see moon patrol, dkong
+ *
+ * References:
+ * http://www.t-linespeakers.org/tech/filters/Sallen-Key.html
+ * http://en.wikipedia.org/wiki/Sallen_Key_filter
+ ***********************************************************************
+ *
+ * DISCRETE_RC_CIRCUIT_1 - RC charge/discharge circuit
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RC_CIRCUIT_1(name of node,
+ * In0 (Logic) node,
+ * In1 (Logic) node,
+ * R static value,
+ * C static value)
+ *
+ * 5V
+ * v
+ * |
+ * .-------.
+ * | 4066 |
+ * In0 >---|c |
+ * '-------'
+ * |
+ * +------------.
+ * | |
+ * .-------. --- C
+ * | 4066 | ---
+ * In1 >---|c | |
+ * '-------' gnd
+ * |
+ * +----> Node Output
+ * |
+ * Z
+ * Z R
+ * Z
+ * |
+ * gnd
+ *
+ * EXAMPLES: see Sky Raider, Battlezone
+ *
+ ************************************************************************
+ *
+ * DISCRETE_RCDISC - Simple single pole RC discharge network
+ *
+ * .------------.
+ * | |
+ * | RC |
+ * | |
+ * INPUT1 -0------>| -ZZZZ-+-- |
+ * | R | |----> Netlist node
+ * RVAL -1------>| --- |
+ * | ---C |
+ * CVAL -2------>| | |
+ * | vref |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCFILTER(name of node,
+ * input node (or value),
+ * resistor value in OHMS,
+ * capacitor value in FARADS)
+ *
+ * Example config line
+ *
+ * DISCRETE_RCDISC(NODE_11,10,100,CAP_U(1))
+ *
+ * C discharges from 10v as indicated by RC of 100R & 1uF.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCDISC2 - Switched input RC discharge network
+ *
+ * .------------.
+ * | |
+ * SWITCH -0------>| IP0 | IP1 |
+ * | |
+ * INPUT0 -1------>| -ZZZZ-. |
+ * | R0 | |
+ * RVAL0 -2------>| | |
+ * | | |
+ * INPUT1 -3------>| -ZZZZ-+-- |
+ * | R1 | |----> Netlist node
+ * RVAL1 -4------>| --- |
+ * | ---C |
+ * CVAL -5------>| | |
+ * | |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCDISC2(name of node,
+ * switch,
+ * input0 node (or value),
+ * resistor0 value in OHMS,
+ * input1 node (or value),
+ * resistor1 value in OHMS,
+ * capacitor value in FARADS)
+ *
+ * Example config line
+ *
+ * DISCRETE_RCDISC2(NODE_9,NODE_10,10.0,100,0.0,100,CAP_U(1))
+ *
+ * When switched by NODE_10, C charges/discharges from 10v/0v
+ * as dictated by R0/C & R1/C combos respectively
+ * of 100R & 1uF.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCDISC3 - RC discharge network
+ *
+ * FIXME: Diode direction (for bzone)
+ *
+ * .-----------------.
+ * | |
+ * ENAB -0------>| |
+ * | diode R2 |
+ * JV -5------>| -+-|>|--ZZZZ-+- |----> Netlist node (JV < 0)
+ * | |
+ * | diode R2 |
+ * INPUT1 -1------>| -+-|<|--ZZZZ-+- |----> Netlist node (JV > 0)
+ * | | | |
+ * RVAL1 -2------>| '-ZZZZ-+----' |
+ * | R1 | |
+ * RVAL2 -3------>| --- |
+ * | ---C |
+ * CVAL -4------>| | |
+ * | gnd |
+ * '-----------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCDISC3(name of node,
+ * enable,
+ * input node (or value),
+ * R1 resistor value in OHMS,
+ * R2 resistor value in OHMS,
+ * capacitor value in FARADS,
+ * diode junction voltage)
+ *
+ * The polarity of the diode junction voltage determines the polarity of the diode.
+ *
+ * Example config line
+ *
+ * DISCRETE_RCDISC3(NODE_11,NODE_10,10,100,220,CAP_U(1), 0.5)
+ *
+ * When enabled by NODE_10, C charges from 10v as indicated by RC
+ * of 100R & 1uF.
+ *
+ * EXAMPLES: see Tank8, bzone
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCDISC4 - RC discharge networks triggered by logic levels
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCDISC4(name of node,
+ * enable,
+ * logic input node,
+ * R1 resistor static value in OHMS,
+ * R2 resistor static value in OHMS,
+ * R3 resistor static value in OHMS,
+ * C1 capacitor static value in FARADS,
+ * vP static value in VOLTS,
+ * circuit type static value)
+ *
+ * Type: 1
+ *
+ * vP >---.
+ * | .------.
+ * Z | |
+ * Z R2 | |\ |
+ * O.C. Z '-|-\ |
+ * |\ Diode R1 | | >-+---> node
+ * Input >---| o----|<|------ZZZZ---+--------+-------|+/
+ * |/ | | |/
+ * --- -----
+ * C1 --- \ / Diode
+ * | V
+ * gnd ---
+ * |
+ * Z
+ * Z R3
+ * Z
+ * |
+ * gnd
+ *
+ * EXAMPLES: see Phoenix
+ *
+ * --------------------------------------------------
+ *
+ * Type: 2
+ *
+ * 5V >---. .------.
+ * Z | |
+ * Z 1k | |\ |
+ * Z '-|-\ |
+ * | R1 C1 Diode | >-+---> node
+ * Input >---+--ZZZZ----||----+-----|>|----+--------|+/
+ * | | |/
+ * ----- Z
+ * ^ Z R2
+ * / \ Diode Z
+ * ----- |
+ * | gnd
+ * gnd
+ *
+ * EXAMPLES: see
+ *
+ * --------------------------------------------------
+ *
+ * Type: 3
+ *
+ * 5V >---. .------.
+ * Z | |
+ * Z 1k | |\ |
+ * Z '-|-\ |
+ * | R1 Diode | >-+---> node
+ * Input >---+--ZZZZ-----|>|------+---------+--------|+/
+ * | | |/
+ * --- C1 Z
+ * --- Z R2
+ * | Z
+ * gnd |
+ * gnd
+ *
+ *
+ * EXAMPLES: see
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCDISC5 - Diode in series with R//C
+ *
+ * .---------------------.
+ * | |
+ * ENAB -0------>| -----------. |
+ * | -- |
+ * INPUT1 -1------>| -|>|--+--|SW|---+- |----> Netlist node
+ * | | -- | |
+ * RVAL -2------>| --- Z |
+ * | C--- Z R |
+ * CVAL -3------>| | Z |
+ * | -----+----- |
+ * | |gnd |
+ * '---------------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCDISC5(name of node,
+ * enable,
+ * input node (or value),
+ * resistor value in OHMS,
+ * capacitor value in FARADS)
+ *
+ * Example config line
+ *
+ * DISCRETE_RCDISC5(NODE_11,NODE_10,10,100,CAP_U(1))
+ *
+ * When enabled by NODE_10, C discharges from 10v as indicated by RC
+ * of 100R & 1uF. If not enabled, the capcitors keeps it load and may
+ * still be charged through input1. The switch is assumed to be a CD4066,
+ * thus if not enabled the output will be drawn by R to GND since
+ * the switch is in high impedance mode.
+ *
+ * EXAMPLES: see Spiders, Galaxian
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCDISC_MODULATED - RC triggered by logic and modulated
+ *
+ * vP >---.
+ * |
+ * Z
+ * Z R1
+ * O.C. Z
+ * |\ | R2 C1 R3
+ * INPUT1 >---| o---+--ZZZ---||------+----+---ZZZ------+---> node
+ * |/ | | /
+ * / \ Z |/
+ * Diode ----- Z R4 .---| NPN
+ * | Z | |\
+ * | | | >
+ * gnd gnd | |
+ * | gnd
+ * INPUT2 >----------ZZZ------------------------.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCDISC_MODULATED(name of node,
+ * INPUT1 node (or value),
+ * INPUT2 node (or value),
+ * R1 value in OHMS (static value),
+ * R2 value in OHMS (static value),
+ * R3 value in OHMS (static value),
+ * R4 value in OHMS (static value),
+ * C1 value in FARADS (static value),
+ * vP value in VOLTS)
+ *
+ * EXAMPLES: dkong
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCFILTER - Simple single pole RC filter network (vRef = 0)
+ * DISCRETE_RCFILTER_VREF - Same but referenced to vRef not 0V
+ *
+ * .------------.
+ * | |
+ * ENAB -0------}| RC FILTER |
+ * | |
+ * INPUT1 -1------}| -ZZZZ-+-- |
+ * | R | |----} Netlist node
+ * RVAL -2------}| --- |
+ * | ---C |
+ * CVAL -3------}| | |
+ * | vRef |
+ * '------------'
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCFILTER(name of node,
+ * enable
+ * input node (or value)
+ * resistor value in OHMS
+ * capacitor value in FARADS)
+ *
+ * DISCRETE_RCFILTER_VREF(name of node,
+ * enable
+ * input node (or value)
+ * resistor value in OHMS
+ * capacitor value in FARADS,
+ * vRef static value)
+ *
+ * Example config line
+ *
+ * DISCRETE_RCFILTER(NODE_11,1,NODE_10,100,CAP_U(1))
+ *
+ * Defines an always enabled RC filter with a 100R & 1uF network
+ * the input is fed from NODE_10.
+ *
+ * This can be also thought of as a low pass filter with a 3dB cutoff
+ * at:
+ * 1
+ * Fcuttoff = --------------
+ * 2*Pi*RVAL*CVAL
+ *
+ * (3dB cutoff is where the output power has dropped by 3dB ie Half)
+ *
+ * EXAMPLES: see Polaris
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCFILTER_SW - Multiple switchable RC filters
+ *
+ * R
+ * INPUT >-----------ZZZZ-+-------+----......-----> Output
+ * | |
+ * +-+ +-+
+ * SWITCH > Bit 0 ---->F1 | | F2 | |
+ * '-' ^ '-'
+ * Bit 1 ---------|----' |
+ * | |
+ * Bit ... --- ---
+ * --- C1 --- C2
+ * | |
+ * GND GND
+ *
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCFILTER_SW(name of node,
+ * enable,
+ * input node (or value),
+ * switch node (or value),
+ * R in Ohms (static value),
+ * C1 in Farads (static value),
+ * C2 in Farads (static value),
+ * C3 in Farads (static value),
+ * C4 in Farads (static value))
+ *
+ * This is a typical filter circuit in circusc or scramble.
+ * Switches are usually CD4066 with a "open" resistance of
+ * typical 470 Ohms at 5V.
+ * This circuit supports up to 4 filters.
+ *
+ * EXAMPLES: see circusc
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_RCINTEGRATE - RC integration circuit/amplifier
+ *
+ *
+ * vP >-------------------+
+ * |
+ * Z
+ * Z R3
+ * Z
+ * |
+ * +-----------------> node (Type 3)
+ * /
+ * |/
+ * INPUT >---------------| NPN
+ * \ .--------------> node (Type 2)
+ * > | R1
+ * +--+--ZZZ-+-------> node (Type 1)
+ * | |
+ * Z ---
+ * Z R2 C---
+ * Z |
+ * | |
+ * gnd gnd
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_RCINTEGRATE(name of node,
+ * INPUT node (or value),
+ * R1 value in OHMS,
+ * R2 value in OHMS,
+ * R3 value in OHMS,
+ * C value in FARADS,
+ * vP node (or value in VOLTS)
+ * TYPE)
+ *
+ * TYPE: RC_INTEGRATE_TYPE1, RC_INTEGRATE_TYPE2, RC_INTEGRATE_TYPE3
+ *
+ * Actually an amplifier as well. Primary reason for implementation was integration.
+ * The integration configuration (TYPE3, R3=0) works quite well, the amplifying
+ * configuration is missing a good, yet simple ( :-) ) transistor model. Around the
+ * defined working point the amplifier delivers results.
+ *
+ * EXAMPLES: dkong
+ *
+ *
+ ***********************************************************************
+ =======================================================================
+ * from from disc_dev.c
+ * Component specific modules
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_555_ASTABLE - NE555 Chip simulation (astable mode).
+ * DISCRETE_555_ASTABLE_CV - NE555 Chip simulation (astable mode) with CV control.
+ *
+ * v_charge v_pos
+ * V V
+ * | |
+ * | |
+ * | |
+ * Z |8
+ * _FAST_CHARGE_DIODE R1 Z .---------.
+ * (optional) | 7| Vcc |
+ * +---------> +-----|Discharge|
+ * | | | |
+ * --- Z | 555 |3
+ * \ / R2 Z | Out|---> Netlist Node
+ * V | 6| |
+ * --- +-----|Threshold|
+ * | | | |
+ * +---------> +-----|Trigger |
+ * | 2| |---< Control Voltage
+ * | | Reset |5
+ * | '---------'
+ * --- 4|
+ * C --- |
+ * | ^
+ * gnd Reset
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_555_ASTABLE(name of node,
+ * reset node (or value),
+ * R1 node (or value) in ohms,
+ * R2 node (or value) in ohms,
+ * C node (or value) in farads,
+ * address of discrete_555_desc structure)
+ *
+ * DISCRETE_555_ASTABLE_CV(name of node,
+ * reset node (or value),
+ * R1 node (or value) in ohms,
+ * R2 node (or value) in ohms,
+ * C node (or value) in farads,
+ * Control Voltage node (or value),
+ * address of discrete_555_desc structure)
+ *
+ * discrete_555_desc =
+ * {
+ * options, - bit mapped options
+ * v_pos, - B+ voltage of 555
+ * v_charge, - voltage (or node) to charge circuit (Defaults to v_pos)
+ * v_out_high - High output voltage of 555 (Defaults to v_pos - 1.2V)
+ * }
+ *
+ * The last 2 options of discrete_555_desc can use the following defaults:
+ * DEFAULT_555_CHARGE - to connect v_charge to v_pos
+ * DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
+ * or combine both as:
+ * DEFAULT_555_VALUES
+ *
+ * eg. {DISC_555_OUT_SQW | DISC_555_OUT_DC, 12, DEFAULT_555_VALUES}
+ *
+ * Output Types: (only needed with DISC_555_OUT_SQW, DISC_555_OUT_CAP
+ * and DISC_555_OUT_ENERGY)
+ * DISC_555_OUT_DC - Output is actual DC. (DEFAULT)
+ * DISC_555_OUT_AC - A cheat to make the waveform AC.
+ *
+ * Waveform Types: (ORed with output types)
+ * DISC_555_OUT_SQW - Output is Squarewave. 0 or v_out_high. (DEFAULT)
+ * When the state changes from low to high (or high to low)
+ * during a sample, the output will high (or low) for that
+ * sample. This can cause alaising effects.
+ * DISC_555_OUT_CAP - Output is Timing Capacitor 'C' voltage.
+ * DISC_555_OUT_COUNT_F - If the 555 frequency is greater then half the sample
+ * rate, then the output may change state more then once
+ * during the sample. Using this flag will cause
+ * the output to be the number of falling edges that
+ * happened during the sample. This is usefull to feed
+ * to counter circuits. The Output Type flag is ingnored
+ * when this flag is used.
+ * DISC_555_OUT_COUNT_R - Same as DISC_555_OUT_COUNT_F but with rising edges.
+ * DISC_555_OUT_ENERGY - Same SQW, but will help reduce aliasing effects.
+ * This should be used when the 555 squarewave output is used
+ * as a final output and not as a clock source.
+ * If the state changes from low to high 1/4 of the way
+ * through the sample, then the output will be 75% of the
+ * normal high value.
+ * DISC_555_OUT_LOGIC_X - This will output the 0/1 level of the flip-flop with
+ * some eXtra info. This x_time is in decimal remainder.
+ * It lets you know the percent of sample time where the
+ * flip-flop changed state. If 0, the change did not happen
+ * during the sample. 1.75 means the flip-flop is 1 and
+ * switched over 1/4 of the way through the sample.
+ * 0.2 means the flip-flop is 0 and switched over 4/5 of
+ * the way through the sample.
+ * X modules can be used with counters to reduce alaising.
+ * DISC_555_OUT_COUNT_F_X - Same as DISC_555_OUT_COUNT_F but with x_time.
+ * DISC_555_OUT_COUNT_R_X - Same as DISC_555_OUT_COUNT_R but with x_time.
+ *
+ * other options - DISCRETE_555_ASTABLE only:
+ * DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE - diode used to bypass rDischarge
+ * when charging for quicker charge.
+ *
+ * EXAMPLES: see Hit Me, Canyon Bomber, Sky Diver
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_555_MSTABLE - NE555 Chip simulation (monostable mode)
+ * - Triggered on falling edge.
+ *
+ * v_charge v_pos
+ * V V
+ * | |
+ * | |
+ * | |
+ * Z |
+ * R Z .---------.
+ * | | Vcc |
+ * +-----|Discharge|
+ * | | |
+ * | | 555 |
+ * | | Out|---> Netlist Node
+ * | | |
+ * +-----|Threshold|
+ * | | |
+ * | | Trigger|--------< Trigger
+ * | | CV|---.
+ * | | Reset | |
+ * | '---------' --- not
+ * --- | --- needed
+ * C --- | |
+ * | ^ gnd
+ * gnd Reset
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_555_MSTABLE(name of node,
+ * reset node (or value),
+ * Trigger node,
+ * R node (or value) in ohms,
+ * C node (or value) in farads,
+ * address of discrete_555_desc structure)
+ *
+ * discrete_555_desc = See DISCRETE_555_ASTABLE for description.
+ * Note: v_charge can not be a node for this circuit.
+ *
+ * Trigger Types
+ * DISC_555_TRIGGER_IS_LOGIC - Input is (0 or !0) logic (DEFAULT)
+ * DISC_555_TRIGGER_IS_VOLTAGE - Input is actual voltage.
+ * Voltage must drop below
+ * trigger to activate.
+ * DISC_555_TRIGGER_IS_COUNT - 1 when trigger, allows passing of x_time.
+ * Mainly connected with other module using
+ * a xxx_COUNT_F_X type.
+ * DISC_555_TRIGGER_DISCHARGES_CAP - some circuits connect an external
+ * device (transistor) to the cap to
+ * discharge it when the trigger is
+ * enabled. Thereby allowing the one-shot
+ * to retrigger.
+ *
+ * Output Types: (ORed with trigger types)
+ * DISC_555_OUT_DC - Output is actual DC. (DEFAULT)
+ * DISC_555_OUT_AC - A cheat to make the waveform AC.
+ *
+ * Waveform Types: (ORed with trigger types)
+ * DISC_555_OUT_SQW - Output is Squarewave. 0 or v_out_high. (DEFAULT)
+ * DISC_555_OUT_CAP - Output is Timing Capacitor 'C' voltage.
+ * DISC_555_OUT_ENERGY - see DISCRETE_555_MSTABLE.
+ *
+ * EXAMPLES: see Frogs, Sprint 8
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_555_CC - Constant Current Controlled 555 Oscillator
+ * Which works out to a VCO when R is fixed.
+ *
+ * v_cc_source v_pos
+ * V V
+ * | .----------------------+
+ * | | |
+ * | | .---------.
+ * | | rDischarge | Vcc |
+ * Z Z .---+-----|Discharge|
+ * Z R Z rBias | | | |
+ * | | | Z | 555 |
+ * | | | Z | Out|---> Netlist Node
+ * .----. | >-' | | |
+ * Vin >--| CC |--+--> option +-----|Threshold|
+ * '----' >-----+ | |
+ * +-----|Trigger |
+ * | | |
+ * .------+-----' | Reset |
+ * | | '---------'
+ * --- Z |
+ * --- C Z rGnd |
+ * | | ^
+ * gnd gnd Reset
+ *
+ * Notes: R sets the current and should NEVER be 0 (short).
+ * The current follows the voltage I=Vin/R and charges C.
+ * rBias, rDischarge and rGnd should be 0 if not used.
+ * Reset is active low for the module.
+ *
+ * Note that the CC source can be connected two different ways.
+ * See the option flags below for more info.
+ *
+ * DISC_555_OUT_SQW mode only:
+ * When there is no rDischarge there is a very short discharge
+ * cycle (almost 0s), so the module triggers the output for 1
+ * sample. This does not effect the timing, just the duty cycle.
+ * But frequencies more the half the sample frequency will be
+ * limited to a max of half the sample frequency.
+ * This mode should be used to drive a counter for any real use.
+ * Just like the real thing.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_555_CC(name of node,
+ * reset node or static value,
+ * Vin node or static value,
+ * R node or static value,
+ * C node or static value,
+ * rBias node or static value,
+ * rGnd node or static value,
+ * rDischarge node or static value,
+ * address of discrete_555_cc_desc structure)
+ *
+ * discrete_555_cc_desc =
+ * {
+ * options; - bit mapped options
+ * v_pos; - B+ voltage of 555
+ * v_cc_source; - Voltage of the Constant Current source
+ * v_out_high; - High output voltage of 555 (Defaults to v_pos - 1.2V)
+ * v_cc_junction; - The voltage drop of the Constant Current source transitor
+ * (0 if Op Amp)
+ * }
+ *
+ * The last 2 options of discrete_555_desc can use the following defaults:
+ * DEFAULT_555_CC_SOURCE - to connect v_cc_source to v_pos
+ * DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
+ * or combine both as:
+ * DEFAULT_555_VALUES
+ *
+ * Output Types:
+ * See DISCRETE_555_ASTABLE for description.
+ *
+ * Waveform Types: (ORed with output types)
+ * See DISCRETE_555_ASTABLE for description.
+ *
+ * Other Flags:
+ * DISCRETE_555_CC_TO_DISCHARGE_PIN - The CC source connects to the
+ * discharge pin. (Default)
+ * DISCRETE_555_CC_TO_CAP - The CC source connects to the
+ * threshold pin. This is not fully
+ * implemented yet. It only works properly
+ * when only rDischarge is defined.
+ *
+ * EXAMPLES: see Fire Truck, Monte Carlo, Super Bug
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_555_VCO1 - Op-Amp based 555 VCO circuit.
+ * DISCRETE_555_VCO1_CV - Op-Amp based 555 VCO circuit with CV control.
+ *
+ * c
+ * .------------------------+---||----+---------------------------> DISC_555_OUT_CAP
+ * | | |
+ * | | |\ |
+ * | r1 | | \ | .------------.
+ * | vIn1 >--+--ZZZZ-------+---|- \ | | |
+ * | | | >-+---+--|Threshold |
+ * | | r2 |+ / | | Out|------> DISC_555_OUT_xx
+ * Z '--ZZZZ--+--------| / '--|Trigger |
+ * Z r4 | |/ | |
+ * Z Z | Reset|------< Reset
+ * | Z r3 vIn2 >--|CV |
+ * .----. Z | |
+ * | En|<--------. | .---|Discharge |
+ * '----' | gnd | '------------'
+ * | | |
+ * gnd '-----------------------+---ZZZZ------> v_charge (ignored)
+ * rX
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_555_VCO1(name of node,
+ * reset node or static value,
+ * Vin1 node or static value,
+ * address of discrete_555_vco1_desc structure)
+ *
+ * DISCRETE_555_VCO1_CV(name of node,
+ * reset node or static value,
+ * Vin1 node or static value,
+ * Vin2 (CV) node or static value,
+ * address of discrete_555_vco1_desc structure)
+ *
+ * discrete_555_vco1_desc =
+ * {
+ * options, - bit mapped options
+ * r1, r2, r3, r4, c,
+ * v_pos, - B+ voltage of 555
+ * v_out_high, - High output voltage of 555 (Defaults to v_pos - 1.2V)
+ * }
+ *
+ * The last option of discrete_555_vco1_desc can use the following default:
+ * DEFAULT_555_HIGH - to use the normal output voltage based on v_pos
+ *
+ * Notes: The value of resistor rX is not needed. It is just a pull-up
+ * for the discharge output.
+ * The 'En' block can be a transistor or 4066 switch. It connects
+ * r4 to ground when En is high.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_566 - NE566 VCO simulation.
+ *
+ * v_charge v_pos
+ * V V
+ * | |
+ * | |
+ * | R .-------.
+ * '---/\/\--|6 8 |
+ * | |
+ * vMod >------------|5 3/4|---------> Netlist Node
+ * | |
+ * .---|7 1 |
+ * | '-------'
+ * --- |
+ * --- C |
+ * | |
+ * v_neg v_neg
+ *
+ * Note: There is usually a 0.001uF cap between pins 5 & 6.
+ * This is for circuit stability and can be ignored for simulation purposes.
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_566(name of node,
+ * vMod node or static value,
+ * R node or static value in ohms,
+ * C node or static value in Farads,
+ * v_pos static value
+ * v_neg static value
+ * v_charge node or static value
+ * options)
+ *
+ * Output Types:
+ * DISC_566_OUT_DC - Output is actual DC. (DEFAULT)
+ * DISC_566_OUT_AC - A cheat to make the waveform AC.
+ *
+ * Waveform Types:
+ * DISC_566_OUT_SQUARE - Pin 3 Square Wave Output (DEFAULT)
+ * DISC_566_OUT_ENERGY - Pin 3 anti-alaised Square Wave Output
+ * DISC_566_OUT_TRIANGLE - Pin 4 Triangle Wave Output
+ * DISC_566_OUT_LOGIC - Internal Flip/Flop Output
+ * DISC_566_COUNT_F - # of falling edges
+ * DISC_566_COUNT_R - # of rising edges
+ * DISC_566_COUNT_F_X - # of falling edges with x-time
+ * DISC_566_COUNT_R_X - # of rising edges with x-time
+ *
+ * EXAMPLES: see Starship 1
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_74LS624 - VCO. 1/2 of 74LS629.
+ *
+ * The datasheet gives no formulae. The implementation is based on
+ * testing a 74LS629.
+ *
+ * For a LS628, use VRng = 3.2
+ *
+ * V+
+ * |
+ * R_rng_in .---------.
+ * vRng >-----------ZZZZ-------|Rng V+ |
+ * R_freq_in | |
+ * vMod >---ZZZZ-+-------------|Freq Z |---------> Netlist Node
+ * | | |
+ * C_freq_in --- .---|CX1 |
+ * --- | | |
+ * | --- | |
+ * | C --- | |
+ * Gnd | | |
+ * '---|CX2 |
+ * '---------'
+ * |
+ * GND
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_74LS624(name of node,(NODE,ENAB,VMOD,VRNG,C,R_FREQ_IN,C_FREQ_IN,R_RNG_IN,OUTTYPE)
+ * enable node or static value,
+ * vMod node or static value,
+ * vRng static value,
+ * C static value in Farads,
+ * R_freq_in static value in Ohms,
+ * C_freq_in static value in Farads,
+ * R_rng_in static value in Ohms,
+ * Type of output static value)
+ *
+ * Type of Output
+ * DISC_LS624_OUT_SQUARE - 4.4V square wave
+ * DISC_LS624_OUT_ENERGY - 4.4V anti-aliased square wave
+ * DISC_LS624_OUT_LOGIC - Logic ( 0 or 1)
+ * DISC_LS624_OUT_LOGIC_X - Logic ( 0 or 1) with x_time
+ * DISC_LS624_OUT_COUNT_F - Number of Falling edges
+ * DISC_LS624_OUT_COUNT_F_X - Number of Falling edges with x_time
+ * DISC_LS624_OUT_COUNT_R - Number of Rising edges
+ * DISC_LS624_OUT_COUNT_R_X - Number of Rising edges with x_time
+ *
+ *
+ * EXAMPLES: see Donkey Kong Jr.; Mario Bros.
+ *
+ ***********************************************************************
+ *
+ * DISCRETE_CUSTOMx - Link to custom code
+ * where x = 1 to 9
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_CUSTOMx(name of node,
+ * input 0 node or static value, ...)
+ *
+ * discrete_custom_info = {discrete_module, custom}
+ * discrete_module = discrete module definition
+ * custom = address of specific initialization data
+ *
+ * In most case, you should be able to use
+ *
+ * discrete_custom_info = {DISCRETE_CUSTOM_MODULE(basename, context type), custom}
+ *
+ * if you have used DISCRETE_STEP(basename) and DISCRETE_RESET(basename) to define
+ * the step/reset procedures.
+ *
+ * EXAMPLES: see Sky Raider, Donkey Kong
+ *
+ ***********************************************************************
+ =======================================================================
+ * Debugging modules.
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_CSVLOGx - Dump n nodes into a csv (comma separated value) file
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_CSVLOGx(node 1, ...)
+ * where x = 1 to 5
+ *
+ * WARNING: This can rapidally use up a lot of hard drive space.
+ * 48kHz sampling of 5 nodes used 217M after 80 seconds.
+ *
+ * Use this to monitor nodes while debugging the driver. You should
+ * remove these nodes from the final driver. You can use up to a maximum
+ * DISCRETE_MAX_CSVLOGS. Each file will be called discreteX_Y.csv,
+ * where X is the sound tag. Y is 0-9, in the order the file is
+ * created in the driver.
+ *
+ * This can be used to monitor how multiple nodes relate to each other.
+ * The resulting file can be imported to a spreadsheet.
+ *
+ ************************************************************************
+ *
+ * DISCRETE_WAVLOG - Dump nodes into a wav file
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_WAVLOG1(node,
+ * static gain for node)
+ *
+ * DISCRETE_WAVLOG2(left node,
+ * static gain for left node,
+ * right node,
+ * static gain for right node)
+ *
+ * Use this to monitor nodes while debugging the driver. You should
+ * remove these nodes from the final driver. You can use up to a maximum
+ * of DISCRETE_MAX_WAVLOGS. Each file will be called discreteX_Y.wav,
+ * where X is the sound tag. Y is 0-9, in the order the file is
+ * created in the driver.
+ *
+ * This can be used to monitor how a node's input affects it's output.
+ * Monitor the input trigger against the final effect, etc. The resulting
+ * file can be played/viewed etc. by music player/editor software.
+ *
+ * When logging nodes that are voltage levels, you may want to use a
+ * gain of 1000. This will make the wav sample level reflect milli-volts.
+ *
+ ************************************************************************
+ =======================================================================
+ * Must be last module.
+ =======================================================================
+ ***********************************************************************
+ *
+ * DISCRETE_OUTPUT - Single output node to Mame mixer and output
+ *
+ * .----------. .
+ * | | .-/|
+ * Netlist node -------->| OUTPUT |----| | Sound Output
+ * | | '-\|
+ * '----------' '
+ *
+ * Declaration syntax
+ *
+ * DISCRETE_OUTPUT(name of output node, gain)
+ *
+ * Example config line
+ *
+ * DISCRETE_OUTPUT(NODE_02, 1000)
+ *
+ * Output stream will be generated from the NODE_02 output stream * 1000.
+ *
+ * Multiple outputs can be used up to DISCRETE_MAX_OUTPUTS.
+ *
+ ************************************************************************/
+
+#include "wavwrite.h"
+
+/*************************************
+ *
+ * macros
+ * see also: emu\machine\rescap.h
+ *
+ *************************************/
+
+/* calculate charge exponent using discrete sample time */
+#define RC_CHARGE_EXP(rc) (1.0 - exp(-this->sample_time() / (rc)))
+/* calculate charge exponent using given sample time */
+#define RC_CHARGE_EXP_DT(rc, dt) (1.0 - exp(-(dt) / (rc)))
+#define RC_CHARGE_NEG_EXP_DT(rc, dt) (1.0 - exp((dt) / (rc)))
+
+/* calculate discharge exponent using discrete sample time */
+#define RC_DISCHARGE_EXP(rc) (exp(-this->sample_time() / (rc)))
+/* calculate discharge exponent using given sample time */
+#define RC_DISCHARGE_EXP_DT(rc, dt) (exp(-(dt) / (rc)))
+#define RC_DISCHARGE_NEG_EXP_DT(rc, dt) (exp((dt) / (rc)))
+
+#define FREQ_OF_555(_r1, _r2, _c) (1.49 / ((_r1 + 2 * _r2) * _c))
+
+/*************************************
+ *
+ * Interface & Naming
+ *
+ *************************************/
+
+#define DISCRETE_CLASS_FUNC(_class, _func) DISCRETE_CLASS_NAME(_class) :: _func
+
+#define DISCRETE_STEP(_class) void DISCRETE_CLASS_FUNC(_class, step)(void)
+#define DISCRETE_RESET(_class) void DISCRETE_CLASS_FUNC(_class, reset)(void)
+#define DISCRETE_START(_class) void DISCRETE_CLASS_FUNC(_class, start)(void)
+#define DISCRETE_STOP(_class) void DISCRETE_CLASS_FUNC(_class, stop)(void)
+#define DISCRETE_DECLARE_INFO(_name) const _name *info = (const _name *)this->custom_data();
+
+//#define DISCRETE_INPUT(_num) (*(this->m_input[_num]))
+#define DISCRETE_INPUT(_num) (input(_num))
+
+/*************************************
+ *
+ * Core constants
+ *
+ *************************************/
+
+#define DISCRETE_MAX_NODES 300
+#define DISCRETE_MAX_INPUTS 10
+#define DISCRETE_MAX_OUTPUTS 8
+
+#define DISCRETE_MAX_TASK_GROUPS 10
+
+
+/*************************************
+ *
+ * Node-specific constants
+ *
+ *************************************/
+
+#define DEFAULT_TTL_V_LOGIC_1 3.4
+
+#define DISC_LOGADJ 1.0
+#define DISC_LINADJ 0.0
+
+/* DISCRETE_COMP_ADDER types */
+#define DISC_COMP_P_CAPACITOR 0x00
+#define DISC_COMP_P_RESISTOR 0x01
+
+/* clk types */
+#define DISC_CLK_MASK 0x03
+#define DISC_CLK_ON_F_EDGE 0x00
+#define DISC_CLK_ON_R_EDGE 0x01
+#define DISC_CLK_BY_COUNT 0x02
+#define DISC_CLK_IS_FREQ 0x03
+
+#define DISC_COUNT_DOWN 0
+#define DISC_COUNT_UP 1
+
+#define DISC_COUNTER_IS_7492 0x08
+
+#define DISC_OUT_MASK 0x30
+#define DISC_OUT_DEFAULT 0x00
+#define DISC_OUT_IS_ENERGY 0x10
+#define DISC_OUT_HAS_XTIME 0x20
+
+/* Function possibilities for the LFSR feedback nodes */
+/* 2 inputs, one output */
+#define DISC_LFSR_XOR 0
+#define DISC_LFSR_OR 1
+#define DISC_LFSR_AND 2
+#define DISC_LFSR_XNOR 3
+#define DISC_LFSR_NOR 4
+#define DISC_LFSR_NAND 5
+#define DISC_LFSR_IN0 6
+#define DISC_LFSR_IN1 7
+#define DISC_LFSR_NOT_IN0 8
+#define DISC_LFSR_NOT_IN1 9
+#define DISC_LFSR_REPLACE 10
+#define DISC_LFSR_XOR_INV_IN0 11
+#define DISC_LFSR_XOR_INV_IN1 12
+
+/* LFSR Flag Bits */
+#define DISC_LFSR_FLAG_OUT_INVERT 0x01
+#define DISC_LFSR_FLAG_RESET_TYPE_L 0x00
+#define DISC_LFSR_FLAG_RESET_TYPE_H 0x02
+#define DISC_LFSR_FLAG_OUTPUT_F0 0x04
+#define DISC_LFSR_FLAG_OUTPUT_SR_SN1 0x08
+
+/* Sample & Hold supported clock types */
+#define DISC_SAMPHOLD_REDGE 0
+#define DISC_SAMPHOLD_FEDGE 1
+#define DISC_SAMPHOLD_HLATCH 2
+#define DISC_SAMPHOLD_LLATCH 3
+
+/* Shift options */
+#define DISC_LOGIC_SHIFT__RESET_L 0x00
+#define DISC_LOGIC_SHIFT__RESET_H 0x10
+#define DISC_LOGIC_SHIFT__LEFT 0x00
+#define DISC_LOGIC_SHIFT__RIGHT 0x20
+
+/* Maximum number of resistors in ladder chain */
+#define DISC_LADDER_MAXRES 8
+
+/* Filter types */
+#define DISC_FILTER_LOWPASS 0
+#define DISC_FILTER_HIGHPASS 1
+#define DISC_FILTER_BANDPASS 2
+
+/* Mixer types */
+#define DISC_MIXER_IS_RESISTOR 0
+#define DISC_MIXER_IS_OP_AMP 1
+#define DISC_MIXER_IS_OP_AMP_WITH_RI 2 /* Used only internally. Use DISC_MIXER_IS_OP_AMP */
+
+/* Triggered Op Amp Functions */
+enum
+{
+ DISC_OP_AMP_TRIGGER_FUNCTION_NONE,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG0,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG0_INV,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG1,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG1_INV,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG2,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG2_INV,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG01_AND,
+ DISC_OP_AMP_TRIGGER_FUNCTION_TRG01_NAND
+};
+
+
+/* Common Op Amp Flags and values */
+#define DISC_OP_AMP_IS_NORTON 0x100
+#define OP_AMP_NORTON_VBE 0.5 // This is the norton junction voltage. Used only internally.
+#define OP_AMP_VP_RAIL_OFFSET 1.5 // This is how close an op-amp can get to the vP rail. Used only internally.
+
+/* Integrate options */
+#define DISC_INTEGRATE_OP_AMP_1 0x00
+#define DISC_INTEGRATE_OP_AMP_2 0x10
+
+/* op amp 1 shot types */
+#define DISC_OP_AMP_1SHT_1 0x00
+
+/* Op Amp Filter Options */
+#define DISC_OP_AMP_FILTER_IS_LOW_PASS_1 0x00
+#define DISC_OP_AMP_FILTER_IS_HIGH_PASS_1 0x10
+#define DISC_OP_AMP_FILTER_IS_BAND_PASS_1 0x20
+#define DISC_OP_AMP_FILTER_IS_BAND_PASS_1M 0x30
+#define DISC_OP_AMP_FILTER_IS_HIGH_PASS_0 0x40
+#define DISC_OP_AMP_FILTER_IS_BAND_PASS_0 0x50
+#define DISC_OP_AMP_FILTER_IS_LOW_PASS_1_A 0x60
+
+#define DISC_OP_AMP_FILTER_TYPE_MASK (0xf0 | DISC_OP_AMP_IS_NORTON) // Used only internally.
+
+/* Sallen-Key filter Opions */
+#define DISC_SALLEN_KEY_LOW_PASS 0x01
+#define DISC_SALLEN_KEY_HIGH_PASS 0x02
+
+
+/* Op Amp Oscillator Flags */
+#define DISC_OP_AMP_OSCILLATOR_TYPE_MASK (0xf0 | DISC_OP_AMP_IS_NORTON) // Used only internally.
+#define DISC_OP_AMP_OSCILLATOR_1 0x00
+#define DISC_OP_AMP_OSCILLATOR_2 0x10
+#define DISC_OP_AMP_OSCILLATOR_VCO_1 0x20
+#define DISC_OP_AMP_OSCILLATOR_VCO_2 0x30
+#define DISC_OP_AMP_OSCILLATOR_VCO_3 0x40
+
+#define DISC_OP_AMP_OSCILLATOR_OUT_MASK 0x07
+#define DISC_OP_AMP_OSCILLATOR_OUT_CAP 0x00
+#define DISC_OP_AMP_OSCILLATOR_OUT_SQW 0x01
+#define DISC_OP_AMP_OSCILLATOR_OUT_ENERGY 0x02
+#define DISC_OP_AMP_OSCILLATOR_OUT_LOGIC_X 0x03
+#define DISC_OP_AMP_OSCILLATOR_OUT_COUNT_F_X 0x04
+#define DISC_OP_AMP_OSCILLATOR_OUT_COUNT_R_X 0x05
+
+/* Schmitt Oscillator Options */
+#define DISC_SCHMITT_OSC_IN_IS_LOGIC 0x00
+#define DISC_SCHMITT_OSC_IN_IS_VOLTAGE 0x01
+
+#define DISC_SCHMITT_OSC_ENAB_IS_AND 0x00
+#define DISC_SCHMITT_OSC_ENAB_IS_NAND 0x02
+#define DISC_SCHMITT_OSC_ENAB_IS_OR 0x04
+#define DISC_SCHMITT_OSC_ENAB_IS_NOR 0x06
+
+#define DISC_SCHMITT_OSC_ENAB_MASK 0x06 /* Bits that define output enable type.
+ * Used only internally in module. */
+
+/* 555 Common output flags */
+#define DISC_555_OUT_DC 0x00
+#define DISC_555_OUT_AC 0x10
+
+#define DISC_555_TRIGGER_IS_LOGIC 0x00
+#define DISC_555_TRIGGER_IS_VOLTAGE 0x20
+#define DISC_555_TRIGGER_IS_COUNT 0x40
+#define DSD_555_TRIGGER_TYPE_MASK 0x60
+#define DISC_555_TRIGGER_DISCHARGES_CAP 0x80
+
+#define DISC_555_OUT_SQW 0x00 /* Squarewave */
+#define DISC_555_OUT_CAP 0x01 /* Cap charge waveform */
+#define DISC_555_OUT_COUNT_F 0x02 /* Falling count */
+#define DISC_555_OUT_COUNT_R 0x03 /* Rising count */
+#define DISC_555_OUT_ENERGY 0x04
+#define DISC_555_OUT_LOGIC_X 0x05
+#define DISC_555_OUT_COUNT_F_X 0x06
+#define DISC_555_OUT_COUNT_R_X 0x07
+
+#define DISC_555_OUT_MASK 0x07 /* Bits that define output type.
+ * Used only internally in module. */
+
+#define DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE 0x80
+#define DISCRETE_555_CC_TO_DISCHARGE_PIN 0x00
+#define DISCRETE_555_CC_TO_CAP 0x80
+
+/* 566 output flags */
+#define DISC_566_OUT_DC 0x00
+#define DISC_566_OUT_AC 0x10
+
+#define DISC_566_OUT_SQUARE 0x00 /* Squarewave */
+#define DISC_566_OUT_ENERGY 0x01 /* anti-alaised Squarewave */
+#define DISC_566_OUT_TRIANGLE 0x02 /* Triangle waveform */
+#define DISC_566_OUT_LOGIC 0x03 /* 0/1 logic output */
+#define DISC_566_OUT_COUNT_F 0x04
+#define DISC_566_OUT_COUNT_R 0x05
+#define DISC_566_OUT_COUNT_F_X 0x06
+#define DISC_566_OUT_COUNT_R_X 0x07
+#define DISC_566_OUT_MASK 0x07 /* Bits that define output type.
+ * Used only internally in module. */
+
+/* LS624 output flags */
+#define DISC_LS624_OUT_SQUARE 0x01
+#define DISC_LS624_OUT_ENERGY 0x02
+#define DISC_LS624_OUT_LOGIC 0x03
+#define DISC_LS624_OUT_LOGIC_X 0x04
+#define DISC_LS624_OUT_COUNT_F 0x05
+#define DISC_LS624_OUT_COUNT_R 0x06
+#define DISC_LS624_OUT_COUNT_F_X 0x07
+#define DISC_LS624_OUT_COUNT_R_X 0x08
+
+/* Oneshot types */
+#define DISC_ONESHOT_FEDGE 0x00
+#define DISC_ONESHOT_REDGE 0x01
+
+#define DISC_ONESHOT_NORETRIG 0x00
+#define DISC_ONESHOT_RETRIG 0x02
+
+#define DISC_OUT_ACTIVE_LOW 0x04
+#define DISC_OUT_ACTIVE_HIGH 0x00
+
+#define DISC_CD4066_THRESHOLD 2.75
+
+/* Integrate */
+
+#define DISC_RC_INTEGRATE_TYPE1 0x00
+#define DISC_RC_INTEGRATE_TYPE2 0x01
+#define DISC_RC_INTEGRATE_TYPE3 0x02
+
+/*************************************
+ *
+ * Classes and structs to handle
+ * linked lists.
+ *
+ *************************************/
+
+#define for_each(_T, _e, _l) for (_T _e = (_l)->begin_ptr() ; _e <= (_l)->end_ptr(); _e++)
+
+/*
+ * add and delete may be slow - the focus is on access!
+ */
+
+template<class _ElementType> struct dynamic_array_t
+{
+public:
+ dynamic_array_t(int initial) {
+ m_count = 0;
+ m_allocated = initial;
+ m_arr = global_alloc_array_clear(_ElementType, m_allocated);
+ }
+ dynamic_array_t() {
+ m_count = 0;
+ m_allocated = 16;
+ m_arr = global_alloc_array_clear(_ElementType, m_allocated);
+ }
+ ~dynamic_array_t() {
+ global_free(m_arr);
+ }
+ _ElementType& operator [] (unsigned int index) const // get array item
+ {
+ return m_arr[index];
+ }
+
+ dynamic_array_t(const dynamic_array_t &a) // copy constructor
+ {
+ m_allocated = a.count();
+ if (m_allocated < 16)
+ m_allocated = 16;
+ m_count = a.count();
+ m_arr = global_alloc_array_clear(_ElementType, m_allocated);
+ for (int i=0; i < m_count; i++)
+ m_arr[i] = a[i];
+ }
+ dynamic_array_t& operator = (const dynamic_array_t &a) // assignment operator
+ {
+ if (this == &a) return *this;
+ m_allocated = a.count();
+ if (m_allocated < 16)
+ m_allocated = 16;
+ m_count = a.count();
+ m_arr = global_alloc_array_clear(_ElementType, m_allocated);
+ for (int i=0; i < m_count; i++)
+ m_arr[i] = a[i];
+ return *this;
+ }
+
+ inline _ElementType* add(_ElementType object)
+ {
+ if (m_count >= m_allocated)
+ {
+ m_allocated *= 2;
+ _ElementType *newarr = global_alloc_array_clear(_ElementType, m_allocated);
+ for (int i=0; i < m_count; i++)
+ newarr[i] = m_arr[i];
+ global_free(m_arr);
+ m_arr = newarr;
+ }
+ m_arr[m_count] = object;
+ m_count++;
+ return &m_arr[m_count-1];
+ }
+ inline void remove(int index)
+ {
+ for (int i=index+1; i < m_count; i++)
+ m_arr[i-1] = m_arr[i];
+ m_count--;
+ }
+ inline void clear(void) { m_count = 0; }
+ inline int count(void) const { return m_count; }
+ inline _ElementType *begin_ptr(void) const { return m_arr; }
+ inline _ElementType *end_ptr(void) const { return m_arr + (m_count - 1); }
+private:
+ _ElementType *m_arr;
+ int m_count;
+ int m_allocated;
+};
+
+/*************************************
+ *
+ * Node-specific struct types
+ *
+ *************************************/
+
+typedef struct _discrete_lfsr_desc discrete_lfsr_desc;
+struct _discrete_lfsr_desc
+{
+ int clock_type;
+ int bitlength;
+ int reset_value;
+
+ int feedback_bitsel0;
+ int feedback_bitsel1;
+ int feedback_function0; /* Combines bitsel0 & bitsel1 */
+
+ int feedback_function1; /* Combines funct0 & infeed bit */
+
+ int feedback_function2; /* Combines funct1 & shifted register */
+ int feedback_function2_mask; /* Which bits are affected by function 2 */
+
+ int flags;
+
+ int output_bit;
+};
+
+
+typedef struct _discrete_op_amp_osc_info discrete_op_amp_osc_info;
+struct _discrete_op_amp_osc_info
+{
+ UINT32 type;
+ double r1;
+ double r2;
+ double r3;
+ double r4;
+ double r5;
+ double r6;
+ double r7;
+ double r8;
+ double c;
+ double vP; // Op amp B+
+};
+
+
+#define DEFAULT_7414_VALUES 1.7, 0.9, 3.4
+
+#define DEFAULT_74LS14_VALUES 1.6, 0.8, 3.4
+
+typedef struct _discrete_schmitt_osc_desc discrete_schmitt_osc_desc;
+struct _discrete_schmitt_osc_desc
+{
+ double rIn;
+ double rFeedback;
+ double c;
+ double trshRise; // voltage that triggers the gate input to go high (vGate) on rise
+ double trshFall; // voltage that triggers the gate input to go low (0V) on fall
+ double vGate; // the output high voltage of the gate that gets fedback through rFeedback
+ int options; // bitmaped options
+};
+
+
+typedef struct _discrete_comp_adder_table discrete_comp_adder_table;
+struct _discrete_comp_adder_table
+{
+ int type;
+ double cDefault; // Default componet. 0 if not used.
+ int length;
+ double c[DISC_LADDER_MAXRES]; // Componet table
+};
+
+
+typedef struct _discrete_dac_r1_ladder discrete_dac_r1_ladder;
+struct _discrete_dac_r1_ladder
+{
+ int ladderLength; // 2 to DISC_LADDER_MAXRES. 1 would be useless.
+ double r[DISC_LADDER_MAXRES]; // Don't use 0 for valid resistors. That is a short.
+ double vBias; // Voltage Bias resistor is tied to (0 = not used)
+ double rBias; // Additional resistor tied to vBias (0 = not used)
+ double rGnd; // Resistor tied to ground (0 = not used)
+ double cFilter; // Filtering cap (0 = not used)
+};
+
+
+typedef struct _discrete_integrate_info discrete_integrate_info;
+struct _discrete_integrate_info
+{
+ UINT32 type;
+ double r1; // r1a + r1b
+ double r2; // r2a + r2b
+ double r3; // r3a + r3b
+ double c;
+ double v1;
+ double vP;
+ double f0;
+ double f1;
+ double f2;
+};
+
+
+#define DISC_MAX_MIXER_INPUTS 8
+typedef struct _discrete_mixer_desc discrete_mixer_desc;
+struct _discrete_mixer_desc
+{
+ int type;
+ double r[DISC_MAX_MIXER_INPUTS]; /* static input resistance values. These are in series with rNode, if used. */
+ int r_node[DISC_MAX_MIXER_INPUTS]; /* variable resistance nodes, if needed. 0 if not used. */
+ double c[DISC_MAX_MIXER_INPUTS];
+ double rI;
+ double rF;
+ double cF;
+ double cAmp;
+ double vRef;
+ double gain; /* Scale value to get output close to +/- 32767 */
+};
+
+
+typedef struct _discrete_op_amp_info discrete_op_amp_info;
+struct _discrete_op_amp_info
+{
+ UINT32 type;
+ double r1;
+ double r2;
+ double r3;
+ double r4;
+ double c;
+ double vN; // Op amp B-
+ double vP; // Op amp B+
+};
+
+
+typedef struct _discrete_op_amp_1sht_info discrete_op_amp_1sht_info;
+struct _discrete_op_amp_1sht_info
+{
+ UINT32 type;
+ double r1;
+ double r2;
+ double r3;
+ double r4;
+ double r5;
+ double c1;
+ double c2;
+ double vN; // Op amp B-
+ double vP; // Op amp B+
+};
+
+
+typedef struct _discrete_op_amp_tvca_info discrete_op_amp_tvca_info;
+struct _discrete_op_amp_tvca_info
+{
+ double r1;
+ double r2; // r2a + r2b
+ double r3; // r3a + r3b
+ double r4;
+ double r5;
+ double r6;
+ double r7;
+ double r8;
+ double r9;
+ double r10;
+ double r11;
+ double c1;
+ double c2;
+ double c3;
+ double c4;
+ double v1;
+ double v2;
+ double v3;
+ double vP;
+ int f0;
+ int f1;
+ int f2;
+ int f3;
+ int f4;
+ int f5;
+};
+
+
+typedef struct _discrete_op_amp_filt_info discrete_op_amp_filt_info;
+struct _discrete_op_amp_filt_info
+{
+ double r1;
+ double r2;
+ double r3;
+ double r4;
+ double rF;
+ double c1;
+ double c2;
+ double c3;
+ double vRef;
+ double vP;
+ double vN;
+};
+
+
+#define DEFAULT_555_CHARGE -1
+#define DEFAULT_555_HIGH -1
+#define DEFAULT_555_VALUES DEFAULT_555_CHARGE, DEFAULT_555_HIGH
+
+typedef struct _discrete_555_desc discrete_555_desc;
+struct _discrete_555_desc
+{
+ int options; /* bit mapped options */
+ double v_pos; /* B+ voltage of 555 */
+ double v_charge; /* voltage to charge circuit (Defaults to v_pos) */
+ double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
+};
+
+#define DEFAULT_555_CC_SOURCE DEFAULT_555_CHARGE
+
+typedef struct _discrete_555_cc_desc discrete_555_cc_desc;
+struct _discrete_555_cc_desc
+{
+ int options; /* bit mapped options */
+ double v_pos; /* B+ voltage of 555 */
+ double v_cc_source; /* Voltage of the Constant Current source */
+ double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
+ double v_cc_junction; /* The voltage drop of the Constant Current source transitor (0 if Op Amp) */
+};
+
+
+typedef struct _discrete_555_vco1_desc discrete_555_vco1_desc;
+struct _discrete_555_vco1_desc
+{
+ int options; /* bit mapped options */
+ double r1, r2, r3, r4, c;
+ double v_pos; /* B+ voltage of 555 */
+ double v_charge; /* (ignored) */
+ double v_out_high; /* High output voltage of 555 (Defaults to v_pos - 1.2V) */
+};
+
+
+typedef struct _discrete_adsr discrete_adsr;
+struct _discrete_adsr
+{
+ double attack_time; /* All times are in seconds */
+ double attack_value;
+ double decay_time;
+ double decay_value;
+ double sustain_time;
+ double sustain_value;
+ double release_time;
+ double release_value;
+};
+
+
+/*************************************
+ *
+ * The node numbers themselves
+ *
+ *************************************/
+
+#define NODE0_DEF(_x) NODE_ ## 0 ## _x = (0x40000000 + (_x) * DISCRETE_MAX_OUTPUTS), \
+ NODE_ ## 0 ## _x ## _00 = NODE_ ## 0 ## _x, NODE_ ## 0 ## _x ## _01, NODE_ ## 0 ## _x ## _02, NODE_ ## 0 ## _x ## _03, \
+ NODE_ ## 0 ## _x ## _04, NODE_ ## 0 ## _x ## _05, NODE_ ## 0 ## _x ## _06, NODE_ ## 0 ## _x ## _07
+#define NODE_DEF(_x) NODE_ ## _x = (0x40000000 + (_x) * DISCRETE_MAX_OUTPUTS), \
+ NODE_ ## _x ## _00 = NODE_ ## _x, NODE_ ## _x ## _01, NODE_ ## _x ## _02, NODE_ ## _x ## _03, \
+ NODE_ ## _x ## _04, NODE_ ## _x ## _05, NODE_ ## _x ## _06, NODE_ ## _x ## _07
+
+enum {
+ NODE0_DEF(0), NODE0_DEF(1), NODE0_DEF(2), NODE0_DEF(3), NODE0_DEF(4), NODE0_DEF(5), NODE0_DEF(6), NODE0_DEF(7), NODE0_DEF(8), NODE0_DEF(9),
+ NODE_DEF(10), NODE_DEF(11), NODE_DEF(12), NODE_DEF(13), NODE_DEF(14), NODE_DEF(15), NODE_DEF(16), NODE_DEF(17), NODE_DEF(18), NODE_DEF(19),
+ NODE_DEF(20), NODE_DEF(21), NODE_DEF(22), NODE_DEF(23), NODE_DEF(24), NODE_DEF(25), NODE_DEF(26), NODE_DEF(27), NODE_DEF(28), NODE_DEF(29),
+ NODE_DEF(30), NODE_DEF(31), NODE_DEF(32), NODE_DEF(33), NODE_DEF(34), NODE_DEF(35), NODE_DEF(36), NODE_DEF(37), NODE_DEF(38), NODE_DEF(39),
+ NODE_DEF(40), NODE_DEF(41), NODE_DEF(42), NODE_DEF(43), NODE_DEF(44), NODE_DEF(45), NODE_DEF(46), NODE_DEF(47), NODE_DEF(48), NODE_DEF(49),
+ NODE_DEF(50), NODE_DEF(51), NODE_DEF(52), NODE_DEF(53), NODE_DEF(54), NODE_DEF(55), NODE_DEF(56), NODE_DEF(57), NODE_DEF(58), NODE_DEF(59),
+ NODE_DEF(60), NODE_DEF(61), NODE_DEF(62), NODE_DEF(63), NODE_DEF(64), NODE_DEF(65), NODE_DEF(66), NODE_DEF(67), NODE_DEF(68), NODE_DEF(69),
+ NODE_DEF(70), NODE_DEF(71), NODE_DEF(72), NODE_DEF(73), NODE_DEF(74), NODE_DEF(75), NODE_DEF(76), NODE_DEF(77), NODE_DEF(78), NODE_DEF(79),
+ NODE_DEF(80), NODE_DEF(81), NODE_DEF(82), NODE_DEF(83), NODE_DEF(84), NODE_DEF(85), NODE_DEF(86), NODE_DEF(87), NODE_DEF(88), NODE_DEF(89),
+ NODE_DEF(90), NODE_DEF(91), NODE_DEF(92), NODE_DEF(93), NODE_DEF(94), NODE_DEF(95), NODE_DEF(96), NODE_DEF(97), NODE_DEF(98), NODE_DEF(99),
+ NODE_DEF(100),NODE_DEF(101),NODE_DEF(102),NODE_DEF(103),NODE_DEF(104),NODE_DEF(105),NODE_DEF(106),NODE_DEF(107),NODE_DEF(108),NODE_DEF(109),
+ NODE_DEF(110),NODE_DEF(111),NODE_DEF(112),NODE_DEF(113),NODE_DEF(114),NODE_DEF(115),NODE_DEF(116),NODE_DEF(117),NODE_DEF(118),NODE_DEF(119),
+ NODE_DEF(120),NODE_DEF(121),NODE_DEF(122),NODE_DEF(123),NODE_DEF(124),NODE_DEF(125),NODE_DEF(126),NODE_DEF(127),NODE_DEF(128),NODE_DEF(129),
+ NODE_DEF(130),NODE_DEF(131),NODE_DEF(132),NODE_DEF(133),NODE_DEF(134),NODE_DEF(135),NODE_DEF(136),NODE_DEF(137),NODE_DEF(138),NODE_DEF(139),
+ NODE_DEF(140),NODE_DEF(141),NODE_DEF(142),NODE_DEF(143),NODE_DEF(144),NODE_DEF(145),NODE_DEF(146),NODE_DEF(147),NODE_DEF(148),NODE_DEF(149),
+ NODE_DEF(150),NODE_DEF(151),NODE_DEF(152),NODE_DEF(153),NODE_DEF(154),NODE_DEF(155),NODE_DEF(156),NODE_DEF(157),NODE_DEF(158),NODE_DEF(159),
+ NODE_DEF(160),NODE_DEF(161),NODE_DEF(162),NODE_DEF(163),NODE_DEF(164),NODE_DEF(165),NODE_DEF(166),NODE_DEF(167),NODE_DEF(168),NODE_DEF(169),
+ NODE_DEF(170),NODE_DEF(171),NODE_DEF(172),NODE_DEF(173),NODE_DEF(174),NODE_DEF(175),NODE_DEF(176),NODE_DEF(177),NODE_DEF(178),NODE_DEF(179),
+ NODE_DEF(180),NODE_DEF(181),NODE_DEF(182),NODE_DEF(183),NODE_DEF(184),NODE_DEF(185),NODE_DEF(186),NODE_DEF(187),NODE_DEF(188),NODE_DEF(189),
+ NODE_DEF(190),NODE_DEF(191),NODE_DEF(192),NODE_DEF(193),NODE_DEF(194),NODE_DEF(195),NODE_DEF(196),NODE_DEF(197),NODE_DEF(198),NODE_DEF(199),
+ NODE_DEF(200),NODE_DEF(201),NODE_DEF(202),NODE_DEF(203),NODE_DEF(204),NODE_DEF(205),NODE_DEF(206),NODE_DEF(207),NODE_DEF(208),NODE_DEF(209),
+ NODE_DEF(210),NODE_DEF(211),NODE_DEF(212),NODE_DEF(213),NODE_DEF(214),NODE_DEF(215),NODE_DEF(216),NODE_DEF(217),NODE_DEF(218),NODE_DEF(219),
+ NODE_DEF(220),NODE_DEF(221),NODE_DEF(222),NODE_DEF(223),NODE_DEF(224),NODE_DEF(225),NODE_DEF(226),NODE_DEF(227),NODE_DEF(228),NODE_DEF(229),
+ NODE_DEF(230),NODE_DEF(231),NODE_DEF(232),NODE_DEF(233),NODE_DEF(234),NODE_DEF(235),NODE_DEF(236),NODE_DEF(237),NODE_DEF(238),NODE_DEF(239),
+ NODE_DEF(240),NODE_DEF(241),NODE_DEF(242),NODE_DEF(243),NODE_DEF(244),NODE_DEF(245),NODE_DEF(246),NODE_DEF(247),NODE_DEF(248),NODE_DEF(249),
+ NODE_DEF(250),NODE_DEF(251),NODE_DEF(252),NODE_DEF(253),NODE_DEF(254),NODE_DEF(255),NODE_DEF(256),NODE_DEF(257),NODE_DEF(258),NODE_DEF(259),
+ NODE_DEF(260),NODE_DEF(261),NODE_DEF(262),NODE_DEF(263),NODE_DEF(264),NODE_DEF(265),NODE_DEF(266),NODE_DEF(267),NODE_DEF(268),NODE_DEF(269),
+ NODE_DEF(270),NODE_DEF(271),NODE_DEF(272),NODE_DEF(273),NODE_DEF(274),NODE_DEF(275),NODE_DEF(276),NODE_DEF(277),NODE_DEF(278),NODE_DEF(279),
+ NODE_DEF(280),NODE_DEF(281),NODE_DEF(282),NODE_DEF(283),NODE_DEF(284),NODE_DEF(285),NODE_DEF(286),NODE_DEF(287),NODE_DEF(288),NODE_DEF(289),
+ NODE_DEF(290),NODE_DEF(291),NODE_DEF(292),NODE_DEF(293),NODE_DEF(294),NODE_DEF(295),NODE_DEF(296),NODE_DEF(297),NODE_DEF(298),NODE_DEF(299)
+};
+
+/* Some Pre-defined nodes for convenience */
+
+#define NODE(_x) (NODE_00 + (_x) * DISCRETE_MAX_OUTPUTS)
+#define NODE_SUB(_x, _y) ((_x) + (_y))
+
+#if DISCRETE_MAX_OUTPUTS == 8
+#define NODE_CHILD_NODE_NUM(_x) ((int)(_x) & 7)
+#define NODE_DEFAULT_NODE(_x) ((int)(_x) & ~7)
+#define NODE_INDEX(_x) (((int)(_x) - NODE_START)>>3)
+#else
+#error "DISCRETE_MAX_OUTPUTS != 8"
+#endif
+
+#define NODE_RELATIVE(_x, _y) (NODE(NODE_INDEX(_x) + (_y)))
+
+#define NODE_NC NODE_00
+#define NODE_SPECIAL NODE(DISCRETE_MAX_NODES)
+
+#define NODE_START NODE_00
+#define NODE_END NODE_SPECIAL
+
+#define IS_VALUE_A_NODE(val) (((val) > NODE_START) && ((val) <= NODE_END))
+
+
+/*************************************
+ *
+ * Enumerated values for Node types
+ * in the simulation
+ *
+ * DSS - Discrete Sound Source
+ * DST - Discrete Sound Transform
+ * DSD - Discrete Sound Device
+ * DSO - Discrete Sound Output
+ *
+ *************************************/
+
+typedef enum
+{
+ DSS_NULL, /* Nothing, nill, zippo, only to be used as terminating node */
+ DSS_NOP, /* just do nothing, placeholder for potential DISCRETE_REPLACE in parent block */
+
+ /* standard node */
+
+ DSS_NODE, /* a standard node */
+
+ /* Custom */
+ DST_CUSTOM, /* whatever you want */
+
+ /* Debugging */
+ DSO_CSVLOG, /* Dump nodes as csv file */
+ DSO_WAVLOG, /* Dump nodes as wav file */
+
+ /* Parallel execution */
+ DSO_TASK_START, /* start of parallel task */
+ DSO_TASK_END, /* end of parallel task */
+
+ /* Output Node -- this must be the last entry in this enum! */
+ DSO_OUTPUT, /* The final output node */
+
+ /* Import another blocklist */
+ DSO_IMPORT, /* import from another discrete block */
+ DSO_REPLACE, /* replace next node */
+ DSO_DELETE, /* delete nodes */
+
+ /* Marks end of this enum -- must be last entry ! */
+ DSO_LAST
+} discrete_node_type;
+
+/*************************************
+ *
+ * Forward declarations
+ *
+ *************************************/
+
+typedef struct _discrete_sound_block discrete_block;
+class discrete_node_base_factory;
+class discrete_task;
+class discrete_base_node;
+class discrete_dss_input_stream_node;
+class discrete_device;
+typedef dynamic_array_t<discrete_base_node *> node_list_t;
+typedef dynamic_array_t<discrete_dss_input_stream_node *> istream_node_list_t;
+typedef dynamic_array_t<discrete_task *> task_list_t;
+
+
+/*************************************
+ *
+ * Discrete module definition
+ *
+ *************************************/
+
+
+/*************************************
+ *
+ * The discrete sound blocks as
+ * defined in the drivers
+ *
+ *************************************/
+
+struct _discrete_sound_block
+{
+ int node; /* Output node number */
+ discrete_node_base_factory *factory;
+ int type; /* see defines below */
+ int active_inputs; /* Number of active inputs on this node type */
+ int input_node[DISCRETE_MAX_INPUTS];/* input/control nodes */
+ double initial[DISCRETE_MAX_INPUTS]; /* Initial values */
+ const void * custom; /* Custom function specific initialisation data */
+ const char * name; /* Node Name */
+ const char * mod_name; /* Module / class name */
+};
+typedef dynamic_array_t<const discrete_block *> sound_block_list_t;
+
+/*************************************
+ *
+ * Node interfaces
+ *
+ *************************************/
+
+class discrete_step_interface
+{
+public:
+ virtual ~discrete_step_interface() { }
+
+ virtual void step(void) = 0;
+ osd_ticks_t run_time;
+ discrete_base_node * self;
+};
+typedef dynamic_array_t<discrete_step_interface *> node_step_list_t;
+
+class discrete_input_interface
+{
+public:
+ virtual ~discrete_input_interface() { }
+
+ virtual void input_write(int sub_node, UINT8 data ) = 0;
+};
+
+class discrete_sound_output_interface
+{
+public:
+ virtual ~discrete_sound_output_interface() { }
+
+ virtual void set_output_ptr(stream_sample_t *ptr) = 0;
+};
+
+
+/*************************************
+ *
+ * Interface to the external world
+ *
+ *************************************/
+
+WRITE8_DEVICE_HANDLER( discrete_sound_w );
+READ8_DEVICE_HANDLER( discrete_sound_r );
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_DISCRETE_ADD(_tag, _clock, _intf) \
+ MCFG_DEVICE_ADD(_tag, DISCRETE, _clock) \
+ MCFG_DISCRETE_INTF(_intf)
+
+#define MCFG_DISCRETE_REPLACE(_tag, _clock, _intf) \
+ MCFG_DEVICE_REPLACE(_tag, DISCRETE, _clock) \
+ MCFG_DISCRETE_INTF(_intf)
+
+#define MCFG_DISCRETE_INTF(_intf) \
+ discrete_device::static_set_intf(*device, (const discrete_block *)&(_intf##_discrete_interface)); \
+
+#define MCFG_SOUND_CONFIG_DISCRETE(name) MCFG_SOUND_CONFIG(name##_discrete_interface)
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class discrete_sound_output_interface;
+typedef dynamic_array_t<discrete_sound_output_interface *> node_output_list_t;
+
+
+// ======================> discrete_device
+
+class discrete_device : public device_t
+{
+ //friend class discrete_base_node;
+
+protected:
+ // construction/destruction
+ discrete_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
+
+public:
+ // inline configuration helpers
+ static void static_set_intf(device_t &device, const discrete_block *intf);
+
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+ virtual ~discrete_device(void);
+
+ /* --------------------------------- */
+
+ virtual void update_to_current_time(void) const { }
+
+ /* process a number of samples */
+ void process(int samples);
+
+ /* access to the discrete_logging facility */
+ void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const char *text, ...) const;
+
+ /* get pointer to a info struct node ref */
+ const double *node_output_ptr(int onode);
+
+ /* FIXME: this is used by csv and wav logs - going forward, identifiers should be explicitly passed */
+ int same_module_index(const discrete_base_node &node);
+
+ /* get node */
+ discrete_base_node *discrete_find_node(int node);
+
+ /* are we profiling */
+ inline int profiling(void) { return m_profiling; }
+
+ inline int sample_rate(void) { return m_sample_rate; }
+ inline double sample_time(void) { return m_sample_time; }
+
+
+protected:
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_stop();
+
+ // configuration state
+ const discrete_block *m_intf;
+
+ // internal state
+
+ /* --------------------------------- */
+
+ /* emulation info */
+ int m_sample_rate;
+ double m_sample_time;
+ double m_neg_sample_time;
+
+ /* list of all nodes */
+ node_list_t m_node_list; /* node_description * */
+
+private:
+ void discrete_build_list(const discrete_block *intf, sound_block_list_t &block_list);
+ void discrete_sanity_check(const sound_block_list_t &block_list);
+ void display_profiling(void);
+ void init_nodes(const sound_block_list_t &block_list);
+
+ /* internal node tracking */
+ discrete_base_node ** m_indexed_node;
+
+ /* tasks */
+ task_list_t task_list; /* discrete_task_context * */
+
+ /* debugging statistics */
+ FILE * m_disclogfile;
+
+ /* parallel tasks */
+ osd_work_queue * m_queue;
+
+ /* profiling */
+ int m_profiling;
+ UINT64 m_total_samples;
+ UINT64 m_total_stream_updates;
+};
+
+// ======================> discrete_sound_device
+
+class discrete_sound_device : public discrete_device,
+ public device_sound_interface
+{
+public:
+ // construction/destruction
+ discrete_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~discrete_sound_device(void) { };
+
+ /* --------------------------------- */
+
+ virtual void update_to_current_time(void) const { m_stream->update(); }
+
+ sound_stream *get_stream(void) { return m_stream; }
+protected:
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_sound_interface overrides
+ virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
+
+private:
+ /* the output stream */
+ sound_stream *m_stream;
+
+ /* the input streams */
+ istream_node_list_t m_input_stream_list;
+ /* output node tracking */
+ node_output_list_t m_output_list;
+};
+
+// device type definition
+extern const device_type DISCRETE;
+
+/*************************************
+ *
+ * Node class
+ *
+ *************************************/
+
+class discrete_base_node
+{
+ friend class discrete_device;
+ template <class C> friend class discrete_node_factory;
+ friend class discrete_task;
+
+public:
+
+ virtual void reset(void) { }
+ virtual void start(void) { }
+ virtual void stop(void) { }
+ virtual void save_state(void);
+
+ virtual int max_output(void) { return 1; };
+
+ inline bool interface(discrete_step_interface *&intf) const { intf = m_step_intf; return (intf != NULL); }
+ inline bool interface(discrete_input_interface *&intf) const { intf = m_input_intf; return (intf != NULL); }
+ inline bool interface(discrete_sound_output_interface *&intf) const { intf = m_output_intf; return (intf != NULL); }
+
+ /* get the input value from node #n */
+ inline double input(int n) { return *(m_input[n]); }
+
+ /* set an output */
+ inline void set_output(int n, double val) { m_output[n] = val; }
+
+ /* Return the node index, i.e. X from NODE(X) */
+ inline int index(void) { return NODE_INDEX(m_block->node); }
+
+ /* Return the node number, i.e. NODE(X) */
+ inline int block_node(void) const { return m_block->node; }
+
+ /* Custom function specific initialisation data */
+ inline const void *custom_data(void) { return m_custom; }
+
+ inline int input_node(int inputnum) { return m_block->input_node[inputnum]; }
+
+ /* Number of active inputs on this node type */
+ inline int active_inputs(void) { return m_active_inputs; }
+ /* Bit Flags. 1 in bit location means input_is_node */
+ inline int input_is_node(void) { return m_input_is_node; }
+
+ inline double sample_time(void) { return m_device->sample_time(); }
+ inline int sample_rate(void) { return m_device->sample_rate(); }
+
+ const char * module_name(void) { return m_block->mod_name; }
+ inline int module_type(void) const { return m_block->type; }
+
+protected:
+
+ discrete_base_node();
+ virtual ~discrete_base_node();
+
+ /* finish node setup after allocation is complete */
+ void init(discrete_device * pdev, const discrete_block *block);
+
+ void resolve_input_nodes(void);
+
+ double m_output[DISCRETE_MAX_OUTPUTS]; /* The node's last output value */
+ const double * m_input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */
+ discrete_device * m_device; /* Points to the parent */
+
+private:
+
+ const discrete_block * m_block; /* Points to the node's setup block. */
+ int m_active_inputs; /* Number of active inputs on this node type */
+
+ const void * m_custom; /* Custom function specific initialisation data */
+ int m_input_is_node;
+
+ discrete_step_interface * m_step_intf;
+ discrete_input_interface * m_input_intf;
+ discrete_sound_output_interface * m_output_intf;
+};
+
+class discrete_node_base_factory
+{
+public:
+ virtual discrete_base_node *Create(discrete_device * pdev, const discrete_block *block) = 0;
+ virtual ~discrete_node_base_factory() {}
+};
+
+template <class C>
+class discrete_node_factory : public discrete_node_base_factory
+{
+ discrete_base_node *Create(discrete_device * pdev, const discrete_block *block);
+};
+
+template <class C>
+discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, const discrete_block *block)
+{
+ discrete_base_node *r = auto_alloc_clear(pdev->machine(), C);
+
+ r->init(pdev, block);
+ return r;
+}
+
+/*************************************
+ *
+ * Class definitions for nodes
+ *
+ *************************************/
+
+#include "disc_cls.h"
+
+/*************************************
+ *
+ * Encapsulation macros for defining
+ * your simulation
+ *
+ *************************************/
+
+#define DISCRETE_SOUND_EXTERN(name) extern const discrete_block name##_discrete_interface[]
+#define DISCRETE_SOUND_START(name) const discrete_block name##_discrete_interface[] = {
+
+#define DSC_SND_ENTRY(_nod, _class, _dss, _num, _iact, _iinit, _custom, _name) { _nod, new discrete_node_factory< DISCRETE_CLASS_NAME(_class) >, _dss, _num, _iact, _iinit, _custom, _name, # _class }
+
+
+#define DISCRETE_SOUND_END DSC_SND_ENTRY( NODE_00, special, DSS_NULL , 0, DSE( NODE_NC ), DSE( 0 ) ,NULL ,"DISCRETE_SOUND_END" ) };
+#define DSE( ... ) { __VA_ARGS__ }
+
+/* Module Name out, enum value, #in, {variable inputs}, {static inputs}, data pointer, "name" */
+
+/* from disc_inp.c */
+#define DISCRETE_ADJUSTMENT(NODE,MIN,MAX,LOGLIN,TAG) DSC_SND_ENTRY( NODE, dss_adjustment , DSS_NODE , 7, DSE( NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( MIN,MAX,LOGLIN,0 ,0 ,100 ), TAG , "DISCRETE_ADJUSTMENT" ),
+#define DISCRETE_ADJUSTMENTX(NODE,MIN,MAX,LOGLIN,TAG,PMIN,PMAX) DSC_SND_ENTRY( NODE, dss_adjustment , DSS_NODE , 7, DSE( NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( MIN,MAX,LOGLIN,0 ,PMIN,PMAX ), TAG , "DISCRETE_ADJUSTMENTX" ),
+#define DISCRETE_CONSTANT(NODE,CONST) DSC_SND_ENTRY( NODE, dss_constant , DSS_NODE , 1, DSE( NODE_NC ), DSE( CONST ) ,NULL ,"DISCRETE_CONSTANT" ),
+#define DISCRETE_INPUT_DATA(NODE) DSC_SND_ENTRY( NODE, dss_input_data , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( 1,0,0 ), NULL, "DISCRETE_INPUT_DATA" ),
+#define DISCRETE_INPUTX_DATA(NODE,GAIN,OFFSET,INIT) DSC_SND_ENTRY( NODE, dss_input_data , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( GAIN,OFFSET,INIT ), NULL, "DISCRETE_INPUTX_DATA" ),
+#define DISCRETE_INPUT_LOGIC(NODE) DSC_SND_ENTRY( NODE, dss_input_logic , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( 1,0,0 ), NULL, "DISCRETE_INPUT_LOGIC" ),
+#define DISCRETE_INPUTX_LOGIC(NODE,GAIN,OFFSET,INIT) DSC_SND_ENTRY( NODE, dss_input_logic , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( GAIN,OFFSET,INIT ), NULL, "DISCRETE_INPUTX_LOGIC" ),
+#define DISCRETE_INPUT_NOT(NODE) DSC_SND_ENTRY( NODE, dss_input_not , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( 1,0,0 ), NULL, "DISCRETE_INPUT_NOT" ),
+#define DISCRETE_INPUTX_NOT(NODE,GAIN,OFFSET,INIT) DSC_SND_ENTRY( NODE, dss_input_not , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( GAIN,OFFSET,INIT ), NULL, "DISCRETE_INPUTX_NOT" ),
+#define DISCRETE_INPUT_PULSE(NODE,INIT) DSC_SND_ENTRY( NODE, dss_input_pulse , DSS_NODE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( 1,0,INIT ), NULL, "DISCRETE_INPUT_PULSE" ),
+
+#define DISCRETE_INPUT_STREAM(NODE, NUM) DSC_SND_ENTRY( NODE, dss_input_stream, DSS_NODE , 3, DSE( NUM,NODE_NC,NODE_NC ), DSE( NUM,1,0 ), NULL, "DISCRETE_INPUT_STREAM" ),
+#define DISCRETE_INPUTX_STREAM(NODE, NUM, GAIN,OFFSET) DSC_SND_ENTRY( NODE, dss_input_stream, DSS_NODE , 3, DSE( NUM,NODE_NC,NODE_NC ), DSE( NUM,GAIN,OFFSET ), NULL, "DISCRETE_INPUTX_STREAM" ),
+
+#define DISCRETE_INPUT_BUFFER(NODE, NUM) DSC_SND_ENTRY( NODE, dss_input_buffer, DSS_NODE , 3, DSE( NUM,NODE_NC,NODE_NC ), DSE( NUM,1,0 ), NULL, "DISCRETE_INPUT_BUFFER" ),
+
+/* from disc_wav.c */
+/* generic modules */
+#define DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MIN,MAX,DIR,INIT0,CLKTYPE) DSC_SND_ENTRY( NODE, dss_counter , DSS_NODE , 8, DSE( ENAB,RESET,CLK,NODE_NC,NODE_NC,DIR,INIT0,NODE_NC ), DSE( ENAB,RESET,CLK,MIN,MAX,DIR,INIT0,CLKTYPE ), NULL, "DISCRETE_COUNTER" ),
+#define DISCRETE_COUNTER_7492(NODE,ENAB,RESET,CLK,CLKTYPE) DSC_SND_ENTRY( NODE, dss_counter , DSS_NODE , 8, DSE( ENAB,RESET,CLK,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,RESET,CLK,CLKTYPE,0,1,0,DISC_COUNTER_IS_7492 ), NULL, "DISCRETE_COUNTER_7492" ),
+#define DISCRETE_LFSR_NOISE(NODE,ENAB,RESET,CLK,AMPL,FEED,BIAS,LFSRTB) DSC_SND_ENTRY( NODE, dss_lfsr_noise , DSS_NODE , 6, DSE( ENAB,RESET,CLK,AMPL,FEED,BIAS ), DSE( ENAB,RESET,CLK,AMPL,FEED,BIAS ), LFSRTB, "DISCRETE_LFSR_NOISE" ),
+#define DISCRETE_NOISE(NODE,ENAB,FREQ,AMPL,BIAS) DSC_SND_ENTRY( NODE, dss_noise , DSS_NODE , 4, DSE( ENAB,FREQ,AMPL,BIAS ), DSE( ENAB,FREQ,AMPL,BIAS ), NULL, "DISCRETE_NOISE" ),
+#define DISCRETE_NOTE(NODE,ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE) DSC_SND_ENTRY( NODE, dss_note , DSS_NODE , 6, DSE( ENAB,CLK,DATA,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,CLK,DATA,MAX1,MAX2,CLKTYPE ), NULL, "DISCRETE_NOTE" ),
+#define DISCRETE_SAWTOOTHWAVE(NODE,ENAB,FREQ,AMPL,BIAS,GRAD,PHASE) DSC_SND_ENTRY( NODE, dss_sawtoothwave, DSS_NODE , 6, DSE( ENAB,FREQ,AMPL,BIAS,NODE_NC,NODE_NC ), DSE( ENAB,FREQ,AMPL,BIAS,GRAD,PHASE ), NULL, "DISCRETE_SAWTOOTHWAVE" ),
+#define DISCRETE_SINEWAVE(NODE,ENAB,FREQ,AMPL,BIAS,PHASE) DSC_SND_ENTRY( NODE, dss_sinewave , DSS_NODE , 5, DSE( ENAB,FREQ,AMPL,BIAS,NODE_NC ), DSE( ENAB,FREQ,AMPL,BIAS,PHASE ), NULL, "DISCRETE_SINEWAVE" ),
+#define DISCRETE_SQUAREWAVE(NODE,ENAB,FREQ,AMPL,DUTY,BIAS,PHASE) DSC_SND_ENTRY( NODE, dss_squarewave , DSS_NODE , 6, DSE( ENAB,FREQ,AMPL,DUTY,BIAS,NODE_NC ), DSE( ENAB,FREQ,AMPL,DUTY,BIAS,PHASE ), NULL, "DISCRETE_SQUAREWAVE" ),
+#define DISCRETE_SQUAREWFIX(NODE,ENAB,FREQ,AMPL,DUTY,BIAS,PHASE) DSC_SND_ENTRY( NODE, dss_squarewfix , DSS_NODE , 6, DSE( ENAB,FREQ,AMPL,DUTY,BIAS,NODE_NC ), DSE( ENAB,FREQ,AMPL,DUTY,BIAS,PHASE ), NULL, "DISCRETE_SQUAREWFIX" ),
+#define DISCRETE_SQUAREWAVE2(NODE,ENAB,AMPL,T_OFF,T_ON,BIAS,TSHIFT) DSC_SND_ENTRY( NODE, dss_squarewave2 , DSS_NODE , 6, DSE( ENAB,AMPL,T_OFF,T_ON,BIAS,NODE_NC ), DSE( ENAB,AMPL,T_OFF,T_ON,BIAS,TSHIFT ), NULL, "DISCRETE_SQUAREWAVE2" ),
+#define DISCRETE_TRIANGLEWAVE(NODE,ENAB,FREQ,AMPL,BIAS,PHASE) DSC_SND_ENTRY( NODE, dss_trianglewave, DSS_NODE , 5, DSE( ENAB,FREQ,AMPL,BIAS,NODE_NC ), DSE( ENAB,FREQ,AMPL,BIAS,PHASE ), NULL, "DISCRETE_TRIANGLEWAVE" ),
+/* Component specific */
+#define DISCRETE_INVERTER_OSC(NODE,ENAB,MOD,RCHARGE,RP,C,R2,INFO) DSC_SND_ENTRY( NODE, dss_inverter_osc, DSS_NODE , 6, DSE( ENAB,MOD,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,MOD,RCHARGE,RP,C,R2 ), INFO, "DISCRETE_INVERTER_OSC" ),
+#define DISCRETE_OP_AMP_OSCILLATOR(NODE,ENAB,INFO) DSC_SND_ENTRY( NODE, dss_op_amp_osc , DSS_NODE , 1, DSE( ENAB ), DSE( ENAB ), INFO, "DISCRETE_OP_AMP_OSCILLATOR" ),
+#define DISCRETE_OP_AMP_VCO1(NODE,ENAB,VMOD1,INFO) DSC_SND_ENTRY( NODE, dss_op_amp_osc , DSS_NODE , 2, DSE( ENAB,VMOD1 ), DSE( ENAB,VMOD1 ), INFO, "DISCRETE_OP_AMP_VCO1" ),
+#define DISCRETE_OP_AMP_VCO2(NODE,ENAB,VMOD1,VMOD2,INFO) DSC_SND_ENTRY( NODE, dss_op_amp_osc , DSS_NODE , 3, DSE( ENAB,VMOD1,VMOD2 ), DSE( ENAB,VMOD1,VMOD2 ), INFO, "DISCRETE_OP_AMP_VCO2" ),
+#define DISCRETE_SCHMITT_OSCILLATOR(NODE,ENAB,INP0,AMPL,TABLE) DSC_SND_ENTRY( NODE, dss_schmitt_osc , DSS_NODE , 3, DSE( ENAB,INP0,AMPL ), DSE( ENAB,INP0,AMPL ), TABLE, "DISCRETE_SCHMITT_OSCILLATOR" ),
+/* Not yet implemented */
+#define DISCRETE_ADSR_ENV(NODE,ENAB,TRIGGER,GAIN,ADSRTB) DSC_SND_ENTRY( NODE, dss_adsr , DSS_NODE , 3, DSE( ENAB,TRIGGER,GAIN ), DSE( ENAB,TRIGGER,GAIN ), ADSRTB, "DISCRETE_ADSR_ENV" ),
+
+/* from disc_mth.c */
+/* generic modules */
+#define DISCRETE_ADDER2(NODE,ENAB,INP0,INP1) DSC_SND_ENTRY( NODE, dst_adder , DSS_NODE , 3, DSE( ENAB,INP0,INP1 ), DSE( ENAB,INP0,INP1 ), NULL, "DISCRETE_ADDER2" ),
+#define DISCRETE_ADDER3(NODE,ENAB,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_adder , DSS_NODE , 4, DSE( ENAB,INP0,INP1,INP2 ), DSE( ENAB,INP0,INP1,INP2 ), NULL, "DISCRETE_ADDER3" ),
+#define DISCRETE_ADDER4(NODE,ENAB,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_adder , DSS_NODE , 5, DSE( ENAB,INP0,INP1,INP2,INP3 ), DSE( ENAB,INP0,INP1,INP2,INP3 ), NULL, "DISCRETE_ADDER4" ),
+#define DISCRETE_CLAMP(NODE,INP0,MIN,MAX) DSC_SND_ENTRY( NODE, dst_clamp , DSS_NODE , 3, DSE( INP0,MIN,MAX ), DSE( INP0,MIN,MAX ), NULL, "DISCRETE_CLAMP" ),
+#define DISCRETE_DIVIDE(NODE,ENAB,INP0,INP1) DSC_SND_ENTRY( NODE, dst_divide , DSS_NODE , 3, DSE( ENAB,INP0,INP1 ), DSE( ENAB,INP0,INP1 ), NULL, "DISCRETE_DIVIDE" ),
+#define DISCRETE_GAIN(NODE,INP0,GAIN) DSC_SND_ENTRY( NODE, dst_gain , DSS_NODE , 3, DSE( INP0,NODE_NC,NODE_NC ), DSE( INP0,GAIN,0 ), NULL, "DISCRETE_GAIN" ),
+#define DISCRETE_INVERT(NODE,INP0) DSC_SND_ENTRY( NODE, dst_gain , DSS_NODE , 3, DSE( INP0,NODE_NC,NODE_NC ), DSE( INP0,-1,0 ), NULL, "DISCRETE_INVERT" ),
+#define DISCRETE_LOGIC_INVERT(NODE,INP0) DSC_SND_ENTRY( NODE, dst_logic_inv , DSS_NODE , 1, DSE( INP0 ), DSE( INP0 ), NULL, "DISCRETE_LOGIC_INVERT" ),
+
+#define DISCRETE_BIT_DECODE(NODE, INP, BIT_N, VOUT) DSC_SND_ENTRY( NODE, dst_bits_decode , DSS_NODE , 4, DSE( INP,NODE_NC,NODE_NC,NODE_NC ), DSE( INP,BIT_N,BIT_N,VOUT ), NULL, "DISCRETE_BIT_DECODE" ),
+#define DISCRETE_BITS_DECODE(NODE, INP, BIT_FROM, BIT_TO, VOUT) DSC_SND_ENTRY( NODE, dst_bits_decode , DSS_NODE , 4, DSE( INP,NODE_NC,NODE_NC,NODE_NC ), DSE( INP,BIT_FROM,BIT_TO,VOUT ), NULL, "DISCRETE_BITS_DECODE" ),
+
+#define DISCRETE_LOGIC_AND(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_and , DSS_NODE , 4, DSE( INP0,INP1,NODE_NC,NODE_NC ), DSE( INP0,INP1,1.0,1.0 ), NULL, "DISCRETE_LOGIC_AND" ),
+#define DISCRETE_LOGIC_AND3(NODE,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_logic_and , DSS_NODE , 4, DSE( INP0,INP1,INP2,NODE_NC ), DSE( INP0,INP1,INP2,1.0 ), NULL, "DISCRETE_LOGIC_AND3" ),
+#define DISCRETE_LOGIC_AND4(NODE,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_logic_and , DSS_NODE , 4, DSE( INP0,INP1,INP2,INP3 ), DSE( INP0,INP1,INP2,INP3 ) ,NULL, "DISCRETE_LOGIC_AND4" ),
+#define DISCRETE_LOGIC_NAND(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_nand , DSS_NODE , 4, DSE( INP0,INP1,NODE_NC,NODE_NC ), DSE( INP0,INP1,1.0,1.0 ), NULL, "DISCRETE_LOGIC_NAND" ),
+#define DISCRETE_LOGIC_NAND3(NODE,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_logic_nand , DSS_NODE , 4, DSE( INP0,INP1,INP2,NODE_NC ), DSE( INP0,INP1,INP2,1.0 ), NULL, "DISCRETE_LOGIC_NAND3" ),
+#define DISCRETE_LOGIC_NAND4(NODE,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_logic_nand , DSS_NODE , 4, DSE( INP0,INP1,INP2,INP3 ), DSE( INP0,INP1,INP2,INP3 ), NULL, ")DISCRETE_LOGIC_NAND4" ),
+#define DISCRETE_LOGIC_OR(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_or , DSS_NODE , 4, DSE( INP0,INP1,NODE_NC,NODE_NC ), DSE( INP0,INP1,0.0,0.0 ), NULL, "DISCRETE_LOGIC_OR" ),
+#define DISCRETE_LOGIC_OR3(NODE,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_logic_or , DSS_NODE , 4, DSE( INP0,INP1,INP2,NODE_NC ), DSE( INP0,INP1,INP2,0.0 ), NULL, "DISCRETE_LOGIC_OR3" ),
+#define DISCRETE_LOGIC_OR4(NODE,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_logic_or , DSS_NODE , 4, DSE( INP0,INP1,INP2,INP3 ), DSE( INP0,INP1,INP2,INP3 ), NULL, "DISCRETE_LOGIC_OR4" ),
+#define DISCRETE_LOGIC_NOR(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_nor , DSS_NODE , 4, DSE( INP0,INP1,NODE_NC,NODE_NC ), DSE( INP0,INP1,0.0,0.0 ), NULL, "DISCRETE_LOGIC_NOR" ),
+#define DISCRETE_LOGIC_NOR3(NODE,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_logic_nor , DSS_NODE , 4, DSE( INP0,INP1,INP2,NODE_NC ), DSE( INP0,INP1,INP2,0.0 ), NULL, "DISCRETE_LOGIC_NOR3" ),
+#define DISCRETE_LOGIC_NOR4(NODE,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_logic_nor , DSS_NODE , 4, DSE( INP0,INP1,INP2,INP3 ), DSE( INP0,INP1,INP2,INP3 ), NULL, "DISCRETE_LOGIC_NOR4" ),
+#define DISCRETE_LOGIC_XOR(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_xor , DSS_NODE , 2, DSE( INP0,INP1 ), DSE( INP0,INP1 ), NULL, "DISCRETE_LOGIC_XOR" ),
+#define DISCRETE_LOGIC_XNOR(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_logic_nxor , DSS_NODE , 2, DSE( INP0,INP1 ), DSE( INP0,INP1 ), NULL, "DISCRETE_LOGIC_XNOR" ),
+#define DISCRETE_LOGIC_DFLIPFLOP(NODE,RESET,SET,CLK,INP) DSC_SND_ENTRY( NODE, dst_logic_dff , DSS_NODE , 4, DSE( RESET,SET,CLK,INP ), DSE( RESET,SET,CLK,INP ), NULL, "DISCRETE_LOGIC_DFLIPFLOP" ),
+#define DISCRETE_LOGIC_JKFLIPFLOP(NODE,RESET,SET,CLK,J,K) DSC_SND_ENTRY( NODE, dst_logic_jkff , DSS_NODE , 5, DSE( RESET,SET,CLK,J,K ), DSE( RESET,SET,CLK,J,K ), NULL, "DISCRETE_LOGIC_JKFLIPFLOP" ),
+#define DISCRETE_LOGIC_SHIFT(NODE,INP0,RESET,CLK,SIZE,OPTIONS) DSC_SND_ENTRY( NODE, dst_logic_shift , DSS_NODE , 5, DSE( INP0,RESET,CLK,NODE_NC,NODE_NC ), DSE( INP0,RESET,CLK,SIZE,OPTIONS ), NULL, "DISCRETE_LOGIC_SHIFT" ),
+#define DISCRETE_LOOKUP_TABLE(NODE,ADDR,SIZE,TABLE) DSC_SND_ENTRY( NODE, dst_lookup_table, DSS_NODE , 2, DSE( ADDR,NODE_NC ), DSE( ADDR,SIZE ), TABLE, "DISCRETE_LOOKUP_TABLE" ),
+#define DISCRETE_MULTIPLEX2(NODE,ADDR,INP0,INP1) DSC_SND_ENTRY( NODE, dst_multiplex , DSS_NODE , 3, DSE( ADDR,INP0,INP1 ), DSE( ADDR,INP0,INP1 ), NULL, "DISCRETE_MULTIPLEX2" ),
+#define DISCRETE_MULTIPLEX4(NODE,ADDR,INP0,INP1,INP2,INP3) DSC_SND_ENTRY( NODE, dst_multiplex , DSS_NODE , 5, DSE( ADDR,INP0,INP1,INP2,INP3 ), DSE( ADDR,INP0,INP1,INP2,INP3 ), NULL, "DISCRETE_MULTIPLEX4" ),
+#define DISCRETE_MULTIPLEX8(NODE,ADDR,INP0,INP1,INP2,INP3,INP4,INP5,INP6,INP7) DSC_SND_ENTRY( NODE, dst_multiplex, DSS_NODE , 9, DSE( ADDR,INP0,INP1,INP2,INP3,INP4,INP5,INP6,INP7 ), DSE( ADDR,INP0,INP1,INP2,INP3,INP4,INP5,INP6,INP7 ), NULL, "DISCRETE_MULTIPLEX8" ),
+#define DISCRETE_MULTIPLY(NODE,INP0,INP1) DSC_SND_ENTRY( NODE, dst_gain , DSS_NODE , 3, DSE( INP0,INP1,NODE_NC ), DSE( INP0,INP1,0 ), NULL, "DISCRETE_MULTIPLY" ),
+#define DISCRETE_MULTADD(NODE,INP0,INP1,INP2) DSC_SND_ENTRY( NODE, dst_gain , DSS_NODE , 3, DSE( INP0,INP1,INP2 ), DSE( INP0,INP1,INP2 ), NULL, "DISCRETE_MULTADD" ),
+#define DISCRETE_ONESHOT(NODE,TRIG,AMPL,WIDTH,TYPE) DSC_SND_ENTRY( NODE, dst_oneshot , DSS_NODE , 5, DSE( 0,TRIG,AMPL,WIDTH,NODE_NC ), DSE( 0,TRIG,AMPL,WIDTH,TYPE ), NULL, "DISCRETE_ONESHOT" ),
+#define DISCRETE_ONESHOTR(NODE,RESET,TRIG,AMPL,WIDTH,TYPE) DSC_SND_ENTRY( NODE, dst_oneshot , DSS_NODE , 5, DSE( RESET,TRIG,AMPL,WIDTH,NODE_NC ), DSE( RESET,TRIG,AMPL,WIDTH,TYPE ), NULL, "One Shot Resetable" ),
+#define DISCRETE_ONOFF(NODE,ENAB,INP0) DSC_SND_ENTRY( NODE, dst_gain , DSS_NODE , 3, DSE( ENAB,INP0,NODE_NC ), DSE( 0,1,0 ), NULL, "DISCRETE_ONOFF" ),
+#define DISCRETE_RAMP(NODE,ENAB,RAMP,GRAD,START,END,CLAMP) DSC_SND_ENTRY( NODE, dst_ramp , DSS_NODE , 6, DSE( ENAB,RAMP,GRAD,START,END,CLAMP ), DSE( ENAB,RAMP,GRAD,START,END,CLAMP ), NULL, "DISCRETE_RAMP" ),
+#define DISCRETE_SAMPLHOLD(NODE,INP0,CLOCK,CLKTYPE) DSC_SND_ENTRY( NODE, dst_samphold , DSS_NODE , 3, DSE( INP0,CLOCK,NODE_NC ), DSE( INP0,CLOCK,CLKTYPE ), NULL, "DISCRETE_SAMPLHOLD" ),
+#define DISCRETE_SWITCH(NODE,ENAB,SWITCH,INP0,INP1) DSC_SND_ENTRY( NODE, dst_switch , DSS_NODE , 4, DSE( ENAB,SWITCH,INP0,INP1 ), DSE( ENAB,SWITCH,INP0,INP1 ), NULL, "DISCRETE_SWITCH" ),
+#define DISCRETE_ASWITCH(NODE,CTRL,INP,THRESHOLD) DSC_SND_ENTRY( NODE, dst_aswitch , DSS_NODE , 3, DSE( CTRL,INP,THRESHOLD ), DSE( CTRL,INP, THRESHOLD), NULL, "Analog Switch" ),
+#define DISCRETE_TRANSFORM2(NODE,INP0,INP1,FUNCT) DSC_SND_ENTRY( NODE, dst_transform , DSS_NODE , 2, DSE( INP0,INP1 ), DSE( INP0,INP1 ), FUNCT, "DISCRETE_TRANSFORM2" ),
+#define DISCRETE_TRANSFORM3(NODE,INP0,INP1,INP2,FUNCT) DSC_SND_ENTRY( NODE, dst_transform , DSS_NODE , 3, DSE( INP0,INP1,INP2 ), DSE( INP0,INP1,INP2 ), FUNCT, "DISCRETE_TRANSFORM3" ),
+#define DISCRETE_TRANSFORM4(NODE,INP0,INP1,INP2,INP3,FUNCT) DSC_SND_ENTRY( NODE, dst_transform , DSS_NODE , 4, DSE( INP0,INP1,INP2,INP3 ), DSE( INP0,INP1,INP2,INP3 ), FUNCT, "DISCRETE_TRANSFORM4" ),
+#define DISCRETE_TRANSFORM5(NODE,INP0,INP1,INP2,INP3,INP4,FUNCT) DSC_SND_ENTRY( NODE, dst_transform , DSS_NODE , 5, DSE( INP0,INP1,INP2,INP3,INP4 ), DSE( INP0,INP1,INP2,INP3,INP4 ), FUNCT, "DISCRETE_TRANSFORM5" ),
+/* Component specific */
+#define DISCRETE_COMP_ADDER(NODE,DATA,TABLE) DSC_SND_ENTRY( NODE, dst_comp_adder , DSS_NODE , 1, DSE( DATA ), DSE( DATA ), TABLE, "DISCRETE_COMP_ADDER" ),
+#define DISCRETE_DAC_R1(NODE,DATA,VDATA,LADDER) DSC_SND_ENTRY( NODE, dst_dac_r1 , DSS_NODE , 2, DSE( DATA,NODE_NC ), DSE( DATA,VDATA ), LADDER, "DISCRETE_DAC_R1" ),
+#define DISCRETE_DIODE_MIXER2(NODE,IN0,IN1,TABLE) DSC_SND_ENTRY( NODE, dst_diode_mix , DSS_NODE , 3, DSE( IN0,IN1 ), DSE( IN0,IN1 ), TABLE, "DISCRETE_DIODE_MIXER2" ),
+#define DISCRETE_DIODE_MIXER3(NODE,IN0,IN1,IN2,TABLE) DSC_SND_ENTRY( NODE, dst_diode_mix , DSS_NODE , 4, DSE( IN0,IN1,IN2 ), DSE( IN0,IN1,IN2 ), TABLE, "DISCRETE_DIODE_MIXER3" ),
+#define DISCRETE_DIODE_MIXER4(NODE,IN0,IN1,IN2,IN3,TABLE) DSC_SND_ENTRY( NODE, dst_diode_mix , DSS_NODE , 5, DSE( IN0,IN1,IN2,IN3 ), DSE( IN0,IN1,IN2,IN3 ), TABLE, "DISCRETE_DIODE_MIXER4" ),
+#define DISCRETE_INTEGRATE(NODE,TRG0,TRG1,INFO) DSC_SND_ENTRY( NODE, dst_integrate , DSS_NODE , 2, DSE( TRG0,TRG1 ), DSE( TRG0,TRG1 ), INFO, "DISCRETE_INTEGRATE" ),
+#define DISCRETE_MIXER2(NODE,ENAB,IN0,IN1,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 3, DSE( ENAB,IN0,IN1 ), DSE( ENAB,IN0,IN1 ), INFO, "DISCRETE_MIXER2" ),
+#define DISCRETE_MIXER3(NODE,ENAB,IN0,IN1,IN2,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 4, DSE( ENAB,IN0,IN1,IN2 ), DSE( ENAB,IN0,IN1,IN2 ), INFO, "DISCRETE_MIXER3" ),
+#define DISCRETE_MIXER4(NODE,ENAB,IN0,IN1,IN2,IN3,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 5, DSE( ENAB,IN0,IN1,IN2,IN3 ), DSE( ENAB,IN0,IN1,IN2,IN3 ), INFO, "DISCRETE_MIXER4" ),
+#define DISCRETE_MIXER5(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 6, DSE( ENAB,IN0,IN1,IN2,IN3,IN4 ), DSE( ENAB,IN0,IN1,IN2,IN3,IN4 ), INFO, "DISCRETE_MIXER5" ),
+#define DISCRETE_MIXER6(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 7, DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5 ), DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5 ), INFO, "DISCRETE_MIXER6" ),
+#define DISCRETE_MIXER7(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 8, DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6 ), DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6 ), INFO, "DISCRETE_MIXER7" ),
+#define DISCRETE_MIXER8(NODE,ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DSS_NODE , 9, DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 ), DSE( ENAB,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 ), INFO, "DISCRETE_MIXER8" ),
+#define DISCRETE_OP_AMP(NODE,ENAB,IN0,IN1,INFO) DSC_SND_ENTRY( NODE, dst_op_amp , DSS_NODE , 3, DSE( ENAB,IN0,IN1 ), DSE( ENAB,IN0,IN1 ), INFO, "DISCRETE_OP_AMP" ),
+#define DISCRETE_OP_AMP_ONESHOT(NODE,TRIG,INFO) DSC_SND_ENTRY( NODE, dst_op_amp_1sht , DSS_NODE , 1, DSE( TRIG ), DSE( TRIG ), INFO, "DISCRETE_OP_AMP_ONESHOT" ),
+#define DISCRETE_OP_AMP_TRIG_VCA(NODE,TRG0,TRG1,TRG2,IN0,IN1,INFO) DSC_SND_ENTRY( NODE, dst_tvca_op_amp , DSS_NODE , 5, DSE( TRG0,TRG1,TRG2,IN0,IN1 ), DSE( TRG0,TRG1,TRG2,IN0,IN1 ), INFO, "DISCRETE_OP_AMP_TRIG_VCA" ),
+#define DISCRETE_VCA(NODE,ENAB,IN0,CTRL,TYPE) DSC_SND_ENTRY( NODE, dst_vca , DSS_NODE , 4, DSE( ENAB,IN0,CTRL,NODE_NC ), DSE( ENAB,IN0,CTRL,TYPE ), NULL, "DISCRETE_VCA" ),
+#define DISCRETE_XTIME_BUFFER(NODE,IN0,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_buffer, DSS_NODE , 4, DSE( IN0,LOW,HIGH,NODE_NC ), DSE( IN0,LOW,HIGH,0 ), NULL, "DISCRETE_XTIME_BUFFER" ),
+#define DISCRETE_XTIME_INVERTER(NODE,IN0,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_buffer, DSS_NODE , 4, DSE( IN0,LOW,HIGH,NODE_NC ), DSE( IN0,LOW,HIGH,1 ), NULL, "DISCRETE_XTIME_INVERTER" ),
+#define DISCRETE_XTIME_AND(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_and , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,0 ), NULL, "DISCRETE_XTIME_AND" ),
+#define DISCRETE_XTIME_NAND(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_and , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,1 ), NULL, "DISCRETE_XTIME_NAND" ),
+#define DISCRETE_XTIME_OR(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_or , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,0 ), NULL, "DISCRETE_XTIME_OR" ),
+#define DISCRETE_XTIME_NOR(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_or , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,1 ), NULL, "DISCRETE_XTIME_NOR" ),
+#define DISCRETE_XTIME_XOR(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_xor , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,0 ), NULL, "DISCRETE_XTIME_XOR" ),
+#define DISCRETE_XTIME_XNOR(NODE,IN0,IN1,LOW,HIGH) DSC_SND_ENTRY( NODE, dst_xtime_xnor , DSS_NODE , 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,1 ), NULL, "DISCRETE_XTIME_XNOR" ),
+
+/* from disc_flt.c */
+/* generic modules */
+#define DISCRETE_FILTER1(NODE,ENAB,INP0,FREQ,TYPE) DSC_SND_ENTRY( NODE, dst_filter1 , DSS_NODE , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,FREQ,TYPE ), NULL, "DISCRETE_FILTER1" ),
+#define DISCRETE_FILTER2(NODE,ENAB,INP0,FREQ,DAMP,TYPE) DSC_SND_ENTRY( NODE, dst_filter2 , DSS_NODE , 5, DSE( ENAB,INP0,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,INP0,FREQ,DAMP,TYPE ), NULL, "DISCRETE_FILTER2" ),
+/* Component specific */
+#define DISCRETE_SALLEN_KEY_FILTER(NODE,ENAB,INP0,TYPE,INFO) DSC_SND_ENTRY( NODE, dst_sallen_key , DSS_NODE , 3, DSE( ENAB,INP0,NODE_NC ), DSE( ENAB,INP0,TYPE ), INFO, "DISCRETE_SALLEN_KEY_FILTER" ),
+#define DISCRETE_CRFILTER(NODE,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_crfilter , DSS_NODE , 4, DSE( INP0,RVAL,CVAL ), DSE( INP0,RVAL,CVAL ), NULL, "DISCRETE_CRFILTER" ),
+#define DISCRETE_CRFILTER_VREF(NODE,INP0,RVAL,CVAL,VREF) DSC_SND_ENTRY( NODE, dst_crfilter , DSS_NODE , 5, DSE( INP0,RVAL,CVAL,VREF ), DSE( INP0,RVAL,CVAL,VREF ), NULL, "DISCRETE_CRFILTER_VREF" ),
+#define DISCRETE_OP_AMP_FILTER(NODE,ENAB,INP0,INP1,TYPE,INFO) DSC_SND_ENTRY( NODE, dst_op_amp_filt , DSS_NODE , 4, DSE( ENAB,INP0,INP1,NODE_NC ), DSE( ENAB,INP0,INP1,TYPE ), INFO, "DISCRETE_OP_AMP_FILTER" ),
+#define DISCRETE_RC_CIRCUIT_1(NODE,INP0,INP1,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rc_circuit_1, DSS_NODE , 4, DSE( INP0,INP1,NODE_NC,NODE_NC ), DSE( INP0,INP1,RVAL,CVAL ), NULL, "DISCRETE_RC_CIRCUIT_1" ),
+#define DISCRETE_RCDISC(NODE,ENAB,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rcdisc , DSS_NODE , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL,CVAL ), NULL, "DISCRETE_RCDISC" ),
+#define DISCRETE_RCDISC2(NODE,SWITCH,INP0,RVAL0,INP1,RVAL1,CVAL) DSC_SND_ENTRY( NODE, dst_rcdisc2 , DSS_NODE , 6, DSE( SWITCH,INP0,NODE_NC,INP1,NODE_NC,NODE_NC ), DSE( SWITCH,INP0,RVAL0,INP1,RVAL1,CVAL ), NULL, "DISCRETE_RCDISC2" ),
+#define DISCRETE_RCDISC3(NODE,ENAB,INP0,RVAL0,RVAL1,CVAL,DJV) DSC_SND_ENTRY( NODE, dst_rcdisc3 , DSS_NODE , 6, DSE( ENAB,INP0,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL0,RVAL1,CVAL,DJV ), NULL, "DISCRETE_RCDISC3" ),
+#define DISCRETE_RCDISC4(NODE,ENAB,INP0,RVAL0,RVAL1,RVAL2,CVAL,VP,TYPE) DSC_SND_ENTRY( NODE, dst_rcdisc4 , DSS_NODE , 8, DSE( ENAB,INP0,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL0,RVAL1,RVAL2,CVAL,VP,TYPE ), NULL, "DISCRETE_RCDISC4" ),
+#define DISCRETE_RCDISC5(NODE,ENAB,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rcdisc5 , DSS_NODE , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL,CVAL ), NULL, "DISCRETE_RCDISC5" ),
+#define DISCRETE_RCDISC_MODULATED(NODE,INP0,INP1,RVAL0,RVAL1,RVAL2,RVAL3,CVAL,VP) DSC_SND_ENTRY( NODE, dst_rcdisc_mod, DSS_NODE , 8, DSE( INP0,INP1,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( INP0,INP1,RVAL0,RVAL1,RVAL2,RVAL3,CVAL,VP ), NULL, "DISCRETE_RCDISC_MODULATED" ),
+#define DISCRETE_RCFILTER(NODE,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rcfilter , DSS_NODE , 3, DSE( INP0,RVAL,CVAL ), DSE( INP0,RVAL,CVAL ), NULL, "DISCRETE_RCFILTER" ),
+#define DISCRETE_RCFILTER_VREF(NODE,INP0,RVAL,CVAL,VREF) DSC_SND_ENTRY( NODE, dst_rcfilter , DSS_NODE , 4, DSE( INP0,RVAL,CVAL,VREF ), DSE( INP0,RVAL,CVAL,VREF ), NULL, "DISCRETE_RCFILTER_VREF" ),
+#define DISCRETE_RCFILTER_SW(NODE,ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4) DSC_SND_ENTRY( NODE, dst_rcfilter_sw, DSS_NODE , 8, DSE( ENAB,INP0,SW,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,INP0,SW,RVAL,CVAL1,CVAL2,CVAL3,CVAL4 ), NULL, "DISCRETE_RCFILTER_SW" ),
+#define DISCRETE_RCINTEGRATE(NODE,INP0,RVAL0,RVAL1,RVAL2,CVAL,vP,TYPE) DSC_SND_ENTRY( NODE, dst_rcintegrate , DSS_NODE , 7, DSE( INP0,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( INP0,RVAL0,RVAL1,RVAL2,CVAL,vP,TYPE ), NULL, "DISCRETE_RCINTEGRATE" ),
+/* For testing - seem to be buggered. Use versions not ending in N. */
+#define DISCRETE_RCDISCN(NODE,ENAB,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rcdiscn , DSS_NODE , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL,CVAL ), NULL, "DISCRETE_RCDISCN" ),
+#define DISCRETE_RCDISC2N(NODE,SWITCH,INP0,RVAL0,INP1,RVAL1,CVAL) DSC_SND_ENTRY( NODE, dst_rcdisc2n , DSS_NODE , 6, DSE( SWITCH,INP0,NODE_NC,INP1,NODE_NC,NODE_NC ), DSE( SWITCH,INP0,RVAL0,INP1,RVAL1,CVAL ), NULL, "DISCRETE_RCDISC2N" ),
+#define DISCRETE_RCFILTERN(NODE,ENAB,INP0,RVAL,CVAL) DSC_SND_ENTRY( NODE, dst_rcfiltern , DSS_NODE , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL,CVAL ), NULL, "DISCRETE_RCFILTERN" ),
+
+/* from disc_dev.c */
+/* generic modules */
+#define DISCRETE_CUSTOM1(NODE,CLASS,IN0,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 1, DSE( IN0 ), DSE( IN0 ), INFO, "DISCRETE_CUSTOM1" ),
+#define DISCRETE_CUSTOM2(NODE,CLASS,IN0,IN1,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 2, DSE( IN0,IN1 ), DSE( IN0,IN1 ), INFO, "DISCRETE_CUSTOM2" ),
+#define DISCRETE_CUSTOM3(NODE,CLASS,IN0,IN1,IN2,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 3, DSE( IN0,IN1,IN2 ), DSE( IN0,IN1,IN2 ), INFO, "DISCRETE_CUSTOM3" ),
+#define DISCRETE_CUSTOM4(NODE,CLASS,IN0,IN1,IN2,IN3,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 4, DSE( IN0,IN1,IN2,IN3 ), DSE( IN0,IN1,IN2,IN3 ), INFO, "DISCRETE_CUSTOM4" ),
+#define DISCRETE_CUSTOM5(NODE,CLASS,IN0,IN1,IN2,IN3,IN4,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 5, DSE( IN0,IN1,IN2,IN3,IN4 ), DSE( IN0,IN1,IN2,IN3,IN4 ), INFO, "DISCRETE_CUSTOM5" ),
+#define DISCRETE_CUSTOM6(NODE,CLASS,IN0,IN1,IN2,IN3,IN4,IN5,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 6, DSE( IN0,IN1,IN2,IN3,IN4,IN5 ), DSE( IN0,IN1,IN2,IN3,IN4,IN5 ), INFO, "DISCRETE_CUSTOM6" ),
+#define DISCRETE_CUSTOM7(NODE,CLASS,IN0,IN1,IN2,IN3,IN4,IN5,IN6,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 7, DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6 ), DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6 ), INFO, "DISCRETE_CUSTOM7" ),
+#define DISCRETE_CUSTOM8(NODE,CLASS,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 8, DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 ), DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7 ), INFO, "DISCRETE_CUSTOM8" ),
+#define DISCRETE_CUSTOM9(NODE,CLASS,IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8,INFO) DSC_SND_ENTRY( NODE, CLASS, DST_CUSTOM , 9, DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8 ), DSE( IN0,IN1,IN2,IN3,IN4,IN5,IN6,IN7,IN8 ), INFO, "DISCRETE_CUSTOM9" ),
+
+/* Component specific */
+#define DISCRETE_555_ASTABLE(NODE,RESET,R1,R2,C,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_astbl , DSS_NODE , 5, DSE( RESET,R1,R2,C,NODE_NC ), DSE( RESET,R1,R2,C,-1 ), OPTIONS, "DISCRETE_555_ASTABLE" ),
+#define DISCRETE_555_ASTABLE_CV(NODE,RESET,R1,R2,C,CTRLV,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_astbl , DSS_NODE , 5, DSE( RESET,R1,R2,C,CTRLV ), DSE( RESET,R1,R2,C,CTRLV ), OPTIONS, "DISCRETE_555_ASTABLE_CV" ),
+#define DISCRETE_555_MSTABLE(NODE,RESET,TRIG,R,C,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_mstbl , DSS_NODE , 4, DSE( RESET,TRIG,R,C ), DSE( RESET,TRIG,R,C ), OPTIONS, "DISCRETE_555_MSTABLE" ),
+#define DISCRETE_555_CC(NODE,RESET,VIN,R,C,RBIAS,RGND,RDIS,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_cc , DSS_NODE , 7, DSE( RESET,VIN,R,C,RBIAS,RGND,RDIS ), DSE( RESET,VIN,R,C,RBIAS,RGND,RDIS ), OPTIONS, "DISCRETE_555_CC" ),
+#define DISCRETE_555_VCO1(NODE,RESET,VIN,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_vco1 , DSS_NODE , 3, DSE( RESET,VIN,NODE_NC ), DSE( RESET,VIN,-1 ), OPTIONS, "DISCRETE_555_VCO1" ),
+#define DISCRETE_555_VCO1_CV(NODE,RESET,VIN,CTRLV,OPTIONS) DSC_SND_ENTRY( NODE, dsd_555_vco1 , DSS_NODE , 3, DSE( RESET,VIN,CTRLV ), DSE( RESET,VIN,CTRLV ), OPTIONS, "DISCRETE_555_VCO1_CV" ),
+#define DISCRETE_566(NODE,VMOD,R,C,VPOS,VNEG,VCHARGE,OPTIONS) DSC_SND_ENTRY( NODE, dsd_566 , DSS_NODE , 7, DSE( VMOD,R,C,NODE_NC,NODE_NC,VCHARGE,NODE_NC ), DSE( VMOD,R,C,VPOS,VNEG,VCHARGE,OPTIONS ), NULL, "DISCRETE_566" ),
+#define DISCRETE_74LS624(NODE,ENAB,VMOD,VRNG,C,R_FREQ_IN,C_FREQ_IN,R_RNG_IN,OUTTYPE) DSC_SND_ENTRY( NODE, dsd_ls624 , DSS_NODE , 8, DSE( ENAB,VMOD,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,VMOD,VRNG,C,R_FREQ_IN,C_FREQ_IN,R_RNG_IN,OUTTYPE ), NULL, "DISCRETE_74LS624" ),
+
+/* NOP */
+#define DISCRETE_NOP(NODE) DSC_SND_ENTRY( NODE, dss_nop , DSS_NOP , 0, DSE( 0 ), DSE( 0 ), NULL, "DISCRETE_NOP" ),
+
+/* logging */
+#define DISCRETE_CSVLOG1(NODE1) DSC_SND_ENTRY( NODE_SPECIAL, dso_csvlog , DSO_CSVLOG , 1, DSE( NODE1 ), DSE( NODE1 ), NULL, "DISCRETE_CSVLOG1" ),
+#define DISCRETE_CSVLOG2(NODE1,NODE2) DSC_SND_ENTRY( NODE_SPECIAL, dso_csvlog , DSO_CSVLOG , 2, DSE( NODE1,NODE2 ), DSE( NODE1,NODE2 ), NULL, "DISCRETE_CSVLOG2" ),
+#define DISCRETE_CSVLOG3(NODE1,NODE2,NODE3) DSC_SND_ENTRY( NODE_SPECIAL, dso_csvlog , DSO_CSVLOG , 3, DSE( NODE1,NODE2,NODE3 ), DSE( NODE1,NODE2,NODE3 ), NULL, "DISCRETE_CSVLOG3" ),
+#define DISCRETE_CSVLOG4(NODE1,NODE2,NODE3,NODE4) DSC_SND_ENTRY( NODE_SPECIAL, dso_csvlog , DSO_CSVLOG , 4, DSE( NODE1,NODE2,NODE3,NODE4 ), DSE( NODE1,NODE2,NODE3,NODE4 ), NULL, "DISCRETE_CSVLOG4" ),
+#define DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5) DSC_SND_ENTRY( NODE_SPECIAL, dso_csvlog , DSO_CSVLOG , 5, DSE( NODE1,NODE2,NODE3,NODE4,NODE5 ), DSE( NODE1,NODE2,NODE3,NODE4,NODE5 ), NULL, "DISCRETE_CSVLOG5" ),
+#define DISCRETE_WAVLOG1(NODE1,GAIN1) DSC_SND_ENTRY( NODE_SPECIAL, dso_wavlog , DSO_WAVLOG , 2, DSE( NODE1,NODE_NC ), DSE( NODE1,GAIN1 ), NULL, "DISCRETE_WAVLOG1" ),
+#define DISCRETE_WAVLOG2(NODE1,GAIN1,NODE2,GAIN2) DSC_SND_ENTRY( NODE_SPECIAL, dso_wavlog , DSO_WAVLOG , 4, DSE( NODE1,NODE_NC,NODE2,NODE_NC ), DSE( NODE1,GAIN1,NODE2,GAIN2 ), NULL, "DISCRETE_WAVLOG2" ),
+
+/* import */
+#define DISCRETE_IMPORT(INFO) DSC_SND_ENTRY( NODE_SPECIAL, special , DSO_IMPORT , 0, DSE( 0 ), DSE( 0 ), &(INFO##_discrete_interface), "DISCRETE_IMPORT" ),
+#define DISCRETE_DELETE(NODE_FROM, NODE_TO) DSC_SND_ENTRY( NODE_SPECIAL, special , DSO_DELETE , 2, DSE( NODE_FROM, NODE_TO ), DSE( NODE_FROM, NODE_TO ), NULL, "DISCRETE_DELETE" ),
+#define DISCRETE_REPLACE DSC_SND_ENTRY( NODE_SPECIAL, special , DSO_REPLACE , 0, DSE( 0 ), DSE( 0 ), NULL, "DISCRETE_REPLACE" ),
+
+/* parallel tasks */
+
+#define DISCRETE_TASK_START(TASK_GROUP) DSC_SND_ENTRY( NODE_SPECIAL, special , DSO_TASK_START,1, DSE( NODE_NC, NODE_NC ), DSE( TASK_GROUP, 0 ), NULL, "DISCRETE_TASK_START" ),
+#define DISCRETE_TASK_END() DSC_SND_ENTRY( NODE_SPECIAL, special , DSO_TASK_END , 1, DSE( 0 ), DSE( 0 ), NULL, "DISCRETE_TASK_END" ),
+//#define DISCRETE_TASK_SYNC() DSC_SND_ENTRY( NODE_SPECIAL, DSO_TASK_SYNC, 0, DSE( 0 ), DSE( 0 ), NULL, "DISCRETE_TASK_SYNC" ),
+
+/* output */
+#define DISCRETE_OUTPUT(OPNODE,GAIN) DSC_SND_ENTRY( NODE_SPECIAL, dso_output , DSO_OUTPUT ,2, DSE( OPNODE,NODE_NC ), DSE( 0,GAIN ), NULL, "DISCRETE_OUTPUT" ),
+
+
+
+#endif /* __DISCRETE_H__ */