1 /******************************************************************************
2 * FILE
3 * Yamaha 3812 emulator interface - MAME VERSION
4 *
5 * CREATED BY
6 * Ernesto Corvi
7 *
8 * UPDATE LOG
9 * JB 28-04-2002 Fixed simultaneous usage of all three different chip types.
10 * Used real sample rate when resample filter is active.
11 * AAT 12-28-2001 Protected Y8950 from accessing unmapped port and keyboard handlers.
12 * CHS 1999-01-09 Fixes new ym3812 emulation interface.
13 * CHS 1998-10-23 Mame streaming sound chip update
14 * EC 1998 Created Interface
15 *
16 * NOTES
17 *
18 ******************************************************************************/
19 #include <stddef.h> // for NULL
20 #include "mamedef.h"
21 //#include "attotime.h"
22 //#include "sndintrf.h"
23 //#include "streams.h"
24 //#include "cpuintrf.h"
25 #include "3812intf.h"
26 #ifdef ENABLE_ALL_CORES
27 #include "fmopl.h"
28 #endif
29
30 #define OPLTYPE_IS_OPL2
31 #include "adlibemu.h"
32
33
34 #define EC_DBOPL 0x00 // DosBox OPL (AdLibEmu)
35 #ifdef ENABLE_ALL_CORES
36 #define EC_MAME 0x01 // YM3826 core from MAME
37 #endif
38
39 typedef struct _ym3812_state ym3812_state;
40 struct _ym3812_state
41 {
42 //sound_stream * stream;
43 //emu_timer * timer[2];
44 void * chip;
45 //const ym3812_interface *intf;
46 //const device_config *device;
47 };
48
49
50 extern UINT8 CHIP_SAMPLING_MODE;
51 extern INT32 CHIP_SAMPLE_RATE;
52 static UINT8 EMU_CORE = 0x00;
53
54 #define MAX_CHIPS 0x02
55 static ym3812_state YM3812Data[MAX_CHIPS];
56
57 /*INLINE ym3812_state *get_safe_token(const device_config *device)
58 {
59 assert(device != NULL);
60 assert(device->token != NULL);
61 assert(device->type == SOUND);
62 assert(sound_get_type(device) == SOUND_YM3812);
63 return (ym3812_state *)device->token;
64 }*/
65
66
67
IRQHandler(void * param,int irq)68 static void IRQHandler(void *param,int irq)
69 {
70 ym3812_state *info = (ym3812_state *)param;
71 //if (info->intf->handler) (info->intf->handler)(info->device, irq ? ASSERT_LINE : CLEAR_LINE);
72 //if (info->intf->handler) (info->intf->handler)(irq ? ASSERT_LINE : CLEAR_LINE);
73 }
74 /*static TIMER_CALLBACK( timer_callback_0 )
75 {
76 ym3812_state *info = (ym3812_state *)ptr;
77 ym3812_timer_over(info->chip,0);
78 }
79
80 static TIMER_CALLBACK( timer_callback_1 )
81 {
82 ym3812_state *info = (ym3812_state *)ptr;
83 ym3812_timer_over(info->chip,1);
84 }*/
85
86 //static void TimerHandler(void *param,int c,attotime period)
TimerHandler(void * param,int c,int period)87 static void TimerHandler(void *param,int c,int period)
88 {
89 ym3812_state *info = (ym3812_state *)param;
90 //if( attotime_compare(period, attotime_zero) == 0 )
91 if( period == 0 )
92 { /* Reset FM Timer */
93 //timer_enable(info->timer[c], 0);
94 }
95 else
96 { /* Start FM Timer */
97 //timer_adjust_oneshot(info->timer[c], period, 0);
98 }
99 }
100
101
102 //static STREAM_UPDATE( ym3812_stream_update )
ym3812_stream_update(UINT8 ChipID,stream_sample_t ** outputs,int samples)103 void ym3812_stream_update(UINT8 ChipID, stream_sample_t **outputs, int samples)
104 {
105 //ym3812_state *info = (ym3812_state *)param;
106 ym3812_state *info = &YM3812Data[ChipID];
107 switch(EMU_CORE)
108 {
109 #ifdef ENABLE_ALL_CORES
110 case EC_MAME:
111 ym3812_update_one(info->chip, outputs, samples);
112 break;
113 #endif
114 case EC_DBOPL:
115 adlib_OPL2_getsample(info->chip, outputs, samples);
116 break;
117 }
118 }
119
_stream_update(void * param)120 static void _stream_update(void * param/*, int interval*/)
121 {
122 ym3812_state *info = (ym3812_state *)param;
123 //stream_update(info->stream);
124
125 switch(EMU_CORE)
126 {
127 #ifdef ENABLE_ALL_CORES
128 case EC_MAME:
129 ym3812_update_one(info->chip, DUMMYBUF, 0);
130 break;
131 #endif
132 case EC_DBOPL:
133 adlib_OPL2_getsample(info->chip, DUMMYBUF, 0);
134 break;
135 }
136 }
137
138
139 //static DEVICE_START( ym3812 )
device_start_ym3812(UINT8 ChipID,int clock)140 int device_start_ym3812(UINT8 ChipID, int clock)
141 {
142 //static const ym3812_interface dummy = { 0 };
143 //ym3812_state *info = get_safe_token(device);
144 ym3812_state *info;
145 int rate;
146
147 if (ChipID >= MAX_CHIPS)
148 return 0;
149
150 info = &YM3812Data[ChipID];
151 rate = (clock & 0x7FFFFFFF)/72;
152 if ((CHIP_SAMPLING_MODE == 0x01 && rate < CHIP_SAMPLE_RATE) ||
153 CHIP_SAMPLING_MODE == 0x02)
154 rate = CHIP_SAMPLE_RATE;
155 //info->intf = device->static_config ? (const ym3812_interface *)device->static_config : &dummy;
156 //info->intf = &dummy;
157 //info->device = device;
158
159 /* stream system initialize */
160 switch(EMU_CORE)
161 {
162 #ifdef ENABLE_ALL_CORES
163 case EC_MAME:
164 info->chip = ym3812_init(clock & 0x7FFFFFFF,rate);
165 //assert_always(info->chip != NULL, "Error creating YM3812 chip");
166
167 //info->stream = stream_create(device,0,1,rate,info,ym3812_stream_update);
168
169 /* YM3812 setup */
170 ym3812_set_timer_handler (info->chip, TimerHandler, info);
171 ym3812_set_irq_handler (info->chip, IRQHandler, info);
172 ym3812_set_update_handler(info->chip, _stream_update, info);
173
174 //info->timer[0] = timer_alloc(device->machine, timer_callback_0, info);
175 //info->timer[1] = timer_alloc(device->machine, timer_callback_1, info);
176 break;
177 #endif
178 case EC_DBOPL:
179 info->chip = adlib_OPL2_init(clock & 0x7FFFFFFF, rate, _stream_update, info);
180 break;
181 }
182
183 return rate;
184 }
185
186 //static DEVICE_STOP( ym3812 )
device_stop_ym3812(UINT8 ChipID)187 void device_stop_ym3812(UINT8 ChipID)
188 {
189 //ym3812_state *info = get_safe_token(device);
190 ym3812_state *info = &YM3812Data[ChipID];
191 switch(EMU_CORE)
192 {
193 #ifdef ENABLE_ALL_CORES
194 case EC_MAME:
195 ym3812_shutdown(info->chip);
196 break;
197 #endif
198 case EC_DBOPL:
199 adlib_OPL2_stop(info->chip);
200 break;
201 }
202 }
203
204 //static DEVICE_RESET( ym3812 )
device_reset_ym3812(UINT8 ChipID)205 void device_reset_ym3812(UINT8 ChipID)
206 {
207 //ym3812_state *info = get_safe_token(device);
208 ym3812_state *info = &YM3812Data[ChipID];
209 switch(EMU_CORE)
210 {
211 #ifdef ENABLE_ALL_CORES
212 case EC_MAME:
213 ym3812_reset_chip(info->chip);
214 break;
215 #endif
216 case EC_DBOPL:
217 adlib_OPL2_reset(info->chip);
218 break;
219 }
220 }
221
222
223 //READ8_DEVICE_HANDLER( ym3812_r )
ym3812_r(UINT8 ChipID,offs_t offset)224 UINT8 ym3812_r(UINT8 ChipID, offs_t offset)
225 {
226 //ym3812_state *info = get_safe_token(device);
227 ym3812_state *info = &YM3812Data[ChipID];
228 switch(EMU_CORE)
229 {
230 #ifdef ENABLE_ALL_CORES
231 case EC_MAME:
232 return ym3812_read(info->chip, offset & 1);
233 #endif
234 case EC_DBOPL:
235 return adlib_OPL2_reg_read(info->chip, offset & 0x01);
236 default:
237 return 0x00;
238 }
239 }
240
241 //WRITE8_DEVICE_HANDLER( ym3812_w )
ym3812_w(UINT8 ChipID,offs_t offset,UINT8 data)242 void ym3812_w(UINT8 ChipID, offs_t offset, UINT8 data)
243 {
244 //ym3812_state *info = get_safe_token(device);
245 ym3812_state *info = &YM3812Data[ChipID];
246 switch(EMU_CORE)
247 {
248 #ifdef ENABLE_ALL_CORES
249 case EC_MAME:
250 ym3812_write(info->chip, offset & 1, data);
251 break;
252 #endif
253 case EC_DBOPL:
254 adlib_OPL2_writeIO(info->chip, offset & 1, data);
255 break;
256 }
257 }
258
259 //READ8_DEVICE_HANDLER( ym3812_status_port_r )
ym3812_status_port_r(UINT8 ChipID,offs_t offset)260 UINT8 ym3812_status_port_r(UINT8 ChipID, offs_t offset)
261 {
262 return ym3812_r(ChipID, 0);
263 }
264 //READ8_DEVICE_HANDLER( ym3812_read_port_r )
ym3812_read_port_r(UINT8 ChipID,offs_t offset)265 UINT8 ym3812_read_port_r(UINT8 ChipID, offs_t offset)
266 {
267 return ym3812_r(ChipID, 1);
268 }
269 //WRITE8_DEVICE_HANDLER( ym3812_control_port_w )
ym3812_control_port_w(UINT8 ChipID,offs_t offset,UINT8 data)270 void ym3812_control_port_w(UINT8 ChipID, offs_t offset, UINT8 data)
271 {
272 ym3812_w(ChipID, 0, data);
273 }
274 //WRITE8_DEVICE_HANDLER( ym3812_write_port_w )
ym3812_write_port_w(UINT8 ChipID,offs_t offset,UINT8 data)275 void ym3812_write_port_w(UINT8 ChipID, offs_t offset, UINT8 data)
276 {
277 ym3812_w(ChipID, 1, data);
278 }
279
280
ym3812_set_emu_core(UINT8 Emulator)281 void ym3812_set_emu_core(UINT8 Emulator)
282 {
283 #ifdef ENABLE_ALL_CORES
284 EMU_CORE = (Emulator < 0x02) ? Emulator : 0x00;
285 #else
286 EMU_CORE = EC_DBOPL;
287 #endif
288
289 return;
290 }
291
ym3812_set_mute_mask(UINT8 ChipID,UINT32 MuteMask)292 void ym3812_set_mute_mask(UINT8 ChipID, UINT32 MuteMask)
293 {
294 ym3812_state *info = &YM3812Data[ChipID];
295 switch(EMU_CORE)
296 {
297 #ifdef ENABLE_ALL_CORES
298 case EC_MAME:
299 opl_set_mute_mask(info->chip, MuteMask);
300 break;
301 #endif
302 case EC_DBOPL:
303 adlib_OPL2_set_mute_mask(info->chip, MuteMask);
304 break;
305 }
306
307 return;
308 }
309
310
311 /**************************************************************************
312 * Generic get_info
313 **************************************************************************/
314
315 /*DEVICE_GET_INFO( ym3812 )
316 {
317 switch (state)
318 {
319 // --- the following bits of info are returned as 64-bit signed integers ---
320 case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ym3812_state); break;
321
322 // --- the following bits of info are returned as pointers to data or functions ---
323 case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym3812 ); break;
324 case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME( ym3812 ); break;
325 case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( ym3812 ); break;
326
327 // --- the following bits of info are returned as NULL-terminated strings ---
328 case DEVINFO_STR_NAME: strcpy(info->s, "YM3812"); break;
329 case DEVINFO_STR_FAMILY: strcpy(info->s, "Yamaha FM"); break;
330 case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
331 case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
332 case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
333 }
334 }*/
335