summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/sound/262intf.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/sound/262intf.c')
-rw-r--r--trunk/src/emu/sound/262intf.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/262intf.c b/trunk/src/emu/sound/262intf.c
new file mode 100644
index 00000000000..de329c7eaf9
--- /dev/null
+++ b/trunk/src/emu/sound/262intf.c
@@ -0,0 +1,161 @@
+/***************************************************************************
+
+ 262intf.c
+
+ MAME interface for YMF262 (OPL3) emulator
+
+***************************************************************************/
+#include "emu.h"
+#include "262intf.h"
+#include "ymf262.h"
+
+
+typedef struct _ymf262_state ymf262_state;
+struct _ymf262_state
+{
+ sound_stream * stream;
+ emu_timer * timer[2];
+ void * chip;
+ const ymf262_interface *intf;
+ device_t *device;
+};
+
+
+INLINE ymf262_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == YMF262);
+ return (ymf262_state *)downcast<legacy_device_base *>(device)->token();
+}
+
+
+
+
+static void IRQHandler_262(void *param,int irq)
+{
+ ymf262_state *info = (ymf262_state *)param;
+ if (info->intf->handler) (info->intf->handler)(info->device, irq);
+}
+
+static TIMER_CALLBACK( timer_callback_262_0 )
+{
+ ymf262_state *info = (ymf262_state *)ptr;
+ ymf262_timer_over(info->chip, 0);
+}
+
+static TIMER_CALLBACK( timer_callback_262_1 )
+{
+ ymf262_state *info = (ymf262_state *)ptr;
+ ymf262_timer_over(info->chip, 1);
+}
+
+static void timer_handler_262(void *param,int timer, attotime period)
+{
+ ymf262_state *info = (ymf262_state *)param;
+ if( period == attotime::zero )
+ { /* Reset FM Timer */
+ info->timer[timer]->enable(false);
+ }
+ else
+ { /* Start FM Timer */
+ info->timer[timer]->adjust(period);
+ }
+}
+
+static STREAM_UPDATE( ymf262_stream_update )
+{
+ ymf262_state *info = (ymf262_state *)param;
+ ymf262_update_one(info->chip, outputs, samples);
+}
+
+static void _stream_update(void *param, int interval)
+{
+ ymf262_state *info = (ymf262_state *)param;
+ info->stream->update();
+}
+
+
+static DEVICE_START( ymf262 )
+{
+ static const ymf262_interface dummy = { 0 };
+ ymf262_state *info = get_safe_token(device);
+ int rate = device->clock()/288;
+
+ info->intf = device->static_config() ? (const ymf262_interface *)device->static_config() : &dummy;
+ info->device = device;
+
+ /* stream system initialize */
+ info->chip = ymf262_init(device,device->clock(),rate);
+ assert_always(info->chip != NULL, "Error creating YMF262 chip");
+
+ info->stream = device->machine().sound().stream_alloc(*device,0,4,rate,info,ymf262_stream_update);
+
+ /* YMF262 setup */
+ ymf262_set_timer_handler (info->chip, timer_handler_262, info);
+ ymf262_set_irq_handler (info->chip, IRQHandler_262, info);
+ ymf262_set_update_handler(info->chip, _stream_update, info);
+
+ info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_262_0), info);
+ info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_262_1), info);
+}
+
+static DEVICE_STOP( ymf262 )
+{
+ ymf262_state *info = get_safe_token(device);
+ ymf262_shutdown(info->chip);
+}
+
+/* reset */
+static DEVICE_RESET( ymf262 )
+{
+ ymf262_state *info = get_safe_token(device);
+ ymf262_reset_chip(info->chip);
+}
+
+
+READ8_DEVICE_HANDLER( ymf262_r )
+{
+ ymf262_state *info = get_safe_token(device);
+ return ymf262_read(info->chip, offset & 3);
+}
+
+WRITE8_DEVICE_HANDLER( ymf262_w )
+{
+ ymf262_state *info = get_safe_token(device);
+ ymf262_write(info->chip, offset & 3, data);
+}
+
+READ8_DEVICE_HANDLER ( ymf262_status_r ) { return ymf262_r(device, 0); }
+WRITE8_DEVICE_HANDLER( ymf262_register_a_w ) { ymf262_w(device, 0, data); }
+WRITE8_DEVICE_HANDLER( ymf262_register_b_w ) { ymf262_w(device, 2, data); }
+WRITE8_DEVICE_HANDLER( ymf262_data_a_w ) { ymf262_w(device, 1, data); }
+WRITE8_DEVICE_HANDLER( ymf262_data_b_w ) { ymf262_w(device, 3, data); }
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+DEVICE_GET_INFO( ymf262 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ymf262_state); break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ymf262 ); break;
+ case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME( ymf262 ); break;
+ case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( ymf262 ); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "YMF262"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "Yamaha FM"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
+ }
+}
+
+
+DEFINE_LEGACY_SOUND_DEVICE(YMF262, ymf262);