From 156a1efd1c8108957b0680920336f11d71056579 Mon Sep 17 00:00:00 2001 From: Couriersud Date: Sat, 15 Jan 2011 13:49:27 +0000 Subject: [PATCH] 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. --- .gitattributes | 4 + src/emu/sound/disc_cls.h | 919 +++++++++----------------------------- src/emu/sound/disc_dev.c | 564 ++++++++++++----------- src/emu/sound/disc_dev.h | 127 ++++++ src/emu/sound/disc_flt.c | 633 ++++++++++++-------------- src/emu/sound/disc_flt.h | 182 ++++++++ src/emu/sound/disc_inp.c | 240 ++++++---- src/emu/sound/disc_mth.c | 540 ++++++++++------------ src/emu/sound/disc_mth.h | 195 ++++++++ src/emu/sound/disc_sys.c | 203 +-------- src/emu/sound/disc_wav.c | 622 ++++++++++++-------------- src/emu/sound/disc_wav.h | 169 +++++++ src/emu/sound/discrete.c | 706 +++++++++++++++++------------ src/emu/sound/discrete.h | 688 ++++++++++++---------------- src/mame/audio/8080bw.c | 2 +- src/mame/audio/bzone.c | 39 +- src/mame/audio/copsnrob.c | 175 ++++---- src/mame/audio/dkong.c | 58 +-- 18 files changed, 2957 insertions(+), 3109 deletions(-) create mode 100644 src/emu/sound/disc_dev.h create mode 100644 src/emu/sound/disc_flt.h create mode 100644 src/emu/sound/disc_mth.h create mode 100644 src/emu/sound/disc_wav.h diff --git a/.gitattributes b/.gitattributes index 8fff1c91100..afccacfe111 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/src/emu/sound/disc_cls.h b/src/emu/sound/disc_cls.h index 5d27b31406d..ec6520f555b 100644 --- a/src/emu/sound/disc_cls.h +++ b/src/emu/sound/disc_cls.h @@ -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__ */ diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index 298e39cb99a..b5230e34377 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -57,34 +57,33 @@ DISCRETE_STEP(dsd_555_astbl) { - DISCRETE_DECLARE_CONTEXT(dsd_555_astbl) DISCRETE_DECLARE_INFO(discrete_555_desc) int count_f = 0; int count_r = 0; double dt; /* change in time */ double x_time = 0; /* time since change happened */ - double v_cap = context->cap_voltage; /* Current voltage on capacitor, before dt */ + double v_cap = m_cap_voltage; /* Current voltage on capacitor, before dt */ double v_cap_next = 0; /* Voltage on capacitor, after dt */ double v_charge, exponent = 0; - UINT8 flip_flop = context->flip_flop; + UINT8 flip_flop = m_flip_flop; UINT8 update_exponent = 0; /* put commonly used stuff in local variables for speed */ - double threshold = context->threshold; - double trigger = context->trigger; + double threshold = m_threshold; + double trigger = m_trigger; if(DSD_555_ASTBL__RESET) { /* We are in RESET */ this->output[0] = 0; - context->flip_flop = 1; - context->cap_voltage = 0; + m_flip_flop = 1; + m_cap_voltage = 0; return; } /* Check: if the Control Voltage node is connected. */ - if (context->use_ctrlv) + if (m_use_ctrlv) { /* If CV is less then .25V, the circuit will oscillate way out of range. * So we will just ignore it when it happens. */ @@ -107,13 +106,13 @@ DISCRETE_STEP(dsd_555_astbl) } /* get the v_charge and update each step if it is a node */ - if (context->v_charge_node != NULL) + if (m_v_charge_node != NULL) { - v_charge = *context->v_charge_node; + v_charge = *m_v_charge_node; if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) v_charge -= 0.5; } else - v_charge = context->v_charge; + v_charge = m_v_charge; /* Calculate future capacitor voltage. @@ -145,22 +144,22 @@ DISCRETE_STEP(dsd_555_astbl) /* The voltage goes high because the cap circuit is open. */ v_cap_next = v_charge; v_cap = v_charge; - context->cap_voltage = 0; + m_cap_voltage = 0; } else { /* Update charge contstants and exponents if nodes changed */ - if (context->has_rc_nodes && (DSD_555_ASTBL__R1 != context->last_r1 || DSD_555_ASTBL__C != context->last_c || DSD_555_ASTBL__R2 != context->last_r2)) + if (m_has_rc_nodes && (DSD_555_ASTBL__R1 != m_last_r1 || DSD_555_ASTBL__C != m_last_c || DSD_555_ASTBL__R2 != m_last_r2)) { - context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; - context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; - context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; - context->exp_bleed = RC_CHARGE_EXP_CLASS(context->t_rc_bleed); - context->exp_charge = RC_CHARGE_EXP_CLASS(context->t_rc_charge); - context->exp_discharge = RC_CHARGE_EXP_CLASS(context->t_rc_discharge); - context->last_r1 = DSD_555_ASTBL__R1; - context->last_r2 = DSD_555_ASTBL__R2; - context->last_c = DSD_555_ASTBL__C; + m_t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; + m_t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; + m_t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; + m_exp_bleed = RC_CHARGE_EXP_CLASS(m_t_rc_bleed); + m_exp_charge = RC_CHARGE_EXP_CLASS(m_t_rc_charge); + m_exp_discharge = RC_CHARGE_EXP_CLASS(m_t_rc_discharge); + m_last_r1 = DSD_555_ASTBL__R1; + m_last_r2 = DSD_555_ASTBL__R2; + m_last_c = DSD_555_ASTBL__C; } /* Keep looping until all toggling in time sample is used up. */ do @@ -172,9 +171,9 @@ DISCRETE_STEP(dsd_555_astbl) /* Oscillation disabled because there is no longer any charge resistor. */ /* Bleed the cap due to circuit losses. */ if (update_exponent) - exponent = RC_CHARGE_EXP_DT(context->t_rc_bleed, dt); + exponent = RC_CHARGE_EXP_DT(m_t_rc_bleed, dt); else - exponent = context->exp_bleed; + exponent = m_exp_bleed; v_cap_next = v_cap - (v_cap * exponent); dt = 0; } @@ -182,9 +181,9 @@ DISCRETE_STEP(dsd_555_astbl) { /* Charging */ if (update_exponent) - exponent = RC_CHARGE_EXP_DT(context->t_rc_charge, dt); + exponent = RC_CHARGE_EXP_DT(m_t_rc_charge, dt); else - exponent = context->exp_charge; + exponent = m_exp_charge; v_cap_next = v_cap + ((v_charge - v_cap) * exponent); dt = 0; @@ -192,7 +191,7 @@ DISCRETE_STEP(dsd_555_astbl) if (v_cap_next >= threshold) { /* calculate the overshoot time */ - dt = context->t_rc_charge * log(1.0 / (1.0 - ((v_cap_next - threshold) / (v_charge - v_cap)))); + dt = m_t_rc_charge * log(1.0 / (1.0 - ((v_cap_next - threshold) / (v_charge - v_cap)))); x_time = dt; v_cap_next = threshold; flip_flop = 0; @@ -207,9 +206,9 @@ DISCRETE_STEP(dsd_555_astbl) if(DSD_555_ASTBL__R2 != 0) { if (update_exponent) - exponent = RC_CHARGE_EXP_DT(context->t_rc_discharge, dt); + exponent = RC_CHARGE_EXP_DT(m_t_rc_discharge, dt); else - exponent = context->exp_discharge; + exponent = m_exp_discharge; v_cap_next = v_cap - (v_cap * exponent); dt = 0; } @@ -224,7 +223,7 @@ DISCRETE_STEP(dsd_555_astbl) { /* calculate the overshoot time */ if (v_cap_next < trigger) - dt = context->t_rc_discharge * log(1.0 / (1.0 - ((trigger - v_cap_next) / v_cap))); + dt = m_t_rc_discharge * log(1.0 / (1.0 - ((trigger - v_cap_next) / v_cap))); x_time = dt; v_cap_next = trigger; flip_flop = 1; @@ -235,32 +234,32 @@ DISCRETE_STEP(dsd_555_astbl) v_cap = v_cap_next; } while(dt); - context->cap_voltage = v_cap; + m_cap_voltage = v_cap; } /* Convert last switch time to a ratio */ x_time = x_time / this->sample_time(); - switch (context->output_type) + switch (m_output_type) { case DISC_555_OUT_SQW: if (count_f + count_r >= 2) /* force at least 1 toggle */ - this->output[0] = context->flip_flop ? 0 : context->v_out_high; + this->output[0] = m_flip_flop ? 0 : m_v_out_high; else - this->output[0] = flip_flop * context->v_out_high; - this->output[0] += context->ac_shift; + this->output[0] = flip_flop * m_v_out_high; + this->output[0] += m_ac_shift; break; case DISC_555_OUT_CAP: this->output[0] = v_cap; /* Fake it to AC if needed */ - if (context->output_is_ac) + if (m_output_is_ac) this->output[0] -= threshold * 3.0 /4.0; break; case DISC_555_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time)); - this->output[0] += context->ac_shift; + this->output[0] = m_v_out_high * (flip_flop ? x_time : (1.0 - x_time)); + this->output[0] += m_ac_shift; break; case DISC_555_OUT_LOGIC_X: this->output[0] = flip_flop + x_time; @@ -278,67 +277,66 @@ DISCRETE_STEP(dsd_555_astbl) this->output[0] = count_r; break; } - context->flip_flop = flip_flop; + m_flip_flop = flip_flop; } DISCRETE_RESET(dsd_555_astbl) { - DISCRETE_DECLARE_CONTEXT(dsd_555_astbl) DISCRETE_DECLARE_INFO(discrete_555_desc) discrete_base_node *v_charge_node; - context->use_ctrlv = (this->input_is_node() >> 4) & 1; - context->output_type = info->options & DISC_555_OUT_MASK; + m_use_ctrlv = (this->input_is_node() >> 4) & 1; + m_output_type = info->options & DISC_555_OUT_MASK; /* Use the defaults or supplied values. */ - context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; + m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; /* setup v_charge or node */ v_charge_node = this->device->discrete_find_node(info->v_charge); if (v_charge_node) - context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); + m_v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); else { - context->v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge; - context->v_charge_node = NULL; + m_v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge; + m_v_charge_node = NULL; - if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) context->v_charge -= 0.5; + if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) m_v_charge -= 0.5; } - if ((DSD_555_ASTBL__CTRLV != -1) && !context->use_ctrlv) + if ((DSD_555_ASTBL__CTRLV != -1) && !m_use_ctrlv) { /* Setup based on supplied Control Voltage static value */ - context->threshold = DSD_555_ASTBL__CTRLV; - context->trigger = DSD_555_ASTBL__CTRLV / 2.0; + m_threshold = DSD_555_ASTBL__CTRLV; + m_trigger = DSD_555_ASTBL__CTRLV / 2.0; } else { /* Setup based on v_pos power source */ - context->threshold = info->v_pos * 2.0 / 3.0; - context->trigger = info->v_pos / 3.0; + m_threshold = info->v_pos * 2.0 / 3.0; + m_trigger = info->v_pos / 3.0; } /* optimization if none of the values are nodes */ - context->has_rc_nodes = 0; + m_has_rc_nodes = 0; if (this->input_is_node() & DSD_555_ASTBL_RC_MASK) - context->has_rc_nodes = 1; + m_has_rc_nodes = 1; else { - context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; - context->exp_bleed = RC_CHARGE_EXP_CLASS(context->t_rc_bleed); - context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; - context->exp_charge = RC_CHARGE_EXP_CLASS(context->t_rc_charge); - context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; - context->exp_discharge = RC_CHARGE_EXP_CLASS(context->t_rc_discharge); + m_t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED; + m_exp_bleed = RC_CHARGE_EXP_CLASS(m_t_rc_bleed); + m_t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE; + m_exp_charge = RC_CHARGE_EXP_CLASS(m_t_rc_charge); + m_t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE; + m_exp_discharge = RC_CHARGE_EXP_CLASS(m_t_rc_discharge); } - context->output_is_ac = info->options & DISC_555_OUT_AC; + m_output_is_ac = info->options & DISC_555_OUT_AC; /* Calculate DC shift needed to make squarewave waveform AC */ - context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0; + m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0; - context->flip_flop = 1; - context->cap_voltage = 0; + m_flip_flop = 1; + m_cap_voltage = 0; /* Step to set the output */ this->step(); @@ -368,7 +366,6 @@ DISCRETE_RESET(dsd_555_astbl) DISCRETE_STEP(dsd_555_mstbl) { - DISCRETE_DECLARE_CONTEXT(dsd_555_mstbl) DISCRETE_DECLARE_INFO(discrete_555_desc) double v_cap; /* Current voltage on capacitor, before dt */ @@ -377,22 +374,22 @@ DISCRETE_STEP(dsd_555_mstbl) double out = 0; int trigger = 0; int trigger_type; - int update_exponent = context->has_rc_nodes; + int update_exponent = m_has_rc_nodes; int flip_flop; if(UNEXPECTED(DSD_555_MSTBL__RESET)) { /* We are in RESET */ this->output[0] = 0; - context->flip_flop = 0; - context->cap_voltage = 0; + m_flip_flop = 0; + m_cap_voltage = 0; return; } dt = this->sample_time(); - flip_flop = context->flip_flop; + flip_flop = m_flip_flop; trigger_type = info->options; - v_cap = context->cap_voltage; + v_cap = m_cap_voltage; switch (trigger_type & DSD_555_TRIGGER_TYPE_MASK) { @@ -402,7 +399,7 @@ DISCRETE_STEP(dsd_555_mstbl) x_time = 1.0 - DSD_555_MSTBL__TRIGGER; break; case DISC_555_TRIGGER_IS_VOLTAGE: - trigger = (int)(DSD_555_MSTBL__TRIGGER < context->trigger); + trigger = (int)(DSD_555_MSTBL__TRIGGER < m_trigger); break; case DISC_555_TRIGGER_IS_COUNT: trigger = (int)DSD_555_MSTBL__TRIGGER; @@ -420,13 +417,13 @@ DISCRETE_STEP(dsd_555_mstbl) x_time = 0; if ((trigger_type & DISC_555_TRIGGER_DISCHARGES_CAP) && trigger) - context->cap_voltage = 0; + m_cap_voltage = 0; /* Wait for trigger */ if (UNEXPECTED(!flip_flop && trigger)) { flip_flop = 1; - context->flip_flop = 1; + m_flip_flop = 1; } if (flip_flop) @@ -439,44 +436,44 @@ DISCRETE_STEP(dsd_555_mstbl) /* The trigger voltage goes high because the cap circuit is open. * and the cap discharges */ v_cap = info->v_pos; /* needed for cap output type */ - context->cap_voltage = 0; + m_cap_voltage = 0; if (!trigger) { flip_flop = 0; - context->flip_flop = 0; + m_flip_flop = 0; } } else { /* Charging */ - double v_diff = context->v_charge - v_cap; + double v_diff = m_v_charge - v_cap; if (UNEXPECTED(update_exponent)) exponent = RC_CHARGE_EXP_DT(DSD_555_MSTBL__R * DSD_555_MSTBL__C, dt); else - exponent = context->exp_charge; + exponent = m_exp_charge; v_cap += v_diff * exponent; /* Has it charged past upper limit? */ /* If trigger is still enabled, then we keep charging, * regardless of threshold. */ - if (UNEXPECTED((v_cap >= context->threshold) && !trigger)) + if (UNEXPECTED((v_cap >= m_threshold) && !trigger)) { - dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap - context->threshold) / v_diff))); + dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap - m_threshold) / v_diff))); x_time = 1.0 - dt / this->sample_time(); v_cap = 0; flip_flop = 0; - context->flip_flop = 0; + m_flip_flop = 0; } - context->cap_voltage = v_cap; + m_cap_voltage = v_cap; } } - switch (context->output_type) + switch (m_output_type) { case DISC_555_OUT_SQW: - out = flip_flop * context->v_out_high - context->ac_shift; + out = flip_flop * m_v_out_high - m_ac_shift; break; case DISC_555_OUT_CAP: if (x_time > 0) @@ -484,17 +481,17 @@ DISCRETE_STEP(dsd_555_mstbl) else out = v_cap; - out -= context->ac_shift; + out -= m_ac_shift; break; case DISC_555_OUT_ENERGY: if (x_time > 0) - out = context->v_out_high * x_time; + out = m_v_out_high * x_time; else if (flip_flop) - out = context->v_out_high; + out = m_v_out_high; else out = 0; - out -= context->ac_shift; + out -= m_ac_shift; break; } this->output[0] = out; @@ -502,47 +499,46 @@ DISCRETE_STEP(dsd_555_mstbl) DISCRETE_RESET(dsd_555_mstbl) { - DISCRETE_DECLARE_CONTEXT(dsd_555_mstbl) DISCRETE_DECLARE_INFO(discrete_555_desc) - context->output_type = info->options & DISC_555_OUT_MASK; - if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R)) + m_output_type = info->options & DISC_555_OUT_MASK; + if ((m_output_type == DISC_555_OUT_COUNT_F) || (m_output_type == DISC_555_OUT_COUNT_R)) { this->device->discrete_log("Invalid Output type in NODE_%d.\n", this->index()); - context->output_type = DISC_555_OUT_SQW; + m_output_type = DISC_555_OUT_SQW; } /* Use the defaults or supplied values. */ - context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; - context->v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge; + m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; + m_v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge; /* Setup based on v_pos power source */ - context->threshold = info->v_pos * 2.0 / 3.0; - context->trigger = info->v_pos / 3.0; + m_threshold = info->v_pos * 2.0 / 3.0; + m_trigger = info->v_pos / 3.0; /* Calculate DC shift needed to make waveform AC */ if (info->options & DISC_555_OUT_AC) { - if (context->output_type == DISC_555_OUT_CAP) - context->ac_shift = context->threshold * 3.0 /4.0; + if (m_output_type == DISC_555_OUT_CAP) + m_ac_shift = m_threshold * 3.0 /4.0; else - context->ac_shift = context->v_out_high / 2.0; + m_ac_shift = m_v_out_high / 2.0; } else - context->ac_shift = 0; + m_ac_shift = 0; - context->trig_is_logic = (info->options & DISC_555_TRIGGER_IS_VOLTAGE) ? 0: 1; - context->trig_discharges_cap = (info->options & DISC_555_TRIGGER_DISCHARGES_CAP) ? 1: 0; + m_trig_is_logic = (info->options & DISC_555_TRIGGER_IS_VOLTAGE) ? 0: 1; + m_trig_discharges_cap = (info->options & DISC_555_TRIGGER_DISCHARGES_CAP) ? 1: 0; - context->flip_flop = 0; - context->cap_voltage = 0; + m_flip_flop = 0; + m_cap_voltage = 0; /* optimization if none of the values are nodes */ - context->has_rc_nodes = 0; + m_has_rc_nodes = 0; if (this->input_is_node() & DSD_555_MSTBL_RC_MASK) - context->has_rc_nodes = 1; + m_has_rc_nodes = 1; else - context->exp_charge = RC_CHARGE_EXP_CLASS(DSD_555_MSTBL__R * DSD_555_MSTBL__C); + m_exp_charge = RC_CHARGE_EXP_CLASS(DSD_555_MSTBL__R * DSD_555_MSTBL__C); this->output[0] = 0; } @@ -585,7 +581,6 @@ DISCRETE_RESET(dsd_555_mstbl) DISCRETE_STEP(dsd_555_cc) { - DISCRETE_DECLARE_CONTEXT(dsd_555_cc) DISCRETE_DECLARE_INFO(discrete_555_cc_desc) int count_f = 0; @@ -605,23 +600,23 @@ DISCRETE_STEP(dsd_555_cc) double r_temp; /* play thing */ double exponent; UINT8 update_exponent, update_t_rc; - UINT8 flip_flop = context->flip_flop; + UINT8 flip_flop = m_flip_flop; if (UNEXPECTED(DSD_555_CC__RESET)) { /* We are in RESET */ this->output[0] = 0; - context->flip_flop = 1; - context->cap_voltage = 0; + m_flip_flop = 1; + m_cap_voltage = 0; return; } dt = this->sample_time(); /* Change in time */ - v_cap = context->cap_voltage; /* Set to voltage before change */ + v_cap = m_cap_voltage; /* Set to voltage before change */ v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction; /* the max v_cap can be and still be charged by i */ /* Calculate charging current */ - i = (context->v_cc_source - v_vcharge_limit) / DSD_555_CC__R; + i = (m_v_cc_source - v_vcharge_limit) / DSD_555_CC__R; if ( i < 0) i = 0; if (info->options & DISCRETE_555_CC_TO_CAP) @@ -630,7 +625,7 @@ DISCRETE_STEP(dsd_555_cc) } else { - switch (context->type) /* see dsd_555_cc_reset for descriptions */ + switch (m_type) /* see dsd_555_cc_reset for descriptions */ { case 1: r_discharge = DSD_555_CC__RDIS; @@ -671,11 +666,11 @@ DISCRETE_STEP(dsd_555_cc) } /* Keep looping until all toggling in time sample is used up. */ - update_t_rc = context->has_rc_nodes; + update_t_rc = m_has_rc_nodes; update_exponent = update_t_rc; do { - if (context->type <= 1) + if (m_type <= 1) { /* Standard constant current charge */ if (flip_flop) @@ -691,7 +686,7 @@ DISCRETE_STEP(dsd_555_cc) exponent = RC_CHARGE_EXP_DT(t_rc, dt); } else - exponent = context->exp_bleed; + exponent = m_exp_bleed; v_cap_next = v_cap - (v_cap * exponent); dt = 0; } @@ -709,12 +704,12 @@ DISCRETE_STEP(dsd_555_cc) dt = 0; /* has it charged past upper limit? */ - if (v_cap_next >= context->threshold) + if (v_cap_next >= m_threshold) { /* calculate the overshoot time */ - dt = DSD_555_CC__C * (v_cap_next - context->threshold) / i; + dt = DSD_555_CC__C * (v_cap_next - m_threshold) / i; x_time = dt; - v_cap_next = context->threshold; + v_cap_next = m_threshold; flip_flop = 0; count_f++; update_exponent = 1; @@ -727,11 +722,11 @@ DISCRETE_STEP(dsd_555_cc) if (update_t_rc) t_rc = DSD_555_CC_T_RC_DISCHARGE_01; else - t_rc = context->t_rc_discharge_01; + t_rc = m_t_rc_discharge_01; if (update_exponent) exponent = RC_CHARGE_EXP_DT(t_rc, dt); else - exponent = context->exp_discharge_01; + exponent = m_exp_discharge_01; if (info->options & DISCRETE_555_CC_TO_CAP) { @@ -749,11 +744,11 @@ DISCRETE_STEP(dsd_555_cc) dt = 0; /* has it discharged past lower limit? */ - if (v_cap_next <= context->trigger) + if (v_cap_next <= m_trigger) { - dt = t_rc * log(1.0 / (1.0 - ((context->trigger - v_cap_next) / v_cap))); + dt = t_rc * log(1.0 / (1.0 - ((m_trigger - v_cap_next) / v_cap))); x_time = dt; - v_cap_next = context->trigger; + v_cap_next = m_trigger; flip_flop = 1; count_r++; update_exponent = 1; @@ -762,7 +757,7 @@ DISCRETE_STEP(dsd_555_cc) else /* Immediate discharge. No change in dt. */ { x_time = dt; - v_cap_next = context->trigger; + v_cap_next = m_trigger; flip_flop = 1; count_r++; } @@ -780,11 +775,11 @@ DISCRETE_STEP(dsd_555_cc) if (update_t_rc) t_rc = DSD_555_CC_T_RC_DISCHARGE_NO_I; else - t_rc = context->t_rc_discharge_no_i; + t_rc = m_t_rc_discharge_no_i; if (update_exponent) exponent = RC_CHARGE_EXP_DT(t_rc, dt); else - exponent = context->exp_discharge_no_i; + exponent = m_exp_discharge_no_i; v_cap_next = v_cap - (v_cap * exponent); dt = 0; @@ -796,27 +791,27 @@ DISCRETE_STEP(dsd_555_cc) * then only the bias voltage will charge the cap. */ v = v_bias; if (v_cap < v_vcharge_limit) v += vi; - else if (context->type <= 3) v = v_vcharge_limit; + else if (m_type <= 3) v = v_vcharge_limit; if (update_t_rc) t_rc = DSD_555_CC_T_RC_CHARGE; else - t_rc = context->t_rc_charge; + t_rc = m_t_rc_charge; if (update_exponent) exponent = RC_CHARGE_EXP_DT(t_rc, dt); else - exponent = context->exp_charge; + exponent = m_exp_charge; v_cap_next = v_cap + ((v - v_cap) * exponent); dt = 0; /* has it charged past upper limit? */ - if (v_cap_next >= context->threshold) + if (v_cap_next >= m_threshold) { /* calculate the overshoot time */ - dt = t_rc * log(1.0 / (1.0 - ((v_cap_next - context->threshold) / (v - v_cap)))); + dt = t_rc * log(1.0 / (1.0 - ((v_cap_next - m_threshold) / (v - v_cap)))); x_time = dt; - v_cap_next = context->threshold; + v_cap_next = m_threshold; flip_flop = 0; count_f++; update_exponent = 1; @@ -829,22 +824,22 @@ DISCRETE_STEP(dsd_555_cc) if (update_t_rc) t_rc = DSD_555_CC_T_RC_DISCHARGE; else - t_rc = context->t_rc_discharge; + t_rc = m_t_rc_discharge; if (update_exponent) exponent = RC_CHARGE_EXP_DT(t_rc, dt); else - exponent = context->exp_discharge; + exponent = m_exp_discharge; v_cap_next = v_cap - (v_cap * exponent); dt = 0; /* has it discharged past lower limit? */ - if (v_cap_next <= context->trigger) + if (v_cap_next <= m_trigger) { /* calculate the overshoot time */ - dt = t_rc * log(1.0 / (1.0 - ((context->trigger - v_cap_next) / v_cap))); + dt = t_rc * log(1.0 / (1.0 - ((m_trigger - v_cap_next) / v_cap))); x_time = dt; - v_cap_next = context->trigger; + v_cap_next = m_trigger; flip_flop = 1; count_r++; update_exponent = 1; @@ -853,7 +848,7 @@ DISCRETE_STEP(dsd_555_cc) else /* Immediate discharge. No change in dt. */ { x_time = dt; - v_cap_next = context->trigger; + v_cap_next = m_trigger; flip_flop = 1; count_r++; } @@ -861,29 +856,29 @@ DISCRETE_STEP(dsd_555_cc) v_cap = v_cap_next; } while(dt); - context->cap_voltage = v_cap; + m_cap_voltage = v_cap; /* Convert last switch time to a ratio */ x_time = x_time / this->sample_time(); - switch (context->output_type) + switch (m_output_type) { case DISC_555_OUT_SQW: if (count_f + count_r >= 2) /* force at least 1 toggle */ - this->output[0] = context->flip_flop ? 0 : context->v_out_high; + this->output[0] = m_flip_flop ? 0 : m_v_out_high; else - this->output[0] = flip_flop * context->v_out_high; + this->output[0] = flip_flop * m_v_out_high; /* Fake it to AC if needed */ - this->output[0] += context->ac_shift; + this->output[0] += m_ac_shift; break; case DISC_555_OUT_CAP: - this->output[0] = v_cap + context->ac_shift; + this->output[0] = v_cap + m_ac_shift; break; case DISC_555_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time)); - this->output[0] += context->ac_shift; + this->output[0] = m_v_out_high * (flip_flop ? x_time : (1.0 - x_time)); + this->output[0] += m_ac_shift; break; case DISC_555_OUT_LOGIC_X: this->output[0] = flip_flop + x_time; @@ -901,47 +896,46 @@ DISCRETE_STEP(dsd_555_cc) this->output[0] = count_r; break; } - context->flip_flop = flip_flop; + m_flip_flop = flip_flop; } DISCRETE_RESET(dsd_555_cc) { - DISCRETE_DECLARE_CONTEXT(dsd_555_cc) DISCRETE_DECLARE_INFO(discrete_555_cc_desc) double r_temp, r_discharge = 0, r_charge = 0; - context->flip_flop = 1; - context->cap_voltage = 0; + m_flip_flop = 1; + m_cap_voltage = 0; - context->output_type = info->options & DISC_555_OUT_MASK; + m_output_type = info->options & DISC_555_OUT_MASK; /* Use the defaults or supplied values. */ - context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; - context->v_cc_source = (info->v_cc_source == DEFAULT_555_CC_SOURCE) ? info->v_pos : info->v_cc_source; + m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; + m_v_cc_source = (info->v_cc_source == DEFAULT_555_CC_SOURCE) ? info->v_pos : info->v_cc_source; /* Setup based on v_pos power source */ - context->threshold = info->v_pos * 2.0 / 3.0; - context->trigger = info->v_pos / 3.0; + m_threshold = info->v_pos * 2.0 / 3.0; + m_trigger = info->v_pos / 3.0; - context->output_is_ac = info->options & DISC_555_OUT_AC; + m_output_is_ac = info->options & DISC_555_OUT_AC; /* Calculate DC shift needed to make squarewave waveform AC */ - context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0; + m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0; /* There are 8 different types of basic oscillators * depending on the resistors used. We will determine * the type of circuit at reset, because the ciruit type * is constant. See Below. */ - context->type = (DSD_555_CC__RDIS > 0) | ((DSD_555_CC__RGND > 0) << 1) | ((DSD_555_CC__RBIAS > 0) << 2); + m_type = (DSD_555_CC__RDIS > 0) | ((DSD_555_CC__RGND > 0) << 1) | ((DSD_555_CC__RBIAS > 0) << 2); /* optimization if none of the values are nodes */ - context->has_rc_nodes = 0; + m_has_rc_nodes = 0; if (this->input_is_node() & DSD_555_CC_RC_MASK) - context->has_rc_nodes = 1; + m_has_rc_nodes = 1; else { - switch (context->type) /* see dsd_555_cc_reset for descriptions */ + switch (m_type) /* see dsd_555_cc_reset for descriptions */ { case 1: r_discharge = DSD_555_CC__RDIS; @@ -969,15 +963,15 @@ DISCRETE_RESET(dsd_555_cc) break; } - context->exp_bleed = RC_CHARGE_EXP_CLASS(DSD_555_CC_T_RC_BLEED); - context->t_rc_discharge_01 = DSD_555_CC_T_RC_DISCHARGE_01; - context->exp_discharge_01 = RC_CHARGE_EXP_CLASS(context->t_rc_discharge_01); - context->t_rc_discharge_no_i = DSD_555_CC_T_RC_DISCHARGE_NO_I; - context->exp_discharge_no_i = RC_CHARGE_EXP_CLASS(context->t_rc_discharge_no_i); - context->t_rc_charge = DSD_555_CC_T_RC_CHARGE; - context->exp_charge = RC_CHARGE_EXP_CLASS(context->t_rc_charge); - context->t_rc_discharge = DSD_555_CC_T_RC_DISCHARGE; - context->exp_discharge = RC_CHARGE_EXP_CLASS(context->t_rc_discharge); + m_exp_bleed = RC_CHARGE_EXP_CLASS(DSD_555_CC_T_RC_BLEED); + m_t_rc_discharge_01 = DSD_555_CC_T_RC_DISCHARGE_01; + m_exp_discharge_01 = RC_CHARGE_EXP_CLASS(m_t_rc_discharge_01); + m_t_rc_discharge_no_i = DSD_555_CC_T_RC_DISCHARGE_NO_I; + m_exp_discharge_no_i = RC_CHARGE_EXP_CLASS(m_t_rc_discharge_no_i); + m_t_rc_charge = DSD_555_CC_T_RC_CHARGE; + m_exp_charge = RC_CHARGE_EXP_CLASS(m_t_rc_charge); + m_t_rc_discharge = DSD_555_CC_T_RC_DISCHARGE; + m_exp_discharge = RC_CHARGE_EXP_CLASS(m_t_rc_discharge); } /* Step to set the output */ @@ -1136,7 +1130,6 @@ DISCRETE_RESET(dsd_555_cc) DISCRETE_STEP(dsd_555_vco1) { - DISCRETE_DECLARE_CONTEXT(dsd_555_vco1) DISCRETE_DECLARE_INFO(discrete_555_vco1_desc) int count_f = 0; @@ -1147,29 +1140,29 @@ DISCRETE_STEP(dsd_555_vco1) double v_cap_next = 0; /* Voltage on capacitor, after dt */ dt = this->sample_time(); /* Change in time */ - v_cap = context->cap_voltage; + v_cap = m_cap_voltage; /* Check: if the Control Voltage node is connected. */ - if (context->ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */ + if (m_ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */ { /* If CV is less then .25V, the circuit will oscillate way out of range. * So we will just ignore it when it happens. */ if (DSD_555_VCO1__VIN2 < .25) return; /* If it is a node then calculate thresholds based on Control Voltage */ - context->threshold = DSD_555_VCO1__VIN2; - context->trigger = DSD_555_VCO1__VIN2 / 2.0; + m_threshold = DSD_555_VCO1__VIN2; + m_trigger = DSD_555_VCO1__VIN2 / 2.0; /* Since the thresholds may have changed we need to update the FF */ - if (v_cap >= context->threshold) + if (v_cap >= m_threshold) { x_time = dt; - context->flip_flop = 0; + m_flip_flop = 0; count_f++; } else - if (v_cap <= context->trigger) + if (v_cap <= m_trigger) { x_time = dt; - context->flip_flop = 1; + m_flip_flop = 1; count_r++; } } @@ -1177,29 +1170,29 @@ DISCRETE_STEP(dsd_555_vco1) /* Keep looping until all toggling in time sample is used up. */ do { - if (context->flip_flop) + if (m_flip_flop) { /* if we are in reset then toggle f/f and discharge */ if (!DSD_555_VCO1__RESET) /* reset active low */ { - context->flip_flop = 0; + m_flip_flop = 0; count_f++; } else { /* Charging */ /* iC=C*dv/dt works out to dv=iC*dt/C */ - v_cap_next = v_cap + (context->i_charge * dt / info->c); + v_cap_next = v_cap + (m_i_charge * dt / info->c); dt = 0; /* has it charged past upper limit? */ - if (v_cap_next >= context->threshold) + if (v_cap_next >= m_threshold) { /* calculate the overshoot time */ - dt = info->c * (v_cap_next - context->threshold) / context->i_charge; - v_cap = context->threshold; + dt = info->c * (v_cap_next - m_threshold) / m_i_charge; + v_cap = m_threshold; x_time = dt; - context->flip_flop = 0; + m_flip_flop = 0; count_f++; } } @@ -1208,7 +1201,7 @@ DISCRETE_STEP(dsd_555_vco1) { /* Discharging */ /* iC=C*dv/dt works out to dv=iC*dt/C */ - v_cap_next = v_cap - (context->i_discharge * dt / info->c); + v_cap_next = v_cap - (m_i_discharge * dt / info->c); /* if we are in reset, then the cap can discharge to 0 */ if (!DSD_555_VCO1__RESET) /* reset active low */ @@ -1220,12 +1213,12 @@ DISCRETE_STEP(dsd_555_vco1) { /* if we are out of reset and the cap voltage is less then * the lower threshold, toggle f/f and start charging */ - if (v_cap <= context->trigger) + if (v_cap <= m_trigger) { - if (context->flip_flop == 0) + if (m_flip_flop == 0) { /* don't need to track x_time here */ - context->flip_flop = 1; + m_flip_flop = 1; count_r++; } } @@ -1233,13 +1226,13 @@ DISCRETE_STEP(dsd_555_vco1) { dt = 0; /* has it discharged past lower limit? */ - if (v_cap_next <= context->trigger) + if (v_cap_next <= m_trigger) { /* calculate the overshoot time */ - dt = info->c * (v_cap_next - context->trigger) / context->i_discharge; - v_cap = context->trigger; + dt = info->c * (v_cap_next - m_trigger) / m_i_discharge; + v_cap = m_trigger; x_time = dt; - context->flip_flop = 1; + m_flip_flop = 1; count_r++; } } @@ -1247,30 +1240,30 @@ DISCRETE_STEP(dsd_555_vco1) } } while(dt); - context->cap_voltage = v_cap_next; + m_cap_voltage = v_cap_next; /* Convert last switch time to a ratio. No x_time in reset. */ x_time = x_time / this->sample_time(); if (!DSD_555_VCO1__RESET) x_time = 0; - switch (context->output_type) + switch (m_output_type) { case DISC_555_OUT_SQW: - this->output[0] = context->flip_flop * context->v_out_high + context->ac_shift; + this->output[0] = m_flip_flop * m_v_out_high + m_ac_shift; break; case DISC_555_OUT_CAP: this->output[0] = v_cap_next; /* Fake it to AC if needed */ - if (context->output_is_ac) - this->output[0] -= context->threshold * 3.0 /4.0; + if (m_output_is_ac) + this->output[0] -= m_threshold * 3.0 /4.0; break; case DISC_555_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time)); - this->output[0] += context->ac_shift; + this->output[0] = m_v_out_high * (m_flip_flop ? x_time : (1.0 - x_time)); + this->output[0] += m_ac_shift; break; case DISC_555_OUT_LOGIC_X: - this->output[0] = context->flip_flop + x_time; + this->output[0] = m_flip_flop + x_time; break; case DISC_555_OUT_COUNT_F_X: this->output[0] = count_f ? count_f + x_time : count_f; @@ -1289,13 +1282,12 @@ DISCRETE_STEP(dsd_555_vco1) DISCRETE_RESET(dsd_555_vco1) { - DISCRETE_DECLARE_CONTEXT(dsd_555_vco1) DISCRETE_DECLARE_INFO(discrete_555_vco1_desc) double v_ratio_r3, v_ratio_r4_1, r_in_1; - context->output_type = info->options & DISC_555_OUT_MASK; - context->output_is_ac = info->options & DISC_555_OUT_AC; + m_output_type = info->options & DISC_555_OUT_MASK; + m_output_is_ac = info->options & DISC_555_OUT_AC; /* Setup op-amp parameters */ @@ -1313,38 +1305,38 @@ DISCRETE_RESET(dsd_555_vco1) /* Now that we know the voltages entering the op amp and the resistance for the * FF states, we can predetermine the ratios for the charge/discharge currents. */ - context->i_discharge = (1 - v_ratio_r3) / info->r1; - context->i_charge = (v_ratio_r3 - v_ratio_r4_1) / r_in_1; + m_i_discharge = (1 - v_ratio_r3) / info->r1; + m_i_charge = (v_ratio_r3 - v_ratio_r4_1) / r_in_1; /* the cap starts off discharged */ - context->cap_voltage = 0; + m_cap_voltage = 0; /* Setup 555 parameters */ /* There is no charge on the cap so the 555 goes high at init. */ - context->flip_flop = 1; - context->ctrlv_is_node = (this->input_is_node() >> 2) & 1; - context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; + m_flip_flop = 1; + m_ctrlv_is_node = (this->input_is_node() >> 2) & 1; + m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; /* Calculate 555 thresholds. * If the Control Voltage is a node, then the thresholds will be calculated each step. * If the Control Voltage is a fixed voltage, then the thresholds will be calculated * from that. Otherwise we will use thresholds based on v_pos. */ - if (!context->ctrlv_is_node && (DSD_555_VCO1__VIN2 != -1)) + if (!m_ctrlv_is_node && (DSD_555_VCO1__VIN2 != -1)) { /* Setup based on supplied Control Voltage static value */ - context->threshold = DSD_555_VCO1__VIN2; - context->trigger = DSD_555_VCO1__VIN2 / 2.0; + m_threshold = DSD_555_VCO1__VIN2; + m_trigger = DSD_555_VCO1__VIN2 / 2.0; } else { /* Setup based on v_pos power source */ - context->threshold = info->v_pos * 2.0 / 3.0; - context->trigger = info->v_pos / 3.0; + m_threshold = info->v_pos * 2.0 / 3.0; + m_trigger = info->v_pos / 3.0; } /* Calculate DC shift needed to make squarewave waveform AC */ - context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0; + m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0; } @@ -1427,8 +1419,6 @@ static const struct DISCRETE_STEP(dsd_566) { - DISCRETE_DECLARE_CONTEXT(dsd_566) - double i = 0; /* Charging current created by vIn */ double i_rise; /* non-linear rise charge current */ double dt; /* change in time */ @@ -1437,20 +1427,20 @@ DISCRETE_STEP(dsd_566) int count_f = 0, count_r = 0; dt = this->sample_time(); /* Change in time */ - v_cap = context->cap_voltage; /* Set to voltage before change */ + v_cap = m_cap_voltage; /* Set to voltage before change */ /* Calculate charging current if it is in range */ - if (EXPECTED(DSD_566__VMOD > context->v_osc_stop)) + if (EXPECTED(DSD_566__VMOD > m_v_osc_stop)) { double v_charge = DSD_566__VCHARGE - DSD_566__VMOD - 0.1; if (v_charge > 0) { i = (v_charge * .95) / DSD_566__R; - if (DSD_566__VMOD < context->v_osc_stable) + if (DSD_566__VMOD < m_v_osc_stable) { /* no where near correct calculation of non linear range */ - i_rise = ((DSD_566__VCHARGE - context->v_osc_stable - 0.1) * .95) / DSD_566__R; - i_rise *= 1.0 - (context->v_osc_stable - DSD_566__VMOD) / (context->v_osc_stable - context->v_osc_stop); + i_rise = ((DSD_566__VCHARGE - m_v_osc_stable - 0.1) * .95) / DSD_566__R; + i_rise *= 1.0 - (m_v_osc_stable - DSD_566__VMOD) / (m_v_osc_stable - m_v_osc_stop); } else i_rise = i; @@ -1463,19 +1453,19 @@ DISCRETE_STEP(dsd_566) /* Keep looping until all toggling in this time sample is used up. */ do { - if (context->flip_flop) + if (m_flip_flop) { /* Discharging */ v_cap -= i * dt / DSD_566__C; dt = 0; /* has it discharged past lower limit? */ - if (UNEXPECTED(v_cap < context->threshold_low)) + if (UNEXPECTED(v_cap < m_threshold_low)) { /* calculate the overshoot time */ - dt = DSD_566__C * (context->threshold_low - v_cap) / i; - v_cap = context->threshold_low; - context->flip_flop = 0; + dt = DSD_566__C * (m_threshold_low - v_cap) / i; + v_cap = m_threshold_low; + m_flip_flop = 0; count_f++; x_time = dt; } @@ -1494,43 +1484,43 @@ DISCRETE_STEP(dsd_566) if (UNEXPECTED(v_cap > DSD_566__VMOD)) v_cap = DSD_566__VMOD; /* has it charged past upper limit? */ - if (UNEXPECTED(v_cap > context->threshold_high)) + if (UNEXPECTED(v_cap > m_threshold_high)) { /* calculate the overshoot time */ - dt = DSD_566__C * (v_cap - context->threshold_high) / i; - v_cap = context->threshold_high; - context->flip_flop = 1; + dt = DSD_566__C * (v_cap - m_threshold_high) / i; + v_cap = m_threshold_high; + m_flip_flop = 1; count_r++; x_time = dt; } } } while(dt); - context->cap_voltage = v_cap; + m_cap_voltage = v_cap; /* Convert last switch time to a ratio */ x_time /= this->sample_time(); - switch (context->out_type) + switch (m_out_type) { case DISC_566_OUT_SQUARE: - this->output[0] = context->flip_flop ? context->v_sqr_high : context->v_sqr_low; - if (context->fake_ac) - this->output[0] += context->ac_shift; + this->output[0] = m_flip_flop ? m_v_sqr_high : m_v_sqr_low; + if (m_fake_ac) + this->output[0] += m_ac_shift; break; case DISC_566_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = context->v_sqr_low + context->v_sqr_diff * (context->flip_flop ? x_time : (1.0 - x_time)); - if (context->fake_ac) - this->output[0] += context->ac_shift; + this->output[0] = m_v_sqr_low + m_v_sqr_diff * (m_flip_flop ? x_time : (1.0 - x_time)); + if (m_fake_ac) + this->output[0] += m_ac_shift; break; case DISC_566_OUT_LOGIC: - this->output[0] = context->flip_flop; + this->output[0] = m_flip_flop; break; case DISC_566_OUT_TRIANGLE: this->output[0] = v_cap; - if (context->fake_ac) - this->output[0] += context->ac_shift; + if (m_fake_ac) + this->output[0] += m_ac_shift; break; case DISC_566_OUT_COUNT_F_X: this->output[0] = count_f ? count_f + x_time : count_f; @@ -1549,13 +1539,11 @@ DISCRETE_STEP(dsd_566) DISCRETE_RESET(dsd_566) { - DISCRETE_DECLARE_CONTEXT(dsd_566) - int v_int; double v_float; - context->out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK; - context->fake_ac = (int)DSD_566__OPTIONS & DISC_566_OUT_AC; + m_out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK; + m_fake_ac = (int)DSD_566__OPTIONS & DISC_566_OUT_AC; if (DSD_566__VNEG >= DSD_566__VPOS) fatalerror("[v_neg >= v_pos] in NODE_%d!\n", this->index()); @@ -1568,25 +1556,25 @@ DISCRETE_RESET(dsd_566) /* fatal for now. */ fatalerror("Power should be integer in NODE_%d\n", this->index()); - context->flip_flop = 0; - context->cap_voltage = 0; + m_flip_flop = 0; + m_cap_voltage = 0; v_int -= 10; - context->threshold_high = ne566.c_high[v_int] + DSD_566__VNEG; - context->threshold_low = ne566.c_low[v_int] + DSD_566__VNEG; - context->v_sqr_high = DSD_566__VPOS - 1; - context->v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG; - context->v_sqr_diff = context->v_sqr_high - context->v_sqr_low; - context->v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG; - context->v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG; + m_threshold_high = ne566.c_high[v_int] + DSD_566__VNEG; + m_threshold_low = ne566.c_low[v_int] + DSD_566__VNEG; + m_v_sqr_high = DSD_566__VPOS - 1; + m_v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG; + m_v_sqr_diff = m_v_sqr_high - m_v_sqr_low; + m_v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG; + m_v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG; - context->ac_shift = 0; - if (context->fake_ac) + m_ac_shift = 0; + if (m_fake_ac) { - if (context->out_type == DISC_566_OUT_TRIANGLE) - context->ac_shift = (context->threshold_high - context->threshold_low) / 2 - context->threshold_high; + if (m_out_type == DISC_566_OUT_TRIANGLE) + m_ac_shift = (m_threshold_high - m_threshold_low) / 2 - m_threshold_high; else - context->ac_shift = context->v_sqr_diff / 2 - context->v_sqr_high; + m_ac_shift = m_v_sqr_diff / 2 - m_v_sqr_high; } /* Step the output */ @@ -1650,12 +1638,10 @@ DISCRETE_RESET(dsd_566) DISCRETE_STEP(dsd_ls624) { - DISCRETE_DECLARE_CONTEXT(dsd_ls624) - double x_time = 0; double freq, t1; double v_freq_2, v_freq_3, v_freq_4; - double t_used = context->t_used; + double t_used = m_t_used; double dt = this->sample_time();; double v_freq = DSD_LS624__VMOD; double v_rng = DSD_LS624__VRNG; @@ -1677,14 +1663,14 @@ DISCRETE_STEP(dsd_ls624) return; /* scale due to input resistance */ - v_freq *= context->v_freq_scale; - v_rng *= context->v_rng_scale; + v_freq *= m_v_freq_scale; + v_rng *= m_v_rng_scale; /* apply cap if needed */ - if (context->has_freq_in_cap) + if (m_has_freq_in_cap) { - context->v_cap_freq_in += (v_freq - context->v_cap_freq_in) * context->exponent; - v_freq = context->v_cap_freq_in; + m_v_cap_freq_in += (v_freq - m_v_cap_freq_in) * m_exponent; + v_freq = m_v_cap_freq_in; } /* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */ @@ -1713,8 +1699,8 @@ DISCRETE_STEP(dsd_ls624) { /* calculate the overshoot time */ t_used -= t1; - context->flip_flop ^= 1; - if (context->flip_flop) + m_flip_flop ^= 1; + if (m_flip_flop) count_r++; else count_f++; @@ -1726,15 +1712,15 @@ DISCRETE_STEP(dsd_ls624) } }while(dt); - context->t_used = t_used; + m_t_used = t_used; /* Convert last switch time to a ratio */ x_time = x_time / this->sample_time(); - switch (context->out_type) + switch (m_out_type) { case DISC_LS624_OUT_LOGIC_X: - this->output[0] = context->flip_flop + x_time; + this->output[0] = m_flip_flop + x_time; break; case DISC_LS624_OUT_COUNT_F_X: this->output[0] = count_f ? count_f + x_time : count_f; @@ -1750,35 +1736,33 @@ DISCRETE_STEP(dsd_ls624) break; case DISC_LS624_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = LS624_OUT_HIGH * (context->flip_flop ? x_time : (1.0 - x_time)); + this->output[0] = LS624_OUT_HIGH * (m_flip_flop ? x_time : (1.0 - x_time)); break; case DISC_LS624_OUT_LOGIC: - this->output[0] = context->flip_flop; + this->output[0] = m_flip_flop; break; case DISC_LS624_OUT_SQUARE: - this->output[0] = context->flip_flop ? LS624_OUT_HIGH : 0; + this->output[0] = m_flip_flop ? LS624_OUT_HIGH : 0; break; } } DISCRETE_RESET(dsd_ls624) { - struct dsd_ls624_context *context = (struct dsd_ls624_context *)this->context; + m_out_type = (int)DSD_LS624__OUTTYPE; - context->out_type = (int)DSD_LS624__OUTTYPE; - - context->flip_flop = 0; - context->t_used = 0; - context->v_freq_scale = LS624_IN_R / (DSD_LS624__R_FREQ_IN + LS624_IN_R); - context->v_rng_scale = LS624_IN_R / (DSD_LS624__R_RNG_IN + LS624_IN_R); + m_flip_flop = 0; + m_t_used = 0; + m_v_freq_scale = LS624_IN_R / (DSD_LS624__R_FREQ_IN + LS624_IN_R); + m_v_rng_scale = LS624_IN_R / (DSD_LS624__R_RNG_IN + LS624_IN_R); if (DSD_LS624__C_FREQ_IN > 0) { - context->has_freq_in_cap = 1; - context->exponent = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(DSD_LS624__R_FREQ_IN, LS624_IN_R) * DSD_LS624__C_FREQ_IN); - context->v_cap_freq_in = 0; + m_has_freq_in_cap = 1; + m_exponent = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(DSD_LS624__R_FREQ_IN, LS624_IN_R) * DSD_LS624__C_FREQ_IN); + m_v_cap_freq_in = 0; } else - context->has_freq_in_cap = 0; + m_has_freq_in_cap = 0; this->output[0] = 0; } diff --git a/src/emu/sound/disc_dev.h b/src/emu/sound/disc_dev.h new file mode 100644 index 00000000000..c6ab28e62b2 --- /dev/null +++ b/src/emu/sound/disc_dev.h @@ -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__ */ diff --git a/src/emu/sound/disc_flt.c b/src/emu/sound/disc_flt.c index 75bb0f8e249..6c47bd4378f 100644 --- a/src/emu/sound/disc_flt.c +++ b/src/emu/sound/disc_flt.c @@ -46,32 +46,28 @@ DISCRETE_STEP(dst_crfilter) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter) - - if (UNEXPECTED(context->has_rc_nodes)) + if (UNEXPECTED(m_has_rc_nodes)) { double rc = DST_CRFILTER__R * DST_CRFILTER__C; - if (rc != context->rc) + if (rc != m_rc) { - context->rc = rc; - context->exponent = RC_CHARGE_EXP_CLASS(rc); + m_rc = rc; + m_exponent = RC_CHARGE_EXP_CLASS(rc); } } - double v_out = DST_CRFILTER__IN - context->vCap; + double v_out = DST_CRFILTER__IN - m_vCap; double v_diff = v_out - DST_CRFILTER__VREF; this->output[0] = v_out; - context->vCap += v_diff * context->exponent; + m_vCap += v_diff * m_exponent; } DISCRETE_RESET(dst_crfilter) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter) - - context->has_rc_nodes = this->input_is_node() & 0x6; - context->rc = DST_CRFILTER__R * DST_CRFILTER__C; - context->exponent = RC_CHARGE_EXP_CLASS(context->rc); - context->vCap = 0; + m_has_rc_nodes = this->input_is_node() & 0x6; + m_rc = DST_CRFILTER__R * DST_CRFILTER__C; + m_exponent = RC_CHARGE_EXP_CLASS(m_rc); + m_vCap = 0; this->output[0] = DST_CRFILTER__IN; } @@ -92,7 +88,7 @@ DISCRETE_RESET(dst_crfilter) #define DST_FILTER1__TYPE DISCRETE_INPUT(3) static void calculate_filter1_coefficients(discrete_base_node *node, double fc, double type, - double *a1, double *b0, double *b1) + struct discrete_filter_coeff &coeff) { double den, w, two_over_T; @@ -102,15 +98,15 @@ static void calculate_filter1_coefficients(discrete_base_node *node, double fc, two_over_T = 2.0*node->sample_rate(); den = w + two_over_T; - *a1 = (w - two_over_T)/den; + coeff.a1 = (w - two_over_T)/den; if (type == DISC_FILTER_LOWPASS) { - *b0 = *b1 = w/den; + coeff.b0 = coeff.b1 = w/den; } else if (type == DISC_FILTER_HIGHPASS) { - *b0 = two_over_T/den; - *b1 = -(*b0); + coeff.b0 = two_over_T/den; + coeff.b1 = -(coeff.b0); } else { @@ -120,8 +116,6 @@ static void calculate_filter1_coefficients(discrete_base_node *node, double fc, DISCRETE_STEP(dst_filter1) { - DISCRETE_DECLARE_CONTEXT(dst_filter1) - double gain = 1.0; if (DST_FILTER1__ENABLE == 0.0) @@ -129,17 +123,15 @@ DISCRETE_STEP(dst_filter1) gain = 0.0; } - this->output[0] = -context->a1*context->y1 + context->b0*gain*DST_FILTER1__IN + context->b1*context->x1; + this->output[0] = -m_fc.a1*m_fc.y1 + m_fc.b0*gain*DST_FILTER1__IN + m_fc.b1*m_fc.x1; - context->x1 = gain*DST_FILTER1__IN; - context->y1 = this->output[0]; + m_fc.x1 = gain*DST_FILTER1__IN; + m_fc.y1 = this->output[0]; } DISCRETE_RESET(dst_filter1) { - DISCRETE_DECLARE_CONTEXT(dst_filter1) - - calculate_filter1_coefficients(this, DST_FILTER1__FREQ, DST_FILTER1__TYPE, &context->a1, &context->b0, &context->b1); + calculate_filter1_coefficients(this, DST_FILTER1__FREQ, DST_FILTER1__TYPE, m_fc); this->output[0] = 0; } @@ -163,8 +155,7 @@ DISCRETE_RESET(dst_filter1) static void calculate_filter2_coefficients(discrete_base_node *node, double fc, double d, double type, - double *a1, double *a2, - double *b0, double *b1, double *b2) + struct discrete_filter_coeff &coeff) { double w; /* cutoff freq, in radians/sec */ double w_squared; @@ -179,24 +170,24 @@ static void calculate_filter2_coefficients(discrete_base_node *node, den = two_over_T_squared + d*w*two_over_T + w_squared; - *a1 = 2.0 * (-two_over_T_squared + w_squared) / den; - *a2 = (two_over_T_squared - d * w * two_over_T + w_squared) / den; + coeff.a1 = 2.0 * (-two_over_T_squared + w_squared) / den; + coeff.a2 = (two_over_T_squared - d * w * two_over_T + w_squared) / den; if (type == DISC_FILTER_LOWPASS) { - *b0 = *b2 = w_squared/den; - *b1 = 2.0 * (*b0); + coeff.b0 = coeff.b2 = w_squared/den; + coeff.b1 = 2.0 * (coeff.b0); } else if (type == DISC_FILTER_BANDPASS) { - *b0 = d * w * two_over_T / den; - *b1 = 0.0; - *b2 = -(*b0); + coeff.b0 = d * w * two_over_T / den; + coeff.b1 = 0.0; + coeff.b2 = -(coeff.b0); } else if (type == DISC_FILTER_HIGHPASS) { - *b0 = *b2 = two_over_T_squared / den; - *b1 = -2.0 * (*b0); + coeff.b0 = coeff.b2 = two_over_T_squared / den; + coeff.b1 = -2.0 * (coeff.b0); } else { @@ -206,8 +197,6 @@ static void calculate_filter2_coefficients(discrete_base_node *node, DISCRETE_STEP(dst_filter2) { - DISCRETE_DECLARE_CONTEXT(dst_filter2) - double gain = 1.0; if (DST_FILTER2__ENABLE == 0.0) @@ -215,22 +204,19 @@ DISCRETE_STEP(dst_filter2) gain = 0.0; } - this->output[0] = -context->a1 * context->y1 - context->a2 * context->y2 + - context->b0 * gain * DST_FILTER2__IN + context->b1 * context->x1 + context->b2 * context->x2; + this->output[0] = -m_fc.a1 * m_fc.y1 - m_fc.a2 * m_fc.y2 + + m_fc.b0 * gain * DST_FILTER2__IN + m_fc.b1 * m_fc.x1 + m_fc.b2 * m_fc.x2; - context->x2 = context->x1; - context->x1 = gain * DST_FILTER2__IN; - context->y2 = context->y1; - context->y1 = this->output[0]; + m_fc.x2 = m_fc.x1; + m_fc.x1 = gain * DST_FILTER2__IN; + m_fc.y2 = m_fc.y1; + m_fc.y1 = this->output[0]; } DISCRETE_RESET(dst_filter2) { - DISCRETE_DECLARE_CONTEXT(dst_filter2) - calculate_filter2_coefficients(this, DST_FILTER2__FREQ, DST_FILTER2__DAMP, DST_FILTER2__TYPE, - &context->a1, &context->a2, - &context->b0, &context->b1, &context->b2); + m_fc); this->output[0] = 0; } @@ -255,14 +241,13 @@ DISCRETE_RESET(dst_filter2) DISCRETE_STEP(dst_op_amp_filt) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp_filt) DISCRETE_DECLARE_INFO(discrete_op_amp_filt_info) double i, v = 0; if (DST_OP_AMP_FILT__ENABLE) { - if (context->is_norton) + if (m_is_norton) { v = DST_OP_AMP_FILT__INP1 - OP_AMP_NORTON_VBE; if (v < 0) v = 0; @@ -270,83 +255,83 @@ DISCRETE_STEP(dst_op_amp_filt) else { /* Millman the input voltages. */ - i = context->iFixed; - switch (context->type) + i = m_iFixed; + switch (m_type) { case DISC_OP_AMP_FILTER_IS_LOW_PASS_1_A: i += (DST_OP_AMP_FILT__INP1 - DST_OP_AMP_FILT__INP2) / info->r1; if (info->r2 != 0) - i += (context->vP - DST_OP_AMP_FILT__INP2) / info->r2; + i += (m_vP - DST_OP_AMP_FILT__INP2) / info->r2; if (info->r3 != 0) - i += (context->vN - DST_OP_AMP_FILT__INP2) / info->r3; + i += (m_vN - DST_OP_AMP_FILT__INP2) / info->r3; break; default: - i += (DST_OP_AMP_FILT__INP1 - context->vRef) / info->r1; + i += (DST_OP_AMP_FILT__INP1 - m_vRef) / info->r1; if (info->r2 != 0) - i += (DST_OP_AMP_FILT__INP2 - context->vRef) / info->r2; + i += (DST_OP_AMP_FILT__INP2 - m_vRef) / info->r2; break; } - v = i * context->rTotal; + v = i * m_rTotal; } - switch (context->type) + switch (m_type) { case DISC_OP_AMP_FILTER_IS_LOW_PASS_1: - context->vC1 += (v - context->vC1) * context->exponentC1; - this->output[0] = context->vC1 * context->gain + info->vRef; + m_vC1 += (v - m_vC1) * m_exponentC1; + this->output[0] = m_vC1 * m_gain + info->vRef; break; case DISC_OP_AMP_FILTER_IS_LOW_PASS_1_A: - context->vC1 += (v - context->vC1) * context->exponentC1; - this->output[0] = context->vC1 * context->gain + DST_OP_AMP_FILT__INP2; + m_vC1 += (v - m_vC1) * m_exponentC1; + this->output[0] = m_vC1 * m_gain + DST_OP_AMP_FILT__INP2; break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_1: - this->output[0] = (v - context->vC1) * context->gain + info->vRef; - context->vC1 += (v - context->vC1) * context->exponentC1; + this->output[0] = (v - m_vC1) * m_gain + info->vRef; + m_vC1 += (v - m_vC1) * m_exponentC1; break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1: - this->output[0] = (v - context->vC2); - context->vC2 += (v - context->vC2) * context->exponentC2; - context->vC1 += (this->output[0] - context->vC1) * context->exponentC1; - this->output[0] = context->vC1 * context->gain + info->vRef; + this->output[0] = (v - m_vC2); + m_vC2 += (v - m_vC2) * m_exponentC2; + m_vC1 += (this->output[0] - m_vC1) * m_exponentC1; + this->output[0] = m_vC1 * m_gain + info->vRef; break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON: - context->vC1 += (v - context->vC1) * context->exponentC1; - context->vC2 += (context->vC1 - context->vC2) * context->exponentC2; - v = context->vC2; - this->output[0] = v - context->vC3; - context->vC3 += (v - context->vC3) * context->exponentC3; - i = this->output[0] / context->rTotal; - this->output[0] = (context->iFixed - i) * info->rF; + m_vC1 += (v - m_vC1) * m_exponentC1; + m_vC2 += (m_vC1 - m_vC2) * m_exponentC2; + v = m_vC2; + this->output[0] = v - m_vC3; + m_vC3 += (v - m_vC3) * m_exponentC3; + i = this->output[0] / m_rTotal; + this->output[0] = (m_iFixed - i) * info->rF; break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_0 | DISC_OP_AMP_IS_NORTON: - this->output[0] = v - context->vC1; - context->vC1 += (v - context->vC1) * context->exponentC1; - i = this->output[0] / context->rTotal; - this->output[0] = (context->iFixed - i) * info->rF; + this->output[0] = v - m_vC1; + m_vC1 += (v - m_vC1) * m_exponentC1; + i = this->output[0] / m_rTotal; + this->output[0] = (m_iFixed - i) * info->rF; break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1M: case DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON: - this->output[0] = -context->a1 * context->y1 - context->a2 * context->y2 + - context->b0 * v + context->b1 * context->x1 + context->b2 * context->x2 + - context->vRef; - context->x2 = context->x1; - context->x1 = v; - context->y2 = context->y1; + this->output[0] = -m_fc.a1 * m_fc.y1 - m_fc.a2 * m_fc.y2 + + m_fc.b0 * v + m_fc.b1 * m_fc.x1 + m_fc.b2 * m_fc.x2 + + m_vRef; + m_fc.x2 = m_fc.x1; + m_fc.x1 = v; + m_fc.y2 = m_fc.y1; break; } /* Clip the output to the voltage rails. * This way we get the original distortion in all it's glory. */ - if (this->output[0] > context->vP) this->output[0] = context->vP; - if (this->output[0] < context->vN) this->output[0] = context->vN; - context->y1 = this->output[0] - context->vRef; + if (this->output[0] > m_vP) this->output[0] = m_vP; + if (this->output[0] < m_vN) this->output[0] = m_vN; + m_fc.y1 = this->output[0] - m_vRef; } else this->output[0] = 0; @@ -355,101 +340,98 @@ DISCRETE_STEP(dst_op_amp_filt) DISCRETE_RESET(dst_op_amp_filt) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp_filt) DISCRETE_DECLARE_INFO(discrete_op_amp_filt_info) /* Convert the passed filter type into an int for easy use. */ - context->type = (int)DST_OP_AMP_FILT__TYPE & DISC_OP_AMP_FILTER_TYPE_MASK; - context->is_norton = (int)DST_OP_AMP_FILT__TYPE & DISC_OP_AMP_IS_NORTON; + m_type = (int)DST_OP_AMP_FILT__TYPE & DISC_OP_AMP_FILTER_TYPE_MASK; + m_is_norton = (int)DST_OP_AMP_FILT__TYPE & DISC_OP_AMP_IS_NORTON; - if (context->is_norton) + if (m_is_norton) { - context->vRef = 0; - context->rTotal = info->r1; - if (context->type == (DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON)) - context->rTotal += info->r2 + info->r3; + m_vRef = 0; + m_rTotal = info->r1; + if (m_type == (DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON)) + m_rTotal += info->r2 + info->r3; /* Setup the current to the + input. */ - context->iFixed = (info->vP - OP_AMP_NORTON_VBE) / info->r4; + m_iFixed = (info->vP - OP_AMP_NORTON_VBE) / info->r4; /* Set the output max. */ - context->vP = info->vP - OP_AMP_NORTON_VBE; - context->vN = info->vN; + m_vP = info->vP - OP_AMP_NORTON_VBE; + m_vN = info->vN; } else { - context->vRef = info->vRef; + m_vRef = info->vRef; /* Set the output max. */ - context->vP = info->vP - OP_AMP_VP_RAIL_OFFSET; - context->vN = info->vN; + m_vP = info->vP - OP_AMP_VP_RAIL_OFFSET; + m_vN = info->vN; /* Work out the input resistance. It is all input and bias resistors in parallel. */ - context->rTotal = 1.0 / info->r1; /* There has to be an R1. Otherwise the table is wrong. */ - if (info->r2 != 0) context->rTotal += 1.0 / info->r2; - if (info->r3 != 0) context->rTotal += 1.0 / info->r3; - context->rTotal = 1.0 / context->rTotal; + m_rTotal = 1.0 / info->r1; /* There has to be an R1. Otherwise the table is wrong. */ + if (info->r2 != 0) m_rTotal += 1.0 / info->r2; + if (info->r3 != 0) m_rTotal += 1.0 / info->r3; + m_rTotal = 1.0 / m_rTotal; - context->iFixed = 0; + m_iFixed = 0; - context->rRatio = info->rF / (context->rTotal + info->rF); - context->gain = -info->rF / context->rTotal; + m_rRatio = info->rF / (m_rTotal + info->rF); + m_gain = -info->rF / m_rTotal; } - switch (context->type) + switch (m_type) { case DISC_OP_AMP_FILTER_IS_LOW_PASS_1: case DISC_OP_AMP_FILTER_IS_LOW_PASS_1_A: - context->exponentC1 = RC_CHARGE_EXP_CLASS(info->rF * info->c1); - context->exponentC2 = 0; + m_exponentC1 = RC_CHARGE_EXP_CLASS(info->rF * info->c1); + m_exponentC2 = 0; break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_1: - context->exponentC1 = RC_CHARGE_EXP_CLASS(context->rTotal * info->c1); - context->exponentC2 = 0; + m_exponentC1 = RC_CHARGE_EXP_CLASS(m_rTotal * info->c1); + m_exponentC2 = 0; break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1: - context->exponentC1 = RC_CHARGE_EXP_CLASS(info->rF * info->c1); - context->exponentC2 = RC_CHARGE_EXP_CLASS(context->rTotal * info->c2); + m_exponentC1 = RC_CHARGE_EXP_CLASS(info->rF * info->c1); + m_exponentC2 = RC_CHARGE_EXP_CLASS(m_rTotal * info->c2); break; case DISC_OP_AMP_FILTER_IS_BAND_PASS_1M | DISC_OP_AMP_IS_NORTON: if (info->r2 == 0) - context->rTotal = info->r1; + m_rTotal = info->r1; else - context->rTotal = RES_2_PARALLEL(info->r1, info->r2); + m_rTotal = RES_2_PARALLEL(info->r1, info->r2); case DISC_OP_AMP_FILTER_IS_BAND_PASS_1M: { - double fc = 1.0 / (2 * M_PI * sqrt(context->rTotal * info->rF * info->c1 * info->c2)); - double d = (info->c1 + info->c2) / sqrt(info->rF / context->rTotal * info->c1 * info->c2); - double gain = -info->rF / context->rTotal * info->c2 / (info->c1 + info->c2); + double fc = 1.0 / (2 * M_PI * sqrt(m_rTotal * info->rF * info->c1 * info->c2)); + double d = (info->c1 + info->c2) / sqrt(info->rF / m_rTotal * info->c1 * info->c2); + double gain = -info->rF / m_rTotal * info->c2 / (info->c1 + info->c2); - calculate_filter2_coefficients(this, fc, d, DISC_FILTER_BANDPASS, - &context->a1, &context->a2, - &context->b0, &context->b1, &context->b2); - context->b0 *= gain; - context->b1 *= gain; - context->b2 *= gain; + calculate_filter2_coefficients(this, fc, d, DISC_FILTER_BANDPASS, m_fc); + m_fc.b0 *= gain; + m_fc.b1 *= gain; + m_fc.b2 *= gain; - if (context->is_norton) - context->vRef = (info->vP - OP_AMP_NORTON_VBE) / info->r3 * info->rF; + if (m_is_norton) + m_vRef = (info->vP - OP_AMP_NORTON_VBE) / info->r3 * info->rF; else - context->vRef = info->vRef; + m_vRef = info->vRef; break; } case DISC_OP_AMP_FILTER_IS_BAND_PASS_0 | DISC_OP_AMP_IS_NORTON: - context->exponentC1 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r1, info->r2 + info->r3 + info->r4) * info->c1); - context->exponentC2 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r1 + info->r2, info->r3 + info->r4) * info->c2); - context->exponentC3 = RC_CHARGE_EXP_CLASS((info->r1 + info->r2 + info->r3 + info->r4) * info->c3); + m_exponentC1 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r1, info->r2 + info->r3 + info->r4) * info->c1); + m_exponentC2 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r1 + info->r2, info->r3 + info->r4) * info->c2); + m_exponentC3 = RC_CHARGE_EXP_CLASS((info->r1 + info->r2 + info->r3 + info->r4) * info->c3); break; case DISC_OP_AMP_FILTER_IS_HIGH_PASS_0 | DISC_OP_AMP_IS_NORTON: - context->exponentC1 = RC_CHARGE_EXP_CLASS(info->r1 * info->c1); + m_exponentC1 = RC_CHARGE_EXP_CLASS(info->r1 * info->c1); break; } /* At startup there is no charge on the caps and output is 0V in relation to vRef. */ - context->vC1 = 0; - context->vC1b = 0; - context->vC2 = 0; - context->vC3 = 0; + m_vC1 = 0; + m_vC1b = 0; + m_vC2 = 0; + m_vC3 = 0; this->output[0] = info->vRef; } @@ -469,8 +451,6 @@ DISCRETE_RESET(dst_op_amp_filt) DISCRETE_STEP( dst_rc_circuit_1 ) { - DISCRETE_DECLARE_CONTEXT(dst_rc_circuit_1) - if (DST_RC_CIRCUIT_1__IN0 == 0) if (DST_RC_CIRCUIT_1__IN1 == 0) /* cap is floating and does not change charge */ @@ -479,41 +459,39 @@ DISCRETE_STEP( dst_rc_circuit_1 ) else { /* cap is discharged */ - context->v_cap -= context->v_cap * context->exp_2; - this->output[0] = context->v_cap * context->v_drop; + m_v_cap -= m_v_cap * m_exp_2; + this->output[0] = m_v_cap * m_v_drop; } else if (DST_RC_CIRCUIT_1__IN1 == 0) { /* cap is charged */ - context->v_cap += (5.0 - context->v_cap) * context->exp_1; + m_v_cap += (5.0 - m_v_cap) * m_exp_1; /* output is pulled to ground */ this->output[0] = 0; } else { /* cap is charged slightly less */ - context->v_cap += (context->v_charge_1_2 - context->v_cap) * context->exp_1_2; - this->output[0] = context->v_cap * context->v_drop; + m_v_cap += (m_v_charge_1_2 - m_v_cap) * m_exp_1_2; + this->output[0] = m_v_cap * m_v_drop; } } DISCRETE_RESET( dst_rc_circuit_1 ) { - DISCRETE_DECLARE_CONTEXT(dst_rc_circuit_1) - /* the charging voltage across the cap based on in2*/ - context->v_drop = RES_VOLTAGE_DIVIDER(CD4066_R_ON, CD4066_R_ON + DST_RC_CIRCUIT_1__R); - context->v_charge_1_2 = 5.0 * context->v_drop; - context->v_cap = 0; + m_v_drop = RES_VOLTAGE_DIVIDER(CD4066_R_ON, CD4066_R_ON + DST_RC_CIRCUIT_1__R); + m_v_charge_1_2 = 5.0 * m_v_drop; + m_v_cap = 0; /* precalculate charging exponents */ /* discharge cap - in1 = 0, in2 = 1*/ - context->exp_2 = RC_CHARGE_EXP_CLASS((CD4066_R_ON + DST_RC_CIRCUIT_1__R) * DST_RC_CIRCUIT_1__C); + m_exp_2 = RC_CHARGE_EXP_CLASS((CD4066_R_ON + DST_RC_CIRCUIT_1__R) * DST_RC_CIRCUIT_1__C); /* charge cap - in1 = 1, in2 = 0 */ - context->exp_1 = RC_CHARGE_EXP_CLASS(CD4066_R_ON * DST_RC_CIRCUIT_1__C); + m_exp_1 = RC_CHARGE_EXP_CLASS(CD4066_R_ON * DST_RC_CIRCUIT_1__C); /* charge cap - in1 = 1, in2 = 1 */ - context->exp_1_2 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(CD4066_R_ON, CD4066_R_ON + DST_RC_CIRCUIT_1__R) * DST_RC_CIRCUIT_1__C); + m_exp_1_2 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(CD4066_R_ON, CD4066_R_ON + DST_RC_CIRCUIT_1__R) * DST_RC_CIRCUIT_1__C); /* starts at 0 until cap starts charging */ this->output[0] = 0; @@ -537,15 +515,13 @@ DISCRETE_RESET( dst_rc_circuit_1 ) DISCRETE_STEP(dst_rcdisc) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - - switch (context->state) + switch (m_state) { case 0: /* waiting for trigger */ if(DST_RCDISC__ENABLE) { - context->state = 1; - context->t = 0; + m_state = 1; + m_t = 0; } this->output[0] = 0; break; @@ -553,24 +529,22 @@ DISCRETE_STEP(dst_rcdisc) case 1: if (DST_RCDISC__ENABLE) { - this->output[0] = DST_RCDISC__IN * exp(context->t / context->exponent0); - context->t += this->sample_time(); + this->output[0] = DST_RCDISC__IN * exp(m_t / m_exponent0); + m_t += this->sample_time(); } else { - context->state = 0; + m_state = 0; } } } DISCRETE_RESET(dst_rcdisc) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - this->output[0] = 0; - context->state = 0; - context->t = 0; - context->exponent0=-1.0 * DST_RCDISC__R * DST_RCDISC__C; + m_state = 0; + m_t = 0; + m_exponent0=-1.0 * DST_RCDISC__R * DST_RCDISC__C; } @@ -596,28 +570,24 @@ DISCRETE_RESET(dst_rcdisc) DISCRETE_STEP(dst_rcdisc2) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - double diff; /* Works differently to other as we are always on, no enable */ /* exponential based in difference between input/output */ diff = ((DST_RCDISC2__ENABLE == 0) ? DST_RCDISC2__IN0 : DST_RCDISC2__IN1) - this->output[0]; - diff = diff - (diff * ((DST_RCDISC2__ENABLE == 0) ? context->exponent0 : context->exponent1)); + diff = diff - (diff * ((DST_RCDISC2__ENABLE == 0) ? m_exponent0 : m_exponent1)); this->output[0] += diff; } DISCRETE_RESET(dst_rcdisc2) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - this->output[0] = 0; - context->state = 0; - context->t = 0; - context->exponent0 = RC_DISCHARGE_EXP_CLASS(DST_RCDISC2__R0 * DST_RCDISC2__C); - context->exponent1 = RC_DISCHARGE_EXP_CLASS(DST_RCDISC2__R1 * DST_RCDISC2__C); + m_state = 0; + m_t = 0; + m_exponent0 = RC_DISCHARGE_EXP_CLASS(DST_RCDISC2__R0 * DST_RCDISC2__C); + m_exponent1 = RC_DISCHARGE_EXP_CLASS(DST_RCDISC2__R1 * DST_RCDISC2__C); } /************************************************************************ @@ -642,8 +612,6 @@ DISCRETE_RESET(dst_rcdisc2) DISCRETE_STEP(dst_rcdisc3) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - double diff; /* Exponential based in difference between input/output */ @@ -651,34 +619,34 @@ DISCRETE_STEP(dst_rcdisc3) if(DST_RCDISC3__ENABLE) { diff = DST_RCDISC3__IN - this->output[0]; - if (context->v_diode > 0) + if (m_v_diode > 0) { if (diff > 0) { - diff = diff * context->exponent0; + diff = diff * m_exponent0; } - else if (diff < -context->v_diode) + else if (diff < -m_v_diode) { - diff = diff * context->exponent1; + diff = diff * m_exponent1; } else { - diff = diff * context->exponent0; + diff = diff * m_exponent0; } } else { if (diff < 0) { - diff = diff * context->exponent0; + diff = diff * m_exponent0; } - else if (diff > -context->v_diode) + else if (diff > -m_v_diode) { - diff = diff * context->exponent1; + diff = diff * m_exponent1; } else { - diff = diff * context->exponent0; + diff = diff * m_exponent0; } } this->output[0] += diff; @@ -691,15 +659,13 @@ DISCRETE_STEP(dst_rcdisc3) DISCRETE_RESET(dst_rcdisc3) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - this->output[0] = 0; - context->state = 0; - context->t = 0; - context->v_diode = DST_RCDISC3__DJV; - context->exponent0 = RC_CHARGE_EXP_CLASS(DST_RCDISC3__R1 * DST_RCDISC3__C); - context->exponent1 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(DST_RCDISC3__R1, DST_RCDISC3__R2) * DST_RCDISC3__C); + m_state = 0; + m_t = 0; + m_v_diode = DST_RCDISC3__DJV; + m_exponent0 = RC_CHARGE_EXP_CLASS(DST_RCDISC3__R1 * DST_RCDISC3__C); + m_exponent1 = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(DST_RCDISC3__R1, DST_RCDISC3__R2) * DST_RCDISC3__C); } @@ -727,8 +693,6 @@ DISCRETE_RESET(dst_rcdisc3) DISCRETE_STEP(dst_rcdisc4) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc4) - int inp1 = (DST_RCDISC4__IN == 0) ? 0 : 1; if (DST_RCDISC4__ENABLE == 0) @@ -737,29 +701,27 @@ DISCRETE_STEP(dst_rcdisc4) return; } - switch (context->type) + switch (m_type) { case 1: case 3: - context->vC1 += ((context->v[inp1] - context->vC1) * context->exp[inp1]); - this->output[0] = context->vC1; + m_vC1 += ((m_v[inp1] - m_vC1) * m_exp[inp1]); + this->output[0] = m_vC1; break; } /* clip output */ - if (this->output[0] > context->max_out) this->output[0] = context->max_out; + if (this->output[0] > m_max_out) this->output[0] = m_max_out; if (this->output[0] < 0) this->output[0] = 0; } DISCRETE_RESET( dst_rcdisc4) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc4) - double v, i, r, rT; - context->type = 0; + m_type = 0; /* some error checking. */ - if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && context->type == 1)) + if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && m_type == 1)) { this->device->discrete_log("Invalid component values in NODE_%d.\n", this->index()); return; @@ -775,13 +737,13 @@ DISCRETE_RESET( dst_rcdisc4) return; } - context->vC1 = 0; + m_vC1 = 0; /* store type as integer */ - context->type = (int)DST_RCDISC4__TYPE; + m_type = (int)DST_RCDISC4__TYPE; /* setup the maximum op-amp output. */ - context->max_out = DST_RCDISC4__VP - OP_AMP_VP_RAIL_OFFSET; + m_max_out = DST_RCDISC4__VP - OP_AMP_VP_RAIL_OFFSET; - switch (context->type) + switch (m_type) { case 1: /* We will simulate this as a voltage divider with 2 states depending @@ -793,16 +755,16 @@ DISCRETE_RESET( dst_rcdisc4) r = RES_2_PARALLEL(DST_RCDISC4__R1, DST_RCDISC4__R3); rT = DST_RCDISC4__R2 + r; i = v / rT; - context->v[1] = i * r + .5; + m_v[1] = i * r + .5; rT = RES_2_PARALLEL(DST_RCDISC4__R2, r); - context->exp[1] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); + m_exp[1] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); /* When the input is 0, R1 is out of circuit. */ rT = DST_RCDISC4__R2 + DST_RCDISC4__R3; i = v / rT; - context->v[0] = i * DST_RCDISC4__R3 + .5; + m_v[0] = i * DST_RCDISC4__R3 + .5; rT = RES_2_PARALLEL(DST_RCDISC4__R2, DST_RCDISC4__R3); - context->exp[0] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); + m_exp[0] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); break; case 3: @@ -811,13 +773,13 @@ DISCRETE_RESET( dst_rcdisc4) * resistance, so we will just use .5k in series with R1. */ r = 500.0 + DST_RCDISC4__R1; - context->v[1] = RES_VOLTAGE_DIVIDER(r, DST_RCDISC4__R2) * (5.0 - 0.5); + m_v[1] = RES_VOLTAGE_DIVIDER(r, DST_RCDISC4__R2) * (5.0 - 0.5); rT = RES_2_PARALLEL(r, DST_RCDISC4__R2); - context->exp[1] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); + m_exp[1] = RC_CHARGE_EXP_CLASS(rT * DST_RCDISC4__C1); /* When the input is 0, R1 is out of circuit. */ - context->v[0] = 0; - context->exp[0] = RC_CHARGE_EXP_CLASS(DST_RCDISC4__R2 * DST_RCDISC4__C1); + m_v[0] = 0; + m_exp[0] = RC_CHARGE_EXP_CLASS(DST_RCDISC4__R2 * DST_RCDISC4__C1); break; } } @@ -839,8 +801,6 @@ DISCRETE_RESET( dst_rcdisc4) DISCRETE_STEP( dst_rcdisc5) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - double diff,u; /* Exponential based in difference between input/output */ @@ -849,20 +809,20 @@ DISCRETE_STEP( dst_rcdisc5) if( u < 0) u = 0; - diff = u - context->v_cap; + diff = u - m_v_cap; if(DST_RCDISC5__ENABLE) { if(diff < 0) - diff = diff * context->exponent0; + diff = diff * m_exponent0; - context->v_cap += diff; - this->output[0] = context->v_cap; + m_v_cap += diff; + this->output[0] = m_v_cap; } else { if(diff > 0) - context->v_cap = u; + m_v_cap = u; this->output[0] = 0; } @@ -870,14 +830,12 @@ DISCRETE_STEP( dst_rcdisc5) DISCRETE_RESET( dst_rcdisc5) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc) - this->output[0] = 0; - context->state = 0; - context->t = 0; - context->v_cap = 0; - context->exponent0 = RC_CHARGE_EXP_CLASS(DST_RCDISC5__R * DST_RCDISC5__C); + m_state = 0; + m_t = 0; + m_v_cap = 0; + m_exponent0 = RC_CHARGE_EXP_CLASS(DST_RCDISC5__R * DST_RCDISC5__C); } @@ -907,13 +865,11 @@ DISCRETE_RESET( dst_rcdisc5) DISCRETE_STEP(dst_rcdisc_mod) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc_mod) - double diff, v_cap, u, vD; int mod_state, mod1_state, mod2_state; /* Exponential based in difference between input/output */ - v_cap = context->v_cap; + v_cap = m_v_cap; mod1_state = DST_RCDISC_MOD__IN1 > 0.5; mod2_state = DST_RCDISC_MOD__IN2 > 0.6; @@ -922,59 +878,57 @@ DISCRETE_STEP(dst_rcdisc_mod) u = mod1_state ? 0 : DST_RCDISC_MOD__VP; /* Clamp */ diff = u - v_cap; - vD = diff * context->vd_gain[mod_state]; + vD = diff * m_vd_gain[mod_state]; if (vD < -0.6) { diff = u + 0.6 - v_cap; - diff -= diff * context->exp_low[mod1_state]; + diff -= diff * m_exp_low[mod1_state]; v_cap += diff; this->output[0] = mod2_state ? 0 : -0.6; } else { - diff -= diff * context->exp_high[mod_state]; + diff -= diff * m_exp_high[mod_state]; v_cap += diff; /* neglecting current through R3 drawn by next8 node */ - this->output[0] = mod2_state ? 0: (u - v_cap) * context->gain[mod1_state]; + this->output[0] = mod2_state ? 0: (u - v_cap) * m_gain[mod1_state]; } - context->v_cap = v_cap; + m_v_cap = v_cap; } DISCRETE_RESET(dst_rcdisc_mod) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc_mod) - double rc[2], rc2[2]; /* pre-calculate fixed values */ /* DST_RCDISC_MOD__IN1 <= 0.5 */ rc[0] = DST_RCDISC_MOD__R1 + DST_RCDISC_MOD__R2; if (rc[0] < 1) rc[0] = 1; - context->exp_low[0] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * rc[0]); - context->gain[0] = RES_VOLTAGE_DIVIDER(rc[0], DST_RCDISC_MOD__R4); + m_exp_low[0] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * rc[0]); + m_gain[0] = RES_VOLTAGE_DIVIDER(rc[0], DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN1 > 0.5 */ rc[1] = DST_RCDISC_MOD__R2; if (rc[1] < 1) rc[1] = 1; - context->exp_low[1] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * rc[1]); - context->gain[1] = RES_VOLTAGE_DIVIDER(rc[1], DST_RCDISC_MOD__R4); + m_exp_low[1] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * rc[1]); + m_gain[1] = RES_VOLTAGE_DIVIDER(rc[1], DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN2 <= 0.6 */ rc2[0] = DST_RCDISC_MOD__R4; /* DST_RCDISC_MOD__IN2 > 0.6 */ rc2[1] = RES_2_PARALLEL(DST_RCDISC_MOD__R3, DST_RCDISC_MOD__R4); /* DST_RCDISC_MOD__IN1 <= 0.5 && DST_RCDISC_MOD__IN2 <= 0.6 */ - context->exp_high[0] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[0] + rc2[0])); - context->vd_gain[0] = RES_VOLTAGE_DIVIDER(rc[0], rc2[0]); + m_exp_high[0] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[0] + rc2[0])); + m_vd_gain[0] = RES_VOLTAGE_DIVIDER(rc[0], rc2[0]); /* DST_RCDISC_MOD__IN1 > 0.5 && DST_RCDISC_MOD__IN2 <= 0.6 */ - context->exp_high[1] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[1] + rc2[0])); - context->vd_gain[1] = RES_VOLTAGE_DIVIDER(rc[1], rc2[0]); + m_exp_high[1] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[1] + rc2[0])); + m_vd_gain[1] = RES_VOLTAGE_DIVIDER(rc[1], rc2[0]); /* DST_RCDISC_MOD__IN1 <= 0.5 && DST_RCDISC_MOD__IN2 > 0.6 */ - context->exp_high[2] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[0] + rc2[1])); - context->vd_gain[2] = RES_VOLTAGE_DIVIDER(rc[0], rc2[1]); + m_exp_high[2] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[0] + rc2[1])); + m_vd_gain[2] = RES_VOLTAGE_DIVIDER(rc[0], rc2[1]); /* DST_RCDISC_MOD__IN1 > 0.5 && DST_RCDISC_MOD__IN2 > 0.6 */ - context->exp_high[3] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[1] + rc2[1])); - context->vd_gain[3] = RES_VOLTAGE_DIVIDER(rc[1], rc2[1]); + m_exp_high[3] = RC_DISCHARGE_EXP_CLASS(DST_RCDISC_MOD__C * (rc[1] + rc2[1])); + m_vd_gain[3] = RES_VOLTAGE_DIVIDER(rc[1], rc2[1]); - context->v_cap = 0; + m_v_cap = 0; this->output[0] = 0; } @@ -996,19 +950,17 @@ DISCRETE_RESET(dst_rcdisc_mod) DISCRETE_STEP(dst_rcfilter) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter) - - if (EXPECTED(context->is_fast)) - this->output[0] += ((DST_RCFILTER__VIN - this->output[0]) * context->exponent); + if (EXPECTED(m_is_fast)) + this->output[0] += ((DST_RCFILTER__VIN - this->output[0]) * m_exponent); else { - if (UNEXPECTED(context->has_rc_nodes)) + if (UNEXPECTED(m_has_rc_nodes)) { double rc = DST_RCFILTER__R * DST_RCFILTER__C; - if (rc != context->rc) + if (rc != m_rc) { - context->rc = rc; - context->exponent = RC_CHARGE_EXP_CLASS(rc); + m_rc = rc; + m_exponent = RC_CHARGE_EXP_CLASS(rc); } } @@ -1016,26 +968,24 @@ DISCRETE_STEP(dst_rcfilter) /* Next Value = PREV + (INPUT_VALUE - PREV)*(1-(EXP(-TIMEDELTA/RC))) */ /************************************************************************/ - context->vCap += ((DST_RCFILTER__VIN - this->output[0]) * context->exponent); - this->output[0] = context->vCap + DST_RCFILTER__VREF; + m_vCap += ((DST_RCFILTER__VIN - this->output[0]) * m_exponent); + this->output[0] = m_vCap + DST_RCFILTER__VREF; } } DISCRETE_RESET(dst_rcfilter) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter) - - context->has_rc_nodes = this->input_is_node() & 0x6; - context->rc = DST_RCFILTER__R * DST_RCFILTER__C; - context->exponent = RC_CHARGE_EXP_CLASS(context->rc); - context->vCap = 0; + m_has_rc_nodes = this->input_is_node() & 0x6; + m_rc = DST_RCFILTER__R * DST_RCFILTER__C; + m_exponent = RC_CHARGE_EXP_CLASS(m_rc); + m_vCap = 0; this->output[0] = 0; /* FIXME --> we really need another class here */ - if (!context->has_rc_nodes && DST_RCFILTER__VREF == 0) - context->is_fast = 1; + if (!m_has_rc_nodes && DST_RCFILTER__VREF == 0) + m_is_fast = 1; else - context->is_fast = 0; + m_is_fast = 0; } /************************************************************************ @@ -1068,8 +1018,6 @@ DISCRETE_RESET(dst_rcfilter) // FIXME: This needs optimization ! DISCRETE_STEP(dst_rcfilter_sw) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter_sw) - int i; int bits = (int)DST_RCFILTER_SW__SWITCH; double us = 0; @@ -1083,24 +1031,24 @@ DISCRETE_STEP(dst_rcfilter_sw) this->output[0] = vIn; break; case 1: - context->vCap[0] += (vIn - context->vCap[0]) * context->exp0; - this->output[0] = context->vCap[0] + (vIn - context->vCap[0]) * context->factor; + m_vCap[0] += (vIn - m_vCap[0]) * m_exp0; + this->output[0] = m_vCap[0] + (vIn - m_vCap[0]) * m_factor; break; case 2: - context->vCap[1] += (vIn - context->vCap[1]) * context->exp1; - this->output[0] = context->vCap[1] + (vIn - context->vCap[1]) * context->factor; + m_vCap[1] += (vIn - m_vCap[1]) * m_exp1; + this->output[0] = m_vCap[1] + (vIn - m_vCap[1]) * m_factor; break; default: for (i = 0; i < 4; i++) { if (( bits & (1 << i)) != 0) - us += context->vCap[i]; + us += m_vCap[i]; } - this->output[0] = context->f1[bits] * vIn + context->f2[bits] * us; + this->output[0] = m_f1[bits] * vIn + m_f2[bits] * us; for (i = 0; i < 4; i++) { if (( bits & (1 << i)) != 0) - context->vCap[i] += (this->output[0] - context->vCap[i]) * context->exp[i]; + m_vCap[i] += (this->output[0] - m_vCap[i]) * m_exp[i]; } } } @@ -1112,14 +1060,12 @@ DISCRETE_STEP(dst_rcfilter_sw) DISCRETE_RESET(dst_rcfilter_sw) { - DISCRETE_DECLARE_CONTEXT(dst_rcfilter_sw) - int i, bits; for (i = 0; i < 4; i++) { - context->vCap[i] = 0; - context->exp[i] = RC_CHARGE_EXP_CLASS( CD4066_ON_RES * DST_RCFILTER_SW__C(i)); + m_vCap[i] = 0; + m_exp[i] = RC_CHARGE_EXP_CLASS( CD4066_ON_RES * DST_RCFILTER_SW__C(i)); } for (bits=0; bits < 15; bits++) @@ -1131,15 +1077,15 @@ DISCRETE_RESET(dst_rcfilter_sw) if (( bits & (1 << i)) != 0) rs += DST_RCFILTER_SW__R; } - context->f1[bits] = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES); - context->f2[bits] = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs); + m_f1[bits] = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES); + m_f2[bits] = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs); } /* fast cases */ - context->exp0 = RC_CHARGE_EXP_CLASS((CD4066_ON_RES + DST_RCFILTER_SW__R) * DST_RCFILTER_SW__C(0)); - context->exp1 = RC_CHARGE_EXP_CLASS((CD4066_ON_RES + DST_RCFILTER_SW__R) * DST_RCFILTER_SW__C(1)); - context->factor = RES_VOLTAGE_DIVIDER(DST_RCFILTER_SW__R, CD4066_ON_RES); + m_exp0 = RC_CHARGE_EXP_CLASS((CD4066_ON_RES + DST_RCFILTER_SW__R) * DST_RCFILTER_SW__C(0)); + m_exp1 = RC_CHARGE_EXP_CLASS((CD4066_ON_RES + DST_RCFILTER_SW__R) * DST_RCFILTER_SW__C(1)); + m_factor = RES_VOLTAGE_DIVIDER(DST_RCFILTER_SW__R, CD4066_ON_RES); this->output[0] = 0; } @@ -1184,35 +1130,33 @@ DISCRETE_RESET(dst_rcfilter_sw) DISCRETE_STEP( dst_rcintegrate) { - DISCRETE_DECLARE_CONTEXT(dst_rcintegrate) - double diff, u, iQ, iQc, iC, RG, vE; double vP; u = DST_RCINTEGRATE__IN1; vP = DST_RCINTEGRATE__VP; - if ( u - 0.7 < context->vCap * context->gain_r1_r2) + if ( u - 0.7 < m_vCap * m_gain_r1_r2) { /* discharge .... */ - diff = 0.0 - context->vCap; - iC = context->c_exp1 * diff; /* iC */ - diff -= diff * context->exp_exponent1; - context->vCap += diff; + diff = 0.0 - m_vCap; + iC = m_c_exp1 * diff; /* iC */ + diff -= diff * m_exp_exponent1; + m_vCap += diff; iQ = 0; - vE = context->vCap * context->gain_r1_r2; + vE = m_vCap * m_gain_r1_r2; RG = vE / iC; } else { /* charging */ - diff = (vP - context->vCE) * context->f - context->vCap; - iC = 0.0 - context->c_exp0 * diff; /* iC */ - diff -= diff * context->exp_exponent0; - context->vCap += diff; - iQ = iC + (iC * DST_RCINTEGRATE__R1 + context->vCap) / DST_RCINTEGRATE__R2; - RG = (vP - context->vCE) / iQ; - vE = (RG - DST_RCINTEGRATE__R3) / RG * (vP - context->vCE); + diff = (vP - m_vCE) * m_f - m_vCap; + iC = 0.0 - m_c_exp0 * diff; /* iC */ + diff -= diff * m_exp_exponent0; + m_vCap += diff; + iQ = iC + (iC * DST_RCINTEGRATE__R1 + m_vCap) / DST_RCINTEGRATE__R2; + RG = (vP - m_vCE) / iQ; + vE = (RG - DST_RCINTEGRATE__R3) / RG * (vP - m_vCE); } @@ -1220,20 +1164,20 @@ DISCRETE_STEP( dst_rcintegrate) if (u > 0.7 + vE) vE = u - 0.7; iQc = EM_IC(u - vE); - context->vCE = MIN(vP - 0.1, vP - RG * iQc); + m_vCE = MIN(vP - 0.1, vP - RG * iQc); /* Avoid oscillations * The method tends to largely overshoot - no wonder without * iterative solution approximation */ - context->vCE = MAX(context->vCE, 0.1 ); - context->vCE = 0.1 * context->vCE + 0.9 * (vP - vE - iQ * DST_RCINTEGRATE__R3); + m_vCE = MAX(m_vCE, 0.1 ); + m_vCE = 0.1 * m_vCE + 0.9 * (vP - vE - iQ * DST_RCINTEGRATE__R3); - switch (context->type) + switch (m_type) { case DISC_RC_INTEGRATE_TYPE1: - this->output[0] = context->vCap; + this->output[0] = m_vCap; break; case DISC_RC_INTEGRATE_TYPE2: this->output[0] = vE; @@ -1243,30 +1187,29 @@ DISCRETE_STEP( dst_rcintegrate) break; } } + DISCRETE_RESET(dst_rcintegrate) { - DISCRETE_DECLARE_CONTEXT(dst_rcintegrate) - double r; double dt = this->sample_time(); - context->type = DST_RCINTEGRATE__TYPE; + m_type = DST_RCINTEGRATE__TYPE; - context->vCap = 0; - context->vCE = 0; + m_vCap = 0; + m_vCE = 0; /* pre-calculate fixed values */ - context->gain_r1_r2 = RES_VOLTAGE_DIVIDER(DST_RCINTEGRATE__R1, DST_RCINTEGRATE__R2); + m_gain_r1_r2 = RES_VOLTAGE_DIVIDER(DST_RCINTEGRATE__R1, DST_RCINTEGRATE__R2); r = DST_RCINTEGRATE__R1 / DST_RCINTEGRATE__R2 * DST_RCINTEGRATE__R3 + DST_RCINTEGRATE__R1 + DST_RCINTEGRATE__R3; - context->f = RES_VOLTAGE_DIVIDER(DST_RCINTEGRATE__R3, DST_RCINTEGRATE__R2); - context->exponent0 = -1.0 * r * context->f * DST_RCINTEGRATE__C; - context->exponent1 = -1.0 * (DST_RCINTEGRATE__R1 + DST_RCINTEGRATE__R2) * DST_RCINTEGRATE__C; - context->exp_exponent0 = exp(dt / context->exponent0); - context->exp_exponent1 = exp(dt / context->exponent1); - context->c_exp0 = DST_RCINTEGRATE__C / context->exponent0 * context->exp_exponent0; - context->c_exp1 = DST_RCINTEGRATE__C / context->exponent1 * context->exp_exponent1; + m_f = RES_VOLTAGE_DIVIDER(DST_RCINTEGRATE__R3, DST_RCINTEGRATE__R2); + m_exponent0 = -1.0 * r * m_f * DST_RCINTEGRATE__C; + m_exponent1 = -1.0 * (DST_RCINTEGRATE__R1 + DST_RCINTEGRATE__R2) * DST_RCINTEGRATE__C; + m_exp_exponent0 = exp(dt / m_exponent0); + m_exp_exponent1 = exp(dt / m_exponent1); + m_c_exp0 = DST_RCINTEGRATE__C / m_exponent0 * m_exp_exponent0; + m_c_exp1 = DST_RCINTEGRATE__C / m_exponent1 * m_exp_exponent1; this->output[0] = 0; } @@ -1289,8 +1232,6 @@ DISCRETE_RESET(dst_rcintegrate) DISCRETE_STEP(dst_sallen_key) { - DISCRETE_DECLARE_CONTEXT(dst_filter2) - double gain = 1.0; if (DST_SALLEN_KEY__ENABLE == 0.0) @@ -1298,18 +1239,17 @@ DISCRETE_STEP(dst_sallen_key) gain = 0.0; } - this->output[0] = -context->a1 * context->y1 - context->a2 * context->y2 + - context->b0 * gain * DST_SALLEN_KEY__INP0 + context->b1 * context->x1 + context->b2 * context->x2; + this->output[0] = -m_fc.a1 * m_fc.y1 - m_fc.a2 * m_fc.y2 + + m_fc.b0 * gain * DST_SALLEN_KEY__INP0 + m_fc.b1 * m_fc.x1 + m_fc.b2 * m_fc.x2; - context->x2 = context->x1; - context->x1 = gain * DST_SALLEN_KEY__INP0; - context->y2 = context->y1; - context->y1 = this->output[0]; + m_fc.x2 = m_fc.x1; + m_fc.x1 = gain * DST_SALLEN_KEY__INP0; + m_fc.y2 = m_fc.y1; + m_fc.y1 = this->output[0]; } DISCRETE_RESET(dst_sallen_key) { - DISCRETE_DECLARE_CONTEXT(dst_filter2) DISCRETE_DECLARE_INFO(discrete_op_amp_filt_info) double freq, q; @@ -1324,9 +1264,7 @@ DISCRETE_RESET(dst_sallen_key) fatalerror("Unknown sallen key filter type"); } - calculate_filter2_coefficients(this, freq, 1.0 / q, DISC_FILTER_LOWPASS, - &context->a1, &context->a2, - &context->b0, &context->b1, &context->b2); + calculate_filter2_coefficients(this, freq, 1.0 / q, DISC_FILTER_LOWPASS, m_fc); this->output[0] = 0; } @@ -1401,8 +1339,6 @@ DISCRETE_RESET(dst_rcdiscN) DISCRETE_STEP(dst_rcdiscN) { - DISCRETE_DECLARE_CONTEXT(dst_filter1) - double gain = 1.0; if (DST_RCDISCN__ENABLE == 0.0) @@ -1412,13 +1348,13 @@ DISCRETE_STEP(dst_rcdiscN) /* A rise in the input signal results in an instant charge, */ /* else discharge through the RC to zero */ - if (gain* DST_RCDISCN__IN > context->x1) + if (gain* DST_RCDISCN__IN > m_x1) this->output[0] = gain* DST_RCDISCN__IN; else - this->output[0] = -context->a1*context->y1; + this->output[0] = -m_a1*m_y1; - context->x1 = gain* DST_RCDISCN__IN; - context->y1 = this->output[0]; + m_x1 = gain* DST_RCDISCN__IN; + m_y1 = this->output[0]; } @@ -1445,29 +1381,26 @@ DISCRETE_STEP(dst_rcdiscN) DISCRETE_STEP(dst_rcdisc2N) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc2) - double input = ((DST_RCDISC2N__ENABLE == 0) ? DST_RCDISC2N__IN0 : DST_RCDISC2N__IN1); if (DST_RCDISC2N__ENABLE == 0) - this->output[0] = -context->a1_0*context->y1 + context->b0_0*input + context->b1_0*context->x1; + this->output[0] = -m_fc0.a1*m_y1 + m_fc0.b0*input + m_fc0.b1 * m_x1; else - this->output[0] = -context->a1_1*context->y1 + context->b0_1*input + context->b1_1*context->x1; + this->output[0] = -m_fc1.a1*m_y1 + m_fc1.b0*input + m_fc1.b1*m_x1; - context->x1 = input; - context->y1 = this->output[0]; + m_x1 = input; + m_y1 = this->output[0]; } DISCRETE_RESET(dst_rcdisc2N) { - DISCRETE_DECLARE_CONTEXT(dst_rcdisc2) double f1,f2; f1 = 1.0 / (2 * M_PI * DST_RCDISC2N__R0 * DST_RCDISC2N__C); f2 = 1.0 / (2 * M_PI * DST_RCDISC2N__R1 * DST_RCDISC2N__C); - calculate_filter1_coefficients(this, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0); - calculate_filter1_coefficients(this, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1); + calculate_filter1_coefficients(this, f1, DISC_FILTER_LOWPASS, m_fc0); + calculate_filter1_coefficients(this, f2, DISC_FILTER_LOWPASS, m_fc1); /* Initialize the object */ this->output[0] = 0; diff --git a/src/emu/sound/disc_flt.h b/src/emu/sound/disc_flt.h new file mode 100644 index 00000000000..a2a5435ee19 --- /dev/null +++ b/src/emu/sound/disc_flt.h @@ -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__ */ diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c index 7bfcef14c90..66f7c50705a 100644 --- a/src/emu/sound/disc_inp.c +++ b/src/emu/sound/disc_inp.c @@ -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(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; -} diff --git a/src/emu/sound/disc_mth.c b/src/emu/sound/disc_mth.c index a42efcfff8f..333bb0270e7 100644 --- a/src/emu/sound/disc_mth.c +++ b/src/emu/sound/disc_mth.c @@ -95,17 +95,15 @@ DISCRETE_STEP(dst_adder) DISCRETE_STEP(dst_comp_adder) { - DISCRETE_DECLARE_CONTEXT(dst_comp_adder) int select; select = (int)DST_COMP_ADDER__SELECT; assert(select < 256); - this->output[0] = context->total[select]; + this->output[0] = m_total[select]; } DISCRETE_RESET(dst_comp_adder) { - DISCRETE_DECLARE_CONTEXT(dst_comp_adder) DISCRETE_DECLARE_INFO(discrete_comp_adder_table) int i, bit; @@ -120,26 +118,26 @@ DISCRETE_RESET(dst_comp_adder) switch (info->type) { case DISC_COMP_P_CAPACITOR: - context->total[i] = info->cDefault; + m_total[i] = info->cDefault; for(bit = 0; bit < bit_length; bit++) { if (i & (1 << bit)) - context->total[i] += info->c[bit]; + m_total[i] += info->c[bit]; } break; case DISC_COMP_P_RESISTOR: - context->total[i] = (info->cDefault != 0) ? 1.0 / info->cDefault : 0; + m_total[i] = (info->cDefault != 0) ? 1.0 / info->cDefault : 0; for(bit = 0; bit < bit_length; bit++) { if ((i & (1 << bit)) && (info->c[bit] != 0)) - context->total[i] += 1.0 / info->c[bit]; + m_total[i] += 1.0 / info->c[bit]; } - if (context->total[i] != 0) - context->total[i] = 1.0 / context->total[i]; + if (m_total[i] != 0) + m_total[i] = 1.0 / m_total[i]; break; } } - this->output[0] = context->total[0]; + this->output[0] = m_total[0]; } /************************************************************************ @@ -180,20 +178,18 @@ DISCRETE_STEP(dst_clamp) DISCRETE_STEP(dst_dac_r1) { - DISCRETE_DECLARE_CONTEXT(dst_dac_r1) - int data = (int)DST_DAC_R1__DATA; - double v = context->v_step[data]; + double v = m_v_step[data]; double x_time = DST_DAC_R1__DATA - data; - double last_v = context->last_v; + double last_v = m_last_v; - context->last_v = v; + m_last_v = v; if (x_time > 0) v = x_time * (v - last_v) + last_v; /* Filter if needed, else just output voltage */ - if (context->has_c_filter) + if (m_has_c_filter) { double out = this->output[0]; double v_diff = v - out; @@ -202,7 +198,7 @@ DISCRETE_STEP(dst_dac_r1) this->output[0] = v; else { - out += v_diff * context->exponent; + out += v_diff * m_exponent; this->output[0] = out; } } @@ -212,7 +208,6 @@ DISCRETE_STEP(dst_dac_r1) DISCRETE_RESET(dst_dac_r1) { - DISCRETE_DECLARE_CONTEXT(dst_dac_r1) DISCRETE_DECLARE_INFO(discrete_dac_r1_ladder) int bit; @@ -222,7 +217,7 @@ DISCRETE_RESET(dst_dac_r1) double i_bias; double v_on = DST_DAC_R1__VON; - context->last_v = 0; + m_last_v = 0; /* Calculate the Millman current of the bias circuit */ if (info->rBias > 0) @@ -263,12 +258,12 @@ DISCRETE_RESET(dst_dac_r1) if (info->cFilter > 0) { - context->has_c_filter = 1; + m_has_c_filter = 1; /* Setup filter constant */ - context->exponent = RC_CHARGE_EXP_CLASS(r_total * info->cFilter); + m_exponent = RC_CHARGE_EXP_CLASS(r_total * info->cFilter); } else - context->has_c_filter = 0; + m_has_c_filter = 0; /* pre-calculate all possible values to speed up step routine */ for(int i = 0; i < total_steps; i++) @@ -291,7 +286,7 @@ DISCRETE_RESET(dst_dac_r1) i_total += i_bit; } } - context->v_step[i] = i_total * r_total; + m_v_step[i] = i_total * r_total; } } @@ -310,14 +305,12 @@ DISCRETE_RESET(dst_dac_r1) DISCRETE_STEP(dst_diode_mix) { - DISCRETE_DECLARE_CONTEXT(dst_diode_mix) - double val, max = 0; int addr; - for (addr = 0; addr < context->size; addr++) + for (addr = 0; addr < m_size; addr++) { - val = DST_DIODE_MIX__INP(addr) - context->v_junction[addr]; + val = DST_DIODE_MIX__INP(addr) - m_v_junction[addr]; if (val > max) max = val; } if (max < 0) max = 0; @@ -326,25 +319,24 @@ DISCRETE_STEP(dst_diode_mix) DISCRETE_RESET(dst_diode_mix) { - DISCRETE_DECLARE_CONTEXT(dst_diode_mix) DISCRETE_DECLARE_INFO(double) int addr; - context->size = this->active_inputs() - DST_DIODE_MIX_INP_OFFSET; - assert(context->size <= 8); + m_size = this->active_inputs() - DST_DIODE_MIX_INP_OFFSET; + assert(m_size <= 8); - for (addr = 0; addr < context->size; addr++) + for (addr = 0; addr < m_size; addr++) { if (info == NULL) { /* setup default junction voltage */ - context->v_junction[addr] = 0.5; + m_v_junction[addr] = 0.5; } else { /* use supplied junction voltage */ - context->v_junction[addr] = *info++; + m_v_junction[addr] = *info++; } } this->step(); @@ -454,7 +446,6 @@ static int dst_trigger_function(int trig0, int trig1, int trig2, int function) DISCRETE_STEP(dst_integrate) { - DISCRETE_DECLARE_CONTEXT(dst_integrate) DISCRETE_DECLARE_INFO(discrete_integrate_info) int trig0, trig1; @@ -469,14 +460,14 @@ DISCRETE_STEP(dst_integrate) /* This forces the cap to completely charge, * and the output to go to it's max value. */ - this->output[0] = context->v_max_out; + this->output[0] = m_v_max_out; return; } - this->output[0] -= context->change; + this->output[0] -= m_change; break; case DISC_INTEGRATE_OP_AMP_1 | DISC_OP_AMP_IS_NORTON: - i_neg = context->v_max_in / info->r1; + i_neg = m_v_max_in / info->r1; i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2; if (i_pos < 0) i_pos = 0; this->output[0] += (i_pos - i_neg) / this->sample_rate() / info->c; @@ -485,39 +476,38 @@ DISCRETE_STEP(dst_integrate) case DISC_INTEGRATE_OP_AMP_2 | DISC_OP_AMP_IS_NORTON: trig0 = (int)DST_INTEGRATE__TRG0; trig1 = (int)DST_INTEGRATE__TRG1; - i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->v_max_in_d / info->r1 : 0; - i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->v_max_in / info->r2 : 0; - i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->v_max_in_d / info->r3 : 0; + i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? m_v_max_in_d / info->r1 : 0; + i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? m_v_max_in / info->r2 : 0; + i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? m_v_max_in_d / info->r3 : 0; this->output[0] += (i_pos - i_neg) / this->sample_rate() / info->c; break; } /* Clip the output. */ if (this->output[0] < 0) this->output[0] = 0; - if (this->output[0] > context->v_max_out) this->output[0] = context->v_max_out; + if (this->output[0] > m_v_max_out) this->output[0] = m_v_max_out; } DISCRETE_RESET(dst_integrate) { - DISCRETE_DECLARE_CONTEXT(dst_integrate) DISCRETE_DECLARE_INFO(discrete_integrate_info) double i, v; if (info->type & DISC_OP_AMP_IS_NORTON) { - context->v_max_out = info->vP - OP_AMP_NORTON_VBE; - context->v_max_in = info->v1 - OP_AMP_NORTON_VBE; - context->v_max_in_d = context->v_max_in - OP_AMP_NORTON_VBE; + m_v_max_out = info->vP - OP_AMP_NORTON_VBE; + m_v_max_in = info->v1 - OP_AMP_NORTON_VBE; + m_v_max_in_d = m_v_max_in - OP_AMP_NORTON_VBE; } else { - context->v_max_out = info->vP - OP_AMP_VP_RAIL_OFFSET; + m_v_max_out = info->vP - OP_AMP_VP_RAIL_OFFSET; v = info->v1 * info->r3 / (info->r2 + info->r3); /* vRef */ v = info->v1 - v; /* actual charging voltage */ i = v / info->r1; - context->change = i / this->sample_rate() / info->c; + m_change = i / this->sample_rate() / info->c; } this->output[0] = 0; } @@ -550,19 +540,17 @@ DISCRETE_STEP(dst_logic_inv) DISCRETE_STEP(dst_bits_decode) { - DISCRETE_DECLARE_CONTEXT(dst_bits_decode) - int new_val = DST_BITS_DECODE__IN; - int last_val = context->last_val; - int last_had_x_time = context->last_had_x_time; + int last_val = m_last_val; + int last_had_x_time = m_last_had_x_time; if (last_val != new_val || last_had_x_time) { int i, new_bit, last_bit, last_bit_had_x_time, bit_changed; double x_time = DST_BITS_DECODE__IN - new_val; - int from = context->from; - int count = context->count; - int decode_x_time = context->decode_x_time; + int from = m_from; + int count = m_count; + int decode_x_time = m_decode_x_time; int has_x_time = x_time > 0 ? 1 : 0; double out = 0; double v_out = DST_BITS_DECODE__VOUT; @@ -599,26 +587,24 @@ DISCRETE_STEP(dst_bits_decode) this->output[i] = out; if (has_x_time && bit_changed) /* set */ - context->last_had_x_time |= 1 << (i + from); + m_last_had_x_time |= 1 << (i + from); else /* clear */ - context->last_had_x_time &= ~(1 << (i + from)); + m_last_had_x_time &= ~(1 << (i + from)); } - context->last_val = new_val; + m_last_val = new_val; } } DISCRETE_RESET(dst_bits_decode) { - DISCRETE_DECLARE_CONTEXT(dst_bits_decode) - - context->from = DST_BITS_DECODE__FROM; - context->count = DST_BITS_DECODE__TO - context->from + 1; + m_from = DST_BITS_DECODE__FROM; + m_count = DST_BITS_DECODE__TO - m_from + 1; if (DST_BITS_DECODE__VOUT == 0) - context->decode_x_time = 1; + m_decode_x_time = 1; else - context->decode_x_time = 0; - context->last_had_x_time = 0; + m_decode_x_time = 0; + m_last_had_x_time = 0; this->step(); } @@ -754,24 +740,20 @@ DISCRETE_STEP(dst_logic_nxor) DISCRETE_STEP(dst_logic_dff) { - DISCRETE_DECLARE_CONTEXT(dst_flipflop) - int clk = (int)DST_LOGIC_DFF__CLOCK; if (DST_LOGIC_DFF__RESET) this->output[0] = 0; else if (DST_LOGIC_DFF__SET) this->output[0] = 1; - else if (!context->last_clk && clk) /* low to high */ + else if (!m_last_clk && clk) /* low to high */ this->output[0] = DST_LOGIC_DFF__DATA; - context->last_clk = clk; + m_last_clk = clk; } DISCRETE_RESET(dst_logic_dff) { - DISCRETE_DECLARE_CONTEXT(dst_flipflop) - - context->last_clk = 0; + m_last_clk = 0; this->output[0] = 0; } @@ -795,8 +777,6 @@ DISCRETE_RESET(dst_logic_dff) DISCRETE_STEP(dst_logic_jkff) { - DISCRETE_DECLARE_CONTEXT(dst_flipflop) - int clk = (int)DST_LOGIC_JKFF__CLOCK; int j = (int)DST_LOGIC_JKFF__J; int k = (int)DST_LOGIC_JKFF__K; @@ -805,7 +785,7 @@ DISCRETE_STEP(dst_logic_jkff) this->output[0] = 0; else if (DST_LOGIC_JKFF__SET) this->output[0] = 1; - else if (context->last_clk && !clk) /* high to low */ + else if (m_last_clk && !clk) /* high to low */ { if (!j) { @@ -824,14 +804,12 @@ DISCRETE_STEP(dst_logic_jkff) this->output[0] = !(int)this->output[0]; } } - context->last_clk = clk; + m_last_clk = clk; } DISCRETE_RESET(dst_logic_jkff) { - DISCRETE_DECLARE_CONTEXT(dst_flipflop) - - context->last_clk = 0; + m_last_clk = 0; this->output[0] = 0; } @@ -848,20 +826,18 @@ DISCRETE_RESET(dst_logic_jkff) DISCRETE_STEP(dst_logic_shift) { - DISCRETE_DECLARE_CONTEXT(dst_logic_shift) - double cycles; double ds_clock; int clock = 0, inc = 0; int input_bit = (DST_LOGIC_SHIFT__IN != 0) ? 1 : 0; ds_clock = DST_LOGIC_SHIFT__CLK; - if (context->clock_type == DISC_CLK_IS_FREQ) + if (m_clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if in reset. */ - cycles = (context->t_left + this->sample_time()) * ds_clock; + cycles = (m_t_left + this->sample_time()) * ds_clock; inc = (int)cycles; - context->t_left = (cycles - inc) / ds_clock; + m_t_left = (cycles - inc) / ds_clock; } else { @@ -869,24 +845,24 @@ DISCRETE_STEP(dst_logic_shift) } /* If reset enabled then set output to the reset value. No x_time in reset. */ - if(((DST_LOGIC_SHIFT__RESET == 0) ? 0 : 1) == context->reset_on_high) + if(((DST_LOGIC_SHIFT__RESET == 0) ? 0 : 1) == m_reset_on_high) { - context->shift_data = 0; + m_shift_data = 0; this->output[0] = 0; return; } /* increment clock */ - switch (context->clock_type) + switch (m_clock_type) { case DISC_CLK_ON_F_EDGE: case DISC_CLK_ON_R_EDGE: /* See if the clock has toggled to the proper edge */ clock = (clock != 0); - if (context->last != clock) + if (m_last != clock) { - context->last = clock; - if (context->clock_type == clock) + m_last = clock; + if (m_clock_type == clock) { /* Toggled */ inc = 1; @@ -902,38 +878,36 @@ DISCRETE_STEP(dst_logic_shift) if (inc > 0) { - if (context->shift_r) + if (m_shift_r) { - context->shift_data >>= 1; - context->shift_data |= input_bit << ((int)DST_LOGIC_SHIFT__SIZE - 1); + m_shift_data >>= 1; + m_shift_data |= input_bit << ((int)DST_LOGIC_SHIFT__SIZE - 1); inc--; - context->shift_data >>= inc; + m_shift_data >>= inc; } else { - context->shift_data <<= 1; - context->shift_data |= input_bit; + m_shift_data <<= 1; + m_shift_data |= input_bit; inc--; - context->shift_data <<= inc; + m_shift_data <<= inc; } - context->shift_data &= context->bit_mask; + m_shift_data &= m_bit_mask; } - this->output[0] = context->shift_data; + this->output[0] = m_shift_data; } DISCRETE_RESET(dst_logic_shift) { - DISCRETE_DECLARE_CONTEXT(dst_logic_shift) + m_bit_mask = (1 << (int)DST_LOGIC_SHIFT__SIZE) - 1; + m_clock_type = (int)DST_LOGIC_SHIFT__OPTIONS & DISC_CLK_MASK; + m_reset_on_high = ((int)DST_LOGIC_SHIFT__OPTIONS & DISC_LOGIC_SHIFT__RESET_H) ? 1 : 0; + m_shift_r = ((int)DST_LOGIC_SHIFT__OPTIONS & DISC_LOGIC_SHIFT__RIGHT) ? 1 : 0; - context->bit_mask = (1 << (int)DST_LOGIC_SHIFT__SIZE) - 1; - context->clock_type = (int)DST_LOGIC_SHIFT__OPTIONS & DISC_CLK_MASK; - context->reset_on_high = ((int)DST_LOGIC_SHIFT__OPTIONS & DISC_LOGIC_SHIFT__RESET_H) ? 1 : 0; - context->shift_r = ((int)DST_LOGIC_SHIFT__OPTIONS & DISC_LOGIC_SHIFT__RIGHT) ? 1 : 0; - - context->t_left = 0; - context->last = 0; - context->shift_data = 0; + m_t_left = 0; + m_last = 0; + m_shift_data = 0; this->output[0] = 0; } @@ -1019,7 +993,6 @@ DISCRETE_STEP(dst_lookup_table) DISCRETE_STEP(dst_mixer) { - DISCRETE_DECLARE_CONTEXT(dst_mixer) DISCRETE_DECLARE_INFO(discrete_mixer_desc) double v, vTemp, r_total, rTemp, rTemp2 = 0; @@ -1027,24 +1000,24 @@ DISCRETE_STEP(dst_mixer) int bit, connected; /* put commonly used stuff in local variables for speed */ - int r_node_bit_flag = context->r_node_bit_flag; - int c_bit_flag = context->c_bit_flag; + int r_node_bit_flag = m_r_node_bit_flag; + int c_bit_flag = m_c_bit_flag; int bit_mask = 1; int has_rF = (info->rF != 0); - int type = context->type; + int type = m_type; double v_ref = info->vRef; double rI = info->rI; if (EXPECTED(DST_MIXER__ENABLE)) { - r_total = context->r_total; + r_total = m_r_total; - if (UNEXPECTED(context->r_node_bit_flag != 0)) + if (UNEXPECTED(m_r_node_bit_flag != 0)) { /* loop and do any high pass filtering for connected caps */ /* but first see if there is an r_node for the current path */ /* if so, then the exponents need to be re-calculated */ - for (bit = 0; bit < context->size; bit++) + for (bit = 0; bit < m_size; bit++) { rTemp = info->r[bit]; connected = 1; @@ -1054,12 +1027,12 @@ DISCRETE_STEP(dst_mixer) if (r_node_bit_flag & bit_mask) { /* a node has the possibility of being disconnected from the circuit. */ - if (*context->r_node[bit] == 0) + if (*m_r_node[bit] == 0) connected = 0; else { /* value currently holds resistance */ - rTemp += *context->r_node[bit]; + rTemp += *m_r_node[bit]; r_total += 1.0 / rTemp; /* is there a capacitor? */ if (c_bit_flag & bit_mask) @@ -1082,10 +1055,10 @@ DISCRETE_STEP(dst_mixer) break; } /* Re-calculate exponent if resistor is a node and has changed value */ - if (*context->r_node[bit] != context->r_last[bit]) + if (*m_r_node[bit] != m_r_last[bit]) { - context->exponent_rc[bit] = RC_CHARGE_EXP_CLASS(rTemp2 * info->c[bit]); - context->r_last[bit] = *context->r_node[bit]; + m_exponent_rc[bit] = RC_CHARGE_EXP_CLASS(rTemp2 * info->c[bit]); + m_r_last[bit] = *m_r_node[bit]; } } } @@ -1097,8 +1070,8 @@ DISCRETE_STEP(dst_mixer) if (c_bit_flag & bit_mask) { /* do input high pass filtering if needed. */ - context->v_cap[bit] += (vTemp - v_ref - context->v_cap[bit]) * context->exponent_rc[bit]; - vTemp -= context->v_cap[bit]; + m_v_cap[bit] += (vTemp - v_ref - m_v_cap[bit]) * m_exponent_rc[bit]; + vTemp -= m_v_cap[bit]; } i += ((type == DISC_MIXER_IS_OP_AMP) ? v_ref - vTemp : vTemp) / rTemp; } @@ -1108,15 +1081,15 @@ DISCRETE_STEP(dst_mixer) else if (UNEXPECTED(c_bit_flag != 0)) { /* no r_nodes, so just do high pass filtering */ - for (bit = 0; bit < context->size; bit++) + for (bit = 0; bit < m_size; bit++) { vTemp = DST_MIXER__IN(bit); if (c_bit_flag & (1 << bit)) { /* do input high pass filtering if needed. */ - context->v_cap[bit] += (vTemp - v_ref - context->v_cap[bit]) * context->exponent_rc[bit]; - vTemp -= context->v_cap[bit]; + m_v_cap[bit] += (vTemp - v_ref - m_v_cap[bit]) * m_exponent_rc[bit]; + vTemp -= m_v_cap[bit]; } i += ((type == DISC_MIXER_IS_OP_AMP) ? v_ref - vTemp : vTemp) / info->r[bit]; } @@ -1126,12 +1099,12 @@ DISCRETE_STEP(dst_mixer) /* no r_nodes or c_nodes, mixing only */ if (UNEXPECTED(type == DISC_MIXER_IS_OP_AMP)) { - for (bit = 0; bit < context->size; bit++) + for (bit = 0; bit < m_size; bit++) i += ( v_ref - DST_MIXER__IN(bit) ) / info->r[bit]; } else { - for (bit = 0; bit < context->size; bit++) + for (bit = 0; bit < m_size; bit++) i += DST_MIXER__IN(bit) / info->r[bit]; } } @@ -1146,7 +1119,7 @@ DISCRETE_STEP(dst_mixer) v = i * ((type == DISC_MIXER_IS_OP_AMP) ? info->rF : r_total); if (UNEXPECTED(type == DISC_MIXER_IS_OP_AMP_WITH_RI)) - v = v_ref + (context->gain * (v_ref - v)); + v = v_ref + (m_gain * (v_ref - v)); /* Do the low pass filtering for cF */ if (EXPECTED(info->cF != 0)) @@ -1154,17 +1127,17 @@ DISCRETE_STEP(dst_mixer) if (UNEXPECTED(r_node_bit_flag != 0)) { /* Re-calculate exponent if resistor nodes are used */ - context->exponent_c_f = RC_CHARGE_EXP_CLASS(r_total * info->cF); + m_exponent_c_f = RC_CHARGE_EXP_CLASS(r_total * info->cF); } - context->v_cap_f += (v - v_ref - context->v_cap_f) * context->exponent_c_f; - v = context->v_cap_f; + m_v_cap_f += (v - v_ref - m_v_cap_f) * m_exponent_c_f; + v = m_v_cap_f; } /* Do the high pass filtering for cAmp */ if (EXPECTED(info->cAmp != 0)) { - context->v_cap_amp += (v - context->v_cap_amp) * context->exponent_c_amp; - v -= context->v_cap_amp; + m_v_cap_amp += (v - m_v_cap_amp) * m_exponent_c_amp; + v -= m_v_cap_amp; } this->output[0] = v * info->gain; } @@ -1177,7 +1150,6 @@ DISCRETE_STEP(dst_mixer) DISCRETE_RESET(dst_mixer) { - DISCRETE_DECLARE_CONTEXT(dst_mixer) DISCRETE_DECLARE_INFO(discrete_mixer_desc) discrete_base_node *r_node; @@ -1186,24 +1158,24 @@ DISCRETE_RESET(dst_mixer) double rTemp = 0; /* link to r_node outputs */ - context->r_node_bit_flag = 0; + m_r_node_bit_flag = 0; for (bit = 0; bit < 8; bit++) { r_node = this->device->discrete_find_node(info->r_node[bit]); if (r_node != NULL) { - context->r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]); - context->r_node_bit_flag |= 1 << bit; + m_r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]); + m_r_node_bit_flag |= 1 << bit; } else - context->r_node[bit] = NULL; + m_r_node[bit] = NULL; /* flag any caps */ if (info->c[bit] != 0) - context->c_bit_flag |= 1 << bit; + m_c_bit_flag |= 1 << bit; } - context->size = this->active_inputs() - 1; + m_size = this->active_inputs() - 1; /* * THERE IS NO ERROR CHECKING!!!!!!!!! @@ -1211,28 +1183,28 @@ DISCRETE_RESET(dst_mixer) * then you deserve a crash. */ - context->type = info->type; + m_type = info->type; if ((info->type == DISC_MIXER_IS_OP_AMP) && (info->rI != 0)) - context->type = DISC_MIXER_IS_OP_AMP_WITH_RI; + m_type = DISC_MIXER_IS_OP_AMP_WITH_RI; /* * Calculate the total of all resistors in parallel. * This is the combined resistance of the voltage sources. * Also calculate the exponents while we are here. */ - context->r_total = 0; - for(bit = 0; bit < context->size; bit++) + m_r_total = 0; + for(bit = 0; bit < m_size; bit++) { if ((info->r[bit] != 0) && !info->r_node[bit] ) { - context->r_total += 1.0 / info->r[bit]; + m_r_total += 1.0 / info->r[bit]; } - context->v_cap[bit] = 0; - context->exponent_rc[bit] = 0; + m_v_cap[bit] = 0; + m_exponent_rc[bit] = 0; if ((info->c[bit] != 0) && !info->r_node[bit]) { - switch (context->type) + switch (m_type) { case DISC_MIXER_IS_RESISTOR: /* is there an rF? */ @@ -1250,35 +1222,35 @@ DISCRETE_RESET(dst_mixer) break; } /* Setup filter constants */ - context->exponent_rc[bit] = RC_CHARGE_EXP_CLASS(rTemp * info->c[bit]); + m_exponent_rc[bit] = RC_CHARGE_EXP_CLASS(rTemp * info->c[bit]); } } if (info->rF != 0) { - if (context->type == DISC_MIXER_IS_RESISTOR) context->r_total += 1.0 / info->rF; + if (m_type == DISC_MIXER_IS_RESISTOR) m_r_total += 1.0 / info->rF; } - if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->r_total += 1.0 / info->rI; + if (m_type == DISC_MIXER_IS_OP_AMP_WITH_RI) m_r_total += 1.0 / info->rI; - context->v_cap_f = 0; - context->exponent_c_f = 0; + m_v_cap_f = 0; + m_exponent_c_f = 0; if (info->cF != 0) { /* Setup filter constants */ - context->exponent_c_f = RC_CHARGE_EXP_CLASS(((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->r_total)) * info->cF); + m_exponent_c_f = RC_CHARGE_EXP_CLASS(((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / m_r_total)) * info->cF); } - context->v_cap_amp = 0; - context->exponent_c_amp = 0; + m_v_cap_amp = 0; + m_exponent_c_amp = 0; if (info->cAmp != 0) { /* Setup filter constants */ /* We will use 100k ohms as an average final stage impedance. */ /* Your amp/speaker system will have more effect on incorrect filtering then any value used here. */ - context->exponent_c_amp = RC_CHARGE_EXP_CLASS(RES_K(100) * info->cAmp); + m_exponent_c_amp = RC_CHARGE_EXP_CLASS(RES_K(100) * info->cAmp); } - if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->gain = info->rF / info->rI; + if (m_type == DISC_MIXER_IS_OP_AMP_WITH_RI) m_gain = info->rF / info->rI; this->output[0] = 0; } @@ -1300,12 +1272,10 @@ DISCRETE_RESET(dst_mixer) DISCRETE_STEP(dst_multiplex) { - DISCRETE_DECLARE_CONTEXT(dst_size) - int addr; addr = DST_MULTIPLEX__ADDR; /* FP to INT */ - if ((addr >= 0) && (addr < context->size)) + if ((addr >= 0) && (addr < m_size)) { this->output[0] = DST_MULTIPLEX__INP(addr); } @@ -1318,9 +1288,7 @@ DISCRETE_STEP(dst_multiplex) DISCRETE_RESET(dst_multiplex) { - DISCRETE_DECLARE_CONTEXT(dst_size) - - context->size = this->active_inputs() - 1; + m_size = this->active_inputs() - 1; this->step(); } @@ -1346,44 +1314,42 @@ DISCRETE_RESET(dst_multiplex) DISCRETE_STEP(dst_oneshot) { - DISCRETE_DECLARE_CONTEXT(dst_oneshot) - int trigger = (DST_ONESHOT__TRIG != 0); /* If the state is triggered we will need to countdown later */ - int do_count = context->state; + int do_count = m_state; if (UNEXPECTED(DST_ONESHOT__RESET)) { /* Hold in Reset */ this->output[0] = 0; - context->state = 0; + m_state = 0; } else { /* are we at an edge? */ - if (UNEXPECTED(trigger != context->last_trig)) + if (UNEXPECTED(trigger != m_last_trig)) { /* There has been a trigger edge */ - context->last_trig = trigger; + m_last_trig = trigger; /* Is it the proper edge trigger */ - if ((context->type & DISC_ONESHOT_REDGE) ? trigger : !trigger) + if ((m_type & DISC_ONESHOT_REDGE) ? trigger : !trigger) { - if (!context->state) + if (!m_state) { /* We have first trigger */ - context->state = 1; - this->output[0] = (context->type & DISC_OUT_ACTIVE_LOW) ? 0 : DST_ONESHOT__AMP; - context->countdown = DST_ONESHOT__WIDTH; + m_state = 1; + this->output[0] = (m_type & DISC_OUT_ACTIVE_LOW) ? 0 : DST_ONESHOT__AMP; + m_countdown = DST_ONESHOT__WIDTH; } else { /* See if we retrigger */ - if (context->type & DISC_ONESHOT_RETRIG) + if (m_type & DISC_ONESHOT_RETRIG) { /* Retrigger */ - context->countdown = DST_ONESHOT__WIDTH; + m_countdown = DST_ONESHOT__WIDTH; do_count = 0; } } @@ -1392,12 +1358,12 @@ DISCRETE_STEP(dst_oneshot) if (UNEXPECTED(do_count)) { - context->countdown -= this->sample_time(); - if(context->countdown <= 0.0) + m_countdown -= this->sample_time(); + if(m_countdown <= 0.0) { - this->output[0] = (context->type & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; - context->countdown = 0; - context->state = 0; + this->output[0] = (m_type & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; + m_countdown = 0; + m_state = 0; } } } @@ -1406,15 +1372,13 @@ DISCRETE_STEP(dst_oneshot) DISCRETE_RESET(dst_oneshot) { - DISCRETE_DECLARE_CONTEXT(dst_oneshot) + m_countdown = 0; + m_state = 0; - context->countdown = 0; - context->state = 0; + m_last_trig = 0; + m_type = DST_ONESHOT__TYPE; - context->last_trig = 0; - context->type = DST_ONESHOT__TYPE; - - this->output[0] = (context->type & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; + this->output[0] = (m_type & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; } @@ -1439,26 +1403,24 @@ DISCRETE_RESET(dst_oneshot) DISCRETE_STEP(dst_ramp) { - DISCRETE_DECLARE_CONTEXT(dst_ramp) - if(DST_RAMP__ENABLE) { - if (!context->last_en) + if (!m_last_en) { - context->last_en = 1; + m_last_en = 1; this->output[0] = DST_RAMP__START; } - if(context->dir ? DST_RAMP__DIR : !DST_RAMP__DIR) this->output[0]+=context->step; - else this->output[0] -= context->step; + if(m_dir ? DST_RAMP__DIR : !DST_RAMP__DIR) this->output[0]+=m_step; + else this->output[0] -= m_step; /* Clamp to min/max */ - if(context->dir ? (this->output[0] < DST_RAMP__START) + if(m_dir ? (this->output[0] < DST_RAMP__START) : (this->output[0] > DST_RAMP__START)) this->output[0] = DST_RAMP__START; - if(context->dir ? (this->output[0] > DST_RAMP__END) + if(m_dir ? (this->output[0] > DST_RAMP__END) : (this->output[0] < DST_RAMP__END)) this->output[0] = DST_RAMP__END; } else { - context->last_en = 0; + m_last_en = 0; /* Disabled so clamp to output */ this->output[0] = DST_RAMP__CLAMP; } @@ -1466,12 +1428,10 @@ DISCRETE_STEP(dst_ramp) DISCRETE_RESET(dst_ramp) { - DISCRETE_DECLARE_CONTEXT(dst_ramp) - this->output[0] = DST_RAMP__CLAMP; - context->step = DST_RAMP__GRAD / this->sample_rate(); - context->dir = ((DST_RAMP__END - DST_RAMP__START) == abs(DST_RAMP__END - DST_RAMP__START)); - context->last_en = 0; + m_step = DST_RAMP__GRAD / this->sample_rate(); + m_dir = ((DST_RAMP__END - DST_RAMP__START) == abs(DST_RAMP__END - DST_RAMP__START)); + m_last_en = 0; } @@ -1490,17 +1450,15 @@ DISCRETE_RESET(dst_ramp) DISCRETE_STEP(dst_samphold) { - DISCRETE_DECLARE_CONTEXT(dst_samphold) - - switch(context->clocktype) + switch(m_clocktype) { case DISC_SAMPHOLD_REDGE: /* Clock the whole time the input is rising */ - if (DST_SAMPHOLD__CLOCK > context->last_input) this->output[0] = DST_SAMPHOLD__IN0; + if (DST_SAMPHOLD__CLOCK > m_last_input) this->output[0] = DST_SAMPHOLD__IN0; break; case DISC_SAMPHOLD_FEDGE: /* Clock the whole time the input is falling */ - if(DST_SAMPHOLD__CLOCK < context->last_input) this->output[0] = DST_SAMPHOLD__IN0; + if(DST_SAMPHOLD__CLOCK < m_last_input) this->output[0] = DST_SAMPHOLD__IN0; break; case DISC_SAMPHOLD_HLATCH: /* Output follows input if clock != 0 */ @@ -1515,17 +1473,15 @@ DISCRETE_STEP(dst_samphold) break; } /* Save the last value */ - context->last_input = DST_SAMPHOLD__CLOCK; + m_last_input = DST_SAMPHOLD__CLOCK; } DISCRETE_RESET(dst_samphold) { - DISCRETE_DECLARE_CONTEXT(dst_samphold) - this->output[0] = 0; - context->last_input = -1; + m_last_input = -1; /* Only stored in here to speed up and save casting in the step function */ - context->clocktype = (int)DST_SAMPHOLD__TYPE; + m_clocktype = (int)DST_SAMPHOLD__TYPE; this->step(); } @@ -1725,7 +1681,6 @@ DISCRETE_STEP(dst_transform) DISCRETE_STEP(dst_op_amp) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp) DISCRETE_DECLARE_INFO(discrete_op_amp_info) double i_pos = 0; @@ -1738,12 +1693,12 @@ DISCRETE_STEP(dst_op_amp) { case DISC_OP_AMP_IS_NORTON: /* work out neg pin current */ - if (context->has_r1) + if (m_has_r1) { i_neg = (DST_OP_AMP__INP0 - OP_AMP_NORTON_VBE) / info->r1; if (i_neg < 0) i_neg = 0; } - i_neg += context->i_fixed; + i_neg += m_i_fixed; /* work out neg pin current */ i_pos = (DST_OP_AMP__INP1 - OP_AMP_NORTON_VBE) / info->r2; @@ -1752,34 +1707,34 @@ DISCRETE_STEP(dst_op_amp) /* work out current across r4 */ i = i_pos - i_neg; - if (context->has_cap) + if (m_has_cap) { - if (context->has_r4) + if (m_has_r4) { /* voltage across r4 charging cap */ i *= info->r4; /* exponential charge */ - context->v_cap += (i - context->v_cap) * context->exponent; + m_v_cap += (i - m_v_cap) * m_exponent; } else /* linear charge */ - context->v_cap += i / context->exponent; - this->output[0] = context->v_cap; + m_v_cap += i / m_exponent; + this->output[0] = m_v_cap; } else - if (context->has_r4) + if (m_has_r4) this->output[0] = i * info->r4; else /* output just swings to rail when there is no r4 */ if (i > 0) - this->output[0] = context->v_max; + this->output[0] = m_v_max; else this->output[0] = 0; /* clamp output */ - if (this->output[0] > context->v_max) this->output[0] = context->v_max; + if (this->output[0] > m_v_max) this->output[0] = m_v_max; else if (this->output[0] < info->vN) this->output[0] = info->vN; - context->v_cap = this->output[0]; + m_v_cap = this->output[0]; break; default: @@ -1792,33 +1747,32 @@ DISCRETE_STEP(dst_op_amp) DISCRETE_RESET(dst_op_amp) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp) DISCRETE_DECLARE_INFO(discrete_op_amp_info) - context->has_r1 = info->r1 > 0; - context->has_r4 = info->r4 > 0; + m_has_r1 = info->r1 > 0; + m_has_r4 = info->r4 > 0; - context->v_max = info->vP - OP_AMP_NORTON_VBE; + m_v_max = info->vP - OP_AMP_NORTON_VBE; - context->v_cap = 0; + m_v_cap = 0; if (info->c > 0) { - context->has_cap = 1; + m_has_cap = 1; /* Setup filter constants */ - if (context->has_r4) + if (m_has_r4) { /* exponential charge */ - context->exponent = RC_CHARGE_EXP_CLASS(info->r4 * info->c); + m_exponent = RC_CHARGE_EXP_CLASS(info->r4 * info->c); } else /* linear charge */ - context->exponent = this->sample_rate() * info->c; + m_exponent = this->sample_rate() * info->c; } if (info->r3 > 0) - context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r3; + m_i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r3; else - context->i_fixed = 0; + m_i_fixed = 0; } @@ -1836,7 +1790,6 @@ DISCRETE_RESET(dst_op_amp) DISCRETE_STEP(dst_op_amp_1sht) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp_1sht) DISCRETE_DECLARE_INFO(discrete_op_amp_1sht_info) double i_pos; @@ -1844,48 +1797,47 @@ DISCRETE_STEP(dst_op_amp_1sht) double v; /* update trigger circuit */ - i_pos = (DST_OP_AMP_1SHT__TRIGGER - context->v_cap2) / info->r2; + i_pos = (DST_OP_AMP_1SHT__TRIGGER - m_v_cap2) / info->r2; i_pos += this->output[0] / info->r5; - context->v_cap2 += (DST_OP_AMP_1SHT__TRIGGER - context->v_cap2) * context->exponent2; + m_v_cap2 += (DST_OP_AMP_1SHT__TRIGGER - m_v_cap2) * m_exponent2; /* calculate currents and output */ - i_neg = (context->v_cap1 - OP_AMP_NORTON_VBE) / info->r3; + i_neg = (m_v_cap1 - OP_AMP_NORTON_VBE) / info->r3; if (i_neg < 0) i_neg = 0; - i_neg += context->i_fixed; + i_neg += m_i_fixed; - if (i_pos > i_neg) this->output[0] = context->v_max; + if (i_pos > i_neg) this->output[0] = m_v_max; else this->output[0] = info->vN; /* update c1 */ /* rough value of voltage at anode of diode if discharging */ v = this->output[0] + 0.6; - if (context->v_cap1 > this->output[0]) + if (m_v_cap1 > this->output[0]) { /* discharge */ - if (context->v_cap1 > v) + if (m_v_cap1 > v) /* immediate discharge through diode */ - context->v_cap1 = v; + m_v_cap1 = v; else /* discharge through r4 */ - context->v_cap1 += (this->output[0] - context->v_cap1) * context->exponent1d; + m_v_cap1 += (this->output[0] - m_v_cap1) * m_exponent1d; } else /* charge */ - context->v_cap1 += ((this->output[0] - OP_AMP_NORTON_VBE) * context->r34ratio + OP_AMP_NORTON_VBE - context->v_cap1) * context->exponent1c; + m_v_cap1 += ((this->output[0] - OP_AMP_NORTON_VBE) * m_r34ratio + OP_AMP_NORTON_VBE - m_v_cap1) * m_exponent1c; } DISCRETE_RESET(dst_op_amp_1sht) { - DISCRETE_DECLARE_CONTEXT(dst_op_amp_1sht) DISCRETE_DECLARE_INFO(discrete_op_amp_1sht_info) - context->exponent1c = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r3, info->r4) * info->c1); - context->exponent1d = RC_CHARGE_EXP_CLASS(info->r4 * info->c1); - context->exponent2 = RC_CHARGE_EXP_CLASS(info->r2 * info->c2); - context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r1; - context->v_cap1 = context->v_cap2 = 0; - context->v_max = info->vP - OP_AMP_NORTON_VBE; - context->r34ratio = info->r3 / (info->r3 + info->r4); + m_exponent1c = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r3, info->r4) * info->c1); + m_exponent1d = RC_CHARGE_EXP_CLASS(info->r4 * info->c1); + m_exponent2 = RC_CHARGE_EXP_CLASS(info->r2 * info->c2); + m_i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r1; + m_v_cap1 = m_v_cap2 = 0; + m_v_max = info->vP - OP_AMP_NORTON_VBE; + m_r34ratio = info->r3 / (info->r3 + info->r4); } @@ -1911,7 +1863,6 @@ DISCRETE_RESET(dst_op_amp_1sht) DISCRETE_STEP(dst_tvca_op_amp) { - DISCRETE_DECLARE_CONTEXT(dst_tvca_op_amp) DISCRETE_DECLARE_INFO(discrete_op_amp_tvca_info) int trig0, trig1, trig2, f3; @@ -1942,13 +1893,13 @@ DISCRETE_STEP(dst_tvca_op_amp) } /* Calculate current going in to - input. */ - i_neg = context->i_fixed + i2 + i3; + i_neg = m_i_fixed + i2 + i3; /* Update the c1 cap voltage. */ if (dst_trigger_function(trig0, trig1, trig2, info->f2)) { /* F2 is not grounding the circuit so we charge the cap. */ - context->v_cap1 += (context->v_trig[f3] - context->v_cap1) * context->exponent_c[f3]; + m_v_cap1 += (m_v_trig[f3] - m_v_cap1) * m_exponent_c[f3]; } else { @@ -1956,27 +1907,27 @@ DISCRETE_STEP(dst_tvca_op_amp) * So now the discharge rate is dependent upon F3. * If F3 is at ground then we discharge to 0V through r6. * If F3 is out of circuit then we discharge to OP_AMP_NORTON_VBE through r6+r7. */ - context->v_cap1 += ((f3 ? OP_AMP_NORTON_VBE : 0.0) - context->v_cap1) * context->exponent_d[f3]; + m_v_cap1 += ((f3 ? OP_AMP_NORTON_VBE : 0.0) - m_v_cap1) * m_exponent_d[f3]; } /* Calculate c1 current going in to + input. */ - i_pos = (context->v_cap1 - OP_AMP_NORTON_VBE) / context->r67; + i_pos = (m_v_cap1 - OP_AMP_NORTON_VBE) / m_r67; if ((i_pos < 0) || !f3) i_pos = 0; /* Update the c2 cap voltage and current. */ if (info->r9 != 0) { f3 = dst_trigger_function(trig0, trig1, trig2, info->f4); - context->v_cap2 += ((f3 ? context->v_trig2 : 0) - context->v_cap2) * context->exponent2[f3]; - i_pos += context->v_cap2 / info->r9; + m_v_cap2 += ((f3 ? m_v_trig2 : 0) - m_v_cap2) * m_exponent2[f3]; + i_pos += m_v_cap2 / info->r9; } /* Update the c3 cap voltage and current. */ if (info->r11 != 0) { f3 = dst_trigger_function(trig0, trig1, trig2, info->f5); - context->v_cap3 += ((f3 ? context->v_trig3 : 0) - context->v_cap3) * context->exponent3[f3]; - i_pos += context->v_cap3 / info->r11; + m_v_cap3 += ((f3 ? m_v_trig3 : 0) - m_v_cap3) * m_exponent3[f3]; + i_pos += m_v_cap3 / info->r11; } /* Calculate output current. */ @@ -1984,21 +1935,21 @@ DISCRETE_STEP(dst_tvca_op_amp) if (i_out < 0) i_out = 0; /* Convert to voltage for final output. */ - if (context->has_c4) + if (m_has_c4) { - if (context->has_r4) + if (m_has_r4) { /* voltage across r4 charging cap */ i_out *= info->r4; /* exponential charge */ - context->v_cap4 += (i_out - context->v_cap4) * context->exponent4; + m_v_cap4 += (i_out - m_v_cap4) * m_exponent4; } else /* linear charge */ - context->v_cap4 += i_out / context->exponent4; - if (context->v_cap4 < 0) - context->v_cap4 = 0; - this->output[0] = context->v_cap4; + m_v_cap4 += i_out / m_exponent4; + if (m_v_cap4 < 0) + m_v_cap4 = 0; + this->output[0] = m_v_cap4; } else this->output[0] = i_out * info->r4; @@ -2006,48 +1957,47 @@ DISCRETE_STEP(dst_tvca_op_amp) /* Clip the output if needed. */ - if (this->output[0] > context->v_out_max) this->output[0] = context->v_out_max; + if (this->output[0] > m_v_out_max) this->output[0] = m_v_out_max; } DISCRETE_RESET(dst_tvca_op_amp) { - DISCRETE_DECLARE_CONTEXT(dst_tvca_op_amp) DISCRETE_DECLARE_INFO(discrete_op_amp_tvca_info) - context->r67 = info->r6 + info->r7; + m_r67 = info->r6 + info->r7; - context->v_out_max = info->vP - OP_AMP_NORTON_VBE; + m_v_out_max = info->vP - OP_AMP_NORTON_VBE; /* This is probably overkill because R5 is usually much lower then r6 or r7, * but it is better to play it safe. */ - context->v_trig[0] = (info->v1 - 0.6) * RES_VOLTAGE_DIVIDER(info->r5, info->r6); - context->v_trig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r5, context->r67) + OP_AMP_NORTON_VBE; - context->i_fixed = context->v_out_max / info->r1; + m_v_trig[0] = (info->v1 - 0.6) * RES_VOLTAGE_DIVIDER(info->r5, info->r6); + m_v_trig[1] = (info->v1 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r5, m_r67) + OP_AMP_NORTON_VBE; + m_i_fixed = m_v_out_max / info->r1; - context->v_cap1 = 0; + m_v_cap1 = 0; /* Charge rate thru r5 */ /* There can be a different charge rates depending on function F3. */ - context->exponent_c[0] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r5, info->r6) * info->c1); - context->exponent_c[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r5, context->r67) * info->c1); + m_exponent_c[0] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r5, info->r6) * info->c1); + m_exponent_c[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r5, m_r67) * info->c1); /* Discharge rate thru r6 + r7 */ - context->exponent_d[1] = RC_CHARGE_EXP_CLASS(context->r67 * info->c1); + m_exponent_d[1] = RC_CHARGE_EXP_CLASS(m_r67 * info->c1); /* Discharge rate thru r6 */ if (info->r6 != 0) { - context->exponent_d[0] = RC_CHARGE_EXP_CLASS(info->r6 * info->c1); + m_exponent_d[0] = RC_CHARGE_EXP_CLASS(info->r6 * info->c1); } - context->v_cap2 = 0; - context->v_trig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r8, info->r9); - context->exponent2[0] = RC_CHARGE_EXP_CLASS(info->r9 * info->c2); - context->exponent2[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r8, info->r9) * info->c2); - context->v_cap3 = 0; - context->v_trig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r10, info->r11); - context->exponent3[0] = RC_CHARGE_EXP_CLASS(info->r11 * info->c3); - context->exponent3[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r10, info->r11) * info->c3); - context->v_cap4 = 0; - if (info->r4 != 0) context->has_r4 = 1; - if (info->c4 != 0) context->has_c4 = 1; - if (context->has_r4 && context->has_c4) - context->exponent4 = RC_CHARGE_EXP_CLASS(info->r4 * info->c4); + m_v_cap2 = 0; + m_v_trig2 = (info->v2 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r8, info->r9); + m_exponent2[0] = RC_CHARGE_EXP_CLASS(info->r9 * info->c2); + m_exponent2[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r8, info->r9) * info->c2); + m_v_cap3 = 0; + m_v_trig3 = (info->v3 - 0.6 - OP_AMP_NORTON_VBE) * RES_VOLTAGE_DIVIDER(info->r10, info->r11); + m_exponent3[0] = RC_CHARGE_EXP_CLASS(info->r11 * info->c3); + m_exponent3[1] = RC_CHARGE_EXP_CLASS(RES_2_PARALLEL(info->r10, info->r11) * info->c3); + m_v_cap4 = 0; + if (info->r4 != 0) m_has_r4 = 1; + if (info->c4 != 0) m_has_c4 = 1; + if (m_has_r4 && m_has_c4) + m_exponent4 = RC_CHARGE_EXP_CLASS(info->r4 * info->c4); this->step(); } diff --git a/src/emu/sound/disc_mth.h b/src/emu/sound/disc_mth.h new file mode 100644 index 00000000000..a20e60728cb --- /dev/null +++ b/src/emu/sound/disc_mth.h @@ -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__ */ diff --git a/src/emu/sound/disc_sys.c b/src/emu/sound/disc_sys.c index df8898b3ba8..8725d9a7bd0 100644 --- a/src/emu/sound/disc_sys.c +++ b/src/emu/sound/disc_sys.c @@ -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; -} diff --git a/src/emu/sound/disc_wav.c b/src/emu/sound/disc_wav.c index 4a382e45f98..088554db08f 100644 --- a/src/emu/sound/disc_wav.c +++ b/src/emu/sound/disc_wav.c @@ -56,23 +56,21 @@ static const int disc_7492_count[6] = {0x00, 0x01, 0x02, 0x04, 0x05, 0x06}; DISCRETE_STEP(dss_counter) { - DISCRETE_DECLARE_CONTEXT(dss_counter) - double cycles; double ds_clock; int clock = 0, inc = 0; - UINT32 last_count = context->last_count; /* it is different then output in 7492 */ + UINT32 last_count = m_last_count; /* it is different then output in 7492 */ double x_time = 0; UINT32 count = last_count; ds_clock = DSS_COUNTER__CLOCK; - if (UNEXPECTED(context->clock_type == DISC_CLK_IS_FREQ)) + if (UNEXPECTED(m_clock_type == DISC_CLK_IS_FREQ)) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + this->sample_time()) * ds_clock; + cycles = (m_t_left + this->sample_time()) * ds_clock; inc = (int)cycles; - context->t_left = (cycles - inc) / ds_clock; - if (inc) x_time = context->t_left / this->sample_time(); + m_t_left = (cycles - inc) / ds_clock; + if (inc) x_time = m_t_left / this->sample_time(); } else { @@ -85,7 +83,7 @@ DISCRETE_STEP(dss_counter) /* If reset enabled then set output to the reset value. No x_time in reset. */ if (UNEXPECTED(DSS_COUNTER__RESET)) { - context->last_count = (int)DSS_COUNTER__INIT; + m_last_count = (int)DSS_COUNTER__INIT; this->output[0] = (int)DSS_COUNTER__INIT; return; } @@ -96,16 +94,16 @@ DISCRETE_STEP(dss_counter) */ if (EXPECTED(DSS_COUNTER__ENABLE)) { - switch (context->clock_type) + switch (m_clock_type) { case DISC_CLK_ON_F_EDGE: case DISC_CLK_ON_R_EDGE: /* See if the clock has toggled to the proper edge */ clock = (clock != 0); - if (context->last_clock != clock) + if (m_last_clock != clock) { - context->last_clock = clock; - if (context->clock_type == clock) + m_last_clock = clock; + if (m_clock_type == clock) { /* Toggled */ inc = 1; @@ -123,27 +121,27 @@ DISCRETE_STEP(dss_counter) if (DSS_COUNTER__DIR) { count += inc; - while (count > context->max) + while (count > m_max) { - count -= context->diff; + count -= m_diff; } } else { count -= inc; - while (count < context->min) + while (count < m_min) { - count += context->diff; + count += m_diff; } } - context->last_count = count; - this->output[0] = context->is_7492 ? disc_7492_count[count] : count; + m_last_count = count; + this->output[0] = m_is_7492 ? disc_7492_count[count] : count; if (UNEXPECTED(count != last_count)) { /* the x_time is only output if the output changed. */ - switch (context->out_type) + switch (m_out_type) { case DISC_OUT_HAS_XTIME: this->output[0] += x_time; @@ -163,35 +161,34 @@ DISCRETE_STEP(dss_counter) DISCRETE_RESET(dss_counter) { - DISCRETE_DECLARE_CONTEXT(dss_counter) if ((int)DSS_COUNTER__CLOCK_TYPE & DISC_COUNTER_IS_7492) { - context->is_7492 = 1; - context->clock_type = DSS_7492__CLOCK_TYPE; - context->max = 5; - context->min = 0; - context->diff = 6; + m_is_7492 = 1; + m_clock_type = DSS_7492__CLOCK_TYPE; + m_max = 5; + m_min = 0; + m_diff = 6; } else { - context->is_7492 = 0; - context->clock_type = DSS_COUNTER__CLOCK_TYPE; - context->max = DSS_COUNTER__MAX; - context->min = DSS_COUNTER__MIN; - context->diff = context->max - context->min + 1; + m_is_7492 = 0; + m_clock_type = DSS_COUNTER__CLOCK_TYPE; + m_max = DSS_COUNTER__MAX; + m_min = DSS_COUNTER__MIN; + m_diff = m_max - m_min + 1; } - if (!context->is_7492 && (DSS_COUNTER__MAX < DSS_COUNTER__MIN)) + if (!m_is_7492 && (DSS_COUNTER__MAX < DSS_COUNTER__MIN)) fatalerror("MAX < MIN in NODE_%02d", this->index()); - context->out_type = context->clock_type & DISC_OUT_MASK; - context->clock_type &= DISC_CLK_MASK; + m_out_type = m_clock_type & DISC_OUT_MASK; + m_clock_type &= DISC_CLK_MASK; - context->t_left = 0; - context->last_count = 0; - context->last_clock = 0; + m_t_left = 0; + m_last_count = 0; + m_last_clock = 0; this->output[0] = DSS_COUNTER__INIT; /* count starts at reset value */ } @@ -282,7 +279,6 @@ INLINE int dss_lfsr_function(discrete_device *dev, int myfunc, int in0, int in1, DISCRETE_STEP(dss_lfsr_noise) { - DISCRETE_DECLARE_CONTEXT(dss_lfsr_noise) DISCRETE_DECLARE_INFO(discrete_lfsr_desc) double cycles; @@ -292,13 +288,13 @@ DISCRETE_STEP(dss_lfsr_noise) if (info->clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + this->sample_time()) / context->t_clock; + cycles = (m_t_left + this->sample_time()) / m_t_clock; inc = (int)cycles; - context->t_left = (cycles - inc) * context->t_clock; + m_t_left = (cycles - inc) * m_t_clock; } /* Reset everything if necessary */ - if(((DSS_LFSR_NOISE__RESET == 0) ? 0 : 1) == context->reset_on_high) + if(((DSS_LFSR_NOISE__RESET == 0) ? 0 : 1) == m_reset_on_high) { this->reset(); return; @@ -310,9 +306,9 @@ DISCRETE_STEP(dss_lfsr_noise) case DISC_CLK_ON_R_EDGE: /* See if the clock has toggled to the proper edge */ clock = (DSS_LFSR_NOISE__CLOCK != 0); - if (context->last != clock) + if (m_last != clock) { - context->last = clock; + m_last = clock; if (info->clock_type == clock) { /* Toggled */ @@ -333,7 +329,7 @@ DISCRETE_STEP(dss_lfsr_noise) for (clock = 0; clock < inc; clock++) { /* Fetch the last feedback result */ - fbresult = (context->lfsr_reg >> info->bitlength) & 0x01; + fbresult = (m_lfsr_reg >> info->bitlength) & 0x01; /* Stage 2 feedback combine fbresultNew with infeed bit */ fbresult = dss_lfsr_function(this->device, info->feedback_function1, fbresult, noise_feed, 0x01); @@ -341,27 +337,27 @@ DISCRETE_STEP(dss_lfsr_noise) /* Stage 3 first we setup where the bit is going to be shifted into */ fbresult = fbresult * info->feedback_function2_mask; /* Then we left shift the register, */ - context->lfsr_reg = context->lfsr_reg << 1; + m_lfsr_reg = m_lfsr_reg << 1; /* Now move the fbresult into the shift register and mask it to the bitlength */ - context->lfsr_reg = dss_lfsr_function(this->device, info->feedback_function2, fbresult, context->lfsr_reg, (1 << info->bitlength) - 1 ); + m_lfsr_reg = dss_lfsr_function(this->device, info->feedback_function2, fbresult, m_lfsr_reg, (1 << info->bitlength) - 1 ); /* Now get and store the new feedback result */ /* Fetch the feedback bits */ - fb0 = (context->lfsr_reg >> info->feedback_bitsel0) & 0x01; - fb1 = (context->lfsr_reg >> info->feedback_bitsel1) & 0x01; + fb0 = (m_lfsr_reg >> info->feedback_bitsel0) & 0x01; + fb1 = (m_lfsr_reg >> info->feedback_bitsel1) & 0x01; /* Now do the combo on them */ fbresult = dss_lfsr_function(this->device, info->feedback_function0, fb0, fb1, 0x01); - context->lfsr_reg = dss_lfsr_function(this->device, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << info->bitlength, (2 << info->bitlength) - 1); + m_lfsr_reg = dss_lfsr_function(this->device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2 << info->bitlength) - 1); } /* Now select the output bit */ - if (context->out_is_f0) + if (m_out_is_f0) this->output[0] = fbresult & 0x01; else - this->output[0] = (context->lfsr_reg >> info->output_bit) & 0x01; + this->output[0] = (m_lfsr_reg >> info->output_bit) & 0x01; /* Final inversion if required */ - if (context->invert_output) this->output[0] = this->output[0] ? 0 : 1; + if (m_invert_output) this->output[0] = this->output[0] ? 0 : 1; /* Gain stage */ this->output[0] = this->output[0] ? DSS_LFSR_NOISE__AMP / 2 : -DSS_LFSR_NOISE__AMP / 2; @@ -369,8 +365,8 @@ DISCRETE_STEP(dss_lfsr_noise) this->output[0] = this->output[0] + DSS_LFSR_NOISE__BIAS; /* output the lfsr reg ?*/ - if (context->out_lfsr_reg) - this->output[1] = (double) context->lfsr_reg; + if (m_out_lfsr_reg) + this->output[1] = (double) m_lfsr_reg; } if(!DSS_LFSR_NOISE__ENABLE) @@ -381,35 +377,34 @@ DISCRETE_STEP(dss_lfsr_noise) DISCRETE_RESET(dss_lfsr_noise) { - DISCRETE_DECLARE_CONTEXT(dss_lfsr_noise) DISCRETE_DECLARE_INFO(discrete_lfsr_desc) int fb0 , fb1, fbresult; - context->reset_on_high = (info->flags & DISC_LFSR_FLAG_RESET_TYPE_H) ? 1 : 0; - context->invert_output = info->flags & DISC_LFSR_FLAG_OUT_INVERT; - context->out_is_f0 = (info->flags & DISC_LFSR_FLAG_OUTPUT_F0) ? 1 : 0; - context->out_lfsr_reg = (info->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0; + m_reset_on_high = (info->flags & DISC_LFSR_FLAG_RESET_TYPE_H) ? 1 : 0; + m_invert_output = info->flags & DISC_LFSR_FLAG_OUT_INVERT; + m_out_is_f0 = (info->flags & DISC_LFSR_FLAG_OUTPUT_F0) ? 1 : 0; + m_out_lfsr_reg = (info->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0; if ((info->clock_type < DISC_CLK_ON_F_EDGE) || (info->clock_type > DISC_CLK_IS_FREQ)) this->device->discrete_log("Invalid clock type passed in NODE_%d\n", this->index()); - context->last = (DSS_COUNTER__CLOCK != 0); - if (info->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; - context->t_left = 0; + m_last = (DSS_COUNTER__CLOCK != 0); + if (info->clock_type == DISC_CLK_IS_FREQ) m_t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; + m_t_left = 0; - context->lfsr_reg = info->reset_value; + m_lfsr_reg = info->reset_value; /* Now get and store the new feedback result */ /* Fetch the feedback bits */ - fb0 = (context->lfsr_reg >> info->feedback_bitsel0) & 0x01; - fb1=(context->lfsr_reg >> info->feedback_bitsel1) & 0x01; + fb0 = (m_lfsr_reg >> info->feedback_bitsel0) & 0x01; + fb1=(m_lfsr_reg >> info->feedback_bitsel1) & 0x01; /* Now do the combo on them */ fbresult = dss_lfsr_function(this->device, info->feedback_function0, fb0, fb1, 0x01); - context->lfsr_reg=dss_lfsr_function(this->device, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << info->bitlength, (2<< info->bitlength ) - 1); + m_lfsr_reg=dss_lfsr_function(this->device, DISC_LFSR_REPLACE, m_lfsr_reg, fbresult << info->bitlength, (2<< info->bitlength ) - 1); /* Now select and setup the output bit */ - this->output[0] = (context->lfsr_reg >> info->output_bit) & 0x01; + this->output[0] = (m_lfsr_reg >> info->output_bit) & 0x01; /* Final inversion if required */ if(info->flags & DISC_LFSR_FLAG_OUT_INVERT) this->output[0] = this->output[0] ? 0 : 1; @@ -438,12 +433,10 @@ DISCRETE_RESET(dss_lfsr_noise) DISCRETE_STEP(dss_noise) { - DISCRETE_DECLARE_CONTEXT(dss_noise) - if(DSS_NOISE__ENABLE) { /* Only sample noise on rollover to next cycle */ - if(context->phase > (2.0 * M_PI)) + if(m_phase > (2.0 * M_PI)) { /* GCC's rand returns a RAND_MAX value of 0x7fff */ int newval = (this->device->machine->rand() & 0x7fff) - 16384; @@ -465,19 +458,17 @@ DISCRETE_STEP(dss_noise) } /* Keep the new phasor in the 2Pi range.*/ - context->phase = fmod(context->phase, 2.0 * M_PI); + m_phase = fmod(m_phase, 2.0 * M_PI); /* The enable input only curtails output, phase rotation still occurs. */ /* We allow the phase to exceed 2Pi here, so we can tell when to sample the noise. */ - context->phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / this->sample_rate()); + m_phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / this->sample_rate()); } DISCRETE_RESET(dss_noise) { - DISCRETE_DECLARE_CONTEXT(dss_noise) - - context->phase=0; + m_phase=0; this->step(); } @@ -504,19 +495,17 @@ DISCRETE_RESET(dss_noise) DISCRETE_STEP(dss_note) { - DISCRETE_DECLARE_CONTEXT(dss_note) - double cycles; int clock = 0, last_count2, inc = 0; double x_time = 0; - if (context->clock_type == DISC_CLK_IS_FREQ) + if (m_clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + this->sample_time()) / context->t_clock; + cycles = (m_t_left + this->sample_time()) / m_t_clock; inc = (int)cycles; - context->t_left = (cycles - inc) * context->t_clock; - if (inc) x_time = context->t_left / this->sample_time(); + m_t_left = (cycles - inc) * m_t_clock; + if (inc) x_time = m_t_left / this->sample_time(); } else { @@ -527,18 +516,18 @@ DISCRETE_STEP(dss_note) if (DSS_NOTE__ENABLE) { - last_count2 = context->count2; + last_count2 = m_count2; - switch (context->clock_type) + switch (m_clock_type) { case DISC_CLK_ON_F_EDGE: case DISC_CLK_ON_R_EDGE: /* See if the clock has toggled to the proper edge */ clock = (clock != 0); - if (context->last != clock) + if (m_last != clock) { - context->last = clock; - if (context->clock_type == clock) + m_last = clock; + if (m_clock_type == clock) { /* Toggled */ inc = 1; @@ -557,30 +546,30 @@ DISCRETE_STEP(dss_note) { for (clock = 0; clock < inc; clock++) { - context->count1++; - if (context->count1 > context->max1) + m_count1++; + if (m_count1 > m_max1) { /* Max 1 count reached. Load Data into counter. */ - context->count1 = (int)DSS_NOTE__DATA; - context->count2 += 1; - if (context->count2 > context->max2) context->count2 = 0; + m_count1 = (int)DSS_NOTE__DATA; + m_count2 += 1; + if (m_count2 > m_max2) m_count2 = 0; } } } - this->output[0] = context->count2; - if (context->count2 != last_count2) + this->output[0] = m_count2; + if (m_count2 != last_count2) { /* the x_time is only output if the output changed. */ - switch (context->out_type) + switch (m_out_type) { case DISC_OUT_IS_ENERGY: if (x_time == 0) x_time = 1.0; this->output[0] = last_count2; - if (context->count2 > last_count2) - this->output[0] += (context->count2 - last_count2) * x_time; + if (m_count2 > last_count2) + this->output[0] += (m_count2 - last_count2) * x_time; else - this->output[0] -= (last_count2 - context->count2) * x_time; + this->output[0] -= (last_count2 - m_count2) * x_time; break; case DISC_OUT_HAS_XTIME: this->output[0] += x_time; @@ -594,19 +583,17 @@ DISCRETE_STEP(dss_note) DISCRETE_RESET(dss_note) { - DISCRETE_DECLARE_CONTEXT(dss_note) + m_clock_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_CLK_MASK; + m_out_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_OUT_MASK; - context->clock_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_CLK_MASK; - context->out_type = (int)DSS_NOTE__CLOCK_TYPE & DISC_OUT_MASK; + m_last = (DSS_NOTE__CLOCK != 0); + m_t_left = 0; + m_t_clock = 1.0 / DSS_NOTE__CLOCK; - context->last = (DSS_NOTE__CLOCK != 0); - context->t_left = 0; - context->t_clock = 1.0 / DSS_NOTE__CLOCK; - - context->count1 = (int)DSS_NOTE__DATA; - context->count2 = 0; - context->max1 = (int)DSS_NOTE__MAX1; - context->max2 = (int)DSS_NOTE__MAX2; + m_count1 = (int)DSS_NOTE__DATA; + m_count2 = 0; + m_max1 = (int)DSS_NOTE__MAX1; + m_max2 = (int)DSS_NOTE__MAX2; this->output[0] = 0; } @@ -629,11 +616,10 @@ DISCRETE_RESET(dss_note) /* The inputs on a norton op-amp are (info->vP - OP_AMP_NORTON_VBE) */ /* which is the same as the output high voltage. We will define them */ /* the same to save a calculation step */ -#define DSS_OP_AMP_OSC_NORTON_VP_IN context->v_out_high +#define DSS_OP_AMP_OSC_NORTON_VP_IN m_v_out_high DISCRETE_STEP(dss_op_amp_osc) { - DISCRETE_DECLARE_CONTEXT(dss_op_amp_osc) DISCRETE_DECLARE_INFO(discrete_op_amp_osc_info) double i = 0; /* Charging current created by vIn */ @@ -647,22 +633,22 @@ DISCRETE_STEP(dss_op_amp_osc) UINT8 force_charge = 0; UINT8 enable = DSS_OP_AMP_OSC__ENABLE; UINT8 update_exponent = 0; - UINT8 flip_flop = context->flip_flop; + UINT8 flip_flop = m_flip_flop; int count_f = 0; int count_r = 0; dt = this->sample_time(); /* Change in time */ - v_cap = context->v_cap; /* Set to voltage before change */ + v_cap = m_v_cap; /* Set to voltage before change */ /* work out the charge currents/voltages. */ - switch (context->type) + switch (m_type) { case DISC_OP_AMP_OSCILLATOR_VCO_1: /* Work out the charge rates. */ /* i is not a current. It is being used as a temp variable. */ - i = DSS_OP_AMP_OSC__VMOD1 * context->temp1; + i = DSS_OP_AMP_OSC__VMOD1 * m_temp1; charge[0] = (DSS_OP_AMP_OSC__VMOD1 - i) / info->r1; - charge[1] = (i - (DSS_OP_AMP_OSC__VMOD1 * context->temp2)) / context->temp3; + charge[1] = (i - (DSS_OP_AMP_OSC__VMOD1 * m_temp2)) / m_temp3; break; case DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON: @@ -670,21 +656,21 @@ DISCRETE_STEP(dss_op_amp_osc) /* resistors can be nodes, so everything needs updating */ double i1, i2; /* add in enable current if using real enable */ - if (context->has_enable) + if (m_has_enable) { if (enable) - i = context->i_enable; + i = m_i_enable; enable = 1; } /* Work out the charge rates. */ - charge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r1 - i; - charge[1] = (context->v_out_high - OP_AMP_NORTON_VBE) / *context->r2 - charge[0]; + charge[0] = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r1 - i; + charge[1] = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r2 - charge[0]; /* Work out the Inverting Schmitt thresholds. */ - i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *context->r5; - i2 = (0.0 - OP_AMP_NORTON_VBE) / *context->r4; - context->threshold_low = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE; - i2 = (context->v_out_high - OP_AMP_NORTON_VBE) / *context->r4; - context->threshold_high = (i1 + i2) * *context->r3 + OP_AMP_NORTON_VBE; + i1 = DSS_OP_AMP_OSC_NORTON_VP_IN / *m_r5; + i2 = (0.0 - OP_AMP_NORTON_VBE) / *m_r4; + m_threshold_low = (i1 + i2) * *m_r3 + OP_AMP_NORTON_VBE; + i2 = (m_v_out_high - OP_AMP_NORTON_VBE) / *m_r4; + m_threshold_high = (i1 + i2) * *m_r3 + OP_AMP_NORTON_VBE; break; } @@ -698,11 +684,11 @@ DISCRETE_STEP(dss_op_amp_osc) else { /* we need to mix any bias and all modulation voltages together. */ - i = context->i_fixed; + i = m_i_fixed; i += DSS_OP_AMP_OSC__VMOD1 / info->r7; if (info->r8 != 0) i += DSS_OP_AMP_OSC__VMOD2 / info->r8; - v = i * context->r_total; + v = i * m_r_total; } /* Work out the charge rates. */ @@ -718,8 +704,8 @@ DISCRETE_STEP(dss_op_amp_osc) case DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON: /* Work out the charge rates. */ i = DSS_OP_AMP_OSC__VMOD1 / info->r1; - charge[0] = i - context->temp1; - charge[1] = context->temp2 - i; + charge[0] = i - m_temp1; + charge[1] = m_temp2 - i; /* if the negative pin current is less then the positive pin current, */ /* then the osc is disabled and the cap keeps charging */ if (charge[0] < 0) @@ -731,12 +717,12 @@ DISCRETE_STEP(dss_op_amp_osc) case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON: /* start with fixed bias */ - charge[0] = context->i_fixed; + charge[0] = m_i_fixed; /* add in enable current if using real enable */ - if (context->has_enable) + if (m_has_enable) { if (enable) - charge[0] -= context->i_enable; + charge[0] -= m_i_enable; enable = 1; } /* we need to mix any bias and all modulation voltages together. */ @@ -748,7 +734,7 @@ DISCRETE_STEP(dss_op_amp_osc) v = DSS_OP_AMP_OSC__VMOD2 - OP_AMP_NORTON_VBE; charge[0] += v / info->r6; } - charge[1] = context->temp1 - charge[0]; + charge[1] = m_temp1 - charge[0]; break; } @@ -762,9 +748,9 @@ DISCRETE_STEP(dss_op_amp_osc) /* Keep looping until all toggling in time sample is used up. */ do { - if (context->is_linear_charge) + if (m_is_linear_charge) { - if ((flip_flop ^ context->flip_flop_xor) || force_charge) + if ((flip_flop ^ m_flip_flop_xor) || force_charge) { /* Charging */ /* iC=C*dv/dt works out to dv=iC*dt/C */ @@ -772,9 +758,9 @@ DISCRETE_STEP(dss_op_amp_osc) dt = 0; /* has it charged past upper limit? */ - if (v_cap_next > context->threshold_high) + if (v_cap_next > m_threshold_high) { - flip_flop = context->flip_flop_xor; + flip_flop = m_flip_flop_xor; if (flip_flop) count_r++; else @@ -782,15 +768,15 @@ DISCRETE_STEP(dss_op_amp_osc) if (force_charge) { /* we need to keep charging the cap to the max thereby disabling the circuit */ - if (v_cap_next > context->v_out_high) - v_cap_next = context->v_out_high; + if (v_cap_next > m_v_out_high) + v_cap_next = m_v_out_high; } else { /* calculate the overshoot time */ - dt = info->c * (v_cap_next - context->threshold_high) / charge[1]; + dt = info->c * (v_cap_next - m_threshold_high) / charge[1]; x_time = dt; - v_cap_next = context->threshold_high; + v_cap_next = m_threshold_high; } } } @@ -801,38 +787,38 @@ DISCRETE_STEP(dss_op_amp_osc) dt = 0; /* has it discharged past lower limit? */ - if (v_cap_next < context->threshold_low) + if (v_cap_next < m_threshold_low) { - flip_flop = !context->flip_flop_xor; + flip_flop = !m_flip_flop_xor; if (flip_flop) count_r++; else count_f++; /* calculate the overshoot time */ - dt = info->c * (context->threshold_low - v_cap_next) / charge[0]; + dt = info->c * (m_threshold_low - v_cap_next) / charge[0]; x_time = dt; - v_cap_next = context->threshold_low; + v_cap_next = m_threshold_low; } } } else /* non-linear charge */ { if (update_exponent) - exponent = RC_CHARGE_EXP_DT(context->charge_rc[flip_flop], dt); + exponent = RC_CHARGE_EXP_DT(m_charge_rc[flip_flop], dt); else - exponent = context->charge_exp[flip_flop]; + exponent = m_charge_exp[flip_flop]; - v_cap_next = v_cap + ((context->charge_v[flip_flop] - v_cap) * exponent); + v_cap_next = v_cap + ((m_charge_v[flip_flop] - v_cap) * exponent); dt = 0; if (flip_flop) { /* Has it charged past upper limit? */ - if (v_cap_next > context->threshold_high) + if (v_cap_next > m_threshold_high) { - dt = context->charge_rc[1] * log(1.0 / (1.0 - ((v_cap_next - context->threshold_high) / (context->v_out_high - v_cap)))); + dt = m_charge_rc[1] * log(1.0 / (1.0 - ((v_cap_next - m_threshold_high) / (m_v_out_high - v_cap)))); x_time = dt; - v_cap_next = context->threshold_high; + v_cap_next = m_threshold_high; flip_flop = 0; count_f++; update_exponent = 1; @@ -841,11 +827,11 @@ DISCRETE_STEP(dss_op_amp_osc) else { /* has it discharged past lower limit? */ - if (v_cap_next < context->threshold_low) + if (v_cap_next < m_threshold_low) { - dt = context->charge_rc[0] * log(1.0 / (1.0 - ((context->threshold_low - v_cap_next) / v_cap))); + dt = m_charge_rc[0] * log(1.0 / (1.0 - ((m_threshold_low - v_cap_next) / v_cap))); x_time = dt; - v_cap_next = context->threshold_low; + v_cap_next = m_threshold_low; flip_flop = 1; count_r++; update_exponent = 1; @@ -854,29 +840,29 @@ DISCRETE_STEP(dss_op_amp_osc) } v_cap = v_cap_next; } while(dt); - if (v_cap > context->v_out_high) - v_cap = context->v_out_high; + if (v_cap > m_v_out_high) + v_cap = m_v_out_high; if (v_cap < 0) v_cap = 0; - context->v_cap = v_cap; + m_v_cap = v_cap; x_time = dt / this->sample_time(); - switch (context->output_type) + switch (m_output_type) { case DISC_OP_AMP_OSCILLATOR_OUT_CAP: this->output[0] = v_cap; break; case DISC_OP_AMP_OSCILLATOR_OUT_ENERGY: if (x_time == 0) x_time = 1.0; - this->output[0] = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time)); + this->output[0] = m_v_out_high * (flip_flop ? x_time : (1.0 - x_time)); break; case DISC_OP_AMP_OSCILLATOR_OUT_SQW: if (count_f + count_r >= 2) /* force at least 1 toggle */ - this->output[0] = context->flip_flop ? 0 : context->v_out_high; + this->output[0] = m_flip_flop ? 0 : m_v_out_high; else - this->output[0] = flip_flop * context->v_out_high; + this->output[0] = flip_flop * m_v_out_high; break; case DISC_OP_AMP_OSCILLATOR_OUT_COUNT_F_X: this->output[0] = count_f ? count_f + x_time : count_f; @@ -885,17 +871,16 @@ DISCRETE_STEP(dss_op_amp_osc) this->output[0] = count_r ? count_r + x_time : count_r; break; case DISC_OP_AMP_OSCILLATOR_OUT_LOGIC_X: - this->output[0] = context->flip_flop + x_time; + this->output[0] = m_flip_flop + x_time; break; } - context->flip_flop = flip_flop; + m_flip_flop = flip_flop; } #define DIODE_DROP 0.7 DISCRETE_RESET(dss_op_amp_osc) { - DISCRETE_DECLARE_CONTEXT(dss_op_amp_osc) DISCRETE_DECLARE_INFO(discrete_op_amp_osc_info) const double *r_info_ptr; @@ -908,7 +893,7 @@ DISCRETE_RESET(dss_op_amp_osc) /* link to resistor static or node values */ r_info_ptr = &info->r1; - r_context_ptr = &context->r1; + r_context_ptr = &m_r1; for (loop = 0; loop < 8; loop ++) { if IS_VALUE_A_NODE(*r_info_ptr) @@ -922,159 +907,159 @@ DISCRETE_RESET(dss_op_amp_osc) r_context_ptr++; } - context->is_linear_charge = 1; - context->output_type = info->type & DISC_OP_AMP_OSCILLATOR_OUT_MASK; - context->type = info->type & DISC_OP_AMP_OSCILLATOR_TYPE_MASK; - context->charge_rc[0] = 0; - context->charge_rc[1] = 0; - context->charge_v[0] = 0; - context->charge_v[1] = 0; - context->i_fixed = 0; - context->has_enable = 0; + m_is_linear_charge = 1; + m_output_type = info->type & DISC_OP_AMP_OSCILLATOR_OUT_MASK; + m_type = info->type & DISC_OP_AMP_OSCILLATOR_TYPE_MASK; + m_charge_rc[0] = 0; + m_charge_rc[1] = 0; + m_charge_v[0] = 0; + m_charge_v[1] = 0; + m_i_fixed = 0; + m_has_enable = 0; - switch (context->type) + switch (m_type) { case DISC_OP_AMP_OSCILLATOR_VCO_1: /* The charge rates vary depending on vMod so they are not precalculated. */ /* Charges while FlipFlop High */ - context->flip_flop_xor = 0; + m_flip_flop_xor = 0; /* Work out the Non-inverting Schmitt thresholds. */ - context->temp1 = (info->vP / 2) / info->r4; - context->temp2 = (info->vP - OP_AMP_VP_RAIL_OFFSET) / info->r3; - context->temp3 = 1.0 / (1.0 / info->r3 + 1.0 / info->r4); - context->threshold_low = context->temp1 * context->temp3; - context->threshold_high = (context->temp1 + context->temp2) * context->temp3; + m_temp1 = (info->vP / 2) / info->r4; + m_temp2 = (info->vP - OP_AMP_VP_RAIL_OFFSET) / info->r3; + m_temp3 = 1.0 / (1.0 / info->r3 + 1.0 / info->r4); + m_threshold_low = m_temp1 * m_temp3; + m_threshold_high = (m_temp1 + m_temp2) * m_temp3; /* There is no charge on the cap so the schmitt goes high at init. */ - context->flip_flop = 1; + m_flip_flop = 1; /* Setup some commonly used stuff */ - context->temp1 = info->r5 / (info->r2 + info->r5); /* voltage ratio across r5 */ - context->temp2 = info->r6 / (info->r1 + info->r6); /* voltage ratio across r6 */ - context->temp3 = 1.0 / (1.0 / info->r1 + 1.0 / info->r6); /* input resistance when r6 switched in */ + m_temp1 = info->r5 / (info->r2 + info->r5); /* voltage ratio across r5 */ + m_temp2 = info->r6 / (info->r1 + info->r6); /* voltage ratio across r6 */ + m_temp3 = 1.0 / (1.0 / info->r1 + 1.0 / info->r6); /* input resistance when r6 switched in */ break; case DISC_OP_AMP_OSCILLATOR_1 | DISC_OP_AMP_IS_NORTON: /* Charges while FlipFlop High */ - context->flip_flop_xor = 0; + m_flip_flop_xor = 0; /* There is no charge on the cap so the schmitt inverter goes high at init. */ - context->flip_flop = 1; + m_flip_flop = 1; /* setup current if using real enable */ if (info->r6 > 0) { - context->has_enable = 1; - context->i_enable = (info->vP - OP_AMP_NORTON_VBE) / (info->r6 + RES_K(1)); + m_has_enable = 1; + m_i_enable = (info->vP - OP_AMP_NORTON_VBE) / (info->r6 + RES_K(1)); } break; case DISC_OP_AMP_OSCILLATOR_2 | DISC_OP_AMP_IS_NORTON: - context->is_linear_charge = 0; + m_is_linear_charge = 0; /* First calculate the parallel charge resistors and volatges. */ /* We can cheat and just calcuate the charges in the working area. */ /* The thresholds are well past the effect of the voltage drop */ /* and the component tolerances far exceed the .5V charge difference */ if (info->r1 != 0) { - context->charge_rc[0] = 1.0 / info->r1; - context->charge_rc[1] = 1.0 / info->r1; - context->charge_v[1] = (info->vP - OP_AMP_NORTON_VBE) / info->r1; + m_charge_rc[0] = 1.0 / info->r1; + m_charge_rc[1] = 1.0 / info->r1; + m_charge_v[1] = (info->vP - OP_AMP_NORTON_VBE) / info->r1; } if (info->r5 != 0) { - context->charge_rc[0] += 1.0 / info->r5; - context->charge_v[0] = DIODE_DROP / info->r5; + m_charge_rc[0] += 1.0 / info->r5; + m_charge_v[0] = DIODE_DROP / info->r5; } if (info->r6 != 0) { - context->charge_rc[1] += 1.0 / info->r6; - context->charge_v[1] += (info->vP - OP_AMP_NORTON_VBE - DIODE_DROP) / info->r6; + m_charge_rc[1] += 1.0 / info->r6; + m_charge_v[1] += (info->vP - OP_AMP_NORTON_VBE - DIODE_DROP) / info->r6; } - context->charge_rc[0] += 1.0 / info->r2; - context->charge_rc[0] = 1.0 / context->charge_rc[0]; - context->charge_v[0] += OP_AMP_NORTON_VBE / info->r2; - context->charge_v[0] *= context->charge_rc[0]; - context->charge_rc[1] += 1.0 / info->r2; - context->charge_rc[1] = 1.0 / context->charge_rc[1]; - context->charge_v[1] += OP_AMP_NORTON_VBE / info->r2; - context->charge_v[1] *= context->charge_rc[1]; + m_charge_rc[0] += 1.0 / info->r2; + m_charge_rc[0] = 1.0 / m_charge_rc[0]; + m_charge_v[0] += OP_AMP_NORTON_VBE / info->r2; + m_charge_v[0] *= m_charge_rc[0]; + m_charge_rc[1] += 1.0 / info->r2; + m_charge_rc[1] = 1.0 / m_charge_rc[1]; + m_charge_v[1] += OP_AMP_NORTON_VBE / info->r2; + m_charge_v[1] *= m_charge_rc[1]; - context->charge_rc[0] *= info->c; - context->charge_rc[1] *= info->c; - context->charge_exp[0] = RC_CHARGE_EXP_CLASS(context->charge_rc[0]); - context->charge_exp[1] = RC_CHARGE_EXP_CLASS(context->charge_rc[1]); - context->threshold_low = (info->vP - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_high = context->threshold_low + (info->vP - 2 * OP_AMP_NORTON_VBE) / info->r3;; - context->threshold_low = context->threshold_low * info->r2 + OP_AMP_NORTON_VBE; - context->threshold_high = context->threshold_high * info->r2 + OP_AMP_NORTON_VBE; + m_charge_rc[0] *= info->c; + m_charge_rc[1] *= info->c; + m_charge_exp[0] = RC_CHARGE_EXP_CLASS(m_charge_rc[0]); + m_charge_exp[1] = RC_CHARGE_EXP_CLASS(m_charge_rc[1]); + m_threshold_low = (info->vP - OP_AMP_NORTON_VBE) / info->r4; + m_threshold_high = m_threshold_low + (info->vP - 2 * OP_AMP_NORTON_VBE) / info->r3;; + m_threshold_low = m_threshold_low * info->r2 + OP_AMP_NORTON_VBE; + m_threshold_high = m_threshold_high * info->r2 + OP_AMP_NORTON_VBE; /* There is no charge on the cap so the schmitt inverter goes high at init. */ - context->flip_flop = 1; + m_flip_flop = 1; break; case DISC_OP_AMP_OSCILLATOR_VCO_1 | DISC_OP_AMP_IS_NORTON: /* Charges while FlipFlop Low */ - context->flip_flop_xor = 1; + m_flip_flop_xor = 1; /* There is no charge on the cap so the schmitt goes low at init. */ - context->flip_flop = 0; + m_flip_flop = 0; /* The charge rates vary depending on vMod so they are not precalculated. */ /* But we can precalculate the fixed currents. */ - if (info->r6 != 0) context->i_fixed += info->vP / info->r6; - context->i_fixed += OP_AMP_NORTON_VBE / info->r1; - context->i_fixed += OP_AMP_NORTON_VBE / info->r2; + if (info->r6 != 0) m_i_fixed += info->vP / info->r6; + m_i_fixed += OP_AMP_NORTON_VBE / info->r1; + m_i_fixed += OP_AMP_NORTON_VBE / info->r2; /* Work out the input resistance to be used later to calculate the Millman voltage. */ - context->r_total = 1.0 / info->r1 + 1.0 / info->r2 + 1.0 / info->r7; - if (info->r6) context->r_total += 1.0 / info->r6; - if (info->r8) context->r_total += 1.0 / info->r8; - context->r_total = 1.0 / context->r_total; + m_r_total = 1.0 / info->r1 + 1.0 / info->r2 + 1.0 / info->r7; + if (info->r6) m_r_total += 1.0 / info->r6; + if (info->r8) m_r_total += 1.0 / info->r8; + m_r_total = 1.0 / m_r_total; /* Work out the Non-inverting Schmitt thresholds. */ i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_low = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_low = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_high = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_high = (i1 - i2) * info->r3 + OP_AMP_NORTON_VBE; break; case DISC_OP_AMP_OSCILLATOR_VCO_2 | DISC_OP_AMP_IS_NORTON: /* Charges while FlipFlop High */ - context->flip_flop_xor = 0; + m_flip_flop_xor = 0; /* There is no charge on the cap so the schmitt inverter goes high at init. */ - context->flip_flop = 1; + m_flip_flop = 1; /* Work out the charge rates. */ - context->temp1 = (info->vP - OP_AMP_NORTON_VBE) / info->r2; - context->temp2 = (info->vP - OP_AMP_NORTON_VBE) * (1.0 / info->r2 + 1.0 / info->r6); + m_temp1 = (info->vP - OP_AMP_NORTON_VBE) / info->r2; + m_temp2 = (info->vP - OP_AMP_NORTON_VBE) * (1.0 / info->r2 + 1.0 / info->r6); /* Work out the Inverting Schmitt thresholds. */ i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; break; case DISC_OP_AMP_OSCILLATOR_VCO_3 | DISC_OP_AMP_IS_NORTON: /* Charges while FlipFlop High */ - context->flip_flop_xor = 0; + m_flip_flop_xor = 0; /* There is no charge on the cap so the schmitt inverter goes high at init. */ - context->flip_flop = 1; + m_flip_flop = 1; /* setup current if using real enable */ if (info->r8 > 0) { - context->has_enable = 1; - context->i_enable = (info->vP - OP_AMP_NORTON_VBE) / (info->r8 + RES_K(1)); + m_has_enable = 1; + m_i_enable = (info->vP - OP_AMP_NORTON_VBE) / (info->r8 + RES_K(1)); } /* Work out the charge rates. */ /* The charge rates vary depending on vMod so they are not precalculated. */ /* But we can precalculate the fixed currents. */ - if (info->r7 != 0) context->i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r7; - context->temp1 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r2; + if (info->r7 != 0) m_i_fixed = (info->vP - OP_AMP_NORTON_VBE) / info->r7; + m_temp1 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r2; /* Work out the Inverting Schmitt thresholds. */ i1 = (info->vP - OP_AMP_NORTON_VBE) / info->r5; i2 = (0.0 - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_low = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; i2 = (info->vP - OP_AMP_NORTON_VBE - OP_AMP_NORTON_VBE) / info->r4; - context->threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; + m_threshold_high = (i1 + i2) * info->r3 + OP_AMP_NORTON_VBE; break; } - context->v_out_high = info->vP - ((context->type & DISC_OP_AMP_IS_NORTON) ? OP_AMP_NORTON_VBE : OP_AMP_VP_RAIL_OFFSET); - context->v_cap = 0; + m_v_out_high = info->vP - ((m_type & DISC_OP_AMP_IS_NORTON) ? OP_AMP_NORTON_VBE : OP_AMP_VP_RAIL_OFFSET); + m_v_cap = 0; this->step(); } @@ -1101,11 +1086,9 @@ DISCRETE_RESET(dss_op_amp_osc) DISCRETE_STEP(dss_sawtoothwave) { - DISCRETE_DECLARE_CONTEXT(dss_sawtoothwave) - if(DSS_SAWTOOTHWAVE__ENABLE) { - this->output[0] = (context->type == 0) ? context->phase * (DSS_SAWTOOTHWAVE__AMP / (2.0 * M_PI)) : DSS_SAWTOOTHWAVE__AMP - (context->phase * (DSS_SAWTOOTHWAVE__AMP / (2.0 * M_PI))); + this->output[0] = (m_type == 0) ? m_phase * (DSS_SAWTOOTHWAVE__AMP / (2.0 * M_PI)) : DSS_SAWTOOTHWAVE__AMP - (m_phase * (DSS_SAWTOOTHWAVE__AMP / (2.0 * M_PI))); this->output[0] -= DSS_SAWTOOTHWAVE__AMP / 2.0; /* Add DC Bias component */ this->output[0] = this->output[0] + DSS_SAWTOOTHWAVE__BIAS; @@ -1122,22 +1105,20 @@ DISCRETE_STEP(dss_sawtoothwave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase = fmod((context->phase + ((2.0 * M_PI * DSS_SAWTOOTHWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); + m_phase = fmod((m_phase + ((2.0 * M_PI * DSS_SAWTOOTHWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); } DISCRETE_RESET(dss_sawtoothwave) { - DISCRETE_DECLARE_CONTEXT(dss_sawtoothwave) - double start; /* Establish starting phase, convert from degrees to radians */ start = (DSS_SAWTOOTHWAVE__PHASE / 360.0) * (2.0 * M_PI); /* Make sure its always mod 2Pi */ - context->phase = fmod(start, 2.0 * M_PI); + m_phase = fmod(start, 2.0 * M_PI); /* Invert gradient depending on sawtooth type /|/|/|/|/| or |\|\|\|\|\ */ - context->type = (DSS_SAWTOOTHWAVE__GRAD) ? 1 : 0; + m_type = (DSS_SAWTOOTHWAVE__GRAD) ? 1 : 0; /* Step the node to set the output */ this->step(); @@ -1162,14 +1143,13 @@ DISCRETE_RESET(dss_sawtoothwave) DISCRETE_STEP(dss_schmitt_osc) { - DISCRETE_DECLARE_CONTEXT(dss_schmitt_osc) DISCRETE_DECLARE_INFO(discrete_schmitt_osc_desc) double supply, v_cap, new_vCap, t, exponent; /* We will always oscillate. The enable just affects the output. */ - v_cap = context->v_cap; - exponent = context->exponent; + v_cap = m_v_cap; + exponent = m_exponent; /* Keep looping until all toggling in time sample is used up. */ do @@ -1181,21 +1161,21 @@ DISCRETE_STEP(dss_schmitt_osc) * use vGate as its voltage. Note that ration_in is just the ratio of the total * voltage and needs to be multipled by the input voltage. ratio_feedback has * already been multiplied by vGate to save time because that voltage never changes. */ - supply = context->input_is_voltage ? context->ration_in * DSS_SCHMITT_OSC__VIN : (DSS_SCHMITT_OSC__VIN ? context->ration_in * info->vGate : 0); - supply += (context->state ? context->ratio_feedback : 0); + supply = m_input_is_voltage ? m_ration_in * DSS_SCHMITT_OSC__VIN : (DSS_SCHMITT_OSC__VIN ? m_ration_in * info->vGate : 0); + supply += (m_state ? m_ratio_feedback : 0); new_vCap = v_cap + ((supply - v_cap) * exponent); - if (context->state) + if (m_state) { /* Charging */ /* has it charged past upper limit? */ if (new_vCap > info->trshRise) { /* calculate the overshoot time */ - t = context->rc * log(1.0 / (1.0 - ((new_vCap - info->trshRise) / (info->vGate - v_cap)))); + t = m_rc * log(1.0 / (1.0 - ((new_vCap - info->trshRise) / (info->vGate - v_cap)))); /* calculate new exponent because of reduced time */ - exponent = RC_CHARGE_EXP_DT(context->rc, t); + exponent = RC_CHARGE_EXP_DT(m_rc, t); v_cap = new_vCap = info->trshRise; - context->state = 0; + m_state = 0; } } else @@ -1205,30 +1185,30 @@ DISCRETE_STEP(dss_schmitt_osc) if (new_vCap < info->trshFall) { /* calculate the overshoot time */ - t = context->rc * log(1.0 / (1.0 - ((info->trshFall - new_vCap) / v_cap))); + t = m_rc * log(1.0 / (1.0 - ((info->trshFall - new_vCap) / v_cap))); /* calculate new exponent because of reduced time */ - exponent = RC_CHARGE_EXP_DT(context->rc, t); + exponent = RC_CHARGE_EXP_DT(m_rc, t); v_cap = new_vCap = info->trshFall; - context->state = 1; + m_state = 1; } } } while(t); - context->v_cap = new_vCap; + m_v_cap = new_vCap; - switch (context->enable_type) + switch (m_enable_type) { case DISC_SCHMITT_OSC_ENAB_IS_AND: - this->output[0] = DSS_SCHMITT_OSC__ENABLE && context->state; + this->output[0] = DSS_SCHMITT_OSC__ENABLE && m_state; break; case DISC_SCHMITT_OSC_ENAB_IS_NAND: - this->output[0] = !(DSS_SCHMITT_OSC__ENABLE && context->state); + this->output[0] = !(DSS_SCHMITT_OSC__ENABLE && m_state); break; case DISC_SCHMITT_OSC_ENAB_IS_OR: - this->output[0] = DSS_SCHMITT_OSC__ENABLE || context->state; + this->output[0] = DSS_SCHMITT_OSC__ENABLE || m_state; break; case DISC_SCHMITT_OSC_ENAB_IS_NOR: - this->output[0] = !(DSS_SCHMITT_OSC__ENABLE || context->state); + this->output[0] = !(DSS_SCHMITT_OSC__ENABLE || m_state); break; } this->output[0] *= DSS_SCHMITT_OSC__AMP; @@ -1236,28 +1216,27 @@ DISCRETE_STEP(dss_schmitt_osc) DISCRETE_RESET(dss_schmitt_osc) { - DISCRETE_DECLARE_CONTEXT(dss_schmitt_osc) DISCRETE_DECLARE_INFO(discrete_schmitt_osc_desc) double rSource; - context->enable_type = info->options & DISC_SCHMITT_OSC_ENAB_MASK; - context->input_is_voltage = (info->options & DISC_SCHMITT_OSC_IN_IS_VOLTAGE) ? 1 : 0; + m_enable_type = info->options & DISC_SCHMITT_OSC_ENAB_MASK; + m_input_is_voltage = (info->options & DISC_SCHMITT_OSC_IN_IS_VOLTAGE) ? 1 : 0; /* The 2 resistors make a voltage divider, so their ratios add together * to make the charging voltage. */ - context->ration_in = info->rFeedback / (info->rIn + info->rFeedback); - context->ratio_feedback = info->rIn / (info->rIn + info->rFeedback) * info->vGate; + m_ration_in = info->rFeedback / (info->rIn + info->rFeedback); + m_ratio_feedback = info->rIn / (info->rIn + info->rFeedback) * info->vGate; /* The voltage source resistance works out to the 2 resistors in parallel. * So use this for the RC charge constant. */ rSource = 1.0 / ((1.0 / info->rIn) + (1.0 / info->rFeedback)); - context->rc = rSource * info->c; - context->exponent = RC_CHARGE_EXP_CLASS(context->rc); + m_rc = rSource * info->c; + m_exponent = RC_CHARGE_EXP_CLASS(m_rc); /* Cap is at 0V on power up. Causing output to be high. */ - context->v_cap = 0; - context->state = 1; + m_v_cap = 0; + m_state = 1; this->output[0] = info->options ? 0 : DSS_SCHMITT_OSC__AMP; } @@ -1282,12 +1261,10 @@ DISCRETE_RESET(dss_schmitt_osc) DISCRETE_STEP(dss_sinewave) { - DISCRETE_DECLARE_CONTEXT(dss_sinewave) - /* Set the output */ if(DSS_SINEWAVE__ENABLE) { - this->output[0] = (DSS_SINEWAVE__AMPL / 2.0) * sin(context->phase); + this->output[0] = (DSS_SINEWAVE__AMPL / 2.0) * sin(m_phase); /* Add DC Bias component */ this->output[0] = this->output[0] + DSS_SINEWAVE__BIAS; } @@ -1303,19 +1280,17 @@ DISCRETE_STEP(dss_sinewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_SINEWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); + m_phase=fmod((m_phase + ((2.0 * M_PI * DSS_SINEWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); } DISCRETE_RESET(dss_sinewave) { - DISCRETE_DECLARE_CONTEXT(dss_sinewave) - double start; /* Establish starting phase, convert from degrees to radians */ start = (DSS_SINEWAVE__PHASE / 360.0) * (2.0 * M_PI); /* Make sure its always mod 2Pi */ - context->phase = fmod(start, 2.0 * M_PI); + m_phase = fmod(start, 2.0 * M_PI); /* Step the output to make it correct */ this->step(); } @@ -1342,15 +1317,13 @@ DISCRETE_RESET(dss_sinewave) DISCRETE_STEP(dss_squarewave) { - DISCRETE_DECLARE_CONTEXT(dss_squarewave) - /* Establish trigger phase from duty */ - context->trigger=((100-DSS_SQUAREWAVE__DUTY)/100)*(2.0*M_PI); + m_trigger=((100-DSS_SQUAREWAVE__DUTY)/100)*(2.0*M_PI); /* Set the output */ if(DSS_SQUAREWAVE__ENABLE) { - if(context->phase>context->trigger) + if(m_phase>m_trigger) this->output[0] = DSS_SQUAREWAVE__AMP /2.0; else this->output[0] =- DSS_SQUAREWAVE__AMP / 2.0; @@ -1370,19 +1343,17 @@ DISCRETE_STEP(dss_squarewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod(context->phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / this->sample_rate()), 2.0 * M_PI); + m_phase=fmod(m_phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / this->sample_rate()), 2.0 * M_PI); } DISCRETE_RESET(dss_squarewave) { - DISCRETE_DECLARE_CONTEXT(dss_squarewave) - double start; /* Establish starting phase, convert from degrees to radians */ start = (DSS_SQUAREWAVE__PHASE / 360.0) * (2.0 * M_PI); /* Make sure its always mod 2Pi */ - context->phase = fmod(start, 2.0 * M_PI); + m_phase = fmod(start, 2.0 * M_PI); /* Step the output */ this->step(); @@ -1409,26 +1380,24 @@ DISCRETE_RESET(dss_squarewave) DISCRETE_STEP(dss_squarewfix) { - DISCRETE_DECLARE_CONTEXT(dss_squarewfix) - - context->t_left -= context->sample_step; + m_t_left -= m_sample_step; /* The enable input only curtails output, phase rotation still occurs */ - while (context->t_left <= 0) + while (m_t_left <= 0) { - context->flip_flop = context->flip_flop ? 0 : 1; - context->t_left += context->flip_flop ? context->t_on : context->t_off; + m_flip_flop = m_flip_flop ? 0 : 1; + m_t_left += m_flip_flop ? m_t_on : m_t_off; } if(DSS_SQUAREWFIX__ENABLE) { /* Add gain and DC Bias component */ - context->t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ - context->t_on = context->t_off * (DSS_SQUAREWFIX__DUTY / 100.0); - context->t_off -= context->t_on; + m_t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ + m_t_on = m_t_off * (DSS_SQUAREWFIX__DUTY / 100.0); + m_t_off -= m_t_on; - this->output[0] = (context->flip_flop ? DSS_SQUAREWFIX__AMP / 2.0 : -(DSS_SQUAREWFIX__AMP / 2.0)) + DSS_SQUAREWFIX__BIAS; + this->output[0] = (m_flip_flop ? DSS_SQUAREWFIX__AMP / 2.0 : -(DSS_SQUAREWFIX__AMP / 2.0)) + DSS_SQUAREWFIX__BIAS; } else { @@ -1438,27 +1407,25 @@ DISCRETE_STEP(dss_squarewfix) DISCRETE_RESET(dss_squarewfix) { - DISCRETE_DECLARE_CONTEXT(dss_squarewfix) - - context->sample_step = 1.0 / this->sample_rate(); - context->flip_flop = 1; + m_sample_step = 1.0 / this->sample_rate(); + m_flip_flop = 1; /* Do the intial time shift and convert freq to off/on times */ - context->t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ - context->t_left = DSS_SQUAREWFIX__PHASE / 360.0; /* convert start phase to % */ - context->t_left = context->t_left - (int)context->t_left; /* keep % between 0 & 1 */ - context->t_left = (context->t_left < 0) ? 1.0 + context->t_left : context->t_left; /* if - then flip to + phase */ - context->t_left *= context->t_off; - context->t_on = context->t_off * (DSS_SQUAREWFIX__DUTY / 100.0); - context->t_off -= context->t_on; + m_t_off = 1.0 / DSS_SQUAREWFIX__FREQ; /* cycle time */ + m_t_left = DSS_SQUAREWFIX__PHASE / 360.0; /* convert start phase to % */ + m_t_left = m_t_left - (int)m_t_left; /* keep % between 0 & 1 */ + m_t_left = (m_t_left < 0) ? 1.0 + m_t_left : m_t_left; /* if - then flip to + phase */ + m_t_left *= m_t_off; + m_t_on = m_t_off * (DSS_SQUAREWFIX__DUTY / 100.0); + m_t_off -= m_t_on; - context->t_left = -context->t_left; + m_t_left = -m_t_left; /* toggle output and work out intial time shift */ - while (context->t_left <= 0) + while (m_t_left <= 0) { - context->flip_flop = context->flip_flop ? 0 : 1; - context->t_left += context->flip_flop ? context->t_on : context->t_off; + m_flip_flop = m_flip_flop ? 0 : 1; + m_t_left += m_flip_flop ? m_t_on : m_t_off; } /* Step the output */ @@ -1487,14 +1454,12 @@ DISCRETE_RESET(dss_squarewfix) DISCRETE_STEP(dss_squarewave2) { - DISCRETE_DECLARE_CONTEXT(dss_squarewave) - double newphase; if(DSS_SQUAREWAVE2__ENABLE) { /* Establish trigger phase from time periods */ - context->trigger = (DSS_SQUAREWAVE2__T_OFF / (DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON)) * (2.0 * M_PI); + m_trigger = (DSS_SQUAREWAVE2__T_OFF / (DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON)) * (2.0 * M_PI); /* Work out the phase step based on phase/freq & sample rate */ /* The enable input only curtails output, phase rotation */ @@ -1503,11 +1468,11 @@ DISCRETE_STEP(dss_squarewave2) /* phase step = 2Pi/(output period/sample period) */ /* boils out to */ /* phase step = 2Pi/(output period*sample freq) */ - newphase = context->phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * this->sample_rate())); + newphase = m_phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * this->sample_rate())); /* Keep the new phasor in the 2Pi range.*/ - context->phase = fmod(newphase, 2.0 * M_PI); + m_phase = fmod(newphase, 2.0 * M_PI); - if(context->phase>context->trigger) + if(m_phase>m_trigger) this->output[0] = DSS_SQUAREWAVE2__AMP / 2.0; else this->output[0] = -DSS_SQUAREWAVE2__AMP / 2.0; @@ -1523,8 +1488,6 @@ DISCRETE_STEP(dss_squarewave2) DISCRETE_RESET(dss_squarewave2) { - DISCRETE_DECLARE_CONTEXT(dss_squarewave) - double start; /* Establish starting phase, convert from degrees to radians */ @@ -1534,7 +1497,7 @@ DISCRETE_RESET(dss_squarewave2) else start = 0.0; /* Make sure its always mod 2Pi */ - context->phase = fmod(start, 2.0 * M_PI); + m_phase = fmod(start, 2.0 * M_PI); /* Step the output */ this->step(); @@ -1586,7 +1549,6 @@ inline double DISCRETE_CLASS_FUNC(dss_inverter_osc, tf)(double x) DISCRETE_STEP(dss_inverter_osc) { DISCRETE_DECLARE_INFO(discrete_inverter_osc_desc) - double diff, vG1, vG2, vG3, vI; double vMix, rMix; int clamped; @@ -1742,12 +1704,10 @@ DISCRETE_RESET(dss_inverter_osc) DISCRETE_STEP(dss_trianglewave) { - DISCRETE_DECLARE_CONTEXT(dss_trianglewave) - if(DSS_TRIANGLEWAVE__ENABLE) { - this->output[0] = context->phase < M_PI ? (DSS_TRIANGLEWAVE__AMP * (context->phase / (M_PI / 2.0) - 1.0)) / 2.0 : - (DSS_TRIANGLEWAVE__AMP * (3.0 - context->phase / (M_PI / 2.0))) / 2.0 ; + this->output[0] = m_phase < M_PI ? (DSS_TRIANGLEWAVE__AMP * (m_phase / (M_PI / 2.0) - 1.0)) / 2.0 : + (DSS_TRIANGLEWAVE__AMP * (3.0 - m_phase / (M_PI / 2.0))) / 2.0 ; /* Add DC Bias component */ this->output[0] = this->output[0] + DSS_TRIANGLEWAVE__BIAS; @@ -1764,19 +1724,17 @@ DISCRETE_STEP(dss_trianglewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_TRIANGLEWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); + m_phase=fmod((m_phase + ((2.0 * M_PI * DSS_TRIANGLEWAVE__FREQ) / this->sample_rate())), 2.0 * M_PI); } DISCRETE_RESET(dss_trianglewave) { - DISCRETE_DECLARE_CONTEXT(dss_trianglewave) - double start; /* Establish starting phase, convert from degrees to radians */ start = (DSS_TRIANGLEWAVE__PHASE / 360.0) * (2.0 * M_PI); /* Make sure its always mod 2Pi */ - context->phase=fmod(start, 2.0 * M_PI); + m_phase=fmod(start, 2.0 * M_PI); /* Step to set the output */ this->step(); diff --git a/src/emu/sound/disc_wav.h b/src/emu/sound/disc_wav.h new file mode 100644 index 00000000000..baa9487ef28 --- /dev/null +++ b/src/emu/sound/disc_wav.h @@ -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__ */ diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c index 85ac68ff548..1c327c3d965 100644 --- a/src/emu/sound/discrete.c +++ b/src/emu/sound/discrete.c @@ -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 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(this); + m_input_intf = dynamic_cast(this); + m_output_intf = dynamic_cast(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(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(device); - asc->m_type = type; + discrete_device_config *disc = downcast(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(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 { diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h index 862365ca962..5c38762c279 100644 --- a/src/emu/sound/discrete.h +++ b/src/emu/sound/discrete.h @@ -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 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 enumerator(void) const {enumerator_t r(m_first); return r; } + inline enumerator_t enumerator(void) const { enumerator_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 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 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 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 node_list_t; +typedef linked_list_t input_stream_node_list_t; +typedef linked_list_t 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 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 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 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 @@ -4671,7 +4544,10 @@ class discrete_node_factory : public discrete_node_base_factory template discrete_base_node * discrete_node_factory::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::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::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::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 */ diff --git a/src/mame/audio/8080bw.c b/src/mame/audio/8080bw.c index dd9654c2585..a88df65833c 100644 --- a/src/mame/audio/8080bw.c +++ b/src/mame/audio/8080bw.c @@ -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; diff --git a/src/mame/audio/bzone.c b/src/mame/audio/bzone.c index 676293cf6e1..f8382465e4d 100644 --- a/src/mame/audio/bzone.c +++ b/src/mame/audio/bzone.c @@ -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; } diff --git a/src/mame/audio/copsnrob.c b/src/mame/audio/copsnrob.c index 5e153e96f7c..0302df725b2 100644 --- a/src/mame/audio/copsnrob.c +++ b/src/mame/audio/copsnrob.c @@ -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 */ } diff --git a/src/mame/audio/dkong.c b/src/mame/audio/dkong.c index b290531ea71..92cb08540c0 100644 --- a/src/mame/audio/dkong.c +++ b/src/mame/audio/dkong.c @@ -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