mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
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:
parent
c7254e6408
commit
ac2c98c54e
@ -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 */
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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)))
|
||||
static const discrete_dac_r1_ladder polepos_54xx_dac =
|
||||
{
|
||||
4, /* number of DAC bits */
|
||||
/* 54XX_0 54XX_1 54XX_2 */
|
||||
{ RES_K(47), /* R124, R136, R152 */
|
||||
RES_K(22), /* R120, R132, R142 */
|
||||
RES_K(10), /* R119, R131, R138 */
|
||||
RES_K(4.7)}, /* R118, R126, R103 */
|
||||
0, 0, 0, 0 /* nothing extra */
|
||||
4, /* number of DAC bits */
|
||||
/* 54XX_0 54XX_1 54XX_2 */
|
||||
{ RES_K(47), /* R124, R136, R152 */
|
||||
RES_K(22), /* R120, R132, R142 */
|
||||
RES_K(10), /* R119, R131, R138 */
|
||||
RES_K(4.7)}, /* R118, R126, R103 */
|
||||
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)))
|
||||
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
// 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) {
|
||||
switch (t->channel[chn].cntMode) {
|
||||
//-------------------------------------------------
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 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;
|
||||
|
@ -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 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 );
|
||||
|
@ -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 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;
|
||||
|
@ -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
|
||||
@ -93,30 +93,33 @@ public:
|
||||
/*----------- defined in audio/polepos.c -----------*/
|
||||
|
||||
class polepos_sound_device : public device_t,
|
||||
public device_sound_interface
|
||||
public device_sound_interface
|
||||
{
|
||||
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 );
|
||||
|
@ -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 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 );
|
||||
|
Loading…
Reference in New Issue
Block a user