diff options
author | 2013-03-07 04:30:56 +0000 | |
---|---|---|
committer | 2013-03-07 04:30:56 +0000 | |
commit | 039aa6d9d75dc54ae07d4035420b96630b031509 (patch) | |
tree | 833ac7ef90d480249f4df425cdc48edcfb5a40c7 /src/mess/audio | |
parent | 6d31dcec5577bd1c98d76ae3c2ce3a44ab047d94 (diff) |
Modernized wswan, special, and svision devices. [Andrew Gardner]
Diffstat (limited to 'src/mess/audio')
-rw-r--r-- | src/mess/audio/special.c | 100 | ||||
-rw-r--r-- | src/mess/audio/svision.c | 357 | ||||
-rw-r--r-- | src/mess/audio/wswan.c | 391 |
3 files changed, 359 insertions, 489 deletions
diff --git a/src/mess/audio/special.c b/src/mess/audio/special.c index 5534bd743f1..8afb2c6a915 100644 --- a/src/mess/audio/special.c +++ b/src/mess/audio/special.c @@ -9,40 +9,54 @@ #include "includes/special.h" -struct specimx_sound_state -{ - sound_stream *mixer_channel; - int specimx_input[3]; -}; -static STREAM_UPDATE( specimx_sh_update ); +// device type definition +const device_type SPECIMX = &device_creator<specimx_sound_device>; + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// specimx_sound_device - constructor +//------------------------------------------------- -INLINE specimx_sound_state *get_safe_token(device_t *device) +specimx_sound_device::specimx_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SPECIMX, "Specialist MX Custom", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_mixer_channel(NULL) { - assert(device != NULL); - assert(device->type() == SPECIMX); - return (specimx_sound_state *)downcast<specimx_sound_device *>(device)->token(); + memset(m_specimx_input, 0, sizeof(int)*3); } -static DEVICE_START(specimx_sound) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void specimx_sound_device::device_start() { - specimx_sound_state *state = get_safe_token(device); - state->specimx_input[0] = state->specimx_input[1] = state->specimx_input[2] = 0; - state->mixer_channel = device->machine().sound().stream_alloc(*device, 0, 1, device->machine().sample_rate(), 0, specimx_sh_update); + m_specimx_input[0] = m_specimx_input[1] = m_specimx_input[2] = 0; + m_mixer_channel = stream_alloc(0, 1, machine().sample_rate()); } -static STREAM_UPDATE( specimx_sh_update ) + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void specimx_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - specimx_sound_state *state = get_safe_token(device); INT16 channel_0_signal; INT16 channel_1_signal; INT16 channel_2_signal; stream_sample_t *sample_left = outputs[0]; - channel_0_signal = state->specimx_input[0] ? 3000 : -3000; - channel_1_signal = state->specimx_input[1] ? 3000 : -3000; - channel_2_signal = state->specimx_input[2] ? 3000 : -3000; + channel_0_signal = m_specimx_input[0] ? 3000 : -3000; + channel_1_signal = m_specimx_input[1] ? 3000 : -3000; + channel_2_signal = m_specimx_input[2] ? 3000 : -3000; while (samples--) { @@ -61,50 +75,14 @@ static STREAM_UPDATE( specimx_sh_update ) } } -void specimx_set_input(device_t *device, int index, int state) -{ - specimx_sound_state *sndstate = get_safe_token(device); - if (sndstate->mixer_channel!=NULL) { - sndstate->mixer_channel->update(); - } - sndstate->specimx_input[index] = state; -} - -const device_type SPECIMX = &device_creator<specimx_sound_device>; - -specimx_sound_device::specimx_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, SPECIMX, "Specialist MX Custom", tag, owner, clock), - device_sound_interface(mconfig, *this) +void specimx_sound_device::set_input(int index, int state) { - m_token = global_alloc_clear(specimx_sound_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void specimx_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void specimx_sound_device::device_start() -{ - DEVICE_START_NAME( specimx_sound )(this); + if (m_mixer_channel!=NULL) + { + m_mixer_channel->update(); + } + m_specimx_input[index] = state; } -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- -void specimx_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); -} diff --git a/src/mess/audio/svision.c b/src/mess/audio/svision.c index fb811934e47..fa9673c63e7 100644 --- a/src/mess/audio/svision.c +++ b/src/mess/audio/svision.c @@ -7,176 +7,47 @@ #include "emu.h" #include "includes/svision.h" -enum SVISION_NOISE_Type -{ - SVISION_NOISE_Type7Bit, - SVISION_NOISE_Type14Bit -}; - -struct SVISION_NOISE -{ - UINT8 reg[3]; - int on, right, left, play; - SVISION_NOISE_Type type; - int state; - int volume; - int count; - double step, pos; - int value; // currently simple random function -}; - -struct SVISION_DMA -{ - UINT8 reg[5]; - int on, right, left; - int ca14to16; - int start,size; - double pos, step; - int finished; -}; -struct SVISION_CHANNEL -{ - UINT8 reg[4]; - int on; - int waveform, volume; - int pos; - int size; - int count; -}; +// device type definition +const device_type SVISION = &device_creator<svision_sound_device>; -struct svision_sound_state -{ - sound_stream *mixer_channel; - SVISION_DMA dma; - SVISION_NOISE noise; - SVISION_CHANNEL channel[2]; -}; +//************************************************************************** +// LIVE DEVICE +//************************************************************************** -INLINE svision_sound_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == SVISION); - return (svision_sound_state *)downcast<svision_sound_device *>(device)->token(); -} +//------------------------------------------------- +// svision_sound_device - constructor +//------------------------------------------------- -int *svision_dma_finished(device_t *device) +svision_sound_device::svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SVISION, "Super Vision Custom", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_mixer_channel(NULL) { - svision_sound_state *state = get_safe_token(device); - return &state->dma.finished; } -void svision_sound_decrement(device_t *device) -{ - svision_sound_state *state = get_safe_token(device); - if (state->channel[0].count > 0) - state->channel[0].count--; - if (state->channel[1].count > 0) - state->channel[1].count--; - if (state->noise.count > 0) - state->noise.count--; -} +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- -WRITE8_DEVICE_HANDLER( svision_sounddma_w ) +void svision_sound_device::device_start() { - svision_sound_state *state = get_safe_token(device); - logerror("%.6f svision snddma write %04x %02x\n", space.machine().time().as_double(),offset+0x18,data); - state->dma.reg[offset] = data; - switch (offset) - { - case 0: - case 1: - state->dma.start = (state->dma.reg[0] | (state->dma.reg[1] << 8)); - break; - case 2: - state->dma.size = (data ? data : 0x100) * 32; - break; - case 3: - state->dma.step = space.machine().device("maincpu")->unscaled_clock() / (256.0 * space.machine().sample_rate() * (1 + (data & 3))); - state->dma.right = data & 4; - state->dma.left = data & 8; - state->dma.ca14to16 = ((data & 0x70) >> 4) << 14; - break; - case 4: - state->dma.on = data & 0x80; - if (state->dma.on) - { - state->dma.pos = 0.0; - } - break; - } -} + memset(&m_dma, 0, sizeof(m_dma)); + memset(&m_noise, 0, sizeof(m_noise)); + memset(m_channel, 0, sizeof(m_channel)); -WRITE8_DEVICE_HANDLER( svision_noise_w ) -{ - svision_sound_state *state = get_safe_token(device); - // logerror("%.6f svision noise write %04x %02x\n",machine.time(),offset+0x28,data); - state->noise.reg[offset]=data; - switch (offset) - { - case 0: - state->noise.volume=data&0xf; - state->noise.step= space.machine().device("maincpu")->unscaled_clock() / (256.0*space.machine().sample_rate()*(1+(data>>4))); - break; - case 1: - state->noise.count = data + 1; - break; - case 2: - state->noise.type = (SVISION_NOISE_Type) (data & 1); - state->noise.play = data & 2; - state->noise.right = data & 4; - state->noise.left = data & 8; - state->noise.on = data & 0x10; /* honey bee start */ - state->noise.state = 1; - break; - } - state->noise.pos=0.0; + m_mixer_channel = stream_alloc(0, 2, machine().sample_rate()); } -void svision_soundport_w(device_t *device, int which, int offset, int data) -{ - svision_sound_state *state = get_safe_token(device); - SVISION_CHANNEL *channel = &state->channel[which]; - UINT16 size; - state->mixer_channel->update(); - channel->reg[offset] = data; - - switch (offset) - { - case 0: - case 1: - size = channel->reg[0] | ((channel->reg[1] & 7) << 8); - if (size) - { - // channel->size=(int)(device->machine().sample_rate()*(size<<5)/4e6); - channel->size= (int) (device->machine().sample_rate() * (size << 5) / device->machine().device("maincpu")->unscaled_clock()); - } - else - { - channel->size = 0; - } - channel->pos = 0; - break; - case 2: - channel->on = data & 0x40; - channel->waveform = (data & 0x30) >> 4; - channel->volume = data & 0xf; - break; - case 3: - channel->count = data + 1; - break; - } -} +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- -/************************************/ -/* Sound handler update */ -/************************************/ -static STREAM_UPDATE( svision_update ) +void svision_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - svision_sound_state *state = get_safe_token(device); stream_sample_t *left=outputs[0], *right=outputs[1]; int i, j; SVISION_CHANNEL *channel; @@ -185,7 +56,7 @@ static STREAM_UPDATE( svision_update ) { *left = 0; *right = 0; - for (channel=state->channel, j=0; j<ARRAY_LENGTH(state->channel); j++, channel++) + for (channel=m_channel, j=0; j<ARRAY_LENGTH(m_channel); j++, channel++) { if (channel->size != 0) { @@ -221,117 +92,175 @@ static STREAM_UPDATE( svision_update ) channel->pos = 0; } } - if (state->noise.on && (state->noise.play || state->noise.count)) + if (m_noise.on && (m_noise.play || m_noise.count)) { - INT16 s = (state->noise.value ? 1 << 8: 0) * state->noise.volume; + INT16 s = (m_noise.value ? 1 << 8: 0) * m_noise.volume; int b1, b2; - if (state->noise.left) + if (m_noise.left) *left += s; - if (state->noise.right) + if (m_noise.right) *right += s; - state->noise.pos += state->noise.step; - if (state->noise.pos >= 1.0) + m_noise.pos += m_noise.step; + if (m_noise.pos >= 1.0) { - switch (state->noise.type) + switch (m_noise.type) { case SVISION_NOISE_Type7Bit: - state->noise.value = state->noise.state & 0x40 ? 1 : 0; - b1 = (state->noise.state & 0x40) != 0; - b2 = (state->noise.state & 0x20) != 0; - state->noise.state=(state->noise.state<<1)+(b1!=b2?1:0); + m_noise.value = m_noise.state & 0x40 ? 1 : 0; + b1 = (m_noise.state & 0x40) != 0; + b2 = (m_noise.state & 0x20) != 0; + m_noise.state=(m_noise.state<<1)+(b1!=b2?1:0); break; case SVISION_NOISE_Type14Bit: default: - state->noise.value = state->noise.state & 0x2000 ? 1 : 0; - b1 = (state->noise.state & 0x2000) != 0; - b2 = (state->noise.state & 0x1000) != 0; - state->noise.state = (state->noise.state << 1) + (b1 != b2 ? 1 : 0); + m_noise.value = m_noise.state & 0x2000 ? 1 : 0; + b1 = (m_noise.state & 0x2000) != 0; + b2 = (m_noise.state & 0x1000) != 0; + m_noise.state = (m_noise.state << 1) + (b1 != b2 ? 1 : 0); } - state->noise.pos -= 1; + m_noise.pos -= 1; } } - if (state->dma.on) + if (m_dma.on) { UINT8 sample; INT16 s; - UINT16 addr = state->dma.start + (unsigned) state->dma.pos / 2; + UINT16 addr = m_dma.start + (unsigned) m_dma.pos / 2; if (addr >= 0x8000 && addr < 0xc000) { - sample = device->machine().root_device().memregion("user1")->base()[(addr & 0x3fff) | state->dma.ca14to16]; + sample = machine().root_device().memregion("user1")->base()[(addr & 0x3fff) | m_dma.ca14to16]; } else { - sample = device->machine().device("maincpu")->memory().space(AS_PROGRAM).read_byte(addr); + sample = machine().device("maincpu")->memory().space(AS_PROGRAM).read_byte(addr); } - if (((unsigned)state->dma.pos) & 1) + if (((unsigned)m_dma.pos) & 1) s = (sample & 0xf); else s = (sample & 0xf0) >> 4; s <<= 8; - if (state->dma.left) + if (m_dma.left) *left += s; - if (state->dma.right) + if (m_dma.right) *right += s; - state->dma.pos += state->dma.step; - if (state->dma.pos >= state->dma.size) + m_dma.pos += m_dma.step; + if (m_dma.pos >= m_dma.size) { - svision_state *sv_state = device->machine().driver_data<svision_state>(); - state->dma.finished = TRUE; - state->dma.on = FALSE; + svision_state *sv_state = machine().driver_data<svision_state>(); + m_dma.finished = TRUE; + m_dma.on = FALSE; sv_state->svision_irq(); } } } } -/************************************/ -/* Sound handler start */ -/************************************/ -static DEVICE_START( svision_sound ) +WRITE8_MEMBER( svision_sound_device::svision_sounddma_w ) { - svision_sound_state *state = get_safe_token(device); - memset(&state->dma, 0, sizeof(state->dma)); - memset(&state->noise, 0, sizeof(state->noise)); - memset(state->channel, 0, sizeof(state->channel)); - - state->mixer_channel = device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), 0, svision_update); + logerror("%.6f svision snddma write %04x %02x\n", space.machine().time().as_double(),offset+0x18,data); + m_dma.reg[offset] = data; + switch (offset) + { + case 0: + case 1: + m_dma.start = (m_dma.reg[0] | (m_dma.reg[1] << 8)); + break; + case 2: + m_dma.size = (data ? data : 0x100) * 32; + break; + case 3: + m_dma.step = space.machine().device("maincpu")->unscaled_clock() / (256.0 * space.machine().sample_rate() * (1 + (data & 3))); + m_dma.right = data & 4; + m_dma.left = data & 8; + m_dma.ca14to16 = ((data & 0x70) >> 4) << 14; + break; + case 4: + m_dma.on = data & 0x80; + if (m_dma.on) + { + m_dma.pos = 0.0; + } + break; + } } -const device_type SVISION = &device_creator<svision_sound_device>; -svision_sound_device::svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, SVISION, "Super Vision Custom", tag, owner, clock), - device_sound_interface(mconfig, *this) +WRITE8_MEMBER( svision_sound_device::svision_noise_w ) { - m_token = global_alloc_clear(svision_sound_state); + // logerror("%.6f svision noise write %04x %02x\n",machine.time(),offset+0x28,data); + m_noise.reg[offset]=data; + switch (offset) + { + case 0: + m_noise.volume=data&0xf; + m_noise.step= space.machine().device("maincpu")->unscaled_clock() / (256.0*space.machine().sample_rate()*(1+(data>>4))); + break; + case 1: + m_noise.count = data + 1; + break; + case 2: + m_noise.type = (SVISION_NOISE_Type) (data & 1); + m_noise.play = data & 2; + m_noise.right = data & 4; + m_noise.left = data & 8; + m_noise.on = data & 0x10; /* honey bee start */ + m_noise.state = 1; + break; + } + m_noise.pos=0.0; } -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- -void svision_sound_device::device_config_complete() +int *svision_sound_device::dma_finished() { + return &m_dma.finished; } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- -void svision_sound_device::device_start() +void svision_sound_device::sound_decrement() { - DEVICE_START_NAME( svision_sound )(this); + if (m_channel[0].count > 0) + m_channel[0].count--; + if (m_channel[1].count > 0) + m_channel[1].count--; + if (m_noise.count > 0) + m_noise.count--; } -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- -void svision_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void svision_sound_device::soundport_w(int which, int offset, int data) { - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); + SVISION_CHANNEL *channel = &m_channel[which]; + UINT16 size; + + m_mixer_channel->update(); + channel->reg[offset] = data; + + switch (offset) + { + case 0: + case 1: + size = channel->reg[0] | ((channel->reg[1] & 7) << 8); + if (size) + { + // channel->size=(int)(device->machine().sample_rate()*(size<<5)/4e6); + channel->size= (int) (machine().sample_rate() * (size << 5) / machine().device("maincpu")->unscaled_clock()); + } + else + { + channel->size = 0; + } + channel->pos = 0; + break; + case 2: + channel->on = data & 0x40; + channel->waveform = (data & 0x30) >> 4; + channel->volume = data & 0xf; + break; + case 3: + channel->count = data + 1; + break; + } } + diff --git a/src/mess/audio/wswan.c b/src/mess/audio/wswan.c index 8bbc7f647d6..b3cdbf33181 100644 --- a/src/mess/audio/wswan.c +++ b/src/mess/audio/wswan.c @@ -11,277 +11,240 @@ #include "includes/wswan.h" -struct CHAN { - UINT16 freq; /* frequency */ - UINT32 period; /* period */ - UINT32 pos; /* position */ - UINT8 vol_left; /* volume left */ - UINT8 vol_right; /* volume right */ - UINT8 on; /* on/off */ - INT8 signal; /* signal */ -}; +// device type definition +const device_type WSWAN = &device_creator<wswan_sound_device>; + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// wswan_sound_device - constructor +//------------------------------------------------- + +wswan_sound_device::wswan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, WSWAN, "WonderSwan Custom", tag, owner, clock), + device_sound_interface(mconfig, *this), + m_channel(NULL), + m_sweep_step(0), + m_sweep_time(0), + m_sweep_count(0), + m_noise_type(0), + m_noise_reset(0), + m_noise_enable(0), + m_sample_address(0), + m_audio2_voice(0), + m_audio3_sweep(0), + m_audio4_noise(0), + m_mono(0), + m_voice_data(0), + m_output_volume(0), + m_external_stereo(0), + m_external_speaker(0), + m_noise_shift(0), + m_master_volume(0) +{ +} -struct wswan_sound_state { - sound_stream *channel; - struct CHAN audio1; /* Audio channel 1 */ - struct CHAN audio2; /* Audio channel 2 */ - struct CHAN audio3; /* Audio channel 3 */ - struct CHAN audio4; /* Audio channel 4 */ - INT8 sweep_step; /* Sweep step */ - UINT32 sweep_time; /* Sweep time */ - UINT32 sweep_count; /* Sweep counter */ - UINT8 noise_type; /* Noise generator type */ - UINT8 noise_reset; /* Noise reset */ - UINT8 noise_enable; /* Noise enable */ - UINT16 sample_address; /* Sample address */ - UINT8 audio2_voice; /* Audio 2 voice */ - UINT8 audio3_sweep; /* Audio 3 sweep */ - UINT8 audio4_noise; /* Audio 4 noise */ - UINT8 mono; /* mono */ - UINT8 voice_data; /* voice data */ - UINT8 output_volume; /* output volume */ - UINT8 external_stereo; /* external stereo */ - UINT8 external_speaker; /* external speaker */ - UINT16 noise_shift; /* Noise counter shift register */ - UINT8 master_volume; /* Master volume */ -}; +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- -INLINE wswan_sound_state *get_safe_token(device_t *device) +void wswan_sound_device::device_start() { - assert(device != NULL); - assert(device->type() == WSWAN); - return (wswan_sound_state *)downcast<wswan_sound_device *>(device)->token(); + m_channel = stream_alloc(0, 2, machine().sample_rate()); + + m_audio1.on = 0; + m_audio1.signal = 16; + m_audio1.pos = 0; + m_audio2.on = 0; + m_audio2.signal = 16; + m_audio2.pos = 0; + m_audio3.on = 0; + m_audio3.signal = 16; + m_audio3.pos = 0; + m_audio4.on = 0; + m_audio4.signal = 16; + m_audio4.pos = 0; +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void wswan_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + stream_sample_t sample, left, right; + + while( samples-- > 0 ) + { + left = right = 0; + + if ( m_audio1.on ) { + sample = m_audio1.signal; + m_audio1.pos++; + if ( m_audio1.pos >= m_audio1.period / 2 ) { + m_audio1.pos = 0; + m_audio1.signal = -m_audio1.signal; + } + left += m_audio1.vol_left * sample; + right += m_audio1.vol_right * sample; + } + + if ( m_audio2.on ) { + if ( m_audio2_voice ) { + left += (m_voice_data - 128)*(m_master_volume & 0x0f); + right += (m_voice_data - 128)*(m_master_volume & 0x0f); + } else { + sample = m_audio2.signal; + m_audio2.pos++; + if ( m_audio2.pos >= m_audio2.period / 2 ) { + m_audio2.pos = 0; + m_audio2.signal = -m_audio2.signal; + } + left += m_audio2.vol_left * sample; + right += m_audio2.vol_right * sample; + } + } + + if ( m_audio3.on ) { + sample = m_audio3.signal; + m_audio3.pos++; + if ( m_audio3.pos >= m_audio3.period / 2 ) { + m_audio3.pos = 0; + m_audio3.signal = -m_audio3.signal; + } + if ( m_audio3_sweep && m_sweep_time ) { + m_sweep_count++; + if ( m_sweep_count >= m_sweep_time ) { + m_sweep_count = 0; + m_audio3.freq += m_sweep_step; + m_audio3.period = machine().sample_rate() / (3072000 / ((2048 - (m_audio3.freq & 0x7ff)) << 5)); + } + } + left += m_audio3.vol_left * sample; + right += m_audio3.vol_right * sample; + } + + if ( m_audio4.on ) { + if ( m_audio4_noise ) { + sample = 0; + } else { + sample = m_audio4.signal; + m_audio4.pos++; + if ( m_audio4.pos >= m_audio4.period / 2 ) { + m_audio4.pos = 0; + m_audio4.signal = -m_audio4.signal; + } + } + left += m_audio4.vol_left * sample; + right += m_audio4.vol_right * sample; + } + + left <<= 5; + right <<= 5; + + *(outputs[0]++) = left; + *(outputs[1]++) = right; + } } -static void wswan_ch_set_freq( running_machine &machine, struct CHAN *ch, UINT16 freq ) + +void wswan_sound_device::wswan_ch_set_freq( CHAN *ch, UINT16 freq ) { freq &= 0x7ff; // docs say freq is 11bits and a few games (Morita Shougi, World Stadium + others) write 0x800 causing a divide by 0 crash ch->freq = freq; - ch->period = machine.sample_rate() / (3072000 / ((2048 - freq) << 5)); + ch->period = machine().sample_rate() / (3072000 / ((2048 - freq) << 5)); } -WRITE8_DEVICE_HANDLER( wswan_sound_port_w ) +WRITE8_MEMBER( wswan_sound_device::wswan_sound_port_w ) { - wswan_sound_state *state = get_safe_token(device); - - state->channel->update(); + m_channel->update(); switch( offset ) { case 0x80: /* Audio 1 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio1, (state->audio1.freq & 0xff00) | data); + wswan_ch_set_freq(&m_audio1, (m_audio1.freq & 0xff00) | data); break; case 0x81: /* Audio 1 freq (hi) */ - wswan_ch_set_freq(space.machine(), &state->audio1, (data << 8 ) | (state->audio1.freq & 0x00ff)); + wswan_ch_set_freq(&m_audio1, (data << 8 ) | (m_audio1.freq & 0x00ff)); break; case 0x82: /* Audio 2 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio2, (state->audio2.freq & 0xff00) | data); + wswan_ch_set_freq(&m_audio2, (m_audio2.freq & 0xff00) | data); break; case 0x83: /* Audio 2 freq (hi) */ - wswan_ch_set_freq(space.machine(), &state->audio2, (data << 8 ) | (state->audio2.freq & 0x00ff)); + wswan_ch_set_freq(&m_audio2, (data << 8 ) | (m_audio2.freq & 0x00ff)); break; case 0x84: /* Audio 3 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio3, (state->audio3.freq & 0xff00) | data); + wswan_ch_set_freq(&m_audio3, (m_audio3.freq & 0xff00) | data); break; case 0x85: /* Audio 3 freq (hi) */ - wswan_ch_set_freq(space.machine(), &state->audio3, (data << 8) | (state->audio3.freq & 0x00ff)); + wswan_ch_set_freq(&m_audio3, (data << 8) | (m_audio3.freq & 0x00ff)); break; case 0x86: /* Audio 4 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio4, (state->audio4.freq & 0xff00) | data); + wswan_ch_set_freq(&m_audio4, (m_audio4.freq & 0xff00) | data); break; case 0x87: /* Audio 4 freq (hi) */ - wswan_ch_set_freq(space.machine(), &state->audio4, (data << 8) | (state->audio4.freq & 0x00ff)); + wswan_ch_set_freq(&m_audio4, (data << 8) | (m_audio4.freq & 0x00ff)); break; case 0x88: /* Audio 1 volume */ - state->audio1.vol_left = ( data & 0xF0 ) >> 4; - state->audio1.vol_right = data & 0x0F; + m_audio1.vol_left = ( data & 0xF0 ) >> 4; + m_audio1.vol_right = data & 0x0F; break; case 0x89: /* Audio 2 volume */ - state->voice_data = data; - state->audio2.vol_left = ( data & 0xF0 ) >> 4; - state->audio2.vol_right = data & 0x0F; + m_voice_data = data; + m_audio2.vol_left = ( data & 0xF0 ) >> 4; + m_audio2.vol_right = data & 0x0F; break; case 0x8A: /* Audio 3 volume */ - state->audio3.vol_left = ( data & 0xF0 ) >> 4; - state->audio3.vol_right = data & 0x0F; + m_audio3.vol_left = ( data & 0xF0 ) >> 4; + m_audio3.vol_right = data & 0x0F; break; case 0x8B: /* Audio 4 volume */ - state->audio4.vol_left = ( data & 0xF0 ) >> 4; - state->audio4.vol_right = data & 0x0F; + m_audio4.vol_left = ( data & 0xF0 ) >> 4; + m_audio4.vol_right = data & 0x0F; break; case 0x8C: /* Sweep step */ - state->sweep_step = (INT8)data; + m_sweep_step = (INT8)data; break; case 0x8D: /* Sweep time */ - state->sweep_time = space.machine().sample_rate() / ( 3072000 / ( 8192 * (data + 1) ) ); + m_sweep_time = space.machine().sample_rate() / ( 3072000 / ( 8192 * (data + 1) ) ); break; case 0x8E: /* Noise control */ - state->noise_type = data & 0x07; - state->noise_reset = ( data & 0x08 ) >> 3; - state->noise_enable = ( data & 0x10 ) >> 4; + m_noise_type = data & 0x07; + m_noise_reset = ( data & 0x08 ) >> 3; + m_noise_enable = ( data & 0x10 ) >> 4; break; case 0x8F: /* Sample location */ - state->sample_address = data << 6; + m_sample_address = data << 6; break; case 0x90: /* Audio control */ - state->audio1.on = data & 0x01; - state->audio2.on = ( data & 0x02 ) >> 1; - state->audio3.on = ( data & 0x04 ) >> 2; - state->audio4.on = ( data & 0x08 ) >> 3; - state->audio2_voice = ( data & 0x20 ) >> 5; - state->audio3_sweep = ( data & 0x40 ) >> 6; - state->audio4_noise = ( data & 0x80 ) >> 7; + m_audio1.on = data & 0x01; + m_audio2.on = ( data & 0x02 ) >> 1; + m_audio3.on = ( data & 0x04 ) >> 2; + m_audio4.on = ( data & 0x08 ) >> 3; + m_audio2_voice = ( data & 0x20 ) >> 5; + m_audio3_sweep = ( data & 0x40 ) >> 6; + m_audio4_noise = ( data & 0x80 ) >> 7; break; case 0x91: /* Audio output */ - state->mono = data & 0x01; - state->output_volume = ( data & 0x06 ) >> 1; - state->external_stereo = ( data & 0x08 ) >> 3; - state->external_speaker = 1; + m_mono = data & 0x01; + m_output_volume = ( data & 0x06 ) >> 1; + m_external_stereo = ( data & 0x08 ) >> 3; + m_external_speaker = 1; break; case 0x92: /* Noise counter shift register (lo) */ - state->noise_shift = ( state->noise_shift & 0xFF00 ) | data; + m_noise_shift = ( m_noise_shift & 0xFF00 ) | data; break; case 0x93: /* Noise counter shift register (hi) */ - state->noise_shift = ( data << 8 ) | ( state->noise_shift & 0x00FF ); + m_noise_shift = ( data << 8 ) | ( m_noise_shift & 0x00FF ); break; case 0x94: /* Master volume */ - state->master_volume = data; + m_master_volume = data; break; } } -static STREAM_UPDATE( wswan_sh_update ) -{ - wswan_sound_state *state = get_safe_token(device); - stream_sample_t sample, left, right; - while( samples-- > 0 ) - { - left = right = 0; - - if ( state->audio1.on ) { - sample = state->audio1.signal; - state->audio1.pos++; - if ( state->audio1.pos >= state->audio1.period / 2 ) { - state->audio1.pos = 0; - state->audio1.signal = -state->audio1.signal; - } - left += state->audio1.vol_left * sample; - right += state->audio1.vol_right * sample; - } - - if ( state->audio2.on ) { - if ( state->audio2_voice ) { - left += (state->voice_data - 128)*(state->master_volume & 0x0f); - right += (state->voice_data - 128)*(state->master_volume & 0x0f); - } else { - sample = state->audio2.signal; - state->audio2.pos++; - if ( state->audio2.pos >= state->audio2.period / 2 ) { - state->audio2.pos = 0; - state->audio2.signal = -state->audio2.signal; - } - left += state->audio2.vol_left * sample; - right += state->audio2.vol_right * sample; - } - } - - if ( state->audio3.on ) { - sample = state->audio3.signal; - state->audio3.pos++; - if ( state->audio3.pos >= state->audio3.period / 2 ) { - state->audio3.pos = 0; - state->audio3.signal = -state->audio3.signal; - } - if ( state->audio3_sweep && state->sweep_time ) { - state->sweep_count++; - if ( state->sweep_count >= state->sweep_time ) { - state->sweep_count = 0; - state->audio3.freq += state->sweep_step; - state->audio3.period = device->machine().sample_rate() / (3072000 / ((2048 - (state->audio3.freq & 0x7ff)) << 5)); - } - } - left += state->audio3.vol_left * sample; - right += state->audio3.vol_right * sample; - } - - if ( state->audio4.on ) { - if ( state->audio4_noise ) { - sample = 0; - } else { - sample = state->audio4.signal; - state->audio4.pos++; - if ( state->audio4.pos >= state->audio4.period / 2 ) { - state->audio4.pos = 0; - state->audio4.signal = -state->audio4.signal; - } - } - left += state->audio4.vol_left * sample; - right += state->audio4.vol_right * sample; - } - - left <<= 5; - right <<= 5; - - *(outputs[0]++) = left; - *(outputs[1]++) = right; - } -} - -static DEVICE_START(wswan_sound) -{ - wswan_sound_state *state = get_safe_token(device); - state->channel = device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), 0, wswan_sh_update); - - state->audio1.on = 0; - state->audio1.signal = 16; - state->audio1.pos = 0; - state->audio2.on = 0; - state->audio2.signal = 16; - state->audio2.pos = 0; - state->audio3.on = 0; - state->audio3.signal = 16; - state->audio3.pos = 0; - state->audio4.on = 0; - state->audio4.signal = 16; - state->audio4.pos = 0; -} - - -const device_type WSWAN = &device_creator<wswan_sound_device>; - -wswan_sound_device::wswan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, WSWAN, "WonderSwan Custom", tag, owner, clock), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(wswan_sound_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void wswan_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void wswan_sound_device::device_start() -{ - DEVICE_START_NAME( wswan_sound )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void wswan_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); -} |