1 /****************************************************************************
2 *
3 * geebee.c
4 *
5 * sound driver
6 * juergen buchmueller <pullmoll@t-online.de>, jan 2000
7 *
8 ****************************************************************************/
9
10 #include <math.h>
11 #include "driver.h"
12
13 static void *volume_timer = NULL;
14 static UINT16 *decay = NULL;
15 static int channel;
16 static int sound_latch = 0;
17 static int sound_signal = 0;
18 static int volume = 0;
19 static int noise = 0;
20
volume_decay(int param)21 static void volume_decay(int param)
22 {
23 if( --volume < 0 )
24 volume = 0;
25 }
26
WRITE_HANDLER(geebee_sound_w)27 WRITE_HANDLER( geebee_sound_w )
28 {
29 stream_update(channel,0);
30 sound_latch = data;
31 volume = 0x7fff; /* set volume */
32 noise = 0x0000; /* reset noise shifter */
33 /* faster decay enabled? */
34 if( sound_latch & 8 )
35 {
36 /*
37 * R24 is 10k, Rb is 0, C57 is 1uF
38 * charge time t1 = 0.693 * (R24 + Rb) * C57 -> 0.22176s
39 * discharge time t2 = 0.693 * (Rb) * C57 -> 0
40 * Then C33 is only charged via D6 (1N914), not discharged!
41 * Decay:
42 * discharge C33 (1uF) through R50 (22k) -> 0.14058s
43 */
44 timer_adjust(volume_timer, TIME_IN_HZ(32768/0.14058), 0, TIME_IN_HZ(32768/0.14058));
45 }
46 else
47 {
48 /*
49 * discharge only after R49 (100k) in the amplifier section,
50 * so the volume shouldn't very fast and only when the signal
51 * is gated through 6N (4066).
52 * I can only guess here that the decay should be slower,
53 * maybe half as fast?
54 */
55 timer_adjust(volume_timer, TIME_IN_HZ(32768/0.2906), 0, TIME_IN_HZ(32768/0.2906));
56 }
57 }
58
geebee_sound_update(int param,INT16 * buffer,int length)59 static void geebee_sound_update(int param, INT16 *buffer, int length)
60 {
61 static int vcarry = 0;
62 static int vcount = 0;
63
64 while (length--)
65 {
66 *buffer++ = sound_signal;
67 /* 1V = HSYNC = 18.432MHz / 3 / 2 / 384 = 8000Hz */
68 vcarry -= 18432000 / 3 / 2 / 384;
69 while (vcarry < 0)
70 {
71 vcarry += Machine->sample_rate;
72 vcount++;
73 /* noise clocked with raising edge of 2V */
74 if ((vcount & 3) == 2)
75 {
76 /* bit0 = bit0 ^ !bit10 */
77 if ((noise & 1) == ((noise >> 10) & 1))
78 noise = ((noise << 1) & 0xfffe) | 1;
79 else
80 noise = (noise << 1) & 0xfffe;
81 }
82 switch (sound_latch & 7)
83 {
84 case 0: /* 4V */
85 sound_signal = (vcount & 0x04) ? decay[volume] : 0;
86 break;
87 case 1: /* 8V */
88 sound_signal = (vcount & 0x08) ? decay[volume] : 0;
89 break;
90 case 2: /* 16V */
91 sound_signal = (vcount & 0x10) ? decay[volume] : 0;
92 break;
93 case 3: /* 32V */
94 sound_signal = (vcount & 0x20) ? decay[volume] : 0;
95 break;
96 case 4: /* TONE1 */
97 sound_signal = !(vcount & 0x01) && !(vcount & 0x10) ? decay[volume] : 0;
98 break;
99 case 5: /* TONE2 */
100 sound_signal = !(vcount & 0x02) && !(vcount & 0x20) ? decay[volume] : 0;
101 break;
102 case 6: /* TONE3 */
103 sound_signal = !(vcount & 0x04) && !(vcount & 0x40) ? decay[volume] : 0;
104 break;
105 default: /* NOISE */
106 /* QH of 74164 #4V */
107 sound_signal = (noise & 0x8000) ? decay[volume] : 0;
108 }
109 }
110 }
111 }
112
geebee_sh_start(const struct MachineSound * msound)113 int geebee_sh_start(const struct MachineSound *msound)
114 {
115 int i;
116
117 decay = (UINT16 *)auto_malloc(32768 * sizeof(INT16));
118 if( !decay )
119 return 1;
120
121 for( i = 0; i < 0x8000; i++ )
122 decay[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
123
124 channel = stream_init("GeeBee", 100, Machine->sample_rate, 0, geebee_sound_update);
125
126 volume_timer = timer_alloc(volume_decay);
127 return 0;
128 }
129
geebee_sh_stop(void)130 void geebee_sh_stop(void)
131 {
132 }
133
geebee_sh_update(void)134 void geebee_sh_update(void)
135 {
136 stream_update(channel,0);
137 }
138