1 /***************************************************************************
2
3 2612intf.c
4
5 The YM2612 emulator supports up to 2 chips.
6 Each chip has the following connections:
7 - Status Read / Control Write A
8 - Port Read / Data Write A
9 - Control Write B
10 - Data Write B
11
12 ***************************************************************************/
13
14 #include <stdlib.h>
15 #include <stddef.h> // for NULL
16 #include "mamedef.h"
17 //#include "sndintrf.h"
18 //#include "streams.h"
19 //#include "sound/fm.h"
20 //#include "sound/2612intf.h"
21 #include "fm.h"
22 #include "2612intf.h"
23 #ifdef ENABLE_ALL_CORES
24 #include "ym2612.h"
25 #include "ym3438.h"
26 #endif
27
28
29 #define EC_MAME 0x00 // YM2612 core from MAME (now fixed, so it isn't worse than Gens anymore)
30 #ifdef ENABLE_ALL_CORES
31 #define EC_GENS 0x02 // Gens YM2612 core from in_vgm
32 #define EC_NUKED 0x01 // Nuked YM3438/YM2612 core
33 #endif
34
35 typedef struct _ym2612_state ym2612_state;
36 struct _ym2612_state
37 {
38 //sound_stream * stream;
39 //emu_timer * timer[2];
40 void * chip;
41 //const ym2612_interface *intf;
42 //const device_config *device;
43 };
44
45
46 extern UINT8 CHIP_SAMPLING_MODE;
47 extern INT32 CHIP_SAMPLE_RATE;
48 static UINT8 EMU_CORE = 0x00;
49
50 #define MAX_CHIPS 0x02
51 static ym2612_state YM2612Data[MAX_CHIPS];
52 static int* GensBuf[0x02] = {NULL, NULL};
53 static UINT8 ChipFlags = 0x00;
54
55 /*INLINE ym2612_state *get_safe_token(const device_config *device)
56 {
57 assert(device != NULL);
58 assert(device->token != NULL);
59 assert(device->type == SOUND);
60 assert(sound_get_type(device) == SOUND_YM2612 || sound_get_type(device) == SOUND_YM3438);
61 return (ym2612_state *)device->token;
62 }*/
63
64 /*------------------------- TM2612 -------------------------------*/
65 /* IRQ Handler */
66 /*static void IRQHandler(void *param,int irq)
67 {
68 ym2612_state *info = (ym2612_state *)param;
69 //if(info->intf->handler) info->intf->handler(info->device, irq);
70 //if(info->intf->handler) info->intf->handler(irq);
71 }*/
72
73 /* Timer overflow callback from timer.c */
74 //static TIMER_CALLBACK( timer_callback_2612_0 )
75 /*void timer_callback_2612_0(void *ptr, int param)
76 {
77 ym2612_state *info = (ym2612_state *)ptr;
78 ym2612_timer_over(info->chip,0);
79 }
80
81 //static TIMER_CALLBACK( timer_callback_2612_1 )
82 void timer_callback_2612_1(void *ptr, int param)
83 {
84 ym2612_state *info = (ym2612_state *)ptr;
85 ym2612_timer_over(info->chip,1);
86 }*/
87
88 /*static void timer_handler(void *param,int c,int count,int clock)
89 {
90 ym2612_state *info = (ym2612_state *)param;
91 if( count == 0 )
92 { // Reset FM Timer
93 //timer_enable(info->timer[c], 0);
94 }
95 else
96 { // Start FM Timer
97 //attotime period = attotime_mul(ATTOTIME_IN_HZ(clock), count);
98 //if (!timer_enable(info->timer[c], 1))
99 // timer_adjust_oneshot(info->timer[c], period, 0);
100 }
101 }*/
102
103 /* update request from fm.c */
ym2612_update_request(void * param)104 void ym2612_update_request(void *param)
105 {
106 ym2612_state *info = (ym2612_state *)param;
107 //stream_update(info->stream);
108
109 switch(EMU_CORE)
110 {
111 case EC_MAME:
112 ym2612_update_one(info->chip, DUMMYBUF, 0);
113 break;
114 #ifdef ENABLE_ALL_CORES
115 case EC_GENS:
116 YM2612_Update(info->chip, DUMMYBUF, 0);
117 YM2612_DacAndTimers_Update(info->chip, DUMMYBUF, 0);
118 break;
119 case EC_NUKED:
120 break;
121 #endif
122 }
123 }
124
125 /***********************************************************/
126 /* YM2612 */
127 /***********************************************************/
128
129 //static STREAM_UPDATE( ym2612_stream_update )
ym2612_stream_update(UINT8 ChipID,stream_sample_t ** outputs,int samples)130 void ym2612_stream_update(UINT8 ChipID, stream_sample_t **outputs, int samples)
131 {
132 //ym2612_state *info = (ym2612_state *)param;
133 ym2612_state *info = &YM2612Data[ChipID];
134 #ifdef ENABLE_ALL_CORES
135 int i;
136 #endif
137
138 switch(EMU_CORE)
139 {
140 case EC_MAME:
141 ym2612_update_one(info->chip, outputs, samples);
142 break;
143 #ifdef ENABLE_ALL_CORES
144 case EC_GENS:
145 YM2612_ClearBuffer(GensBuf, samples);
146 YM2612_Update(info->chip, GensBuf, samples);
147 YM2612_DacAndTimers_Update(info->chip, GensBuf, samples);
148 for (i = 0x00; i < samples; i ++)
149 {
150 outputs[0x00][i] = (stream_sample_t)GensBuf[0x00][i];
151 outputs[0x01][i] = (stream_sample_t)GensBuf[0x01][i];
152 }
153 break;
154 case EC_NUKED:
155 OPN2_GenerateStream(info->chip, outputs, samples);
156 break;
157 #endif
158 }
159 }
160
161
162 //static STATE_POSTLOAD( ym2612_intf_postload )
163 /*static void ym2612_intf_postload(UINT8 ChipID)
164 {
165 //ym2612_state *info = (ym2612_state *)param;
166 ym2612_state *info = &YM2612Data[ChipID];
167 ym2612_postload(info->chip);
168 }*/
169
170
171 //static DEVICE_START( ym2612 )
device_start_ym2612(UINT8 ChipID,int clock)172 int device_start_ym2612(UINT8 ChipID, int clock)
173 {
174 //static const ym2612_interface dummy = { 0 };
175 //ym2612_state *info = get_safe_token(device);
176 ym2612_state *info;
177 int rate;
178 int chiptype;
179
180 if (ChipID >= MAX_CHIPS)
181 return 0;
182
183 chiptype = clock&0x80000000;
184 clock&=0x3fffffff;
185
186 info = &YM2612Data[ChipID];
187 rate = clock/72;
188 if (! (EMU_CORE == EC_MAME && (ChipFlags & 0x04))) // if not ("double rate" required)
189 rate /= 2;
190 if ((CHIP_SAMPLING_MODE == 0x01 && rate < CHIP_SAMPLE_RATE) ||
191 CHIP_SAMPLING_MODE == 0x02)
192 rate = CHIP_SAMPLE_RATE;
193 //info->intf = device->static_config ? (const ym2612_interface *)device->static_config : &dummy;
194 //info->intf = &dummy;
195 //info->device = device;
196
197 /* FM init */
198 /* Timer Handler set */
199 //info->timer[0] = timer_alloc(device->machine, timer_callback_2612_0, info);
200 //info->timer[1] = timer_alloc(device->machine, timer_callback_2612_1, info);
201
202 /* stream system initialize */
203 //info->stream = stream_create(device,0,2,rate,info,ym2612_stream_update);
204
205 /**** initialize YM2612 ****/
206 switch(EMU_CORE)
207 {
208 case EC_MAME:
209 //info->chip = ym2612_init(info,clock,rate,timer_handler,IRQHandler);
210 info->chip = ym2612_init(info, clock, rate, NULL, NULL);
211 break;
212 #ifdef ENABLE_ALL_CORES
213 case EC_GENS:
214 if (GensBuf[0x00] == NULL)
215 {
216 GensBuf[0x00] = malloc(sizeof(int) * 0x100);
217 GensBuf[0x01] = GensBuf[0x00] + 0x80;
218 }
219 info->chip = YM2612_Init(clock, rate, 0x00);
220 YM2612_SetMute(info->chip, 0x80); // Disable SSG-EG
221 break;
222 case EC_NUKED:
223 info->chip = malloc(sizeof(ym3438_t));
224 if(chiptype)
225 OPN2_SetChipType(ym3438_type_discrete);
226 OPN2_Reset(info->chip, rate, clock);
227 #endif
228 }
229 //assert_always(info->chip != NULL, "Error creating YM2612 chip");
230 //ym2612_postload(info->chip);
231
232 //state_save_register_postload(device->machine, ym2612_intf_postload, info);
233 //ym2612_intf_postload();
234 return rate;
235 }
236
237
238 //static DEVICE_STOP( ym2612 )
device_stop_ym2612(UINT8 ChipID)239 void device_stop_ym2612(UINT8 ChipID)
240 {
241 //ym2612_state *info = get_safe_token(device);
242 ym2612_state *info = &YM2612Data[ChipID];
243 switch(EMU_CORE)
244 {
245 case EC_MAME:
246 ym2612_shutdown(info->chip);
247 break;
248 #ifdef ENABLE_ALL_CORES
249 case EC_GENS:
250 YM2612_End(info->chip);
251 if (GensBuf[0x00] != NULL)
252 {
253 free(GensBuf[0x00]);
254 GensBuf[0x00] = NULL;
255 GensBuf[0x01] = NULL;
256 }
257 break;
258 case EC_NUKED:
259 free(info->chip);
260 break;
261 #endif
262 }
263 }
264
265 //static DEVICE_RESET( ym2612 )
device_reset_ym2612(UINT8 ChipID)266 void device_reset_ym2612(UINT8 ChipID)
267 {
268 //ym2612_state *info = get_safe_token(device);
269 ym2612_state *info = &YM2612Data[ChipID];
270 switch(EMU_CORE)
271 {
272 case EC_MAME:
273 ym2612_reset_chip(info->chip);
274 break;
275 #ifdef ENABLE_ALL_CORES
276 case EC_GENS:
277 YM2612_Reset(info->chip);
278 break;
279 case EC_NUKED:
280 OPN2_Reset(info->chip, 0, 0);
281 break;
282 #endif
283 }
284 }
285
286
287 //READ8_DEVICE_HANDLER( ym2612_r )
ym2612_r(UINT8 ChipID,offs_t offset)288 UINT8 ym2612_r(UINT8 ChipID, offs_t offset)
289 {
290 //ym2612_state *info = get_safe_token(device);
291 ym2612_state *info = &YM2612Data[ChipID];
292 switch(EMU_CORE)
293 {
294 case EC_MAME:
295 return ym2612_read(info->chip, offset & 3);
296 #ifdef ENABLE_ALL_CORES
297 case EC_GENS:
298 return YM2612_Read(info->chip);
299 case EC_NUKED:
300 return OPN2_Read(info->chip, offset);
301 #endif
302 default:
303 return 0x00;
304 }
305 }
306
307 //WRITE8_DEVICE_HANDLER( ym2612_w )
ym2612_w(UINT8 ChipID,offs_t offset,UINT8 data)308 void ym2612_w(UINT8 ChipID, offs_t offset, UINT8 data)
309 {
310 //ym2612_state *info = get_safe_token(device);
311 ym2612_state *info = &YM2612Data[ChipID];
312 switch(EMU_CORE)
313 {
314 case EC_MAME:
315 ym2612_write(info->chip, offset & 3, data);
316 break;
317 #ifdef ENABLE_ALL_CORES
318 case EC_GENS:
319 YM2612_Write(info->chip, (unsigned char)(offset & 0x03), data);
320 break;
321 case EC_NUKED:
322 OPN2_WriteBuffered(info->chip, offset, data);
323 break;
324 #endif
325 }
326 }
327
328
329 /*READ8_DEVICE_HANDLER( ym2612_status_port_a_r ) { return ym2612_r(device, 0); }
330 READ8_DEVICE_HANDLER( ym2612_status_port_b_r ) { return ym2612_r(device, 2); }
331 READ8_DEVICE_HANDLER( ym2612_data_port_a_r ) { return ym2612_r(device, 1); }
332 READ8_DEVICE_HANDLER( ym2612_data_port_b_r ) { return ym2612_r(device, 3); }
333
334 WRITE8_DEVICE_HANDLER( ym2612_control_port_a_w ) { ym2612_w(device, 0, data); }
335 WRITE8_DEVICE_HANDLER( ym2612_control_port_b_w ) { ym2612_w(device, 2, data); }
336 WRITE8_DEVICE_HANDLER( ym2612_data_port_a_w ) { ym2612_w(device, 1, data); }
337 WRITE8_DEVICE_HANDLER( ym2612_data_port_b_w ) { ym2612_w(device, 3, data); }*/
ym2612_status_port_a_r(UINT8 ChipID,offs_t offset)338 UINT8 ym2612_status_port_a_r(UINT8 ChipID, offs_t offset)
339 {
340 return ym2612_r(ChipID, 0);
341 }
ym2612_status_port_b_r(UINT8 ChipID,offs_t offset)342 UINT8 ym2612_status_port_b_r(UINT8 ChipID, offs_t offset)
343 {
344 return ym2612_r(ChipID, 2);
345 }
ym2612_data_port_a_r(UINT8 ChipID,offs_t offset)346 UINT8 ym2612_data_port_a_r(UINT8 ChipID, offs_t offset)
347 {
348 return ym2612_r(ChipID, 1);
349 }
ym2612_data_port_b_r(UINT8 ChipID,offs_t offset)350 UINT8 ym2612_data_port_b_r(UINT8 ChipID, offs_t offset)
351 {
352 return ym2612_r(ChipID, 3);
353 }
354
ym2612_control_port_a_w(UINT8 ChipID,offs_t offset,UINT8 data)355 void ym2612_control_port_a_w(UINT8 ChipID, offs_t offset, UINT8 data)
356 {
357 ym2612_w(ChipID, 0, data);
358 }
ym2612_control_port_b_w(UINT8 ChipID,offs_t offset,UINT8 data)359 void ym2612_control_port_b_w(UINT8 ChipID, offs_t offset, UINT8 data)
360 {
361 ym2612_w(ChipID, 2, data);
362 }
ym2612_data_port_a_w(UINT8 ChipID,offs_t offset,UINT8 data)363 void ym2612_data_port_a_w(UINT8 ChipID, offs_t offset, UINT8 data)
364 {
365 ym2612_w(ChipID, 1, data);
366 }
ym2612_data_port_b_w(UINT8 ChipID,offs_t offset,UINT8 data)367 void ym2612_data_port_b_w(UINT8 ChipID, offs_t offset, UINT8 data)
368 {
369 ym2612_w(ChipID, 3, data);
370 }
371
372
ym2612_set_emu_core(UINT8 Emulator)373 void ym2612_set_emu_core(UINT8 Emulator)
374 {
375 #ifdef ENABLE_ALL_CORES
376 EMU_CORE = (Emulator < 0x03) ? Emulator : 0x00;
377 #else
378 EMU_CORE = EC_MAME;
379 #endif
380
381 return;
382 }
383
ym2612_set_options(UINT8 Flags)384 void ym2612_set_options(UINT8 Flags)
385 {
386 ChipFlags = Flags;
387 switch(EMU_CORE)
388 {
389 case EC_MAME:
390 ym2612_setoptions(Flags);
391 break;
392 #ifdef ENABLE_ALL_CORES
393 case EC_GENS:
394 YM2612_SetOptions(Flags);
395 break;
396 case EC_NUKED:
397 OPN2_SetOptions(Flags);
398 break;
399 #endif
400 }
401
402 return;
403 }
404
ym2612_set_mute_mask(UINT8 ChipID,UINT32 MuteMask)405 void ym2612_set_mute_mask(UINT8 ChipID, UINT32 MuteMask)
406 {
407 ym2612_state *info = &YM2612Data[ChipID];
408 switch(EMU_CORE)
409 {
410 case EC_MAME:
411 ym2612_set_mutemask(info->chip, MuteMask);
412 break;
413 #ifdef ENABLE_ALL_CORES
414 case EC_GENS:
415 YM2612_SetMute(info->chip, (int)MuteMask);
416 break;
417 case EC_NUKED:
418 OPN2_SetMute(info->chip, MuteMask);
419 break;
420 #endif
421 }
422
423 return;
424 }
425
426
427
428 /**************************************************************************
429 * Generic get_info
430 **************************************************************************/
431
432 /*DEVICE_GET_INFO( ym2612 )
433 {
434 switch (state)
435 {
436 // --- the following bits of info are returned as 64-bit signed integers ---
437 case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ym2612_state); break;
438
439 // --- the following bits of info are returned as pointers to data or functions ---
440 case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym2612 ); break;
441 case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME( ym2612 ); break;
442 case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( ym2612 ); break;
443
444 // --- the following bits of info are returned as NULL-terminated strings ---
445 case DEVINFO_STR_NAME: strcpy(info->s, "YM2612"); break;
446 case DEVINFO_STR_FAMILY: strcpy(info->s, "Yamaha FM"); break;
447 case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
448 case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
449 case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
450 }
451 }
452
453
454 DEVICE_GET_INFO( ym3438 )
455 {
456 switch (state)
457 {
458 // --- the following bits of info are returned as NULL-terminated strings ---
459 case DEVINFO_STR_NAME: strcpy(info->s, "YM3438"); break;
460
461 default: DEVICE_GET_INFO_CALL(ym2612); break;
462 }
463 }*/
464