diff options
Diffstat (limited to 'trunk/src/emu/sound/k056800.c')
-rw-r--r-- | trunk/src/emu/sound/k056800.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/trunk/src/emu/sound/k056800.c b/trunk/src/emu/sound/k056800.c new file mode 100644 index 00000000000..6103f2f3208 --- /dev/null +++ b/trunk/src/emu/sound/k056800.c @@ -0,0 +1,177 @@ +/*********************************************************************** + + Konami K056800 (MIRAC) + Sound interface + + +***********************************************************************/ + +#include "emu.h" +#include "sound/k056800.h" + +typedef struct _k056800_state k056800_state; +struct _k056800_state +{ + UINT8 host_reg[8]; + UINT8 sound_reg[8]; + + emu_timer *sound_cpu_timer; + UINT8 sound_cpu_irq1_enable; + k056800_irq_cb irq_cb; +}; + +/***************************************************************************** + INLINE FUNCTIONS +*****************************************************************************/ + +INLINE k056800_state *k056800_get_safe_token( device_t *device ) +{ + assert(device != NULL); + assert(device->type() == K056800); + + return (k056800_state *)downcast<legacy_device_base *>(device)->token(); +} + +INLINE const k056800_interface *k056800_get_interface( device_t *device ) +{ + assert(device != NULL); + assert((device->type() == K056800)); + return (const k056800_interface *) device->static_config(); +} + +/***************************************************************************** + DEVICE HANDLERS +*****************************************************************************/ + + +static UINT8 k056800_host_reg_r( device_t *device, int reg ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + UINT8 value = k056800->host_reg[reg]; + if (reg == 2) + value &= ~3; // suppress VOLWR busy flags + + return value; +} + +static void k056800_host_reg_w( device_t *device, int reg, UINT8 data ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + + k056800->sound_reg[reg] = data; + + if (reg == 7) + k056800->irq_cb(device->machine(), 1); +} + +static UINT8 k056800_sound_reg_r( device_t *device, int reg ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + return k056800->sound_reg[reg]; +} + +static void k056800_sound_reg_w( device_t *device, int reg, UINT8 data ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + + if (reg == 4) + k056800->sound_cpu_irq1_enable = data & 0x01; + + k056800->host_reg[reg] = data; +} + +static TIMER_CALLBACK( k056800_sound_cpu_timer_tick ) +{ + k056800_state *k056800 = (k056800_state *)ptr; + + if (k056800->sound_cpu_irq1_enable) + k056800->irq_cb(machine, 0); +} + +READ32_DEVICE_HANDLER( k056800_host_r ) +{ + UINT32 r = 0; + + if (ACCESSING_BITS_24_31) + r |= k056800_host_reg_r(device, (offset * 4) + 0) << 24; + + if (ACCESSING_BITS_16_23) + r |= k056800_host_reg_r(device, (offset * 4) + 1) << 16; + + if (ACCESSING_BITS_8_15) + r |= k056800_host_reg_r(device, (offset * 4) + 2) << 8; + + if (ACCESSING_BITS_0_7) + r |= k056800_host_reg_r(device, (offset * 4) + 3) << 0; + + + return r; +} + +WRITE32_DEVICE_HANDLER( k056800_host_w ) +{ + if (ACCESSING_BITS_24_31) + k056800_host_reg_w(device, (offset * 4) + 0, (data >> 24) & 0xff); + + if (ACCESSING_BITS_16_23) + k056800_host_reg_w(device, (offset * 4) + 1, (data >> 16) & 0xff); + + if (ACCESSING_BITS_8_15) + k056800_host_reg_w(device, (offset * 4) + 2, (data >> 8) & 0xff); + + if (ACCESSING_BITS_0_7) + k056800_host_reg_w(device, (offset * 4) + 3, (data >> 0) & 0xff); + +} + +READ16_DEVICE_HANDLER( k056800_sound_r ) +{ + return k056800_sound_reg_r(device, offset); +} + +WRITE16_DEVICE_HANDLER( k056800_sound_w ) +{ + k056800_sound_reg_w(device, offset, data); +} + +/***************************************************************************** + DEVICE INTERFACE +*****************************************************************************/ + +static DEVICE_START( k056800 ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + const k056800_interface *intf = k056800_get_interface(device); + attotime timer_period = attotime::from_hz(44100) * 128; // roughly 2.9us + + k056800->irq_cb = intf->irq_cb; + + k056800->sound_cpu_timer = device->machine().scheduler().timer_alloc(FUNC(k056800_sound_cpu_timer_tick), k056800); + k056800->sound_cpu_timer->adjust(timer_period, 0, timer_period); + + device->save_item(NAME(k056800->host_reg)); + device->save_item(NAME(k056800->sound_reg)); + device->save_item(NAME(k056800->sound_cpu_irq1_enable)); +} + +static DEVICE_RESET( k056800 ) +{ + k056800_state *k056800 = k056800_get_safe_token(device); + + memset(k056800->host_reg, 0, sizeof(k056800->host_reg)); + memset(k056800->sound_reg, 0, sizeof(k056800->sound_reg)); + + k056800->sound_cpu_irq1_enable = 0; +} + + +static const char DEVTEMPLATE_SOURCE[] = __FILE__; + +#define DEVTEMPLATE_ID( p, s ) p##k056800##s +#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET +#define DEVTEMPLATE_NAME "Konami 056800 MIRAC" +#define DEVTEMPLATE_FAMILY "Konami custom" +#include "devtempl.h" + + +DEFINE_LEGACY_DEVICE(K056800, k056800); |