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 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 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 y0, y1, y2; /* y[k], y[k-1], y[k-2], current and previous 2 output values */
double a1, a2; /* digital filter coefficients, denominator */ double a1, a2; /* digital filter coefficients, denominator */

View File

@ -6,39 +6,51 @@
#include "emu.h" #include "emu.h"
#include "includes/cps3.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; int i;
// the actual 'user5' region only exists on the nocd sets, on the others it's allocated in the initialization. // 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. // 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 */ /* Clear the buffers */
memset(outputs[0], 0, samples*sizeof(*outputs[0])); 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 ++) for (i = 0; i < CPS3_VOICES; i ++)
{ {
if (state->m_key & (1 << i)) if (m_key & (1 << i))
{ {
int j; int j;
/* TODO */ /* TODO */
#define SWAP(a) ((a >> 16) | ((a & 0xffff) << 16)) #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 start = vptr->regs[1];
UINT32 end = vptr->regs[5]; UINT32 end = vptr->regs[5];
@ -88,12 +100,12 @@ static STREAM_UPDATE( cps3_stream_update )
} }
else else
{ {
state->m_key &= ~(1 << i); m_key &= ~(1 << i);
break; break;
} }
} }
sample = state->m_base[BYTE4_XOR_LE(start + pos)]; sample = m_base[BYTE4_XOR_LE(start + pos)];
frac += step; frac += step;
outputs[0][j] += (sample * (vol_l >> 8)); outputs[0][j] += (sample * (vol_l >> 8));
@ -104,26 +116,16 @@ static STREAM_UPDATE( cps3_stream_update )
vptr->frac = frac; vptr->frac = frac;
} }
} }
} }
static DEVICE_START( cps3_sound )
WRITE32_MEMBER( cps3_sound_device::cps3_sound_w )
{ {
cps3_sound_state *state = get_safe_token(device); m_stream->update();
/* 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();
if (offset < 0x80) 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) else if (offset == 0x80)
{ {
@ -133,13 +135,13 @@ WRITE32_DEVICE_HANDLER( cps3_sound_w )
for (i = 0; i < CPS3_VOICES; i++) for (i = 0; i < CPS3_VOICES; i++)
{ {
// Key off -> Key on // 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; m_voice[i].frac = 0;
state->m_voice[i].pos = 0; m_voice[i].pos = 0;
} }
} }
state->m_key = key; m_key = key;
} }
else 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); m_stream->update();
state->m_stream->update();
if (offset < 0x80) 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) else if (offset == 0x80)
{ {
return state->m_key << 16; return m_key << 16;
} }
else else
{ {
@ -167,42 +169,3 @@ READ32_DEVICE_HANDLER( cps3_sound_r )
return 0; 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 "emu.h"
#include "includes/gridlee.h" #include "includes/gridlee.h"
#include "sound/samples.h"
/************************************* // device type definition
* const device_type GRIDLEE = &device_creator<gridlee_sound_device>;
* Structures
*
*************************************/
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 */ memset(m_sound_data, 0, sizeof(UINT8)*24);
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();
} }
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]; stream_sample_t *buffer = outputs[0];
/* loop over samples */ /* loop over samples */
while (samples--) while (samples--)
{ {
/* tone channel */ /* tone channel */
state->m_tone_fraction += state->m_tone_step; m_tone_fraction += m_tone_step;
*buffer++ = (state->m_tone_fraction & 0x0800000) ? (state->m_tone_volume << 6) : 0; *buffer++ = (m_tone_fraction & 0x0800000) ? (m_tone_volume << 6) : 0;
} }
} }
/************************************* WRITE8_MEMBER( gridlee_sound_device::gridlee_sound_w )
*
* Sound startup routines
*
*************************************/
static DEVICE_START( gridlee_sound )
{ {
gridlee_sound_state *state = get_safe_token(device); UINT8 *sound_data = m_sound_data;
running_machine &machine = device->machine(); samples_device *samples = m_samples;
/* allocate the stream */ m_stream->update();
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();
switch (offset) switch (offset)
{ {
@ -113,13 +100,13 @@ WRITE8_DEVICE_HANDLER( gridlee_sound_w )
case 0x08+0x08: case 0x08+0x08:
if (data) 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 else
state->m_tone_step = 0; m_tone_step = 0;
break; break;
case 0x09+0x08: case 0x09+0x08:
state->m_tone_volume = data; m_tone_volume = data;
break; break;
case 0x0b+0x08: case 0x0b+0x08:
@ -177,42 +164,3 @@ fclose(f);
} }
#endif #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 Sound handler
****************************************************************************/ ****************************************************************************/
#include "emu.h" #include "emu.h"
#include "sound/filter.h"
#include "machine/rescap.h" #include "machine/rescap.h"
#include "namco52.h" #include "namco52.h"
#include "namco54.h" #include "namco54.h"
@ -14,22 +13,12 @@
#define POLEPOS_R166 1000.0 #define POLEPOS_R166 1000.0
#define POLEPOS_R167 2200.0 #define POLEPOS_R167 2200.0
#define POLEPOS_R168 4700.0 #define POLEPOS_R168 4700.0
/* resistor values when shorted by 4066 running at 5V */ /* resistor values when shorted by 4066 running at 5V */
#define POLEPOS_R166_SHUNT 1.0/(1.0/POLEPOS_R166 + 1.0/250) #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_R167_SHUNT 1.0/(1.0/POLEPOS_R166 + 1.0/250)
#define POLEPOS_R168_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] = static const double volume_table[8] =
{ {
(POLEPOS_R168_SHUNT + POLEPOS_R167_SHUNT + POLEPOS_R166_SHUNT + 2200) / 10000, (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_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)); 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 */ //-------------------------------------------------
/************************************/ // device_start - device-specific startup
static STREAM_UPDATE( engine_sound_update ) //-------------------------------------------------
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; UINT32 step, clock, slot;
UINT8 *base; UINT8 *base;
double volume, i_total; double volume, i_total;
@ -66,98 +107,65 @@ static STREAM_UPDATE( engine_sound_update )
int loop; int loop;
/* if we're not enabled, just fill with 0 */ /* if we're not enabled, just fill with 0 */
if (!state->m_sample_enable) if (!m_sample_enable)
{ {
memset(buffer, 0, samples * sizeof(*buffer)); memset(buffer, 0, samples * sizeof(*buffer));
return; return;
} }
/* determine the effective clock rate */ /* 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; step = (clock << 12) / OUTPUT_RATE;
/* determine the volume */ /* determine the volume */
slot = (state->m_sample_msb >> 3) & 7; slot = (m_sample_msb >> 3) & 7;
volume = volume_table[slot]; 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 */ /* fill in the sample */
while (samples--) while (samples--)
{ {
state->m_filter_engine[0].x0 = (3.4 / 255 * base[(state->m_current_position >> 12) & 0x7ff] - 2) * volume; m_filter_engine[0].x0 = (3.4 / 255 * base[(m_current_position >> 12) & 0x7ff] - 2) * volume;
state->m_filter_engine[1].x0 = state->m_filter_engine[0].x0; m_filter_engine[1].x0 = m_filter_engine[0].x0;
state->m_filter_engine[2].x0 = state->m_filter_engine[0].x0; m_filter_engine[2].x0 = m_filter_engine[0].x0;
i_total = 0; i_total = 0;
for (loop = 0; loop < 3; loop++) 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. /* The op-amp powered @ 5V will clip to 0V & 3.5V.
* Adjusted to vRef of 2V, we will clip as follows: */ * 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 (m_filter_engine[loop].y0 > 1.5) 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 < -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 */ i_total *= r_filt_total * 32000/2; /* now contains voltage adjusted by final gain */
*buffer++ = (int)i_total; *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 */ /* 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. */ /* Update stream first so all samples at old frequency are updated. */
state->m_stream->update(); m_stream->update();
state->m_sample_lsb = data & 62; m_sample_lsb = data & 62;
state->m_sample_enable = data & 1; m_sample_enable = data & 1;
} }
/************************************/ /************************************/
/* Write MSB of engine sound */ /* 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); m_stream->update();
state->m_stream->update(); m_sample_msb = data & 63;
state->m_sample_msb = data & 63;
} }
@ -178,13 +186,13 @@ WRITE8_DEVICE_HANDLER( polepos_engine_sound_msb_w )
#define POLEPOS_54XX_DAC_R (1.0 / (1.0 / RES_K(47) + 1.0 / RES_K(22) + 1.0 / RES_K(10) + 1.0 / RES_K(4.7))) #define POLEPOS_54XX_DAC_R (1.0 / (1.0 / RES_K(47) + 1.0 / RES_K(22) + 1.0 / RES_K(10) + 1.0 / RES_K(4.7)))
static const discrete_dac_r1_ladder polepos_54xx_dac = static const discrete_dac_r1_ladder polepos_54xx_dac =
{ {
4, /* number of DAC bits */ 4, /* number of DAC bits */
/* 54XX_0 54XX_1 54XX_2 */ /* 54XX_0 54XX_1 54XX_2 */
{ RES_K(47), /* R124, R136, R152 */ { RES_K(47), /* R124, R136, R152 */
RES_K(22), /* R120, R132, R142 */ RES_K(22), /* R120, R132, R142 */
RES_K(10), /* R119, R131, R138 */ RES_K(10), /* R119, R131, R138 */
RES_K(4.7)}, /* R118, R126, R103 */ RES_K(4.7)}, /* R118, R126, R103 */
0, 0, 0, 0 /* nothing extra */ 0, 0, 0, 0 /* nothing extra */
}; };
#define POLEPOS_52XX_DAC_R (1.0 / (1.0 / RES_K(100) + 1.0 / RES_K(47) + 1.0 / RES_K(22) + 1.0 / RES_K(10))) #define POLEPOS_52XX_DAC_R (1.0 / (1.0 / RES_K(100) + 1.0 / RES_K(47) + 1.0 / RES_K(22) + 1.0 / RES_K(10)))
@ -246,6 +254,7 @@ static const discrete_op_amp_filt_info polepos_chanl3_filt =
0 /* vN */ 0 /* vN */
}; };
DISCRETE_SOUND_START(polepos) DISCRETE_SOUND_START(polepos)
/************************************************ /************************************************
@ -350,49 +359,3 @@ DISCRETE_SOUND_START(polepos)
DISCRETE_SOUND_END 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) #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; memset(m_vol_crash, 0, sizeof(INT16)*16);
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();
} }
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; 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++ ) 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++ ) for( i = 0; i < 16; i++ )
{ {
@ -219,39 +94,13 @@ static DEVICE_START( redbaron_sound )
r0 += 1.0/1000; r0 += 1.0/1000;
r0 = 1.0/r0; r0 = 1.0/r0;
r1 = 1.0/r1; 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 // 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) void redbaron_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{ {
// should never get here stream_sample_t *buffer = outputs[0];
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); 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 CLOCK_DIVIDER 16
#define BUF_LEN 100000 #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_CHAN0 0
#define T8253_CHAN1 1 #define T8253_CHAN1 1
#define T8253_CHAN2 2 #define T8253_CHAN2 2
#define T8253_CWORD 3 #define T8253_CWORD 3
INLINE tiamc1_sound_state *get_safe_token(device_t *device) // device type definition
const device_type TIAMC1 = &device_creator<tiamc1_sound_device>;
//**************************************************************************
// 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)
{ {
assert(device != NULL);
assert(device->type() == TIAMC1);
return (tiamc1_sound_state *)downcast<tiamc1_sound_device *>(device)->token();
} }
static void timer8253_reset(struct timer8253struct *t) { //-------------------------------------------------
memset(t,0,sizeof(struct timer8253struct)); // 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));
} }
static void timer8253_tick(struct timer8253struct *t,int chn) { //-------------------------------------------------
if (t->channel[chn].enable && t->channel[chn].gate) { // sound_stream_update - handle a stream update
switch (t->channel[chn].cntMode) { //-------------------------------------------------
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));
}
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: case 0:
t->channel[chn].count--; t->channel[chn].count--;
if (t->channel[chn].count == 0xffff) 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) if(t->channel[chn].count==0)
t->channel[chn].output = 1; 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].enable = 0;
t->channel[chn].output = 1; 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; int chn;
switch (reg) { switch (reg)
{
case T8253_CWORD: case T8253_CWORD:
chn = val >> 6; chn = val >> 6;
if (chn < 3) { if (chn < 3)
{
t->channel[chn].bcdMode = (val & 1) ? 1 : 0; t->channel[chn].bcdMode = (val & 1) ? 1 : 0;
t->channel[chn].cntMode = (val >> 1) & 0x07; t->channel[chn].cntMode = (val >> 1) & 0x07;
t->channel[chn].valMode = (val >> 4) & 0x03; t->channel[chn].valMode = (val >> 4) & 0x03;
switch (t->channel[chn].valMode) { switch (t->channel[chn].valMode)
{
case 1: case 1:
case 2: case 2:
t->channel[chn].loadCnt = 1; 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); mame_printf_debug("unhandled val mode %i\n", t->channel[chn].valMode);
} }
switch (t->channel[chn].cntMode) { switch (t->channel[chn].cntMode)
{
case 0: case 0:
t->channel[chn].output = 0; t->channel[chn].output = 0;
t->channel[chn].enable = 0; t->channel[chn].enable = 0;
@ -170,7 +246,8 @@ static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
default: default:
chn = reg; chn = reg;
switch (t->channel[chn].valMode) { switch (t->channel[chn].valMode)
{
case 1: case 1:
t->channel[chn].cnval = (t->channel[chn].cnval & 0xff00) | val; t->channel[chn].cnval = (t->channel[chn].cnval & 0xff00) | val;
break; 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); 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].enable = 0;
} }
t->channel[chn].loadCnt--; t->channel[chn].loadCnt--;
if (t->channel[chn].loadCnt == 0) { if (t->channel[chn].loadCnt == 0)
switch (t->channel[chn].valMode) { {
switch (t->channel[chn].valMode)
{
case 1: case 1:
case 2: case 2:
t->channel[chn].loadCnt = 1; 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); mame_printf_debug("unhandled val mode %i\n", t->channel[chn].valMode);
} }
switch (t->channel[chn].cntMode) { switch (t->channel[chn].cntMode)
{
case 3: case 3:
t->channel[chn].count = t->channel[chn].cnval; t->channel[chn].count = t->channel[chn].cnval;
t->channel[chn].enable = 1; 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; 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; 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(&m_timer0, offset, data);
timer8253_wr(&state->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(&m_timer1, offset, data);
timer8253_wr(&state->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(&m_timer1, 0, (data & 1) ? 1 : 0);
timer8253_set_gate(&state->m_timer1, 0, (data & 1) ? 1 : 0); timer8253_set_gate(&m_timer1, 1, (data & 2) ? 1 : 0);
timer8253_set_gate(&state->m_timer1, 1, (data & 2) ? 1 : 0); timer8253_set_gate(&m_timer1, 2, (data & 4) ? 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");
} }

View File

@ -283,9 +283,9 @@ READ8_MEMBER(bzone_state::redbaron_joy_r)
WRITE8_MEMBER(bzone_state::redbaron_joysound_w) 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; 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(0x040C0084, 0x040C0087) AM_WRITE(cram_bank_w)
AM_RANGE(0x040C0088, 0x040C008b) AM_WRITE(cram_gfxflash_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(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 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(0x9600, 0x9600) AM_READ_PORT("DSW")
AM_RANGE(0x9700, 0x9700) AM_READ_PORT("IN2") AM_WRITENOP AM_RANGE(0x9700, 0x9700) AM_READ_PORT("IN2") AM_WRITENOP
AM_RANGE(0x9820, 0x9820) AM_READ(random_num_r) 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(0x9c00, 0x9cff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0xa000, 0xffff) AM_ROM AM_RANGE(0xa000, 0xffff) AM_ROM
ADDRESS_MAP_END ADDRESS_MAP_END

View File

@ -303,8 +303,8 @@ WRITE8_MEMBER(polepos_state::polepos_latch_w)
polepos_sound_enable(machine().device("namco"),bit); polepos_sound_enable(machine().device("namco"),bit);
if (!bit) if (!bit)
{ {
polepos_engine_sound_lsb_w(machine().device("polepos"), space, 0, 0); machine().device<polepos_sound_device>("polepos")->polepos_engine_sound_lsb_w(space, 0, 0);
polepos_engine_sound_msb_w(machine().device("polepos"), space, 0, 0); machine().device<polepos_sound_device>("polepos")->polepos_engine_sound_msb_w(space, 0, 0);
} }
break; 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, 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(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(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(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_LEGACY("polepos", polepos_engine_sound_msb_w) /* Car Sound ( Upper 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 ADDRESS_MAP_END
static ADDRESS_MAP_START( z80_io, AS_IO, 8, polepos_state ) 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(0xbd, 0xbd) AM_WRITE(tiamc1_bg_vshift_w)/* background V scroll */
AM_RANGE(0xbe, 0xbe) AM_WRITE(tiamc1_bankswitch_w) /* VRAM selector */ AM_RANGE(0xbe, 0xbe) AM_WRITE(tiamc1_bankswitch_w) /* VRAM selector */
AM_RANGE(0xbf, 0xbf) AM_WRITENOP /* charset control */ 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(0xd0, 0xd0) AM_READ_PORT("IN0")
AM_RANGE(0xd1, 0xd1) AM_READ_PORT("IN1") AM_RANGE(0xd1, 0xd1) AM_READ_PORT("IN1")
AM_RANGE(0xd2, 0xd2) AM_READ_PORT("IN2") AM_RANGE(0xd2, 0xd2) AM_READ_PORT("IN2")
AM_RANGE(0xd2, 0xd2) AM_WRITE(tiamc1_control_w) /* coin counter and lockout */ 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(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(0xd4, 0xd7) AM_DEVWRITE("2x8253", tiamc1_sound_device, tiamc1_timer1_w) /* timer 1 */
AM_RANGE(0xda, 0xda) AM_DEVWRITE_LEGACY("2x8253", tiamc1_timer1_gate_w) /* timer 1 gate control */ AM_RANGE(0xda, 0xda) AM_DEVWRITE("2x8253", tiamc1_sound_device, tiamc1_timer1_gate_w) /* timer 1 gate control */
ADDRESS_MAP_END ADDRESS_MAP_END
static INPUT_PORTS_START( tiamc1 ) static INPUT_PORTS_START( tiamc1 )

View File

@ -4,7 +4,6 @@
*************************************************************************/ *************************************************************************/
#include "devlegcy.h"
#include "sound/discrete.h" #include "sound/discrete.h"
#define BZONE_MASTER_CLOCK (XTAL_12_096MHz) #define BZONE_MASTER_CLOCK (XTAL_12_096MHz)
@ -38,29 +37,53 @@ public:
/*----------- defined in audio/bzone.c -----------*/ /*----------- defined in audio/bzone.c -----------*/
MACHINE_CONFIG_EXTERN( bzone_audio ); MACHINE_CONFIG_EXTERN( bzone_audio );
/*----------- defined in audio/redbaron.c -----------*/ /*----------- defined in audio/redbaron.c -----------*/
DECLARE_WRITE8_DEVICE_HANDLER( redbaron_sounds_w ); //**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> redbaron_sound_device
class redbaron_sound_device : public device_t, class redbaron_sound_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
redbaron_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete();
virtual void device_start(); virtual void device_start();
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 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: private:
// internal state INT16 *m_vol_lookup;
void *m_token;
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; extern const device_type REDBARON;

View File

@ -4,7 +4,6 @@
****************************************************************************/ ****************************************************************************/
#include "devlegcy.h"
#include "machine/intelfsh.h" #include "machine/intelfsh.h"
class cps3_state : public driver_device 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_do_alt_char_dma( UINT32 src, UINT32 real_dest, UINT32 real_length );
void cps3_process_character_dma(UINT32 address); void cps3_process_character_dma(UINT32 address);
void copy_from_nvram(); void copy_from_nvram();
inline void cps3_drawgfxzoom(bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, 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, unsigned int code, unsigned int color, int flipx, int flipy, int sx, int sy,
int transparency,int transparent_color, int transparency, int transparent_color,
int scalex, int scaley,bitmap_ind8 *pri_buffer,UINT32 pri_mask); int scalex, int scaley, bitmap_ind8 *pri_buffer, UINT32 pri_mask);
}; };
/*----------- defined in audio/cps3.c -----------*/ /*----------- 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, class cps3_sound_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
cps3_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete();
virtual void device_start(); virtual void device_start();
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 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: private:
// internal state sound_stream *m_stream;
void *m_token; cps3_voice m_voice[CPS3_VOICES];
UINT16 m_key;
INT8* m_base;
}; };
extern const device_type CPS3; 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) #define GRIDLEE_MASTER_CLOCK (20000000)
@ -67,27 +67,34 @@ public:
/*----------- defined in audio/gridlee.c -----------*/ /*----------- defined in audio/gridlee.c -----------*/
DECLARE_WRITE8_DEVICE_HANDLER( gridlee_sound_w );
class gridlee_sound_device : public device_t, class gridlee_sound_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
gridlee_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete();
virtual void device_start(); virtual void device_start();
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 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: private:
// internal state /* tone variables */
void *m_token; 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; extern const device_type GRIDLEE;

View File

@ -4,9 +4,9 @@
*************************************************************************/ *************************************************************************/
#include "devlegcy.h" #include "sound/filter.h"
#include "sound/discrete.h"
#include "sound/tms5220.h" #include "sound/tms5220.h"
#include "sound/discrete.h"
class polepos_state : public driver_device class polepos_state : public driver_device
@ -93,30 +93,33 @@ public:
/*----------- defined in audio/polepos.c -----------*/ /*----------- defined in audio/polepos.c -----------*/
class polepos_sound_device : public device_t, class polepos_sound_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
polepos_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete();
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 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: private:
// internal state UINT32 m_current_position;
void *m_token; 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; 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 ); DISCRETE_SOUND_EXTERN( polepos );

View File

@ -1,4 +1,3 @@
#include "devlegcy.h"
class tiamc1_state : public driver_device class tiamc1_state : public driver_device
{ {
@ -40,30 +39,75 @@ public:
/*----------- defined in audio/tiamc1.c -----------*/ /*----------- 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, class tiamc1_sound_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
tiamc1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); 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: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete();
virtual void device_start(); virtual void device_start();
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); 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: private:
// internal state void timer8253_reset(struct timer8253struct *t);
void *m_token; 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; 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 );