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