diff options
Diffstat (limited to 'trunk/src/mame/audio/geebee.c')
-rw-r--r-- | trunk/src/mame/audio/geebee.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/trunk/src/mame/audio/geebee.c b/trunk/src/mame/audio/geebee.c new file mode 100644 index 00000000000..a4b45dab655 --- /dev/null +++ b/trunk/src/mame/audio/geebee.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * + * geebee.c + * + * sound driver + * juergen buchmueller <pullmoll@t-online.de>, jan 2000 + * + ****************************************************************************/ + +#include "emu.h" +#include "includes/warpwarp.h" + + +typedef struct _geebee_sound_state geebee_sound_state; +struct _geebee_sound_state +{ + emu_timer *m_volume_timer; + UINT16 *m_decay; + sound_stream *m_channel; + int m_sound_latch; + int m_sound_signal; + int m_volume; + int m_noise; + int m_vcount; +}; + +INLINE geebee_sound_state *get_safe_token(device_t *device) +{ + assert(device != NULL); + assert(device->type() == GEEBEE); + + return (geebee_sound_state *)downcast<legacy_device_base *>(device)->token(); +} + +static TIMER_CALLBACK( volume_decay ) +{ + geebee_sound_state *state = (geebee_sound_state *)ptr; + if( --state->m_volume < 0 ) + state->m_volume = 0; +} + +WRITE8_DEVICE_HANDLER( geebee_sound_w ) +{ + geebee_sound_state *state = get_safe_token(device); + + state->m_channel->update(); + state->m_sound_latch = data; + state->m_volume = 0x7fff; /* set volume */ + state->m_noise = 0x0000; /* reset noise shifter */ + /* faster decay enabled? */ + if( state->m_sound_latch & 8 ) + { + /* + * R24 is 10k, Rb is 0, C57 is 1uF + * charge time t1 = 0.693 * (R24 + Rb) * C57 -> 0.22176s + * discharge time t2 = 0.693 * (Rb) * C57 -> 0 + * Then C33 is only charged via D6 (1N914), not discharged! + * Decay: + * discharge C33 (1uF) through R50 (22k) -> 0.14058s + */ + attotime period = attotime::from_hz(32768) * 14058 / 100000; + state->m_volume_timer->adjust(period, 0, period); + } + else + { + /* + * discharge only after R49 (100k) in the amplifier section, + * so the volume shouldn't very fast and only when the signal + * is gated through 6N (4066). + * I can only guess here that the decay should be slower, + * maybe half as fast? + */ + attotime period = attotime::from_hz(32768) * 29060 / 100000; + state->m_volume_timer->adjust(period, 0, period); + } +} + +static STREAM_UPDATE( geebee_sound_update ) +{ + geebee_sound_state *state = get_safe_token(device); + stream_sample_t *buffer = outputs[0]; + + while (samples--) + { + *buffer++ = state->m_sound_signal; + /* 1V = HSYNC = 18.432MHz / 3 / 2 / 384 = 8000Hz */ + { + state->m_vcount++; + /* noise clocked with raising edge of 2V */ + if ((state->m_vcount & 3) == 2) + { + /* bit0 = bit0 ^ !bit10 */ + if ((state->m_noise & 1) == ((state->m_noise >> 10) & 1)) + state->m_noise = ((state->m_noise << 1) & 0xfffe) | 1; + else + state->m_noise = (state->m_noise << 1) & 0xfffe; + } + switch (state->m_sound_latch & 7) + { + case 0: /* 4V */ + state->m_sound_signal = (state->m_vcount & 0x04) ? state->m_decay[state->m_volume] : 0; + break; + case 1: /* 8V */ + state->m_sound_signal = (state->m_vcount & 0x08) ? state->m_decay[state->m_volume] : 0; + break; + case 2: /* 16V */ + state->m_sound_signal = (state->m_vcount & 0x10) ? state->m_decay[state->m_volume] : 0; + break; + case 3: /* 32V */ + state->m_sound_signal = (state->m_vcount & 0x20) ? state->m_decay[state->m_volume] : 0; + break; + case 4: /* TONE1 */ + state->m_sound_signal = !(state->m_vcount & 0x01) && !(state->m_vcount & 0x10) ? state->m_decay[state->m_volume] : 0; + break; + case 5: /* TONE2 */ + state->m_sound_signal = !(state->m_vcount & 0x02) && !(state->m_vcount & 0x20) ? state->m_decay[state->m_volume] : 0; + break; + case 6: /* TONE3 */ + state->m_sound_signal = !(state->m_vcount & 0x04) && !(state->m_vcount & 0x40) ? state->m_decay[state->m_volume] : 0; + break; + default: /* NOISE */ + /* QH of 74164 #4V */ + state->m_sound_signal = (state->m_noise & 0x8000) ? state->m_decay[state->m_volume] : 0; + } + } + } +} + +static DEVICE_START( geebee_sound ) +{ + geebee_sound_state *state = get_safe_token(device); + running_machine &machine = device->machine(); + int i; + + state->m_decay = auto_alloc_array(machine, UINT16, 32768); + + for( i = 0; i < 0x8000; i++ ) + state->m_decay[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096)); + + /* 1V = HSYNC = 18.432MHz / 3 / 2 / 384 = 8000Hz */ + state->m_channel = device->machine().sound().stream_alloc(*device, 0, 1, 18432000 / 3 / 2 / 384, NULL, geebee_sound_update); + state->m_vcount = 0; + + state->m_volume_timer = machine.scheduler().timer_alloc(FUNC(volume_decay), state); +} + +DEVICE_GET_INFO( geebee_sound ) +{ + switch (state) + { + case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(geebee_sound_state); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(geebee_sound); break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "Gee Bee Custom"); break; + case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; + } +} + + +DEFINE_LEGACY_SOUND_DEVICE(GEEBEE, geebee_sound); |