Modernized polepos, redbaron, cps3, tiamc1, and gridlee sound devices. [Andrew

Gardner]

Out of whatsnew.txt:
There are now exactly 100 files that include devlegcy.h.  Getting closer...
This commit is contained in:
Andrew Gardner 2013-02-21 05:30:51 +00:00
parent c7254e6408
commit ac2c98c54e
16 changed files with 679 additions and 754 deletions

View File

@ -65,6 +65,20 @@ filter_real filter_compute(filter* f, filter_state* s);
struct filter2_context
{
filter2_context() :
x0(0.0),
x1(0.0),
x2(0.0),
y0(0.0),
y1(0.0),
y2(0.0),
a1(0.0),
a2(0.0),
b0(0.0),
b1(0.0),
b2(0.0)
{}
double x0, x1, x2; /* x[k], x[k-1], x[k-2], current and previous 2 input values */
double y0, y1, y2; /* y[k], y[k-1], y[k-2], current and previous 2 output values */
double a1, a2; /* digital filter coefficients, denominator */

View File

@ -6,39 +6,51 @@
#include "emu.h"
#include "includes/cps3.h"
#define CPS3_VOICES 16
struct cps3_voice
// device type definition
const device_type CPS3 = &device_creator<cps3_sound_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// cps3_sound_device - constructor
//-------------------------------------------------
cps3_sound_device::cps3_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, CPS3, "CPS3 Custom", tag, owner, clock),
device_sound_interface(mconfig, *this),
m_stream(NULL),
m_key(0),
m_base(NULL)
{
UINT32 regs[8];
UINT32 pos;
UINT16 frac;
};
struct cps3_sound_state
{
sound_stream *m_stream;
cps3_voice m_voice[CPS3_VOICES];
UINT16 m_key;
INT8* m_base;
};
INLINE cps3_sound_state *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == CPS3);
return (cps3_sound_state *)downcast<cps3_sound_device *>(device)->token();
}
static STREAM_UPDATE( cps3_stream_update )
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void cps3_sound_device::device_start()
{
/* Allocate the stream */
m_stream = stream_alloc(0, 2, clock() / 384);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void cps3_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
cps3_sound_state *state = get_safe_token(device);
int i;
// the actual 'user5' region only exists on the nocd sets, on the others it's allocated in the initialization.
// it's a shared gfx/sound region, so can't be allocated as part of the sound device.
state->m_base = (INT8*)device->machine().driver_data<cps3_state>()->m_user5region;
m_base = (INT8*)machine().driver_data<cps3_state>()->m_user5region;
/* Clear the buffers */
memset(outputs[0], 0, samples*sizeof(*outputs[0]));
@ -46,14 +58,14 @@ static STREAM_UPDATE( cps3_stream_update )
for (i = 0; i < CPS3_VOICES; i ++)
{
if (state->m_key & (1 << i))
if (m_key & (1 << i))
{
int j;
/* TODO */
#define SWAP(a) ((a >> 16) | ((a & 0xffff) << 16))
cps3_voice *vptr = &state->m_voice[i];
cps3_voice *vptr = &m_voice[i];
UINT32 start = vptr->regs[1];
UINT32 end = vptr->regs[5];
@ -88,12 +100,12 @@ static STREAM_UPDATE( cps3_stream_update )
}
else
{
state->m_key &= ~(1 << i);
m_key &= ~(1 << i);
break;
}
}
sample = state->m_base[BYTE4_XOR_LE(start + pos)];
sample = m_base[BYTE4_XOR_LE(start + pos)];
frac += step;
outputs[0][j] += (sample * (vol_l >> 8));
@ -104,26 +116,16 @@ static STREAM_UPDATE( cps3_stream_update )
vptr->frac = frac;
}
}
}
static DEVICE_START( cps3_sound )
WRITE32_MEMBER( cps3_sound_device::cps3_sound_w )
{
cps3_sound_state *state = get_safe_token(device);
/* Allocate the stream */
state->m_stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock() / 384, NULL, cps3_stream_update);
}
WRITE32_DEVICE_HANDLER( cps3_sound_w )
{
cps3_sound_state *state = get_safe_token(device);
state->m_stream->update();
m_stream->update();
if (offset < 0x80)
{
COMBINE_DATA(&state->m_voice[offset / 8].regs[offset & 7]);
COMBINE_DATA(&m_voice[offset / 8].regs[offset & 7]);
}
else if (offset == 0x80)
{
@ -133,13 +135,13 @@ WRITE32_DEVICE_HANDLER( cps3_sound_w )
for (i = 0; i < CPS3_VOICES; i++)
{
// Key off -> Key on
if ((key & (1 << i)) && !(state->m_key & (1 << i)))
if ((key & (1 << i)) && !(m_key & (1 << i)))
{
state->m_voice[i].frac = 0;
state->m_voice[i].pos = 0;
m_voice[i].frac = 0;
m_voice[i].pos = 0;
}
}
state->m_key = key;
m_key = key;
}
else
{
@ -148,18 +150,18 @@ WRITE32_DEVICE_HANDLER( cps3_sound_w )
}
}
READ32_DEVICE_HANDLER( cps3_sound_r )
READ32_MEMBER( cps3_sound_device::cps3_sound_r )
{
cps3_sound_state *state = get_safe_token(device);
state->m_stream->update();
m_stream->update();
if (offset < 0x80)
{
return state->m_voice[offset / 8].regs[offset & 7] & mem_mask;
return m_voice[offset / 8].regs[offset & 7] & mem_mask;
}
else if (offset == 0x80)
{
return state->m_key << 16;
return m_key << 16;
}
else
{
@ -167,42 +169,3 @@ READ32_DEVICE_HANDLER( cps3_sound_r )
return 0;
}
}
const device_type CPS3 = &device_creator<cps3_sound_device>;
cps3_sound_device::cps3_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, CPS3, "CPS3 Custom", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(cps3_sound_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void cps3_sound_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void cps3_sound_device::device_start()
{
DEVICE_START_NAME( cps3_sound )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void cps3_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");
}

View File

@ -6,87 +6,74 @@
#include "emu.h"
#include "includes/gridlee.h"
#include "sound/samples.h"
/*************************************
*
* Structures
*
*************************************/
// device type definition
const device_type GRIDLEE = &device_creator<gridlee_sound_device>;
struct gridlee_sound_state
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// gridlee_sound_device - constructor
//-------------------------------------------------
gridlee_sound_device::gridlee_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, GRIDLEE, "Gridlee Custom", tag, owner, clock),
device_sound_interface(mconfig, *this),
m_tone_step(0),
m_tone_fraction(0),
m_tone_volume(0),
m_stream(NULL),
m_samples(NULL),
m_freq_to_step(0.0)
{
/* tone variables */
UINT32 m_tone_step;
UINT32 m_tone_fraction;
UINT8 m_tone_volume;
/* sound streaming variables */
sound_stream *m_stream;
samples_device *m_samples;
double m_freq_to_step;
UINT8 m_sound_data[24];
};
/*************************************
*
* Core sound generation
*
*************************************/
INLINE gridlee_sound_state *get_safe_token( device_t *device )
{
assert(device != NULL);
assert(device->type() == GRIDLEE);
return (gridlee_sound_state *)downcast<gridlee_sound_device *>(device)->token();
memset(m_sound_data, 0, sizeof(UINT8)*24);
}
static STREAM_UPDATE( gridlee_stream_update )
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void gridlee_sound_device::device_start()
{
/* allocate the stream */
m_stream = stream_alloc(0, 1, machine().sample_rate());
m_samples = machine().device<samples_device>("samples");
m_freq_to_step = (double)(1 << 24) / (double)machine().sample_rate();
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void gridlee_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
gridlee_sound_state *state = get_safe_token(device);
stream_sample_t *buffer = outputs[0];
/* loop over samples */
while (samples--)
{
/* tone channel */
state->m_tone_fraction += state->m_tone_step;
*buffer++ = (state->m_tone_fraction & 0x0800000) ? (state->m_tone_volume << 6) : 0;
m_tone_fraction += m_tone_step;
*buffer++ = (m_tone_fraction & 0x0800000) ? (m_tone_volume << 6) : 0;
}
}
/*************************************
*
* Sound startup routines
*
*************************************/
static DEVICE_START( gridlee_sound )
WRITE8_MEMBER( gridlee_sound_device::gridlee_sound_w )
{
gridlee_sound_state *state = get_safe_token(device);
running_machine &machine = device->machine();
UINT8 *sound_data = m_sound_data;
samples_device *samples = m_samples;
/* allocate the stream */
state->m_stream = device->machine().sound().stream_alloc(*device, 0, 1, machine.sample_rate(), NULL, gridlee_stream_update);
state->m_samples = device->machine().device<samples_device>("samples");
state->m_freq_to_step = (double)(1 << 24) / (double)machine.sample_rate();
}
WRITE8_DEVICE_HANDLER( gridlee_sound_w )
{
gridlee_sound_state *state = get_safe_token(device);
UINT8 *sound_data = state->m_sound_data;
samples_device *samples = state->m_samples;
state->m_stream->update();
m_stream->update();
switch (offset)
{
@ -113,13 +100,13 @@ WRITE8_DEVICE_HANDLER( gridlee_sound_w )
case 0x08+0x08:
if (data)
state->m_tone_step = state->m_freq_to_step * (double)(data * 5);
m_tone_step = m_freq_to_step * (double)(data * 5);
else
state->m_tone_step = 0;
m_tone_step = 0;
break;
case 0x09+0x08:
state->m_tone_volume = data;
m_tone_volume = data;
break;
case 0x0b+0x08:
@ -177,42 +164,3 @@ fclose(f);
}
#endif
}
const device_type GRIDLEE = &device_creator<gridlee_sound_device>;
gridlee_sound_device::gridlee_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, GRIDLEE, "Gridlee Custom", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(gridlee_sound_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void gridlee_sound_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void gridlee_sound_device::device_start()
{
DEVICE_START_NAME( gridlee_sound )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void gridlee_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");
}

View File

@ -3,7 +3,6 @@
Sound handler
****************************************************************************/
#include "emu.h"
#include "sound/filter.h"
#include "machine/rescap.h"
#include "namco52.h"
#include "namco54.h"
@ -14,22 +13,12 @@
#define POLEPOS_R166 1000.0
#define POLEPOS_R167 2200.0
#define POLEPOS_R168 4700.0
/* resistor values when shorted by 4066 running at 5V */
#define POLEPOS_R166_SHUNT 1.0/(1.0/POLEPOS_R166 + 1.0/250)
#define POLEPOS_R167_SHUNT 1.0/(1.0/POLEPOS_R166 + 1.0/250)
#define POLEPOS_R168_SHUNT 1.0/(1.0/POLEPOS_R166 + 1.0/250)
struct polepos_sound_state
{
UINT32 m_current_position;
int m_sample_msb;
int m_sample_lsb;
int m_sample_enable;
sound_stream *m_stream;
filter2_context m_filter_engine[3];
};
static const double volume_table[8] =
{
(POLEPOS_R168_SHUNT + POLEPOS_R167_SHUNT + POLEPOS_R166_SHUNT + 2200) / 10000,
@ -45,20 +34,72 @@ static const double volume_table[8] =
static const double r_filt_out[3] = {RES_K(4.7), RES_K(7.5), RES_K(10)};
static const double r_filt_total = 1.0 / (1.0/RES_K(4.7) + 1.0/RES_K(7.5) + 1.0/RES_K(10));
INLINE polepos_sound_state *get_safe_token( device_t *device )
{
assert(device != NULL);
assert(device->type() == POLEPOS);
return (polepos_sound_state *)downcast<polepos_sound_device *>(device)->token();
// device type definition
const device_type POLEPOS = &device_creator<polepos_sound_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// polepos_sound_device - constructor
//-------------------------------------------------
polepos_sound_device::polepos_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, POLEPOS, "Pole Position Custom", tag, owner, clock),
device_sound_interface(mconfig, *this),
m_current_position(0),
m_sample_msb(0),
m_sample_lsb(0),
m_sample_enable(0),
m_stream(NULL)
{
}
/************************************/
/* Stream updater */
/************************************/
static STREAM_UPDATE( engine_sound_update )
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void polepos_sound_device::device_start()
{
m_stream = stream_alloc(0, 1, OUTPUT_RATE);
m_sample_msb = m_sample_lsb = 0;
m_sample_enable = 0;
/* setup the filters */
filter_opamp_m_bandpass_setup(this, RES_K(220), RES_K(33), RES_K(390), CAP_U(.01), CAP_U(.01),
&m_filter_engine[0]);
filter_opamp_m_bandpass_setup(this, RES_K(150), RES_K(22), RES_K(330), CAP_U(.0047), CAP_U(.0047),
&m_filter_engine[1]);
/* Filter 3 is a little different. Because of the input capacitor, it is
* a high pass filter. */
filter2_setup(this, FILTER_HIGHPASS, 950, Q_TO_DAMP(.707), 1, &m_filter_engine[2]);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void polepos_sound_device::device_reset()
{
int loop;
for (loop = 0; loop < 3; loop++)
filter2_reset(&m_filter_engine[loop]);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void polepos_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
polepos_sound_state *state = get_safe_token(device);
UINT32 step, clock, slot;
UINT8 *base;
double volume, i_total;
@ -66,98 +107,65 @@ static STREAM_UPDATE( engine_sound_update )
int loop;
/* if we're not enabled, just fill with 0 */
if (!state->m_sample_enable)
if (!m_sample_enable)
{
memset(buffer, 0, samples * sizeof(*buffer));
return;
}
/* determine the effective clock rate */
clock = (device->machine().device("maincpu")->unscaled_clock() / 16) * ((state->m_sample_msb + 1) * 64 + state->m_sample_lsb + 1) / (64*64);
clock = (machine().device("maincpu")->unscaled_clock() / 16) * ((m_sample_msb + 1) * 64 + m_sample_lsb + 1) / (64*64);
step = (clock << 12) / OUTPUT_RATE;
/* determine the volume */
slot = (state->m_sample_msb >> 3) & 7;
slot = (m_sample_msb >> 3) & 7;
volume = volume_table[slot];
base = &device->machine().root_device().memregion("engine")->base()[slot * 0x800];
base = &machine().root_device().memregion("engine")->base()[slot * 0x800];
/* fill in the sample */
while (samples--)
{
state->m_filter_engine[0].x0 = (3.4 / 255 * base[(state->m_current_position >> 12) & 0x7ff] - 2) * volume;
state->m_filter_engine[1].x0 = state->m_filter_engine[0].x0;
state->m_filter_engine[2].x0 = state->m_filter_engine[0].x0;
m_filter_engine[0].x0 = (3.4 / 255 * base[(m_current_position >> 12) & 0x7ff] - 2) * volume;
m_filter_engine[1].x0 = m_filter_engine[0].x0;
m_filter_engine[2].x0 = m_filter_engine[0].x0;
i_total = 0;
for (loop = 0; loop < 3; loop++)
{
filter2_step(&state->m_filter_engine[loop]);
filter2_step(&m_filter_engine[loop]);
/* The op-amp powered @ 5V will clip to 0V & 3.5V.
* Adjusted to vRef of 2V, we will clip as follows: */
if (state->m_filter_engine[loop].y0 > 1.5) state->m_filter_engine[loop].y0 = 1.5;
if (state->m_filter_engine[loop].y0 < -2) state->m_filter_engine[loop].y0 = -2;
if (m_filter_engine[loop].y0 > 1.5) m_filter_engine[loop].y0 = 1.5;
if (m_filter_engine[loop].y0 < -2) m_filter_engine[loop].y0 = -2;
i_total += state->m_filter_engine[loop].y0 / r_filt_out[loop];
i_total += m_filter_engine[loop].y0 / r_filt_out[loop];
}
i_total *= r_filt_total * 32000/2; /* now contains voltage adjusted by final gain */
*buffer++ = (int)i_total;
state->m_current_position += step;
m_current_position += step;
}
}
/************************************/
/* Sound handler start */
/************************************/
static DEVICE_START( polepos_sound )
{
polepos_sound_state *state = get_safe_token(device);
state->m_stream = device->machine().sound().stream_alloc(*device, 0, 1, OUTPUT_RATE, NULL, engine_sound_update);
state->m_sample_msb = state->m_sample_lsb = 0;
state->m_sample_enable = 0;
/* setup the filters */
filter_opamp_m_bandpass_setup(device, RES_K(220), RES_K(33), RES_K(390), CAP_U(.01), CAP_U(.01),
&state->m_filter_engine[0]);
filter_opamp_m_bandpass_setup(device, RES_K(150), RES_K(22), RES_K(330), CAP_U(.0047), CAP_U(.0047),
&state->m_filter_engine[1]);
/* Filter 3 is a little different. Because of the input capacitor, it is
* a high pass filter. */
filter2_setup(device, FILTER_HIGHPASS, 950, Q_TO_DAMP(.707), 1,
&state->m_filter_engine[2]);
}
/************************************/
/* Sound handler reset */
/************************************/
static DEVICE_RESET( polepos_sound )
{
polepos_sound_state *state = get_safe_token(device);
int loop;
for (loop = 0; loop < 3; loop++)
filter2_reset(&state->m_filter_engine[loop]);
}
/************************************/
/* Write LSB of engine sound */
/************************************/
WRITE8_DEVICE_HANDLER( polepos_engine_sound_lsb_w )
WRITE8_MEMBER( polepos_sound_device::polepos_engine_sound_lsb_w )
{
polepos_sound_state *state = get_safe_token(device);
/* Update stream first so all samples at old frequency are updated. */
state->m_stream->update();
state->m_sample_lsb = data & 62;
state->m_sample_enable = data & 1;
m_stream->update();
m_sample_lsb = data & 62;
m_sample_enable = data & 1;
}
/************************************/
/* Write MSB of engine sound */
/************************************/
WRITE8_DEVICE_HANDLER( polepos_engine_sound_msb_w )
WRITE8_MEMBER( polepos_sound_device::polepos_engine_sound_msb_w )
{
polepos_sound_state *state = get_safe_token(device);
state->m_stream->update();
state->m_sample_msb = data & 63;
m_stream->update();
m_sample_msb = data & 63;
}
@ -246,6 +254,7 @@ static const discrete_op_amp_filt_info polepos_chanl3_filt =
0 /* vN */
};
DISCRETE_SOUND_START(polepos)
/************************************************
@ -350,49 +359,3 @@ DISCRETE_SOUND_START(polepos)
DISCRETE_SOUND_END
const device_type POLEPOS = &device_creator<polepos_sound_device>;
polepos_sound_device::polepos_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, POLEPOS, "Pole Position Custom", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(polepos_sound_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void polepos_sound_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void polepos_sound_device::device_start()
{
DEVICE_START_NAME( polepos_sound )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void polepos_sound_device::device_reset()
{
DEVICE_RESET_NAME( polepos_sound )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void polepos_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");
}

View File

@ -1,6 +1,6 @@
/*************************************************************************
Atari Red Baron hardware
Atari Red Baron sound hardware
*************************************************************************/
/*
@ -20,177 +20,52 @@
#define OUTPUT_RATE (48000)
struct redbaron_sound_state
// device type definition
const device_type REDBARON = &device_creator<redbaron_sound_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// redbaron_sound_device - constructor
//-------------------------------------------------
redbaron_sound_device::redbaron_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, REDBARON, "Red Baron Custom", tag, owner, clock),
device_sound_interface(mconfig, *this),
m_vol_lookup(NULL),
m_channel(NULL),
m_latch(0),
m_poly_counter(0),
m_poly_shift(0),
m_filter_counter(0),
m_crash_amp(0),
m_shot_amp(0),
m_shot_amp_counter(0),
m_squeal_amp(0),
m_squeal_amp_counter(0),
m_squeal_off_counter(0),
m_squeal_on_counter(0),
m_squeal_out(0)
{
INT16 *m_vol_lookup;
INT16 m_vol_crash[16];
sound_stream *m_channel;
int m_latch;
int m_poly_counter;
int m_poly_shift;
int m_filter_counter;
int m_crash_amp;
int m_shot_amp;
int m_shot_amp_counter;
int m_squeal_amp;
int m_squeal_amp_counter;
int m_squeal_off_counter;
int m_squeal_on_counter;
int m_squeal_out;
};
INLINE redbaron_sound_state *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == REDBARON);
return (redbaron_sound_state *)downcast<redbaron_sound_device *>(device)->token();
memset(m_vol_crash, 0, sizeof(INT16)*16);
}
WRITE8_DEVICE_HANDLER( redbaron_sounds_w )
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void redbaron_sound_device::device_start()
{
redbaron_sound_state *state = get_safe_token(device);
/* If sound is off, don't bother playing samples */
if( data == state->m_latch )
return;
state->m_channel->update();
state->m_latch = data;
}
#ifdef UNUSED_FUNCTION
WRITE8_DEVICE_HANDLER( redbaron_pokey_w )
{
redbaron_sound_state *state = get_safe_token(device);
if( state->m_latch & 0x20 )
pokey_w(device, offset, data);
}
#endif
static STREAM_UPDATE( redbaron_sound_update )
{
redbaron_sound_state *state = get_safe_token(device);
stream_sample_t *buffer = outputs[0];
while( samples-- )
{
int sum = 0;
/* polynome shifter E5 and F4 (LS164) clocked with 12kHz */
state->m_poly_counter -= 12000;
while( state->m_poly_counter <= 0 )
{
state->m_poly_counter += OUTPUT_RATE;
if( ((state->m_poly_shift & 0x0001) == 0) == ((state->m_poly_shift & 0x4000) == 0) )
state->m_poly_shift = (state->m_poly_shift << 1) | 1;
else
state->m_poly_shift <<= 1;
}
/* What is the exact low pass filter frequency? */
state->m_filter_counter -= 330;
while( state->m_filter_counter <= 0 )
{
state->m_filter_counter += OUTPUT_RATE;
state->m_crash_amp = (state->m_poly_shift & 1) ? state->m_latch >> 4 : 0;
}
/* mix crash sound at 35% */
sum += state->m_vol_crash[state->m_crash_amp] * 35 / 100;
/* shot not active: charge C32 (0.1u) */
if( (state->m_latch & 0x04) == 0 )
state->m_shot_amp = 32767;
else
if( (state->m_poly_shift & 0x8000) == 0 )
{
if( state->m_shot_amp > 0 )
{
/* discharge C32 (0.1u) through R26 (33k) + R27 (15k)
* 0.68 * C32 * (R26 + R27) = 3264us
*/
// #define C32_DISCHARGE_TIME (int)(32767 / 0.003264);
/* I think this is to short. Is C32 really 1u? */
#define C32_DISCHARGE_TIME (int)(32767 / 0.03264);
state->m_shot_amp_counter -= C32_DISCHARGE_TIME;
while( state->m_shot_amp_counter <= 0 )
{
state->m_shot_amp_counter += OUTPUT_RATE;
if( --state->m_shot_amp == 0 )
break;
}
/* mix shot sound at 35% */
sum += state->m_vol_lookup[state->m_shot_amp] * 35 / 100;
}
}
if( (state->m_latch & 0x02) == 0 )
state->m_squeal_amp = 0;
else
{
if( state->m_squeal_amp < 32767 )
{
/* charge C5 (22u) over R3 (68k) and CR1 (1N914)
* time = 0.68 * C5 * R3 = 1017280us
*/
#define C5_CHARGE_TIME (int)(32767 / 1.01728);
state->m_squeal_amp_counter -= C5_CHARGE_TIME;
while( state->m_squeal_amp_counter <= 0 )
{
state->m_squeal_amp_counter += OUTPUT_RATE;
if( ++state->m_squeal_amp == 32767 )
break;
}
}
if( state->m_squeal_out )
{
/* NE555 setup as pulse position modulator
* C = 0.01u, Ra = 33k, Rb = 47k
* frequency = 1.44 / ((33k + 2*47k) * 0.01u) = 1134Hz
* modulated by squeal_amp
*/
state->m_squeal_off_counter -= (1134 + 1134 * state->m_squeal_amp / 32767) / 3;
while( state->m_squeal_off_counter <= 0 )
{
state->m_squeal_off_counter += OUTPUT_RATE;
state->m_squeal_out = 0;
}
}
else
{
state->m_squeal_on_counter -= 1134;
while( state->m_squeal_on_counter <= 0 )
{
state->m_squeal_on_counter += OUTPUT_RATE;
state->m_squeal_out = 1;
}
}
}
/* mix sequal sound at 40% */
if( state->m_squeal_out )
sum += 32767 * 40 / 100;
*buffer++ = sum;
}
}
static DEVICE_START( redbaron_sound )
{
redbaron_sound_state *state = get_safe_token(device);
int i;
state->m_vol_lookup = auto_alloc_array(device->machine(), INT16, 32768);
m_vol_lookup = auto_alloc_array(machine(), INT16, 32768);
for( i = 0; i < 0x8000; i++ )
state->m_vol_lookup[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
m_vol_lookup[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
for( i = 0; i < 16; i++ )
{
@ -219,39 +94,13 @@ static DEVICE_START( redbaron_sound )
r0 += 1.0/1000;
r0 = 1.0/r0;
r1 = 1.0/r1;
state->m_vol_crash[i] = 32767 * r0 / (r0 + r1);
m_vol_crash[i] = 32767 * r0 / (r0 + r1);
}
state->m_channel = device->machine().sound().stream_alloc(*device, 0, 1, OUTPUT_RATE, 0, redbaron_sound_update);
m_channel = stream_alloc(0, 1, OUTPUT_RATE);
}
const device_type REDBARON = &device_creator<redbaron_sound_device>;
redbaron_sound_device::redbaron_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, REDBARON, "Red Baron Custom", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(redbaron_sound_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void redbaron_sound_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void redbaron_sound_device::device_start()
{
DEVICE_START_NAME( redbaron_sound )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
@ -259,6 +108,127 @@ void redbaron_sound_device::device_start()
void redbaron_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");
stream_sample_t *buffer = outputs[0];
while( samples-- )
{
int sum = 0;
/* polynome shifter E5 and F4 (LS164) clocked with 12kHz */
m_poly_counter -= 12000;
while( m_poly_counter <= 0 )
{
m_poly_counter += OUTPUT_RATE;
if( ((m_poly_shift & 0x0001) == 0) == ((m_poly_shift & 0x4000) == 0) )
m_poly_shift = (m_poly_shift << 1) | 1;
else
m_poly_shift <<= 1;
}
/* What is the exact low pass filter frequency? */
m_filter_counter -= 330;
while( m_filter_counter <= 0 )
{
m_filter_counter += OUTPUT_RATE;
m_crash_amp = (m_poly_shift & 1) ? m_latch >> 4 : 0;
}
/* mix crash sound at 35% */
sum += m_vol_crash[m_crash_amp] * 35 / 100;
/* shot not active: charge C32 (0.1u) */
if( (m_latch & 0x04) == 0 )
m_shot_amp = 32767;
else
if( (m_poly_shift & 0x8000) == 0 )
{
if( m_shot_amp > 0 )
{
/* discharge C32 (0.1u) through R26 (33k) + R27 (15k)
* 0.68 * C32 * (R26 + R27) = 3264us
*/
// #define C32_DISCHARGE_TIME (int)(32767 / 0.003264);
/* I think this is to short. Is C32 really 1u? */
#define C32_DISCHARGE_TIME (int)(32767 / 0.03264);
m_shot_amp_counter -= C32_DISCHARGE_TIME;
while( m_shot_amp_counter <= 0 )
{
m_shot_amp_counter += OUTPUT_RATE;
if( --m_shot_amp == 0 )
break;
}
/* mix shot sound at 35% */
sum += m_vol_lookup[m_shot_amp] * 35 / 100;
}
}
if( (m_latch & 0x02) == 0 )
m_squeal_amp = 0;
else
{
if( m_squeal_amp < 32767 )
{
/* charge C5 (22u) over R3 (68k) and CR1 (1N914)
* time = 0.68 * C5 * R3 = 1017280us
*/
#define C5_CHARGE_TIME (int)(32767 / 1.01728);
m_squeal_amp_counter -= C5_CHARGE_TIME;
while( m_squeal_amp_counter <= 0 )
{
m_squeal_amp_counter += OUTPUT_RATE;
if( ++m_squeal_amp == 32767 )
break;
}
}
if( m_squeal_out )
{
/* NE555 setup as pulse position modulator
* C = 0.01u, Ra = 33k, Rb = 47k
* frequency = 1.44 / ((33k + 2*47k) * 0.01u) = 1134Hz
* modulated by squeal_amp
*/
m_squeal_off_counter -= (1134 + 1134 * m_squeal_amp / 32767) / 3;
while( m_squeal_off_counter <= 0 )
{
m_squeal_off_counter += OUTPUT_RATE;
m_squeal_out = 0;
}
}
else
{
m_squeal_on_counter -= 1134;
while( m_squeal_on_counter <= 0 )
{
m_squeal_on_counter += OUTPUT_RATE;
m_squeal_out = 1;
}
}
}
/* mix sequal sound at 40% */
if( m_squeal_out )
sum += 32767 * 40 / 100;
*buffer++ = sum;
}
}
WRITE8_MEMBER( redbaron_sound_device::redbaron_sounds_w )
{
/* If sound is off, don't bother playing samples */
if( data == m_latch )
return;
m_channel->update();
m_latch = data;
}
#ifdef UNUSED_FUNCTION
WRITE8_MEMBER( redbaron_sound_device::redbaron_pokey_w )
{
if( m_latch & 0x20 )
pokey_w(device, offset, data);
}
#endif

View File

@ -37,55 +37,126 @@
#define CLOCK_DIVIDER 16
#define BUF_LEN 100000
struct timer8253chan {
UINT16 count;
UINT16 cnval;
UINT8 bcdMode;
UINT8 cntMode;
UINT8 valMode;
UINT8 gate;
UINT8 output;
UINT8 loadCnt;
UINT8 enable;
};
struct timer8253struct {
struct timer8253chan channel[3];
};
struct tiamc1_sound_state
{
sound_stream *m_channel;
int m_timer1_divider;
struct timer8253struct m_timer0;
struct timer8253struct m_timer1;
};
#define T8253_CHAN0 0
#define T8253_CHAN1 1
#define T8253_CHAN2 2
#define T8253_CWORD 3
INLINE tiamc1_sound_state *get_safe_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == TIAMC1);
// device type definition
const device_type TIAMC1 = &device_creator<tiamc1_sound_device>;
return (tiamc1_sound_state *)downcast<tiamc1_sound_device *>(device)->token();
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// tiamc1_sound_device - constructor
//-------------------------------------------------
tiamc1_sound_device::tiamc1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TIAMC1, "TIA-MC1 Custom", tag, owner, clock),
device_sound_interface(mconfig, *this),
m_channel(NULL),
m_timer1_divider(0)
{
}
static void timer8253_reset(struct timer8253struct *t) {
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void tiamc1_sound_device::device_start()
{
int i, j;
timer8253_reset(&m_timer0);
timer8253_reset(&m_timer1);
m_channel = stream_alloc(0, 1, clock() / CLOCK_DIVIDER);
m_timer1_divider = 0;
for (i = 0; i < 2; i++)
{
struct timer8253struct *t = (i ? &m_timer1 : &m_timer0);
for (j = 0; j < 3; j++)
{
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].count);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].cnval);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].bcdMode);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].cntMode);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].valMode);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].gate);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].output);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].loadCnt);
state_save_register_item(machine(), "channel", NULL, i * 3 + j, t->channel[j].enable);
}
}
save_item(NAME(m_timer1_divider));
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void tiamc1_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
int count, o0, o1, o2, len, orval = 0;
len = samples * CLOCK_DIVIDER;
for (count = 0; count < len; count++)
{
m_timer1_divider++;
if (m_timer1_divider == 228)
{
m_timer1_divider = 0;
timer8253_tick(&m_timer1, 0);
timer8253_tick(&m_timer1, 1);
timer8253_tick(&m_timer1, 2);
timer8253_set_gate(&m_timer0, 0, timer8253_get_output(&m_timer1, 0));
timer8253_set_gate(&m_timer0, 1, timer8253_get_output(&m_timer1, 1));
timer8253_set_gate(&m_timer0, 2, timer8253_get_output(&m_timer1, 2));
}
timer8253_tick(&m_timer0, 0);
timer8253_tick(&m_timer0, 1);
timer8253_tick(&m_timer0, 2);
o0 = timer8253_get_output(&m_timer0, 0) ? 1 : 0;
o1 = timer8253_get_output(&m_timer0, 1) ? 1 : 0;
o2 = timer8253_get_output(&m_timer0, 2) ? 1 : 0;
orval = (orval << 1) | (((o0 | o1) ^ 0xff) & o2);
if ((count + 1) % CLOCK_DIVIDER == 0)
{
outputs[0][count / CLOCK_DIVIDER] = orval ? 0x2828 : 0;
orval = 0;
}
}
}
void tiamc1_sound_device::timer8253_reset(struct timer8253struct *t)
{
memset(t,0,sizeof(struct timer8253struct));
}
static void timer8253_tick(struct timer8253struct *t,int chn) {
if (t->channel[chn].enable && t->channel[chn].gate) {
switch (t->channel[chn].cntMode) {
void tiamc1_sound_device::timer8253_tick(struct timer8253struct *t, int chn)
{
if (t->channel[chn].enable && t->channel[chn].gate)
{
switch (t->channel[chn].cntMode)
{
case 0:
t->channel[chn].count--;
if (t->channel[chn].count == 0xffff)
@ -109,7 +180,8 @@ static void timer8253_tick(struct timer8253struct *t,int chn) {
if(t->channel[chn].count==0)
t->channel[chn].output = 1;
if(t->channel[chn].count == 0xffff) {
if(t->channel[chn].count == 0xffff)
{
t->channel[chn].enable = 0;
t->channel[chn].output = 1;
}
@ -120,19 +192,22 @@ static void timer8253_tick(struct timer8253struct *t,int chn) {
static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
void tiamc1_sound_device::timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
{
int chn;
switch (reg) {
switch (reg)
{
case T8253_CWORD:
chn = val >> 6;
if (chn < 3) {
if (chn < 3)
{
t->channel[chn].bcdMode = (val & 1) ? 1 : 0;
t->channel[chn].cntMode = (val >> 1) & 0x07;
t->channel[chn].valMode = (val >> 4) & 0x03;
switch (t->channel[chn].valMode) {
switch (t->channel[chn].valMode)
{
case 1:
case 2:
t->channel[chn].loadCnt = 1;
@ -146,7 +221,8 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
mame_printf_debug("unhandled val mode %i\n", t->channel[chn].valMode);
}
switch (t->channel[chn].cntMode) {
switch (t->channel[chn].cntMode)
{
case 0:
t->channel[chn].output = 0;
t->channel[chn].enable = 0;
@ -170,7 +246,8 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
default:
chn = reg;
switch (t->channel[chn].valMode) {
switch (t->channel[chn].valMode)
{
case 1:
t->channel[chn].cnval = (t->channel[chn].cnval & 0xff00) | val;
break;
@ -184,14 +261,17 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
mame_printf_debug("unhandled val mode %i\n", t->channel[chn].valMode);
}
if (t->channel[chn].cntMode==0) {
if (t->channel[chn].cntMode==0)
{
t->channel[chn].enable = 0;
}
t->channel[chn].loadCnt--;
if (t->channel[chn].loadCnt == 0) {
switch (t->channel[chn].valMode) {
if (t->channel[chn].loadCnt == 0)
{
switch (t->channel[chn].valMode)
{
case 1:
case 2:
t->channel[chn].loadCnt = 1;
@ -205,7 +285,8 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
mame_printf_debug("unhandled val mode %i\n", t->channel[chn].valMode);
}
switch (t->channel[chn].cntMode) {
switch (t->channel[chn].cntMode)
{
case 3:
t->channel[chn].count = t->channel[chn].cnval;
t->channel[chn].enable = 1;
@ -224,145 +305,33 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
}
}
static void timer8253_set_gate(struct timer8253struct *t, int chn, UINT8 gate)
void tiamc1_sound_device::timer8253_set_gate(struct timer8253struct *t, int chn, UINT8 gate)
{
t->channel[chn].gate = gate;
}
static char timer8253_get_output(struct timer8253struct *t, int chn)
char tiamc1_sound_device::timer8253_get_output(struct timer8253struct *t, int chn)
{
return t->channel[chn].output;
}
WRITE8_DEVICE_HANDLER( tiamc1_timer0_w )
WRITE8_MEMBER( tiamc1_sound_device::tiamc1_timer0_w )
{
tiamc1_sound_state *state = get_safe_token(device);
timer8253_wr(&state->m_timer0, offset, data);
timer8253_wr(&m_timer0, offset, data);
}
WRITE8_DEVICE_HANDLER( tiamc1_timer1_w )
WRITE8_MEMBER( tiamc1_sound_device::tiamc1_timer1_w )
{
tiamc1_sound_state *state = get_safe_token(device);
timer8253_wr(&state->m_timer1, offset, data);
timer8253_wr(&m_timer1, offset, data);
}
WRITE8_DEVICE_HANDLER( tiamc1_timer1_gate_w )
WRITE8_MEMBER( tiamc1_sound_device::tiamc1_timer1_gate_w )
{
tiamc1_sound_state *state = get_safe_token(device);
timer8253_set_gate(&state->m_timer1, 0, (data & 1) ? 1 : 0);
timer8253_set_gate(&state->m_timer1, 1, (data & 2) ? 1 : 0);
timer8253_set_gate(&state->m_timer1, 2, (data & 4) ? 1 : 0);
}
static STREAM_UPDATE( tiamc1_sound_update )
{
tiamc1_sound_state *state = get_safe_token(device);
int count, o0, o1, o2, len, orval = 0;
len = samples * CLOCK_DIVIDER;
for (count = 0; count < len; count++) {
state->m_timer1_divider++;
if (state->m_timer1_divider == 228) {
state->m_timer1_divider = 0;
timer8253_tick(&state->m_timer1, 0);
timer8253_tick(&state->m_timer1, 1);
timer8253_tick(&state->m_timer1, 2);
timer8253_set_gate(&state->m_timer0, 0, timer8253_get_output(&state->m_timer1, 0));
timer8253_set_gate(&state->m_timer0, 1, timer8253_get_output(&state->m_timer1, 1));
timer8253_set_gate(&state->m_timer0, 2, timer8253_get_output(&state->m_timer1, 2));
}
timer8253_tick(&state->m_timer0, 0);
timer8253_tick(&state->m_timer0, 1);
timer8253_tick(&state->m_timer0, 2);
o0 = timer8253_get_output(&state->m_timer0, 0) ? 1 : 0;
o1 = timer8253_get_output(&state->m_timer0, 1) ? 1 : 0;
o2 = timer8253_get_output(&state->m_timer0, 2) ? 1 : 0;
orval = (orval << 1) | (((o0 | o1) ^ 0xff) & o2);
if ((count + 1) % CLOCK_DIVIDER == 0) {
outputs[0][count / CLOCK_DIVIDER] = orval ? 0x2828 : 0;
orval = 0;
}
}
}
static DEVICE_START( tiamc1_sound )
{
tiamc1_sound_state *state = get_safe_token(device);
running_machine &machine = device->machine();
int i, j;
timer8253_reset(&state->m_timer0);
timer8253_reset(&state->m_timer1);
state->m_channel = device->machine().sound().stream_alloc(*device, 0, 1, device->clock() / CLOCK_DIVIDER, 0, tiamc1_sound_update);
state->m_timer1_divider = 0;
for (i = 0; i < 2; i++) {
struct timer8253struct *t = (i ? &state->m_timer1 : &state->m_timer0);
for (j = 0; j < 3; j++) {
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].count);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].cnval);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].bcdMode);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].cntMode);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].valMode);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].gate);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].output);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].loadCnt);
state_save_register_item(machine, "channel", NULL, i * 3 + j, t->channel[j].enable);
}
}
device->save_item(NAME(state->m_timer1_divider));
}
const device_type TIAMC1 = &device_creator<tiamc1_sound_device>;
tiamc1_sound_device::tiamc1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TIAMC1, "TIA-MC1 Custom", tag, owner, clock),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(tiamc1_sound_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void tiamc1_sound_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void tiamc1_sound_device::device_start()
{
DEVICE_START_NAME( tiamc1_sound )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void tiamc1_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");
timer8253_set_gate(&m_timer1, 0, (data & 1) ? 1 : 0);
timer8253_set_gate(&m_timer1, 1, (data & 2) ? 1 : 0);
timer8253_set_gate(&m_timer1, 2, (data & 4) ? 1 : 0);
}

View File

@ -283,9 +283,9 @@ READ8_MEMBER(bzone_state::redbaron_joy_r)
WRITE8_MEMBER(bzone_state::redbaron_joysound_w)
{
device_t *device = machine().device("custom");
redbaron_sound_device *device = machine().device<redbaron_sound_device>("custom");
m_rb_input_select = data & 1;
redbaron_sounds_w(device, space, offset, data);
device->redbaron_sounds_w(space, offset, data);
}

View File

@ -2127,7 +2127,7 @@ static ADDRESS_MAP_START( cps3_map, AS_PROGRAM, 32, cps3_state )
AM_RANGE(0x040C0084, 0x040C0087) AM_WRITE(cram_bank_w)
AM_RANGE(0x040C0088, 0x040C008b) AM_WRITE(cram_gfxflash_bank_w)
AM_RANGE(0x040e0000, 0x040e02ff) AM_DEVREADWRITE_LEGACY("cps3", cps3_sound_r, cps3_sound_w)
AM_RANGE(0x040e0000, 0x040e02ff) AM_DEVREADWRITE("cps3", cps3_sound_device, cps3_sound_r, cps3_sound_w)
AM_RANGE(0x04100000, 0x041fffff) AM_READWRITE(cram_data_r, cram_data_w)
AM_RANGE(0x04200000, 0x043fffff) AM_READWRITE(cps3_gfxflash_r, cps3_gfxflash_w) // GFX Flash ROMS

View File

@ -311,7 +311,7 @@ static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM, 8, gridlee_state )
AM_RANGE(0x9600, 0x9600) AM_READ_PORT("DSW")
AM_RANGE(0x9700, 0x9700) AM_READ_PORT("IN2") AM_WRITENOP
AM_RANGE(0x9820, 0x9820) AM_READ(random_num_r)
AM_RANGE(0x9828, 0x993f) AM_DEVWRITE_LEGACY("gridlee", gridlee_sound_w)
AM_RANGE(0x9828, 0x993f) AM_DEVWRITE("gridlee", gridlee_sound_device, gridlee_sound_w)
AM_RANGE(0x9c00, 0x9cff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0xa000, 0xffff) AM_ROM
ADDRESS_MAP_END

View File

@ -303,8 +303,8 @@ WRITE8_MEMBER(polepos_state::polepos_latch_w)
polepos_sound_enable(machine().device("namco"),bit);
if (!bit)
{
polepos_engine_sound_lsb_w(machine().device("polepos"), space, 0, 0);
polepos_engine_sound_msb_w(machine().device("polepos"), space, 0, 0);
machine().device<polepos_sound_device>("polepos")->polepos_engine_sound_lsb_w(space, 0, 0);
machine().device<polepos_sound_device>("polepos")->polepos_engine_sound_msb_w(space, 0, 0);
}
break;
@ -496,8 +496,8 @@ static ADDRESS_MAP_START( z80_map, AS_PROGRAM, 8, polepos_state )
AM_RANGE(0xa000, 0xa000) AM_MIRROR(0x0cff) AM_READ(polepos_ready_r) /* READY */
AM_RANGE(0xa000, 0xa007) AM_MIRROR(0x0cf8) AM_WRITE(polepos_latch_w) /* misc latches */
AM_RANGE(0xa100, 0xa100) AM_MIRROR(0x0cff) AM_WRITE(watchdog_reset_w) /* Watchdog */
AM_RANGE(0xa200, 0xa200) AM_MIRROR(0x0cff) AM_DEVWRITE_LEGACY("polepos", polepos_engine_sound_lsb_w) /* Car Sound ( Lower Nibble ) */
AM_RANGE(0xa300, 0xa300) AM_MIRROR(0x0cff) AM_DEVWRITE_LEGACY("polepos", polepos_engine_sound_msb_w) /* Car Sound ( Upper Nibble ) */
AM_RANGE(0xa200, 0xa200) AM_MIRROR(0x0cff) AM_DEVWRITE("polepos", polepos_sound_device, polepos_engine_sound_lsb_w) /* Car Sound ( Lower Nibble ) */
AM_RANGE(0xa300, 0xa300) AM_MIRROR(0x0cff) AM_DEVWRITE("polepos", polepos_sound_device, polepos_engine_sound_msb_w) /* Car Sound ( Upper Nibble ) */
ADDRESS_MAP_END
static ADDRESS_MAP_START( z80_io, AS_IO, 8, polepos_state )

View File

@ -148,14 +148,14 @@ static ADDRESS_MAP_START( tiamc1_io_map, AS_IO, 8, tiamc1_state )
AM_RANGE(0xbd, 0xbd) AM_WRITE(tiamc1_bg_vshift_w)/* background V scroll */
AM_RANGE(0xbe, 0xbe) AM_WRITE(tiamc1_bankswitch_w) /* VRAM selector */
AM_RANGE(0xbf, 0xbf) AM_WRITENOP /* charset control */
AM_RANGE(0xc0, 0xc3) AM_DEVWRITE_LEGACY("2x8253", tiamc1_timer0_w) /* timer 0 */
AM_RANGE(0xc0, 0xc3) AM_DEVWRITE("2x8253", tiamc1_sound_device, tiamc1_timer0_w) /* timer 0 */
AM_RANGE(0xd0, 0xd0) AM_READ_PORT("IN0")
AM_RANGE(0xd1, 0xd1) AM_READ_PORT("IN1")
AM_RANGE(0xd2, 0xd2) AM_READ_PORT("IN2")
AM_RANGE(0xd2, 0xd2) AM_WRITE(tiamc1_control_w) /* coin counter and lockout */
AM_RANGE(0xd3, 0xd3) AM_WRITENOP /* 8255 ctrl. Used for i/o ports */
AM_RANGE(0xd4, 0xd7) AM_DEVWRITE_LEGACY("2x8253", tiamc1_timer1_w) /* timer 1 */
AM_RANGE(0xda, 0xda) AM_DEVWRITE_LEGACY("2x8253", tiamc1_timer1_gate_w) /* timer 1 gate control */
AM_RANGE(0xd4, 0xd7) AM_DEVWRITE("2x8253", tiamc1_sound_device, tiamc1_timer1_w) /* timer 1 */
AM_RANGE(0xda, 0xda) AM_DEVWRITE("2x8253", tiamc1_sound_device, tiamc1_timer1_gate_w) /* timer 1 gate control */
ADDRESS_MAP_END
static INPUT_PORTS_START( tiamc1 )

View File

@ -4,7 +4,6 @@
*************************************************************************/
#include "devlegcy.h"
#include "sound/discrete.h"
#define BZONE_MASTER_CLOCK (XTAL_12_096MHz)
@ -38,29 +37,53 @@ public:
/*----------- defined in audio/bzone.c -----------*/
MACHINE_CONFIG_EXTERN( bzone_audio );
/*----------- defined in audio/redbaron.c -----------*/
DECLARE_WRITE8_DEVICE_HANDLER( redbaron_sounds_w );
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> redbaron_sound_device
class redbaron_sound_device : public device_t,
public device_sound_interface
{
public:
redbaron_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~redbaron_sound_device() { global_free(m_token); }
~redbaron_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( redbaron_sounds_w );
private:
// internal state
void *m_token;
INT16 *m_vol_lookup;
INT16 m_vol_crash[16];
sound_stream *m_channel;
int m_latch;
int m_poly_counter;
int m_poly_shift;
int m_filter_counter;
int m_crash_amp;
int m_shot_amp;
int m_shot_amp_counter;
int m_squeal_amp;
int m_squeal_amp_counter;
int m_squeal_off_counter;
int m_squeal_on_counter;
int m_squeal_out;
};
extern const device_type REDBARON;

View File

@ -4,7 +4,6 @@
****************************************************************************/
#include "devlegcy.h"
#include "machine/intelfsh.h"
class cps3_state : public driver_device
@ -123,39 +122,61 @@ public:
void cps3_do_alt_char_dma( UINT32 src, UINT32 real_dest, UINT32 real_length );
void cps3_process_character_dma(UINT32 address);
void copy_from_nvram();
inline void cps3_drawgfxzoom(bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx,
unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
int transparency,int transparent_color,
int scalex, int scaley,bitmap_ind8 *pri_buffer,UINT32 pri_mask);
inline void cps3_drawgfxzoom(bitmap_rgb32 &dest_bmp, const rectangle &clip, gfx_element *gfx,
unsigned int code, unsigned int color, int flipx, int flipy, int sx, int sy,
int transparency, int transparent_color,
int scalex, int scaley, bitmap_ind8 *pri_buffer, UINT32 pri_mask);
};
/*----------- defined in audio/cps3.c -----------*/
#define CPS3_VOICES (16)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
struct cps3_voice
{
cps3_voice() :
pos(0),
frac(0)
{
memset(regs, 0, sizeof(UINT32)*8);
}
UINT32 regs[8];
UINT32 pos;
UINT16 frac;
};
// ======================> cps3_sound_device
class cps3_sound_device : public device_t,
public device_sound_interface
{
public:
cps3_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~cps3_sound_device() { global_free(m_token); }
~cps3_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_WRITE32_MEMBER( cps3_sound_w );
DECLARE_READ32_MEMBER( cps3_sound_r );
private:
// internal state
void *m_token;
sound_stream *m_stream;
cps3_voice m_voice[CPS3_VOICES];
UINT16 m_key;
INT8* m_base;
};
extern const device_type CPS3;
DECLARE_WRITE32_DEVICE_HANDLER( cps3_sound_w );
DECLARE_READ32_DEVICE_HANDLER( cps3_sound_r );

View File

@ -6,7 +6,7 @@
***************************************************************************/
#include "devlegcy.h"
#include "sound/samples.h"
#define GRIDLEE_MASTER_CLOCK (20000000)
@ -67,27 +67,34 @@ public:
/*----------- defined in audio/gridlee.c -----------*/
DECLARE_WRITE8_DEVICE_HANDLER( gridlee_sound_w );
class gridlee_sound_device : public device_t,
public device_sound_interface
{
public:
gridlee_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~gridlee_sound_device() { global_free(m_token); }
~gridlee_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( gridlee_sound_w );
private:
// internal state
void *m_token;
/* tone variables */
UINT32 m_tone_step;
UINT32 m_tone_fraction;
UINT8 m_tone_volume;
/* sound streaming variables */
sound_stream *m_stream;
samples_device *m_samples;
double m_freq_to_step;
UINT8 m_sound_data[24];
};
extern const device_type GRIDLEE;

View File

@ -4,9 +4,9 @@
*************************************************************************/
#include "devlegcy.h"
#include "sound/discrete.h"
#include "sound/filter.h"
#include "sound/tms5220.h"
#include "sound/discrete.h"
class polepos_state : public driver_device
@ -97,26 +97,29 @@ class polepos_sound_device : public device_t,
{
public:
polepos_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~polepos_sound_device() { global_free(m_token); }
~polepos_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();
virtual void device_reset();
// 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( polepos_engine_sound_lsb_w );
DECLARE_WRITE8_MEMBER( polepos_engine_sound_msb_w );
private:
// internal state
void *m_token;
UINT32 m_current_position;
int m_sample_msb;
int m_sample_lsb;
int m_sample_enable;
sound_stream *m_stream;
filter2_context m_filter_engine[3];
};
extern const device_type POLEPOS;
DECLARE_WRITE8_DEVICE_HANDLER( polepos_engine_sound_lsb_w );
DECLARE_WRITE8_DEVICE_HANDLER( polepos_engine_sound_msb_w );
DISCRETE_SOUND_EXTERN( polepos );

View File

@ -1,4 +1,3 @@
#include "devlegcy.h"
class tiamc1_state : public driver_device
{
@ -40,30 +39,75 @@ public:
/*----------- defined in audio/tiamc1.c -----------*/
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
struct timer8253chan
{
timer8253chan() :
count(0),
cnval(0),
bcdMode(0),
cntMode(0),
valMode(0),
gate(0),
output(0),
loadCnt(0),
enable(0)
{}
UINT16 count;
UINT16 cnval;
UINT8 bcdMode;
UINT8 cntMode;
UINT8 valMode;
UINT8 gate;
UINT8 output;
UINT8 loadCnt;
UINT8 enable;
};
struct timer8253struct
{
struct timer8253chan channel[3];
};
// ======================> qsound_device
class tiamc1_sound_device : public device_t,
public device_sound_interface
{
public:
tiamc1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~tiamc1_sound_device() { global_free(m_token); }
~tiamc1_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( tiamc1_timer0_w );
DECLARE_WRITE8_MEMBER( tiamc1_timer1_w );
DECLARE_WRITE8_MEMBER( tiamc1_timer1_gate_w );
private:
// internal state
void *m_token;
void timer8253_reset(struct timer8253struct *t);
void timer8253_tick(struct timer8253struct *t,int chn);
void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val);
char timer8253_get_output(struct timer8253struct *t, int chn);
void timer8253_set_gate(struct timer8253struct *t, int chn, UINT8 gate);
private:
sound_stream *m_channel;
int m_timer1_divider;
timer8253struct m_timer0;
timer8253struct m_timer1;
};
extern const device_type TIAMC1;
DECLARE_WRITE8_DEVICE_HANDLER( tiamc1_timer0_w );
DECLARE_WRITE8_DEVICE_HANDLER( tiamc1_timer1_w );
DECLARE_WRITE8_DEVICE_HANDLER( tiamc1_timer1_gate_w );