~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/emu/sound/disc_dev.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
        int             output_is_ac;
59
59
        double  ac_shift;                               /* DC shift needed to make waveform ac */
60
60
        int             flip_flop;                              /* 555 flip/flop output state */
 
61
        int             has_rc_nodes;
 
62
        double  exp_charge;
61
63
        double  cap_voltage;                    /* voltage on cap */
62
64
        double  threshold;
63
65
        double  trigger;
106
108
 
107
109
struct dsd_566_context
108
110
{
109
 
        int                     error;
110
111
        unsigned int state[2];                  /* keeps track of excess flip_flop changes during the current step */
111
112
        int                     flip_flop;                      /* 566 flip/flop output state */
112
113
        double          cap_voltage;            /* voltage on cap */
113
 
        double          v_charge;                       /* static charge value */
114
 
        double     *v_charge_node;              /* point to charge node */
115
114
        double          v_sqr_low;                      /* voltage for a squarewave at low */
116
115
        double          v_sqr_high;                     /* voltage for a squarewave at high */
 
116
        double          v_sqr_diff;
117
117
        double          threshold_low;          /* falling threshold */
118
118
        double          threshold_high;         /* rising threshold */
119
 
        double          triangle_ac_offset;     /* used to shift a triangle to AC */
 
119
        double          ac_shift;                       /* used to fake AC */
 
120
        double          v_osc_stable;
 
121
        double          v_osc_stop;
 
122
        int                     fake_ac;
 
123
        int                     out_type;
120
124
};
121
125
 
122
126
struct dsd_ls624_context
124
128
        int                     state;
125
129
        double          remain;                 /* remaining time from last step */
126
130
        int                     out_type;
 
131
        double          k1;                             /* precalculated cap part of formula */
 
132
        double          k2;                             /* precalculated ring part of formula */
 
133
        double          dt_vmod_at_0;
 
134
};
 
135
 
 
136
struct dsd_ls629_context
 
137
{
 
138
        double  v_bias;
 
139
        double  v_cap;
 
140
        double  v_peak;
 
141
        double  v_threshold;
 
142
        double  k_vmod_to_i;
 
143
        int             flip_flop;
 
144
        int             out_type;
127
145
};
128
146
 
129
147
 
141
159
 *
142
160
 * Jan 2004, D Renaud.
143
161
 ************************************************************************/
144
 
#define DSD_555_ASTBL__RESET    (! *(node->input[0]))
145
 
#define DSD_555_ASTBL__R1               (*(node->input[1]))
146
 
#define DSD_555_ASTBL__R2               (*(node->input[2]))
147
 
#define DSD_555_ASTBL__C                (*(node->input[3]))
148
 
#define DSD_555_ASTBL__CTRLV    (*(node->input[4]))
 
162
#define DSD_555_ASTBL__RESET    (! DISCRETE_INPUT(0))
 
163
#define DSD_555_ASTBL__R1               DISCRETE_INPUT(1)
 
164
#define DSD_555_ASTBL__R2               DISCRETE_INPUT(2)
 
165
#define DSD_555_ASTBL__C                DISCRETE_INPUT(3)
 
166
#define DSD_555_ASTBL__CTRLV    DISCRETE_INPUT(4)
149
167
 
150
168
/* bit mask of the above RC inputs */
151
169
#define DSD_555_ASTBL_RC_MASK   0x0e
168
186
        double  v_cap   = context->cap_voltage; /* Current voltage on capacitor, before dt */
169
187
        double  v_cap_next = 0;                                 /* Voltage on capacitor, after dt */
170
188
        double  v_charge, exponent = 0;
171
 
        int             update_exponent = 0;
 
189
        UINT8   flip_flop = context->flip_flop;
 
190
        UINT8   update_exponent = 0;
172
191
 
173
192
        /* put commonly used stuff in local variables for speed */
174
193
        double  threshold = context->threshold;
195
214
                /* Since the thresholds may have changed we need to update the FF */
196
215
                if (v_cap >= threshold)
197
216
                {
198
 
                        context->flip_flop = 0;
 
217
                        flip_flop = 0;
199
218
                        count_f++;
200
219
                }
201
220
                else
202
221
                if (v_cap <= trigger)
203
222
                {
204
 
                        context->flip_flop = 1;
 
223
                        flip_flop = 1;
205
224
                        count_r++;
206
225
                }
207
226
        }
234
253
     * dt = R*C(log(1/(1-(Vc/Vr))))
235
254
     */
236
255
 
237
 
        dt = discrete_current_context->sample_time;
 
256
        dt = node->info->sample_time;
238
257
 
239
258
        /* Sometimes a switching network is used to setup the capacitance.
240
259
     * These may select no capacitor, causing oscillation to stop.
241
260
     */
242
261
        if (DSD_555_ASTBL__C == 0)
243
262
        {
244
 
                context->flip_flop = 1;
 
263
                flip_flop = 1;
245
264
                /* The voltage goes high because the cap circuit is open. */
246
265
                v_cap_next = v_charge;
247
266
                v_cap      = v_charge;
265
284
                /* Keep looping until all toggling in time sample is used up. */
266
285
                do
267
286
                {
268
 
                        if (context->flip_flop)
 
287
                        if (flip_flop)
269
288
                        {
270
289
                                if (DSD_555_ASTBL__R1 == 0)
271
290
                                {
294
313
                                                /* calculate the overshoot time */
295
314
                                                dt     = context->t_rc_charge  * log(1.0 / (1.0 - ((v_cap_next - threshold) / (v_charge - v_cap))));
296
315
                                                x_time = dt;
297
 
                                                v_cap  = threshold;
298
 
                                                context->flip_flop = 0;
 
316
                                                v_cap_next  = threshold;
 
317
                                                flip_flop = 0;
299
318
                                                count_f++;
300
319
                                                update_exponent = 1;
301
320
                                        }
326
345
                                        if (v_cap_next < trigger)
327
346
                                                dt = context->t_rc_discharge  * log(1.0 / (1.0 - ((trigger - v_cap_next) / v_cap)));
328
347
                                        x_time = dt;
329
 
                                        v_cap  = trigger;
330
 
                                        context->flip_flop = 1;
 
348
                                        v_cap_next  = trigger;
 
349
                                        flip_flop = 1;
331
350
                                        count_r++;
332
351
                                        update_exponent = 1;
333
352
                                }
334
353
                        }
 
354
                        v_cap = v_cap_next;
335
355
                } while(dt);
336
356
 
337
 
                context->cap_voltage = v_cap_next;
 
357
                context->cap_voltage = v_cap;
338
358
        }
339
359
 
340
360
        /* Convert last switch time to a ratio */
341
 
        x_time = x_time / discrete_current_context->sample_time;
 
361
        x_time = x_time / node->info->sample_time;
342
362
 
343
363
        switch (context->output_type)
344
364
        {
345
365
                case DISC_555_OUT_SQW:
346
 
                        node->output[0] = context->flip_flop * context->v_out_high + context->ac_shift;
 
366
                        if (count_f + count_r >= 2)
 
367
                                /* force at least 1 toggle */
 
368
                                node->output[0] = context->flip_flop ? 0 : context->v_out_high;
 
369
                        else
 
370
                                node->output[0] = flip_flop * context->v_out_high;
 
371
                        node->output[0] += context->ac_shift;
347
372
                        break;
348
373
                case DISC_555_OUT_CAP:
349
 
                        node->output[0] = v_cap_next;
 
374
                        node->output[0] = v_cap;
350
375
                        /* Fake it to AC if needed */
351
376
                        if (context->output_is_ac)
352
377
                                node->output[0] -= threshold * 3.0 /4.0;
353
378
                        break;
354
379
                case DISC_555_OUT_ENERGY:
355
380
                        if (x_time == 0) x_time = 1.0;
356
 
                        node->output[0]  = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time));
 
381
                        node->output[0]  = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time));
357
382
                        node->output[0] += context->ac_shift;
358
383
                        break;
359
384
                case DISC_555_OUT_LOGIC_X:
360
 
                        node->output[0] = context->flip_flop + x_time;
 
385
                        node->output[0] = flip_flop + x_time;
361
386
                        break;
362
387
                case DISC_555_OUT_COUNT_F_X:
363
388
                        node->output[0] = count_f ? count_f + x_time : count_f;
372
397
                        node->output[0] = count_r;
373
398
                        break;
374
399
        }
 
400
        context->flip_flop = flip_flop;
375
401
}
376
402
 
377
403
static DISCRETE_RESET(dsd_555_astbl)
387
413
        context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high;
388
414
 
389
415
        /* setup v_charge or node */
390
 
        v_charge_node = discrete_find_node(NULL, info->v_charge);
 
416
        v_charge_node = discrete_find_node(node->info, info->v_charge);
391
417
        if (v_charge_node)
392
418
                context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
393
419
        else
450
476
 *
451
477
 * Oct 2004, D Renaud.
452
478
 ************************************************************************/
453
 
#define DSD_555_MSTBL__RESET    (! *(node->input[0]))
454
 
#define DSD_555_MSTBL__TRIGGER  (*(node->input[1]))
455
 
#define DSD_555_MSTBL__R                (*(node->input[2]))
456
 
#define DSD_555_MSTBL__C                (*(node->input[3]))
 
479
#define DSD_555_MSTBL__RESET    (! DISCRETE_INPUT(0))
 
480
#define DSD_555_MSTBL__TRIGGER  DISCRETE_INPUT(1)
 
481
#define DSD_555_MSTBL__R                DISCRETE_INPUT(2)
 
482
#define DSD_555_MSTBL__C                DISCRETE_INPUT(3)
 
483
 
 
484
/* bit mask of the above RC inputs */
 
485
#define DSD_555_MSTBL_RC_MASK   0x0c
457
486
 
458
487
static DISCRETE_STEP(dsd_555_mstbl)
459
488
{
462
491
 
463
492
        double v_cap;                   /* Current voltage on capacitor, before dt */
464
493
        double v_cap_next = 0;  /* Voltage on capacitor, after dt */
 
494
        double x_time  = 0;             /* time since change happened */
 
495
        double dt, exponent;
 
496
        int trigger = 0;
 
497
        int trigger_type;
 
498
        int update_exponent = 0;
465
499
 
466
500
        if(DSD_555_MSTBL__RESET)
467
501
        {
469
503
                node->output[0]     = 0;
470
504
                context->flip_flop  = 0;
471
505
                context->cap_voltage = 0;
472
 
        }
473
 
        else
474
 
        {
475
 
                int trigger;
476
 
 
477
 
                if (context->trig_is_logic)
478
 
                        trigger = !DSD_555_MSTBL__TRIGGER;
479
 
                else
480
 
                        trigger = DSD_555_MSTBL__TRIGGER < context->trigger;
481
 
 
482
 
                if (context->trig_discharges_cap && trigger)
 
506
                return;
 
507
        }
 
508
 
 
509
        trigger_type = info->options;
 
510
        dt = node->info->sample_time;
 
511
 
 
512
        switch (trigger_type & DSD_555_TRIGGER_TYPE_MASK)
 
513
        {
 
514
                case DISC_555_TRIGGER_IS_LOGIC:
 
515
                        trigger = (int)!DSD_555_MSTBL__TRIGGER;
 
516
                        break;
 
517
                case DISC_555_TRIGGER_IS_VOLTAGE:
 
518
                        trigger = (int)(DSD_555_MSTBL__TRIGGER < context->trigger);
 
519
                        break;
 
520
                case DISC_555_TRIGGER_IS_COUNT:
 
521
                        trigger = (int)DSD_555_MSTBL__TRIGGER;
 
522
                        if (trigger && !context->flip_flop)
 
523
                        {
 
524
                                x_time = DSD_555_MSTBL__TRIGGER - trigger;
 
525
                                if (x_time != 0)
 
526
                                {
 
527
                                        /* adjust sample to after trigger */
 
528
                                        x_time = (1.0 - x_time);
 
529
                                        update_exponent = 1;
 
530
                                        dt = x_time * node->info->sample_time;
 
531
                                }
 
532
                        }
 
533
                        break;
 
534
        }
 
535
 
 
536
        if ((trigger_type & DISC_555_TRIGGER_DISCHARGES_CAP) && trigger)
 
537
                context->cap_voltage = 0;
 
538
 
 
539
        /* Wait for trigger */
 
540
        if (!context->flip_flop && trigger)
 
541
                context->flip_flop = 1;
 
542
 
 
543
        if (context->flip_flop)
 
544
        {
 
545
                v_cap = context->cap_voltage;
 
546
 
 
547
                /* Sometimes a switching network is used to setup the capacitance.
 
548
         * These may select 'no' capacitor, causing oscillation to stop.
 
549
         */
 
550
                if (DSD_555_MSTBL__C == 0)
 
551
                {
 
552
                        context->flip_flop = 0;
 
553
                        /* The voltage goes high because the cap circuit is open. */
 
554
                        v_cap_next = info->v_pos;
 
555
                        v_cap      = info->v_pos;
483
556
                        context->cap_voltage = 0;
484
 
 
485
 
                if (!context->flip_flop)
486
 
                {
487
 
                        /* Wait for trigger */
488
 
                        if (trigger)
489
 
                                context->flip_flop = 1;
490
557
                }
491
558
                else
492
559
                {
493
 
                        v_cap = context->cap_voltage;
 
560
                        /* Charging */
 
561
                        update_exponent |= context->has_rc_nodes;
 
562
                        if (update_exponent)
 
563
                                exponent = RC_CHARGE_EXP_DT(DSD_555_MSTBL__R * DSD_555_MSTBL__C, dt);
 
564
                        else
 
565
                                exponent = context->exp_charge;
 
566
                        v_cap_next = v_cap + ((info->v_pos - v_cap) * exponent);
494
567
 
495
 
                        /* Sometimes a switching network is used to setup the capacitance.
496
 
             * These may select 'no' capacitor, causing oscillation to stop.
497
 
             */
498
 
                        if (DSD_555_MSTBL__C == 0)
 
568
                        /* Has it charged past upper limit? */
 
569
                        /* If trigger is still enabled, then we keep charging,
 
570
             * regardless of threshold. */
 
571
                        if ((v_cap_next >= context->threshold) && !trigger)
499
572
                        {
 
573
                                dt = DSD_555_MSTBL__R * DSD_555_MSTBL__C  * log(1.0 / (1.0 - ((v_cap_next - context->threshold) / (context->v_charge - v_cap))));
 
574
                                x_time = dt / node->info->sample_time;
 
575
                                v_cap_next = 0;
 
576
                                v_cap      = context->threshold;
500
577
                                context->flip_flop = 0;
501
 
                                /* The voltage goes high because the cap circuit is open. */
502
 
                                v_cap_next = info->v_pos;
503
 
                                v_cap      = info->v_pos;
504
 
                                context->cap_voltage = 0;
505
 
                        }
506
 
                        else
507
 
                        {
508
 
                                /* Charging */
509
 
                                v_cap_next = v_cap + ((info->v_pos - v_cap) * RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C));
510
 
 
511
 
                                /* Has it charged past upper limit? */
512
 
                                /* If trigger is still enabled, then we keep charging,
513
 
                 * regardless of threshold. */
514
 
                                if ((v_cap_next >= context->threshold) && !trigger)
515
 
                                {
516
 
                                        v_cap_next = 0;
517
 
                                        v_cap      = context->threshold;
518
 
                                        context->flip_flop = 0;
519
 
                                }
520
 
                        }
521
 
 
522
 
                        context->cap_voltage = v_cap_next;
523
 
 
524
 
                        switch (info->options & DISC_555_OUT_MASK)
525
 
                        {
526
 
                                case DISC_555_OUT_SQW:
527
 
                                        node->output[0] = context->flip_flop * context->v_out_high;
528
 
                                        /* Fake it to AC if needed */
529
 
                                        if (context->output_is_ac)
530
 
                                                node->output[0] -= context->v_out_high / 2.0;
531
 
                                        break;
532
 
                                case DISC_555_OUT_CAP:
533
 
                                        node->output[0] = v_cap_next;
534
 
                                        /* Fake it to AC if needed */
535
 
                                        if (context->output_is_ac)
536
 
                                                node->output[0] -= context->threshold * 3.0 /4.0;
537
 
                                        break;
538
578
                        }
539
579
                }
 
580
 
 
581
                context->cap_voltage = v_cap_next;
 
582
        }
 
583
 
 
584
        switch (info->options & DISC_555_OUT_MASK)
 
585
        {
 
586
                case DISC_555_OUT_SQW:
 
587
                        node->output[0] = context->flip_flop * context->v_out_high;
 
588
                        /* Fake it to AC if needed */
 
589
                        if (context->output_is_ac)
 
590
                                node->output[0] -= context->v_out_high / 2.0;
 
591
                        break;
 
592
                case DISC_555_OUT_CAP:
 
593
                        node->output[0] = v_cap_next;
 
594
                        /* Fake it to AC if needed */
 
595
                        if (context->output_is_ac)
 
596
                                node->output[0] -= context->threshold * 3.0 /4.0;
 
597
                        break;
 
598
                case DISC_555_OUT_ENERGY:
 
599
                        if (x_time == 0) x_time = 1.0;
 
600
                        node->output[0] = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time));
 
601
                                if (context->output_is_ac)
 
602
                                        node->output[0] -= context->v_out_high / 2.0;
 
603
                        break;
540
604
        }
541
605
}
542
606
 
548
612
        context->output_type = info->options & DISC_555_OUT_MASK;
549
613
        if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R))
550
614
        {
551
 
                discrete_log("Invalid Output type in NODE_%d.\n", node->node - NODE_00);
 
615
                discrete_log(node->info, "Invalid Output type in NODE_%d.\n", NODE_BLOCKINDEX(node));
552
616
                context->output_type = DISC_555_OUT_SQW;
553
617
        }
554
618
 
570
634
        context->flip_flop   = 0;
571
635
        context->cap_voltage = 0;
572
636
 
 
637
        /* optimization if none of the values are nodes */
 
638
        context->has_rc_nodes = 0;
 
639
        if (node->input_is_node & DSD_555_MSTBL_RC_MASK)
 
640
                context->has_rc_nodes = 1;
 
641
        else
 
642
                context->exp_charge = RC_CHARGE_EXP(DSD_555_MSTBL__R * DSD_555_MSTBL__C);
 
643
 
573
644
        node->output[0] = 0;
574
645
}
575
646
 
590
661
 *
591
662
 * Mar 2004, D Renaud.
592
663
 ************************************************************************/
593
 
#define DSD_555_CC__RESET       (! *(node->input[0]))
594
 
#define DSD_555_CC__VIN         (*(node->input[1]))
595
 
#define DSD_555_CC__R           (*(node->input[2]))
596
 
#define DSD_555_CC__C           (*(node->input[3]))
597
 
#define DSD_555_CC__RBIAS       (*(node->input[4]))
598
 
#define DSD_555_CC__RGND        (*(node->input[5]))
599
 
#define DSD_555_CC__RDIS        (*(node->input[6]))
 
664
#define DSD_555_CC__RESET       (! DISCRETE_INPUT(0))
 
665
#define DSD_555_CC__VIN         DISCRETE_INPUT(1)
 
666
#define DSD_555_CC__R           DISCRETE_INPUT(2)
 
667
#define DSD_555_CC__C           DISCRETE_INPUT(3)
 
668
#define DSD_555_CC__RBIAS       DISCRETE_INPUT(4)
 
669
#define DSD_555_CC__RGND        DISCRETE_INPUT(5)
 
670
#define DSD_555_CC__RDIS        DISCRETE_INPUT(6)
600
671
 
601
672
/* bit mask of the above RC inputs not including DSD_555_CC__R */
602
673
#define DSD_555_CC_RC_MASK      0x78
630
701
        double  v_vcharge_limit;        /* vIn and the junction voltage limit the max charging voltage from i */
631
702
        double  r_temp;                         /* play thing */
632
703
        double  exponent;
633
 
        int             update_exponent, update_t_rc;
634
 
 
635
 
 
636
 
        if (DSD_555_CC__RESET)
 
704
        UINT8   update_exponent, update_t_rc;
 
705
        UINT8   flip_flop = context->flip_flop;
 
706
 
 
707
 
 
708
        if (UNEXPECTED(DSD_555_CC__RESET))
637
709
        {
638
710
                /* We are in RESET */
639
711
                node->output[0]      = 0;
642
714
                return;
643
715
        }
644
716
 
645
 
        dt    = discrete_current_context->sample_time;  /* Change in time */
 
717
        dt    = node->info->sample_time;        /* Change in time */
646
718
        v_cap = context->cap_voltage;   /* Set to voltage before change */
647
719
        v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction;        /* the max v_cap can be and still be charged by i */
648
720
        /* Calculate charging current */
703
775
                if (context->type <= 1)
704
776
                {
705
777
                        /* Standard constant current charge */
706
 
                        if (context->flip_flop)
 
778
                        if (flip_flop)
707
779
                        {
708
780
                                if (i == 0)
709
781
                                {
739
811
                                                /* calculate the overshoot time */
740
812
                                                dt     = DSD_555_CC__C * (v_cap_next - context->threshold) / i;
741
813
                                                x_time = dt;
742
 
                                                v_cap  = context->threshold;
743
 
                                                context->flip_flop = 0;
 
814
                                                v_cap_next = context->threshold;
 
815
                                                flip_flop = 0;
744
816
                                                count_f++;
745
817
                                                update_exponent = 1;
746
818
                                        }
778
850
                                {
779
851
                                        dt     = t_rc  * log(1.0 / (1.0 - ((context->trigger - v_cap_next) / v_cap)));
780
852
                                        x_time = dt;
781
 
                                        v_cap  = context->trigger;
782
 
                                        context->flip_flop = 1;
 
853
                                        v_cap_next  = context->trigger;
 
854
                                        flip_flop = 1;
783
855
                                        count_r++;
784
856
                                        update_exponent = 1;
785
857
                                }
787
859
                        else    /* Immediate discharge. No change in dt. */
788
860
                        {
789
861
                                x_time = dt;
790
 
                                v_cap  = context->trigger;
791
 
                                context->flip_flop = 1;
 
862
                                v_cap_next = context->trigger;
 
863
                                flip_flop = 1;
792
864
                                count_r++;
793
865
                        }
794
866
                }
795
867
                else
796
868
                {
797
869
                        /* The constant current gets changed to a voltage due to a load resistor. */
798
 
                        if (context->flip_flop)
 
870
                        if (flip_flop)
799
871
                        {
800
872
                                if ((i == 0) && (DSD_555_CC__RBIAS == 0))
801
873
                                {
841
913
                                                /* calculate the overshoot time */
842
914
                                                dt     = t_rc  * log(1.0 / (1.0 - ((v_cap_next - context->threshold) / (v - v_cap))));
843
915
                                                x_time = dt;
844
 
                                                v_cap  = context->threshold;
845
 
                                                context->flip_flop = 0;
 
916
                                                v_cap_next = context->threshold;
 
917
                                                flip_flop = 0;
846
918
                                                count_f++;
847
919
                                                update_exponent = 1;
848
920
                                        }
869
941
                                        /* calculate the overshoot time */
870
942
                                        dt     = t_rc  * log(1.0 / (1.0 - ((context->trigger - v_cap_next) / v_cap)));
871
943
                                        x_time = dt;
872
 
                                        v_cap  = context->trigger;
873
 
                                        context->flip_flop = 1;
 
944
                                        v_cap_next = context->trigger;
 
945
                                        flip_flop = 1;
874
946
                                        count_r++;
875
947
                                        update_exponent = 1;
876
948
                                }
878
950
                        else    /* Immediate discharge. No change in dt. */
879
951
                        {
880
952
                                x_time = dt;
881
 
                                v_cap  = context->trigger;
882
 
                                context->flip_flop = 1;
 
953
                                v_cap_next = context->trigger;
 
954
                                flip_flop = 1;
883
955
                                count_r++;
884
956
                        }
885
957
                }
 
958
                v_cap = v_cap_next;
886
959
        } while(dt);
887
960
 
888
 
        context->cap_voltage = v_cap_next;
 
961
        context->cap_voltage = v_cap;
889
962
 
890
963
        /* Convert last switch time to a ratio */
891
 
        x_time = x_time / discrete_current_context->sample_time;
 
964
        x_time = x_time / node->info->sample_time;
892
965
 
893
966
        switch (context->output_type)
894
967
        {
895
968
                case DISC_555_OUT_SQW:
896
 
                        if (count_r && (~context->type & 0x01))
897
 
                        {
898
 
                                /* There has been an immediate discharge, so keep low for 1 sample. */
899
 
                                node->output[0] = 0;
900
 
                        }
 
969
                        if (count_f + count_r >= 2)
 
970
                                /* force at least 1 toggle */
 
971
                                node->output[0] = context->flip_flop ? 0 : context->v_out_high;
901
972
                        else
902
 
                                node->output[0] = context->flip_flop * context->v_out_high;
 
973
                                node->output[0] = flip_flop * context->v_out_high;
903
974
                        /* Fake it to AC if needed */
904
975
                        node->output[0] += context->ac_shift;
905
976
                        break;
906
977
                case DISC_555_OUT_CAP:
907
 
                        node->output[0] = v_cap_next + context->ac_shift;
 
978
                        node->output[0] = v_cap + context->ac_shift;
908
979
                        break;
909
980
                case DISC_555_OUT_ENERGY:
910
981
                        if (x_time == 0) x_time = 1.0;
911
 
                        node->output[0]  = context->v_out_high * (context->flip_flop ? x_time : (1.0 - x_time));
 
982
                        node->output[0]  = context->v_out_high * (flip_flop ? x_time : (1.0 - x_time));
912
983
                        node->output[0] += context->ac_shift;
913
984
                        break;
914
985
                case DISC_555_OUT_LOGIC_X:
915
 
                        node->output[0] = context->flip_flop + x_time;
 
986
                        node->output[0] = flip_flop + x_time;
916
987
                        break;
917
988
                case DISC_555_OUT_COUNT_F_X:
918
989
                        node->output[0] = count_f ? count_f + x_time : count_f;
927
998
                        node->output[0] = count_r;
928
999
                        break;
929
1000
        }
 
1001
        context->flip_flop = flip_flop;
930
1002
}
931
1003
 
932
1004
static DISCRETE_RESET(dsd_555_cc)
1155
1227
 *
1156
1228
 * Apr 2006, D Renaud.
1157
1229
 ************************************************************************/
1158
 
#define DSD_555_VCO1__RESET     (*(node->input[0]))     /* reset active low */
1159
 
#define DSD_555_VCO1__VIN1      (*(node->input[1]))
1160
 
#define DSD_555_VCO1__VIN2      (*(node->input[2]))
 
1230
#define DSD_555_VCO1__RESET     DISCRETE_INPUT(0)       /* reset active low */
 
1231
#define DSD_555_VCO1__VIN1      DISCRETE_INPUT(1)
 
1232
#define DSD_555_VCO1__VIN2      DISCRETE_INPUT(2)
1161
1233
 
1162
1234
static DISCRETE_STEP(dsd_555_vco1)
1163
1235
{
1171
1243
        double  v_cap;                  /* Current voltage on capacitor, before dt */
1172
1244
        double  v_cap_next = 0; /* Voltage on capacitor, after dt */
1173
1245
 
1174
 
        dt    = discrete_current_context->sample_time;  /* Change in time */
 
1246
        dt    = node->info->sample_time;        /* Change in time */
1175
1247
        v_cap = context->cap_voltage;
1176
1248
 
1177
1249
        /* Check: if the Control Voltage node is connected. */
1275
1347
        context->cap_voltage = v_cap_next;
1276
1348
 
1277
1349
        /* Convert last switch time to a ratio.  No x_time in reset. */
1278
 
        x_time = x_time / discrete_current_context->sample_time;
 
1350
        x_time = x_time / node->info->sample_time;
1279
1351
        if (!DSD_555_VCO1__RESET) x_time = 0;
1280
1352
 
1281
1353
        switch (context->output_type)
1372
1444
        context->ac_shift = context->output_is_ac ? -context->v_out_high / 2.0 : 0;
1373
1445
}
1374
1446
 
 
1447
 
1375
1448
/************************************************************************
1376
1449
 *
1377
1450
 * DSD_566 - Usage of node_description values
1378
1451
 *
1379
 
 * input[0]    - Enable input value
1380
 
 * input[1]    - Modulation Voltage
1381
 
 * input[2]    - R value
1382
 
 * input[3]    - C value
1383
 
 *
1384
 
 * also passed discrete_566_desc structure
1385
 
 *
1386
 
 * Mar 2004, D Renaud.
 
1452
 * Mar 2004, D Renaud. updated Sept 2009
 
1453
 *
 
1454
 * The data sheets for this are no where near correct.
 
1455
 * This simulation is based on the internal schematic and testing of
 
1456
 * a real Signetics IC.
 
1457
 *
 
1458
 * The 566 is a constant current based VCO.  If you change R, that affects
 
1459
 * the charge/discharge rate.  A constant current source will charge the
 
1460
 * cap linearly.  Of course due to the transistors there will be some
 
1461
 * non-linear areas at the ends of the Vmod range.  As the Vmod voltage
 
1462
 * drops from Vcharge, the frequency generated increases.
 
1463
 *
 
1464
 * The Triangle (pin 4) output is just a buffered version of the cap
 
1465
 * charge.  It is about 1.35 higher then the cap voltage.
 
1466
 * The Square (pin 3) output starts low as the cap voltages rises.
 
1467
 * Once a threshold is reached, the cap starts to discharge, and the
 
1468
 * Square output goes high.  The Square high output is about 1V less then
 
1469
 * B+.  Unloaded it is .75V less.  With a 4.7k pull-down resistor, it
 
1470
 * is 1.06V less.  So I will simulate at 1V less. The Square low voltage
 
1471
 * is non-linear so I will use a table.  The cap toggle thresholds vary
 
1472
 * depending on B+, so they will be simulated with a table.
 
1473
 *
 
1474
 * The data sheets show Vmod should be no less then 3/4*B+.  In reality
 
1475
 * you can go to close to 1/2*B+ before you loose linearity.  Below 1/2,
 
1476
 * oscillation stops.  When Vmod is 0V to 0.1V less then B+, it also
 
1477
 * looses linearity, and stops oscillating when >= B+.  This is because
 
1478
 * there is no voltage difference to create a current source.
 
1479
 *
 
1480
 * The current source is dependant on the voltage difference between B+
 
1481
 * and Vmod.  Due to transistor action, it is not 100%, but this formula
 
1482
 * gives a good approximation:
 
1483
 * I = ((B+ - Vmod - 0.1) * 0.95) / R
 
1484
 * You can test the current VS modulation function by using 10k for R
 
1485
 * and replace C with a 10k resistor.  Then you can monitor the voltage
 
1486
 * on pin 7 to work out the current.  I=V/R.  It will start to oscillate
 
1487
 * when in the cap threshold range.
 
1488
 *
 
1489
 * When Vmod drops below the stable range, the current source no longer
 
1490
 * functions properly.  Technically this is out of the range specified
 
1491
 * for the IC.  Of course old games used this range anyways, so we need
 
1492
 * to know how the real IC behaves.  When Vmod drops below the stable range,
 
1493
 * the charge current is stops dropping instead of increasing, while the
 
1494
 * discharge current still functions.  This means the frequency generated
 
1495
 * starts to drop as the voltage lowers, instead of the normal increase
 
1496
 * in frequency.
 
1497
 *
1387
1498
 ************************************************************************/
1388
 
#define DSD_566__ENABLE (*(node->input[0]))
1389
 
#define DSD_566__VMOD   (*(node->input[1]))
1390
 
#define DSD_566__R              (*(node->input[2]))
1391
 
#define DSD_566__C              (*(node->input[3]))
 
1499
#define DSD_566__VMOD           DISCRETE_INPUT(0)
 
1500
#define DSD_566__R                      DISCRETE_INPUT(1)
 
1501
#define DSD_566__C                      DISCRETE_INPUT(2)
 
1502
#define DSD_566__VPOS           DISCRETE_INPUT(3)
 
1503
#define DSD_566__VNEG           DISCRETE_INPUT(4)
 
1504
#define DSD_566__VCHARGE        DISCRETE_INPUT(5)
 
1505
#define DSD_566__OPTIONS        DISCRETE_INPUT(6)
 
1506
 
 
1507
 
 
1508
static const struct
 
1509
{
 
1510
        double  c_high[6];
 
1511
        double  c_low[6];
 
1512
        double  sqr_low[6];
 
1513
        double  osc_stable[6];
 
1514
        double  osc_stop[6];
 
1515
} ne566 =
 
1516
{
 
1517
        /* 10      10.5      11      11.5      12     13     14     15             B+ */
 
1518
        {3.364, /*3.784,*/ 4.259, /*4.552,*/ 4.888, 5.384, 5.896, 6.416},               /* c_high */
 
1519
        {1.940, /*2.100,*/ 2.276, /*2.404,*/ 2.580, 2.880, 3.180, 3.488},               /* c_low */
 
1520
        {4.352, /*4.144,*/ 4.080, /*4.260,*/ 4.500, 4.960, 5.456, 5.940},               /* sqr_low */
 
1521
        {4.885, /*5.316,*/ 5.772, /*6.075,*/ 6.335, 6.912, 7.492, 7.945},               /* osc_stable */
 
1522
        {4.495, /*4.895,*/ 5.343, /*5.703,*/ 5.997, 6.507, 7.016, 7.518}                /* osc_stop */
 
1523
};
1392
1524
 
1393
1525
static DISCRETE_STEP(dsd_566)
1394
1526
{
1395
 
        const  discrete_566_desc *info    = (const  discrete_566_desc *)node->custom;
1396
1527
        struct dsd_566_context   *context = (struct dsd_566_context *)node->context;
1397
1528
 
1398
 
        double i;                               /* Charging current created by vIn */
1399
 
        double dt;                              /* change in time */
1400
 
        double v_cap;                   /* Current voltage on capacitor, before dt */
1401
 
        double v_cap_next = 0;  /* Voltage on capacitor, after dt */
1402
 
        double v_charge;
1403
 
 
1404
 
        if (DSD_566__ENABLE && !context->error)
 
1529
        double  i = 0;                  /* Charging current created by vIn */
 
1530
        double  i_rise;                 /* non-linear rise charge current */
 
1531
        double  dt;                             /* change in time */
 
1532
        double  x_time = 0;
 
1533
        double  v_cap;                  /* Current voltage on capacitor, before dt */
 
1534
        int             count_f = 0, count_r = 0;
 
1535
 
 
1536
        dt    = node->info->sample_time;        /* Change in time */
 
1537
        v_cap = context->cap_voltage;   /* Set to voltage before change */
 
1538
 
 
1539
        /* Calculate charging current if it is in range */
 
1540
        if (EXPECTED(DSD_566__VMOD > context->v_osc_stop))
1405
1541
        {
1406
 
                dt    = discrete_current_context->sample_time;  /* Change in time */
1407
 
                v_cap = context->cap_voltage;   /* Set to voltage before change */
1408
 
 
1409
 
                /* get the v_charge and update each step if it is a node */
1410
 
                if (context->v_charge_node != NULL)
1411
 
                {
1412
 
                        v_charge  = *context->v_charge_node;
1413
 
                        v_charge -= info->v_neg;
1414
 
                }
1415
 
                else
1416
 
                        v_charge = context->v_charge;
1417
 
 
1418
 
                /* Calculate charging current */
1419
 
                i = (v_charge - DSD_566__VMOD) / DSD_566__R;
1420
 
 
1421
 
                /* Keep looping until all toggling in time sample is used up. */
1422
 
                do
1423
 
                {
1424
 
                        if (context->flip_flop)
 
1542
                double v_charge = DSD_566__VCHARGE - DSD_566__VMOD - 0.1;
 
1543
                if (v_charge > 0)
 
1544
                {
 
1545
                        i = (v_charge * .95) / DSD_566__R;
 
1546
                        if (DSD_566__VMOD < context->v_osc_stable)
1425
1547
                        {
1426
 
                                /* Discharging */
1427
 
                                v_cap_next = v_cap - (i * dt / DSD_566__C);
1428
 
                                dt         = 0;
1429
 
 
1430
 
                                /* has it discharged past lower limit? */
1431
 
                                if (v_cap_next <= context->threshold_low)
1432
 
                                {
1433
 
                                        if (v_cap_next < context->threshold_low)
1434
 
                                        {
1435
 
                                                /* calculate the overshoot time */
1436
 
                                                dt = DSD_566__C * (context->threshold_low - v_cap_next) / i;
1437
 
                                        }
1438
 
                                        v_cap = context->threshold_low;
1439
 
                                        context->flip_flop = 0;
1440
 
                                        /*
1441
 
                     * If the sampling rate is too low and the desired frequency is too high
1442
 
                     * then we will start getting too many outputs that can't catch up.  We will
1443
 
                     * limit this to 3.  The output is already incorrect because of the low sampling,
1444
 
                     * but at least this way it can recover.
1445
 
                     */
1446
 
                                        context->state[0] = (context->state[0] + 1) & 0x03;
1447
 
                                }
 
1548
                                /* no where near correct calculation of non linear range */
 
1549
                                i_rise = ((DSD_566__VCHARGE - context->v_osc_stable - 0.1) * .95) / DSD_566__R;
 
1550
                                i_rise *= 1.0 - (context->v_osc_stable - DSD_566__VMOD) / (context->v_osc_stable - context->v_osc_stop);
1448
1551
                        }
1449
1552
                        else
1450
 
                        {
1451
 
                                /* Charging */
1452
 
                                /* iC=C*dv/dt  works out to dv=iC*dt/C */
1453
 
                                v_cap_next = v_cap + (i * dt / DSD_566__C);
1454
 
                                dt         = 0;
1455
 
                                /* Yes, if the cap voltage has reached the max voltage it can,
1456
 
                 * and the 566 threshold has not been reached, then oscillation stops.
1457
 
                 * This is the way the actual electronics works.
1458
 
                 * This is why you never play with the pots after being factory adjusted
1459
 
                 * to work in the proper range. */
1460
 
                                if (v_cap_next > DSD_566__VMOD) v_cap_next = DSD_566__VMOD;
1461
 
 
1462
 
                                /* has it charged past upper limit? */
1463
 
                                if (v_cap_next >= context->threshold_high)
1464
 
                                {
1465
 
                                        if (v_cap_next > context->threshold_high)
1466
 
                                        {
1467
 
                                                /* calculate the overshoot time */
1468
 
                                                dt = DSD_566__C * (v_cap_next - context->threshold_high) / i;
1469
 
                                        }
1470
 
                                        v_cap = context->threshold_high;
1471
 
                                        context->flip_flop = 1;
1472
 
                                        context->state[1] = (context->state[1] + 1) & 0x03;
1473
 
                                }
1474
 
                        }
1475
 
                } while(dt);
1476
 
 
1477
 
                context->cap_voltage = v_cap_next;
1478
 
 
1479
 
                switch (info->options & DISC_566_OUT_MASK)
1480
 
                {
1481
 
                        case DISC_566_OUT_SQUARE:
1482
 
                        case DISC_566_OUT_LOGIC:
1483
 
                                /* use up any output states */
1484
 
                                if (node->output[0] && context->state[0])
1485
 
                                {
1486
 
                                        node->output[0] = 0;
1487
 
                                        context->state[0]--;
1488
 
                                }
1489
 
                                else if (!node->output[0] && context->state[1])
1490
 
                                {
1491
 
                                        node->output[0] = 1;
1492
 
                                        context->state[1]--;
1493
 
                                }
1494
 
                                else
1495
 
                                {
1496
 
                                        node->output[0] = context->flip_flop;
1497
 
                                }
1498
 
                                if ((info->options & DISC_566_OUT_MASK) != DISC_566_OUT_LOGIC)
1499
 
                                        node->output[0] = context->flip_flop ? context->v_sqr_high : context->v_sqr_low;
1500
 
                                break;
1501
 
                        case DISC_566_OUT_TRIANGLE:
1502
 
                                /* we can ignore any unused states when
1503
 
                 * outputting the cap voltage */
1504
 
                                node->output[0] = v_cap_next;
1505
 
                                if (info->options & DISC_566_OUT_AC)
1506
 
                                        node->output[0] -= context->triangle_ac_offset;
1507
 
                                break;
1508
 
                }
1509
 
        }
1510
 
        else
1511
 
                node->output[0] = 0;
 
1553
                                i_rise = i;
 
1554
                }
 
1555
                else
 
1556
                        return;
 
1557
        }
 
1558
        else return;
 
1559
 
 
1560
        /* Keep looping until all toggling in this time sample is used up. */
 
1561
        do
 
1562
        {
 
1563
                if (context->flip_flop)
 
1564
                {
 
1565
                        /* Discharging */
 
1566
                        v_cap -= i * dt / DSD_566__C;
 
1567
                        dt     = 0;
 
1568
 
 
1569
                        /* has it discharged past lower limit? */
 
1570
                        if (UNEXPECTED(v_cap < context->threshold_low))
 
1571
                        {
 
1572
                                /* calculate the overshoot time */
 
1573
                                dt = DSD_566__C * (context->threshold_low - v_cap) / i;
 
1574
                                v_cap = context->threshold_low;
 
1575
                                context->flip_flop = 0;
 
1576
                                count_f++;
 
1577
                                x_time = dt;
 
1578
                        }
 
1579
                }
 
1580
                else
 
1581
                {
 
1582
                        /* Charging */
 
1583
                        /* iC=C*dv/dt  works out to dv=iC*dt/C */
 
1584
                        v_cap += i_rise * dt / DSD_566__C;
 
1585
                        dt     = 0;
 
1586
                        /* Yes, if the cap voltage has reached the max voltage it can,
 
1587
             * and the 566 threshold has not been reached, then oscillation stops.
 
1588
             * This is the way the actual electronics works.
 
1589
             * This is why you never play with the pots after being factory adjusted
 
1590
             * to work in the proper range. */
 
1591
                        if (UNEXPECTED(v_cap > DSD_566__VMOD)) v_cap = DSD_566__VMOD;
 
1592
 
 
1593
                        /* has it charged past upper limit? */
 
1594
                        if (UNEXPECTED(v_cap > context->threshold_high))
 
1595
                        {
 
1596
                                /* calculate the overshoot time */
 
1597
                                dt = DSD_566__C * (v_cap - context->threshold_high) / i;
 
1598
                                v_cap = context->threshold_high;
 
1599
                                context->flip_flop = 1;
 
1600
                                count_r++;
 
1601
                                x_time = dt;
 
1602
                        }
 
1603
                }
 
1604
        } while(dt);
 
1605
 
 
1606
        context->cap_voltage = v_cap;
 
1607
 
 
1608
        /* Convert last switch time to a ratio */
 
1609
        x_time /= node->info->sample_time;
 
1610
 
 
1611
        switch (context->out_type)
 
1612
        {
 
1613
                case DISC_566_OUT_SQUARE:
 
1614
                        node->output[0] = context->flip_flop ? context->v_sqr_high : context->v_sqr_low;
 
1615
                        if (context->fake_ac)
 
1616
                                node->output[0] += context->ac_shift;
 
1617
                        break;
 
1618
                case DISC_566_OUT_ENERGY:
 
1619
                        if (x_time == 0) x_time = 1.0;
 
1620
                        node->output[0]  = context->v_sqr_low + context->v_sqr_diff * (context->flip_flop ? x_time : (1.0 - x_time));
 
1621
                        if (context->fake_ac)
 
1622
                                node->output[0] += context->ac_shift;
 
1623
                        break;
 
1624
                case DISC_566_OUT_LOGIC:
 
1625
                                node->output[0] = context->flip_flop;
 
1626
                        break;
 
1627
                case DISC_566_OUT_TRIANGLE:
 
1628
                        node->output[0] = v_cap;
 
1629
                        if (context->fake_ac)
 
1630
                                node->output[0] += context->ac_shift;
 
1631
                        break;
 
1632
                case DISC_566_OUT_COUNT_F_X:
 
1633
                        node->output[0] = count_f ? count_f + x_time : count_f;
 
1634
                        break;
 
1635
                case DISC_566_OUT_COUNT_R_X:
 
1636
                        node->output[0] =  count_r ? count_r + x_time : count_r;
 
1637
                        break;
 
1638
                case DISC_566_OUT_COUNT_F:
 
1639
                        node->output[0] = count_f;
 
1640
                        break;
 
1641
                case DISC_566_OUT_COUNT_R:
 
1642
                        node->output[0] = count_r;
 
1643
                        break;
 
1644
        }
1512
1645
}
1513
1646
 
1514
1647
static DISCRETE_RESET(dsd_566)
1515
1648
{
1516
 
        const  discrete_566_desc *info    = (const  discrete_566_desc *)node->custom;
1517
1649
        struct dsd_566_context   *context = (struct dsd_566_context *)node->context;
1518
 
        node_description *v_charge_node;
1519
 
 
1520
 
        double  v_diff, temp;
1521
 
 
1522
 
        context->error = 0;
1523
 
        if (info->v_neg >= info->v_pos)
1524
 
        {
1525
 
                logerror("[v_neg >= v_pos] - NODE_%d DISABLED!\n", node->node - NODE_00);
1526
 
                context->error = 1;
1527
 
                return;
1528
 
        }
1529
 
 
1530
 
        /* setup v_charge or node */
1531
 
        v_charge_node = discrete_find_node(NULL, info->v_charge);
1532
 
        if (v_charge_node)
1533
 
                context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]);
1534
 
        else
1535
 
        {
1536
 
                context->v_charge  = (info->v_charge == DEFAULT_566_CHARGE) ? info->v_pos : info->v_charge;
1537
 
                context->v_charge -= info->v_neg;
1538
 
                context->v_charge_node = NULL;
1539
 
        }
1540
 
 
1541
 
        v_diff = info->v_pos - info->v_neg;
 
1650
 
 
1651
        int             v_int;
 
1652
        double  v_float;
 
1653
 
 
1654
        context->out_type = (int)DSD_566__OPTIONS & DISC_566_OUT_MASK;
 
1655
        context->fake_ac =  (int)DSD_566__OPTIONS & DISC_566_OUT_AC;
 
1656
 
 
1657
        if (DSD_566__VNEG >= DSD_566__VPOS)
 
1658
                fatalerror("[v_neg >= v_pos] in NODE_%d!\n", NODE_BLOCKINDEX(node));
 
1659
 
 
1660
        v_float = DSD_566__VPOS - DSD_566__VNEG;
 
1661
        v_int = (int)v_float;
 
1662
        if ( v_float < 10 || v_float > 15 )
 
1663
                fatalerror("v_neg and/or v_pos out of range in NODE_%d\n", NODE_BLOCKINDEX(node));
 
1664
        if ( v_float != v_int )
 
1665
                /* fatal for now. */
 
1666
                fatalerror("Power should be integer in NODE_%d\n", NODE_BLOCKINDEX(node));
 
1667
 
1542
1668
        context->flip_flop   = 0;
1543
1669
        context->cap_voltage = 0;
1544
 
        context->state[0]    = 0;
1545
 
        context->state[1]    = 0;
1546
 
 
1547
 
        /* The data sheets are useless for this IC.  I will have to get my hands on a chip
1548
 
     * to make real measurements.  For now this should work fine for 12V. */
1549
 
        context->threshold_high = v_diff / 2 + info->v_neg;
1550
 
        context->threshold_low  = context->threshold_high - (0.2 * v_diff);
1551
 
        context->v_sqr_high     = info->v_pos - 0.6;
1552
 
        context->v_sqr_low      = context->threshold_high;
1553
 
 
1554
 
        if (info->options & DISC_566_OUT_AC)
 
1670
 
 
1671
        v_int -= 10;
 
1672
        context->threshold_high = ne566.c_high[v_int] + DSD_566__VNEG;
 
1673
        context->threshold_low  = ne566.c_low[v_int] + DSD_566__VNEG;
 
1674
        context->v_sqr_high     = DSD_566__VPOS - 1;
 
1675
        context->v_sqr_low      = ne566.sqr_low[v_int] + DSD_566__VNEG;
 
1676
        context->v_sqr_diff     = context->v_sqr_high - context->v_sqr_low;
 
1677
        context->v_osc_stable   = ne566.osc_stable[v_int] + DSD_566__VNEG;
 
1678
        context->v_osc_stop             = ne566.osc_stop[v_int] + DSD_566__VNEG;
 
1679
 
 
1680
        context->ac_shift = 0;
 
1681
        if (context->fake_ac)
1555
1682
        {
1556
 
                temp = (context->v_sqr_high - context->v_sqr_low) / 2;
1557
 
                context->v_sqr_high =  temp;
1558
 
                context->v_sqr_low  = -temp;
1559
 
                context->triangle_ac_offset = context->threshold_high - (0.1 * v_diff);
 
1683
                if (context->out_type == DISC_566_OUT_TRIANGLE)
 
1684
                        context->ac_shift = (context->threshold_high - context->threshold_low) / 2 - context->threshold_high;
 
1685
                else
 
1686
                        context->ac_shift = context->v_sqr_diff / 2 - context->v_sqr_high;
1560
1687
        }
1561
1688
 
1562
1689
        /* Step the output */
1563
1690
        DISCRETE_STEP_CALL(dsd_566);
1564
1691
}
1565
1692
 
 
1693
 
1566
1694
/************************************************************************
1567
1695
 *
1568
1696
 * DSD_LS624 - Usage of node_description values
1569
1697
 *
1570
 
 * input[0]    - Enable input value
1571
 
 * input[1]    - Modulation Voltage
1572
 
 * input[2]    - Range Voltage
1573
 
 * input[3]    - C value
1574
 
 * input[4]    - Output type
 
1698
 * input[0]    - Modulation Voltage
 
1699
 * input[1]    - Range Voltage
 
1700
 * input[2]    - C value
 
1701
 * input[3]    - Output type
1575
1702
 *
1576
1703
 * Dec 2007, Couriersud
1577
1704
 ************************************************************************/
1578
 
#define DSD_LS624__ENABLE       (*(node->input[0]))
1579
 
#define DSD_LS624__VMOD         (*(node->input[1]))
1580
 
#define DSD_LS624__VRNG         (*(node->input[2]))
1581
 
#define DSD_LS624__C            (*(node->input[3]))
1582
 
#define DSD_LS624__OUTTYPE      (*(node->input[4]))
 
1705
#define DSD_LS624__VMOD         DISCRETE_INPUT(0)
 
1706
#define DSD_LS624__VRNG         DISCRETE_INPUT(1)
 
1707
#define DSD_LS624__C            DISCRETE_INPUT(2)
 
1708
#define DSD_LS624__OUTTYPE      DISCRETE_INPUT(3)
1583
1709
 
1584
1710
/*
1585
1711
 * The datasheet mentions a 600 ohm discharge. It also gives
1593
1719
 * where calculated using least square approximation.
1594
1720
 * This approach gives a bit better results compared to the first approach.
1595
1721
 */
1596
 
#define LS624_F(_C, _VI, _VR)   pow(10, -0.912029404 * log10(_C) + 0.243264328 * (_VI) \
1597
 
                          - 0.091695877 * (_VR) -0.014110946 * (_VI) * (_VR) - 3.207072925)
 
1722
/* Original formula before optimization of static values
 
1723
 #define LS624_F(_C, _VI, _VR)  pow(10, -0.912029404 * log10(_C) + 0.243264328 * (_VI) \
 
1724
                  - 0.091695877 * (_VR) -0.014110946 * (_VI) * (_VR) - 3.207072925)
 
1725
*/
 
1726
 
 
1727
/* pow(10, x) = exp(ln(10)*x) */
 
1728
#define pow10(x) exp(2.30258509299404568401*(x))
 
1729
 
 
1730
#define LS624_F(_VI)    pow10(context->k1 + 0.243264328 * (_VI) + context->k2 * (_VI))
1598
1731
 
1599
1732
static DISCRETE_STEP(dsd_ls624)
1600
1733
{
1601
1734
        struct dsd_ls624_context *context = (struct dsd_ls624_context *)node->context;
1602
1735
 
1603
 
        if (DSD_LS624__ENABLE)
1604
 
        {
1605
 
                double  dt;     /* change in time */
1606
 
                double  sample_t;
1607
 
                double  t;
1608
 
                double  en = 0.0f;
1609
 
                int             cntf = 0, cntr = 0;
1610
 
 
1611
 
                sample_t = discrete_current_context->sample_time;       /* Change in time */
1612
 
                //dt  = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD) / 2.0;
1613
 
                dt  = 1.0f / (2.0f * LS624_F(DSD_LS624__C, DSD_LS624__VMOD, DSD_LS624__VRNG));
1614
 
                t   = context->remain;
1615
 
                en += (double) context->state * t;
1616
 
                while (t + dt <= sample_t)
1617
 
                {
1618
 
                        en += (double) context->state * dt;
1619
 
                        context->state = (1 - context->state);
1620
 
                        if (context->state)
1621
 
                                cntr++;
 
1736
        double  dt;     /* change in time */
 
1737
        double  sample_t;
 
1738
        double  t;
 
1739
        double  en = 0.0f;
 
1740
        int             cntf = 0, cntr = 0;
 
1741
 
 
1742
        sample_t = node->info->sample_time;     /* Change in time */
 
1743
        //dt  = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD) / 2.0;
 
1744
        if (EXPECTED(DSD_LS624__VMOD > 0.001))
 
1745
                dt = 0.5 / LS624_F(DSD_LS624__VMOD);
 
1746
        else
 
1747
                /* close enough to 0, so we can speed things up by no longer call pow() */
 
1748
                dt = context->dt_vmod_at_0;
 
1749
        t   = context->remain;
 
1750
        en += (double) context->state * t;
 
1751
        while (EXPECTED(t + dt <= sample_t))
 
1752
        {
 
1753
                en += (double) context->state * dt;
 
1754
                context->state = (1 - context->state);
 
1755
                if (context->state)
 
1756
                        cntr++;
 
1757
                else
 
1758
                        cntf++;
 
1759
                t += dt;
 
1760
        }
 
1761
        en += (sample_t - t) * (double) context->state;
 
1762
        context->remain = t - sample_t;
 
1763
 
 
1764
        switch (context->out_type)
 
1765
        {
 
1766
                case DISC_LS624_OUT_ENERGY:
 
1767
                        node->output[0] = en / sample_t;
 
1768
                        break;
 
1769
                case DISC_LS624_OUT_LOGIC:
 
1770
                        /* filter out randomness */
 
1771
                        if (UNEXPECTED(cntf + cntr > 1))
 
1772
                                node->output[0] = 1;
1622
1773
                        else
1623
 
                                cntf++;
1624
 
                        t += dt;
1625
 
                }
1626
 
                en += (sample_t - t) * (double) context->state;
1627
 
                context->remain = t - sample_t;
1628
 
 
1629
 
                switch (context->out_type)
1630
 
                {
1631
 
                        case DISC_LS624_OUT_ENERGY:
1632
 
                                node->output[0] = en / sample_t;
1633
 
                                break;
1634
 
                        case DISC_LS624_OUT_LOGIC:
1635
 
                                /* filter out randomness */
1636
 
                                if (cntf + cntr > 1)
1637
 
                                        node->output[0] = 1;
1638
 
                                else
1639
 
                                        node->output[0] = context->state;
1640
 
                                break;
1641
 
                        case DISC_LS624_OUT_COUNT_F:
1642
 
                                node->output[0] = cntf;
1643
 
                                break;
1644
 
                        case DISC_LS624_OUT_COUNT_R:
1645
 
                                node->output[0] = cntr;
1646
 
                                break;
1647
 
                }
1648
 
 
 
1774
                                node->output[0] = context->state;
 
1775
                        break;
 
1776
                case DISC_LS624_OUT_COUNT_F:
 
1777
                        node->output[0] = cntf;
 
1778
                        break;
 
1779
                case DISC_LS624_OUT_COUNT_R:
 
1780
                        node->output[0] = cntr;
 
1781
                        break;
1649
1782
        }
1650
 
        else
1651
 
                node->output[0] = 0;
1652
1783
}
1653
1784
 
1654
1785
static DISCRETE_RESET(dsd_ls624)
1659
1790
        context->state    = 0;
1660
1791
        context->out_type = DSD_LS624__OUTTYPE;
1661
1792
 
 
1793
        /* precalculate some parts of the formula for speed */
 
1794
        context->k1 = -0.912029404 * log10(DSD_LS624__C) -0.091695877 * (DSD_LS624__VRNG) - 3.207072925;
 
1795
        context->k2 = -0.014110946 * (DSD_LS624__VRNG);
 
1796
 
 
1797
        context->dt_vmod_at_0 = 0.5 / LS624_F(0);
 
1798
 
1662
1799
        /* Step the output */
1663
1800
        DISCRETE_STEP_CALL(dsd_ls624);
1664
1801
}
 
1802
 
 
1803
 
 
1804
/************************************************************************
 
1805
 *
 
1806
 * DSD_LS629 - Usage of node_description values
 
1807
 *
 
1808
 * Dec 2007, Couriersud based on data sheet
 
1809
 * Oct 2009, complete re-write based on IC testing
 
1810
 ************************************************************************/
 
1811
#define DSD_LS629__ENABLE               DISCRETE_INPUT(0)
 
1812
#define DSD_LS629__VMOD                 DISCRETE_INPUT(1)
 
1813
#define DSD_LS629__VRNG                 DISCRETE_INPUT(2)
 
1814
#define DSD_LS629__C                    DISCRETE_INPUT(3)
 
1815
#define DSD_LS629__R_FREQ_IN    DISCRETE_INPUT(4)
 
1816
#define DSD_LS629__OUTTYPE              DISCRETE_INPUT(5)
 
1817
 
 
1818
#define LS624_R_EXT                     600.0           /* as specified in data sheet */
 
1819
#define LS624_OUT_HIGH          4.5                     /* measured */
 
1820
#define LS624_FREQ_R_IN         RES_K(95)       /* measured */
 
1821
 
 
1822
/*
 
1823
 * The 74LS624 series are constant current based VCOs.  The Freq Control voltage
 
1824
 * modulates the current source.  The current is created from Rext, which is
 
1825
 * internally fixed at 600 ohms for all devices except the 74LS628 which has
 
1826
 * external connections.  The current source linearly discharges the cap voltage.
 
1827
 * The cap starts with 0V charge across it.  One side is connected to a fixed voltage
 
1828
 * bias circuit.  The other side is charged negatively from the current source until
 
1829
 * a certain low threshold is reached.  Once this threshold is reached, the output
 
1830
 * toggles state and the pins on the cap reverse in respect to the charge/bias hookup.
 
1831
 * This starts the one side of the cap to be at bias, and the other side of the cap is
 
1832
 * now at bias + the charge on the cap which is bias - threshold.
 
1833
 * Y = 0;  CX1 = bias;    CX2 = charge
 
1834
 * Y = 1;  CX1 = charge;  CX2 = bias
 
1835
 * The Range voltage adjusts the threshold voltage.  The higher the Range voltage,
 
1836
 * the lower the threshold voltage, the longer the cap can charge, the lower the frequency.
 
1837
 *
 
1838
 * The current is based on the mysterious Rext mentioned in the data sheet.
 
1839
 * I = (VfreqControl / 5) / Rext
 
1840
 * where Rext = 600 ohms or external Rext on a 74LS628
 
1841
 * The Freq Control has an input impedance of approximately 100k, so any input resistance
 
1842
 * connected to the Freq Control pin works as a voltage divider.
 
1843
 * I = (VfreqControl / 5 * 100000 / (RfreqControl + 100000)) / Rext
 
1844
 * That gives us a change in voltage on the cap of
 
1845
 * dV = I / sampleRate / C_inFarads
 
1846
 */
 
1847
 
 
1848
/* The range to bias and threshold routines were created from testing a real chip.
 
1849
 * This data was entered into the function finder routine at www.zunzun.com
 
1850
 * to create the following 2 routines
 
1851
 */
 
1852
 
 
1853
double range_to_bias(double range)
 
1854
{
 
1855
        /* Quadratic2D_model */
 
1856
        double bias;
 
1857
 
 
1858
        // coefficients
 
1859
        const double a =  2.3107142857142846E+00;
 
1860
        const double b = -1.0714285714278806E-03;
 
1861
        const double c = -1.7857142857144002E-03;
 
1862
 
 
1863
        bias  = a;
 
1864
        bias += b * range;
 
1865
        bias += c * pow(range, 2.0);
 
1866
        return bias;
 
1867
}
 
1868
 
 
1869
double range_to_threshold(double range)
 
1870
{
 
1871
        /* Polyfunctional2D_model */
 
1872
        double threshold;
 
1873
 
 
1874
        // coefficients
 
1875
        const double a = -1.6124587587173614E-01;
 
1876
        const double b = -1.3501987413150401E-01;
 
1877
        const double offset = 2.2550390868489893E+00;
 
1878
 
 
1879
        threshold  = a * range;
 
1880
        threshold += b * exp(-1.0 * range);
 
1881
        threshold += offset;
 
1882
        return threshold;
 
1883
}
 
1884
 
 
1885
 
 
1886
static DISCRETE_STEP(dsd_ls629)
 
1887
{
 
1888
        struct dsd_ls629_context *context = (struct dsd_ls629_context *)node->context;
 
1889
 
 
1890
        double  i;                      /* Charging current created by Freq Control */
 
1891
        double  dt;                             /* change in time */
 
1892
        double  x_time = 0;
 
1893
        double  v_cap;                  /* Current voltage on capacitor, before dt */
 
1894
        int             count_f = 0, count_r = 0;
 
1895
 
 
1896
        if (UNEXPECTED(DSD_LS629__ENABLE == 0))
 
1897
                return;
 
1898
 
 
1899
        dt    = node->info->sample_time;        /* Change in time */
 
1900
        v_cap = context->v_cap;                         /* Set to voltage before change */
 
1901
 
 
1902
 
 
1903
        /* Calculate charging current */
 
1904
        i = DSD_LS629__VMOD * context->k_vmod_to_i;
 
1905
 
 
1906
        /* Keep looping until all toggling in this time sample is used up. */
 
1907
        do
 
1908
        {
 
1909
                /* Always Discharging */
 
1910
                v_cap -= i * dt / DSD_LS629__C;
 
1911
                dt     = 0;
 
1912
 
 
1913
                /* has it discharged past lower limit? */
 
1914
                if (UNEXPECTED(v_cap < context->v_threshold))
 
1915
                {
 
1916
                        /* calculate the overshoot time */
 
1917
                        dt = DSD_LS629__C * (context->v_threshold - v_cap) / i;
 
1918
                        v_cap = context->v_peak;
 
1919
                        context->flip_flop ^= 1;
 
1920
                        if (context->flip_flop)
 
1921
                                count_r++;
 
1922
                        else
 
1923
                                count_f++;
 
1924
                        x_time = dt;
 
1925
                }
 
1926
        } while(dt);
 
1927
 
 
1928
        context->v_cap = v_cap;
 
1929
 
 
1930
        /* Convert last switch time to a ratio */
 
1931
        x_time = x_time / node->info->sample_time;
 
1932
 
 
1933
        switch (context->out_type)
 
1934
        {
 
1935
                case DISC_LS624_OUT_SQUARE:
 
1936
                        node->output[0] = context->flip_flop ? LS624_OUT_HIGH : 0;
 
1937
                        break;
 
1938
                case DISC_LS624_OUT_ENERGY:
 
1939
                        if (x_time == 0) x_time = 1.0;
 
1940
                        node->output[0]  = LS624_OUT_HIGH * (context->flip_flop ? x_time : (1.0 - x_time));
 
1941
                        break;
 
1942
                case DISC_LS624_OUT_LOGIC:
 
1943
                                node->output[0] = context->flip_flop;
 
1944
                        break;
 
1945
                case DISC_LS624_OUT_COUNT_F_X:
 
1946
                        node->output[0] = count_f ? count_f + x_time : count_f;
 
1947
                        break;
 
1948
                case DISC_LS624_OUT_COUNT_R_X:
 
1949
                        node->output[0] =  count_r ? count_r + x_time : count_r;
 
1950
                        break;
 
1951
                case DISC_LS624_OUT_COUNT_F:
 
1952
                        node->output[0] = count_f;
 
1953
                        break;
 
1954
                case DISC_LS624_OUT_COUNT_R:
 
1955
                        node->output[0] = count_r;
 
1956
                        break;
 
1957
        }
 
1958
}
 
1959
 
 
1960
#define LS624_LOSS_FACTOR       0.92
 
1961
 
 
1962
static DISCRETE_RESET(dsd_ls629)
 
1963
{
 
1964
        struct dsd_ls629_context *context = (struct dsd_ls629_context *)node->context;
 
1965
 
 
1966
        context->out_type = (int)DSD_LS629__OUTTYPE;
 
1967
 
 
1968
        context->v_bias = range_to_bias(DSD_LS629__VRNG);
 
1969
        context->v_cap = context->v_bias;
 
1970
        context->v_threshold = range_to_threshold(DSD_LS629__VRNG);
 
1971
        /* The voltage at the current charge pin after a state change */
 
1972
        context->v_peak = context->v_bias * 2 - context->v_threshold;
 
1973
        context->flip_flop = 0;
 
1974
        /* precalulate the voltage to current formula */
 
1975
        context->k_vmod_to_i  = 1.0 / 5 * LS624_FREQ_R_IN / (DSD_LS629__R_FREQ_IN + LS624_FREQ_R_IN) / LS624_R_EXT;
 
1976
        context->k_vmod_to_i *= LS624_LOSS_FACTOR;
 
1977
 
 
1978
        node->output[0] = 0;
 
1979
}