1
/***************************************************************************
5
Generic simple sound functions.
7
Copyright Nicola Salmoria and the MAME Team.
8
Visit http://mamedev.org for licensing and usage restrictions.
10
***************************************************************************/
16
/***************************************************************************
18
***************************************************************************/
20
struct _generic_audio_private
22
UINT16 latch_clear_value;
23
UINT16 latched_value[4];
29
/***************************************************************************
31
***************************************************************************/
33
/*-------------------------------------------------
34
generic_sound_init - initialize globals and
35
register for save states
36
-------------------------------------------------*/
38
int generic_sound_init(running_machine &machine)
40
generic_audio_private *state;
42
state = machine.generic_audio_data = auto_alloc_clear(machine, generic_audio_private);
44
/* register globals with the save state system */
45
state_save_register_global_array(machine, state->latched_value);
46
state_save_register_global_array(machine, state->latch_read);
53
/***************************************************************************
55
Many games use a master-slave CPU setup. Typically, the main CPU writes
56
a command to some register, and then writes to another register to trigger
57
an interrupt on the slave CPU (the interrupt might also be triggered by
58
the first write). The slave CPU, notified by the interrupt, goes and reads
61
***************************************************************************/
63
/*-------------------------------------------------
64
latch_callback - time-delayed callback to
66
-------------------------------------------------*/
68
static TIMER_CALLBACK( latch_callback )
70
generic_audio_private *state = machine.generic_audio_data;
71
UINT16 value = param >> 8;
72
int which = param & 0xff;
74
/* if the latch hasn't been read and the value is changed, log a warning */
75
if (!state->latch_read[which] && state->latched_value[which] != value)
76
logerror("Warning: sound latch %d written before being read. Previous: %02x, new: %02x\n", which, state->latched_value[which], value);
78
/* store the new value and mark it not read */
79
state->latched_value[which] = value;
80
state->latch_read[which] = 0;
84
/*-------------------------------------------------
85
latch_w - handle a write to a given latch
86
-------------------------------------------------*/
88
INLINE void latch_w(address_space *space, int which, UINT16 value)
90
space->machine().scheduler().synchronize(FUNC(latch_callback), which | (value << 8));
94
/*-------------------------------------------------
95
latch_r - handle a read from a given latch
96
-------------------------------------------------*/
98
INLINE UINT16 latch_r(address_space *space, int which)
100
generic_audio_private *state = space->machine().generic_audio_data;
101
state->latch_read[which] = 1;
102
return state->latched_value[which];
106
/*-------------------------------------------------
107
latch_clear - clear a given latch
108
-------------------------------------------------*/
110
INLINE void latch_clear(address_space *space, int which)
112
generic_audio_private *state = space->machine().generic_audio_data;
113
state->latched_value[which] = state->latch_clear_value;
117
/*-------------------------------------------------
118
soundlatch_w - global write handlers for
119
writing to sound latches
120
-------------------------------------------------*/
122
WRITE8_HANDLER( soundlatch_w ) { latch_w(space, 0, data); }
123
WRITE16_HANDLER( soundlatch_word_w ) { latch_w(space, 0, data); }
124
WRITE8_HANDLER( soundlatch2_w ) { latch_w(space, 1, data); }
125
WRITE16_HANDLER( soundlatch2_word_w ) { latch_w(space, 1, data); }
126
WRITE8_HANDLER( soundlatch3_w ) { latch_w(space, 2, data); }
127
WRITE16_HANDLER( soundlatch3_word_w ) { latch_w(space, 2, data); }
128
WRITE8_HANDLER( soundlatch4_w ) { latch_w(space, 3, data); }
129
WRITE16_HANDLER( soundlatch4_word_w ) { latch_w(space, 3, data); }
132
/*-------------------------------------------------
133
soundlatch_r - global read handlers for
134
reading from sound latches
135
-------------------------------------------------*/
137
READ8_HANDLER( soundlatch_r ) { return latch_r(space, 0); }
138
READ16_HANDLER( soundlatch_word_r ) { return latch_r(space, 0); }
139
READ8_HANDLER( soundlatch2_r ) { return latch_r(space, 1); }
140
READ16_HANDLER( soundlatch2_word_r ) { return latch_r(space, 1); }
141
READ8_HANDLER( soundlatch3_r ) { return latch_r(space, 2); }
142
READ16_HANDLER( soundlatch3_word_r ) { return latch_r(space, 2); }
143
READ8_HANDLER( soundlatch4_r ) { return latch_r(space, 3); }
144
READ16_HANDLER( soundlatch4_word_r ) { return latch_r(space, 3); }
147
/*-------------------------------------------------
148
soundlatch_clear_w - global write handlers
149
for clearing sound latches
150
-------------------------------------------------*/
152
WRITE8_HANDLER( soundlatch_clear_w ) { latch_clear(space, 0); }
153
WRITE8_HANDLER( soundlatch2_clear_w ) { latch_clear(space, 1); }
154
WRITE8_HANDLER( soundlatch3_clear_w ) { latch_clear(space, 2); }
155
WRITE8_HANDLER( soundlatch4_clear_w ) { latch_clear(space, 3); }
158
/*-------------------------------------------------
159
soundlatch_setclearedvalue - set the "clear"
160
value for all sound latches
161
-------------------------------------------------*/
163
void soundlatch_setclearedvalue(running_machine &machine, int value)
165
generic_audio_private *state = machine.generic_audio_data;
166
assert_always(machine.phase() == MACHINE_PHASE_INIT, "Can only call soundlatch_setclearedvalue at init time!");
167
state->latch_clear_value = value;