summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/audio
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-03-07 04:30:56 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-03-07 04:30:56 +0000
commit039aa6d9d75dc54ae07d4035420b96630b031509 (patch)
tree833ac7ef90d480249f4df425cdc48edcfb5a40c7 /src/mess/audio
parent6d31dcec5577bd1c98d76ae3c2ce3a44ab047d94 (diff)
Modernized wswan, special, and svision devices. [Andrew Gardner]
Diffstat (limited to 'src/mess/audio')
-rw-r--r--src/mess/audio/special.c100
-rw-r--r--src/mess/audio/svision.c357
-rw-r--r--src/mess/audio/wswan.c391
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");
-}