1 // license:BSD-3-Clause
2 // copyright-holders:Derrick Renaud
3 /*************************************************************************
4 
5     audio\nitedrvr.c
6 
7 *************************************************************************/
8 #include "emu.h"
9 #include "includes/nitedrvr.h"
10 #include "sound/discrete.h"
11 
12 
13 /* Discrete Sound Emulation */
14 
15 static const discrete_lfsr_desc nitedrvr_lfsr =
16 {
17 	DISC_CLK_IS_FREQ,
18 	16,         /* Bit Length */
19 	0,          /* Reset Value */
20 	0,          /* Use Bit 0 as XOR input 0 */
21 	14,         /* Use Bit 14 as XOR input 1 */
22 	DISC_LFSR_XNOR,     /* Feedback stage1 is XNOR */
23 	DISC_LFSR_OR,       /* Feedback stage2 is just stage 1 output OR with external feed */
24 	DISC_LFSR_REPLACE,  /* Feedback stage3 replaces the shifted register contents */
25 	0x000001,       /* Everything is shifted into the first bit only */
26 	0,          /* Output is already inverted by XNOR */
27 	15          /* Output bit */
28 };
29 
30 /* Nodes - Sounds */
31 #define NITEDRVR_NOISE          NODE_10
32 #define NITEDRVR_BANG_SND       NODE_11
33 #define NITEDRVR_MOTOR_SND      NODE_12
34 #define NITEDRVR_SCREECH1_SND   NODE_13
35 #define NITEDRVR_SCREECH2_SND   NODE_14
36 
37 DISCRETE_SOUND_START(nitedrvr_discrete)
38 	/************************************************/
39 	/* nitedrvr  Effects Relataive Gain Table       */
40 	/*                                              */
41 	/* Effect    V-ampIn  Gain ratio      Relative  */
42 	/* Bang       3.8     5/(5+6.8)        1000.0   */
43 	/* Motor      3.8     5/(5+10)          786.7   */
44 	/* Screech1   3.8     5/(5+47)          226.9   */
45 	/* Screech2   3.8     5/(5+47)          226.9   */
46 	/************************************************/
47 
48 	/************************************************/
49 	/* Input register mapping for nitedrvr          */
50 	/************************************************/
51 	/*                    NODE                GAIN      OFFSET  INIT */
52 	DISCRETE_INPUTX_DATA (NITEDRVR_BANG_DATA, 1000.0/15, 0.0,   0.0)
53 	DISCRETE_INPUT_LOGIC (NITEDRVR_SKID1_EN)
54 	DISCRETE_INPUT_LOGIC (NITEDRVR_SKID2_EN)
55 	DISCRETE_INPUTX_DATA (NITEDRVR_MOTOR_DATA, -1, 0x0f, 0)
56 	DISCRETE_INPUT_LOGIC (NITEDRVR_CRASH_EN)
57 	DISCRETE_INPUT_NOT   (NITEDRVR_ATTRACT_EN)
58 
59 	/************************************************/
60 	/* NOTE: Motor circuit is a rip from Sprint for */
61 	/* now. This will have to be converted to 566.  */
62 	/*                                              */
63 	/* Motor sound circuit is based on a 556 VCO    */
64 	/* with the input frequency set by the MotorSND */
65 	/* latch (4 bit). This freqency is then used to */
66 	/* driver a modulo 12 counter, with div6, 4 & 3 */
67 	/* summed as the output of the circuit.         */
68 	/* VCO Output is Sq wave = 27-382Hz             */
69 	/*  F1 freq - (Div6)                            */
70 	/*  F2 freq = (Div4)                            */
71 	/*  F3 freq = (Div3) 33.3% duty, 33.3 deg phase */
72 	/* To generate the frequency we take the freq.  */
73 	/* diff. and /15 to get all the steps between   */
74 	/* 0 - 15.  Then add the low frequency and send */
75 	/* that value to a squarewave generator.        */
76 	/* Also as the frequency changes, it ramps due  */
77 	/* to a 2.2uf capacitor on the R-ladder.        */
78 	/* Note the VCO freq. is controlled by a 250k   */
79 	/* pot.  The freq. used here is for the pot set */
80 	/* to 125k.  The low freq is allways the same.  */
81 	/* This adjusts the high end.                   */
82 	/* 0k = 214Hz.   250k = 4416Hz                  */
83 	/************************************************/
84 	DISCRETE_RCFILTER(NODE_20, NITEDRVR_MOTOR_DATA, 123037, 2.2e-6)
85 	DISCRETE_ADJUSTMENT(NODE_21, (214.0-27.0)/12/31, (4416.0-27.0)/12/31, DISC_LOGADJ, "MOTOR")
86 	DISCRETE_MULTIPLY(NODE_22, NODE_20, NODE_21)
87 
88 	DISCRETE_MULTADD(NODE_23, NODE_22, 2, 27.0/6)   /* F1 = /12*2 = /6 */
89 	DISCRETE_SQUAREWAVE(NODE_24, 1, NODE_23, (786.7/3), 50.0, 0, 0)
90 	DISCRETE_RCFILTER(NODE_25, NODE_24, 10000, 1e-7)
91 
92 	DISCRETE_MULTADD(NODE_26, NODE_22, 3, 27.0/4)   /* F2 = /12*3 = /4 */
93 	DISCRETE_SQUAREWAVE(NODE_27, 1, NODE_26, (786.7/3), 50.0, 0, 0)
94 	DISCRETE_RCFILTER(NODE_28, NODE_27, 10000, 1e-7)
95 
96 	DISCRETE_MULTADD(NODE_29, NODE_22, 4, 27.0/3)   /* F3 = /12*4 = /3 */
97 	DISCRETE_SQUAREWAVE(NODE_30, 1, NODE_29, (786.7/3), 100.0/3, 0, 360.0/3)
98 	DISCRETE_RCFILTER(NODE_31, NODE_30, 10000, 1e-7)
99 
100 	DISCRETE_ADDER3(NITEDRVR_MOTOR_SND, NITEDRVR_ATTRACT_EN, NODE_25, NODE_28, NODE_31)
101 
102 	/************************************************/
103 	/* Bang circuit is built around a noise         */
104 	/* generator built from 2 shift registers that  */
105 	/* are clocked by the 4V signal.                */
106 	/* 4V = HSYNC/2/4                               */
107 	/*    = 15750/2/4                               */
108 	/* Output is integrated to apply decay.         */
109 	/************************************************/
110 	DISCRETE_LFSR_NOISE(NITEDRVR_NOISE, NITEDRVR_CRASH_EN, NITEDRVR_CRASH_EN, 15750.0/2/4, 1.0, 0, 0, &nitedrvr_lfsr)
111 
112 	DISCRETE_MULTIPLY(NODE_62, NITEDRVR_NOISE, NITEDRVR_BANG_DATA)
113 	DISCRETE_RCFILTER(NITEDRVR_BANG_SND, NODE_62, 545.6, 3.3e-7)
114 
115 	/************************************************/
116 	/* Skid circuits ripped from other drivers      */
117 	/* for now.                                     */
118 	/*                                              */
119 	/* Skid circuits takes the noise output from    */
120 	/* the crash circuit and applies +ve feedback   */
121 	/* to cause oscillation. There is also an RC    */
122 	/* filter on the input to the feedback cct.     */
123 	/* RC is 1K & 10uF                              */
124 	/* Feedback cct is modelled by using the RC out */
125 	/* as the frequency input on a VCO,             */
126 	/* breadboarded freq range as:                  */
127 	/*  0 = 940Hz, 34% duty                         */
128 	/*  1 = 630Hz, 29% duty                         */
129 	/*  the duty variance is so small we ignore it  */
130 	/************************************************/
131 	DISCRETE_INVERT(NODE_70, NITEDRVR_NOISE)
132 	DISCRETE_RCFILTER(NODE_71, NODE_70, 1000, 1e-5)
133 	DISCRETE_MULTADD(NODE_72, NODE_71, 940.0-630.0, ((940.0-630.0)/2)+630.0)
134 	DISCRETE_SQUAREWAVE(NITEDRVR_SCREECH1_SND, NITEDRVR_SKID1_EN, NODE_72, 226.9, 31.5, 0, 0.0)
135 
136 	DISCRETE_MULTADD(NODE_75, NODE_71, 1380.0-626.0, 626.0+((1380.0-626.0)/2))  /* Frequency */
137 	DISCRETE_MULTADD(NODE_76, NODE_71, 32.0-13.0, 13.0+((32.0-13.0)/2))     /* Duty */
138 	DISCRETE_SQUAREWAVE(NITEDRVR_SCREECH2_SND, NITEDRVR_SKID2_EN, NODE_75, 226.9, NODE_76, 0, 0.0)
139 
140 	/************************************************/
141 	/* Combine all sound sources.                   */
142 	/* Add some final gain to get to a good sound   */
143 	/* level.                                       */
144 	/************************************************/
145 	DISCRETE_ADDER4(NODE_90, 1, NITEDRVR_MOTOR_SND, NITEDRVR_BANG_SND, NITEDRVR_SCREECH1_SND, NITEDRVR_SCREECH2_SND)
146 
147 	DISCRETE_OUTPUT(NODE_90, 65534.0/(786.7+1000.0+226.9))
148 DISCRETE_SOUND_END
149