1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 /***************************************************************************
4
5 Sega Zaxxon hardware
6
7 ****************************************************************************
8
9 Sound interface is provided by an 8255. The 8255 is a parallel peripheral
10 interface, used also in Scramble. It has three 8-bit outputs.
11 All sounds are generated by discrete circuits. Each sound is triggered by
12 an output pin of the 8255.
13
14 Zaxxon Sound Information: (from the schematics)
15 by Frank Palazzolo
16
17 There are four registers in the 8255. they are mapped to
18 (111x xxxx 0011 11pp) by Zaxxon. Zaxxon writes to these
19 at FF3C-FF3F.
20
21 There are three modes of the 8255, but by the schematics I
22 can see that Zaxxon is using "Mode 0", which is very simple.
23
24 Important Note:
25 These are all Active-Low outputs.
26 A 1 De-activates the sound, while a 0 Activates/Triggers it
27
28 Port A Output:
29 FF3C bit7 Battleship
30 bit6 Laser
31 bit5 Base Missle
32 bit4 Homing Missle
33 bit3 Player Ship D
34 bit2 Player Ship C
35 bit1 Player Ship B
36 bit0 Player Ship A
37
38 Port B Output:
39 FF3D bit7 Cannon
40 bit6 N/C
41 bit5 M-Exp
42 bit4 S-Exp
43 bit3 N/C
44 bit2 N/C
45 bit1 N/C
46 bit0 N/C
47
48 Port C Output:
49 FF3E bit7 N/C
50 bit6 N/C
51 bit5 N/C
52 bit4 N/C
53 bit3 Alarm 3
54 bit2 Alarm 2
55 bit1 N/C
56 bit0 Shot
57
58 Control Byte:
59 FF3F Should be written an 0x80 for Mode 0
60 (Very Simple) operation of the 8255
61
62 ***************************************************************************/
63
64 #include "emu.h"
65 #include "sound/samples.h"
66 #include "includes/zaxxon.h"
67
68
69
70 /*************************************
71 *
72 * Zaxxon sound hardware description
73 *
74 *************************************/
75
76 static const char *const zaxxon_sample_names[] =
77 {
78 "*zaxxon",
79 "03", /* 0 - Homing Missile */
80 "02", /* 1 - Base Missile */
81 "01", /* 2 - Laser (force field) */
82 "00", /* 3 - Battleship (end of level boss) */
83 "11", /* 4 - S-Exp (enemy explosion) */
84 "10", /* 5 - M-Exp (ship explosion) */
85 "08", /* 6 - Cannon (ship fire) */
86 "23", /* 7 - Shot (enemy fire) */
87 "21", /* 8 - Alarm 2 (target lock) */
88 "20", /* 9 - Alarm 3 (low fuel) */
89 "05", /* 10 - initial background noise */
90 "04", /* 11 - looped asteroid noise */
91 nullptr
92 };
93
94
zaxxon_samples(machine_config & config)95 void zaxxon_state::zaxxon_samples(machine_config &config)
96 {
97 SAMPLES(config, m_samples);
98 m_samples->set_channels(12);
99 m_samples->set_samples_names(zaxxon_sample_names);
100 m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25);
101 }
102
103
104
105 /*************************************
106 *
107 * Zaxxon PPI write handlers
108 *
109 *************************************/
110
zaxxon_sound_a_w(uint8_t data)111 void zaxxon_state::zaxxon_sound_a_w(uint8_t data)
112 {
113 uint8_t diff = data ^ m_sound_state[0];
114 m_sound_state[0] = data;
115
116 /* PLAYER SHIP A/B: volume */
117 m_samples->set_volume(10, 0.5 + 0.157 * (data & 0x03));
118 m_samples->set_volume(11, 0.5 + 0.157 * (data & 0x03));
119
120 /* PLAYER SHIP C: channel 10 */
121 if ((diff & 0x04) && !(data & 0x04)) m_samples->start(10, 10, true);
122 if ((diff & 0x04) && (data & 0x04)) m_samples->stop(10);
123
124 /* PLAYER SHIP D: channel 11 */
125 if ((diff & 0x08) && !(data & 0x08)) m_samples->start(11, 11, true);
126 if ((diff & 0x08) && (data & 0x08)) m_samples->stop(11);
127
128 /* HOMING MISSILE: channel 0 */
129 if ((diff & 0x10) && !(data & 0x10)) m_samples->start(0, 0, true);
130 if ((diff & 0x10) && (data & 0x10)) m_samples->stop(0);
131
132 /* BASE MISSILE: channel 1 */
133 if ((diff & 0x20) && !(data & 0x20)) m_samples->start(1, 1);
134
135 /* LASER: channel 2 */
136 if ((diff & 0x40) && !(data & 0x40)) m_samples->start(2, 2, true);
137 if ((diff & 0x40) && (data & 0x40)) m_samples->stop(2);
138
139 /* BATTLESHIP: channel 3 */
140 if ((diff & 0x80) && !(data & 0x80)) m_samples->start(3, 3, true);
141 if ((diff & 0x80) && (data & 0x80)) m_samples->stop(3);
142 }
143
144
zaxxon_sound_b_w(uint8_t data)145 void zaxxon_state::zaxxon_sound_b_w(uint8_t data)
146 {
147 uint8_t diff = data ^ m_sound_state[1];
148 m_sound_state[1] = data;
149
150 /* S-EXP: channel 4 */
151 if ((diff & 0x10) && !(data & 0x10)) m_samples->start(4, 4);
152
153 /* M-EXP: channel 5 */
154 if ((diff & 0x20) && !(data & 0x20) && !m_samples->playing(5)) m_samples->start(5, 5);
155
156 /* CANNON: channel 6 */
157 if ((diff & 0x80) && !(data & 0x80)) m_samples->start(6, 6);
158 }
159
160
zaxxon_sound_c_w(uint8_t data)161 void zaxxon_state::zaxxon_sound_c_w(uint8_t data)
162 {
163 uint8_t diff = data ^ m_sound_state[2];
164 m_sound_state[2] = data;
165
166 /* SHOT: channel 7 */
167 if ((diff & 0x01) && !(data & 0x01)) m_samples->start(7, 7);
168
169 /* ALARM2: channel 8 */
170 if ((diff & 0x04) && !(data & 0x04)) m_samples->start(8, 8);
171
172 /* ALARM3: channel 9 */
173 if ((diff & 0x08) && !(data & 0x08) && !m_samples->playing(9)) m_samples->start(9, 9);
174 }
175
176
177
178 /*************************************
179 *
180 * Congo sound hardware description
181 *
182 *************************************/
183
184 static const char *const congo_sample_names[] =
185 {
186 "*congo",
187 "gorilla", /* 0 */
188 "bass", /* 1 */
189 "congal", /* 2 */
190 "congah", /* 3 */
191 "rim", /* 4 */
192 nullptr
193 };
194
195
congo_samples(machine_config & config)196 void zaxxon_state::congo_samples(machine_config &config)
197 {
198 SAMPLES(config, m_samples);
199 m_samples->set_channels(5);
200 m_samples->set_samples_names(congo_sample_names);
201 m_samples->add_route(ALL_OUTPUTS, "speaker", 0.25);
202 }
203
204
205
206 /*************************************
207 *
208 * Congo PPI write handlers
209 *
210 *************************************/
211
congo_sound_b_w(uint8_t data)212 void zaxxon_state::congo_sound_b_w(uint8_t data)
213 {
214 uint8_t diff = data ^ m_sound_state[1];
215 m_sound_state[1] = data;
216
217 /* bit 7 = mute */
218
219 /* GORILLA: channel 0 */
220 if ((diff & 0x02) && !(data & 0x02) && !m_samples->playing(0)) m_samples->start(0, 0);
221 }
222
223
congo_sound_c_w(uint8_t data)224 void zaxxon_state::congo_sound_c_w(uint8_t data)
225 {
226 uint8_t diff = data ^ m_sound_state[2];
227 m_sound_state[2] = data;
228
229 /* BASS DRUM: channel 1 */
230 if ((diff & 0x01) && !(data & 0x01)) m_samples->start(1, 1);
231 if ((diff & 0x01) && (data & 0x01)) m_samples->stop(1);
232
233 /* CONGA (LOW): channel 2 */
234 if ((diff & 0x02) && !(data & 0x02)) m_samples->start(2, 2);
235 if ((diff & 0x02) && (data & 0x02)) m_samples->stop(2);
236
237 /* CONGA (HIGH): channel 3 */
238 if ((diff & 0x04) && !(data & 0x04)) m_samples->start(3, 3);
239 if ((diff & 0x04) && (data & 0x04)) m_samples->stop(3);
240
241 /* RIM: channel 4 */
242 if ((diff & 0x08) && !(data & 0x08)) m_samples->start(4, 4);
243 if ((diff & 0x08) && (data & 0x08)) m_samples->stop(4);
244 }
245