summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/laserbat.cpp
blob: 864b0c11c1f37fe4006459ade48e9385ef03c702 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
/*
    Laser Battle / Lazarian (c) 1981 Zaccaria
    Cat and Mouse           (c) 1982 Zaccaria

    audio emulation by Vas Crabb
*/

#include "emu.h"
#include "includes/laserbat.h"


uint8_t laserbat_state_base::rhsc_r()
{
	return m_rhsc;
}

void laserbat_state_base::whsc_w(uint8_t data)
{
	m_whsc = data;
}

void laserbat_state_base::csound1_w(uint8_t data)
{
	m_csound1 = data;
}

void laserbat_state_base::csound2_w(uint8_t data)
{
	m_csound2 = data;
}


/*
    The Laser Battle/Lazarian sound board has a SN76477 CSG, two TMS3615
    tone synthesisers, and a TDA1010 power amplifier.  It receives
    commands from the game board over a 16-bit unidirectional data bus.
    The CPU cannot write all sixteen lines atomically, it writes to
    lines 1-8 as one group and 9-16 as another group.

    The game board makes the audio output from the first S2636 PVI (5E)
    available on a pin at the sound board interface connector, but it
    isn't routed anywhere, so you won't hear it.

    The TMS3615 at 05 is clocked at 250kHz (4MHz crystal oscillator
    divided by 16), and its divide-by-two output is used to clock the
    TMS3615 at 04.  This gives a base 16' note of C3.  The combined 8'
    or 16' outputs are selectable by jumper, allowing the board to be
    switched between two octaves.  There's no indication of which octave
    would have been selected in the Lazarian manual.

    There's a filter network between the TMS3615 outputs and the power
    amplifier with several parameters controllable from the game board.

    The audio output of the SN76477 isn't actually used.  Rather, the
    signal from before the output amplifier is taken and used to gate
    distortion elements in the analog filter network.

    +-----+----------------------------------------------------------+
    | Bit | Function                                                 |
    +-----+----------------------------------------------------------+
    |   1 | Multiplexed data bit 1                                   |
    |   2 | Multiplexed data bit 2                                   |
    |   3 | Multiplexed data bit 3                                   |
    |   4 | Multiplexed data bit 4                                   |
    |   5 | Multiplexed data bit 5                                   |
    |   6 | Multiplexed data bit 6                                   |
    |   7 | Multiplexed data bit 7                                   |
    |   8 | Multiplexed data bit 8                                   |
    |   9 | SN76477/distortion control (positive edge trigger)       |
    |  10 | High octave key 13                                       |
    |  11 | Key/SLF resistor select A                                |
    |  12 | Key/SLF resistor select B                                |
    |  13 | Key/SLF resistor control                                 |
    |  14 | Gates 22k/10nF low-pass filter and one SN-driven effect  |
    |  15 | SN76477 VCO select (inverted)                            |
    |  16 | TMS3615 reset                                            |
    +-----+----------------------------------------------------------+

    +-------+----------+-----------------------------------+
    | 11-13 | SLF res. | Key select                        |
    +-------+----------+-----------------------------------+
    |   0   |   27k    |                                   |
    |   1   |   22k    |                                   |
    |   2   |   22k    |                                   |
    |   3   |   12k    |                                   |
    |   4   |   inf.   |                                   |
    |   5   |   inf.   | Low octave 1-8                    |
    |   6   |   inf.   | Low octave 9-13, high octave 2-4  |
    |   7   |   inf.   | High octave 5-12                  |
    +-------+----------+-----------------------------------+

    When bit 13 is high, no SLF control resistor is connected to the
    CSG.  When bit 13 is low, bits 11 and 12 select between 27k, 22k and
    12k.

    When bit 13 is high, the clock input of a latch driving eight of
    TMS3615 key inputs will be driven low, depending on bits 11 and 12.
    These latches are positive edge triggered, and you have to beware of
    glitches, so the safe way to set key inputs is:
    * Ensure bit 13 is low
    * Write desired key data pattern to CSOUND1
    * Write CSOUND2 setting bits 11 and 12 to select keys to set
    * Write CSOUND2 setting bit 13 high
    * Write CSOUND2 setting bit 13 low
    * Write CSOUND2 setting bits 11 and 12 to select SLF resistor

    Note that the SLF resistor will necessarily thrash around during the
    process of setting key data.  It's a side-effect of the way control
    lines are overloaded.

    The SN76477 control bits are defined as follows:

    +-----+---------------------------------------------------------+
    | Bit | Function                                                |
    +-----+---------------------------------------------------------+
    |  1  | Noise filter/VCO resistor select A                      |
    |  2  | Noise filter/VCO resistor select B                      |
    |  3  | Noise filter/VCO resistor select C                      |
    |  4  | AB SOUND (connected to System Inhibit input)            |
    |  5  | VCO/NOISE (connected to Mixer Select B input)           |
    |  6  | DEGR (controls a distortion element in filter network)  |
    |  7  | FILT (gates 10nF capacitor across distortion elements)  |
    |  8  | A (controls a distortion element in filter network)     |
    +-----+---------------------------------------------------------+

*/

void laserbat_state::csound2_w(uint8_t data)
{
	// there are a bunch of edge-triggered things, so grab changes
	unsigned const diff = data ^ m_csound2;

	// SN76477 and distortion control
	if (data & diff & 0x01)
	{
		switch (m_csound1 & 0x07)
		{
		case 0x00:
			m_csg->noise_filter_res_w(RES_K(270));  // R30
			m_csg->vco_res_w(RES_K(47));            // R47
			break;
		case 0x01:
			m_csg->noise_filter_res_w(RES_K(220));  // R23
			m_csg->vco_res_w(RES_K(27));            // R40
			break;
		case 0x02:
			m_csg->noise_filter_res_w(RES_K(150));  // R24
			m_csg->vco_res_w(RES_K(22));            // R41
			break;
		case 0x03:
			m_csg->noise_filter_res_w(RES_K(120));  // R25
			m_csg->vco_res_w(RES_K(15));            // R42
			break;
		case 0x04:
			m_csg->noise_filter_res_w(RES_K(82));   // R29
			m_csg->vco_res_w(RES_K(12));            // R46
			break;
		case 0x05:
			m_csg->noise_filter_res_w(RES_K(68));   // R28
			m_csg->vco_res_w(RES_K(8.2));           // R45
			break;
		case 0x06:
			m_csg->noise_filter_res_w(RES_K(47));   // R27
			m_csg->vco_res_w(RES_K(6.8));           // R44
			break;
		case 0x07:
			m_csg->noise_filter_res_w(RES_K(33));   // R26
			m_csg->vco_res_w(RES_K(4.7));           // R43
			break;
		}
		m_csg->enable_w((m_csound1 & 0x08) ? 1 : 0);
		m_csg->mixer_b_w((m_csound1 & 0x10) ? 1 : 0);
		// TODO: DEGR/FILT/A
	}

	// edge-triggered latches plus a dedicated bit for note control
	m_keys = (m_keys & 0x00ffffff) | ((data & 0x02) ? 0x01000000 : 0x00000000);
	if ((m_csound2 & 0x10) && (diff & 0x1c))
	{
		switch (m_csound2 & 0x0c)
		{
		case 0x00:
			break;
		case 0x04:
			m_keys = (m_keys & 0x01ffff00) | (unsigned(m_csound1) << 0);
			break;
		case 0x08:
			m_keys = (m_keys & 0x01ff00ff) | (unsigned(m_csound1) << 8);
			break;
		case 0x0c:
			m_keys = (m_keys & 0x0100ffff) | (unsigned(m_csound1) << 16);
			break;
		}
	}
	m_synth_low->enable_w((m_keys >> 0) & 0x01fff);
	m_synth_high->enable_w((m_keys >> 12) & 0x01ffe);

	// bits 11-13 set the SLF control register directly
	switch (data & 0x1c)
	{
	case 0x00:  // R54
		m_csg->slf_res_w(RES_K(27));
		break;
	case 0x04:  // R53
	case 0x08:  // R52
		m_csg->slf_res_w(RES_K(22));
		break;
	case 0x0c:  // R51
		m_csg->slf_res_w(RES_K(12));
		break;
	default:    // NC
		m_csg->slf_res_w(RES_INF);
		break;
	}

	// TODO: BIT14 filter control

	// inverted VCO select
	m_csg->vco_w((data & 0x40) ? 0 : 1);

	// TODO: BIT15 TMS reset

	// keep for detecting changes next time
	m_csound2 = data;
}


/*
    The Cat and Mouse sound board has a 6802 processor with three ROMs,
    a 6821 PIA, two AY-3-8910 PSGs, and some other logic and analog
    circuitry.  Unfortunately we lack a schematic, so all knowledge of
    this board is based on tracing the sound program, examining PCB
    photos and cross-referencing with the schematic for the 1B11142
    schematic.

    The 6821 PIA is mapped at addresses $005C..$005F.  The known PIA
    signal assignments are as follows:

    +------+-----------------------+
    | PA0  | PSG1/PSG2 DA0         |
    | PA1  | PSG1/PSG2 DA1         |
    | PA2  | PSG1/PSG2 DA2         |
    | PA3  | PSG1/PSG2 DA3         |
    | PA4  | PSG1/PSG2 DA4         |
    | PA5  | PSG1/PSG2 DA5         |
    | PA6  | PSG1/PSG2 DA6         |
    | PA7  | PSG1/PSG2 DA7         |
    | PB0  | PSG1 BC1              |
    | PB1  | PSG1 BDIR             |
    | PB2  | PSG2 BC1              |
    | PB3  | PSG2 BDIR             |
    | CA1  | Host interface bit 6  |
    | CB1  | periodic IRQ source   |
    | IRQA | 6802 NMI              |
    | IRQB | 6802 IRQ              |
    +------+-----------------------+

    The program makes use of I/O port A on the first PSG as outputs.  At
    a guess, it could have the same function as it does on other
    Zaccaria sound boards.

    The first PSG receives commands from the game board in the low five
    bits of port B.  Commands are processed on receiving an NMI.  The
    sound program always masks out the high three bits of the value so
    they could be connected to anything on the board.

    The I/O ports on the second PSG don't appear to be used at all.

    The game board sends commands to the sound board over a 16-bit
    unidirectional data bus.  The CPU cannot write all sixteen lines
    atomically, it write to lines 1-8 as one group and 9-16 as another
    group.  However only seven lines are actually connected to the sound
    board:

    +-----+----------+-------------+
    | Bit | Name     | Connection  |
    +-----+----------+-------------+
    |   1 | SOUND 0  | PSG1 IOB0   |
    |   2 | SOUND 1  | PSG1 IOB1   |
    |   3 | SOUND 2  | PSG1 IOB2   |
    |   4 | SOUND 3  | PSG1 IOB3   |
    |   5 | SOUND 4  | PSG1 IOB4   |
    |   6 | SOUND 5  | PIA CA1     |
    |   7 |          |             |
    |   8 |          |             |
    |   9 |          | 14L A11     |
    |  10 |          |             |
    |  11 |          |             |
    |  12 |          |             |
    |  13 |          |             |
    |  14 |          |             |
    |  15 |          |             |
    |  16 | RESET    | Unknown     |
    +-----+----------+-------------+

    Bit 9 is used to select the sprite ROM bank.  There's a wire visible
    on the component side of the PCB connecting it to the high address
    bit (A11) of the sprite ROM at 14L.

    There could well be other connections on the sound board - these are
    just what can be deduced by tracing the sound program.

    The game board makes the audio output from the first S2636 PVI
    (5E) available on a pin at the sound board interface connector, but
    it isn't routed anywhere.
*/

void catnmous_state::csound1_w(uint8_t data)
{
	m_audiopcb->sound_w(data);

	m_csound1 = data;
}

void catnmous_state::csound2_w(uint8_t data)
{
	// the bottom bit is used for sprite banking, of all things
	m_gfx2 = memregion("gfx2")->base() + ((data & 0x01) ? 0x0800 : 0x0000);

	// the top bit is called RESET on the wiring diagram
	m_audiopcb->reset_w((data & 0x80) ? 1 : 0);

	m_csound2 = data;
}