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; -INLINE specimx_sound_state *get_safe_token(device_t *device) + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// specimx_sound_device - constructor +//------------------------------------------------- + +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(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) + +void specimx_sound_device::set_input(int index, int state) { - specimx_sound_state *sndstate = get_safe_token(device); - if (sndstate->mixer_channel!=NULL) { - sndstate->mixer_channel->update(); + if (m_mixer_channel!=NULL) + { + m_mixer_channel->update(); } - sndstate->specimx_input[index] = state; + m_specimx_input[index] = state; } -const device_type SPECIMX = &device_creator; - -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_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); -} - -//------------------------------------------------- -// 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; -}; - -struct svision_sound_state -{ - sound_stream *mixer_channel; - SVISION_DMA dma; - SVISION_NOISE noise; - SVISION_CHANNEL channel[2]; -}; +// device type definition +const device_type SVISION = &device_creator; -INLINE svision_sound_state *get_safe_token(device_t *device) +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// svision_sound_device - constructor +//------------------------------------------------- + +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) { - assert(device != NULL); - assert(device->type() == SVISION); - return (svision_sound_state *)downcast(device)->token(); } -int *svision_dma_finished(device_t *device) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void svision_sound_device::device_start() { - svision_sound_state *state = get_safe_token(device); - return &state->dma.finished; + memset(&m_dma, 0, sizeof(m_dma)); + memset(&m_noise, 0, sizeof(m_noise)); + memset(m_channel, 0, sizeof(m_channel)); + + m_mixer_channel = stream_alloc(0, 2, machine().sample_rate()); } -void svision_sound_decrement(device_t *device) + +//------------------------------------------------- +// 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) { - 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--; -} - -WRITE8_DEVICE_HANDLER( svision_sounddma_w ) -{ - 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; - } -} - -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; -} - -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 handler update */ -/************************************/ -static STREAM_UPDATE( svision_update ) -{ - 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; jchannel); j++, channel++) + for (channel=m_channel, j=0; jsize != 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(); - state->dma.finished = TRUE; - state->dma.on = FALSE; + svision_state *sv_state = machine().driver_data(); + 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(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,213 +11,137 @@ #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 */ -}; - -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 type definition +const device_type WSWAN = &device_creator; -INLINE wswan_sound_state *get_safe_token(device_t *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) { - assert(device != NULL); - assert(device->type() == WSWAN); - return (wswan_sound_state *)downcast(device)->token(); } -static void wswan_ch_set_freq( running_machine &machine, struct CHAN *ch, UINT16 freq ) + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void wswan_sound_device::device_start() { - 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)); + 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; } -WRITE8_DEVICE_HANDLER( wswan_sound_port_w ) + +//------------------------------------------------- +// 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) { - wswan_sound_state *state = get_safe_token(device); - - state->channel->update(); - - switch( offset ) { - case 0x80: /* Audio 1 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio1, (state->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)); - break; - case 0x82: /* Audio 2 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio2, (state->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)); - break; - case 0x84: /* Audio 3 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio3, (state->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)); - break; - case 0x86: /* Audio 4 freq (lo) */ - wswan_ch_set_freq(space.machine(), &state->audio4, (state->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)); - break; - case 0x88: /* Audio 1 volume */ - state->audio1.vol_left = ( data & 0xF0 ) >> 4; - state->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; - break; - case 0x8A: /* Audio 3 volume */ - state->audio3.vol_left = ( data & 0xF0 ) >> 4; - state->audio3.vol_right = data & 0x0F; - break; - case 0x8B: /* Audio 4 volume */ - state->audio4.vol_left = ( data & 0xF0 ) >> 4; - state->audio4.vol_right = data & 0x0F; - break; - case 0x8C: /* Sweep step */ - state->sweep_step = (INT8)data; - break; - case 0x8D: /* Sweep time */ - state->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; - break; - case 0x8F: /* Sample location */ - state->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; - 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; - break; - case 0x92: /* Noise counter shift register (lo) */ - state->noise_shift = ( state->noise_shift & 0xFF00 ) | data; - break; - case 0x93: /* Noise counter shift register (hi) */ - state->noise_shift = ( data << 8 ) | ( state->noise_shift & 0x00FF ); - break; - case 0x94: /* Master volume */ - state->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; + 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 += state->audio1.vol_left * sample; - right += state->audio1.vol_right * sample; + left += m_audio1.vol_left * sample; + right += m_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); + 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 = state->audio2.signal; - state->audio2.pos++; - if ( state->audio2.pos >= state->audio2.period / 2 ) { - state->audio2.pos = 0; - state->audio2.signal = -state->audio2.signal; + 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 += state->audio2.vol_left * sample; - right += state->audio2.vol_right * sample; + left += m_audio2.vol_left * sample; + right += m_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 ( 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 ( 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)); + 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 += state->audio3.vol_left * sample; - right += state->audio3.vol_right * sample; + left += m_audio3.vol_left * sample; + right += m_audio3.vol_right * sample; } - if ( state->audio4.on ) { - if ( state->audio4_noise ) { + if ( m_audio4.on ) { + if ( m_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; + 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 += state->audio4.vol_left * sample; - right += state->audio4.vol_right * sample; + left += m_audio4.vol_left * sample; + right += m_audio4.vol_right * sample; } left <<= 5; @@ -228,60 +152,99 @@ static STREAM_UPDATE( wswan_sh_update ) } } -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; +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)); +} + +WRITE8_MEMBER( wswan_sound_device::wswan_sound_port_w ) +{ + m_channel->update(); + + switch( offset ) { + case 0x80: /* Audio 1 freq (lo) */ + wswan_ch_set_freq(&m_audio1, (m_audio1.freq & 0xff00) | data); + break; + case 0x81: /* Audio 1 freq (hi) */ + wswan_ch_set_freq(&m_audio1, (data << 8 ) | (m_audio1.freq & 0x00ff)); + break; + case 0x82: /* Audio 2 freq (lo) */ + wswan_ch_set_freq(&m_audio2, (m_audio2.freq & 0xff00) | data); + break; + case 0x83: /* Audio 2 freq (hi) */ + wswan_ch_set_freq(&m_audio2, (data << 8 ) | (m_audio2.freq & 0x00ff)); + break; + case 0x84: /* Audio 3 freq (lo) */ + wswan_ch_set_freq(&m_audio3, (m_audio3.freq & 0xff00) | data); + break; + case 0x85: /* Audio 3 freq (hi) */ + wswan_ch_set_freq(&m_audio3, (data << 8) | (m_audio3.freq & 0x00ff)); + break; + case 0x86: /* Audio 4 freq (lo) */ + wswan_ch_set_freq(&m_audio4, (m_audio4.freq & 0xff00) | data); + break; + case 0x87: /* Audio 4 freq (hi) */ + wswan_ch_set_freq(&m_audio4, (data << 8) | (m_audio4.freq & 0x00ff)); + break; + case 0x88: /* Audio 1 volume */ + m_audio1.vol_left = ( data & 0xF0 ) >> 4; + m_audio1.vol_right = data & 0x0F; + break; + case 0x89: /* Audio 2 volume */ + m_voice_data = data; + m_audio2.vol_left = ( data & 0xF0 ) >> 4; + m_audio2.vol_right = data & 0x0F; + break; + case 0x8A: /* Audio 3 volume */ + m_audio3.vol_left = ( data & 0xF0 ) >> 4; + m_audio3.vol_right = data & 0x0F; + break; + case 0x8B: /* Audio 4 volume */ + m_audio4.vol_left = ( data & 0xF0 ) >> 4; + m_audio4.vol_right = data & 0x0F; + break; + case 0x8C: /* Sweep step */ + m_sweep_step = (INT8)data; + break; + case 0x8D: /* Sweep time */ + m_sweep_time = space.machine().sample_rate() / ( 3072000 / ( 8192 * (data + 1) ) ); + break; + case 0x8E: /* Noise control */ + m_noise_type = data & 0x07; + m_noise_reset = ( data & 0x08 ) >> 3; + m_noise_enable = ( data & 0x10 ) >> 4; + break; + case 0x8F: /* Sample location */ + m_sample_address = data << 6; + break; + case 0x90: /* Audio control */ + 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 */ + 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) */ + m_noise_shift = ( m_noise_shift & 0xFF00 ) | data; + break; + case 0x93: /* Noise counter shift register (hi) */ + m_noise_shift = ( data << 8 ) | ( m_noise_shift & 0x00FF ); + break; + case 0x94: /* Master volume */ + m_master_volume = data; + break; + } } -const device_type WSWAN = &device_creator; - -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"); -} diff --git a/src/mess/drivers/svision.c b/src/mess/drivers/svision.c index fda7a29713f..2a3f49d3c92 100644 --- a/src/mess/drivers/svision.c +++ b/src/mess/drivers/svision.c @@ -166,19 +166,19 @@ WRITE8_MEMBER(svision_state::svision_w) break; case 0x10: case 0x11: case 0x12: case 0x13: - svision_soundport_w(m_sound, 0, offset & 3, data); + m_sound->soundport_w(0, offset & 3, data); break; case 0x14: case 0x15: case 0x16: case 0x17: - svision_soundport_w(m_sound, 1, offset & 3, data); + m_sound->soundport_w(1, offset & 3, data); break; case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: - svision_sounddma_w(m_sound, space, offset - 0x18, data); + m_sound->svision_sounddma_w(space, offset - 0x18, data); break; case 0x28: case 0x29: case 0x2a: - svision_noise_w(m_sound, space, offset - 0x28, data); + m_sound->svision_noise_w(space, offset - 0x28, data); break; default: @@ -443,14 +443,14 @@ INTERRUPT_GEN_MEMBER(svision_state::svision_frame_int) if (BANK&1) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); - svision_sound_decrement(m_sound); + m_sound->sound_decrement(); } DRIVER_INIT_MEMBER(svision_state,svision) { m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this)); - m_sound = machine().device("custom"); - m_dma_finished = svision_dma_finished(m_sound); + m_sound = machine().device("custom"); + m_dma_finished = m_sound->dma_finished(); m_pet.on = FALSE; m_user1 = memregion("user1"); m_bank1 = membank("bank1"); @@ -461,8 +461,8 @@ DRIVER_INIT_MEMBER(svision_state,svision) DRIVER_INIT_MEMBER(svision_state,svisions) { m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this)); - m_sound = machine().device("custom"); - m_dma_finished = svision_dma_finished(m_sound); + m_sound = machine().device("custom"); + m_dma_finished = m_sound->dma_finished(); m_user1 = memregion("user1"); m_bank1 = membank("bank1"); m_bank2 = membank("bank2"); diff --git a/src/mess/includes/special.h b/src/mess/includes/special.h index 3f897c49b13..2c0004995c5 100644 --- a/src/mess/includes/special.h +++ b/src/mess/includes/special.h @@ -21,6 +21,8 @@ #include "machine/ram.h" +class specimx_sound_device; // defined below + class special_state : public driver_device { public: @@ -83,7 +85,7 @@ public: UINT8 m_erik_color_2; UINT8 m_erik_background; UINT8 m_specimx_color; - device_t *m_specimx_audio; + specimx_sound_device *m_specimx_audio; int m_specialist_8255_porta; int m_specialist_8255_portb; int m_specialist_8255_portc; @@ -148,56 +150,35 @@ extern const struct pit8253_config specimx_pit8253_intf; extern const i8255_interface specialist_ppi8255_interface; - - - - - - /*----------- defined in video/special.c -----------*/ - - - - - - - - - - - - - - extern const rgb_t specimx_palette[16]; + /*----------- defined in audio/special.c -----------*/ class specimx_sound_device : public device_t, - public device_sound_interface + public device_sound_interface { public: specimx_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~specimx_sound_device() { global_free(m_token); } + ~specimx_sound_device() { } - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + void set_input(int index, int state); + private: - // internal state - void *m_token; + sound_stream *m_mixer_channel; + int m_specimx_input[3]; }; extern const device_type SPECIMX; - -void specimx_set_input(device_t *device, int index, int state); - #endif /* SPECIAL_H_ */ diff --git a/src/mess/includes/svision.h b/src/mess/includes/svision.h index de26701fa64..143fb9c40e4 100644 --- a/src/mess/includes/svision.h +++ b/src/mess/includes/svision.h @@ -27,6 +27,7 @@ struct tvlink_t int palette_on; }; +class svision_sound_device; // defined below class svision_state : public driver_device { @@ -40,7 +41,7 @@ public: , m_joy2(*this, "JOY2") { } - device_t *m_sound; + svision_sound_device *m_sound; int *m_dma_finished; svision_t m_svision; svision_pet_t m_pet; @@ -86,35 +87,124 @@ void svision_irq( running_machine &machine ); /*----------- defined in audio/svision.c -----------*/ + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +enum SVISION_NOISE_Type +{ + SVISION_NOISE_Type7Bit, + SVISION_NOISE_Type14Bit +}; + +struct SVISION_NOISE +{ + SVISION_NOISE() : + on(0), + right(0), + left(0), + play(0), + type(SVISION_NOISE_Type7Bit), + state(0), + volume(0), + count(0), + step(0.0), + pos(0.0), + value(0) + { + memset(reg, 0, sizeof(UINT8)*3); + } + + 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 +{ + SVISION_DMA() : + on(0), + right(0), + left(0), + ca14to16(0), + start(0), + size(0), + pos(0.0), + step(0.0), + finished(0) + { + memset(reg, 0, sizeof(UINT8)*5); + } + + UINT8 reg[5]; + int on, right, left; + int ca14to16; + int start,size; + double pos, step; + int finished; +}; + +struct SVISION_CHANNEL +{ + SVISION_CHANNEL() : + on(0), + waveform(0), + volume(0), + pos(0), + size(0), + count(0) + { + memset(reg, 0, sizeof(UINT8)*4); + } + + UINT8 reg[4]; + int on; + int waveform, volume; + int pos; + int size; + int count; +}; + + +// ======================> svision_sound_device + class svision_sound_device : public device_t, - public device_sound_interface + public device_sound_interface { public: svision_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~svision_sound_device() { global_free(m_token); } + ~svision_sound_device() { } - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + DECLARE_WRITE8_MEMBER( svision_sounddma_w ); + DECLARE_WRITE8_MEMBER( svision_noise_w ); + +public: + int *dma_finished(); + void sound_decrement(); + void soundport_w(int which, int offset, int data); + private: - // internal state - void *m_token; + sound_stream *m_mixer_channel; + SVISION_DMA m_dma; + SVISION_NOISE m_noise; + SVISION_CHANNEL m_channel[2]; }; extern const device_type SVISION; -int *svision_dma_finished(device_t *device); -void svision_sound_decrement(device_t *device); -void svision_soundport_w(device_t *device, int which, int offset, int data); -DECLARE_WRITE8_DEVICE_HANDLER( svision_sounddma_w ); -DECLARE_WRITE8_DEVICE_HANDLER( svision_noise_w ); - - #endif /* SVISION_H_ */ diff --git a/src/mess/includes/wswan.h b/src/mess/includes/wswan.h index b14fea82796..cdea374b396 100644 --- a/src/mess/includes/wswan.h +++ b/src/mess/includes/wswan.h @@ -185,30 +185,79 @@ void wswan_refresh_scanline( running_machine &machine ); /*----------- defined in audio/wswan.c -----------*/ +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +struct CHAN +{ + CHAN() : + freq(0), + period(0), + pos(0), + vol_left(0), + vol_right(0), + on(0), + signal(0) { } + + 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 */ +}; + + +// ======================> wswan_sound_device + class wswan_sound_device : public device_t, public device_sound_interface { public: wswan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~wswan_sound_device() { global_free(m_token); } + ~wswan_sound_device() { } - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + +public: + DECLARE_WRITE8_MEMBER( wswan_sound_port_w ); + private: - // internal state - void *m_token; + void wswan_ch_set_freq( CHAN *ch, UINT16 freq ); + +private: + sound_stream *m_channel; + CHAN m_audio1; /* Audio channel 1 */ + CHAN m_audio2; /* Audio channel 2 */ + CHAN m_audio3; /* Audio channel 3 */ + CHAN m_audio4; /* Audio channel 4 */ + INT8 m_sweep_step; /* Sweep step */ + UINT32 m_sweep_time; /* Sweep time */ + UINT32 m_sweep_count; /* Sweep counter */ + UINT8 m_noise_type; /* Noise generator type */ + UINT8 m_noise_reset; /* Noise reset */ + UINT8 m_noise_enable; /* Noise enable */ + UINT16 m_sample_address; /* Sample address */ + UINT8 m_audio2_voice; /* Audio 2 voice */ + UINT8 m_audio3_sweep; /* Audio 3 sweep */ + UINT8 m_audio4_noise; /* Audio 4 noise */ + UINT8 m_mono; /* mono */ + UINT8 m_voice_data; /* voice data */ + UINT8 m_output_volume; /* output volume */ + UINT8 m_external_stereo; /* external stereo */ + UINT8 m_external_speaker; /* external speaker */ + UINT16 m_noise_shift; /* Noise counter shift register */ + UINT8 m_master_volume; /* Master volume */ }; extern const device_type WSWAN; -DECLARE_WRITE8_DEVICE_HANDLER( wswan_sound_port_w ); - #endif /* WSWAN_H_ */ diff --git a/src/mess/machine/special.c b/src/mess/machine/special.c index 99d06f97fed..5e564fc3b81 100644 --- a/src/mess/machine/special.c +++ b/src/mess/machine/special.c @@ -182,17 +182,17 @@ WRITE8_MEMBER( special_state::specimx_select_bank ) WRITE_LINE_MEMBER( special_state::specimx_pit8253_out0_changed ) { - specimx_set_input( m_specimx_audio, 0, state ); + m_specimx_audio->set_input( 0, state ); } WRITE_LINE_MEMBER( special_state::specimx_pit8253_out1_changed ) { - specimx_set_input( m_specimx_audio, 1, state ); + m_specimx_audio->set_input( 1, state ); } WRITE_LINE_MEMBER( special_state::specimx_pit8253_out2_changed ) { - specimx_set_input( m_specimx_audio, 2, state ); + m_specimx_audio->set_input( 2, state ); } @@ -220,7 +220,7 @@ const struct pit8253_config specimx_pit8253_intf = MACHINE_START_MEMBER(special_state,specimx) { - m_specimx_audio = machine().device("custom"); + m_specimx_audio = machine().device("custom"); m_drive = 0; m_fdc->setup_drq_cb(fd1793_t::line_cb(FUNC(special_state::fdc_drq), this)); } diff --git a/src/mess/machine/wswan.c b/src/mess/machine/wswan.c index bf865019afd..c5d52d2126d 100644 --- a/src/mess/machine/wswan.c +++ b/src/mess/machine/wswan.c @@ -846,7 +846,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Master volume Bit 4-7 - Unknown */ - wswan_sound_port_w( machine().device("custom"), space, offset, data ); + machine().device("custom")->wswan_sound_port_w( space, offset, data ); break; case 0xa0: /* Hardware type - this is probably read only Bit 0 - Enable cartridge slot and/or disable bios