1 /*************************************************************************
2 
3 	Exidy 6502 hardware
4 
5 *************************************************************************/
6 
7 /* Sound channel usage
8    0 = CPU music,  Shoot
9    1 = Crash
10    2 = Spectar sound
11    3 = Tone generator
12 */
13 
14 #include "driver.h"
15 #include "exidy.h"
16 
17 static int tone_channel;
18 
19 unsigned char targ_spec_flag;
20 static unsigned char targ_sh_ctrl0=0;
21 static unsigned char targ_sh_ctrl1=0;
22 static unsigned char tone_active;
23 
24 #define MAXFREQ_A_TARG 125000
25 #define MAXFREQ_A_SPECTAR 525000
26 
27 static int sound_a_freq;
28 static unsigned char tone_pointer;
29 static unsigned char tone_offset;
30 
31 static unsigned char tone_prom[32] =
32 {
33     0xE5,0xE5,0xED,0xED,0xE5,0xE5,0xED,0xED,0xE7,0xE7,0xEF,0xEF,0xE7,0xE7,0xEF,0xEF,
34     0xC1,0xE1,0xC9,0xE9,0xC5,0xE5,0xCD,0xED,0xC3,0xE3,0xCB,0xEB,0xC7,0xE7,0xCF,0xEF
35 };
36 
37 /* waveforms for the audio hardware */
38 static unsigned char waveform1[32] =
39 {
40 	/* sine-wave */
41 	0x0F, 0x0F, 0x0F, 0x06, 0x06, 0x09, 0x09, 0x06, 0x06, 0x09, 0x06, 0x0D, 0x0F, 0x0F, 0x0D, 0x00,
42 	0xE6, 0xDE, 0xE1, 0xE6, 0xEC, 0xE6, 0xE7, 0xE7, 0xE7, 0xEC, 0xEC, 0xEC, 0xE7, 0xE1, 0xE1, 0xE7,
43 };
44 
45 /* some macros to make detecting bit changes easier */
46 #define RISING_EDGE(bit)  ((data & bit) && !(targ_sh_ctrl0 & bit))
47 #define FALLING_EDGE(bit) (!(data & bit) && (targ_sh_ctrl0 & bit))
48 
49 
targ_tone_generator(int data)50 void targ_tone_generator(int data)
51 {
52 	int maxfreq;
53 
54 
55 	if (targ_spec_flag) maxfreq = MAXFREQ_A_TARG;
56 	else maxfreq = MAXFREQ_A_SPECTAR;
57 
58     sound_a_freq = data;
59     if (sound_a_freq == 0xFF || sound_a_freq == 0x00)
60 	{
61 		mixer_set_volume(tone_channel,0);
62     }
63     else
64 	{
65 		mixer_set_sample_frequency(tone_channel,maxfreq/(0xFF-sound_a_freq));
66 		mixer_set_volume(tone_channel,tone_active*100);
67 	}
68 }
69 
targ_sh_start(const struct MachineSound * msound)70 int targ_sh_start(const struct MachineSound *msound)
71 {
72 	tone_channel = mixer_allocate_channel(50);
73 
74 	tone_pointer=0;
75 	tone_offset=0;
76 	tone_active=0;
77 	sound_a_freq = 0x00;
78 	mixer_set_volume(tone_channel,0);
79 	mixer_play_sample(tone_channel,(signed char*)waveform1,32,1000,1);
80 	return 0;
81 }
82 
targ_sh_stop(void)83 void targ_sh_stop(void)
84 {
85     mixer_stop_sample(tone_channel);
86 }
87 
WRITE_HANDLER(targ_sh_w)88 WRITE_HANDLER( targ_sh_w )
89 {
90 	int maxfreq;
91 
92 
93 	if (targ_spec_flag) maxfreq = MAXFREQ_A_TARG;
94 	else maxfreq = MAXFREQ_A_SPECTAR;
95 
96     if (offset) {
97         if (targ_spec_flag) {
98             if (data & 0x02)
99                 tone_offset=16;
100             else
101                 tone_offset=0;
102 
103             if ((data & 0x01) && !(targ_sh_ctrl1 & 0x01)) {
104                 tone_pointer++;
105                 if (tone_pointer > 15) tone_pointer = 0;
106                 targ_tone_generator(tone_prom[tone_pointer+tone_offset]);
107             }
108        }
109        else {
110             targ_tone_generator(data);
111        }
112        targ_sh_ctrl1=data;
113     }
114     else
115     {
116         /* cpu music */
117         if ((data & 0x01) != (targ_sh_ctrl0 & 0x01)) {
118             DAC_data_w(0,(data & 0x01) * 0xFF);
119         }
120         /* Shoot */
121         if FALLING_EDGE(0x02) {
122             if (!sample_playing(0))  sample_start(0,1,0);
123         }
124         if RISING_EDGE(0x02) {
125             sample_stop(0);
126         }
127 
128         /* Crash */
129         if RISING_EDGE(0x20) {
130             if (data & 0x40) {
131                 sample_start(1,2,0); }
132             else {
133                 sample_start(1,0,0); }
134         }
135 
136         /* Sspec */
137         if (data & 0x10) {
138             sample_stop(2);
139         }
140         else {
141             if ((data & 0x08) != (targ_sh_ctrl0 & 0x08)) {
142             if (data & 0x08) {
143                 sample_start(2,3,1); }
144             else {
145                 sample_start(2,4,1); }
146             }
147         }
148 
149         /* Game (tone generator enable) */
150         if FALLING_EDGE(0x80) {
151            tone_pointer=0;
152            tone_active=0;
153            if (sound_a_freq == 0xFF || sound_a_freq == 0x00)
154 		   {
155 				mixer_set_volume(tone_channel,0);
156            }
157            else
158 		   {
159              mixer_set_sample_frequency(tone_channel,maxfreq/(0xFF-sound_a_freq));
160              mixer_set_volume(tone_channel,0);
161 		   }
162         }
163         if RISING_EDGE(0x80) {
164             tone_active=1;
165         }
166         targ_sh_ctrl0 = data;
167     }
168 }
169 
170