mirror of
https://github.com/holub/mame
synced 2025-05-22 21:58:57 +03:00
Modernized wswan, special, and svision devices. [Andrew Gardner]
This commit is contained in:
parent
6d31dcec55
commit
039aa6d9d7
@ -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>;
|
||||
|
||||
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<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)
|
||||
|
||||
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::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");
|
||||
}
|
||||
|
@ -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<svision_sound_device>;
|
||||
|
||||
|
||||
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<svision_sound_device *>(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; 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<wswan_sound_device>;
|
||||
|
||||
|
||||
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<wswan_sound_device *>(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::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");
|
||||
}
|
||||
|
@ -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<svision_sound_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<svision_sound_device>("custom");
|
||||
m_dma_finished = m_sound->dma_finished();
|
||||
m_user1 = memregion("user1");
|
||||
m_bank1 = membank("bank1");
|
||||
m_bank2 = membank("bank2");
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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<specimx_sound_device>("custom");
|
||||
m_drive = 0;
|
||||
m_fdc->setup_drq_cb(fd1793_t::line_cb(FUNC(special_state::fdc_drq), this));
|
||||
}
|
||||
|
@ -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<wswan_sound_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
|
||||
|
Loading…
Reference in New Issue
Block a user