Discrete subsystem: Maintenance commit before I move from linked lists to dynamic arrays.

- Also fixes bzone regression.
- Contexts have disappeared now. All modules use class level private variables now.
- Reorganized code and added more include files.
- This is still work in progress. It is working though.
This commit is contained in:
Couriersud 2011-01-15 13:49:27 +00:00
parent 8d47838f94
commit 156a1efd1c
18 changed files with 2957 additions and 3109 deletions

4
.gitattributes vendored
View File

@ -959,11 +959,15 @@ src/emu/sound/digitalk.c svneol=native#text/plain
src/emu/sound/digitalk.h svneol=native#text/plain
src/emu/sound/disc_cls.h svneol=native#text/plain
src/emu/sound/disc_dev.c svneol=native#text/plain
src/emu/sound/disc_dev.h svneol=native#text/plain
src/emu/sound/disc_flt.c svneol=native#text/plain
src/emu/sound/disc_flt.h svneol=native#text/plain
src/emu/sound/disc_inp.c svneol=native#text/plain
src/emu/sound/disc_mth.c svneol=native#text/plain
src/emu/sound/disc_mth.h svneol=native#text/plain
src/emu/sound/disc_sys.c svneol=native#text/plain
src/emu/sound/disc_wav.c svneol=native#text/plain
src/emu/sound/disc_wav.h svneol=native#text/plain
src/emu/sound/discrete.c svneol=native#text/plain
src/emu/sound/discrete.h svneol=native#text/plain
src/emu/sound/dmadac.c svneol=native#text/plain

View File

@ -18,764 +18,245 @@
*
***********************************************************************/
#define DISCRETE_CLASS_NAME(_name) _name ## _node
#define DISCRETE_CLASS_NAME(_name) discrete_ ## _name ## _node
#define DISCRETE_CLASS_CONSTRUCTOR(_name, _ctxsize) \
#if 0
#define DISCRETE_CLASS_CONSTRUCTOR(_name, _base, _ctxsize) \
DISCRETE_CLASS_NAME(_name)(discrete_device * pdev, const discrete_sound_block *block) \
: discrete_base_node(pdev, block) { m_context_size = _ctxsize; }
: DISCRETE_CLASS_NAME(_base)(pdev, block) { m_context_size = _ctxsize; }
#else
#define DISCRETE_CLASS_CONSTRUCTOR(_name, _base) \
DISCRETE_CLASS_NAME(_name)() \
: DISCRETE_CLASS_NAME(_base)() { }
#endif
#if 1
#define DISCRETE_CLASS_DESTRUCTOR(_name) \
public: \
virtual ~ DISCRETE_CLASS_NAME(_name)(void) { }
#else
#define DISCRETE_CLASS_DESTRUCTOR(_name)
#endif
#define DISCRETE_CLASS_STEP_RESET(_name, _ctxsize, _maxout) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, _ctxsize) \
void step(void); \
void reset(void); \
int max_output(void) { return _maxout; } \
#define DISCRETE_CLASS_STEP_RESETA(_name, _maxout, _priv) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node, public discrete_step_interface \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, base) \
void step(void); \
void reset(void); \
int max_output(void) { return _maxout; } \
DISCRETE_CLASS_DESTRUCTOR(_name) \
private: \
_priv \
}
#define DISCRETE_CLASS_STEP(_name, _ctxsize, _maxout) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, _ctxsize) \
\
void step(void); \
void reset(void) { this->step(); } \
int max_output(void) { return _maxout; } \
#define DISCRETE_CLASS_STEPA(_name, _maxout, _priv) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node, public discrete_step_interface \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, base) \
void step(void); \
void reset(void) { this->step(); } \
int max_output(void) { return _maxout; } \
DISCRETE_CLASS_DESTRUCTOR(_name) \
private: \
_priv \
}
#define DISCRETE_CLASS_RESET(_name, _ctxsize, _maxout) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, _ctxsize) \
void step(void) { } \
void reset(void); \
bool is_stepping(void) { return false; } \
int max_output(void) { return _maxout; } \
#define DISCRETE_CLASS_RESET(_name, _maxout) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, base) \
void reset(void); \
int max_output(void) { return _maxout; } \
DISCRETE_CLASS_DESTRUCTOR(_name) \
}
#define DISCRETE_CLASS(_name, _ctxsize, _maxout) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, _ctxsize) \
void step(void); \
void reset(void); \
void start(void); \
void stop(void); \
bool is_stepping(void); \
int max_output(void) { return _maxout; } \
#define DISCRETE_CLASSA(_name, _maxout, _priv) \
class DISCRETE_CLASS_NAME(_name): public discrete_base_node, public discrete_step_interface \
{ \
public: \
DISCRETE_CLASS_CONSTRUCTOR(_name, base) \
void step(void); \
void reset(void); \
void start(void); \
void stop(void); \
int max_output(void) { return _maxout; } \
DISCRETE_CLASS_DESTRUCTOR(_name) \
private: \
_priv \
}
class DISCRETE_CLASS_NAME(special): public discrete_base_node
{
public:
DISCRETE_CLASS_CONSTRUCTOR(special, 0)
void step(void) { }
bool is_stepping(void) { return false; }
DISCRETE_CLASS_CONSTRUCTOR(special, base)
int max_output(void) { return 0; }
DISCRETE_CLASS_DESTRUCTOR(special)
};
class DISCRETE_CLASS_NAME(unimplemented): public discrete_base_node
{
public:
DISCRETE_CLASS_CONSTRUCTOR(unimplemented, 0)
void step(void) { }
bool is_stepping(void) { return false; }
DISCRETE_CLASS_CONSTRUCTOR(unimplemented, base)
int max_output(void) { return 0; }
};
#define DSS_INV_TAB_SIZE 500
struct dss_adjustment_context
{
const input_port_config *port;
INT32 lastpval;
INT32 pmin;
double pscale;
double min;
double scale;
};
struct dss_input_context
{
stream_sample_t *ptr; /* current in ptr for stream */
double gain; /* node gain */
double offset; /* node offset */
UINT8 data; /* data written */
UINT8 is_stream;
UINT8 is_buffered;
UINT32 stream_in_number;
/* the buffer stream */
sound_stream *buffer_stream;
};
struct dss_lfsr_noise_context
{
unsigned int lfsr_reg;
int last; /* Last clock state */
double t_clock; /* fixed counter clock in seconds */
double t_left; /* time unused during last sample in seconds */
double sample_step;
double t;
UINT8 reset_on_high;
UINT8 invert_output;
UINT8 out_is_f0;
UINT8 out_lfsr_reg;
};
struct dss_noise_context
{
double phase;
};
struct dss_note_context
{
int clock_type;
int out_type;
int last; /* Last clock state */
double t_clock; /* fixed counter clock in seconds */
double t_left; /* time unused during last sample in seconds */
int max1; /* Max 1 Count stored as int for easy use. */
int max2; /* Max 2 Count stored as int for easy use. */
int count1; /* current count1 */
int count2; /* current count2 */
};
struct dss_op_amp_osc_context
{
const double *r1; /* pointers to resistor values */
const double *r2;
const double *r3;
const double *r4;
const double *r5;
const double *r6;
const double *r7;
const double *r8;
int type;
UINT8 flip_flop; /* flip/flop output state */
UINT8 flip_flop_xor; /* flip_flop ^ flip_flop_xor, 0 = discharge, 1 = charge */
UINT8 output_type;
UINT8 has_enable;
double v_out_high;
double threshold_low; /* falling threshold */
double threshold_high; /* rising threshold */
double v_cap; /* current capacitor voltage */
double r_total; /* all input resistors in parallel */
double i_fixed; /* fixed current at the input */
double i_enable; /* fixed current at the input if enabled */
double temp1; /* Multi purpose */
double temp2; /* Multi purpose */
double temp3; /* Multi purpose */
double is_linear_charge;
double charge_rc[2];
double charge_exp[2];
double charge_v[2];
};
struct dss_sawtoothwave_context
{
double phase;
int type;
};
struct dss_schmitt_osc_context
{
double ration_in; /* ratio of total charging voltage that comes from the input */
double ratio_feedback; /* ratio of total charging voltage that comes from the feedback */
double v_cap; /* current capacitor voltage */
double rc; /* r*c */
double exponent;
int state; /* state of the output */
int enable_type;
UINT8 input_is_voltage;
};
struct dss_sinewave_context
{
double phase;
};
struct dss_squarewave_context
{
double phase;
double trigger;
};
struct dss_squarewfix_context
{
int flip_flop;
double sample_step;
double t_left;
double t_off;
double t_on;
};
struct dss_trianglewave_context
{
double phase;
};
struct dss_adsrenv_context
{
double phase;
};
struct dss_counter_context
{
int clock_type;
int out_type;
int is_7492;
int last_clock;
UINT32 last_count;
UINT32 last; /* Last clock state */
UINT32 min;
UINT32 max;
UINT32 diff;
double t_left; /* time unused during last sample in seconds */
};
struct dst_filter1_context
{
double x1; /* x[k-1], previous input value */
double y1; /* y[k-1], previous output value */
double a1; /* digital filter coefficients, denominator */
double b0, b1; /* digital filter coefficients, numerator */
};
struct dst_filter2_context
{
double x1, x2; /* x[k-1], x[k-2], previous 2 input values */
double y1, y2; /* y[k-1], y[k-2], previous 2 output values */
double a1, a2; /* digital filter coefficients, denominator */
double b0, b1, b2; /* digital filter coefficients, numerator */
};
struct dst_sallen_key_context
{
double x1, x2; /* x[k-1], x[k-2], previous 2 input values */
double y1, y2; /* y[k-1], y[k-2], previous 2 output values */
double a1, a2; /* digital filter coefficients, denominator */
double b0, b1, b2; /* digital filter coefficients, numerator */
};
struct dst_op_amp_filt_context
{
int type; /* What kind of filter */
int is_norton; /* 1 = Norton op-amps */
double vRef;
double vP;
double vN;
double rTotal; /* All input resistance in parallel. */
double iFixed; /* Current supplied by r3 & r4 if used. */
double exponentC1;
double exponentC2;
double exponentC3;
double rRatio; /* divide ratio of resistance network */
double vC1; /* Charge on C1 */
double vC1b; /* Charge on C1, part of C1 charge if needed */
double vC2; /* Charge on C2 */
double vC3; /* Charge on C2 */
double gain; /* Gain of the filter */
double x1, x2; /* x[k-1], x[k-2], previous 2 input values */
double y1, y2; /* y[k-1], y[k-2], previous 2 output values */
double a1,a2; /* digital filter coefficients, denominator */
double b0,b1,b2; /* digital filter coefficients, numerator */
};
struct dst_rc_circuit_1_context
{
double v_cap;
double v_charge_1_2;
double v_drop;
double exp_1;
double exp_1_2;
double exp_2;
};
struct dst_rcdisc_context
{
int state;
double t; /* time */
double exponent0;
double exponent1;
double v_cap; /* rcdisc5 */
double v_diode; /* rcdisc3 */
};
struct dst_rcdisc_mod_context
{
double v_cap;
double exp_low[2];
double exp_high[4];
double gain[2];
double vd_gain[4];
};
struct dst_rcdisc4_context
{
int type;
double max_out;
double vC1;
double v[2];
double exp[2];
};
struct dst_rcfilter_context
{
double vCap;
double rc;
double exponent;
UINT8 has_rc_nodes;
UINT8 is_fast;
};
struct dst_crfilter_context
{
double vCap;
double rc;
double exponent;
UINT8 has_rc_nodes;
UINT8 is_fast;
};
struct dst_rcfilter_sw_context
{
double vCap[4];
double exp[4];
double exp0; /* fast case bit 0 */
double exp1; /* fast case bit 1 */
double factor; /* fast case */
double f1[16];
double f2[16];
};
struct dst_rcintegrate_context
{
int type;
double gain_r1_r2;
double f; /* r2,r3 gain */
double vCap;
double vCE;
double exponent0;
double exponent1;
double exp_exponent0;
double exp_exponent1;
double c_exp0;
double c_exp1;
};
struct dso_csvlog_context
{
FILE *csv_file;
INT64 sample_num;
char name[32];
};
struct dso_wavlog_context
{
wav_file *wavfile;
char name[32];
};
struct dsd_555_astbl_context
{
int use_ctrlv;
int output_type;
int output_is_ac;
double ac_shift; /* DC shift needed to make waveform ac */
int flip_flop; /* 555 flip/flop output state */
double cap_voltage; /* voltage on cap */
double threshold;
double trigger;
double v_out_high; /* Logic 1 voltage level */
double v_charge;
double *v_charge_node; /* point to output of node */
int has_rc_nodes;
double exp_bleed;
double exp_charge;
double exp_discharge;
double t_rc_bleed;
double t_rc_charge;
double t_rc_discharge;
double last_r1;
double last_r2;
double last_c;
};
struct dsd_555_mstbl_context
{
int trig_is_logic;
int trig_discharges_cap;
int output_type;
double ac_shift; /* DC shift needed to make waveform ac */
int flip_flop; /* 555 flip/flop output state */
int has_rc_nodes;
double exp_charge;
double cap_voltage; /* voltage on cap */
double threshold;
double trigger;
double v_out_high; /* Logic 1 voltage level */
double v_charge;
};
struct dsd_555_cc_context
{
unsigned int type; /* type of 555cc circuit */
int output_type;
int output_is_ac;
double ac_shift; /* DC shift needed to make waveform ac */
int flip_flop; /* 555 flip/flop output state */
double cap_voltage; /* voltage on cap */
double threshold;
double trigger;
double v_out_high; /* Logic 1 voltage level */
double v_cc_source;
int has_rc_nodes;
double exp_bleed;
double exp_charge;
double exp_discharge;
double exp_discharge_01;
double exp_discharge_no_i;
double t_rc_charge;
double t_rc_discharge;
double t_rc_discharge_01;
double t_rc_discharge_no_i;
};
struct dsd_555_vco1_context
{
int ctrlv_is_node;
int output_type;
int output_is_ac;
double ac_shift; /* DC shift needed to make waveform ac */
int flip_flop; /* flip/flop output state */
double v_out_high; /* 555 high voltage */
double threshold; /* falling threshold */
double trigger; /* rising threshold */
double i_charge; /* charge current */
double i_discharge; /* discharge current */
double cap_voltage; /* current capacitor voltage */
};
struct dsd_566_context
{
unsigned int state[2]; /* keeps track of excess flip_flop changes during the current step */
int flip_flop; /* 566 flip/flop output state */
double cap_voltage; /* voltage on cap */
double v_sqr_low; /* voltage for a squarewave at low */
double v_sqr_high; /* voltage for a squarewave at high */
double v_sqr_diff;
double threshold_low; /* falling threshold */
double threshold_high; /* rising threshold */
double ac_shift; /* used to fake AC */
double v_osc_stable;
double v_osc_stop;
int fake_ac;
int out_type;
};
struct dsd_ls624_context
{
double exponent;
double t_used;
double v_cap_freq_in;
double v_freq_scale;
double v_rng_scale;
int flip_flop;
int has_freq_in_cap;
int out_type;
};
struct dst_comp_adder_context
{
double total[256];
};
struct dst_bits_decode_context
{
int count;
int decode_x_time;
int from;
int last_val;
int last_had_x_time;
};
struct dst_dac_r1_context
{
double exponent;
double last_v;
double v_step[256];
int has_c_filter;
};
struct dst_diode_mix_context
{
int size;
double v_junction[8];
};
struct dst_flipflop_context
{
int last_clk;
};
struct dst_integrate_context
{
double change;
double v_max_in; /* v1 - norton VBE */
double v_max_in_d; /* v1 - norton VBE - diode drop */
double v_max_out;
};
#define DISC_MIXER_MAX_INPS 8
struct dst_mixer_context
{
int type;
int size;
int r_node_bit_flag;
int c_bit_flag;
double r_total;
double *r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */
double r_last[DISC_MIXER_MAX_INPS];
double exponent_rc[DISC_MIXER_MAX_INPS]; /* For high pass filtering cause by cIn */
double v_cap[DISC_MIXER_MAX_INPS]; /* cap voltage of each input */
double exponent_c_f; /* Low pass on mixed inputs */
double exponent_c_amp; /* Final high pass caused by out cap and amp input impedance */
double v_cap_f; /* cap voltage of cF */
double v_cap_amp; /* cap voltage of cAmp */
double gain; /* used for DISC_MIXER_IS_OP_AMP_WITH_RI */
};
struct dst_oneshot_context
{
double countdown;
int state;
int last_trig;
int type;
};
struct dst_ramp_context
{
double step;
int dir; /* 1 if End is higher then Start */
int last_en; /* Keep track of the last enable value */
};
struct dst_samphold_context
{
double last_input;
int clocktype;
};
struct dst_logic_shift_context
{
double t_left; /* time unused during last sample in seconds */
UINT32 shift_data;
UINT32 bit_mask;
UINT8 clock_type;
UINT8 reset_on_high;
UINT8 shift_r;
UINT8 last;
DISCRETE_CLASS_DESTRUCTOR(unimplemented)
};
struct dst_size_context
{
int size;
};
struct dst_multiplex_context
{
int size;
};
struct dst_op_amp_context
{
UINT8 has_cap;
UINT8 has_r1;
UINT8 has_r4;
double v_max;
double i_fixed;
double v_cap;
double exponent;
};
struct dst_op_amp_1sht_context
{
double i_fixed;
double v_max;
double r34ratio;
double v_cap1;
double v_cap2;
double exponent1c;
double exponent1d;
double exponent2;
};
struct dst_tvca_op_amp_context
{
double v_out_max; /* Maximum output voltage */
double v_trig[2]; /* Voltage used to charge cap1 based on function F3 */
double v_trig2; /* Voltage used to charge cap2 */
double v_trig3; /* Voltage used to charge cap3 */
double i_fixed; /* Fixed current going into - input */
double exponent_c[2]; /* Charge exponents based on function F3 */
double exponent_d[2]; /* Discharge exponents based on function F3 */
double exponent2[2]; /* Discharge/charge exponents based on function F4 */
double exponent3[2]; /* Discharge/charge exponents based on function F5 */
double exponent4; /* Discharge/charge exponents for c4 */
double v_cap1; /* charge on cap c1 */
double v_cap2; /* charge on cap c2 */
double v_cap3; /* charge on cap c3 */
double v_cap4; /* charge on cap c4 */
double r67; /* = r6 + r7 (for easy use later) */
UINT8 has_c4;
UINT8 has_r4;
// int size;
};
struct dst_rcdisc2_context
/*************************************
*
* disc_sys.c
*
*************************************/
class DISCRETE_CLASS_NAME(dso_output): public discrete_base_node, public discrete_output_interface, public discrete_step_interface
{
double x1; /* x[k-1], last input value */
double y1; /* y[k-1], last output value */
double a1_0, b0_0, b1_0; /* digital filter coefficients, filter #1 */
double a1_1, b0_1, b1_1; /* digital filter coefficients, filter #2 */
};
;
DISCRETE_CLASS_STEP_RESET(dso_output, 0, 0);
DISCRETE_CLASS(dso_csvlog, sizeof(struct dso_csvlog_context), 0);
DISCRETE_CLASS(dso_wavlog, sizeof(struct dso_wavlog_context), 0);
DISCRETE_CLASS(dso_task_start, 0, 0);
DISCRETE_CLASS_STEP_RESET(dso_task_end, 0, 0);
DISCRETE_CLASS_STEP_RESET(dss_adjustment, sizeof(struct dss_adjustment_context), 1);
DISCRETE_CLASS_RESET(dss_constant, 0, 1);
DISCRETE_CLASS_RESET(dss_input_data, sizeof(struct dss_input_context), 1);
DISCRETE_CLASS_RESET(dss_input_logic, sizeof(struct dss_input_context), 1);
DISCRETE_CLASS_RESET(dss_input_not, sizeof(struct dss_input_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_input_pulse, sizeof(struct dss_input_context), 1);
DISCRETE_CLASS(dss_input_stream, sizeof(struct dss_input_context), 1);
/* from disc_wav.c */
/* Generic modules */
DISCRETE_CLASS_STEP_RESET(dss_counter, sizeof(struct dss_counter_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_lfsr_noise, sizeof(struct dss_lfsr_noise_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_noise, sizeof(struct dss_noise_context), 2);
DISCRETE_CLASS_STEP_RESET(dss_note, sizeof(struct dss_note_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_sawtoothwave, sizeof(struct dss_sawtoothwave_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_sinewave, sizeof(struct dss_sinewave_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_squarewave, sizeof(struct dss_squarewave_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_squarewfix, sizeof(struct dss_squarewfix_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_squarewave2, sizeof(struct dss_squarewave_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_trianglewave, sizeof(struct dss_trianglewave_context), 1);
/* Component specific modules */
class DISCRETE_CLASS_NAME(dss_inverter_osc): public discrete_base_node
{
protected:
inline double tftab(double x);
inline double tf(double x);
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_inverter_osc, 0)
DISCRETE_CLASS_CONSTRUCTOR(dso_output, base)
void step(void) {
/* Add gain to the output and put into the buffers */
/* Clipping will be handled by the main sound system */
double val = DISCRETE_INPUT(0) * DISCRETE_INPUT(1);
*m_ptr++ = val;
}
int max_output(void) { return 0; }
void set_output(stream_sample_t *ptr) { m_ptr = ptr; }
DISCRETE_CLASS_DESTRUCTOR(dso_output)
private:
stream_sample_t *m_ptr;
};
DISCRETE_CLASSA(dso_csvlog, 0,
FILE *m_csv_file;
INT64 m_sample_num;
char m_name[32];
);
DISCRETE_CLASSA(dso_wavlog, 0,
wav_file *m_wavfile;
char m_name[32];
);
/*************************************
*
* disc_inp.c
*
*************************************/
class DISCRETE_CLASS_NAME(dss_adjustment): public discrete_base_node, public discrete_step_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_adjustment, base)
void step(void);
void reset(void);
int max_output(void) { return 1; }
private:
double mc_v_cap;
double mc_v_g2_old;
double mc_w;
double mc_wc;
double mc_rp;
double mc_r1;
double mc_r2;
double mc_c;
double mc_tf_a;
double mc_tf_b;
double mc_tf_tab[DSS_INV_TAB_SIZE];
const input_port_config *m_port;
INT32 m_lastpval;
INT32 m_pmin;
double m_pscale;
double m_min;
double m_scale;
DISCRETE_CLASS_DESTRUCTOR(dss_adjustment)
};
DISCRETE_CLASS_RESET(dss_constant, 1);
DISCRETE_CLASS_STEP_RESET(dss_op_amp_osc, sizeof(struct dss_op_amp_osc_context), 1);
DISCRETE_CLASS_STEP_RESET(dss_schmitt_osc, sizeof(struct dss_schmitt_osc_context), 1);
/* Not yet implemented */
DISCRETE_CLASS_STEP_RESET(dss_adsrenv, sizeof(struct dss_adsrenv_context), 1);
class DISCRETE_CLASS_NAME(dss_input_data): public discrete_base_node, public discrete_input_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_data, base)
void reset(void);
void input_write(int sub_node, UINT8 data );
DISCRETE_CLASS_DESTRUCTOR(dss_input_data)
private:
double m_gain; /* node gain */
double m_offset; /* node offset */
UINT8 m_data; /* data written */
};
/* from disc_mth.c */
/* Generic modules */
DISCRETE_CLASS_STEP(dst_adder, 0, 1);
DISCRETE_CLASS_STEP(dst_clamp, 0, 1);
DISCRETE_CLASS_STEP(dst_divide,0, 1);
DISCRETE_CLASS_STEP(dst_gain, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_inv, 0, 1);
DISCRETE_CLASS_STEP_RESET(dst_bits_decode, sizeof(struct dst_bits_decode_context), 8);
DISCRETE_CLASS_STEP(dst_logic_and, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_nand, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_or, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_nor, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_xor, 0, 1);
DISCRETE_CLASS_STEP(dst_logic_nxor, 0, 1);
DISCRETE_CLASS_STEP_RESET(dst_logic_dff, sizeof(struct dst_flipflop_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_logic_jkff, sizeof(struct dst_flipflop_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_logic_shift, sizeof(struct dst_logic_shift_context), 1);
DISCRETE_CLASS_STEP(dst_lookup_table, 0, 1);
DISCRETE_CLASS_STEP_RESET(dst_multiplex, sizeof(struct dst_multiplex_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_oneshot, sizeof(struct dst_oneshot_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_ramp, sizeof(struct dst_ramp_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_samphold, sizeof(struct dst_samphold_context), 1);
DISCRETE_CLASS_STEP(dst_switch, 0, 1);
DISCRETE_CLASS_STEP(dst_aswitch, 0, 1);
DISCRETE_CLASS_STEP(dst_transform, 0, 1);
/* Component specific */
DISCRETE_CLASS_STEP_RESET(dst_comp_adder, sizeof(struct dst_comp_adder_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_dac_r1, sizeof(struct dst_dac_r1_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_diode_mix, sizeof(struct dst_diode_mix_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_integrate, sizeof(struct dst_integrate_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_mixer, sizeof(struct dst_mixer_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_op_amp, sizeof(struct dst_op_amp_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_op_amp_1sht, sizeof(struct dst_op_amp_1sht_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_tvca_op_amp, sizeof(struct dst_tvca_op_amp_context), 1);
DISCRETE_CLASS_STEP(dst_xtime_buffer, 0, 1);
DISCRETE_CLASS_STEP(dst_xtime_and, 0, 1);
DISCRETE_CLASS_STEP(dst_xtime_or, 0, 1);
DISCRETE_CLASS_STEP(dst_xtime_xor, 0, 1);
class DISCRETE_CLASS_NAME(dss_input_logic): public discrete_base_node, public discrete_input_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_logic, base)
void reset(void);
void input_write(int sub_node, UINT8 data );
DISCRETE_CLASS_DESTRUCTOR(dss_input_logic)
private:
double m_gain; /* node gain */
double m_offset; /* node offset */
UINT8 m_data; /* data written */
};
/* from disc_flt.c */
/* Generic modules */
DISCRETE_CLASS_STEP_RESET(dst_filter1, sizeof(struct dst_filter1_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_filter2, sizeof(struct dst_filter2_context), 1);
/* Component specific modules */
DISCRETE_CLASS_STEP_RESET(dst_sallen_key, sizeof(struct dst_sallen_key_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_crfilter, sizeof(struct dst_crfilter_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_op_amp_filt, sizeof(struct dst_op_amp_filt_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rc_circuit_1, sizeof(struct dst_rc_circuit_1_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc, sizeof(struct dst_rcdisc_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc2, sizeof(struct dst_rcdisc_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc3, sizeof(struct dst_rcdisc_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc4, sizeof(struct dst_rcdisc4_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc5, sizeof(struct dst_rcdisc_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcintegrate, sizeof(struct dst_rcintegrate_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc_mod, sizeof(struct dst_rcdisc_mod_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcfilter, sizeof(struct dst_rcfilter_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcfilter_sw, sizeof(struct dst_rcfilter_sw_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdiscN, sizeof(struct dst_filter1_context), 1);
DISCRETE_CLASS_STEP_RESET(dst_rcdisc2N, sizeof(struct dst_rcdisc2_context), 1);
/* from disc_dev.c */
/* generic modules */
/* Component specific modules */
DISCRETE_CLASS_STEP_RESET(dsd_555_astbl, sizeof(struct dsd_555_astbl_context), 1);
DISCRETE_CLASS_STEP_RESET(dsd_555_mstbl, sizeof(struct dsd_555_mstbl_context), 1);
DISCRETE_CLASS_STEP_RESET(dsd_555_cc, sizeof(struct dsd_555_cc_context), 1);
DISCRETE_CLASS_STEP_RESET(dsd_555_vco1, sizeof(struct dsd_555_vco1_context), 1);
DISCRETE_CLASS_STEP_RESET(dsd_566, sizeof(struct dsd_566_context), 1);
DISCRETE_CLASS_STEP_RESET(dsd_ls624, sizeof(struct dsd_ls624_context), 1);
/* must be the last one */
class DISCRETE_CLASS_NAME(dss_input_not): public discrete_base_node, public discrete_input_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_not, base)
void reset(void);
void input_write(int sub_node, UINT8 data );
DISCRETE_CLASS_DESTRUCTOR(dss_input_not)
private:
double m_gain; /* node gain */
double m_offset; /* node offset */
UINT8 m_data; /* data written */
};
class DISCRETE_CLASS_NAME(dss_input_pulse): public discrete_base_node, public discrete_input_interface, public discrete_step_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_pulse, base)
void step(void);
void reset(void);
void input_write(int sub_node, UINT8 data );
DISCRETE_CLASS_DESTRUCTOR(dss_input_pulse)
private:
double m_gain; /* node gain */
double m_offset; /* node offset */
UINT8 m_data; /* data written */
};
class DISCRETE_CLASS_NAME(dss_input_stream): public discrete_base_node, public discrete_input_interface, public discrete_step_interface
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_stream, base)
void step(void);
void reset(void);
void start(void);
void input_write(int sub_node, UINT8 data );
virtual bool is_buffered(void) { return false; }
//protected:
UINT32 m_stream_in_number;
stream_sample_t *m_ptr; /* current in ptr for stream */
DISCRETE_CLASS_DESTRUCTOR(dss_input_stream)
private:
static STREAM_UPDATE( static_stream_generate );
void stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples);
double m_gain; /* node gain */
double m_offset; /* node offset */
UINT8 m_data; /* data written */
UINT8 m_is_buffered;
/* the buffer stream */
sound_stream *m_buffer_stream;
};
class DISCRETE_CLASS_NAME(dss_input_buffer): public DISCRETE_CLASS_NAME(dss_input_stream)
{
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_input_buffer, dss_input_stream)
bool is_buffered(void) { return true; }
DISCRETE_CLASS_DESTRUCTOR(dss_input_buffer)
};
#include "disc_wav.h"
#include "disc_mth.h"
#include "disc_flt.h"
#include "disc_dev.h"
#endif /* __DISCRETE_H__ */

File diff suppressed because it is too large Load Diff

127
src/emu/sound/disc_dev.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#ifndef __DISC_DEV_H__
#define __DISC_DEV_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
* Discrete classes 2010 - Couriersud
*
***********************************************************************/
#include "discrete.h"
DISCRETE_CLASS_STEP_RESETA(dsd_555_astbl, 1,
int m_use_ctrlv;
int m_output_type;
int m_output_is_ac;
double m_ac_shift; /* DC shift needed to make waveform ac */
int m_flip_flop; /* 555 flip/flop output state */
double m_cap_voltage; /* voltage on cap */
double m_threshold;
double m_trigger;
double m_v_out_high; /* Logic 1 voltage level */
double m_v_charge;
double *m_v_charge_node; /* point to output of node */
int m_has_rc_nodes;
double m_exp_bleed;
double m_exp_charge;
double m_exp_discharge;
double m_t_rc_bleed;
double m_t_rc_charge;
double m_t_rc_discharge;
double m_last_r1;
double m_last_r2;
double m_last_c;
);
DISCRETE_CLASS_STEP_RESETA(dsd_555_mstbl, 1,
int m_trig_is_logic;
int m_trig_discharges_cap;
int m_output_type;
double m_ac_shift; /* DC shift needed to make waveform ac */
int m_flip_flop; /* 555 flip/flop output state */
int m_has_rc_nodes;
double m_exp_charge;
double m_cap_voltage; /* voltage on cap */
double m_threshold;
double m_trigger;
double m_v_out_high; /* Logic 1 voltage level */
double m_v_charge;
);
DISCRETE_CLASS_STEP_RESETA(dsd_555_cc, 1,
unsigned int m_type; /* type of 555cc circuit */
int m_output_type;
int m_output_is_ac;
double m_ac_shift; /* DC shift needed to make waveform ac */
int m_flip_flop; /* 555 flip/flop output state */
double m_cap_voltage; /* voltage on cap */
double m_threshold;
double m_trigger;
double m_v_out_high; /* Logic 1 voltage level */
double m_v_cc_source;
int m_has_rc_nodes;
double m_exp_bleed;
double m_exp_charge;
double m_exp_discharge;
double m_exp_discharge_01;
double m_exp_discharge_no_i;
double m_t_rc_charge;
double m_t_rc_discharge;
double m_t_rc_discharge_01;
double m_t_rc_discharge_no_i;
);
DISCRETE_CLASS_STEP_RESETA(dsd_555_vco1, 1,
int m_ctrlv_is_node;
int m_output_type;
int m_output_is_ac;
double m_ac_shift; /* DC shift needed to make waveform ac */
int m_flip_flop; /* flip/flop output state */
double m_v_out_high; /* 555 high voltage */
double m_threshold; /* falling threshold */
double m_trigger; /* rising threshold */
double m_i_charge; /* charge current */
double m_i_discharge; /* discharge current */
double m_cap_voltage; /* current capacitor voltage */
);
DISCRETE_CLASS_STEP_RESETA(dsd_566, 1,
unsigned int m_state[2]; /* keeps track of excess flip_flop changes during the current step */
int m_flip_flop; /* 566 flip/flop output state */
double m_cap_voltage; /* voltage on cap */
double m_v_sqr_low; /* voltage for a squarewave at low */
double m_v_sqr_high; /* voltage for a squarewave at high */
double m_v_sqr_diff;
double m_threshold_low; /* falling threshold */
double m_threshold_high; /* rising threshold */
double m_ac_shift; /* used to fake AC */
double m_v_osc_stable;
double m_v_osc_stop;
int m_fake_ac;
int m_out_type;
);
DISCRETE_CLASS_STEP_RESETA(dsd_ls624, 1,
double m_exponent;
double m_t_used;
double m_v_cap_freq_in;
double m_v_freq_scale;
double m_v_rng_scale;
int m_flip_flop;
int m_has_freq_in_cap;
int m_out_type;
);
#endif /* __DISC_WAV_H__ */

File diff suppressed because it is too large Load Diff

182
src/emu/sound/disc_flt.h Normal file
View File

@ -0,0 +1,182 @@
#pragma once
#ifndef __DISC_FLTH__
#define __DISC_FLT_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
* Discrete classes 2010 - Couriersud
*
***********************************************************************/
#include "discrete.h"
struct discrete_filter_coeff
{
double x1, x2; /* x[k-1], x[k-2], previous 2 input values */
double y1, y2; /* y[k-1], y[k-2], previous 2 output values */
double a1, a2; /* digital filter coefficients, denominator */
double b0, b1, b2; /* digital filter coefficients, numerator */
};
DISCRETE_CLASS_STEP_RESETA(dst_filter1, 1,
/* uses x1, y1, a1, b0, b1 */
struct discrete_filter_coeff m_fc;
);
DISCRETE_CLASS_STEP_RESETA(dst_filter2, 1,
struct discrete_filter_coeff m_fc;
);
DISCRETE_CLASS_STEP_RESETA(dst_sallen_key, 1,
struct discrete_filter_coeff m_fc;
);
DISCRETE_CLASS_STEP_RESETA(dst_crfilter, 1,
double m_vCap;
double m_rc;
double m_exponent;
UINT8 m_has_rc_nodes;
UINT8 m_is_fast;
);
DISCRETE_CLASS_STEP_RESETA(dst_op_amp_filt, 1,
int m_type; /* What kind of filter */
int m_is_norton; /* 1 = Norton op-amps */
double m_vRef;
double m_vP;
double m_vN;
double m_rTotal; /* All input resistance in parallel. */
double m_iFixed; /* Current supplied by r3 & r4 if used. */
double m_exponentC1;
double m_exponentC2;
double m_exponentC3;
double m_rRatio; /* divide ratio of resistance network */
double m_vC1; /* Charge on C1 */
double m_vC1b; /* Charge on C1, part of C1 charge if needed */
double m_vC2; /* Charge on C2 */
double m_vC3; /* Charge on C2 */
double m_gain; /* Gain of the filter */
struct discrete_filter_coeff m_fc;
);
DISCRETE_CLASS_STEP_RESETA(dst_rc_circuit_1, 1,
double m_v_cap;
double m_v_charge_1_2;
double m_v_drop;
double m_exp_1;
double m_exp_1_2;
double m_exp_2;
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc, 1,
int m_state;
double m_t; /* time */
double m_exponent0;
double m_exponent1;
double m_v_cap; /* rcdisc5 */
double m_v_diode; /* rcdisc3 */
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc2, 1,
int m_state;
double m_t; /* time */
double m_exponent0;
double m_exponent1;
double m_v_cap; /* rcdisc5 */
double m_v_diode; /* rcdisc3 */
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc3, 1,
int m_state;
double m_t; /* time */
double m_exponent0;
double m_exponent1;
double m_v_cap; /* rcdisc5 */
double m_v_diode; /* rcdisc3 */
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc4, 1,
int m_type;
double m_max_out;
double m_vC1;
double m_v[2];
double m_exp[2];
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc5, 1,
int m_state;
double m_t; /* time */
double m_exponent0;
double m_exponent1;
double m_v_cap; /* rcdisc5 */
double m_v_diode; /* rcdisc3 */
);
DISCRETE_CLASS_STEP_RESETA(dst_rcintegrate, 1,
int m_type;
double m_gain_r1_r2;
double m_f; /* r2,r3 gain */
double m_vCap;
double m_vCE;
double m_exponent0;
double m_exponent1;
double m_exp_exponent0;
double m_exp_exponent1;
double m_c_exp0;
double m_c_exp1;
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc_mod, 1,
double m_v_cap;
double m_exp_low[2];
double m_exp_high[4];
double m_gain[2];
double m_vd_gain[4];
);
DISCRETE_CLASS_STEP_RESETA(dst_rcfilter, 1,
double m_vCap;
double m_rc;
double m_exponent;
UINT8 m_has_rc_nodes;
UINT8 m_is_fast;
);
DISCRETE_CLASS_STEP_RESETA(dst_rcfilter_sw, 1,
double m_vCap[4];
double m_exp[4];
double m_exp0; /* fast case bit 0 */
double m_exp1; /* fast case bit 1 */
double m_factor; /* fast case */
double m_f1[16];
double m_f2[16];
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdiscN, 1,
double m_x1; /* x[k-1], previous input value */
double m_y1; /* y[k-1], previous output value */
double m_a1; /* digital filter coefficients, denominator */
double m_b[2]; /* digital filter coefficients, numerator */
);
DISCRETE_CLASS_STEP_RESETA(dst_rcdisc2N, 1,
struct discrete_filter_coeff m_fc0;
struct discrete_filter_coeff m_fc1;
double m_x1;
double m_y1;
);
#endif /* __DISC_FLT_H__ */

View File

@ -55,17 +55,15 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
DISCRETE_STEP(dss_adjustment)
{
DISCRETE_DECLARE_CONTEXT(dss_adjustment)
INT32 rawportval = input_port_read_direct(context->port);
INT32 rawportval = input_port_read_direct(m_port);
/* only recompute if the value changed from last time */
if (UNEXPECTED(rawportval != context->lastpval))
if (UNEXPECTED(rawportval != m_lastpval))
{
double portval = (double)(rawportval - context->pmin) * context->pscale;
double scaledval = portval * context->scale + context->min;
double portval = (double)(rawportval - m_pmin) * m_pscale;
double scaledval = portval * m_scale + m_min;
context->lastpval = rawportval;
m_lastpval = rawportval;
if (DSS_ADJUSTMENT__LOG == 0)
this->output[0] = scaledval;
else
@ -75,23 +73,21 @@ DISCRETE_STEP(dss_adjustment)
DISCRETE_RESET(dss_adjustment)
{
DISCRETE_DECLARE_CONTEXT(dss_adjustment)
double min, max;
context->port = device->machine->m_portlist.find((const char *)this->custom_data());
if (context->port == NULL)
m_port = device->machine->m_portlist.find((const char *)this->custom_data());
if (m_port == NULL)
fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag", this->index());
context->lastpval = 0x7fffffff;
context->pmin = DSS_ADJUSTMENT__PMIN;
context->pscale = 1.0 / (double)(DSS_ADJUSTMENT__PMAX - DSS_ADJUSTMENT__PMIN);
m_lastpval = 0x7fffffff;
m_pmin = DSS_ADJUSTMENT__PMIN;
m_pscale = 1.0 / (double)(DSS_ADJUSTMENT__PMAX - DSS_ADJUSTMENT__PMIN);
/* linear scale */
if (DSS_ADJUSTMENT__LOG == 0)
{
context->min = DSS_ADJUSTMENT__MIN;
context->scale = DSS_ADJUSTMENT__MAX - DSS_ADJUSTMENT__MIN;
m_min = DSS_ADJUSTMENT__MIN;
m_scale = DSS_ADJUSTMENT__MAX - DSS_ADJUSTMENT__MIN;
}
/* logarithmic scale */
@ -100,8 +96,8 @@ DISCRETE_RESET(dss_adjustment)
/* force minimum and maximum to be > 0 */
min = (DSS_ADJUSTMENT__MIN > 0) ? DSS_ADJUSTMENT__MIN : 1;
max = (DSS_ADJUSTMENT__MAX > 0) ? DSS_ADJUSTMENT__MAX : 1;
context->min = log10(min);
context->scale = log10(max) - log10(min);
m_min = log10(min);
m_scale = log10(max) - log10(min);
}
this->step();
@ -133,69 +129,116 @@ DISCRETE_RESET(dss_constant)
* input[3] - Current data value
*
************************************************************************/
DISCRETE_RESET(dss_input_pulse)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
context->is_buffered = FALSE;
context->is_stream = FALSE;
context->gain = DSS_INPUT__GAIN;
context->offset = DSS_INPUT__OFFSET;
context->data = (DSS_INPUT__INIT == 0) ? 0 : 1;
this->output[0] = context->data * context->gain + context->offset;
}
DISCRETE_RESET(dss_input_data)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
m_gain = DSS_INPUT__GAIN;
m_offset = DSS_INPUT__OFFSET;
context->is_buffered = FALSE;
context->is_stream = FALSE;
context->gain = DSS_INPUT__GAIN;
context->offset = DSS_INPUT__OFFSET;
m_data = DSS_INPUT__INIT;
this->output[0] = m_data * m_gain + m_offset;
}
context->data = DSS_INPUT__INIT;
this->output[0] = context->data * context->gain + context->offset;
void DISCRETE_CLASS_FUNC(dss_input_data, input_write)(int sub_node, UINT8 data )
{
UINT8 new_data = 0;
new_data = data;
if (m_data != new_data)
{
/* Bring the system up to now */
device->update();
m_data = new_data;
/* Update the node output here so we don't have to do it each step */
this->output[0] = m_data * m_gain + m_offset;
}
}
DISCRETE_RESET(dss_input_logic)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
m_gain = DSS_INPUT__GAIN;
m_offset = DSS_INPUT__OFFSET;
context->is_buffered = FALSE;
context->is_stream = FALSE;
context->gain = DSS_INPUT__GAIN;
context->offset = DSS_INPUT__OFFSET;
m_data = (DSS_INPUT__INIT == 0) ? 0 : 1;
this->output[0] = m_data * m_gain + m_offset;
}
context->data = (DSS_INPUT__INIT == 0) ? 0 : 1;
this->output[0] = context->data * context->gain + context->offset;
void DISCRETE_CLASS_FUNC(dss_input_logic, input_write)(int sub_node, UINT8 data )
{
UINT8 new_data = 0;
new_data = data ? 1 : 0;
if (m_data != new_data)
{
/* Bring the system up to now */
device->update();
m_data = new_data;
/* Update the node output here so we don't have to do it each step */
this->output[0] = m_data * m_gain + m_offset;
}
}
DISCRETE_RESET(dss_input_not)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
m_gain = DSS_INPUT__GAIN;
m_offset = DSS_INPUT__OFFSET;
context->is_buffered = FALSE;
context->is_stream = FALSE;
context->gain = DSS_INPUT__GAIN;
context->offset = DSS_INPUT__OFFSET;
m_data = (DSS_INPUT__INIT == 0) ? 1 : 0;
this->output[0] = m_data * m_gain + m_offset;
}
context->data = (DSS_INPUT__INIT == 0) ? 1 : 0;
this->output[0] = context->data * context->gain + context->offset;
void DISCRETE_CLASS_FUNC(dss_input_not, input_write)(int sub_node, UINT8 data )
{
UINT8 new_data = 0;
new_data = data ? 0 : 1;
if (m_data != new_data)
{
/* Bring the system up to now */
device->update();
m_data = new_data;
/* Update the node output here so we don't have to do it each step */
this->output[0] = m_data * m_gain + m_offset;
}
}
DISCRETE_STEP(dss_input_pulse)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
/* Set a valid output */
this->output[0] = context->data;
this->output[0] = m_data;
/* Reset the input to default for the next cycle */
/* node order is now important */
context->data = DSS_INPUT__INIT;
m_data = DSS_INPUT__INIT;
}
DISCRETE_RESET(dss_input_pulse)
{
m_data = (DSS_INPUT__INIT == 0) ? 0 : 1;
this->output[0] = m_data;
}
void DISCRETE_CLASS_FUNC(dss_input_pulse, input_write)(int sub_node, UINT8 data )
{
UINT8 new_data = 0;
new_data = data ? 1 : 0;
if (m_data != new_data)
{
/* Bring the system up to now */
device->update();
m_data = new_data;
}
}
/************************************************************************
*
@ -210,15 +253,26 @@ DISCRETE_STEP(dss_input_pulse)
#define DSS_INPUT_STREAM__GAIN DISCRETE_INPUT(1)
#define DSS_INPUT_STREAM__OFFSET DISCRETE_INPUT(2)
STREAM_UPDATE( discrete_dss_input_stream_node::static_stream_generate )
{
reinterpret_cast<discrete_dss_input_stream_node *>(param)->stream_generate(inputs, outputs, samples);
}
void discrete_dss_input_stream_node::stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
stream_sample_t *ptr = outputs[0];
int samplenum = samples;
while (samplenum-- > 0)
*(ptr++) = m_data;
}
DISCRETE_STEP(dss_input_stream)
{
/* the context pointer is set to point to the current input stream data in discrete_stream_update */
DISCRETE_DECLARE_CONTEXT(dss_input)
if (EXPECTED(context->ptr))
if (EXPECTED(m_ptr))
{
this->output[0] = (*context->ptr) * context->gain + context->offset;
context->ptr++;
this->output[0] = (*m_ptr) * m_gain + m_offset;
m_ptr++;
}
else
this->output[0] = 0;
@ -226,47 +280,61 @@ DISCRETE_STEP(dss_input_stream)
DISCRETE_RESET(dss_input_stream)
{
DISCRETE_DECLARE_CONTEXT(dss_input)
m_ptr = NULL;
m_data = 0;
}
context->ptr = NULL;
context->data = 0;
void DISCRETE_CLASS_FUNC(dss_input_stream, input_write)(int sub_node, UINT8 data )
{
UINT8 new_data = 0;
new_data = data;
if (m_data != new_data)
{
if (m_is_buffered)
{
/* Bring the system up to now */
stream_update(m_buffer_stream);
m_data = new_data;
}
else
{
/* Bring the system up to now */
device->update();
m_data = new_data;
/* Update the node output here so we don't have to do it each step */
this->output[0] = new_data * m_gain + m_offset;
}
}
}
DISCRETE_START(dss_input_stream)
{
discrete_base_node::start();
DISCRETE_DECLARE_CONTEXT(dss_input)
assert(DSS_INPUT_STREAM__STREAM < this->device->m_input_stream_list.count());
assert(DSS_INPUT_STREAM__STREAM < this->device->m_input_list.count());
context->is_stream = TRUE;
/* Stream out number is set during start */
context->stream_in_number = DSS_INPUT_STREAM__STREAM;
context->gain = DSS_INPUT_STREAM__GAIN;
context->offset = DSS_INPUT_STREAM__OFFSET;
context->ptr = NULL;
m_stream_in_number = DSS_INPUT_STREAM__STREAM;
m_gain = DSS_INPUT_STREAM__GAIN;
m_offset = DSS_INPUT_STREAM__OFFSET;
m_ptr = NULL;
if (this->module_type() == DSS_INPUT_BUFFER)
m_is_buffered = is_buffered();
if (m_is_buffered)
{
context->is_buffered = TRUE;
context->buffer_stream = stream_create(this->device, 0, 1, this->sample_rate(), (void *) this, buffer_stream_update);
m_buffer_stream = stream_create(this->device, 0, 1, this->sample_rate(), this, static_stream_generate);
stream_set_input(this->device->discrete_stream, context->stream_in_number,
context->buffer_stream, 0, 1.0);
stream_set_input(device->m_stream, m_stream_in_number,
m_buffer_stream, 0, 1.0);
}
else
{
context->is_buffered = FALSE;
context->buffer_stream = NULL;
m_buffer_stream = NULL;
}
}
DISCRETE_STOP(dss_input_stream)
{
}
DISCRETE_IS_STEPPING(dss_input_stream)
{
return true;
}

File diff suppressed because it is too large Load Diff

195
src/emu/sound/disc_mth.h Normal file
View File

@ -0,0 +1,195 @@
#pragma once
#ifndef __DISC_MTH_H__
#define __DISC_MTH_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
* Discrete classes 2010 - Couriersud
*
***********************************************************************/
#include "discrete.h"
DISCRETE_CLASS_STEPA(dst_adder, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_clamp, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_divide, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_gain, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_inv, 1, /* no context */ );
DISCRETE_CLASS_STEP_RESETA(dst_bits_decode, 8,
int m_count;
int m_decode_x_time;
int m_from;
int m_last_val;
int m_last_had_x_time;
);
DISCRETE_CLASS_STEPA(dst_logic_and, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_nand, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_or, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_nor, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_xor, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_logic_nxor, 1, /* no context */ );
DISCRETE_CLASS_STEP_RESETA(dst_logic_dff, 1,
int m_last_clk;
);
DISCRETE_CLASS_STEP_RESETA(dst_logic_jkff, 1,
int m_last_clk;
);
DISCRETE_CLASS_STEP_RESETA(dst_logic_shift, 1,
double m_t_left; /* time unused during last sample in seconds */
UINT32 m_shift_data;
UINT32 m_bit_mask;
UINT8 m_clock_type;
UINT8 m_reset_on_high;
UINT8 m_shift_r;
UINT8 m_last;
);
DISCRETE_CLASS_STEPA(dst_lookup_table, 1, /* no context */ );
DISCRETE_CLASS_STEP_RESETA(dst_multiplex, 1,
int m_size;
);
DISCRETE_CLASS_STEP_RESETA(dst_oneshot, 1,
double m_countdown;
int m_state;
int m_last_trig;
int m_type;
);
DISCRETE_CLASS_STEP_RESETA(dst_ramp, 1,
double m_step;
int m_dir; /* 1 if End is higher then Start */
int m_last_en; /* Keep track of the last enable value */
);
DISCRETE_CLASS_STEP_RESETA(dst_samphold, 1,
double m_last_input;
int m_clocktype;
);
DISCRETE_CLASS_STEPA(dst_switch, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_aswitch, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_transform, 1, /* no context */ );
/* Component specific */
DISCRETE_CLASS_STEP_RESETA(dst_comp_adder, 1,
double m_total[256];
);
DISCRETE_CLASS_STEP_RESETA(dst_dac_r1, 1,
double m_exponent;
double m_last_v;
double m_v_step[256];
int m_has_c_filter;
);
DISCRETE_CLASS_STEP_RESETA(dst_diode_mix, 1,
int m_size;
double m_v_junction[8];
);
DISCRETE_CLASS_STEP_RESETA(dst_integrate, 1,
double m_change;
double m_v_max_in; /* v1 - norton VBE */
double m_v_max_in_d; /* v1 - norton VBE - diode drop */
double m_v_max_out;
);
#define DISC_MIXER_MAX_INPS 8
DISCRETE_CLASS_STEP_RESETA(dst_mixer, 1,
int m_type;
int m_size;
int m_r_node_bit_flag;
int m_c_bit_flag;
double m_r_total;
double *m_r_node[DISC_MIXER_MAX_INPS]; /* Either pointer to resistance node output OR NULL */
double m_r_last[DISC_MIXER_MAX_INPS];
double m_exponent_rc[DISC_MIXER_MAX_INPS]; /* For high pass filtering cause by cIn */
double m_v_cap[DISC_MIXER_MAX_INPS]; /* cap voltage of each input */
double m_exponent_c_f; /* Low pass on mixed inputs */
double m_exponent_c_amp; /* Final high pass caused by out cap and amp input impedance */
double m_v_cap_f; /* cap voltage of cF */
double m_v_cap_amp; /* cap voltage of cAmp */
double m_gain; /* used for DISC_MIXER_IS_OP_AMP_WITH_RI */
);
DISCRETE_CLASS_STEP_RESETA(dst_op_amp, 1,
UINT8 m_has_cap;
UINT8 m_has_r1;
UINT8 m_has_r4;
double m_v_max;
double m_i_fixed;
double m_v_cap;
double m_exponent;
);
DISCRETE_CLASS_STEP_RESETA(dst_op_amp_1sht, 1,
double m_i_fixed;
double m_v_max;
double m_r34ratio;
double m_v_cap1;
double m_v_cap2;
double m_exponent1c;
double m_exponent1d;
double m_exponent2;
);
DISCRETE_CLASS_STEP_RESETA(dst_tvca_op_amp, 1,
double m_v_out_max; /* Maximum output voltage */
double m_v_trig[2]; /* Voltage used to charge cap1 based on function F3 */
double m_v_trig2; /* Voltage used to charge cap2 */
double m_v_trig3; /* Voltage used to charge cap3 */
double m_i_fixed; /* Fixed current going into - input */
double m_exponent_c[2]; /* Charge exponents based on function F3 */
double m_exponent_d[2]; /* Discharge exponents based on function F3 */
double m_exponent2[2]; /* Discharge/charge exponents based on function F4 */
double m_exponent3[2]; /* Discharge/charge exponents based on function F5 */
double m_exponent4; /* Discharge/charge exponents for c4 */
double m_v_cap1; /* charge on cap c1 */
double m_v_cap2; /* charge on cap c2 */
double m_v_cap3; /* charge on cap c3 */
double m_v_cap4; /* charge on cap c4 */
double m_r67; /* = r6 + r7 (for easy use later) */
UINT8 m_has_c4;
UINT8 m_has_r4;
);
DISCRETE_CLASS_STEPA(dst_xtime_buffer, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_xtime_and, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_xtime_or, 1, /* no context */ );
DISCRETE_CLASS_STEPA(dst_xtime_xor, 1, /* no context */ );
#endif /* __DISC_WAV_H__ */

View File

@ -25,194 +25,47 @@
*
*************************************/
static void task_check(discrete_task *task, discrete_task *dest_task)
{
int inputnum;
/* Determine, which nodes in the task are referenced by nodes in dest_task
* and add them to the list of nodes to be buffered for further processing
*/
for_each(discrete_base_node *, node_entry, &task->list)
{
discrete_base_node *task_node = node_entry.item();
for_each(discrete_base_node *, step_entry, &dest_task->list)
{
discrete_base_node *dest_node = step_entry.item();
/* loop over all active inputs */
for (inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++)
{
int inputnode = dest_node->input_node(inputnum);
if IS_VALUE_A_NODE(inputnode)
{
if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode))
{
discrete_source_node *source;
int i, found = -1;
for (i = 0; i < task->numbuffered; i++)
if (task->nodes[i]->block_node() == inputnode)
{
found = i;
break;
}
if (found<0)
{
if (task->numbuffered >= DISCRETE_MAX_TASK_OUTPUTS)
fatalerror("dso_task_start - Number of maximum buffered nodes exceeded");
task->node_buf[task->numbuffered] = auto_alloc_array(task_node->device->machine, double,
((task_node->sample_rate() + STREAMS_UPDATE_FREQUENCY) / STREAMS_UPDATE_FREQUENCY));
task->source[task->numbuffered] = (double *) dest_node->input[inputnum];
task->nodes[task->numbuffered] = task_node->device->discrete_find_node(inputnode);
i = task->numbuffered;
task->numbuffered++;
}
task_node->device->discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode), NODE_CHILD_NODE_NUM(inputnode), task, task->task_group, dest_node->index(), dest_task->task_group);
/* register into source list */
source = auto_alloc(dest_node->device->machine, discrete_source_node);
dest_task->source_list.add_tail(source);
source->task = task;
source->output_node = i;
/* point the input to a buffered location */
dest_node->input[inputnum] = &source->buffer;
}
}
}
}
}
}
/* fixme: remove abusing the context */
#define DISCRETE_DECLARE_TASK discrete_task *task = (discrete_task *) this->context;
DISCRETE_START( dso_task_start )
{
DISCRETE_DECLARE_TASK
task->task_group = (int) DISCRETE_INPUT(0);
if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS)
fatalerror("discrete_dso_task: illegal task_group %d", task->task_group);
for_each(discrete_task *, dest_task, &device->task_list)
{
if (task->task_group > dest_task.item()->task_group)
task_check(dest_task.item(), task);
}
}
DISCRETE_IS_STEPPING( dso_task_start )
{
return true;
}
DISCRETE_STOP( dso_task_start )
{
}
DISCRETE_STEP( dso_task_end )
{
DISCRETE_DECLARE_TASK
int i;
for (i = 0; i < task->numbuffered; i++)
*(task->ptr[i]++) = *task->source[i];
}
DISCRETE_RESET( dso_task_end )
{
/* nothing to do - just avoid being stepped */
}
DISCRETE_STEP( dso_task_start )
{
DISCRETE_DECLARE_TASK
/* update source node buffer */
for_each(discrete_source_node *, sn, &task->source_list)
{
sn.item()->buffer = *sn.item()->ptr++;
}
}
DISCRETE_RESET( dso_task_start )
{
/* nothing to do - just avoid being stepped */
}
DISCRETE_STEP( dso_output )
{
stream_sample_t **output = (stream_sample_t **) &this->context;
double val;
/* Add gain to the output and put into the buffers */
/* Clipping will be handled by the main sound system */
val = DISCRETE_INPUT(0) * DISCRETE_INPUT(1);
**output = val;
(*output)++;
}
DISCRETE_RESET( dso_output )
{
/* nothing to do - just avoid being stepped */
}
DISCRETE_START( dso_csvlog )
{
DISCRETE_DECLARE_CONTEXT(dso_csvlog)
int log_num, node_num;
log_num = device->same_module_index(*this);
context->sample_num = 0;
m_sample_num = 0;
sprintf(context->name, "discrete_%s_%d.csv", device->tag(), log_num);
context->csv_file = fopen(context->name, "w");
sprintf(m_name, "discrete_%s_%d.csv", device->tag(), log_num);
m_csv_file = fopen(m_name, "w");
/* Output some header info */
fprintf(context->csv_file, "\"MAME Discrete System Node Log\"\n");
fprintf(context->csv_file, "\"Log Version\", 1.0\n");
fprintf(context->csv_file, "\"Sample Rate\", %d\n", this->sample_rate());
fprintf(context->csv_file, "\n");
fprintf(context->csv_file, "\"Sample\"");
fprintf(m_csv_file, "\"MAME Discrete System Node Log\"\n");
fprintf(m_csv_file, "\"Log Version\", 1.0\n");
fprintf(m_csv_file, "\"Sample Rate\", %d\n", this->sample_rate());
fprintf(m_csv_file, "\n");
fprintf(m_csv_file, "\"Sample\"");
for (node_num = 0; node_num < this->active_inputs(); node_num++)
{
fprintf(context->csv_file, ", \"NODE_%2d\"", NODE_INDEX(this->input_node(node_num)));
fprintf(m_csv_file, ", \"NODE_%2d\"", NODE_INDEX(this->input_node(node_num)));
}
fprintf(context->csv_file, "\n");
fprintf(m_csv_file, "\n");
}
DISCRETE_STOP( dso_csvlog )
{
DISCRETE_DECLARE_CONTEXT(dso_csvlog)
/* close any csv files */
if (context->csv_file)
fclose(context->csv_file);
if (m_csv_file)
fclose(m_csv_file);
}
DISCRETE_STEP( dso_csvlog )
{
DISCRETE_DECLARE_CONTEXT(dso_csvlog)
int nodenum;
/* Dump any csv logs */
fprintf(context->csv_file, "%" I64FMT "d", ++context->sample_num);
fprintf(m_csv_file, "%" I64FMT "d", ++m_sample_num);
for (nodenum = 0; nodenum < this->active_inputs(); nodenum++)
{
fprintf(context->csv_file, ", %f", *this->input[nodenum]);
fprintf(m_csv_file, ", %f", *this->input[nodenum]);
}
fprintf(context->csv_file, "\n");
fprintf(m_csv_file, "\n");
}
DISCRETE_RESET( dso_csvlog )
@ -220,35 +73,25 @@ DISCRETE_RESET( dso_csvlog )
this->step();
}
DISCRETE_IS_STEPPING( dso_csvlog )
{
return true;
}
DISCRETE_START( dso_wavlog )
{
DISCRETE_DECLARE_CONTEXT(dso_wavlog)
int log_num;
log_num = device->same_module_index(*this);
sprintf(context->name, "discrete_%s_%d.wav", device->tag(), log_num);
context->wavfile = wav_open(context->name, sample_rate(), active_inputs()/2);
sprintf(m_name, "discrete_%s_%d.wav", device->tag(), log_num);
m_wavfile = wav_open(m_name, sample_rate(), active_inputs()/2);
}
DISCRETE_STOP( dso_wavlog )
{
DISCRETE_DECLARE_CONTEXT(dso_wavlog)
/* close any wave files */
if (context->wavfile)
wav_close(context->wavfile);
if (m_wavfile)
wav_close(m_wavfile);
}
DISCRETE_STEP( dso_wavlog )
{
DISCRETE_DECLARE_CONTEXT(dso_wavlog)
double val;
INT16 wave_data_l, wave_data_r;
@ -260,7 +103,7 @@ DISCRETE_STEP( dso_wavlog )
if (this->active_inputs() == 2)
{
/* DISCRETE_WAVLOG1 */
wav_add_data_16(context->wavfile, &wave_data_l, 1);
wav_add_data_16(m_wavfile, &wave_data_l, 1);
}
else
{
@ -269,7 +112,7 @@ DISCRETE_STEP( dso_wavlog )
val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val;
wave_data_r = (INT16)val;
wav_add_data_16lr(context->wavfile, &wave_data_l, &wave_data_r, 1);
wav_add_data_16lr(m_wavfile, &wave_data_l, &wave_data_r, 1);
}
}
@ -278,7 +121,3 @@ DISCRETE_RESET( dso_wavlog )
this->step();
}
DISCRETE_IS_STEPPING( dso_wavlog )
{
return true;
}

File diff suppressed because it is too large Load Diff

169
src/emu/sound/disc_wav.h Normal file
View File

@ -0,0 +1,169 @@
#pragma once
#ifndef __DISC_WAV_H__
#define __DISC_WAV_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
* Discrete classes 2010 - Couriersud
*
***********************************************************************/
#include "discrete.h"
DISCRETE_CLASS_STEP_RESETA(dss_counter, 1,
int m_clock_type;
int m_out_type;
int m_is_7492;
int m_last_clock;
UINT32 m_last_count;
UINT32 m_last; /* Last clock state */
UINT32 m_min;
UINT32 m_max;
UINT32 m_diff;
double m_t_left; /* time unused during last sample in seconds */
);
DISCRETE_CLASS_STEP_RESETA(dss_lfsr_noise, 2,
unsigned int m_lfsr_reg;
int m_last; /* Last clock state */
double m_t_clock; /* fixed counter clock in seconds */
double m_t_left; /* time unused during last sample in seconds */
double m_sample_step;
double m_t;
UINT8 m_reset_on_high;
UINT8 m_invert_output;
UINT8 m_out_is_f0;
UINT8 m_out_lfsr_reg;
);
DISCRETE_CLASS_STEP_RESETA(dss_noise, 2,
double m_phase;
);
DISCRETE_CLASS_STEP_RESETA(dss_note, 1,
int m_clock_type;
int m_out_type;
int m_last; /* Last clock state */
double m_t_clock; /* fixed counter clock in seconds */
double m_t_left; /* time unused during last sample in seconds */
int m_max1; /* Max 1 Count stored as int for easy use. */
int m_max2; /* Max 2 Count stored as int for easy use. */
int m_count1; /* current count1 */
int m_count2; /* current count2 */
);
DISCRETE_CLASS_STEP_RESETA(dss_sawtoothwave, 1,
double m_phase;
int m_type;
);
DISCRETE_CLASS_STEP_RESETA(dss_sinewave, 1,
double m_phase;
);
DISCRETE_CLASS_STEP_RESETA(dss_squarewave, 1,
double m_phase;
double m_trigger;
);
DISCRETE_CLASS_STEP_RESETA(dss_squarewfix, 1,
int m_flip_flop;
double m_sample_step;
double m_t_left;
double m_t_off;
double m_t_on;
);
DISCRETE_CLASS_STEP_RESETA(dss_squarewave2, 1,
double m_phase;
double m_trigger;
);
DISCRETE_CLASS_STEP_RESETA(dss_trianglewave, 1,
double m_phase;
);
/* Component specific modules */
#define DSS_INV_TAB_SIZE 500
class DISCRETE_CLASS_NAME(dss_inverter_osc): public discrete_base_node, public discrete_step_interface
{
protected:
inline double tftab(double x);
inline double tf(double x);
public:
DISCRETE_CLASS_CONSTRUCTOR(dss_inverter_osc, base)
void step(void);
void reset(void);
private:
double mc_v_cap;
double mc_v_g2_old;
double mc_w;
double mc_wc;
double mc_rp;
double mc_r1;
double mc_r2;
double mc_c;
double mc_tf_a;
double mc_tf_b;
double mc_tf_tab[DSS_INV_TAB_SIZE];
};
DISCRETE_CLASS_STEP_RESETA(dss_op_amp_osc, 1,
const double *m_r1; /* pointers to resistor values */
const double *m_r2;
const double *m_r3;
const double *m_r4;
const double *m_r5;
const double *m_r6;
const double *m_r7;
const double *m_r8;
int m_type;
UINT8 m_flip_flop; /* flip/flop output state */
UINT8 m_flip_flop_xor; /* flip_flop ^ flip_flop_xor, 0 = discharge, 1 = charge */
UINT8 m_output_type;
UINT8 m_has_enable;
double m_v_out_high;
double m_threshold_low; /* falling threshold */
double m_threshold_high; /* rising threshold */
double m_v_cap; /* current capacitor voltage */
double m_r_total; /* all input resistors in parallel */
double m_i_fixed; /* fixed current at the input */
double m_i_enable; /* fixed current at the input if enabled */
double m_temp1; /* Multi purpose */
double m_temp2; /* Multi purpose */
double m_temp3; /* Multi purpose */
double m_is_linear_charge;
double m_charge_rc[2];
double m_charge_exp[2];
double m_charge_v[2];
);
DISCRETE_CLASS_STEP_RESETA(dss_schmitt_osc, 1,
double m_ration_in; /* ratio of total charging voltage that comes from the input */
double m_ratio_feedback; /* ratio of total charging voltage that comes from the feedback */
double m_v_cap; /* current capacitor voltage */
double m_rc; /* r*c */
double m_exponent;
int m_state; /* state of the output */
int m_enable_type;
UINT8 m_input_is_voltage;
);
/* Not yet implemented */
DISCRETE_CLASS_STEP_RESETA(dss_adsrenv, 1,
double m_phase;
);
#endif /* __DISC_WAV_H__ */

View File

@ -39,6 +39,7 @@
#include "discrete.h"
/*************************************
*
* Performance
@ -56,7 +57,7 @@
* Values > 500 have a slightly worse performace (too much cache misses?).
*/
#define MAX_SAMPLES_PER_TASK_SLICE (240)
#define MAX_SAMPLES_PER_TASK_SLICE (960/4)
/*************************************
*
@ -77,39 +78,83 @@
/*************************************
*
* Prototypes
* Internal classes
*
*************************************/
//static DEVICE_RESET( discrete );
//static STREAM_UPDATE( discrete_stream_update );
static STREAM_UPDATE( buffer_stream_update );
typedef struct
{
const discrete_task *task;
const double *ptr;
int output_node;
double buffer;
} discrete_source_node;
typedef linked_list_t<discrete_source_node *> source_node_list_t;
class discrete_task
{
friend class discrete_device;
public:
virtual ~discrete_task(void) { }
inline void step_nodes(void);
inline bool lock_threadid(INT32 threadid)
{
INT32 prev_id;
prev_id = compare_exchange32(&m_threadid, -1, threadid);
return (prev_id == -1 && m_threadid == threadid);
}
inline void unlock(void) { m_threadid = -1; }
discrete_device *device;
//const linked_list_entry *list;
node_step_list_t step_list;
/* list of source nodes */
source_node_list_t source_list; /* discrete_source_node */
int task_group;
double *m_ptr[DISCRETE_MAX_TASK_OUTPUTS];
protected:
discrete_task(discrete_device *pdev)
: device(pdev), task_group(0), m_threadid(-1), m_numbuffered(0)
{
source_list.reset();
step_list.reset();
}
static void *task_callback(void *param, int threadid);
inline bool process(void);
void check(discrete_task *dest_task);
void prepare_for_queue(int samples);
double *m_node_buf[DISCRETE_MAX_TASK_OUTPUTS];
private:
volatile INT32 m_threadid;
int m_numbuffered;
volatile int m_samples;
const double *m_source[DISCRETE_MAX_TASK_OUTPUTS];
discrete_base_node *m_nodes[DISCRETE_MAX_TASK_OUTPUTS];
};
static int profiling = 0;
/*************************************
*
* Debug logging
* Included simulation objects
*
*************************************/
void CLIB_DECL ATTR_PRINTF(2,3) discrete_device::discrete_log(const char *text, ...) const
{
if (DISCRETE_DEBUGLOG)
{
va_list arg;
va_start(arg, text);
if(m_disclogfile)
{
vfprintf(m_disclogfile, text, arg);
fprintf(m_disclogfile, "\n");
fflush(m_disclogfile);
}
va_end(arg);
}
}
#include "disc_sys.c" /* discrete core modules and support functions */
#include "disc_wav.c" /* Wave sources - SINE/SQUARE/NOISE/etc */
#include "disc_mth.c" /* Math Devices - ADD/GAIN/etc */
#include "disc_inp.c" /* Input Devices - INPUT/CONST/etc */
#include "disc_flt.c" /* Filter Devices - RCF/HPF/LPF */
#include "disc_dev.c" /* Popular Devices - NE555/etc */
/*************************************
*
@ -158,31 +203,21 @@ INLINE void linked_list_add(const discrete_device *info, linked_list_entry **lis
/*************************************
*
* Included simulation objects
* Task implementation
*
*************************************/
#include "disc_sys.c" /* discrete core modules and support functions */
#include "disc_wav.c" /* Wave sources - SINE/SQUARE/NOISE/etc */
#include "disc_mth.c" /* Math Devices - ADD/GAIN/etc */
#include "disc_inp.c" /* Input Devices - INPUT/CONST/etc */
#include "disc_flt.c" /* Filter Devices - RCF/HPF/LPF */
#include "disc_dev.c" /* Popular Devices - NE555/etc */
/*************************************
*
* Master module list
*
*************************************/
inline void discrete_device::step_nodes_in_list(node_list_t &list)
inline void discrete_task::step_nodes(void)
{
if (EXPECTED(!profiling))
for_each(discrete_source_node *, sn, &source_list)
{
for_each(discrete_base_node *, entry, &list)
sn.item()->buffer = *sn.item()->ptr++;
}
if (EXPECTED(!device->profiling()))
{
for_each(discrete_step_interface *, entry, &step_list)
{
/* Now step the node */
entry.item()->step();
@ -192,9 +227,9 @@ inline void discrete_device::step_nodes_in_list(node_list_t &list)
{
osd_ticks_t last = get_profile_ticks();
for_each(discrete_base_node *, entry, &list)
for_each(discrete_step_interface *, entry, &step_list)
{
discrete_base_node *node = entry.item();
discrete_step_interface *node = entry.item();
node->run_time -= last;
node->step();
@ -202,26 +237,276 @@ inline void discrete_device::step_nodes_in_list(node_list_t &list)
node->run_time += last;
}
}
for (int i = 0; i < m_numbuffered; i++)
*(m_ptr[i]++) = *m_source[i];
}
void *discrete_task::task_callback(void *param, int threadid)
{
task_list_t *list = (task_list_t *) param;
do
{
for_each(discrete_task *, task, list)
{
/* try to lock */
if (task.item()->lock_threadid(threadid))
{
if (!task.item()->process())
return NULL;
task.item()->unlock();
}
}
} while (1);
return NULL;
}
bool discrete_task::process(void)
{
int samples = MIN(m_samples, MAX_SAMPLES_PER_TASK_SLICE);
/* check dependencies */
for_each(discrete_source_node *, sn, &source_list)
{
int avail;
avail = sn.item()->task->m_ptr[sn.item()->output_node] - sn.item()->ptr;
assert_always(avail >= 0, "task_callback: available samples are negative");
if (avail < samples)
samples = avail;
}
m_samples -= samples;
assert_always(m_samples >=0, "task_callback: task_samples got negative");
while (samples > 0)
{
/* step */
step_nodes();
samples--;
}
if (m_samples == 0)
{
/* return and keep the task locked so it is not picked up by other worker threads */
return false;
}
return true;
}
void discrete_task::prepare_for_queue(int samples)
{
m_samples = samples;
/* set up task buffers */
for (int i = 0; i < m_numbuffered; i++)
m_ptr[i] = m_node_buf[i];
/* initialize sources */
for_each(discrete_source_node *, sn, &source_list)
{
sn.item()->ptr = sn.item()->task->m_node_buf[sn.item()->output_node];
}
}
void discrete_task::check(discrete_task *dest_task)
{
int inputnum;
/* Determine, which nodes in the task are referenced by nodes in dest_task
* and add them to the list of nodes to be buffered for further processing
*/
for_each(discrete_step_interface *, node_entry, &step_list)
{
discrete_base_node *task_node = node_entry.item()->self;
for_each(discrete_step_interface *, step_entry, &dest_task->step_list)
{
discrete_base_node *dest_node = step_entry.item()->self;
/* loop over all active inputs */
for (inputnum = 0; inputnum < dest_node->active_inputs(); inputnum++)
{
int inputnode = dest_node->input_node(inputnum);
if IS_VALUE_A_NODE(inputnode)
{
if (NODE_DEFAULT_NODE(task_node->block_node()) == NODE_DEFAULT_NODE(inputnode))
{
discrete_source_node *source;
int i, found = -1;
for (i = 0; i < m_numbuffered; i++)
if (m_nodes[i]->block_node() == inputnode)
{
found = i;
break;
}
if (found<0)
{
if (m_numbuffered >= DISCRETE_MAX_TASK_OUTPUTS)
fatalerror("dso_task_start - Number of maximum buffered nodes exceeded");
m_node_buf[m_numbuffered] = auto_alloc_array(task_node->device->machine, double,
((task_node->sample_rate() + STREAMS_UPDATE_FREQUENCY) / STREAMS_UPDATE_FREQUENCY));
m_source[m_numbuffered] = (double *) dest_node->input[inputnum];
m_nodes[m_numbuffered] = task_node->device->discrete_find_node(inputnode);
i = m_numbuffered;
m_numbuffered++;
}
device->discrete_log("dso_task_start - buffering %d(%d) in task %p group %d referenced by %d group %d", NODE_INDEX(inputnode), NODE_CHILD_NODE_NUM(inputnode), this, task_group, dest_node->index(), dest_task->task_group);
/* register into source list */
source = auto_alloc(dest_node->device->machine, discrete_source_node);
dest_task->source_list.add_tail(source);
source->task = this;
source->output_node = i;
/* point the input to a buffered location */
dest_node->input[inputnum] = &source->buffer;
}
}
}
}
}
}
/*************************************
*
* Find a given node
* Base node implementation
*
*************************************/
discrete_base_node::discrete_base_node() :
m_step_intf(NULL),
m_input_intf(NULL)
{
output[0] = 0.0;
}
discrete_base_node::~discrete_base_node(void)
{
/* currently noting */
}
void discrete_base_node::init(discrete_device * pdev, const discrete_sound_block *xblock)
{
device = pdev;
m_block = xblock;
m_custom = m_block->custom;
m_active_inputs = m_block->active_inputs;
m_step_intf = dynamic_cast<discrete_step_interface *>(this);
m_input_intf = dynamic_cast<discrete_input_interface *>(this);
m_output_intf = dynamic_cast<discrete_output_interface *>(this);
if (m_step_intf)
{
m_step_intf->run_time = 0;
m_step_intf->self = this;
}
}
void discrete_base_node::start(void)
{
}
int discrete_base_node::index(void)
{
return NODE_INDEX(m_block->node);
}
void discrete_base_node::save_state(device_t *device)
{
if (m_block->node != NODE_SPECIAL)
state_save_register_device_item_array(device, m_block->node, output);
}
discrete_base_node *discrete_device::discrete_find_node(int node)
{
if (node < NODE_START || node > NODE_END) return NULL;
return m_indexed_node[NODE_INDEX(node)];
}
void discrete_base_node::find_input_nodes(void)
{
int inputnum;
/* loop over all active inputs */
for (inputnum = 0; inputnum < m_active_inputs; inputnum++)
{
int inputnode = m_block->input_node[inputnum];
/* if this input is node-based, find the node in the indexed list */
if IS_VALUE_A_NODE(inputnode)
{
discrete_base_node *node_ref = device->m_indexed_node[NODE_INDEX(inputnode)];
if (!node_ref)
fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", index(), NODE_INDEX(inputnode));
if ((NODE_CHILD_NODE_NUM(inputnode) >= node_ref->max_output()) /*&& (node_ref->module_type() != DST_CUSTOM)*/)
fatalerror("discrete_start - NODE_%02d referenced non existent output %d on node NODE_%02d", index(), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode));
input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */
m_input_is_node |= 1 << inputnum; /* Bit flag if input is node */
}
else
{
/* warn if trying to use a node for an input that can only be static */
if IS_VALUE_A_NODE(m_block->initial[inputnum])
{
device->discrete_log("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum);
/* also report it in the error log so it is not missed */
logerror("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum);
}
else
{
input[inputnum] = &(m_block->initial[inputnum]);
}
}
}
for (inputnum = m_active_inputs; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
{
/* FIXME: Check that no nodes follow ! */
input[inputnum] = &(m_block->initial[inputnum]);
}
}
/*************************************
*
* Build import list
* Device implementation
*
*************************************/
//-------------------------------------------------
// discrete_log: Debug logging
//-------------------------------------------------
void CLIB_DECL ATTR_PRINTF(2,3) discrete_device::discrete_log(const char *text, ...) const
{
if (DISCRETE_DEBUGLOG)
{
va_list arg;
va_start(arg, text);
if(m_disclogfile)
{
vfprintf(m_disclogfile, text, arg);
fprintf(m_disclogfile, "\n");
fflush(m_disclogfile);
}
va_end(arg);
}
}
//-------------------------------------------------
// discrete_build_list: Build import list
//-------------------------------------------------
void discrete_device::discrete_build_list(const discrete_sound_block *intf, linked_list_entry ***current)
{
int node_count = 0;
@ -289,11 +574,9 @@ void discrete_device::discrete_build_list(const discrete_sound_block *intf, link
}
}
/*************************************
*
* Sanity check list
*
*************************************/
//-------------------------------------------------
// discrete_sanity_check: Sanity check list
//-------------------------------------------------
void discrete_device::discrete_sanity_check(void)
{
@ -327,6 +610,10 @@ void discrete_device::discrete_sanity_check(void)
}
//-------------------------------------------------
// discrete_sanity_check: Sanity check list
//-------------------------------------------------
/*************************************
*
* Master discrete system start
@ -345,6 +632,19 @@ static UINT64 list_run_time(const node_list_t &list)
UINT64 total = 0;
for_each(discrete_base_node *, node, &list)
{
discrete_step_interface *step;
if (node.item()->interface(step))
total += step->run_time;
}
return total;
}
static UINT64 step_list_run_time(const node_step_list_t &list)
{
UINT64 total = 0;
for_each(discrete_step_interface *, node, &list)
{
total += node.item()->run_time;
}
@ -367,14 +667,16 @@ void discrete_device::display_profiling(void)
printf("Threshold (mean): %16" I64FMT "d\n", tresh / m_total_samples );
for_each(discrete_base_node *, node, &m_node_list)
{
if (node.item()->run_time > tresh)
printf("%3d: %20s %8.2f %10.2f\n", node.item()->index(), node.item()->module_name(), (float) node.item()->run_time / (float) total * 100.0, ((float) node.item()->run_time) / (float) m_total_samples);
discrete_step_interface *step;
if (node.item()->interface(step))
if (step->run_time > tresh)
printf("%3d: %20s %8.2f %10.2f\n", node.item()->index(), node.item()->module_name(), (float) step->run_time / (float) total * 100.0, ((float) step->run_time) / (float) m_total_samples);
}
/* Task information */
for_each(discrete_task *, task, &task_list)
{
tt = list_run_time(task.item()->list);
tt = step_list_run_time(task.item()->step_list);
printf("Task(%d): %8.2f %15.2f\n", task.item()->task_group, tt / (double) total * 100.0, tt / (double) m_total_samples);
}
@ -396,64 +698,7 @@ void discrete_device::display_profiling(void)
*
*************************************/
static void *task_callback(void *param, int threadid)
{
task_list_t *list = (task_list_t *) param;
int samples;
do
{
for_each(discrete_task *, task, list)
{
/* try to lock */
if (task.item()->lock_threadid(threadid))
{
samples = MIN(task.item()->samples, MAX_SAMPLES_PER_TASK_SLICE);
/* check dependencies */
for_each(discrete_source_node *, sn, &task.item()->source_list)
{
int avail;
avail = sn.item()->task->ptr[sn.item()->output_node] - sn.item()->ptr;
assert_always(avail >= 0, "task_callback: available samples are negative");
if (avail < samples)
samples = avail;
}
task.item()->samples -= samples;
assert_always(task.item()->samples >=0, "task_callback: task_samples got negative");
while (samples > 0)
{
/* step */
task.item()-> device->step_nodes_in_list(task.item()->list);
samples--;
}
if (task.item()->samples == 0)
{
/* return and keep the task locked so it is not picked up by other worker threads */
return NULL;
}
task.item()->unlock();
}
}
} while (1);
return NULL;
}
static STREAM_UPDATE( buffer_stream_update )
{
const discrete_base_node *node = (discrete_base_node *) param;
const struct dss_input_context *context = (struct dss_input_context *)node->context;
stream_sample_t *ptr = outputs[0];
int data = context->data;
int samplenum = samples;
while (samplenum-- > 0)
*(ptr++) = data;
}
@ -502,7 +747,7 @@ void discrete_device::init_nodes(const linked_list_entry *block_list)
{
/* Output Node */
case DSO_OUTPUT:
m_output_list.add_tail(node);
/* nothing -> handled later */
break;
/* CSVlog Node for debugging */
@ -518,18 +763,16 @@ void discrete_device::init_nodes(const linked_list_entry *block_list)
if (task != NULL)
fatalerror("init_nodes() - Nested DISCRETE_START_TASK.");
task = auto_alloc_clear(machine, discrete_task(this));
node->context = task;
task->task_group = block->initial[0];
if (task->task_group < 0 || task->task_group >= DISCRETE_MAX_TASK_GROUPS)
fatalerror("discrete_dso_task: illegal task_group %d", task->task_group);
//printf("task group %d\n", task->task_group);
task_list.add_tail(task);
break;
case DSO_TASK_END:
if (task == NULL)
fatalerror("init_nodes() - NO DISCRETE_START_TASK.");
task->numbuffered = 0;
task->task_group = -1; /* will be set later */
task->source_list.reset();
task_list.add_tail(task);
node->context = task;
//task = NULL;
break;
default:
@ -546,13 +789,10 @@ void discrete_device::init_nodes(const linked_list_entry *block_list)
}
/* if we are an stream input node, track that */
if (block->type == DSS_INPUT_STREAM)
discrete_dss_input_stream_node *input_stream = dynamic_cast<discrete_dss_input_stream_node *>(node);
if (input_stream != NULL)
{
m_input_list.add_tail(node);
}
else if (block->type == DSS_INPUT_BUFFER)
{
m_input_list.add_tail(node);
m_input_stream_list.add_tail(input_stream);
}
/* add to node list */
@ -560,15 +800,22 @@ void discrete_device::init_nodes(const linked_list_entry *block_list)
/* our running order just follows the order specified */
/* does the node step ? */
if (node->is_stepping())
discrete_step_interface *step;
if (node->interface(step))
{
/* do we belong to a task? */
if (task == NULL)
fatalerror("init_nodes() - found node outside of task.");
fatalerror("init_nodes() - found node outside of task: %s", node->module_name() );
else
task->list.add_tail(node);
task->step_list.add_tail(step);
}
/* if this is an output interface, add it the output list */
discrete_output_interface *out;
if (node->interface(out))
m_output_list.add_tail(out);
if (block->type == DSO_TASK_END)
{
task = NULL;
@ -594,86 +841,6 @@ void discrete_device::init_nodes(const linked_list_entry *block_list)
*
*************************************/
discrete_base_node::discrete_base_node(discrete_device * pdev, const discrete_sound_block *xblock) :
context(NULL),
device(pdev),
run_time(0),
m_context_size(0),
m_block(xblock)
{
output[0] = 0.0;
m_custom = m_block->custom;
m_active_inputs = m_block->active_inputs;
}
discrete_base_node::~discrete_base_node(void)
{
if (m_context_size)
global_free(context);
}
void discrete_base_node::start(void)
{
/* allocate memory if necessary */
if (m_context_size)
context = global_alloc_array(UINT8, m_context_size);
}
int discrete_base_node::index(void)
{
return NODE_INDEX(m_block->node);
}
void discrete_base_node::save_state(device_t *device)
{
if (m_block->node != NODE_SPECIAL)
state_save_register_device_item_array(device, m_block->node, output);
}
void discrete_base_node::find_input_nodes(void)
{
int inputnum;
/* loop over all active inputs */
for (inputnum = 0; inputnum < m_active_inputs; inputnum++)
{
int inputnode = m_block->input_node[inputnum];
/* if this input is node-based, find the node in the indexed list */
if IS_VALUE_A_NODE(inputnode)
{
discrete_base_node *node_ref = device->m_indexed_node[NODE_INDEX(inputnode)];
if (!node_ref)
fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", index(), NODE_INDEX(inputnode));
if ((NODE_CHILD_NODE_NUM(inputnode) >= node_ref->max_output()) /*&& (node_ref->module_type() != DST_CUSTOM)*/)
fatalerror("discrete_start - NODE_%02d referenced non existent output %d on node NODE_%02d", index(), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode));
input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */
m_input_is_node |= 1 << inputnum; /* Bit flag if input is node */
}
else
{
/* warn if trying to use a node for an input that can only be static */
if IS_VALUE_A_NODE(m_block->initial[inputnum])
{
device->discrete_log("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum);
/* also report it in the error log so it is not missed */
logerror("Warning - discrete_start - NODE_%02d trying to use a node on static input %d", index(), inputnum);
}
else
{
input[inputnum] = &(m_block->initial[inputnum]);
//node->input[inputnum] = getDoublePtr(node->block->initial[inputnum]);
}
}
}
for (inputnum = m_active_inputs; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
{
/* FIXME: Check that no nodes follow ! */
input[inputnum] = &(m_block->initial[inputnum]);
}
}
int discrete_device::same_module_index(discrete_base_node &node)
{
@ -700,38 +867,24 @@ const device_type DISCRETE = discrete_device_config::static_alloc_device_config;
// DEVICE CONFIGURATION
//**************************************************************************
#if 0
//-------------------------------------------------
// static_set_type - configuration helper to set
// the chip type
// static_set_intf - configuration helper to set
// the interface
//-------------------------------------------------
void discrete_device_config::static_set_type(device_config *device, int type)
void discrete_device_config::static_set_intf(device_config *device, const discrete_sound_block *intf)
{
discrete_device_config *asc = downcast<discrete_device_config *>(device);
asc->m_type = type;
discrete_device_config *disc = downcast<discrete_device_config *>(device);
disc->m_intf = intf;
}
//-------------------------------------------------
// static_set_type - configuration helper to set
// the IRQ callback
//-------------------------------------------------
void discrete_device_config::static_set_irqf(device_config *device, void (*irqf)(device_t *device, int state))
{
discrete_device_config *asc = downcast<discrete_device_config *>(device);
asc->m_irq_func = irqf;
}
#endif
//-------------------------------------------------
// discrete_device_config - constructor
//-------------------------------------------------
discrete_device_config::discrete_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
: device_config(mconfig, static_alloc_device_config, "DISCRETE", tag, owner, clock),
device_config_sound_interface(mconfig, *this)
device_config_sound_interface(mconfig, *this), m_intf(NULL)
{
}
@ -774,7 +927,7 @@ discrete_device::~discrete_device(void)
{
osd_work_queue_free(m_queue);
if (profiling)
if (m_profiling)
{
display_profiling();
}
@ -805,7 +958,7 @@ void discrete_device::device_start()
//m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate);
linked_list_entry **intf;
const discrete_sound_block *intf_start = (discrete_sound_block *) baseconfig().static_config();
const discrete_sound_block *intf_start = (m_config.m_intf != NULL) ? m_config.m_intf : (discrete_sound_block *) baseconfig().static_config();
char name[32];
/* If a clock is specified we will use it, otherwise run at the audio sample rate. */
@ -825,8 +978,9 @@ void discrete_device::device_start()
m_disclogfile = fopen(name, "w");
/* enable profiling */
m_profiling = 0;
if (getenv("DISCRETE_PROFILING"))
profiling = atoi(getenv("DISCRETE_PROFILING"));
m_profiling = atoi(getenv("DISCRETE_PROFILING"));
/* Build the final block list */
m_block_list = NULL;
@ -839,7 +993,7 @@ void discrete_device::device_start()
/* Start with empty lists */
m_node_list.reset();
m_output_list.reset();
m_input_list.reset();
m_input_stream_list.reset();
/* allocate memory to hold pointers to nodes by index */
m_indexed_node = auto_alloc_array_clear(this->machine, discrete_base_node *, DISCRETE_MAX_NODES);
@ -854,7 +1008,7 @@ void discrete_device::device_start()
}
/* initialize the stream(s) */
discrete_stream = stream_create(this,m_input_list.count(), m_output_list.count(), m_sample_rate, this, static_stream_generate);
m_stream = stream_create(this,m_input_stream_list.count(), m_output_list.count(), m_sample_rate, this, static_stream_generate);
/* allocate a queue */
@ -866,6 +1020,17 @@ void discrete_device::device_start()
{
node.item()->start();
}
/* Now set up tasks */
for_each(discrete_task *, task, &task_list)
{
for_each(discrete_task *, dest_task, &task_list)
{
if (task.item()->task_group > dest_task.item()->task_group)
dest_task.item()->check(task.item());
}
}
}
@ -876,7 +1041,7 @@ void discrete_device::device_start()
void discrete_device::device_reset()
{
stream_update(discrete_stream);
update();
/* loop over all nodes */
for_each (discrete_base_node *, node, &m_node_list)
@ -906,47 +1071,35 @@ void discrete_device::stream_generate(stream_sample_t **inputs, stream_sample_t
return;
/* Setup any output streams */
outputnum = 0;
for_each(discrete_base_node *, node, &m_output_list)
for_each(discrete_output_interface *, node, &m_output_list)
{
node.item()->context = (void *) outputs[outputnum];
node.item()->set_output(outputs[outputnum]);
outputnum++;
}
/* Setup any input streams */
for_each(discrete_base_node *, node, &m_input_list)
for_each(discrete_dss_input_stream_node *, node, &m_input_stream_list)
{
struct dss_input_context *context = (struct dss_input_context *) node.item()->context;
context->ptr = (stream_sample_t *) inputs[context->stream_in_number];
node.item()->m_ptr = (stream_sample_t *) inputs[node.item()->m_stream_in_number];
}
/* Setup tasks */
for_each(discrete_task *, task, &task_list)
{
int i;
task.item()->samples = samples;
/* unlock the thread */
task.item()->unlock();
/* set up task buffers */
for (i = 0; i < task.item()->numbuffered; i++)
task.item()->ptr[i] = task.item()->node_buf[i];
/* initialize sources */
for_each(discrete_source_node *, sn, &task.item()->source_list)
{
sn.item()->ptr = sn.item()->task->node_buf[sn.item()->output_node];
}
task.item()->prepare_for_queue(samples);
}
for_each(discrete_task *, task, &task_list)
{
/* Fire a work item for each task */
osd_work_item_queue(m_queue, task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE);
osd_work_item_queue(m_queue, discrete_task::task_callback, (void *) &task_list, WORK_ITEM_FLAG_AUTO_RELEASE);
}
osd_work_queue_wait(m_queue, osd_ticks_per_second()*10);
if (profiling)
if (m_profiling)
{
m_total_samples += samples;
m_total_stream_updates++;
@ -967,7 +1120,7 @@ READ8_MEMBER( discrete_device::read )
if (node)
{
/* Bring the system up to now */
stream_update(discrete_stream);
stream_update(m_stream);
data = (UINT8) node->output[NODE_CHILD_NODE_NUM(offset)];
}
@ -988,44 +1141,11 @@ WRITE8_MEMBER( discrete_device::write )
/* Update the node input value if it's a proper input node */
if (node)
{
struct dss_input_context *context = (struct dss_input_context *)node->context;
UINT8 new_data = 0;
switch (node->module_type())
{
case DSS_INPUT_DATA:
case DSS_INPUT_BUFFER:
new_data = data;
break;
case DSS_INPUT_LOGIC:
case DSS_INPUT_PULSE:
new_data = data ? 1 : 0;
break;
case DSS_INPUT_NOT:
new_data = data ? 0 : 1;
break;
}
if (context->data != new_data)
{
if (context->is_buffered)
{
/* Bring the system up to now */
stream_update(context->buffer_stream);
context->data = new_data;
}
else
{
/* Bring the system up to now */
stream_update(discrete_stream);
context->data = new_data;
/* Update the node output here so we don't have to do it each step */
node->output[0] = new_data * context->gain + context->offset;
}
}
discrete_input_interface *intf;
if (node->interface(intf))
intf->input_write(0, data);
else
discrete_log("discrete_sound_w write to non-input NODE_%02d\n", offset-NODE_00);
}
else
{

View File

@ -3497,7 +3497,7 @@
*
*************************************/
#define DISCRETE_CLASS_FUNC(_class, _func) _class ## _node :: _func
#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)
@ -3505,7 +3505,7 @@
#define DISCRETE_STOP(_class) void DISCRETE_CLASS_FUNC(_class, stop)(void)
#define DISCRETE_IS_STEPPING(_class) bool DISCRETE_CLASS_FUNC(_class, is_stepping)(void)
#define DISCRETE_DECLARE_CONTEXT(_name) struct _name##_context *context = (struct _name##_context *)this->context;
#define DISCRETE_DECLARE_CONTEXT(_name) struct _name##_context *context = (struct _name##_context *)this->m_context;
#define DISCRETE_DECLARE_INFO(_name) const _name *info = (const _name *)this->custom_data();
#define DISCRETE_INPUT(_num) (*(this->input[_num]))
@ -3760,12 +3760,14 @@ struct _linked_list_entry
template<class T> class enumerator_t
{
public:
enumerator_t(linked_list_entry *first) : m_cur(first) { }
~enumerator_t() { }
enumerator_t(linked_list_entry *first, resource_pool &pool = global_resource_pool) : m_cur(first) { }
virtual ~enumerator_t() { }
//inline void set_first(linked_list_entry *first) { m_cur = first; }
inline T item(void) { return (T) m_cur->ptr; }
inline void next(void) { m_cur = m_cur->next; }
inline bool has_item(void) { return (m_cur != NULL); }
protected:
private:
linked_list_entry *m_cur;
};
@ -3832,129 +3834,12 @@ public:
}
return cnt;
}
inline enumerator_t<T> enumerator(void) const {enumerator_t<T> r(m_first); return r; }
inline enumerator_t<T> enumerator(void) const { enumerator_t<T> r(m_first); return r; }
private:
linked_list_entry *m_first;
linked_list_entry *m_last;
};
/*************************************
*
* Forward declarations
*
*************************************/
typedef struct _discrete_sound_block discrete_sound_block;
class discrete_base_node;
class discrete_device;
typedef linked_list_t<discrete_base_node *> node_list_t;
/*************************************
*
* Discrete module definition
*
*************************************/
class discrete_node_base_factory // Each class which can have run time specified object creation
{ // has an equivalent factory class that provides a Create virtual
// function override
public:
virtual discrete_base_node *Create(discrete_device * pdev, const discrete_sound_block *block) = 0;
virtual ~discrete_node_base_factory() {}
};
/*************************************
*
* 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 */
};
/*************************************
*
* Core runtime info
*
* this structure is exposed mainly
* to read the sample rate info
* and possibly context info
*
*************************************/
typedef struct _discrete_source_node discrete_source_node;
typedef linked_list_t<discrete_source_node *> source_node_list_t;
class discrete_task
{
public:
discrete_task(discrete_device *pdev)
: device(pdev), numbuffered(0), task_group(0), m_threadid(-1)
{
source_list.reset();
list.reset();
}
~discrete_task(void) { }
discrete_device *device;
//const linked_list_entry *list;
node_list_t list;
volatile int samples;
/* list of source nodes */
source_node_list_t source_list; /* discrete_source_node */
int numbuffered;
int task_group;
double *ptr[DISCRETE_MAX_TASK_OUTPUTS];
const double *source[DISCRETE_MAX_TASK_OUTPUTS];
double *node_buf[DISCRETE_MAX_TASK_OUTPUTS];
discrete_base_node *nodes[DISCRETE_MAX_TASK_OUTPUTS];
inline bool lock_threadid(INT32 threadid)
{
INT32 prev_id;
prev_id = compare_exchange32(&m_threadid, -1, threadid);
return (prev_id == -1 && m_threadid == threadid);
}
inline void unlock(void) { m_threadid = -1; }
private:
volatile INT32 m_threadid;
};
typedef linked_list_t<discrete_task *> task_list_t;
struct _discrete_source_node
{
const discrete_task *task;
const double *ptr;
int output_node;
double buffer;
};
/*************************************
*
* Node-specific struct types
@ -4317,108 +4202,9 @@ 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 */
/* from disc_inp.c */
DSS_ADJUSTMENT, /* Adjustment node */
DSS_CONSTANT, /* Constant node */
/* Do not change or add to the next 4 without also modifying disc_inp.c */
DSS_INPUT_DATA, /* Input node */
DSS_INPUT_LOGIC, /* Input node */
DSS_INPUT_NOT, /* Input node */
DSS_INPUT_PULSE, /* Input node, single pulsed version */
DSS_INPUT_STREAM, /* Stream Input */
DSS_INPUT_BUFFER, /* Buffer Input node, for high freq inputs like DAC */
/* standard node */
/* from disc_wav.c */
/* generic modules */
DSS_COUNTER, /* External clock Binary Counter */
DSS_COUNTER_FIX, /* Fixed frequency Binary Counter */
DSS_LFSR_NOISE, /* Cyclic/Resetable LFSR based Noise generator */
DSS_NOTE, /* Note Generator */
DSS_NOISE, /* Random Noise generator */
DSS_SAWTOOTHWAVE, /* Sawtooth wave generator */
DSS_SINEWAVE, /* Sine Wave generator */
DSS_SQUAREWAVE, /* Square Wave generator, adjustable frequency based */
DSS_SQUAREWFIX, /* Square Wave generator, fixed frequency based (faster) */
DSS_SQUAREWAVE2, /* Square Wave generator, time based */
DSS_INVERTER_OSC, /* Oscillator based on inverter circuits */
DSS_TRIANGLEWAVE, /* Triangle wave generator, frequency based */
/* Component specific */
DSS_OP_AMP_OSC, /* Op Amp Oscillator */
DSS_SCHMITT_OSC, /* Schmitt Feedback Oscillator */
/* Not yet implemented */
DSS_ADSR, /* ADSR Envelope generator */
/* from disc_mth.c */
/* generic modules */
DST_ADDER, /* C = A+B */
DST_CLAMP, /* Signal Clamp */
DST_DIVIDE, /* Gain Block, C = A/B */
DST_GAIN, /* Gain Block, D = (A*B) + C*/
DST_BITS_DECODE, /* Decode bits from input value */
DST_LOGIC_INV,
DST_LOGIC_AND,
DST_LOGIC_NAND,
DST_LOGIC_OR,
DST_LOGIC_NOR,
DST_LOGIC_XOR,
DST_LOGIC_NXOR,
DST_LOGIC_DFF,
DST_LOGIC_JKFF,
DST_LOGIC_SHIFT,
DST_LOOKUP_TABLE, /* return value from lookup table */
DST_MULTIPLEX, /* 1 of x multiplexer */
DST_ONESHOT, /* One-shot pulse generator */
DST_RAMP, /* Ramp up/down simulation */
DST_SAMPHOLD, /* Sample & hold transform */
DST_SWITCH, /* C = A or B */
DST_ASWITCH, /* Analog switch */
DST_TRANSFORM, /* Muliply math functions based on string */
/* Component specific */
DST_COMP_ADDER, /* Selectable Parallel Component Adder */
DST_DAC_R1, /* R1 Ladder DAC with cap smoothing */
DST_DIODE_MIX, /* Diode mixer */
DST_INTEGRATE, /* Various Integration circuits */
DST_MIXER, /* Final Mixing Stage */
DST_OP_AMP, /* Op Amp circuits */
DST_OP_AMP_1SHT, /* Op Amp One Shot */
DST_TVCA_OP_AMP, /* Triggered Op Amp Voltage controlled amplifier circuits */
DST_VCA, /* IC Voltage controlled amplifiers */
DST_XTIME_BUFFER,
DST_XTIME_AND,
DST_XTIME_OR,
DST_XTIME_XOR,
/* from disc_flt.c */
/* generic modules */
DST_FILTER1, /* 1st Order Filter, Low or High Pass */
DST_FILTER2, /* 2nd Order Filter, Low, High, or Band Pass */
/* Component specific */
DST_SALLEN_KEY, /* Sallen key filters */
DST_CRFILTER, /* RC Bypass Filter (High Pass) */
DST_OP_AMP_FILT, /* Op Amp filters */
DST_RC_CIRCUIT_1,
DST_RCDISC, /* Simple RC discharge */
DST_RCDISC2, /* Switched 2 Input RC discharge */
DST_RCDISC3, /* Charge/discharge with diode */
DST_RCDISC4, /* various Charge/discharge circuits */
DST_RCDISC5, /* Diode in series with R//C */
DST_RCINTEGRATE, /* NPN RC charge/discharge network */
DST_RCDISC_MOD, /* Two diode mixer with Transistor and charge/discharge network */
DST_RCFILTER, /* Simple RC Filter network */
DST_RCFILTER_SW, /* Switcheable RC Filter network */
/* For testing - seem to be buggered. Use versions not ending in N. */
DST_RCFILTERN, /* Simple RC Filter network */
DST_RCDISCN, /* Simple RC discharge */
DST_RCDISC2N, /* Switched 2 Input RC discharge */
/* from disc_dev.c */
/* Component specific */
DSD_555_ASTBL, /* NE555 Astable Emulation */
DSD_555_MSTBL, /* NE555 Monostable Emulation */
DSD_555_CC, /* Constant Current 555 circuit (VCO)*/
DSD_555_VCO1, /* Op-Amp linear ramp based 555 VCO */
DSD_566, /* NE566 Emulation */
DSD_LS624, /* 74LS624 Emulation */
DSS_NODE, /* a standard node */
/* Custom */
DST_CUSTOM, /* whatever you want */
@ -4443,6 +4229,83 @@ typedef enum
DSO_LAST
} discrete_node_type;
/*************************************
*
* Forward declarations
*
*************************************/
typedef struct _discrete_sound_block discrete_sound_block;
class discrete_node_base_factory;
class discrete_task;
class discrete_base_node;
class discrete_dss_input_stream_node;
class discrete_device;
typedef linked_list_t<discrete_base_node *> node_list_t;
typedef linked_list_t<discrete_dss_input_stream_node *> input_stream_node_list_t;
typedef linked_list_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 */
};
/*************************************
*
* 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 linked_list_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_output_interface
{
public:
virtual ~discrete_output_interface() { }
virtual void set_output(stream_sample_t *ptr) = 0;
};
/*************************************
*
@ -4456,25 +4319,18 @@ READ8_DEVICE_HANDLER( discrete_sound_r );
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//FIXME: Later
#if 0
#define MCFG_DISCRETE_ADD(_tag, _clock, _type, _irqf) \
MCFG_DEVICE_ADD(_tag, ASC, _clock) \
MCFG_DISCRETE_TYPE(_type) \
MCFG_IRQ_FUNC(_irqf)
#define MCFG_DISCRETE_REPLACE(_tag, _clock, _type, _irqf) \
MCFG_DEVICE_REPLACE(_tag, ASC, _clock) \
MCFG_DISCRETE_TYPE(_type) \
MCFG_IRQ_FUNC(_irqf)
#define MCFG_DISCRETE_ADD(_tag, _clock, _intf) \
MCFG_DEVICE_ADD(_tag, DISCRETE, _clock) \
MCFG_DISCRETE_INTF(_intf)
#define MCFG_DISCRETE_TYPE(_type) \
DISCRETE_device_config::static_set_type(device, _type); \
#define MCFG_DISCRETE_REPLACE(_tag, _clock, _intf) \
MCFG_DEVICE_REPLACE(_tag, DISCRETE, _clock) \
MCFG_DISCRETE_INTF(_intf)
#define MCFG_IRQ_FUNC(_irqf) \
DISCRETE_device_config::static_set_irqf(device, _irqf); \
#define MCFG_DISCRETE_INTF(_intf) \
discrete_device_config::static_set_intf(device, (const discrete_sound_block *)&(_intf##_discrete_interface)); \
#endif
#define MCFG_SOUND_CONFIG_DISCRETE(name) MCFG_SOUND_CONFIG(name##_discrete_interface)
@ -4497,13 +4353,15 @@ public:
virtual device_t *alloc_device(running_machine &machine) const;
// inline configuration helpers
//static void static_set_type(device_config *device, int type);
//static void static_set_irqf(device_config *device, void (*irqf)(device_t *device, int state));
static void static_set_intf(device_config *device, const discrete_sound_block *intf);
protected:
const discrete_sound_block *m_intf;
// inline data
};
class discrete_output_interface;
typedef linked_list_t<discrete_output_interface *> node_output_list_t;
// ======================> discrete_device
@ -4512,6 +4370,7 @@ class discrete_device : public device_t, public device_sound_interface
{
friend class discrete_device_config;
friend class discrete_base_node;
friend class discrete_dss_input_stream_node;
// construction/destruction
discrete_device(running_machine &_machine, const discrete_device_config &config);
@ -4527,16 +4386,14 @@ public:
discrete_base_node *discrete_find_node(int node);
/* FIXME: this is used by csv and wav logs - going forward, identifiers should be explicitly passed */
int same_module_index(discrete_base_node &node);
inline void step_nodes_in_list(node_list_t &list);
inline int profiling(void) { return m_profiling; }
void update(void) { stream_update(m_stream); }
/* FIXME: theses should be protected */
/* the output stream */
sound_stream *discrete_stream;
/* tasks */
task_list_t task_list; /* discrete_task_context * */
task_list_t task_list; /* discrete_task_context * */
/* the input streams */
node_list_t m_input_list;
input_stream_node_list_t m_input_stream_list;
protected:
@ -4554,17 +4411,21 @@ protected:
/* --------------------------------- */
void discrete_build_list(const discrete_sound_block *intf, linked_list_entry ***current);
void discrete_sanity_check(void);
void display_profiling(void);
void init_nodes(const linked_list_entry *block_list);
/* the output stream */
sound_stream *m_stream;
/* emulation info */
int m_sample_rate;
double m_sample_time;
double m_neg_sample_time;
private:
void discrete_build_list(const discrete_sound_block *intf, linked_list_entry ***current);
void discrete_sanity_check(void);
void display_profiling(void);
void init_nodes(const linked_list_entry *block_list);
/* internal node tracking */
discrete_base_node **m_indexed_node;
@ -4575,7 +4436,7 @@ private:
linked_list_entry *m_block_list; /* discrete_sound_block * */
/* output node tracking */
node_list_t m_output_list;
node_output_list_t m_output_list;
/* debugging statistics */
FILE *m_disclogfile;
@ -4584,36 +4445,36 @@ private:
osd_work_queue *m_queue;
/* profiling */
int m_profiling;
UINT64 m_total_samples;
UINT64 m_total_stream_updates;
};
// device type definition
extern const device_type DISCRETE;
/*************************************
*
* Internal structure of a node
* Node class
*
*************************************/
class discrete_base_node
{
friend class discrete_device;
template <class C> friend class discrete_node_factory;
friend class discrete_task;
public:
discrete_base_node(discrete_device * pdev, const discrete_sound_block *block);
virtual ~discrete_base_node(void);
virtual void step(void) = 0;
virtual void reset(void) { }
virtual void start(void);
virtual void stop(void) { }
virtual bool is_stepping(void) { return true; };
inline bool interface(discrete_step_interface *&intf) { intf = m_step_intf; return (intf != NULL); }
inline bool interface(discrete_input_interface *&intf) { intf = m_input_intf; return (intf != NULL); }
inline bool interface(discrete_output_interface *&intf) { intf = m_output_intf; return (intf != NULL); }
virtual int max_output(void) { return 1; };
@ -4632,10 +4493,8 @@ public:
/* The node's last output value */
double output[DISCRETE_MAX_OUTPUTS];
/* Contextual information specific to this node type */
void * context;
const double * input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */
/* 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 */
@ -4649,17 +4508,31 @@ public:
discrete_device *device; /* Points to the parent */
osd_ticks_t run_time;
protected:
/* fixme: temporary until contexts become private data */
int m_context_size;
discrete_base_node();
virtual ~discrete_base_node();
/* finish node setup after allocation is complete */
void init(discrete_device * pdev, const discrete_sound_block *block);
private:
const discrete_sound_block *m_block; /* Points to the node's setup block. */
int m_active_inputs; /* Number of active inputs on this node type */
/* Custom function specific initialisation data */
const void * m_custom;
int m_input_is_node;
discrete_step_interface *m_step_intf;
discrete_input_interface *m_input_intf;
discrete_output_interface *m_output_intf;
};
class discrete_node_base_factory
{
public:
virtual discrete_base_node *Create(discrete_device * pdev, const discrete_sound_block *block) = 0;
virtual ~discrete_node_base_factory() {}
};
template <class C>
@ -4671,7 +4544,10 @@ class discrete_node_factory : public discrete_node_base_factory
template <class C>
discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, const discrete_sound_block *block)
{
return auto_alloc_clear(pdev->machine, C(pdev, block));
discrete_base_node *r = auto_alloc_clear(pdev->machine, C);
r->init(pdev, block);
return r;
}
/*************************************
@ -4692,7 +4568,7 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co
#define DISCRETE_SOUND_EXTERN(name) extern const discrete_sound_block name##_discrete_interface[]
#define DISCRETE_SOUND_START(name) const discrete_sound_block name##_discrete_interface[] = {
#define DSC_SND_ENTRY(_nod, _class, _dss, _num, _iact, _iinit, _custom, _name) { _nod, new discrete_node_factory< _class ## _node >, _dss, _num, _iact, _iinit, _custom, _name, # _dss }
#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" ) };
@ -4701,143 +4577,143 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co
/* 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_ADJUSTMENT , 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_ADJUSTMENT , 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_CONSTANT , 1, DSE( NODE_NC ), DSE( CONST ) ,NULL ,"DISCRETE_CONSTANT" ),
#define DISCRETE_INPUT_DATA(NODE) DSC_SND_ENTRY( NODE, dss_input_data , DSS_INPUT_DATA , 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_INPUT_DATA , 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_INPUT_LOGIC , 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_INPUT_LOGIC , 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_INPUT_NOT , 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_INPUT_NOT , 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_INPUT_PULSE , 3, DSE( NODE_NC,NODE_NC,NODE_NC ), DSE( 1,0,INIT ), NULL, "DISCRETE_INPUT_PULSE" ),
#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_INPUT_STREAM, 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_INPUT_STREAM, 3, DSE( NUM,NODE_NC,NODE_NC ), DSE( NUM,GAIN,OFFSET ), NULL, "DISCRETE_INPUTX_STREAM" ),
#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_stream, DSS_INPUT_BUFFER, 3, DSE( NUM,NODE_NC,NODE_NC ), DSE( NUM,1,0 ), NULL, "DISCRETE_INPUT_BUFFER" ),
#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_COUNTER , 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_COUNTER , 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_LFSR_NOISE , 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_NOISE , 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_NOTE , 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_SAWTOOTHWAVE, 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_SINEWAVE , 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_SQUAREWAVE , 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_SQUAREWFIX , 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_SQUAREWAVE2 , 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_TRIANGLEWAVE, 5, DSE( ENAB,FREQ,AMPL,BIAS,NODE_NC ), DSE( ENAB,FREQ,AMPL,BIAS,PHASE ), NULL, "DISCRETE_TRIANGLEWAVE" ),
#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_INVERTER_OSC, 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_OP_AMP_OSC , 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_OP_AMP_OSC , 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_OP_AMP_OSC , 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_SCHMITT_OSC , 3, DSE( ENAB,INP0,AMPL ), DSE( ENAB,INP0,AMPL ), TABLE, "DISCRETE_SCHMITT_OSCILLATOR" ),
#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_ADSR , 3, DSE( ENAB,TRIGGER,GAIN ), DSE( ENAB,TRIGGER,GAIN ), ADSRTB, "DISCRETE_ADSR_ENV" ),
#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 , DST_ADDER , 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 , DST_ADDER , 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 , DST_ADDER , 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 , DST_CLAMP , 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 , DST_DIVIDE , 3, DSE( ENAB,INP0,INP1 ), DSE( ENAB,INP0,INP1 ), NULL, "DISCRETE_DIVIDE" ),
#define DISCRETE_GAIN(NODE,INP0,GAIN) DSC_SND_ENTRY( NODE, dst_gain , DST_GAIN , 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 , DST_GAIN , 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 , DST_LOGIC_INV , 1, DSE( INP0 ), DSE( INP0 ), NULL, "DISCRETE_LOGIC_INVERT" ),
#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 , DST_BITS_DECODE , 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 , DST_BITS_DECODE , 4, DSE( INP,NODE_NC,NODE_NC,NODE_NC ), DSE( INP,BIT_FROM,BIT_TO,VOUT ), NULL, "DISCRETE_BITS_DECODE" ),
#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 , DST_LOGIC_AND , 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 , DST_LOGIC_AND , 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 , DST_LOGIC_AND , 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 , DST_LOGIC_NAND , 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 , DST_LOGIC_NAND , 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 , DST_LOGIC_NAND , 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 , DST_LOGIC_OR , 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 , DST_LOGIC_OR , 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 , DST_LOGIC_OR , 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 , DST_LOGIC_NOR , 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 , DST_LOGIC_NOR , 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 , DST_LOGIC_NOR , 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 , DST_LOGIC_XOR , 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 , DST_LOGIC_NXOR , 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 , DST_LOGIC_DFF , 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 , DST_LOGIC_JKFF , 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 , DST_LOGIC_SHIFT , 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, DST_LOOKUP_TABLE, 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 , DST_MULTIPLEX , 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 , DST_MULTIPLEX , 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, DST_MULTIPLEX, 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 , DST_GAIN , 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 , DST_GAIN , 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 , DST_ONESHOT , 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 , DST_ONESHOT , 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 , DST_GAIN , 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 , DST_RAMP , 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 , DST_SAMPHOLD , 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 , DST_SWITCH , 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 , DST_ASWITCH , 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 , DST_TRANSFORM , 2, DSE( INP0,INP1 ), DSE( INP0,INP1 ), FUNCT, "DISCRETE_TRANSFORM2" ),
#define DISCRETE_TRANSFORM3(NODE,INP0,INP1,INP2,FUNCT) DSC_SND_ENTRY( NODE, dst_transform , DST_TRANSFORM , 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 , DST_TRANSFORM , 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 , DST_TRANSFORM , 5, DSE( INP0,INP1,INP2,INP3,INP4 ), DSE( INP0,INP1,INP2,INP3,INP4 ), FUNCT, "DISCRETE_TRANSFORM5" ),
#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 , DST_COMP_ADDER , 1, DSE( DATA ), DSE( DATA ), TABLE, "DISCRETE_COMP_ADDER" ),
#define DISCRETE_DAC_R1(NODE,DATA,VDATA,LADDER) DSC_SND_ENTRY( NODE, dst_dac_r1 , DST_DAC_R1 , 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 , DST_DIODE_MIX , 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 , DST_DIODE_MIX , 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 , DST_DIODE_MIX , 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 , DST_INTEGRATE , 2, DSE( TRG0,TRG1 ), DSE( TRG0,TRG1 ), INFO, "DISCRETE_INTEGRATE" ),
#define DISCRETE_MIXER2(NODE,ENAB,IN0,IN1,INFO) DSC_SND_ENTRY( NODE, dst_mixer , DST_MIXER , 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 , DST_MIXER , 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 , DST_MIXER , 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 , DST_MIXER , 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 , DST_MIXER , 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 , DST_MIXER , 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 , DST_MIXER , 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 , DST_OP_AMP , 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 , DST_OP_AMP_1SHT , 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 , DST_TVCA_OP_AMP , 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 , DST_VCA , 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, DST_XTIME_BUFFER, 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, DST_XTIME_BUFFER, 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, DST_XTIME_AND, 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, DST_XTIME_AND, 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, DST_XTIME_OR, 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, DST_XTIME_OR, 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, DST_XTIME_XOR, 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, DST_XTIME_XNOR, 5, DSE( IN0,IN1,LOW,HIGH,NODE_NC ), DSE( IN0,IN1,LOW,HIGH,1 ), NULL, "DISCRETE_XTIME_XNOR" ),
#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 , DST_FILTER1 , 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 , DST_FILTER2 , 5, DSE( ENAB,INP0,NODE_NC,NODE_NC,NODE_NC ), DSE( ENAB,INP0,FREQ,DAMP,TYPE ), NULL, "DISCRETE_FILTER2" ),
#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 , DST_SALLEN_KEY , 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 , DST_CRFILTER , 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 , DST_CRFILTER , 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 , DST_OP_AMP_FILT , 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, DST_RC_CIRCUIT_1, 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 , DST_RCDISC , 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 , DST_RCDISC2 , 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 , DST_RCDISC3 , 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 , DST_RCDISC4 , 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 , DST_RCDISC5 , 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, DST_RCDISC_MOD, 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 , DST_RCFILTER , 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 , DST_RCFILTER , 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, DST_RCFILTER_SW, 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 , DST_RCINTEGRATE , 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" ),
#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 , DST_RCDISCN , 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 , DST_RCDISC2N , 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 , DST_RCFILTERN , 4, DSE( ENAB,INP0,NODE_NC,NODE_NC ), DSE( ENAB,INP0,RVAL,CVAL ), NULL, "DISCRETE_RCFILTERN" ),
#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 */
@ -4852,36 +4728,36 @@ discrete_base_node * discrete_node_factory<C>::Create(discrete_device * pdev, co
#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 , DSD_555_ASTBL , 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 , DSD_555_ASTBL , 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 , DSD_555_MSTBL , 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 , DSD_555_CC , 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 , DSD_555_VCO1 , 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 , DSD_555_VCO1 , 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 , DSD_566 , 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 , DSD_LS624 , 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" ),
#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_wavelog , DSO_WAVELOG , 2, DSE( NODE1,NODE_NC ), DSE( NODE1,GAIN1 ), NULL, "DISCRETE_WAVLOG1" ),
#define DISCRETE_WAVLOG2(NODE1,GAIN1,NODE2,GAIN2) DSC_SND_ENTRY( NODE_SPECIAL, dso_wavelog , DSO_WAVELOG , 4, DSE( NODE1,NODE_NC,NODE2,NODE_NC ), DSE( NODE1,GAIN1,NODE2,GAIN2 ), NULL, "DISCRETE_WAVLOG2" ),
#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_wavelog , DSO_WAVELOG , 2, DSE( NODE1,NODE_NC ), DSE( NODE1,GAIN1 ), NULL, "DISCRETE_WAVLOG1" ),
#define DISCRETE_WAVLOG2(NODE1,GAIN1,NODE2,GAIN2) DSC_SND_ENTRY( NODE_SPECIAL, dso_wavelog , DSO_WAVELOG , 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" ),
#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, dso_task_start,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, dso_task_end ,DSO_TASK_END , 1, DSE( 0 ), DSE( 0 ), NULL, "DISCRETE_TASK_END" ),
#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 */

View File

@ -153,7 +153,7 @@ WRITE8_HANDLER( lrescue_sh_port_2_w )
speaker_level_w(state->speaker, (data & 0x08) ? 1 : 0); /* Bitstream tunes - endlevel and bonus1 */
if (rising_bits & 0x10) sample_start(state->samples, 3, 6, 0); /* Shooting Star and Rescue Ship sounds */
if (~data & 0x10 && state->port_2_last_extra & 0x10) sample_stop (state->samples, 3); /* This makes the rescue ship sound beep on and off */
if ((~data & 0x10) && (state->port_2_last_extra & 0x10)) sample_stop (state->samples, 3); /* This makes the rescue ship sound beep on and off */
state->c8080bw_flip_screen = data & 0x20;

View File

@ -227,46 +227,39 @@ static const discrete_mixer_desc bzone_final_mixer_desc =
#define BZONE_CUSTOM_FILTER__C DISCRETE_INPUT(7)
#define BZONE_CUSTOM_FILTER__VP DISCRETE_INPUT(8)
struct bzone_custom_filter_context
{
double v_in1_gain;
double v_p;
double exponent;
double gain[2];
};
#define CD4066_R_ON 270
DISCRETE_CLASS_STEP_RESET(bzone_custom_filter, sizeof(struct bzone_custom_filter_context), 1);
DISCRETE_CLASS_STEP_RESETA(bzone_custom_filter, 1,
double m_v_in1_gain;
double m_v_p;
double m_exponent;
double m_gain[2];
);
DISCRETE_STEP(bzone_custom_filter)
{
DISCRETE_DECLARE_CONTEXT(bzone_custom_filter)
int in0 = (BZONE_CUSTOM_FILTER__IN0 == 0) ? 0 : 1;
double v;
if (BZONE_CUSTOM_FILTER__IN1 > 0)
v = 0;
v = BZONE_CUSTOM_FILTER__IN1 * context->v_in1_gain * context->gain[in0];
if (v > context->v_p) v = context->v_p;
v = BZONE_CUSTOM_FILTER__IN1 * m_v_in1_gain * m_gain[in0];
if (v > m_v_p) v = m_v_p;
if (v < 0) v = 0;
this->output[0] += (v - this->output[0]) * context->exponent;
this->output[0] += (v - this->output[0]) * m_exponent;
}
DISCRETE_RESET(bzone_custom_filter)
{
DISCRETE_DECLARE_CONTEXT(bzone_custom_filter)
context->gain[0] = BZONE_CUSTOM_FILTER__R1 + BZONE_CUSTOM_FILTER__R2;
context->gain[0] = BZONE_CUSTOM_FILTER__R5 / context->gain[0] + 1;
context->gain[1] = RES_2_PARALLEL(CD4066_R_ON, BZONE_CUSTOM_FILTER__R1) + BZONE_CUSTOM_FILTER__R2;
context->gain[1] = BZONE_CUSTOM_FILTER__R5 / context->gain[1] + 1;
context->v_in1_gain = RES_VOLTAGE_DIVIDER(BZONE_CUSTOM_FILTER__R3, BZONE_CUSTOM_FILTER__R4);
context->v_p = BZONE_CUSTOM_FILTER__VP - OP_AMP_VP_RAIL_OFFSET;
context->exponent = RC_CHARGE_EXP_CLASS(BZONE_CUSTOM_FILTER__R5 * BZONE_CUSTOM_FILTER__C);;
m_gain[0] = BZONE_CUSTOM_FILTER__R1 + BZONE_CUSTOM_FILTER__R2;
m_gain[0] = BZONE_CUSTOM_FILTER__R5 / m_gain[0] + 1;
m_gain[1] = RES_2_PARALLEL(CD4066_R_ON, BZONE_CUSTOM_FILTER__R1) + BZONE_CUSTOM_FILTER__R2;
m_gain[1] = BZONE_CUSTOM_FILTER__R5 / m_gain[1] + 1;
m_v_in1_gain = RES_VOLTAGE_DIVIDER(BZONE_CUSTOM_FILTER__R3, BZONE_CUSTOM_FILTER__R4);
m_v_p = BZONE_CUSTOM_FILTER__VP - OP_AMP_VP_RAIL_OFFSET;
m_exponent = RC_CHARGE_EXP_CLASS(BZONE_CUSTOM_FILTER__R5 * BZONE_CUSTOM_FILTER__C);;
this->output[0] = 0;
}

View File

@ -265,30 +265,25 @@ static const discrete_555_cc_desc copsnrob_motor01_555cc =
************************************************/
#define COPSNROB_CUSTOM_NOISE__FREQ DISCRETE_INPUT(0)
struct copsnrob_custom_noise_context
{
int flip_flop;
int noise1_had_xtime;
int noise2_had_xtime;
UINT8 high_byte;
UINT8 low_byte;
double t_used;
double t1;
};
DISCRETE_CLASS_STEP_RESET(copsnrob_custom_noise, sizeof(struct copsnrob_custom_noise_context), 2);
DISCRETE_CLASS_STEP_RESETA(copsnrob_custom_noise, 2,
int m_flip_flop;
int m_noise1_had_xtime;
int m_noise2_had_xtime;
UINT8 m_high_byte;
UINT8 m_low_byte;
double m_t_used;
double m_t1;
);
#define COPSNROB_CUSTOM_NOISE_HIGH 4.2
DISCRETE_STEP(copsnrob_custom_noise)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_custom_noise)
double t_used = context->t_used;
double t1 = context->t1;
double t_used = m_t_used;
double t1 = m_t1;
double x_time = 0;
UINT8 low_byte = context->low_byte;
UINT8 high_byte = context->high_byte;
UINT8 low_byte = m_low_byte;
UINT8 high_byte = m_high_byte;
UINT8 xnor_out; /* IC F2, pin 2 */
int last_noise1_bit = (low_byte >> 4) & 0x01;
int last_noise2_bit = (low_byte >> 5) & 0x01;
@ -302,9 +297,9 @@ DISCRETE_STEP(copsnrob_custom_noise)
{
/* calculate the overshoot time */
t_used -= t1;
context->flip_flop ^= 1;
m_flip_flop ^= 1;
/* clocks on low to high */
if (context->flip_flop)
if (m_flip_flop)
{
int new_noise_bit;
@ -314,8 +309,8 @@ DISCRETE_STEP(copsnrob_custom_noise)
high_byte = (high_byte << 1) | xnor_out;
if (high_byte == 0xff) /* IC H1, pin 8 */
high_byte = 0;
context->low_byte = low_byte;
context->high_byte = high_byte;
m_low_byte = low_byte;
m_high_byte = high_byte;
/* Convert last switch time to a ratio */
x_time = t_used / this->sample_time();
@ -324,45 +319,43 @@ DISCRETE_STEP(copsnrob_custom_noise)
if (last_noise1_bit != new_noise_bit)
{
this->output[0] = COPSNROB_CUSTOM_NOISE_HIGH * (new_noise_bit ? x_time : (1.0 - x_time));
context->noise1_had_xtime = 1;
m_noise1_had_xtime = 1;
}
new_noise_bit = (low_byte >> 5) & 0x01;
if (last_noise2_bit != new_noise_bit)
{
this->output[1] = COPSNROB_CUSTOM_NOISE_HIGH * (new_noise_bit ? x_time : (1.0 - x_time));
context->noise2_had_xtime = 1;
m_noise2_had_xtime = 1;
}
}
}
else
{
/* see if we need to move from x_time state to full state */
if (context->noise1_had_xtime)
if (m_noise1_had_xtime)
{
this->output[0] = COPSNROB_CUSTOM_NOISE_HIGH * last_noise1_bit;
context->noise1_had_xtime = 0;
m_noise1_had_xtime = 0;
}
if (context->noise2_had_xtime)
if (m_noise2_had_xtime)
{
this->output[1] = COPSNROB_CUSTOM_NOISE_HIGH * last_noise2_bit;
context->noise2_had_xtime = 0;
m_noise2_had_xtime = 0;
}
}
context->t_used = t_used;
m_t_used = t_used;
}
DISCRETE_RESET(copsnrob_custom_noise)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_custom_noise)
context->t1 = 0.5 / COPSNROB_CUSTOM_NOISE__FREQ ;
context->flip_flop = 0;
context->low_byte = 0;
context->high_byte = 0;
context->noise1_had_xtime = 0;
context->noise2_had_xtime = 0;
context->t_used = 0;
m_t1 = 0.5 / COPSNROB_CUSTOM_NOISE__FREQ ;
m_flip_flop = 0;
m_low_byte = 0;
m_high_byte = 0;
m_noise1_had_xtime = 0;
m_noise2_had_xtime = 0;
m_t_used = 0;
}
/************************************************
@ -378,26 +371,21 @@ DISCRETE_RESET(copsnrob_custom_noise)
#define COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__R DISCRETE_INPUT(1)
#define COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__C DISCRETE_INPUT(2)
struct copsnrob_zings_555_monostable_context
{
double rc;
double exponent;
double v_cap;
int flip_flop;
};
DISCRETE_CLASS_STEP_RESET(copsnrob_zings_555_monostable, sizeof(struct copsnrob_zings_555_monostable_context), 1);
DISCRETE_CLASS_STEP_RESETA(copsnrob_zings_555_monostable, 1,
double m_rc;
double m_exponent;
double m_v_cap;
int m_flip_flop;
);
DISCRETE_STEP(copsnrob_zings_555_monostable)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_zings_555_monostable)
const double v_threshold = 5.0 * 2 / 3;
const double v_out_high = 5.0 - 0.5; /* light load */
int ff_set = COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__TRIG < (5.0 / 3) ? 1 : 0;
int flip_flop = context->flip_flop;
double v_cap = context->v_cap;
int flip_flop = m_flip_flop;
double v_cap = m_v_cap;
double x_time = 0;
/* From testing a real IC */
@ -409,7 +397,7 @@ DISCRETE_STEP(copsnrob_zings_555_monostable)
if (ff_set)
{
flip_flop = 1;
context->flip_flop = flip_flop;
m_flip_flop = flip_flop;
}
if (flip_flop)
@ -417,14 +405,14 @@ DISCRETE_STEP(copsnrob_zings_555_monostable)
double v_diff = v_out_high - v_cap;
/* charge */
v_cap += v_diff * context->exponent;
v_cap += v_diff * m_exponent;
/* no state change if trigger is low */
if (!ff_set && (v_cap > v_threshold))
{
double rc = context->rc;
double rc = m_rc;
flip_flop = 0;
context->flip_flop = flip_flop;
m_flip_flop = flip_flop;
/* calculate overshoot */
x_time = rc * log(1.0 / (1.0 - ((v_cap - v_threshold) / v_diff)));
/* discharge the overshoot */
@ -439,12 +427,12 @@ DISCRETE_STEP(copsnrob_zings_555_monostable)
if (v_cap == 0)
return;
/* discharge */
v_cap -= v_cap * context->exponent;
v_cap -= v_cap * m_exponent;
/* Optimization - close enough to 0 to be 0 */
if (v_cap < 0.000001)
v_cap = 0;
}
context->v_cap = v_cap;
m_v_cap = v_cap;
if (x_time > 0)
this->output[0] = v_out_high * x_time;
@ -456,12 +444,10 @@ DISCRETE_STEP(copsnrob_zings_555_monostable)
DISCRETE_RESET(copsnrob_zings_555_monostable)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_zings_555_monostable)
context->rc = COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__R * COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__C;
context->exponent = RC_CHARGE_EXP_CLASS(context->rc);
context->v_cap = 0;
context->flip_flop = 0;
m_rc = COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__R * COPSNROB_CUSTOM_ZINGS_555_MONOSTABLE__C;
m_exponent = RC_CHARGE_EXP_CLASS(m_rc);
m_v_cap = 0;
m_flip_flop = 0;
this->output[0] = 0;
}
@ -482,37 +468,32 @@ DISCRETE_RESET(copsnrob_zings_555_monostable)
#define COPSNROB_CUSTOM_ZINGS_555_ASTABLE__HIGH 4.5
struct copsnrob_zings_555_astable_context
{
double r2c2;
double r_total_cv;
double exponent1;
double exponent2;
double v_cap1;
double v_cap2;
int flip_flop;
};
DISCRETE_CLASS_STEP_RESET(copsnrob_zings_555_astable, sizeof(struct copsnrob_zings_555_astable_context), 1);
DISCRETE_CLASS_STEP_RESETA(copsnrob_zings_555_astable, 1,
double m_r2c2;
double m_r_total_cv;
double m_exponent1;
double m_exponent2;
double m_v_cap1;
double m_v_cap2;
int m_flip_flop;
);
DISCRETE_STEP(copsnrob_zings_555_astable)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_zings_555_astable)
double v_trigger, v_threshold;
double v1 = COPSNROB_CUSTOM_ZINGS_555_ASTABLE__RESET;
double v_cap1 = context->v_cap1;
double v_cap1 = m_v_cap1;
double v_cap2 = this->output[0];
double dt = 0;
int reset_active = (v1 < 0.7) ? 1 : 0;
int flip_flop = context->flip_flop;
int flip_flop = m_flip_flop;
/* calculate voltage at CV pin */
/* start by adding currents */
double v_cv = 5.0 / RES_K(5);
v_cv += v1 / COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R1;
/* convert to voltage */
v_cv *= context->r_total_cv;
v_cv *= m_r_total_cv;
/* The reset voltage also charges the CV cap */
double v_diff1 = v_cv - v_cap1;
@ -520,19 +501,19 @@ DISCRETE_STEP(copsnrob_zings_555_astable)
if (fabs(v_diff1) < 0.000001)
v_cap1 = v_cv;
else
v_cap1 += v_diff1 * context->exponent1;
context->v_cap1 = v_cap1;
v_cap1 += v_diff1 * m_exponent1;
m_v_cap1 = v_cap1;
if (reset_active)
{
if (flip_flop)
context->flip_flop = 0;
m_flip_flop = 0;
/* we still need to discharge C2 */
/* Optimization - only discharge if needed */
if (v_cap2 != 0)
{
/* discharge */
v_cap2 -= v_cap2 * context->exponent2;
v_cap2 -= v_cap2 * m_exponent2;
/* Optimization - close enough to 0 to be 0 */
if (v_cap2 < 0.000001)
this->output[0] = 0;
@ -553,12 +534,12 @@ DISCRETE_STEP(copsnrob_zings_555_astable)
{
/* charge */
double v_diff2 = COPSNROB_CUSTOM_ZINGS_555_ASTABLE__HIGH - v_cap2;
v_cap2 += v_diff2 * context->exponent2;
v_cap2 += v_diff2 * m_exponent2;
if (v_cap2 > v_threshold)
{
double r2c2 = context->r2c2;
double r2c2 = m_r2c2;
context->flip_flop = 0;
m_flip_flop = 0;
/* calculate overshoot */
dt = r2c2 * log(1.0 / (1.0 - ((v_cap2 - v_threshold) / v_diff2)));
/* discharge the overshoot */
@ -570,12 +551,12 @@ DISCRETE_STEP(copsnrob_zings_555_astable)
{
/* discharge */
double v_diff2 = v_cap2;
v_cap2 -= v_diff2 * context->exponent2;
v_cap2 -= v_diff2 * m_exponent2;
if (v_cap2 < v_trigger)
{
double r2c2 = context->r2c2;
double r2c2 = m_r2c2;
context->flip_flop = 1;
m_flip_flop = 1;
/* calculate overshoot */
dt = r2c2 * log(1.0 / (1.0 - ((v_trigger - v_cap2) / v_diff2)));
/* charge the overshoot */
@ -591,14 +572,12 @@ DISCRETE_STEP(copsnrob_zings_555_astable)
DISCRETE_RESET(copsnrob_zings_555_astable)
{
DISCRETE_DECLARE_CONTEXT(copsnrob_zings_555_astable)
context->r_total_cv = RES_3_PARALLEL(COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R1, RES_K(10), RES_K(5));
context->r2c2 = COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R2 * COPSNROB_CUSTOM_ZINGS_555_ASTABLE__C2;
context->exponent1 = RC_CHARGE_EXP_CLASS(COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R1 * COPSNROB_CUSTOM_ZINGS_555_ASTABLE__C1);
context->exponent2 = RC_CHARGE_EXP_CLASS(context->r2c2);
context->v_cap1 = 0;
context->flip_flop = 0;
m_r_total_cv = RES_3_PARALLEL(COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R1, RES_K(10), RES_K(5));
m_r2c2 = COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R2 * COPSNROB_CUSTOM_ZINGS_555_ASTABLE__C2;
m_exponent1 = RC_CHARGE_EXP_CLASS(COPSNROB_CUSTOM_ZINGS_555_ASTABLE__R1 * COPSNROB_CUSTOM_ZINGS_555_ASTABLE__C1);
m_exponent2 = RC_CHARGE_EXP_CLASS(m_r2c2);
m_v_cap1 = 0;
m_flip_flop = 0;
this->output[0] = 0; /* charge on C2 */
}

View File

@ -294,52 +294,45 @@ static const discrete_op_amp_filt_info dkong_sallen_key_info =
#define DKONG_CUSTOM_C DISCRETE_INPUT(6)
#define DKONG_CUSTOM_V DISCRETE_INPUT(7)
struct dkong_custom_mixer_context
{
double i_in1[2];
double r_in[2];
double r_total[2];
double exp[2];
};
DISCRETE_CLASS_STEP_RESET(dkong_custom_mixer, sizeof(struct dkong_custom_mixer_context), 1);
DISCRETE_CLASS_STEP_RESETA(dkong_custom_mixer, 1,
double m_i_in1[2];
double m_r_in[2];
double m_r_total[2];
double m_exp[2];
);
DISCRETE_STEP( dkong_custom_mixer )
{
DISCRETE_DECLARE_CONTEXT(dkong_custom_mixer)
int in_1 = (int)DKONG_CUSTOM_IN1;
/* start of with 555 current */
double i_total = DKONG_CUSTOM_V / RES_K(5);
/* add in current from In1 */
i_total += context->i_in1[in_1];
i_total += m_i_in1[in_1];
/* add in current from In2 */
i_total += DKONG_CUSTOM_IN2 / DKONG_CUSTOM_R3;
/* charge cap */
/* node->output is cap voltage, (i_total * context->r_total[in_1]) is current charge voltage */
this->output[0] += (i_total * context->r_total[in_1] - this->output[0]) * context->exp[in_1];
/* node->output is cap voltage, (i_total * m_r_total[in_1]) is current charge voltage */
this->output[0] += (i_total * m_r_total[in_1] - this->output[0]) * m_exp[in_1];
}
#define NE555_CV_R RES_2_PARALLEL(RES_K(5), RES_K(10))
DISCRETE_RESET( dkong_custom_mixer )
{
DISCRETE_DECLARE_CONTEXT(dkong_custom_mixer)
/* everything is based on the input to the O.C. inverter */
/* precalculate current from In1 */
context->i_in1[0] = DKONG_CUSTOM_V / (DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2);
context->i_in1[1] = 0;
m_i_in1[0] = DKONG_CUSTOM_V / (DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2);
m_i_in1[1] = 0;
/* precalculate total resistance for input circuit */
context->r_in[0] = RES_2_PARALLEL((DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2), DKONG_CUSTOM_R3);
context->r_in[1] = RES_2_PARALLEL(DKONG_CUSTOM_R2, DKONG_CUSTOM_R3);
m_r_in[0] = RES_2_PARALLEL((DKONG_CUSTOM_R1 + DKONG_CUSTOM_R2), DKONG_CUSTOM_R3);
m_r_in[1] = RES_2_PARALLEL(DKONG_CUSTOM_R2, DKONG_CUSTOM_R3);
/* precalculate total charging resistance */
context->r_total[0] = RES_2_PARALLEL(context->r_in[0] + DKONG_CUSTOM_R4, NE555_CV_R);
context->r_total[1] = RES_2_PARALLEL((context->r_in[1] + DKONG_CUSTOM_R4), NE555_CV_R);
m_r_total[0] = RES_2_PARALLEL(m_r_in[0] + DKONG_CUSTOM_R4, NE555_CV_R);
m_r_total[1] = RES_2_PARALLEL((m_r_in[1] + DKONG_CUSTOM_R4), NE555_CV_R);
/* precalculate charging exponents */
context->exp[0] = RC_CHARGE_EXP_CLASS(context->r_total[0] * DKONG_CUSTOM_C);
context->exp[1] = RC_CHARGE_EXP_CLASS(context->r_total[1] * DKONG_CUSTOM_C);
m_exp[0] = RC_CHARGE_EXP_CLASS(m_r_total[0] * DKONG_CUSTOM_C);
m_exp[1] = RC_CHARGE_EXP_CLASS(m_r_total[1] * DKONG_CUSTOM_C);
this->output[0] = 0;
}
@ -394,8 +387,8 @@ static DISCRETE_SOUND_START(dkong2b)
DISCRETE_CUSTOM8(NODE_28, dkong_custom_mixer, DS_SOUND1_INV, NODE_25,
DK_R32, DK_R50, DK_R51, DK_R49, DK_C24, DK_SUP_V, NULL)
#else
DISCRETE_LOGIC_INVERT(DS_SOUND1,1,DS_SOUND1_INV)
DISCRETE_MULTIPLY(NODE_24,1,DS_SOUND1,DK_SUP_V)
DISCRETE_LOGIC_INVERT(DS_SOUND1,DS_SOUND1_INV)
DISCRETE_MULTIPLY(NODE_24,DS_SOUND1,DK_SUP_V)
DISCRETE_TRANSFORM3(NODE_26,DS_SOUND1,DK_R32,DK_R49+DK_R50,"01*2+")
DISCRETE_MIXER4(NODE_28, 1, NODE_24, NODE_25, DK_SUP_V, 0,&dkong_rc_jump_desc)
#endif
@ -426,8 +419,8 @@ static DISCRETE_SOUND_START(dkong2b)
DISCRETE_CUSTOM8(NODE_54, dkong_custom_mixer, DS_SOUND0_INV, NODE_51,
DK_R36, DK_R45, DK_R46, DK_R44, DK_C29, DK_SUP_V, NULL)
#else
DISCRETE_LOGIC_INVERT(DS_SOUND0,1,DS_SOUND0_INV)
DISCRETE_MULTIPLY(NODE_50,1,DS_SOUND0,DK_SUP_V)
DISCRETE_LOGIC_INVERT(DS_SOUND0,DS_SOUND0_INV)
DISCRETE_MULTIPLY(NODE_50,DS_SOUND0,DK_SUP_V)
DISCRETE_TRANSFORM3(NODE_52,DS_SOUND0,DK_R46,R_SERIES(DK_R44,DK_R45),"01*2+")
DISCRETE_MIXER4(NODE_54, 1, NODE_50, NODE_51, DK_SUP_V, 0,&dkong_rc_walk_desc)
#endif
@ -1399,15 +1392,13 @@ MACHINE_CONFIG_FRAGMENT( dkong2b_audio )
MCFG_CPU_IO_MAP(dkong_sound_io_map)
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("discrete", DISCRETE, 0)
MCFG_SOUND_CONFIG_DISCRETE(dkong2b)
MCFG_DISCRETE_ADD("discrete", 0, dkong2b)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END
MACHINE_CONFIG_DERIVED( radarscp_audio, dkong2b_audio )
MCFG_SOUND_MODIFY("discrete")
MCFG_SOUND_CONFIG_DISCRETE(radarscp)
MCFG_DISCRETE_REPLACE("discrete", 0, radarscp)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.7)
MACHINE_CONFIG_END
@ -1463,8 +1454,7 @@ MACHINE_CONFIG_FRAGMENT( dkongjr_audio )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("discrete", DISCRETE, 0)
MCFG_SOUND_CONFIG_DISCRETE(dkongjr)
MCFG_DISCRETE_ADD("discrete", 0, dkongjr)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END