~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/mame/audio/gottlieb.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Emmanuel Kasper, Jordi Mallach
  • Date: 2012-06-05 20:02:23 UTC
  • mfrom: (0.3.1) (0.1.4)
  • Revision ID: package-import@ubuntu.com-20120605200223-gnlpogjrg6oqe9md
Tags: 0.146-1
[ Emmanuel Kasper ]
* New upstream release
* Drop patch to fix man pages section and patches to link with flac 
  and jpeg system lib: all this has been pushed upstream by Cesare Falco
* Add DM-Upload-Allowed: yes field.

[ Jordi Mallach ]
* Create a "gnu" TARGETOS stanza that defines NO_AFFINITY_NP.
* Stop setting TARGETOS to "unix" in d/rules. It should be autodetected,
  and set to the appropriate value.
* mame_manpage_section.patch: Change mame's manpage section to 6 (games),
  in the TH declaration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
2
 
3
 
    Gottlieb hardware
4
 
    dedicated to Warren Davis, Jeff Lee, Tim Skelly & David Thiel
 
3
    gottlieb.h
 
4
 
 
5
    Gottlieb 6502-based sound hardware implementations.
 
6
 
 
7
    Dedicated to Warren Davis, Jeff Lee, Tim Skelly & David Thiel
 
8
 
 
9
****************************************************************************
 
10
 
 
11
    Copyright Aaron Giles
 
12
    All rights reserved.
 
13
 
 
14
    Redistribution and use in source and binary forms, with or without
 
15
    modification, are permitted provided that the following conditions are
 
16
    met:
 
17
 
 
18
        * Redistributions of source code must retain the above copyright
 
19
          notice, this list of conditions and the following disclaimer.
 
20
        * Redistributions in binary form must reproduce the above copyright
 
21
          notice, this list of conditions and the following disclaimer in
 
22
          the documentation and/or other materials provided with the
 
23
          distribution.
 
24
        * Neither the name 'MAME' nor the names of its contributors may be
 
25
          used to endorse or promote products derived from this software
 
26
          without specific prior written permission.
 
27
 
 
28
    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
 
29
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
30
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
31
    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
 
32
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
33
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
34
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
35
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
36
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
37
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
38
    POSSIBILITY OF SUCH DAMAGE.
5
39
 
6
40
***************************************************************************/
7
41
 
8
42
#include "emu.h"
9
 
#include "debugger.h"
10
 
#include "cpu/m6502/m6502.h"
11
 
#include "machine/6532riot.h"
12
 
#include "sound/samples.h"
13
 
#include "sound/dac.h"
14
 
#include "sound/ay8910.h"
15
 
//#include "sound/votrax.h"
16
 
#include "sound/sp0250.h"
17
43
#include "includes/gottlieb.h"
18
44
 
19
45
 
22
48
#define SOUND2_SPEECH_CLOCK     XTAL_3_12MHz
23
49
 
24
50
 
25
 
 
26
 
 
27
 
 
28
 
 
29
 
 
30
 
 
31
 
 
32
 
static void gottlieb1_sh_w(device_t *riot, UINT8 data);
33
 
static void gottlieb2_sh_w(address_space *space, UINT8 data);
34
 
static void trigger_sample(device_t *samples, UINT8 data);
35
 
 
36
 
 
37
 
 
38
 
/*************************************
39
 
 *
40
 
 *  Generic interfaces
41
 
 *
42
 
 *************************************/
43
 
 
44
 
WRITE8_HANDLER( gottlieb_sh_w )
45
 
{
46
 
        device_t *riot = space->machine().device("riot");
47
 
 
48
 
        /* identify rev1 boards by the presence of a 6532 RIOT device */
49
 
        if (riot != NULL)
50
 
                gottlieb1_sh_w(riot, data);
51
 
        else
52
 
                gottlieb2_sh_w(space, data);
53
 
}
54
 
 
55
 
 
56
 
 
57
 
/*************************************
58
 
 *
59
 
 *  Rev. 1 handlers
60
 
 *
61
 
 *************************************/
62
 
 
63
 
static void gottlieb1_sh_w(device_t *riot, UINT8 data)
64
 
{
65
 
        device_t *samples = riot->machine().device("samples");
66
 
        int pa7 = (data & 0x0f) != 0xf;
67
 
        int pa0_5 = ~data & 0x3f;
68
 
 
69
 
        /* snoop the data looking for commands that need samples */
70
 
        if (pa7 && samples != NULL)
71
 
                trigger_sample(samples, pa0_5);
72
 
 
73
 
        /* write the command data to the low 6 bits, and the trigger to the upper bit */
74
 
        riot6532_porta_in_set(riot, pa0_5 | (pa7 << 7), 0xbf);
75
 
}
76
 
 
77
 
 
78
 
 
79
 
/*************************************
80
 
 *
81
 
 *  Rev. 1 RIOT interfaces
82
 
 *
83
 
 *************************************/
84
 
 
85
 
static WRITE_LINE_DEVICE_HANDLER( snd_interrupt )
86
 
{
87
 
        cputag_set_input_line(device->machine(), "audiocpu", M6502_IRQ_LINE, state);
88
 
}
89
 
 
90
 
 
91
 
static WRITE8_DEVICE_HANDLER( r6532_portb_w )
92
 
{
93
 
        /* unsure if this is ever used, but the NMI is connected to the RIOT's PB7 */
94
 
        cputag_set_input_line(device->machine(), "audiocpu", INPUT_LINE_NMI, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
95
 
}
96
 
 
97
 
 
98
 
static const riot6532_interface gottlieb_riot6532_intf =
99
 
{
100
 
        DEVCB_NULL,
101
 
        DEVCB_INPUT_PORT("SB1"),
102
 
        DEVCB_NULL,
103
 
        DEVCB_HANDLER(r6532_portb_w),
104
 
        DEVCB_LINE(snd_interrupt)
105
 
};
106
 
 
107
 
 
108
 
 
109
 
/*************************************
110
 
 *
111
 
 *  Rev. 1 sample players
112
 
 *
113
 
 *************************************/
114
 
 
115
 
static void play_sample(device_t *samples, const char *phonemes)
116
 
{
117
 
        if (strcmp(phonemes, "[0] HEH3LOOW     AH1EH3I3YMTERI2NDAHN") == 0)       /* Q-Bert - Hello, I am turned on */
118
 
                sample_start(samples, 0, 42, 0);
119
 
        else if (strcmp(phonemes, "[0]BAH1EH1Y") == 0)                                                    /* Q-Bert - Bye, bye */
120
 
                sample_start(samples, 0, 43, 0);
121
 
        else if (strcmp(phonemes, "[0]A2YHT LEH2FTTH") == 0)                                      /* Reactor - Eight left */
122
 
                sample_start(samples, 0, 0, 0);
123
 
        else if (strcmp(phonemes, "[0]SI3KS DTYN LEH2FTTH") == 0)                                 /* Reactor - Sixteen left */
124
 
                sample_start(samples, 0, 1, 0);
125
 
        else if (strcmp(phonemes, "[0]WO2RNYNG KO2R UH1NSDTABUH1L") == 0)                 /* Reactor - Warning core unstable */
126
 
                sample_start(samples, 0, 5, 0);
127
 
        else if (strcmp(phonemes, "[0]CHAMBERR   AE1EH2KTI1VA1I3DTEH1DT ") == 0) /* Reactor - Chamber activated */
128
 
                sample_start(samples, 0, 7, 0);
129
 
}
130
 
 
131
 
 
132
 
static void trigger_sample(device_t *samples, UINT8 data)
133
 
{
134
 
        gottlieb_state *state = samples->machine().driver_data<gottlieb_state>();
 
51
//**************************************************************************
 
52
//  GLOBAL VARIABLES
 
53
//**************************************************************************
 
54
 
 
55
extern const device_type GOTTLIEB_SOUND_REV1 = &device_creator<gottlieb_sound_r1_device>;
 
56
extern const device_type GOTTLIEB_SOUND_REV1_WITH_VOTRAX = &device_creator<gottlieb_sound_r1_with_votrax_device>;
 
57
extern const device_type GOTTLIEB_SOUND_REV2 = &device_creator<gottlieb_sound_r2_device>;
 
58
 
 
59
 
 
60
 
 
61
//**************************************************************************
 
62
//  OLD CRAPPY SAMPLE PLAYER
 
63
//**************************************************************************
 
64
 
 
65
#if USE_FAKE_VOTRAX
 
66
 
 
67
void gottlieb_sound_r1_device::trigger_sample(UINT8 data)
 
68
{
135
69
        /* Reactor samples */
136
 
        if (strcmp(samples->machine().system().name, "reactor") == 0)
 
70
        if (strcmp(machine().system().name, "reactor") == 0)
137
71
        {
138
72
                switch (data)
139
73
                {
141
75
                        case 56:
142
76
                        case 57:
143
77
                        case 59:
144
 
                                sample_start(samples, 0, data - 53, 0);
 
78
                                m_samples->start(0, data - 53);
145
79
                                break;
146
80
 
147
81
                        case 31:
148
 
                                state->m_score_sample = 7;
 
82
                                m_score_sample = 7;
149
83
                                break;
150
84
 
151
85
                        case 39:
152
 
                                state->m_score_sample++;
153
 
                                if (state->m_score_sample < 20)
154
 
                                        sample_start(samples, 0, state->m_score_sample, 0);
 
86
                                m_score_sample++;
 
87
                                if (m_score_sample < 20)
 
88
                                        m_samples->start(0, m_score_sample);
155
89
                                break;
156
90
                }
157
91
        }
166
100
                        case 19:
167
101
                        case 20:
168
102
                        case 21:
169
 
                                sample_start(samples, 0, (data - 17) * 8 + state->m_random_offset, 0);
170
 
                                state->m_random_offset = (state->m_random_offset + 1) & 7;
 
103
                                m_samples->start(0, (data - 17) * 8 + m_random_offset);
 
104
                                m_random_offset = (m_random_offset + 1) & 7;
171
105
                                break;
172
106
 
173
107
                        case 22:
174
 
                                sample_start(samples, 0,40,0);
 
108
                                m_samples->start(0,40);
175
109
                                break;
176
110
 
177
111
                        case 23:
178
 
                                sample_start(samples, 0,41,0);
 
112
                                m_samples->start(0,41);
179
113
                                break;
180
114
                }
181
115
        }
182
116
}
183
117
 
184
 
 
185
 
#ifdef UNUSED_FUNCTION
186
 
void gottlieb_knocker(running_machine &machine)
187
 
{
188
 
        device_t *samples = space->machine().device("samples");
189
 
        if (!strcmp(machine.system().name,"reactor"))   /* reactor */
190
 
        {
191
 
        }
192
 
        else if (samples != NULL)       /* qbert */
193
 
                sample_start(samples, 0,44,0);
194
 
}
195
 
#endif
196
 
 
197
 
 
198
 
 
199
 
/*************************************
200
 
 *
201
 
 *  Rev. 1 speech interface
202
 
 *
203
 
 *************************************/
204
 
 
205
 
/* callback for the timer */
206
 
static TIMER_CALLBACK( gottlieb_nmi_generate )
207
 
{
208
 
        cputag_set_input_line(machine, "audiocpu", INPUT_LINE_NMI, PULSE_LINE);
209
 
}
210
 
 
211
 
 
212
 
static WRITE8_HANDLER( vortrax_data_w )
213
 
{
214
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
 
118
void gottlieb_sound_r1_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
 
119
{
 
120
        m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
 
121
}
 
122
 
 
123
void gottlieb_sound_r1_device::fake_votrax_data_w(UINT8 data)
 
124
{
215
125
        static const char *const PhonemeTable[0x40] =
216
126
        {
217
127
                "EH3", "EH2", "EH1", "PA0", "DT" , "A1" , "A2" , "ZH",
228
138
 
229
139
logerror("Votrax: intonation %d, phoneme %02x %s\n",data >> 6,data & 0x3f,PhonemeTable[data & 0x3f]);
230
140
 
231
 
        state->m_votrax_queue[state->m_votrax_queuepos++] = data;
 
141
        m_votrax_queue[m_votrax_queuepos++] = data;
232
142
 
233
143
        if ((data & 0x3f) == 0x3f)
234
144
        {
235
 
                if (state->m_votrax_queuepos > 1)
 
145
                if (m_votrax_queuepos > 1)
236
146
                {
237
 
                        device_t *samples = space->machine().device("samples");
238
147
                        int last = -1;
239
148
                        int i;
240
149
                        char phonemes[200];
241
150
 
242
151
                        phonemes[0] = 0;
243
 
                        for (i = 0;i < state->m_votrax_queuepos-1;i++)
 
152
                        for (i = 0;i < m_votrax_queuepos-1;i++)
244
153
                        {
245
154
                                static const char *const inf[4] = { "[0]", "[1]", "[2]", "[3]" };
246
 
                                int phoneme = state->m_votrax_queue[i] & 0x3f;
247
 
                                int inflection = state->m_votrax_queue[i] >> 6;
 
155
                                int phoneme = m_votrax_queue[i] & 0x3f;
 
156
                                int inflection = m_votrax_queue[i] >> 6;
248
157
                                if (inflection != last) strcat(phonemes, inf[inflection]);
249
158
                                last = inflection;
250
159
                                if (phoneme == 0x03 || phoneme == 0x3e) strcat(phonemes," ");
252
161
                        }
253
162
 
254
163
                        mame_printf_debug("Votrax played '%s'\n", phonemes);
255
 
                        play_sample(samples, phonemes);
256
 
#if 0
257
 
                        popmessage("%s", phonemes);
258
 
#endif
 
164
 
 
165
                        if (strcmp(phonemes, "[0] HEH3LOOW     AH1EH3I3YMTERI2NDAHN") == 0)       /* Q-Bert & Tylz - Hello, I am turned on */
 
166
                                m_samples->start(0, 42);
 
167
                        else if (strcmp(phonemes, "[0]BAH1EH1Y") == 0)                                                    /* Q-Bert - Bye, bye */
 
168
                                m_samples->start(0, 43);
 
169
                        else if (strcmp(phonemes, "[0]A2YHT LEH2FTTH") == 0)                                      /* Reactor - Eight left */
 
170
                                m_samples->start(0, 0);
 
171
                        else if (strcmp(phonemes, "[0]SI3KS DTYN LEH2FTTH") == 0)                                 /* Reactor - Sixteen left */
 
172
                                m_samples->start(0, 1);
 
173
                        else if (strcmp(phonemes, "[0]WO2RNYNG KO2R UH1NSDTABUH1L") == 0)                 /* Reactor - Warning core unstable */
 
174
                                m_samples->start(0, 5);
 
175
                        else if (strcmp(phonemes, "[0]CHAMBERR   AE1EH2KTI1VA1I3DTEH1DT ") == 0) /* Reactor - Chamber activated */
 
176
                                m_samples->start(0, 7);
259
177
                }
260
178
 
261
 
                state->m_votrax_queuepos = 0;
 
179
                m_votrax_queuepos = 0;
262
180
        }
263
181
 
264
182
        /* generate a NMI after a while to make the CPU continue to send data */
265
 
        space->machine().scheduler().timer_set(attotime::from_usec(50), FUNC(gottlieb_nmi_generate));
266
 
}
267
 
 
268
 
static WRITE8_HANDLER( speech_clock_dac_w )
269
 
{
270
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
271
 
if (data != state->m_last)
272
 
        mame_printf_debug("clock = %02X\n", data);
273
 
state->m_last = data;
274
 
}
275
 
 
276
 
 
277
 
/*************************************
278
 
 *
279
 
 *  Rev 1. initialization
280
 
 *
281
 
 *************************************/
282
 
 
283
 
static SOUND_START( gottlieb1 )
284
 
{
285
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
286
 
        state->m_score_sample = 7;
287
 
        state->m_random_offset = 0;
288
 
 
289
 
        state_save_register_global_array(machine, state->m_votrax_queue);
290
 
        state_save_register_global(machine, state->m_votrax_queuepos);
291
 
}
292
 
 
293
 
 
294
 
 
295
 
/*************************************
296
 
 *
297
 
 *  Rev 1. address map
298
 
 *
299
 
 *************************************/
300
 
 
301
 
static ADDRESS_MAP_START( gottlieb_sound1_map, AS_PROGRAM, 8 )
302
 
        /* A15 not decoded except in expansion socket */
 
183
        timer_set(attotime::from_usec(50));
 
184
}
 
185
 
 
186
static const char *const reactor_sample_names[] =
 
187
{
 
188
        "*reactor",
 
189
        "fx_53", /* "8 left" */
 
190
        "fx_54", /* "16 left" */
 
191
        "fx_55", /* "24 left" */
 
192
        "fx_56", /* "32 left" */
 
193
        "fx_57", /* "40 left" */
 
194
        "fx_58", /* "warning, core unstable" */
 
195
        "fx_59", /* "bonus" */
 
196
        "fx_31", /* "chamber activated" */
 
197
        "fx_39a", /* "2000" */
 
198
        "fx_39b", /* "5000" */
 
199
        "fx_39c", /* "10000" */
 
200
        "fx_39d", /* "15000" */
 
201
        "fx_39e", /* "20000" */
 
202
        "fx_39f", /* "25000" */
 
203
        "fx_39g", /* "30000" */
 
204
        "fx_39h", /* "35000" */
 
205
        "fx_39i", /* "40000" */
 
206
        "fx_39j", /* "45000" */
 
207
        "fx_39k", /* "50000" */
 
208
        "fx_39l", /* "55000" */
 
209
     0  /* end of array */
 
210
};
 
211
 
 
212
static const char *const qbert_sample_names[] =
 
213
{
 
214
        "*qbert",
 
215
        "fx_17a", /* random speech, voice clock 255 */
 
216
        "fx_17b", /* random speech, voice clock 255 */
 
217
        "fx_17c", /* random speech, voice clock 255 */
 
218
        "fx_17d", /* random speech, voice clock 255 */
 
219
        "fx_17e", /* random speech, voice clock 255 */
 
220
        "fx_17f", /* random speech, voice clock 255 */
 
221
        "fx_17g", /* random speech, voice clock 255 */
 
222
        "fx_17h", /* random speech, voice clock 255 */
 
223
        "fx_18a", /* random speech, voice clock 176 */
 
224
        "fx_18b", /* random speech, voice clock 176 */
 
225
        "fx_18c", /* random speech, voice clock 176 */
 
226
        "fx_18d", /* random speech, voice clock 176 */
 
227
        "fx_18e", /* random speech, voice clock 176 */
 
228
        "fx_18f", /* random speech, voice clock 176 */
 
229
        "fx_18g", /* random speech, voice clock 176 */
 
230
        "fx_18h", /* random speech, voice clock 176 */
 
231
        "fx_19a", /* random speech, voice clock 128 */
 
232
        "fx_19b", /* random speech, voice clock 128 */
 
233
        "fx_19c", /* random speech, voice clock 128 */
 
234
        "fx_19d", /* random speech, voice clock 128 */
 
235
        "fx_19e", /* random speech, voice clock 128 */
 
236
        "fx_19f", /* random speech, voice clock 128 */
 
237
        "fx_19g", /* random speech, voice clock 128 */
 
238
        "fx_19h", /* random speech, voice clock 128 */
 
239
        "fx_20a", /* random speech, voice clock 96 */
 
240
        "fx_20b", /* random speech, voice clock 96 */
 
241
        "fx_20c", /* random speech, voice clock 96 */
 
242
        "fx_20d", /* random speech, voice clock 96 */
 
243
        "fx_20e", /* random speech, voice clock 96 */
 
244
        "fx_20f", /* random speech, voice clock 96 */
 
245
        "fx_20g", /* random speech, voice clock 96 */
 
246
        "fx_20h", /* random speech, voice clock 96 */
 
247
        "fx_21a", /* random speech, voice clock 62 */
 
248
        "fx_21b", /* random speech, voice clock 62 */
 
249
        "fx_21c", /* random speech, voice clock 62 */
 
250
        "fx_21d", /* random speech, voice clock 62 */
 
251
        "fx_21e", /* random speech, voice clock 62 */
 
252
        "fx_21f", /* random speech, voice clock 62 */
 
253
        "fx_21g", /* random speech, voice clock 62 */
 
254
        "fx_21h", /* random speech, voice clock 62 */
 
255
        "fx_22", /* EH2 with decreasing voice clock */
 
256
        "fx_23", /* O1 with varying voice clock */
 
257
        "fx_28",
 
258
        "fx_36",
 
259
        "knocker",
 
260
        0       /* end of array */
 
261
};
 
262
 
 
263
static const samples_interface reactor_samples_interface =
 
264
{
 
265
        1,      /* one channel */
 
266
        reactor_sample_names
 
267
};
 
268
 
 
269
static const samples_interface qbert_samples_interface =
 
270
{
 
271
        1,      /* one channel */
 
272
        qbert_sample_names
 
273
};
 
274
 
 
275
MACHINE_CONFIG_FRAGMENT( reactor_samples )
 
276
        MCFG_SAMPLES_ADD("samples", reactor_samples_interface)
 
277
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
 
278
MACHINE_CONFIG_END
 
279
 
 
280
MACHINE_CONFIG_FRAGMENT( qbert_samples )
 
281
        MCFG_SAMPLES_ADD("samples", qbert_samples_interface)
 
282
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
 
283
MACHINE_CONFIG_END
 
284
 
 
285
#endif
 
286
 
 
287
 
 
288
 
 
289
//**************************************************************************
 
290
//  REV 1 SOUND BOARD: 6502 + DAC
 
291
//**************************************************************************
 
292
 
 
293
//-------------------------------------------------
 
294
//  gottlieb_sound_r1_device - constructors
 
295
//-------------------------------------------------
 
296
 
 
297
gottlieb_sound_r1_device::gottlieb_sound_r1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
 
298
        : device_t(mconfig, GOTTLIEB_SOUND_REV1, "Gottlieb Sound rev. 1", "gotsndr1", tag, owner, clock),
 
299
          device_mixer_interface(mconfig, *this),
 
300
          m_audiocpu(*this, "audiocpu"),
 
301
          m_riot(*this, "riot"),
 
302
          m_dac(*this, "dac"),
 
303
          m_votrax(*this, "votrax"),
 
304
          m_populate_votrax(false),
 
305
          m_last_speech_clock(0)
 
306
#if USE_FAKE_VOTRAX
 
307
          , m_samples(*this, ":samples"),
 
308
          m_score_sample(0),
 
309
          m_random_offset(0),
 
310
          m_votrax_queuepos(0)
 
311
#endif
 
312
{
 
313
}
 
314
 
 
315
gottlieb_sound_r1_device::gottlieb_sound_r1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, bool populate_votrax)
 
316
        : device_t(mconfig, GOTTLIEB_SOUND_REV1, "Gottlieb Sound rev. 1", "gotsndr1", tag, owner, clock),
 
317
          device_mixer_interface(mconfig, *this),
 
318
          m_audiocpu(*this, "audiocpu"),
 
319
          m_riot(*this, "riot"),
 
320
          m_dac(*this, "dac"),
 
321
          m_votrax(*this, "votrax"),
 
322
          m_populate_votrax(populate_votrax),
 
323
          m_last_speech_clock(0)
 
324
#if USE_FAKE_VOTRAX
 
325
          , m_samples(*this, ":samples"),
 
326
          m_score_sample(0),
 
327
          m_random_offset(0),
 
328
          m_votrax_queuepos(0)
 
329
#endif
 
330
{
 
331
}
 
332
 
 
333
 
 
334
//-------------------------------------------------
 
335
//  write - handle an external command write
 
336
//-------------------------------------------------
 
337
 
 
338
WRITE8_MEMBER( gottlieb_sound_r1_device::write )
 
339
{
 
340
        // write the command data to the low 6 bits, and the trigger to the upper bit
 
341
        UINT8 pa7 = (data & 0x0f) != 0xf;
 
342
        UINT8 pa0_5 = ~data & 0x3f;
 
343
        m_riot->porta_in_set(pa0_5 | (pa7 << 7), 0xbf);
 
344
 
 
345
#if USE_FAKE_VOTRAX
 
346
        if (pa7 && m_samples != NULL)
 
347
                trigger_sample(pa0_5);
 
348
#endif
 
349
}
 
350
 
 
351
 
 
352
//-------------------------------------------------
 
353
//  snd_interrupt - signal a sound interrupt
 
354
//-------------------------------------------------
 
355
 
 
356
WRITE_LINE_MEMBER( gottlieb_sound_r1_device::snd_interrupt )
 
357
{
 
358
        m_audiocpu->set_input_line(M6502_IRQ_LINE, state);
 
359
}
 
360
 
 
361
 
 
362
//-------------------------------------------------
 
363
//  r6532_portb_w - handle writes to the RIOT's
 
364
//  port B
 
365
//-------------------------------------------------
 
366
 
 
367
WRITE8_MEMBER( gottlieb_sound_r1_device::r6532_portb_w )
 
368
{
 
369
        // unsure if this is ever used, but the NMI is connected to the RIOT's PB7
 
370
        m_audiocpu->set_input_line(INPUT_LINE_NMI, (data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
 
371
}
 
372
 
 
373
 
 
374
//-------------------------------------------------
 
375
//  votrax_data_w - write data to the Votrax SC-01
 
376
//  speech chip
 
377
//-------------------------------------------------
 
378
 
 
379
WRITE8_MEMBER( gottlieb_sound_r1_device::votrax_data_w )
 
380
{
 
381
        if (m_votrax != NULL)
 
382
        {
 
383
                m_votrax->inflection_w(space, offset, data >> 6);
 
384
                m_votrax->write(space, offset, ~data & 0x3f);
 
385
        }
 
386
 
 
387
#if USE_FAKE_VOTRAX
 
388
        fake_votrax_data_w(data);
 
389
#endif
 
390
}
 
391
 
 
392
 
 
393
//-------------------------------------------------
 
394
//  speech_clock_dac_w - modify the clock driving
 
395
//  the Votrax SC-01 speech chip
 
396
//-------------------------------------------------
 
397
 
 
398
WRITE8_MEMBER( gottlieb_sound_r1_device::speech_clock_dac_w )
 
399
{
 
400
        if (m_votrax != NULL)
 
401
        {
 
402
                // nominal clock is 0xa0
 
403
                if (data != m_last_speech_clock)
 
404
                {
 
405
                        mame_printf_debug("clock = %02X\n", data);
 
406
 
 
407
                        // totally random guesswork; would like to get real measurements on a board
 
408
                        if (m_votrax != NULL)
 
409
                                m_votrax->set_unscaled_clock(600000 + (data - 0xa0) * 10000);
 
410
                        m_last_speech_clock = data;
 
411
                }
 
412
        }
 
413
}
 
414
 
 
415
 
 
416
//-------------------------------------------------
 
417
//  votrax_request - map the VOTRAX SC-01 request
 
418
//  line to the NMI pin on the sound chip
 
419
//-------------------------------------------------
 
420
 
 
421
WRITE_LINE_MEMBER( gottlieb_sound_r1_device::votrax_request )
 
422
{
 
423
        m_audiocpu->set_input_line(INPUT_LINE_NMI, state);
 
424
}
 
425
 
 
426
 
 
427
//-------------------------------------------------
 
428
//  RIOT interface
 
429
//-------------------------------------------------
 
430
 
 
431
static const riot6532_interface gottlieb_riot6532_intf =
 
432
{
 
433
        DEVCB_NULL,
 
434
        DEVCB_INPUT_PORT("SB1"),
 
435
        DEVCB_NULL,
 
436
        DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, gottlieb_sound_r1_device, r6532_portb_w),
 
437
        DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, gottlieb_sound_r1_device, snd_interrupt)
 
438
};
 
439
 
 
440
 
 
441
//-------------------------------------------------
 
442
//  VOTRAX interface
 
443
//-------------------------------------------------
 
444
 
 
445
static const votrax_sc01_interface gottlieb_votrax_interface =
 
446
{
 
447
        DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, gottlieb_sound_r1_device, votrax_request)
 
448
};
 
449
 
 
450
 
 
451
//-------------------------------------------------
 
452
//  audio CPU map
 
453
//-------------------------------------------------
 
454
 
 
455
static ADDRESS_MAP_START( gottlieb_sound_r1_map, AS_PROGRAM, 8, gottlieb_sound_r1_device )
 
456
        // A15 not decoded except in expansion socket
303
457
        ADDRESS_MAP_GLOBAL_MASK(0x7fff)
304
458
        AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0d80) AM_RAM
305
 
        AM_RANGE(0x0200, 0x021f) AM_MIRROR(0x0de0) AM_DEVREADWRITE("riot", riot6532_r, riot6532_w)
306
 
        AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x0fff) AM_DEVWRITE("dac", dac_w)
307
 
        AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x0fff) AM_WRITE(vortrax_data_w)
 
459
        AM_RANGE(0x0200, 0x021f) AM_MIRROR(0x0de0) AM_DEVREADWRITE("riot", riot6532_device, read, write)
 
460
        AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x0fff) AM_DEVWRITE_LEGACY("dac", dac_w)
 
461
        AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x0fff) AM_WRITE(votrax_data_w)
308
462
        AM_RANGE(0x3000, 0x3000) AM_MIRROR(0x0fff) AM_WRITE(speech_clock_dac_w)
309
463
        AM_RANGE(0x6000, 0x7fff) AM_ROM
310
464
ADDRESS_MAP_END
311
465
 
312
466
 
313
 
 
314
 
/*************************************
315
 
 *
316
 
 *  Rev. 1 machine driver
317
 
 *
318
 
 *************************************/
319
 
 
320
 
MACHINE_CONFIG_FRAGMENT( gottlieb_soundrev1 )
321
 
        MCFG_SOUND_START(gottlieb1)
322
 
 
 
467
//-------------------------------------------------
 
468
//  machine configuration
 
469
//-------------------------------------------------
 
470
 
 
471
MACHINE_CONFIG_FRAGMENT( gottlieb_sound_r1 )
 
472
        // audio CPU
 
473
        MCFG_CPU_ADD("audiocpu", M6502, SOUND1_CLOCK/4) // the board can be set to /2 as well
 
474
        MCFG_CPU_PROGRAM_MAP(gottlieb_sound_r1_map)
 
475
 
 
476
        // I/O configuration
323
477
        MCFG_RIOT6532_ADD("riot", SOUND1_CLOCK/4, gottlieb_riot6532_intf)
324
478
 
325
 
        MCFG_CPU_ADD("audiocpu", M6502, SOUND1_CLOCK/4) /* the board can be set to /2 as well */
326
 
        MCFG_CPU_PROGRAM_MAP(gottlieb_sound1_map)
327
 
 
328
 
        /* sound hardware */
 
479
        // sound devices
329
480
        MCFG_SOUND_ADD("dac", DAC, 0)
330
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
331
 
MACHINE_CONFIG_END
332
 
 
333
 
 
334
 
 
335
 
/*************************************
336
 
 *
337
 
 *  Rev. 1 input ports
338
 
 *
339
 
 *************************************/
340
 
 
341
 
INPUT_PORTS_START( gottlieb1_sound )
 
481
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.50)
 
482
MACHINE_CONFIG_END
 
483
 
 
484
MACHINE_CONFIG_FRAGMENT( gottlieb_sound_r1_with_votrax )
 
485
        MCFG_FRAGMENT_ADD(gottlieb_sound_r1)
 
486
 
 
487
        // add the VOTRAX
 
488
        MCFG_VOTRAX_SC01_ADD("votrax", 720000, gottlieb_votrax_interface)
 
489
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.50)
 
490
MACHINE_CONFIG_END
 
491
 
 
492
 
 
493
//-------------------------------------------------
 
494
//  input ports
 
495
//-------------------------------------------------
 
496
 
 
497
INPUT_PORTS_START( gottlieb_sound_r1 )
342
498
        PORT_START("SB1")
343
499
        PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SB1:7" )
344
500
        PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SB1:6" )
349
505
        PORT_DIPNAME( 0x40, 0x40, "Sound Test" )                        PORT_DIPLOCATION("SB1:2")
350
506
        PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
351
507
        PORT_DIPSETTING(    0x00, DEF_STR( On ) )
352
 
        PORT_BIT( 0x80, 0x80, IPT_UNKNOWN )     /* To U3-6 on QBert */
353
 
INPUT_PORTS_END
354
 
 
355
 
 
356
 
 
357
 
/*************************************
358
 
 *
359
 
 *  Rev. 2 communication handlers
360
 
 *
361
 
 *************************************/
362
 
 
363
 
static void gottlieb2_sh_w(address_space *space, UINT8 data)
364
 
{
365
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
366
 
        /* when data is not 0xff, the transparent latch at A3 allows it to pass through unmolested */
 
508
        PORT_BIT( 0x80, 0x80, IPT_SPECIAL )
 
509
INPUT_PORTS_END
 
510
 
 
511
INPUT_PORTS_START( gottlieb_sound_r1_with_votrax )
 
512
        PORT_INCLUDE(gottlieb_sound_r1)
 
513
        PORT_MODIFY("SB1")
 
514
        PORT_BIT( 0x80, 0x80, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("votrax", votrax_sc01_device, request)
 
515
INPUT_PORTS_END
 
516
 
 
517
 
 
518
//-------------------------------------------------
 
519
//  device_mconfig_additions - return a pointer to
 
520
//  the device's machine fragment
 
521
//-------------------------------------------------
 
522
 
 
523
machine_config_constructor gottlieb_sound_r1_device::device_mconfig_additions() const
 
524
{
 
525
        return MACHINE_CONFIG_NAME( gottlieb_sound_r1 );
 
526
}
 
527
 
 
528
 
 
529
//-------------------------------------------------
 
530
//  device_input_ports - return a pointer to
 
531
//  the device's I/O ports
 
532
//-------------------------------------------------
 
533
 
 
534
ioport_constructor gottlieb_sound_r1_device::device_input_ports() const
 
535
{
 
536
        return INPUT_PORTS_NAME( gottlieb_sound_r1 );
 
537
}
 
538
 
 
539
 
 
540
//-------------------------------------------------
 
541
//  device_start - device-specific startup
 
542
//-------------------------------------------------
 
543
 
 
544
void gottlieb_sound_r1_device::device_start()
 
545
{
 
546
}
 
547
 
 
548
 
 
549
 
 
550
//**************************************************************************
 
551
//  REV 1 SOUND BOARD WITH VOTRAX
 
552
//**************************************************************************
 
553
 
 
554
//-------------------------------------------------
 
555
//  gottlieb_sound_r1_with_votrax_device -
 
556
//  constructor
 
557
//-------------------------------------------------
 
558
 
 
559
gottlieb_sound_r1_with_votrax_device::gottlieb_sound_r1_with_votrax_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
 
560
        : gottlieb_sound_r1_device(mconfig, tag, owner, clock, true)
 
561
{
 
562
}
 
563
 
 
564
 
 
565
//-------------------------------------------------
 
566
//  device_mconfig_additions - return a pointer to
 
567
//  the device's machine fragment
 
568
//-------------------------------------------------
 
569
 
 
570
machine_config_constructor gottlieb_sound_r1_with_votrax_device::device_mconfig_additions() const
 
571
{
 
572
        return MACHINE_CONFIG_NAME( gottlieb_sound_r1_with_votrax );
 
573
}
 
574
 
 
575
 
 
576
//-------------------------------------------------
 
577
//  device_input_ports - return a pointer to
 
578
//  the device's I/O ports
 
579
//-------------------------------------------------
 
580
 
 
581
ioport_constructor gottlieb_sound_r1_with_votrax_device::device_input_ports() const
 
582
{
 
583
        return INPUT_PORTS_NAME( gottlieb_sound_r1_with_votrax );
 
584
}
 
585
 
 
586
 
 
587
 
 
588
//**************************************************************************
 
589
//  REV 2 SOUND BOARD: 6502 + 2 x DAC + 2 x AY-8913
 
590
//**************************************************************************
 
591
 
 
592
//-------------------------------------------------
 
593
//  gottlieb_sound_r2_device - constructor
 
594
//-------------------------------------------------
 
595
 
 
596
gottlieb_sound_r2_device::gottlieb_sound_r2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
 
597
        : device_t(mconfig, GOTTLIEB_SOUND_REV2, "Gottlieb Sound rev. 2", "gotsndr2", tag, owner, clock),
 
598
          device_mixer_interface(mconfig, *this),
 
599
          m_audiocpu(*this, "audiocpu"),
 
600
          m_speechcpu(*this, "speechcpu"),
 
601
          m_dac(*this, "dac"),
 
602
          m_ay1(*this, "ay1"),
 
603
          m_ay2(*this, "ay2"),
 
604
          m_sp0250(*this, "spsnd"),
 
605
          m_cobram3_mod(false),
 
606
          m_nmi_timer(NULL),
 
607
          m_nmi_state(0),
 
608
          m_audiocpu_latch(0),
 
609
          m_speechcpu_latch(0),
 
610
          m_speech_control(0),
 
611
          m_last_command(0),
 
612
          m_psg_latch(0),
 
613
          m_psg_data_latch(0),
 
614
          m_sp0250_latch(0)
 
615
{
 
616
}
 
617
 
 
618
 
 
619
//-------------------------------------------------
 
620
//  static_enable_cobram3_mods - enable changes
 
621
//  for cobram3
 
622
//-------------------------------------------------
 
623
 
 
624
void gottlieb_sound_r2_device::static_enable_cobram3_mods(device_t &device)
 
625
{
 
626
        downcast<gottlieb_sound_r2_device &>(device).m_cobram3_mod = true;
 
627
}
 
628
 
 
629
 
 
630
//-------------------------------------------------
 
631
//  write - handle an external command write
 
632
//-------------------------------------------------
 
633
 
 
634
WRITE8_MEMBER( gottlieb_sound_r2_device::write )
 
635
{
 
636
        // when data is not 0xff, the transparent latch at A3 allows it to pass through unmolested
367
637
        if (data != 0xff)
368
638
        {
369
 
                /* each CPU has its own latch */
370
 
                soundlatch_w(space, 0, data);
371
 
                soundlatch2_w(space, 0, data);
372
 
 
373
 
                /* if the previous data was 0xff, clock an IRQ on each */
374
 
                if (state->m_last_command == 0xff)
375
 
                {
376
 
                        cputag_set_input_line(space->machine(), "audiocpu", M6502_IRQ_LINE, ASSERT_LINE);
377
 
                        cputag_set_input_line(space->machine(), "speech", M6502_IRQ_LINE, ASSERT_LINE);
378
 
                }
379
 
        }
380
 
        state->m_last_command = data;
381
 
}
382
 
 
383
 
 
384
 
static READ8_HANDLER( speech_data_r )
385
 
{
386
 
        cputag_set_input_line(space->machine(), "speech", M6502_IRQ_LINE, CLEAR_LINE);
387
 
        return soundlatch_r(space, offset);
388
 
}
389
 
 
390
 
 
391
 
static READ8_HANDLER( audio_data_r )
392
 
{
393
 
        cputag_set_input_line(space->machine(), "audiocpu", M6502_IRQ_LINE, CLEAR_LINE);
394
 
        return soundlatch2_r(space, offset);
395
 
}
396
 
 
397
 
 
398
 
static WRITE8_HANDLER( signal_audio_nmi_w )
399
 
{
400
 
        cputag_set_input_line(space->machine(), "audiocpu", INPUT_LINE_NMI, ASSERT_LINE);
401
 
        cputag_set_input_line(space->machine(), "audiocpu", INPUT_LINE_NMI, CLEAR_LINE);
402
 
}
403
 
 
404
 
 
405
 
 
406
 
/*************************************
407
 
 *
408
 
 *  Rev. 2 NMI timer
409
 
 *
410
 
 *************************************/
411
 
 
412
 
INLINE void nmi_timer_adjust(running_machine &machine)
413
 
{
414
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
415
 
        /* adjust timer to go off in the future based on the current rate */
416
 
        state->m_nmi_timer->adjust(attotime::from_hz(SOUND2_CLOCK/16) * (256 * (256 - state->m_nmi_rate)));
417
 
}
418
 
 
419
 
 
420
 
INLINE void nmi_state_update(running_machine &machine)
421
 
{
422
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
423
 
        /* update the NMI line state based on the enable and state */
424
 
        cputag_set_input_line(machine, "speech", INPUT_LINE_NMI, (state->m_nmi_state && (state->m_speech_control & 1)) ? ASSERT_LINE : CLEAR_LINE);
425
 
}
426
 
 
427
 
 
428
 
static TIMER_CALLBACK( nmi_clear )
429
 
{
430
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
431
 
        /* clear the NMI state and update it */
432
 
        state->m_nmi_state = 0;
433
 
        nmi_state_update(machine);
434
 
}
435
 
 
436
 
 
437
 
static TIMER_CALLBACK( nmi_callback )
438
 
{
439
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
440
 
        /* assert the NMI if it is not disabled */
441
 
        state->m_nmi_state = 1;
442
 
        nmi_state_update(machine);
443
 
 
444
 
        /* set a timer to turn it off again on hte next SOUND_CLOCK/16 */
445
 
        machine.scheduler().timer_set(attotime::from_hz(SOUND2_CLOCK/16), FUNC(nmi_clear));
446
 
 
447
 
        /* adjust the NMI timer for the next time */
448
 
        nmi_timer_adjust(machine);
449
 
}
450
 
 
451
 
 
452
 
static WRITE8_HANDLER( nmi_rate_w )
453
 
{
454
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
455
 
        /* the new rate is picked up when the previous timer expires */
456
 
        state->m_nmi_rate = data;
457
 
}
458
 
 
459
 
 
460
 
 
461
 
/*************************************
462
 
 *
463
 
 *  Rev. 2 sound chip access
464
 
 *
465
 
 *************************************/
466
 
 
467
 
static CUSTOM_INPUT( speech_drq_custom_r )
468
 
{
469
 
        return sp0250_drq_r(field.machine().device("spsnd"));
470
 
}
471
 
 
472
 
 
473
 
static WRITE8_DEVICE_HANDLER( gottlieb_dac_w )
474
 
{
475
 
        gottlieb_state *state = device->machine().driver_data<gottlieb_state>();
476
 
        /* dual DAC; the first DAC serves as the reference voltage for the
477
 
       second, effectively scaling the output */
478
 
        state->m_dac_data[offset] = data;
479
 
        dac_data_16_w(device, state->m_dac_data[0] * state->m_dac_data[1]);
480
 
}
481
 
 
482
 
 
483
 
static WRITE8_HANDLER( speech_control_w )
484
 
{
485
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
486
 
        UINT8 previous = state->m_speech_control;
487
 
        state->m_speech_control = data;
488
 
 
489
 
        /* bit 0 enables/disables the NMI line */
490
 
        nmi_state_update(space->machine());
491
 
 
492
 
        /* bit 1 controls a LED on the sound board */
493
 
 
494
 
        /* bit 2 goes to 8913 BDIR pin */
495
 
        if ((previous & 0x04) != 0 && (data & 0x04) == 0)
496
 
        {
497
 
                /* bit 3 selects which of the two 8913 to enable */
498
 
                /* bit 4 goes to the 8913 BC1 pin */
499
 
                device_t *ay = space->machine().device((data & 0x08) ? "ay1" : "ay2");
500
 
                ay8910_data_address_w(ay, data >> 4, *state->m_psg_latch);
501
 
        }
502
 
 
503
 
        /* bit 5 goes to the speech chip DIRECT DATA TEST pin */
504
 
 
505
 
        /* bit 6 = speech chip DATA PRESENT pin; high then low to make the chip read data */
506
 
        if ((previous & 0x40) == 0 && (data & 0x40) != 0)
507
 
        {
508
 
                device_t *sp = space->machine().device("spsnd");
509
 
                sp0250_w(sp, 0, *state->m_sp0250_latch);
510
 
        }
511
 
 
512
 
        /* bit 7 goes to the speech chip RESET pin */
513
 
        if ((previous ^ data) & 0x80)
514
 
                space->machine().device("spsnd")->reset();
515
 
}
516
 
 
517
 
static WRITE8_HANDLER( cobram3_speech_control_w )
518
 
{
519
 
        gottlieb_state *state = space->machine().driver_data<gottlieb_state>();
520
 
        UINT8 previous = state->m_speech_control;
521
 
        state->m_speech_control = data;
522
 
 
523
 
        /* bit 0 enables/disables the NMI line */
524
 
        nmi_state_update(space->machine());
525
 
 
526
 
        /* bit 1 controls a LED on the sound board */
527
 
 
528
 
        if ( data & 0x10 )
529
 
        {
530
 
                state->m_psg_data_latch = *state->m_psg_latch;
 
639
                // latch data on a timer
 
640
                synchronize(TID_SOUND_LATCH_WRITE, data);
 
641
 
 
642
                // if the previous data was 0xff, clock an IRQ on each
 
643
                if (m_last_command == 0xff)
 
644
                {
 
645
                        m_audiocpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
 
646
                        m_speechcpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
 
647
                }
 
648
        }
 
649
        m_last_command = data;
 
650
}
 
651
 
 
652
 
 
653
//-------------------------------------------------
 
654
//  nmi_timer_adjust - adjust the NMI timer to
 
655
//  fire based on its configured rate
 
656
//-------------------------------------------------
 
657
 
 
658
inline void gottlieb_sound_r2_device::nmi_timer_adjust()
 
659
{
 
660
        // adjust timer to go off in the future based on the current rate
 
661
        m_nmi_timer->adjust(attotime::from_hz(SOUND2_CLOCK/16) * (256 * (256 - m_nmi_rate)));
 
662
}
 
663
 
 
664
 
 
665
//-------------------------------------------------
 
666
//  nmi_state_update - update the NMI state based
 
667
//  on the timer firing and the enable control
 
668
//-------------------------------------------------
 
669
 
 
670
inline void gottlieb_sound_r2_device::nmi_state_update()
 
671
{
 
672
        // update the NMI line state based on the enable and state
 
673
        m_speechcpu->set_input_line(INPUT_LINE_NMI, (m_nmi_state && (m_speech_control & 1)) ? ASSERT_LINE : CLEAR_LINE);
 
674
}
 
675
 
 
676
 
 
677
//-------------------------------------------------
 
678
//  speech_data_r - read the input command latch
 
679
//  from the audio CPU
 
680
//-------------------------------------------------
 
681
 
 
682
READ8_MEMBER( gottlieb_sound_r2_device::audio_data_r )
 
683
{
 
684
        m_audiocpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
 
685
        return m_audiocpu_latch;
 
686
}
 
687
 
 
688
 
 
689
//-------------------------------------------------
 
690
//  speech_data_r - read the input command latch
 
691
//  from the speech CPU
 
692
//-------------------------------------------------
 
693
 
 
694
READ8_MEMBER( gottlieb_sound_r2_device::speech_data_r )
 
695
{
 
696
        m_speechcpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
 
697
        return m_speechcpu_latch;
 
698
}
 
699
 
 
700
 
 
701
//-------------------------------------------------
 
702
//  signal_audio_nmi_w - signal an NMI from the
 
703
//  speech CPU to the audio CPU
 
704
//-------------------------------------------------
 
705
 
 
706
WRITE8_MEMBER( gottlieb_sound_r2_device::signal_audio_nmi_w )
 
707
{
 
708
        m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
 
709
        m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
 
710
}
 
711
 
 
712
 
 
713
//-------------------------------------------------
 
714
//  nmi_rate_w - adjust the NMI rate on the speech
 
715
//  CPU
 
716
//-------------------------------------------------
 
717
 
 
718
WRITE8_MEMBER( gottlieb_sound_r2_device::nmi_rate_w )
 
719
{
 
720
        // the new rate is picked up when the previous timer expires
 
721
        m_nmi_rate = data;
 
722
}
 
723
 
 
724
 
 
725
//-------------------------------------------------
 
726
//  speech_drq_custom_r - return the SP0250
 
727
//  request line as an input port bit
 
728
//-------------------------------------------------
 
729
 
 
730
CUSTOM_INPUT_MEMBER( gottlieb_sound_r2_device::speech_drq_custom_r )
 
731
{
 
732
        return sp0250_drq_r(m_sp0250);
 
733
}
 
734
 
 
735
 
 
736
//-------------------------------------------------
 
737
//  dac_w - write to one of the two DACs on the
 
738
//  board
 
739
//-------------------------------------------------
 
740
 
 
741
WRITE8_MEMBER( gottlieb_sound_r2_device::dac_w )
 
742
{
 
743
        // dual DAC; the first DAC serves as the reference voltage for the
 
744
    // second, effectively scaling the output
 
745
        m_dac_data[offset] = data;
 
746
        dac_data_16_w(m_dac, m_dac_data[0] * m_dac_data[1]);
 
747
}
 
748
 
 
749
 
 
750
//-------------------------------------------------
 
751
//  speech_control_w - primary audio control
 
752
//  register on the speech board
 
753
//-------------------------------------------------
 
754
 
 
755
WRITE8_MEMBER( gottlieb_sound_r2_device::speech_control_w )
 
756
{
 
757
        UINT8 previous = m_speech_control;
 
758
        m_speech_control = data;
 
759
 
 
760
        // bit 0 enables/disables the NMI line
 
761
        nmi_state_update();
 
762
 
 
763
        // bit 1 controls a LED on the sound board
 
764
 
 
765
        // bits 2-4 control the AY-8913, but act differently between the
 
766
        // standard sound board and the modified Cobra Command board
 
767
        if (!m_cobram3_mod)
 
768
        {
 
769
                // bit 2 goes to 8913 BDIR pin
 
770
                if ((previous & 0x04) != 0 && (data & 0x04) == 0)
 
771
                {
 
772
                        // bit 3 selects which of the two 8913 to enable
 
773
                        // bit 4 goes to the 8913 BC1 pin
 
774
                        if ((data & 0x08) != 0)
 
775
                                ay8910_data_address_w(m_ay1, data >> 4, m_psg_latch);
 
776
                        else
 
777
                                ay8910_data_address_w(m_ay2, data >> 4, m_psg_latch);
 
778
                }
531
779
        }
532
780
        else
533
781
        {
534
 
                device_t *ay = space->machine().device((data & 0x08) ? "ay1" : "ay2");
535
 
                ay8910_address_w(ay, 0, *state->m_psg_latch);
536
 
                ay8910_data_w(ay, 0, state->m_psg_data_latch);
 
782
                if ( data & 0x10 )
 
783
                {
 
784
                        m_psg_data_latch = m_psg_latch;
 
785
                }
 
786
                else
 
787
                {
 
788
                        ay8913_device *ay = (data & 0x08) ? m_ay1 : m_ay2;
 
789
                        ay8910_address_w(ay, 0, m_psg_latch);
 
790
                        ay8910_data_w(ay, 0, m_psg_data_latch);
 
791
                }
537
792
        }
538
 
        /* bit 5 goes to the speech chip DIRECT DATA TEST pin */
539
 
 
540
 
        /* bit 6 = speech chip DATA PRESENT pin; high then low to make the chip read data */
 
793
 
 
794
        // bit 5 goes to the speech chip DIRECT DATA TEST pin
 
795
 
 
796
        // bit 6 = speech chip DATA PRESENT pin; high then low to make the chip read data
541
797
        if ((previous & 0x40) == 0 && (data & 0x40) != 0)
542
 
        {
543
 
                device_t *sp = space->machine().device("spsnd");
544
 
                sp0250_w(sp, 0, *state->m_sp0250_latch);
545
 
        }
 
798
                sp0250_w(m_sp0250, 0, m_sp0250_latch);
546
799
 
547
 
        /* bit 7 goes to the speech chip RESET pin */
 
800
        // bit 7 goes to the speech chip RESET pin
548
801
        if ((previous ^ data) & 0x80)
549
 
                space->machine().device("spsnd")->reset();
550
 
}
551
 
 
552
 
 
553
 
/*************************************
554
 
 *
555
 
 *  Rev. 2 initialization
556
 
 *
557
 
 *************************************/
558
 
 
559
 
static SOUND_START( gottlieb2 )
560
 
{
561
 
        gottlieb_state *state = machine.driver_data<gottlieb_state>();
562
 
        /* set up the NMI timer */
563
 
        state->m_nmi_timer = machine.scheduler().timer_alloc(FUNC(nmi_callback));
564
 
        state->m_nmi_rate = 0;
565
 
        nmi_timer_adjust(machine);
566
 
 
567
 
        state->m_dac_data[0] = state->m_dac_data[1] = 0xff;
568
 
 
569
 
        /* register for save states */
570
 
        state_save_register_global(machine, state->m_nmi_rate);
571
 
        state_save_register_global(machine, state->m_nmi_state);
572
 
        state_save_register_global(machine, state->m_speech_control);
573
 
        state_save_register_global(machine, state->m_last_command);
574
 
}
575
 
 
576
 
 
577
 
 
578
 
/*************************************
579
 
 *
580
 
 *  Rev. 2 address map
581
 
 *
582
 
 *************************************/
583
 
 
584
 
static ADDRESS_MAP_START( gottlieb_speech2_map, AS_PROGRAM, 8 )
585
 
        AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x1c00) AM_RAM
586
 
        AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x1fff) AM_WRITEONLY AM_BASE_MEMBER(gottlieb_state, m_sp0250_latch)
587
 
        AM_RANGE(0x4000, 0x4000) AM_MIRROR(0x1fff) AM_WRITE(speech_control_w)
588
 
        AM_RANGE(0x6000, 0x6000) AM_MIRROR(0x1fff) AM_READ_PORT("SB2")
589
 
        AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x1fff) AM_WRITEONLY AM_BASE_MEMBER(gottlieb_state, m_psg_latch)
590
 
        AM_RANGE(0xa000, 0xa000) AM_MIRROR(0x07ff) AM_WRITE(nmi_rate_w)
591
 
        AM_RANGE(0xa800, 0xa800) AM_MIRROR(0x07ff) AM_READ(speech_data_r)
592
 
        AM_RANGE(0xb000, 0xb000) AM_MIRROR(0x07ff) AM_WRITE(signal_audio_nmi_w)
593
 
        AM_RANGE(0xc000, 0xffff) AM_ROM
594
 
ADDRESS_MAP_END
595
 
 
596
 
 
597
 
static ADDRESS_MAP_START( gottlieb_cobram3_speech2_map, AS_PROGRAM, 8 )
598
 
        AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x1c00) AM_RAM
599
 
        AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x1fff) AM_WRITEONLY AM_BASE_MEMBER(gottlieb_state, m_sp0250_latch)
600
 
        AM_RANGE(0x4000, 0x4000) AM_MIRROR(0x1fff) AM_WRITE(cobram3_speech_control_w)
601
 
        AM_RANGE(0x6000, 0x6000) AM_MIRROR(0x1fff) AM_READ_PORT("SB2")
602
 
        AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x1fff) AM_WRITEONLY AM_BASE_MEMBER(gottlieb_state, m_psg_latch)
603
 
        AM_RANGE(0xa000, 0xa000) AM_MIRROR(0x07ff) AM_WRITE(nmi_rate_w)
604
 
        AM_RANGE(0xa800, 0xa800) AM_MIRROR(0x07ff) AM_READ(speech_data_r)
605
 
        AM_RANGE(0xb000, 0xb000) AM_MIRROR(0x07ff) AM_WRITE(signal_audio_nmi_w)
606
 
        AM_RANGE(0xc000, 0xffff) AM_ROM
607
 
ADDRESS_MAP_END
608
 
 
609
 
static ADDRESS_MAP_START( gottlieb_audio2_map, AS_PROGRAM, 8 )
 
802
                m_sp0250->reset();
 
803
}
 
804
 
 
805
 
 
806
//-------------------------------------------------
 
807
//  psg_latch_w - store an 8-bit value in the PSG
 
808
//  latch register
 
809
//-------------------------------------------------
 
810
 
 
811
WRITE8_MEMBER( gottlieb_sound_r2_device::psg_latch_w )
 
812
{
 
813
        m_psg_latch = data;
 
814
}
 
815
 
 
816
 
 
817
//-------------------------------------------------
 
818
//  psg_latch_w - store an 8-bit value in the
 
819
//  SP0250 latch register
 
820
//-------------------------------------------------
 
821
 
 
822
WRITE8_MEMBER( gottlieb_sound_r2_device::sp0250_latch_w )
 
823
{
 
824
        m_sp0250_latch = data;
 
825
}
 
826
 
 
827
 
 
828
//-------------------------------------------------
 
829
//  sound CPU address map
 
830
//-------------------------------------------------
 
831
 
 
832
static ADDRESS_MAP_START( gottlieb_sound_r2_map, AS_PROGRAM, 8, gottlieb_sound_r2_device )
610
833
        AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x3c00) AM_RAM
611
 
        AM_RANGE(0x4000, 0x4001) AM_MIRROR(0x3ffe) AM_DEVWRITE("dac1", gottlieb_dac_w) AM_BASE_MEMBER(gottlieb_state, m_dac_data)
 
834
        AM_RANGE(0x4000, 0x4001) AM_MIRROR(0x3ffe) AM_WRITE(dac_w)
612
835
        AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x3fff) AM_READ(audio_data_r)
613
836
        AM_RANGE(0xe000, 0xffff) AM_MIRROR(0x2000) AM_ROM
614
837
ADDRESS_MAP_END
615
838
 
616
839
 
617
 
 
618
 
/*************************************
619
 
 *
620
 
 *  Rev. 2 machine driver
621
 
 *
622
 
 *************************************/
623
 
 
624
 
MACHINE_CONFIG_FRAGMENT( gottlieb_soundrev2 )
625
 
        /* audio CPUs */
626
 
        MCFG_CPU_ADD("audiocpu", M6502, SOUND2_CLOCK/4)
627
 
        MCFG_CPU_PROGRAM_MAP(gottlieb_audio2_map)
628
 
 
629
 
        MCFG_CPU_ADD("speech", M6502, SOUND2_CLOCK/4)
630
 
        MCFG_CPU_PROGRAM_MAP(gottlieb_speech2_map)
631
 
 
632
 
        /* sound hardware */
633
 
        MCFG_SOUND_START( gottlieb2 )
634
 
 
635
 
        MCFG_SOUND_ADD("dac1", DAC, 0)
636
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
637
 
 
638
 
        MCFG_SOUND_ADD("dac2", DAC, 0)
639
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
640
 
 
641
 
        MCFG_SOUND_ADD("ay1", AY8913, SOUND2_CLOCK/2)
642
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
643
 
 
644
 
        MCFG_SOUND_ADD("ay2", AY8913, SOUND2_CLOCK/2)
645
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
646
 
 
647
 
        MCFG_SOUND_ADD("spsnd", SP0250, SOUND2_SPEECH_CLOCK)
648
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
649
 
MACHINE_CONFIG_END
650
 
 
651
 
MACHINE_CONFIG_FRAGMENT( gottlieb_cobram3_soundrev2 )
652
 
        /* audio CPUs */
653
 
        MCFG_CPU_ADD("audiocpu", M6502, SOUND2_CLOCK/4)
654
 
        MCFG_DEVICE_DISABLE()
655
 
        MCFG_CPU_PROGRAM_MAP(gottlieb_audio2_map)
656
 
 
657
 
        MCFG_CPU_ADD("speech", M6502, SOUND2_CLOCK/4)
658
 
        MCFG_CPU_PROGRAM_MAP(gottlieb_cobram3_speech2_map)
659
 
 
660
 
        /* sound hardware */
661
 
        MCFG_SOUND_START( gottlieb2 )
662
 
 
663
 
        MCFG_SOUND_ADD("dac1", DAC, 0)
664
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
665
 
 
666
 
        MCFG_SOUND_ADD("dac2", DAC, 0)
667
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.15)
668
 
 
669
 
        MCFG_SOUND_ADD("ay1", AY8913, SOUND2_CLOCK/2)
670
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
671
 
 
672
 
        MCFG_SOUND_ADD("ay2", AY8913, SOUND2_CLOCK/2)
673
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
674
 
 
675
 
        MCFG_SOUND_ADD("spsnd", SP0250, SOUND2_SPEECH_CLOCK)
676
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
677
 
MACHINE_CONFIG_END
678
 
 
679
 
 
680
 
/*************************************
681
 
 *
682
 
 *  Rev. 2 input ports
683
 
 *
684
 
 *************************************/
685
 
 
686
 
INPUT_PORTS_START( gottlieb2_sound )
 
840
//-------------------------------------------------
 
841
//  sppech CPU address map
 
842
//-------------------------------------------------
 
843
 
 
844
static ADDRESS_MAP_START( gottlieb_speech_r2_map, AS_PROGRAM, 8, gottlieb_sound_r2_device )
 
845
        AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x1c00) AM_RAM
 
846
        AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x1fff) AM_WRITE(sp0250_latch_w)
 
847
        AM_RANGE(0x4000, 0x4000) AM_MIRROR(0x1fff) AM_WRITE(speech_control_w)
 
848
        AM_RANGE(0x6000, 0x6000) AM_MIRROR(0x1fff) AM_READ_PORT("SB2")
 
849
        AM_RANGE(0x8000, 0x8000) AM_MIRROR(0x1fff) AM_WRITE(psg_latch_w)
 
850
        AM_RANGE(0xa000, 0xa000) AM_MIRROR(0x07ff) AM_WRITE(nmi_rate_w)
 
851
        AM_RANGE(0xa800, 0xa800) AM_MIRROR(0x07ff) AM_READ(speech_data_r)
 
852
        AM_RANGE(0xb000, 0xb000) AM_MIRROR(0x07ff) AM_WRITE(signal_audio_nmi_w)
 
853
        AM_RANGE(0xc000, 0xffff) AM_ROM
 
854
ADDRESS_MAP_END
 
855
 
 
856
 
 
857
//-------------------------------------------------
 
858
//  machine configuration
 
859
//-------------------------------------------------
 
860
 
 
861
MACHINE_CONFIG_FRAGMENT( gottlieb_sound_r2 )
 
862
        // audio CPUs
 
863
        MCFG_CPU_ADD("audiocpu", M6502, SOUND2_CLOCK/4)
 
864
        MCFG_CPU_PROGRAM_MAP(gottlieb_sound_r2_map)
 
865
 
 
866
        MCFG_CPU_ADD("speechcpu", M6502, SOUND2_CLOCK/4)
 
867
        MCFG_CPU_PROGRAM_MAP(gottlieb_speech_r2_map)
 
868
 
 
869
        // sound hardware
 
870
        MCFG_SOUND_ADD("dac", DAC, 0)
 
871
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.15)
 
872
 
 
873
        MCFG_SOUND_ADD("ay1", AY8913, SOUND2_CLOCK/2)
 
874
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.15)
 
875
 
 
876
        MCFG_SOUND_ADD("ay2", AY8913, SOUND2_CLOCK/2)
 
877
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.15)
 
878
 
 
879
        MCFG_SOUND_ADD("spsnd", SP0250, SOUND2_SPEECH_CLOCK)
 
880
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 1.0)
 
881
MACHINE_CONFIG_END
 
882
 
 
883
 
 
884
//-------------------------------------------------
 
885
//  input ports
 
886
//-------------------------------------------------
 
887
 
 
888
INPUT_PORTS_START( gottlieb_sound_r2 )
687
889
        PORT_START("SB2")
688
890
        PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SB2:1")
689
891
        PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SB2:2")
694
896
        PORT_DIPNAME( 0x40, 0x40, "Sound Test" )                        PORT_DIPLOCATION("SB2:7")
695
897
        PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
696
898
        PORT_DIPSETTING(    0x00, DEF_STR( On ) )
697
 
        PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(speech_drq_custom_r, NULL)
 
899
        PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, gottlieb_sound_r2_device, speech_drq_custom_r, NULL)
698
900
INPUT_PORTS_END
 
901
 
 
902
 
 
903
//-------------------------------------------------
 
904
//  device_mconfig_additions - return a pointer to
 
905
//  the device's machine fragment
 
906
//-------------------------------------------------
 
907
 
 
908
machine_config_constructor gottlieb_sound_r2_device::device_mconfig_additions() const
 
909
{
 
910
        return MACHINE_CONFIG_NAME( gottlieb_sound_r2 );
 
911
}
 
912
 
 
913
 
 
914
//-------------------------------------------------
 
915
//  device_input_ports - return a pointer to
 
916
//  the device's I/O ports
 
917
//-------------------------------------------------
 
918
 
 
919
ioport_constructor gottlieb_sound_r2_device::device_input_ports() const
 
920
{
 
921
        return INPUT_PORTS_NAME( gottlieb_sound_r2 );
 
922
}
 
923
 
 
924
 
 
925
//-------------------------------------------------
 
926
//  device_start - device-specific startup
 
927
//-------------------------------------------------
 
928
 
 
929
void gottlieb_sound_r2_device::device_start()
 
930
{
 
931
        // set up the NMI timer
 
932
        m_nmi_timer = timer_alloc(TID_NMI_GENERATE);
 
933
        m_nmi_rate = 0;
 
934
        nmi_timer_adjust();
 
935
 
 
936
        // reset the DACs
 
937
        m_dac_data[0] = m_dac_data[1] = 0xff;
 
938
 
 
939
        // disable the non-speech CPU for cobram3
 
940
        if (m_cobram3_mod)
 
941
                m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
 
942
 
 
943
        // register for save states
 
944
        save_item(NAME(m_nmi_rate));
 
945
        save_item(NAME(m_nmi_state));
 
946
        save_item(NAME(m_speech_control));
 
947
        save_item(NAME(m_last_command));
 
948
}
 
949
 
 
950
 
 
951
//-------------------------------------------------
 
952
//  device_timer - handle timer-based behaviors
 
953
//-------------------------------------------------
 
954
 
 
955
void gottlieb_sound_r2_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
 
956
{
 
957
        switch (id)
 
958
        {
 
959
                case TID_NMI_GENERATE:
 
960
                        // update state
 
961
                        m_nmi_state = 1;
 
962
                        nmi_state_update();
 
963
 
 
964
                        // set a timer to turn it off again on hte next SOUND_CLOCK/16
 
965
                        timer_set(attotime::from_hz(SOUND2_CLOCK/16), TID_NMI_CLEAR);
 
966
 
 
967
                        // adjust the NMI timer for the next time
 
968
                        nmi_timer_adjust();
 
969
                        break;
 
970
 
 
971
                case TID_NMI_CLEAR:
 
972
                        // update state
 
973
                        m_nmi_state = 0;
 
974
                        nmi_state_update();
 
975
                        break;
 
976
 
 
977
                case TID_SOUND_LATCH_WRITE:
 
978
                        // each CPU has its own latch
 
979
                        m_audiocpu_latch = param;
 
980
                        m_speechcpu_latch = param;
 
981
                        break;
 
982
        }
 
983
}