diff options
Diffstat (limited to 'src/emu/sound/st0016.c')
-rw-r--r-- | src/emu/sound/st0016.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/emu/sound/st0016.c b/src/emu/sound/st0016.c new file mode 100644 index 00000000000..c1c121fa5f3 --- /dev/null +++ b/src/emu/sound/st0016.c @@ -0,0 +1,180 @@ +/************************************ + Seta custom ST-0016 chip + sound emulation by R. Belmont, Tomasz Slanina, and David Haywood +************************************/ + +#include <math.h> +#include "sndintrf.h" +#include "streams.h" +#include "cpuintrf.h" +#include "st0016.h" + +#define VERBOSE (0) + +UINT8 *st0016_sound_regs; + +struct st0016_info +{ + sound_stream * stream; + UINT8 **sound_ram; + int vpos[8], frac[8], lponce[8]; +}; + +WRITE8_HANDLER(st0016_snd_w) +{ + struct st0016_info *info = sndti_token(SOUND_ST0016, 0); + int voice = offset/32; + int reg = offset & 0x1f; + int oldreg = st0016_sound_regs[offset]; +#if VERBOSE + int vbase = offset & ~0x1f; +#endif + + st0016_sound_regs[offset] = data; + + if ((voice < 8) && (data != oldreg)) + { + if ((reg == 0x16) && (data != 0)) + { + info->vpos[voice] = info->frac[voice] = info->lponce[voice] = 0; + +#if VERBOSE + logerror("Key on V%02d: st %06x-%06x lp %06x-%06x frq %x flg %x\n", voice, + st0016_sound_regs[vbase+2]<<16 | st0016_sound_regs[vbase+1]<<8 | st0016_sound_regs[vbase+2], + st0016_sound_regs[vbase+0xe]<<16 | st0016_sound_regs[vbase+0xd]<<8 | st0016_sound_regs[vbase+0xc], + st0016_sound_regs[vbase+6]<<16 | st0016_sound_regs[vbase+5]<<8 | st0016_sound_regs[vbase+4], + st0016_sound_regs[vbase+0xa]<<16 | st0016_sound_regs[vbase+0x9]<<8 | st0016_sound_regs[vbase+0x8], + st0016_sound_regs[vbase+0x11]<<8 | st0016_sound_regs[vbase+0x10], + st0016_sound_regs[vbase+0x16]); +#endif + } + } +} + +static void st0016_update(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int length) +{ + struct st0016_info *info = param; + UINT8 *sound_ram = *info->sound_ram; + int v, i, snum; + unsigned char *slot; + INT32 mix[48000*2]; + INT32 *mixp; + INT16 sample; + int sptr, eptr, freq, lsptr, leptr; + + memset(mix, 0, sizeof(mix[0])*length*2); + + for (v = 0; v < 8; v++) + { + slot = (unsigned char *)&st0016_sound_regs[v * 32]; + + if (slot[0x16] & 0x06) + { + mixp = &mix[0]; + + sptr = slot[0x02]<<16 | slot[0x01]<<8 | slot[0x00]; + eptr = slot[0x0e]<<16 | slot[0x0d]<<8 | slot[0x0c]; + freq = slot[0x11]<<8 | slot[0x10]; + lsptr = slot[0x06]<<16 | slot[0x05]<<8 | slot[0x04]; + leptr = slot[0x0a]<<16 | slot[0x09]<<8 | slot[0x08]; + + for (snum = 0; snum < length; snum++) + { + sample = sound_ram[(sptr + info->vpos[v])&0x1fffff]<<8; + + *mixp++ += (sample * (char)slot[0x14]) >> 8; + *mixp++ += (sample * (char)slot[0x15]) >> 8; + + info->frac[v] += freq; + info->vpos[v] += (info->frac[v]>>16); + info->frac[v] &= 0xffff; + + // stop if we're at the end + if (info->lponce[v]) + { + // we've looped once, check loop end rather than sample end + if ((info->vpos[v] + sptr) >= leptr) + { + info->vpos[v] = (lsptr - sptr); + } + } + else + { + // not looped yet, check sample end + if ((info->vpos[v] + sptr) >= eptr) + { + if (slot[0x16] & 0x01) // loop? + { + info->vpos[v] = (lsptr - sptr); + info->lponce[v] = 1; + } + else + { + slot[0x16] = 0; + info->vpos[v] = info->frac[v] = 0; + } + } + } + } + } + } + + mixp = &mix[0]; + for (i = 0; i < length; i++) + { + outputs[0][i] = (*mixp++)>>4; + outputs[1][i] = (*mixp++)>>4; + } +} + +static void *st0016_start(int sndindex, int clock, const void *config) +{ + const struct ST0016interface *intf = config; + struct st0016_info *info; + + info = auto_malloc(sizeof(*info)); + memset(info, 0, sizeof(*info)); + + info->sound_ram = intf->p_soundram; + + info->stream = stream_create(0, 2, 44100, info, st0016_update); + + return info; +} + + + +/************************************************************************** + * Generic get_info + **************************************************************************/ + +static void st0016_set_info(void *token, UINT32 state, sndinfo *info) +{ + switch (state) + { + /* no parameters to set */ + } +} + + +void st0016_get_info(void *token, UINT32 state, sndinfo *info) +{ + switch (state) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case SNDINFO_PTR_SET_INFO: info->set_info = st0016_set_info; break; + case SNDINFO_PTR_START: info->start = st0016_start; break; + case SNDINFO_PTR_STOP: /* Nothing */ break; + case SNDINFO_PTR_RESET: /* Nothing */ break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case SNDINFO_STR_NAME: info->s = "ST0016"; break; + case SNDINFO_STR_CORE_FAMILY: info->s = "Seta custom"; break; + case SNDINFO_STR_CORE_VERSION: info->s = "1.0"; break; + case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break; + case SNDINFO_STR_CORE_CREDITS: info->s = "Copyright (c) 2004, The MAME Team"; break; + } +} + |