12
12
***************************************************************************/
15
16
#include "ay8910.h"
16
17
#include "2608intf.h"
19
20
#ifdef BUILD_YM2608
21
#define YM2608_NUMBUF 2
22
/* use FM.C with stream system */
24
static int stream[MAX_2608];
26
/* Global Interface holder */
27
static const struct YM2608interface *intf;
29
static void *Timer[MAX_2608][2];
24
sound_stream * stream;
25
mame_timer * timer[2];
28
const struct YM2608interface *intf;
33
static void psg_set_clock(void *param, int clock)
35
struct ym2608_info *info = param;
36
ay8910_set_clock_ym(info->psg, clock);
39
static void psg_write(void *param, int address, int data)
41
struct ym2608_info *info = param;
42
ay8910_write_ym(info->psg, address, data);
45
static int psg_read(void *param)
47
struct ym2608_info *info = param;
48
return ay8910_read_ym(info->psg);
51
static void psg_reset(void *param)
53
struct ym2608_info *info = param;
54
ay8910_reset_ym(info->psg);
57
static const struct ssg_callbacks psgintf =
33
static void IRQHandler(int n,int irq)
67
static void IRQHandler(void *param,int irq)
35
if(intf->handler[n]) intf->handler[n](irq);
69
struct ym2608_info *info = param;
70
if(info->intf->handler) info->intf->handler(irq);
38
73
/* Timer overflow callback from timer.c */
39
static void timer_callback_2608(int param)
74
static void timer_callback_2608_0(void *param)
76
struct ym2608_info *info = param;
77
YM2608TimerOver(info->chip,0);
80
static void timer_callback_2608_1(void *param)
82
struct ym2608_info *info = param;
83
YM2608TimerOver(info->chip,1);
47
86
/* TimerHandler from fm.c */
48
static void TimerHandler(int n,int c,int count,double stepTime)
87
static void TimerHandler(void *param,int c,int count,double stepTime)
89
struct ym2608_info *info = param;
51
91
{ /* Reset FM Timer */
52
timer_enable(Timer[n][c], 0);
92
timer_enable(info->timer[c], 0);
55
95
{ /* Start FM Timer */
56
96
double timeSec = (double)count * stepTime;
57
if (!timer_enable(Timer[n][c], 1))
58
timer_adjust(Timer[n][c], timeSec, (c<<7)|n, 0);
62
static void FMTimerInit( void )
66
for( i = 0 ; i < MAX_2608 ; i++ )
68
Timer[i][0] = timer_alloc(timer_callback_2608);
69
Timer[i][1] = timer_alloc(timer_callback_2608);
97
if (!timer_enable(info->timer[c], 1))
98
timer_adjust_ptr(info->timer[c], timeSec, 0);
73
102
/* update request from fm.c */
74
void YM2608UpdateRequest(int chip)
76
stream_update(stream[chip],100);
79
int YM2608_sh_start(const struct MachineSound *msound)
103
void YM2608UpdateRequest(void *param)
105
struct ym2608_info *info = param;
106
stream_update(info->stream,100);
109
static void ym2608_stream_update(void *param, stream_sample_t **inputs, stream_sample_t **buffers, int length)
111
struct ym2608_info *info = param;
112
YM2608UpdateOne(info->chip, buffers, length);
116
static void ym2608_postload(void *param)
118
struct ym2608_info *info = param;
119
YM2608Postload(info->chip);
123
static void *ym2608_start(int sndindex, int clock, const void *config)
125
static const struct YM2608interface generic_2608 = { 0 };
126
const struct YM2608interface *intf = config ? config : &generic_2608;
82
127
int rate = Machine->sample_rate;
83
char buf[YM2608_NUMBUF][40];
84
const char *name[YM2608_NUMBUF];
85
int mixed_vol,vol[YM2608_NUMBUF];
86
void *pcmbufa[YM2608_NUMBUF];
87
int pcmsizea[YM2608_NUMBUF];
90
intf = msound->sound_interface;
91
if( intf->num > MAX_2608 ) return 1;
93
if (AY8910_sh_start_ym(msound)) return 1;
131
struct ym2608_info *info;
133
info = auto_malloc(sizeof(*info));
134
memset(info, 0, sizeof(*info));
137
info->psg = ay8910_start_ym(SOUND_YM2608, sndindex, clock, 1, intf->portAread, intf->portBread, intf->portAwrite, intf->portBwrite);
138
if (!info->psg) return NULL;
95
140
/* Timer Handler set */
141
info->timer[0] =timer_alloc_ptr(timer_callback_2608_0, info);
142
info->timer[1] =timer_alloc_ptr(timer_callback_2608_1, info);
98
144
/* stream system initialize */
99
for (i = 0;i < intf->num;i++)
102
mixed_vol = intf->volumeFM[i];
104
for (j = 0 ; j < YM2608_NUMBUF ; j++)
107
vol[j] = mixed_vol & 0xffff;
109
sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
111
stream[i] = stream_init_multi(YM2608_NUMBUF,name,vol,rate,i,YM2608UpdateOne);
112
/* setup adpcm buffers */
113
pcmbufa[i] = (void *)(memory_region(intf->pcmrom[i]));
114
pcmsizea[i] = memory_region_length(intf->pcmrom[i]);
145
info->stream = stream_create(0,2,rate,info,ym2608_stream_update);
146
/* setup adpcm buffers */
147
pcmbufa = (void *)(memory_region(info->intf->pcmrom));
148
pcmsizea = memory_region_length(info->intf->pcmrom);
118
150
/* initialize YM2608 */
119
if (YM2608Init(intf->num,intf->baseclock,rate,
151
info->chip = YM2608Init(info,sndindex,clock,rate,
120
152
pcmbufa,pcmsizea,
121
TimerHandler,IRQHandler) == 0)
153
TimerHandler,IRQHandler,&psgintf);
155
state_save_register_func_postload_ptr(ym2608_postload, info);
128
/************************************************/
129
/* Sound Hardware Stop */
130
/************************************************/
131
void YM2608_sh_stop(void)
137
void YM2608_sh_reset(void)
141
for (i = 0;i < intf->num;i++)
145
/************************************************/
146
/* Status Read for YM2608 - Chip 0 */
164
static void ym2608_stop(void *token)
166
struct ym2608_info *info = token;
167
YM2608Shutdown(info->chip);
168
ay8910_stop_ym(info->psg);
171
static void ym2608_reset(void *token)
173
struct ym2608_info *info = token;
174
YM2608ResetChip(info->chip);
177
/************************************************/
178
/* Status Read for YM2608 - Chip 0 */
147
179
/************************************************/
148
180
READ8_HANDLER( YM2608_status_port_0_A_r )
150
/*logerror("PC %04x: 2608 S0A=%02X\n",activecpu_get_pc(),YM2608Read(0,0)); */
151
return YM2608Read(0,0);
182
/*logerror("PC %04x: 2608 S0A=%02X\n",activecpu_get_pc(),YM2608Read(sndti_token(SOUND_YM2608, 0),0)); */
183
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
184
return YM2608Read(info->chip,0);
154
187
READ8_HANDLER( YM2608_status_port_0_B_r )
156
/*logerror("PC %04x: 2608 S0B=%02X\n",activecpu_get_pc(),YM2608Read(0,2)); */
157
return YM2608Read(0,2);
189
/*logerror("PC %04x: 2608 S0B=%02X\n",activecpu_get_pc(),YM2608Read(sndti_token(SOUND_YM2608, 0),2)); */
190
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
191
return YM2608Read(info->chip,2);
160
194
/************************************************/
161
/* Status Read for YM2608 - Chip 1 */
195
/* Status Read for YM2608 - Chip 1 */
162
196
/************************************************/
163
197
READ8_HANDLER( YM2608_status_port_1_A_r ) {
164
return YM2608Read(1,0);
198
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
199
return YM2608Read(info->chip,0);
167
202
READ8_HANDLER( YM2608_status_port_1_B_r ) {
168
return YM2608Read(1,2);
203
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
204
return YM2608Read(info->chip,2);
171
207
/************************************************/
172
/* Port Read for YM2608 - Chip 0 */
208
/* Port Read for YM2608 - Chip 0 */
173
209
/************************************************/
174
210
READ8_HANDLER( YM2608_read_port_0_r ){
175
return YM2608Read(0,1);
211
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
212
return YM2608Read(info->chip,1);
178
215
/************************************************/
179
/* Port Read for YM2608 - Chip 1 */
216
/* Port Read for YM2608 - Chip 1 */
180
217
/************************************************/
181
218
READ8_HANDLER( YM2608_read_port_1_r ){
182
return YM2608Read(1,1);
219
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
220
return YM2608Read(info->chip,1);
185
223
/************************************************/
186
/* Control Write for YM2608 - Chip 0 */
187
/* Consists of 2 addresses */
224
/* Control Write for YM2608 - Chip 0 */
225
/* Consists of 2 addresses */
188
226
/************************************************/
189
227
WRITE8_HANDLER( YM2608_control_port_0_A_w )
191
YM2608Write(0,0,data);
229
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
230
YM2608Write(info->chip,0,data);
194
233
WRITE8_HANDLER( YM2608_control_port_0_B_w )
196
YM2608Write(0,2,data);
235
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
236
YM2608Write(info->chip,2,data);
199
239
/************************************************/
200
/* Control Write for YM2608 - Chip 1 */
201
/* Consists of 2 addresses */
240
/* Control Write for YM2608 - Chip 1 */
241
/* Consists of 2 addresses */
202
242
/************************************************/
203
243
WRITE8_HANDLER( YM2608_control_port_1_A_w ){
204
YM2608Write(1,0,data);
244
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
245
YM2608Write(info->chip,0,data);
207
248
WRITE8_HANDLER( YM2608_control_port_1_B_w ){
208
YM2608Write(1,2,data);
249
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
250
YM2608Write(info->chip,2,data);
211
253
/************************************************/
212
/* Data Write for YM2608 - Chip 0 */
213
/* Consists of 2 addresses */
254
/* Data Write for YM2608 - Chip 0 */
255
/* Consists of 2 addresses */
214
256
/************************************************/
215
257
WRITE8_HANDLER( YM2608_data_port_0_A_w )
217
YM2608Write(0,1,data);
259
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
260
YM2608Write(info->chip,1,data);
220
263
WRITE8_HANDLER( YM2608_data_port_0_B_w )
222
YM2608Write(0,3,data);
265
struct ym2608_info *info = sndti_token(SOUND_YM2608, 0);
266
YM2608Write(info->chip,3,data);
225
269
/************************************************/
226
/* Data Write for YM2608 - Chip 1 */
227
/* Consists of 2 addresses */
270
/* Data Write for YM2608 - Chip 1 */
271
/* Consists of 2 addresses */
228
272
/************************************************/
229
273
WRITE8_HANDLER( YM2608_data_port_1_A_w ){
230
YM2608Write(1,1,data);
274
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
275
YM2608Write(info->chip,1,data);
232
277
WRITE8_HANDLER( YM2608_data_port_1_B_w ){
233
YM2608Write(1,3,data);
278
struct ym2608_info *info = sndti_token(SOUND_YM2608, 1);
279
YM2608Write(info->chip,3,data);
236
282
/**************** end of file ****************/
285
/**************************************************************************
287
**************************************************************************/
289
static void ym2608_set_info(void *token, UINT32 state, sndinfo *info)
293
/* no parameters to set */
298
void ym2608_get_info(void *token, UINT32 state, sndinfo *info)
302
/* --- the following bits of info are returned as 64-bit signed integers --- */
304
/* --- the following bits of info are returned as pointers to data or functions --- */
305
case SNDINFO_PTR_SET_INFO: info->set_info = ym2608_set_info; break;
306
case SNDINFO_PTR_START: info->start = ym2608_start; break;
307
case SNDINFO_PTR_STOP: info->stop = ym2608_stop; break;
308
case SNDINFO_PTR_RESET: info->reset = ym2608_reset; break;
310
/* --- the following bits of info are returned as NULL-terminated strings --- */
311
case SNDINFO_STR_NAME: info->s = "YM2608"; break;
312
case SNDINFO_STR_CORE_FAMILY: info->s = "Yamaha FM"; break;
313
case SNDINFO_STR_CORE_VERSION: info->s = "1.0"; break;
314
case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break;
315
case SNDINFO_STR_CORE_CREDITS: info->s = "Copyright (c) 2004, The MAME Team"; break;