27
27
#define DEFAULT_555_BLEED_R RES_M(10)
29
struct dsd_555_astbl_context
34
double ac_shift; /* DC shift needed to make waveform ac */
35
int flip_flop; /* 555 flip/flop output state */
36
double cap_voltage; /* voltage on cap */
39
double v_out_high; /* Logic 1 voltage level */
41
double *v_charge_node; /* point to output of node */
48
double t_rc_discharge;
54
struct dsd_555_mstbl_context
57
int trig_discharges_cap;
59
double ac_shift; /* DC shift needed to make waveform ac */
60
int flip_flop; /* 555 flip/flop output state */
63
double cap_voltage; /* voltage on cap */
66
double v_out_high; /* Logic 1 voltage level */
70
struct dsd_555_cc_context
72
unsigned int type; /* type of 555cc circuit */
75
double ac_shift; /* DC shift needed to make waveform ac */
76
int flip_flop; /* 555 flip/flop output state */
77
double cap_voltage; /* voltage on cap */
80
double v_out_high; /* Logic 1 voltage level */
86
double exp_discharge_01;
87
double exp_discharge_no_i;
89
double t_rc_discharge;
90
double t_rc_discharge_01;
91
double t_rc_discharge_no_i;
94
struct dsd_555_vco1_context
99
double ac_shift; /* DC shift needed to make waveform ac */
100
int flip_flop; /* flip/flop output state */
101
double v_out_high; /* 555 high voltage */
102
double threshold; /* falling threshold */
103
double trigger; /* rising threshold */
104
double i_charge; /* charge current */
105
double i_discharge; /* discharge current */
106
double cap_voltage; /* current capacitor voltage */
109
struct dsd_566_context
111
unsigned int state[2]; /* keeps track of excess flip_flop changes during the current step */
112
int flip_flop; /* 566 flip/flop output state */
113
double cap_voltage; /* voltage on cap */
114
double v_sqr_low; /* voltage for a squarewave at low */
115
double v_sqr_high; /* voltage for a squarewave at high */
117
double threshold_low; /* falling threshold */
118
double threshold_high; /* rising threshold */
119
double ac_shift; /* used to fake AC */
126
struct dsd_ls624_context
130
double v_cap_freq_in;
139
29
/************************************************************************
141
31
* DSD_555_ASTBL - - 555 Astable simulation
168
58
DISCRETE_STEP(dsd_555_astbl)
170
DISCRETE_DECLARE_CONTEXT(dsd_555_astbl)
171
60
DISCRETE_DECLARE_INFO(discrete_555_desc)
175
64
double dt; /* change in time */
176
65
double x_time = 0; /* time since change happened */
177
double v_cap = context->cap_voltage; /* Current voltage on capacitor, before dt */
66
double v_cap = m_cap_voltage; /* Current voltage on capacitor, before dt */
178
67
double v_cap_next = 0; /* Voltage on capacitor, after dt */
179
68
double v_charge, exponent = 0;
180
UINT8 flip_flop = context->flip_flop;
69
UINT8 flip_flop = m_flip_flop;
181
70
UINT8 update_exponent = 0;
183
73
/* put commonly used stuff in local variables for speed */
184
double threshold = context->threshold;
185
double trigger = context->trigger;
74
double threshold = m_threshold;
75
double trigger = m_trigger;
187
77
if(DSD_555_ASTBL__RESET)
189
79
/* We are in RESET */
191
context->flip_flop = 1;
192
context->cap_voltage = 0;
196
86
/* Check: if the Control Voltage node is connected. */
197
if (context->use_ctrlv)
199
89
/* If CV is less then .25V, the circuit will oscillate way out of range.
200
90
* So we will just ignore it when it happens. */
255
145
/* The voltage goes high because the cap circuit is open. */
256
146
v_cap_next = v_charge;
257
147
v_cap = v_charge;
258
context->cap_voltage = 0;
262
152
/* Update charge contstants and exponents if nodes changed */
263
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))
153
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))
265
context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED;
266
context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE;
267
context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE;
268
context->exp_bleed = RC_CHARGE_EXP(context->t_rc_bleed);
269
context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge);
270
context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge);
271
context->last_r1 = DSD_555_ASTBL__R1;
272
context->last_r2 = DSD_555_ASTBL__R2;
273
context->last_c = DSD_555_ASTBL__C;
155
m_t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED;
156
m_t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE;
157
m_t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE;
158
m_exp_bleed = RC_CHARGE_EXP(m_t_rc_bleed);
159
m_exp_charge = RC_CHARGE_EXP(m_t_rc_charge);
160
m_exp_discharge = RC_CHARGE_EXP(m_t_rc_discharge);
161
m_last_r1 = DSD_555_ASTBL__R1;
162
m_last_r2 = DSD_555_ASTBL__R2;
163
m_last_c = DSD_555_ASTBL__C;
275
165
/* Keep looping until all toggling in time sample is used up. */
345
235
v_cap = v_cap_next;
348
context->cap_voltage = v_cap;
238
m_cap_voltage = v_cap;
351
241
/* Convert last switch time to a ratio */
352
x_time = x_time / node->info->sample_time;
242
x_time = x_time / this->sample_time();
354
switch (context->output_type)
244
switch (m_output_type)
356
246
case DISC_555_OUT_SQW:
357
247
if (count_f + count_r >= 2)
358
248
/* force at least 1 toggle */
359
node->output[0] = context->flip_flop ? 0 : context->v_out_high;
249
v_out = m_flip_flop ? 0 : m_v_out_high;
361
node->output[0] = flip_flop * context->v_out_high;
362
node->output[0] += context->ac_shift;
251
v_out = flip_flop * m_v_out_high;
364
254
case DISC_555_OUT_CAP:
365
node->output[0] = v_cap;
366
256
/* Fake it to AC if needed */
367
if (context->output_is_ac)
368
node->output[0] -= threshold * 3.0 /4.0;
258
v_out -= threshold * 3.0 /4.0;
370
260
case DISC_555_OUT_ENERGY:
371
261
if (x_time == 0) x_time = 1.0;
372
node->output[0] = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time));
373
node->output[0] += context->ac_shift;
262
v_out = m_v_out_high * (flip_flop ? x_time : (1.0 - x_time));
375
265
case DISC_555_OUT_LOGIC_X:
376
node->output[0] = flip_flop + x_time;
266
v_out = flip_flop + x_time;
378
268
case DISC_555_OUT_COUNT_F_X:
379
node->output[0] = count_f ? count_f + x_time : count_f;
269
v_out = count_f ? count_f + x_time : count_f;
381
271
case DISC_555_OUT_COUNT_R_X:
382
node->output[0] = count_r ? count_r + x_time : count_r;
272
v_out = count_r ? count_r + x_time : count_r;
384
274
case DISC_555_OUT_COUNT_F:
385
node->output[0] = count_f;
387
277
case DISC_555_OUT_COUNT_R:
388
node->output[0] = count_r;
391
context->flip_flop = flip_flop;
281
set_output(0, v_out);
282
m_flip_flop = flip_flop;
394
285
DISCRETE_RESET(dsd_555_astbl)
396
DISCRETE_DECLARE_CONTEXT(dsd_555_astbl)
397
287
DISCRETE_DECLARE_INFO(discrete_555_desc)
399
node_description *v_charge_node;
401
context->use_ctrlv = (node->input_is_node >> 4) & 1;
402
context->output_type = info->options & DISC_555_OUT_MASK;
289
m_use_ctrlv = (this->input_is_node() >> 4) & 1;
290
m_output_type = info->options & DISC_555_OUT_MASK;
404
292
/* Use the defaults or supplied values. */
405
context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
293
m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
407
295
/* setup v_charge or node */
408
v_charge_node = discrete_find_node(node->info, info->v_charge);
410
context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
296
m_v_charge_node = m_device->node_output_ptr(info->v_charge);
297
if (m_v_charge_node == NULL)
413
context->v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge;
414
context->v_charge_node = NULL;
299
m_v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge;
416
if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) context->v_charge -= 0.5;
301
if (info->options & DISC_555_ASTABLE_HAS_FAST_CHARGE_DIODE) m_v_charge -= 0.5;
419
if ((DSD_555_ASTBL__CTRLV != -1) && !context->use_ctrlv)
304
if ((DSD_555_ASTBL__CTRLV != -1) && !m_use_ctrlv)
421
306
/* Setup based on supplied Control Voltage static value */
422
context->threshold = DSD_555_ASTBL__CTRLV;
423
context->trigger = DSD_555_ASTBL__CTRLV / 2.0;
307
m_threshold = DSD_555_ASTBL__CTRLV;
308
m_trigger = DSD_555_ASTBL__CTRLV / 2.0;
427
312
/* Setup based on v_pos power source */
428
context->threshold = info->v_pos * 2.0 / 3.0;
429
context->trigger = info->v_pos / 3.0;
313
m_threshold = info->v_pos * 2.0 / 3.0;
314
m_trigger = info->v_pos / 3.0;
432
317
/* optimization if none of the values are nodes */
433
context->has_rc_nodes = 0;
434
if (node->input_is_node & DSD_555_ASTBL_RC_MASK)
435
context->has_rc_nodes = 1;
319
if (this->input_is_node() & DSD_555_ASTBL_RC_MASK)
438
context->t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED;
439
context->exp_bleed = RC_CHARGE_EXP(context->t_rc_bleed);
440
context->t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE;
441
context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge);
442
context->t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE;
443
context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge);
323
m_t_rc_bleed = DSD_555_ASTBL_T_RC_BLEED;
324
m_exp_bleed = RC_CHARGE_EXP(m_t_rc_bleed);
325
m_t_rc_charge = DSD_555_ASTBL_T_RC_CHARGE;
326
m_exp_charge = RC_CHARGE_EXP(m_t_rc_charge);
327
m_t_rc_discharge = DSD_555_ASTBL_T_RC_DISCHARGE;
328
m_exp_discharge = RC_CHARGE_EXP(m_t_rc_discharge);
446
context->output_is_ac = info->options & DISC_555_OUT_AC;
331
m_output_is_ac = info->options & DISC_555_OUT_AC;
447
332
/* Calculate DC shift needed to make squarewave waveform AC */
448
context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0;
333
m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0;
450
context->flip_flop = 1;
451
context->cap_voltage = 0;
453
338
/* Step to set the output */
454
DISCRETE_STEP_CALL(dsd_555_astbl);
549
433
/* The trigger voltage goes high because the cap circuit is open.
550
434
* and the cap discharges */
551
435
v_cap = info->v_pos; /* needed for cap output type */
552
context->cap_voltage = 0;
557
context->flip_flop = 0;
563
double v_diff = context->v_charge - v_cap;
447
double v_diff = m_v_charge - v_cap;
565
449
if (UNEXPECTED(update_exponent))
566
450
exponent = RC_CHARGE_EXP_DT(DSD_555_MSTBL__R * DSD_555_MSTBL__C, dt);
568
exponent = context->exp_charge;
452
exponent = m_exp_charge;
569
453
v_cap += v_diff * exponent;
571
455
/* Has it charged past upper limit? */
572
456
/* If trigger is still enabled, then we keep charging,
573
457
* regardless of threshold. */
574
if (UNEXPECTED((v_cap >= context->threshold) && !trigger))
458
if (UNEXPECTED((v_cap >= m_threshold) && !trigger))
576
dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap - context->threshold) / v_diff)));
577
x_time = 1.0 - dt / node->info->sample_time;
460
dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C * log(1.0 / (1.0 - ((v_cap - m_threshold) / v_diff)));
461
x_time = 1.0 - dt / this->sample_time();
580
context->flip_flop = 0;
582
context->cap_voltage = v_cap;
466
m_cap_voltage = v_cap;
586
switch (context->output_type)
470
switch (m_output_type)
588
472
case DISC_555_OUT_SQW:
589
out = flip_flop * context->v_out_high - context->ac_shift;
473
out = flip_flop * m_v_out_high - m_ac_shift;
591
475
case DISC_555_OUT_CAP:
597
out -= context->ac_shift;
599
483
case DISC_555_OUT_ENERGY:
601
out = context->v_out_high * x_time;
485
out = m_v_out_high * x_time;
602
486
else if (flip_flop)
603
out = context->v_out_high;
607
out -= context->ac_shift;
610
node->output[0] = out;
613
497
DISCRETE_RESET(dsd_555_mstbl)
615
DISCRETE_DECLARE_CONTEXT(dsd_555_mstbl)
616
499
DISCRETE_DECLARE_INFO(discrete_555_desc)
618
context->output_type = info->options & DISC_555_OUT_MASK;
619
if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R))
501
m_output_type = info->options & DISC_555_OUT_MASK;
502
if ((m_output_type == DISC_555_OUT_COUNT_F) || (m_output_type == DISC_555_OUT_COUNT_R))
621
discrete_log(node->info, "Invalid Output type in NODE_%d.\n", NODE_BLOCKINDEX(node));
622
context->output_type = DISC_555_OUT_SQW;
504
m_device->discrete_log("Invalid Output type in NODE_%d.\n", this->index());
505
m_output_type = DISC_555_OUT_SQW;
625
508
/* Use the defaults or supplied values. */
626
context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
627
context->v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge;
509
m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
510
m_v_charge = (info->v_charge == DEFAULT_555_CHARGE) ? info->v_pos : info->v_charge;
629
512
/* Setup based on v_pos power source */
630
context->threshold = info->v_pos * 2.0 / 3.0;
631
context->trigger = info->v_pos / 3.0;
513
m_threshold = info->v_pos * 2.0 / 3.0;
514
m_trigger = info->v_pos / 3.0;
633
516
/* Calculate DC shift needed to make waveform AC */
634
517
if (info->options & DISC_555_OUT_AC)
636
if (context->output_type == DISC_555_OUT_CAP)
637
context->ac_shift = context->threshold * 3.0 /4.0;
519
if (m_output_type == DISC_555_OUT_CAP)
520
m_ac_shift = m_threshold * 3.0 /4.0;
639
context->ac_shift = context->v_out_high / 2.0;
522
m_ac_shift = m_v_out_high / 2.0;
642
context->ac_shift = 0;
644
context->trig_is_logic = (info->options & DISC_555_TRIGGER_IS_VOLTAGE) ? 0: 1;
645
context->trig_discharges_cap = (info->options & DISC_555_TRIGGER_DISCHARGES_CAP) ? 1: 0;
647
context->flip_flop = 0;
648
context->cap_voltage = 0;
527
m_trig_is_logic = (info->options & DISC_555_TRIGGER_IS_VOLTAGE) ? 0: 1;
528
m_trig_discharges_cap = (info->options & DISC_555_TRIGGER_DISCHARGES_CAP) ? 1: 0;
650
533
/* optimization if none of the values are nodes */
651
context->has_rc_nodes = 0;
652
if (node->input_is_node & DSD_555_MSTBL_RC_MASK)
653
context->has_rc_nodes = 1;
535
if (this->input_is_node() & DSD_555_MSTBL_RC_MASK)
655
context->exp_charge = RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C);
538
m_exp_charge = RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C);
715
597
double r_temp; /* play thing */
717
599
UINT8 update_exponent, update_t_rc;
718
UINT8 flip_flop = context->flip_flop;
600
UINT8 flip_flop = m_flip_flop;
721
605
if (UNEXPECTED(DSD_555_CC__RESET))
723
607
/* We are in RESET */
725
context->flip_flop = 1;
726
context->cap_voltage = 0;
730
dt = node->info->sample_time; /* Change in time */
731
v_cap = context->cap_voltage; /* Set to voltage before change */
614
dt = this->sample_time(); /* Change in time */
615
v_cap = m_cap_voltage; /* Set to voltage before change */
732
616
v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction; /* the max v_cap can be and still be charged by i */
733
617
/* Calculate charging current */
734
i = (context->v_cc_source - v_vcharge_limit) / DSD_555_CC__R;
618
i = (m_v_cc_source - v_vcharge_limit) / DSD_555_CC__R;
735
619
if ( i < 0) i = 0;
737
621
if (info->options & DISCRETE_555_CC_TO_CAP)
906
790
* then only the bias voltage will charge the cap. */
908
792
if (v_cap < v_vcharge_limit) v += vi;
909
else if (context->type <= 3) v = v_vcharge_limit;
793
else if (m_type <= 3) v = v_vcharge_limit;
912
796
t_rc = DSD_555_CC_T_RC_CHARGE;
914
t_rc = context->t_rc_charge;
798
t_rc = m_t_rc_charge;
915
799
if (update_exponent)
916
800
exponent = RC_CHARGE_EXP_DT(t_rc, dt);
918
exponent = context->exp_charge;
802
exponent = m_exp_charge;
920
804
v_cap_next = v_cap + ((v - v_cap) * exponent);
923
807
/* has it charged past upper limit? */
924
if (v_cap_next >= context->threshold)
808
if (v_cap_next >= m_threshold)
926
810
/* calculate the overshoot time */
927
dt = t_rc * log(1.0 / (1.0 - ((v_cap_next - context->threshold) / (v - v_cap))));
811
dt = t_rc * log(1.0 / (1.0 - ((v_cap_next - m_threshold) / (v - v_cap))));
929
v_cap_next = context->threshold;
813
v_cap_next = m_threshold;
932
816
update_exponent = 1;
971
855
v_cap = v_cap_next;
974
context->cap_voltage = v_cap;
858
m_cap_voltage = v_cap;
976
860
/* Convert last switch time to a ratio */
977
x_time = x_time / node->info->sample_time;
861
x_time = x_time / this->sample_time();
979
switch (context->output_type)
863
switch (m_output_type)
981
865
case DISC_555_OUT_SQW:
982
866
if (count_f + count_r >= 2)
983
867
/* force at least 1 toggle */
984
node->output[0] = context->flip_flop ? 0 : context->v_out_high;
868
v_out = m_flip_flop ? 0 : m_v_out_high;
986
node->output[0] = flip_flop * context->v_out_high;
870
v_out = flip_flop * m_v_out_high;
987
871
/* Fake it to AC if needed */
988
node->output[0] += context->ac_shift;
990
874
case DISC_555_OUT_CAP:
991
node->output[0] = v_cap + context->ac_shift;
875
v_out = v_cap + m_ac_shift;
993
877
case DISC_555_OUT_ENERGY:
994
878
if (x_time == 0) x_time = 1.0;
995
node->output[0] = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time));
996
node->output[0] += context->ac_shift;
879
v_out = m_v_out_high * (flip_flop ? x_time : (1.0 - x_time));
998
882
case DISC_555_OUT_LOGIC_X:
999
node->output[0] = flip_flop + x_time;
883
v_out = flip_flop + x_time;
1001
885
case DISC_555_OUT_COUNT_F_X:
1002
node->output[0] = count_f ? count_f + x_time : count_f;
886
v_out = count_f ? count_f + x_time : count_f;
1004
888
case DISC_555_OUT_COUNT_R_X:
1005
node->output[0] = count_r ? count_r + x_time : count_r;
889
v_out = count_r ? count_r + x_time : count_r;
1007
891
case DISC_555_OUT_COUNT_F:
1008
node->output[0] = count_f;
1010
894
case DISC_555_OUT_COUNT_R:
1011
node->output[0] = count_r;
1014
context->flip_flop = flip_flop;
898
set_output(0, v_out);
899
m_flip_flop = flip_flop;
1017
902
DISCRETE_RESET(dsd_555_cc)
1019
DISCRETE_DECLARE_CONTEXT(dsd_555_cc)
1020
904
DISCRETE_DECLARE_INFO(discrete_555_cc_desc)
1022
906
double r_temp, r_discharge = 0, r_charge = 0;
1024
context->flip_flop = 1;
1025
context->cap_voltage = 0;
1027
context->output_type = info->options & DISC_555_OUT_MASK;
911
m_output_type = info->options & DISC_555_OUT_MASK;
1029
913
/* Use the defaults or supplied values. */
1030
context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
1031
context->v_cc_source = (info->v_cc_source == DEFAULT_555_CC_SOURCE) ? info->v_pos : info->v_cc_source;
914
m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
915
m_v_cc_source = (info->v_cc_source == DEFAULT_555_CC_SOURCE) ? info->v_pos : info->v_cc_source;
1033
917
/* Setup based on v_pos power source */
1034
context->threshold = info->v_pos * 2.0 / 3.0;
1035
context->trigger = info->v_pos / 3.0;
918
m_threshold = info->v_pos * 2.0 / 3.0;
919
m_trigger = info->v_pos / 3.0;
1037
context->output_is_ac = info->options & DISC_555_OUT_AC;
921
m_output_is_ac = info->options & DISC_555_OUT_AC;
1038
922
/* Calculate DC shift needed to make squarewave waveform AC */
1039
context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0;
923
m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0;
1041
925
/* There are 8 different types of basic oscillators
1042
926
* depending on the resistors used. We will determine
1043
927
* the type of circuit at reset, because the ciruit type
1044
928
* is constant. See Below.
1046
context->type = (DSD_555_CC__RDIS > 0) | ((DSD_555_CC__RGND > 0) << 1) | ((DSD_555_CC__RBIAS > 0) << 2);
930
m_type = (DSD_555_CC__RDIS > 0) | ((DSD_555_CC__RGND > 0) << 1) | ((DSD_555_CC__RBIAS > 0) << 2);
1048
932
/* optimization if none of the values are nodes */
1049
context->has_rc_nodes = 0;
1050
if (node->input_is_node & DSD_555_CC_RC_MASK)
1051
context->has_rc_nodes = 1;
934
if (this->input_is_node() & DSD_555_CC_RC_MASK)
1054
switch (context->type) /* see dsd_555_cc_reset for descriptions */
938
switch (m_type) /* see dsd_555_cc_reset for descriptions */
1057
941
r_discharge = DSD_555_CC__RDIS;
1082
context->exp_bleed = RC_CHARGE_EXP(DSD_555_CC_T_RC_BLEED);
1083
context->t_rc_discharge_01 = DSD_555_CC_T_RC_DISCHARGE_01;
1084
context->exp_discharge_01 = RC_CHARGE_EXP(context->t_rc_discharge_01);
1085
context->t_rc_discharge_no_i = DSD_555_CC_T_RC_DISCHARGE_NO_I;
1086
context->exp_discharge_no_i = RC_CHARGE_EXP(context->t_rc_discharge_no_i);
1087
context->t_rc_charge = DSD_555_CC_T_RC_CHARGE;
1088
context->exp_charge = RC_CHARGE_EXP(context->t_rc_charge);
1089
context->t_rc_discharge = DSD_555_CC_T_RC_DISCHARGE;
1090
context->exp_discharge = RC_CHARGE_EXP(context->t_rc_discharge);
966
m_exp_bleed = RC_CHARGE_EXP(DSD_555_CC_T_RC_BLEED);
967
m_t_rc_discharge_01 = DSD_555_CC_T_RC_DISCHARGE_01;
968
m_exp_discharge_01 = RC_CHARGE_EXP(m_t_rc_discharge_01);
969
m_t_rc_discharge_no_i = DSD_555_CC_T_RC_DISCHARGE_NO_I;
970
m_exp_discharge_no_i = RC_CHARGE_EXP(m_t_rc_discharge_no_i);
971
m_t_rc_charge = DSD_555_CC_T_RC_CHARGE;
972
m_exp_charge = RC_CHARGE_EXP(m_t_rc_charge);
973
m_t_rc_discharge = DSD_555_CC_T_RC_DISCHARGE;
974
m_exp_discharge = RC_CHARGE_EXP(m_t_rc_discharge);
1093
977
/* Step to set the output */
1094
DISCRETE_STEP_CALL(dsd_555_cc);
1256
1139
double v_cap; /* Current voltage on capacitor, before dt */
1257
1140
double v_cap_next = 0; /* Voltage on capacitor, after dt */
1259
dt = node->info->sample_time; /* Change in time */
1260
v_cap = context->cap_voltage;
1144
dt = this->sample_time(); /* Change in time */
1145
v_cap = m_cap_voltage;
1262
1147
/* Check: if the Control Voltage node is connected. */
1263
if (context->ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */
1148
if (m_ctrlv_is_node && DSD_555_VCO1__RESET) /* reset active low */
1265
1150
/* If CV is less then .25V, the circuit will oscillate way out of range.
1266
1151
* So we will just ignore it when it happens. */
1267
1152
if (DSD_555_VCO1__VIN2 < .25) return;
1268
1153
/* If it is a node then calculate thresholds based on Control Voltage */
1269
context->threshold = DSD_555_VCO1__VIN2;
1270
context->trigger = DSD_555_VCO1__VIN2 / 2.0;
1154
m_threshold = DSD_555_VCO1__VIN2;
1155
m_trigger = DSD_555_VCO1__VIN2 / 2.0;
1271
1156
/* Since the thresholds may have changed we need to update the FF */
1272
if (v_cap >= context->threshold)
1157
if (v_cap >= m_threshold)
1275
context->flip_flop = 0;
1279
if (v_cap <= context->trigger)
1164
if (v_cap <= m_trigger)
1282
context->flip_flop = 1;
1360
context->cap_voltage = v_cap_next;
1245
m_cap_voltage = v_cap_next;
1362
1247
/* Convert last switch time to a ratio. No x_time in reset. */
1363
x_time = x_time / node->info->sample_time;
1248
x_time = x_time / this->sample_time();
1364
1249
if (!DSD_555_VCO1__RESET) x_time = 0;
1366
switch (context->output_type)
1251
switch (m_output_type)
1368
1253
case DISC_555_OUT_SQW:
1369
node->output[0] = context->flip_flop * context->v_out_high + context->ac_shift;
1254
v_out = m_flip_flop * m_v_out_high + m_ac_shift;
1371
1256
case DISC_555_OUT_CAP:
1372
node->output[0] = v_cap_next;
1373
1258
/* Fake it to AC if needed */
1374
if (context->output_is_ac)
1375
node->output[0] -= context->threshold * 3.0 /4.0;
1260
v_out -= m_threshold * 3.0 /4.0;
1377
1262
case DISC_555_OUT_ENERGY:
1378
1263
if (x_time == 0) x_time = 1.0;
1379
node->output[0] = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time));
1380
node->output[0] += context->ac_shift;
1264
v_out = m_v_out_high * (m_flip_flop ? x_time : (1.0 - x_time));
1265
v_out += m_ac_shift;
1382
1267
case DISC_555_OUT_LOGIC_X:
1383
node->output[0] = context->flip_flop + x_time;
1268
v_out = m_flip_flop + x_time;
1385
1270
case DISC_555_OUT_COUNT_F_X:
1386
node->output[0] = count_f ? count_f + x_time : count_f;
1271
v_out = count_f ? count_f + x_time : count_f;
1388
1273
case DISC_555_OUT_COUNT_R_X:
1389
node->output[0] = count_r ? count_r + x_time : count_r;
1274
v_out = count_r ? count_r + x_time : count_r;
1391
1276
case DISC_555_OUT_COUNT_F:
1392
node->output[0] = count_f;
1394
1279
case DISC_555_OUT_COUNT_R:
1395
node->output[0] = count_r;
1283
set_output(0, v_out);
1400
1286
DISCRETE_RESET(dsd_555_vco1)
1402
DISCRETE_DECLARE_CONTEXT(dsd_555_vco1)
1403
1288
DISCRETE_DECLARE_INFO(discrete_555_vco1_desc)
1405
1290
double v_ratio_r3, v_ratio_r4_1, r_in_1;
1407
context->output_type = info->options & DISC_555_OUT_MASK;
1408
context->output_is_ac = info->options & DISC_555_OUT_AC;
1292
m_output_type = info->options & DISC_555_OUT_MASK;
1293
m_output_is_ac = info->options & DISC_555_OUT_AC;
1410
1295
/* Setup op-amp parameters */
1424
1309
/* Now that we know the voltages entering the op amp and the resistance for the
1425
1310
* FF states, we can predetermine the ratios for the charge/discharge currents. */
1426
context->i_discharge = (1 - v_ratio_r3) / info->r1;
1427
context->i_charge = (v_ratio_r3 - v_ratio_r4_1) / r_in_1;
1311
m_i_discharge = (1 - v_ratio_r3) / info->r1;
1312
m_i_charge = (v_ratio_r3 - v_ratio_r4_1) / r_in_1;
1429
1314
/* the cap starts off discharged */
1430
context->cap_voltage = 0;
1432
1317
/* Setup 555 parameters */
1434
1319
/* There is no charge on the cap so the 555 goes high at init. */
1435
context->flip_flop = 1;
1436
context->ctrlv_is_node = (node->input_is_node >> 2) & 1;
1437
context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
1321
m_ctrlv_is_node = (this->input_is_node() >> 2) & 1;
1322
m_v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
1439
1324
/* Calculate 555 thresholds.
1440
1325
* If the Control Voltage is a node, then the thresholds will be calculated each step.
1441
1326
* If the Control Voltage is a fixed voltage, then the thresholds will be calculated
1442
1327
* from that. Otherwise we will use thresholds based on v_pos. */
1443
if (!context->ctrlv_is_node && (DSD_555_VCO1__VIN2 != -1))
1328
if (!m_ctrlv_is_node && (DSD_555_VCO1__VIN2 != -1))
1445
1330
/* Setup based on supplied Control Voltage static value */
1446
context->threshold = DSD_555_VCO1__VIN2;
1447
context->trigger = DSD_555_VCO1__VIN2 / 2.0;
1331
m_threshold = DSD_555_VCO1__VIN2;
1332
m_trigger = DSD_555_VCO1__VIN2 / 2.0;
1451
1336
/* Setup based on v_pos power source */
1452
context->threshold = info->v_pos * 2.0 / 3.0;
1453
context->trigger = info->v_pos / 3.0;
1337
m_threshold = info->v_pos * 2.0 / 3.0;
1338
m_trigger = info->v_pos / 3.0;
1456
1341
/* Calculate DC shift needed to make squarewave waveform AC */
1457
context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0;
1342
m_ac_shift = m_output_is_ac ? -m_v_out_high / 2.0 : 0;
1546
1429
double v_cap; /* Current voltage on capacitor, before dt */
1547
1430
int count_f = 0, count_r = 0;
1549
dt = node->info->sample_time; /* Change in time */
1550
v_cap = context->cap_voltage; /* Set to voltage before change */
1434
dt = this->sample_time(); /* Change in time */
1435
v_cap = m_cap_voltage; /* Set to voltage before change */
1552
1437
/* Calculate charging current if it is in range */
1553
if (EXPECTED(DSD_566__VMOD > context->v_osc_stop))
1438
if (EXPECTED(DSD_566__VMOD > m_v_osc_stop))
1555
1440
double v_charge = DSD_566__VCHARGE - DSD_566__VMOD - 0.1;
1556
1441
if (v_charge > 0)
1558
1443
i = (v_charge * .95) / DSD_566__R;
1559
if (DSD_566__VMOD < context->v_osc_stable)
1444
if (DSD_566__VMOD < m_v_osc_stable)
1561
1446
/* no where near correct calculation of non linear range */
1562
i_rise = ((DSD_566__VCHARGE - context->v_osc_stable - 0.1) * .95) / DSD_566__R;
1563
i_rise *= 1.0 - (context->v_osc_stable - DSD_566__VMOD) / (context->v_osc_stable - context->v_osc_stop);
1447
i_rise = ((DSD_566__VCHARGE - m_v_osc_stable - 0.1) * .95) / DSD_566__R;
1448
i_rise *= 1.0 - (m_v_osc_stable - DSD_566__VMOD) / (m_v_osc_stable - m_v_osc_stop);
1604
1489
if (UNEXPECTED(v_cap > DSD_566__VMOD)) v_cap = DSD_566__VMOD;
1606
1491
/* has it charged past upper limit? */
1607
if (UNEXPECTED(v_cap > context->threshold_high))
1492
if (UNEXPECTED(v_cap > m_threshold_high))
1609
1494
/* calculate the overshoot time */
1610
dt = DSD_566__C * (v_cap - context->threshold_high) / i;
1611
v_cap = context->threshold_high;
1612
context->flip_flop = 1;
1495
dt = DSD_566__C * (v_cap - m_threshold_high) / i;
1496
v_cap = m_threshold_high;
1619
context->cap_voltage = v_cap;
1504
m_cap_voltage = v_cap;
1621
1506
/* Convert last switch time to a ratio */
1622
x_time /= node->info->sample_time;
1507
x_time /= this->sample_time();
1624
switch (context->out_type)
1626
1511
case DISC_566_OUT_SQUARE:
1627
node->output[0] = context->flip_flop ? context->v_sqr_high : context->v_sqr_low;
1628
if (context->fake_ac)
1629
node->output[0] += context->ac_shift;
1512
v_out = m_flip_flop ? m_v_sqr_high : m_v_sqr_low;
1514
v_out += m_ac_shift;
1631
1516
case DISC_566_OUT_ENERGY:
1632
1517
if (x_time == 0) x_time = 1.0;
1633
node->output[0] = context->v_sqr_low + context->v_sqr_diff * (context->flip_flop ? x_time : (1.0 - x_time));
1634
if (context->fake_ac)
1635
node->output[0] += context->ac_shift;
1518
v_out = m_v_sqr_low + m_v_sqr_diff * (m_flip_flop ? x_time : (1.0 - x_time));
1520
v_out += m_ac_shift;
1637
1522
case DISC_566_OUT_LOGIC:
1638
node->output[0] = context->flip_flop;
1523
v_out = m_flip_flop;
1640
1525
case DISC_566_OUT_TRIANGLE:
1641
node->output[0] = v_cap;
1642
if (context->fake_ac)
1643
node->output[0] += context->ac_shift;
1528
v_out += m_ac_shift;
1645
1530
case DISC_566_OUT_COUNT_F_X:
1646
node->output[0] = count_f ? count_f + x_time : count_f;
1531
v_out = count_f ? count_f + x_time : count_f;
1648
1533
case DISC_566_OUT_COUNT_R_X:
1649
node->output[0] = count_r ? count_r + x_time : count_r;
1534
v_out = count_r ? count_r + x_time : count_r;
1651
1536
case DISC_566_OUT_COUNT_F:
1652
node->output[0] = count_f;
1654
1539
case DISC_566_OUT_COUNT_R:
1655
node->output[0] = count_r;
1543
set_output(0, v_out);
1660
1546
DISCRETE_RESET(dsd_566)
1662
DISCRETE_DECLARE_CONTEXT(dsd_566)
1665
1549
double v_float;
1667
context->out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK;
1668
context->fake_ac = (int)DSD_566__OPTIONS & DISC_566_OUT_AC;
1551
m_out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK;
1552
m_fake_ac = (int)DSD_566__OPTIONS & DISC_566_OUT_AC;
1670
1554
if (DSD_566__VNEG >= DSD_566__VPOS)
1671
fatalerror("[v_neg >= v_pos] in NODE_%d!\n", NODE_BLOCKINDEX(node));
1555
fatalerror("[v_neg >= v_pos] in NODE_%d!\n", this->index());
1673
1557
v_float = DSD_566__VPOS - DSD_566__VNEG;
1674
1558
v_int = (int)v_float;
1675
1559
if ( v_float < 10 || v_float > 15 )
1676
fatalerror("v_neg and/or v_pos out of range in NODE_%d\n", NODE_BLOCKINDEX(node));
1560
fatalerror("v_neg and/or v_pos out of range in NODE_%d\n", this->index());
1677
1561
if ( v_float != v_int )
1678
1562
/* fatal for now. */
1679
fatalerror("Power should be integer in NODE_%d\n", NODE_BLOCKINDEX(node));
1563
fatalerror("Power should be integer in NODE_%d\n", this->index());
1681
context->flip_flop = 0;
1682
context->cap_voltage = 0;
1685
context->threshold_high = ne566.c_high[v_int] + DSD_566__VNEG;
1686
context->threshold_low = ne566.c_low[v_int] + DSD_566__VNEG;
1687
context->v_sqr_high = DSD_566__VPOS - 1;
1688
context->v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG;
1689
context->v_sqr_diff = context->v_sqr_high - context->v_sqr_low;
1690
context->v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG;
1691
context->v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG;
1569
m_threshold_high = ne566.c_high[v_int] + DSD_566__VNEG;
1570
m_threshold_low = ne566.c_low[v_int] + DSD_566__VNEG;
1571
m_v_sqr_high = DSD_566__VPOS - 1;
1572
m_v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG;
1573
m_v_sqr_diff = m_v_sqr_high - m_v_sqr_low;
1574
m_v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG;
1575
m_v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG;
1693
context->ac_shift = 0;
1694
if (context->fake_ac)
1696
if (context->out_type == DISC_566_OUT_TRIANGLE)
1697
context->ac_shift = (context->threshold_high - context->threshold_low) / 2 - context->threshold_high;
1580
if (m_out_type == DISC_566_OUT_TRIANGLE)
1581
m_ac_shift = (m_threshold_high - m_threshold_low) / 2 - m_threshold_high;
1699
context->ac_shift = context->v_sqr_diff / 2 - context->v_sqr_high;
1583
m_ac_shift = m_v_sqr_diff / 2 - m_v_sqr_high;
1702
1586
/* Step the output */
1703
DISCRETE_STEP_CALL(dsd_566);
1824
1706
/* calculate the overshoot time */
1826
context->flip_flop ^= 1;
1827
if (context->flip_flop)
1831
1713
/* fix up any frequency increase change errors */
1832
while(t_used > node->info->sample_time)
1833
t_used -= node->info->sample_time;
1714
while(t_used > this->sample_time())
1715
t_used -= this->sample_time();
1834
1716
x_time = t_used;
1839
context->t_used = t_used;
1841
1723
/* Convert last switch time to a ratio */
1842
x_time = x_time / node->info->sample_time;
1724
x_time = x_time / this->sample_time();
1844
switch (context->out_type)
1846
1728
case DISC_LS624_OUT_LOGIC_X:
1847
node->output[0] = context->flip_flop + x_time;
1729
set_output(0, m_flip_flop + x_time);
1849
1731
case DISC_LS624_OUT_COUNT_F_X:
1850
node->output[0] = count_f ? count_f + x_time : count_f;
1732
set_output(0, count_f ? count_f + x_time : count_f);
1852
1734
case DISC_LS624_OUT_COUNT_R_X:
1853
node->output[0] = count_r ? count_r + x_time : count_r;
1735
set_output(0, count_r ? count_r + x_time : count_r);
1855
1737
case DISC_LS624_OUT_COUNT_F:
1856
node->output[0] = count_f;
1738
set_output(0, count_f);
1858
1740
case DISC_LS624_OUT_COUNT_R:
1859
node->output[0] = count_r;
1741
set_output(0, count_r);
1861
1743
case DISC_LS624_OUT_ENERGY:
1862
1744
if (x_time == 0) x_time = 1.0;
1863
node->output[0] = LS624_OUT_HIGH * (context->flip_flop ? x_time : (1.0 - x_time));
1745
set_output(0, LS624_OUT_HIGH * (m_flip_flop ? x_time : (1.0 - x_time)));
1865
1747
case DISC_LS624_OUT_LOGIC:
1866
node->output[0] = context->flip_flop;
1748
set_output(0, m_flip_flop);
1868
1750
case DISC_LS624_OUT_SQUARE:
1869
node->output[0] = context->flip_flop ? LS624_OUT_HIGH : 0;
1751
set_output(0, m_flip_flop ? LS624_OUT_HIGH : 0);
1874
1756
DISCRETE_RESET(dsd_ls624)
1876
struct dsd_ls624_context *context = (struct dsd_ls624_context *)node->context;
1878
context->out_type = (int)DSD_LS624__OUTTYPE;
1880
context->flip_flop = 0;
1881
context->t_used = 0;
1882
context->v_freq_scale = LS624_IN_R / (DSD_LS624__R_FREQ_IN + LS624_IN_R);
1883
context->v_rng_scale = LS624_IN_R / (DSD_LS624__R_RNG_IN + LS624_IN_R);
1758
m_out_type = (int)DSD_LS624__OUTTYPE;
1762
m_v_freq_scale = LS624_IN_R / (DSD_LS624__R_FREQ_IN + LS624_IN_R);
1763
m_v_rng_scale = LS624_IN_R / (DSD_LS624__R_RNG_IN + LS624_IN_R);
1884
1764
if (DSD_LS624__C_FREQ_IN > 0)
1886
context->has_freq_in_cap = 1;
1887
context->exponent = RC_CHARGE_EXP(RES_2_PARALLEL(DSD_LS624__R_FREQ_IN, LS624_IN_R) * DSD_LS624__C_FREQ_IN);
1888
context->v_cap_freq_in = 0;
1766
m_has_freq_in_cap = 1;
1767
m_exponent = RC_CHARGE_EXP(RES_2_PARALLEL(DSD_LS624__R_FREQ_IN, LS624_IN_R) * DSD_LS624__C_FREQ_IN);
1768
m_v_cap_freq_in = 0;
1891
context->has_freq_in_cap = 0;
1771
m_has_freq_in_cap = 0;
1893
node->output[0] = 0;