mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
Modernized hc55516 sound chip. [Osso]
This commit is contained in:
parent
94c417325e
commit
8e4b11a87e
@ -8,7 +8,6 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "hc55516.h"
|
||||
#include "devlegcy.h"
|
||||
|
||||
|
||||
/* 4x oversampling */
|
||||
@ -22,276 +21,6 @@
|
||||
#define SAMPLE_GAIN 10000.0
|
||||
|
||||
|
||||
struct hc55516_state
|
||||
{
|
||||
sound_stream *channel;
|
||||
int clock; /* 0 = software driven, non-0 = oscillator */
|
||||
int active_clock_hi;
|
||||
UINT8 shiftreg_mask;
|
||||
|
||||
UINT8 last_clock_state;
|
||||
UINT8 digit;
|
||||
UINT8 new_digit;
|
||||
UINT8 shiftreg;
|
||||
|
||||
INT16 curr_sample;
|
||||
INT16 next_sample;
|
||||
|
||||
UINT32 update_count;
|
||||
|
||||
double filter;
|
||||
double integrator;
|
||||
};
|
||||
|
||||
|
||||
static double charge, decay, leak;
|
||||
|
||||
|
||||
static STREAM_UPDATE( hc55516_update );
|
||||
|
||||
|
||||
|
||||
INLINE hc55516_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == HC55516 ||
|
||||
device->type() == MC3417 ||
|
||||
device->type() == MC3418);
|
||||
return (hc55516_state *)downcast<hc55516_device *>(device)->token();
|
||||
}
|
||||
|
||||
|
||||
static void start_common(device_t *device, UINT8 _shiftreg_mask, int _active_clock_hi)
|
||||
{
|
||||
hc55516_state *chip = get_safe_token(device);
|
||||
|
||||
/* compute the fixed charge, decay, and leak time constants */
|
||||
charge = pow(exp(-1.0), 1.0 / (FILTER_CHARGE_TC * 16000.0));
|
||||
decay = pow(exp(-1.0), 1.0 / (FILTER_DECAY_TC * 16000.0));
|
||||
leak = pow(exp(-1.0), 1.0 / (INTEGRATOR_LEAK_TC * 16000.0));
|
||||
|
||||
chip->clock = device->clock();
|
||||
chip->shiftreg_mask = _shiftreg_mask;
|
||||
chip->active_clock_hi = _active_clock_hi;
|
||||
chip->last_clock_state = 0;
|
||||
|
||||
/* create the stream */
|
||||
chip->channel = device->machine().sound().stream_alloc(*device, 0, 1, SAMPLE_RATE, chip, hc55516_update);
|
||||
|
||||
device->save_item(NAME(chip->last_clock_state));
|
||||
device->save_item(NAME(chip->digit));
|
||||
device->save_item(NAME(chip->new_digit));
|
||||
device->save_item(NAME(chip->shiftreg));
|
||||
device->save_item(NAME(chip->curr_sample));
|
||||
device->save_item(NAME(chip->next_sample));
|
||||
device->save_item(NAME(chip->update_count));
|
||||
device->save_item(NAME(chip->filter));
|
||||
device->save_item(NAME(chip->integrator));
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_START( hc55516 )
|
||||
{
|
||||
start_common(device, 0x07, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_START( mc3417 )
|
||||
{
|
||||
start_common(device, 0x07, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_START( mc3418 )
|
||||
{
|
||||
start_common(device, 0x0f, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static DEVICE_RESET( hc55516 )
|
||||
{
|
||||
hc55516_state *chip = get_safe_token(device);
|
||||
chip->last_clock_state = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE int is_external_osciallator(hc55516_state *chip)
|
||||
{
|
||||
return chip->clock != 0;
|
||||
}
|
||||
|
||||
|
||||
INLINE int is_active_clock_transition(hc55516_state *chip, int clock_state)
|
||||
{
|
||||
return (( chip->active_clock_hi && !chip->last_clock_state && clock_state) ||
|
||||
(!chip->active_clock_hi && chip->last_clock_state && !clock_state));
|
||||
}
|
||||
|
||||
|
||||
INLINE int current_clock_state(hc55516_state *chip)
|
||||
{
|
||||
return ((UINT64)chip->update_count * chip->clock * 2 / SAMPLE_RATE) & 0x01;
|
||||
}
|
||||
|
||||
|
||||
static void process_digit(hc55516_state *chip)
|
||||
{
|
||||
double integrator = chip->integrator, temp;
|
||||
|
||||
/* shift the bit into the shift register */
|
||||
chip->shiftreg = (chip->shiftreg << 1) | chip->digit;
|
||||
|
||||
/* move the estimator up or down a step based on the bit */
|
||||
if (chip->digit)
|
||||
integrator += chip->filter;
|
||||
else
|
||||
integrator -= chip->filter;
|
||||
|
||||
/* simulate leakage */
|
||||
integrator *= leak;
|
||||
|
||||
/* if we got all 0's or all 1's in the last n bits, bump the step up */
|
||||
if (((chip->shiftreg & chip->shiftreg_mask) == 0) ||
|
||||
((chip->shiftreg & chip->shiftreg_mask) == chip->shiftreg_mask))
|
||||
{
|
||||
chip->filter = FILTER_MAX - ((FILTER_MAX - chip->filter) * charge);
|
||||
|
||||
if (chip->filter > FILTER_MAX)
|
||||
chip->filter = FILTER_MAX;
|
||||
}
|
||||
|
||||
/* simulate decay */
|
||||
else
|
||||
{
|
||||
chip->filter *= decay;
|
||||
|
||||
if (chip->filter < FILTER_MIN)
|
||||
chip->filter = FILTER_MIN;
|
||||
}
|
||||
|
||||
/* compute the sample as a 32-bit word */
|
||||
temp = integrator * SAMPLE_GAIN;
|
||||
chip->integrator = integrator;
|
||||
|
||||
/* compress the sample range to fit better in a 16-bit word */
|
||||
if (temp < 0)
|
||||
chip->next_sample = (int)(temp / (-temp * (1.0 / 32768.0) + 1.0));
|
||||
else
|
||||
chip->next_sample = (int)(temp / (temp * (1.0 / 32768.0) + 1.0));
|
||||
}
|
||||
|
||||
|
||||
static STREAM_UPDATE( hc55516_update )
|
||||
{
|
||||
hc55516_state *chip = (hc55516_state *)param;
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
int i;
|
||||
INT32 sample, slope;
|
||||
|
||||
/* zero-length? bail */
|
||||
if (samples == 0)
|
||||
return;
|
||||
|
||||
if (!is_external_osciallator(chip))
|
||||
{
|
||||
/* track how many samples we've updated without a clock */
|
||||
chip->update_count += samples;
|
||||
if (chip->update_count > SAMPLE_RATE / 32)
|
||||
{
|
||||
chip->update_count = SAMPLE_RATE;
|
||||
chip->next_sample = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the interpolation slope */
|
||||
sample = chip->curr_sample;
|
||||
slope = ((INT32)chip->next_sample - sample) / samples;
|
||||
chip->curr_sample = chip->next_sample;
|
||||
|
||||
if (is_external_osciallator(chip))
|
||||
{
|
||||
/* external oscillator */
|
||||
for (i = 0; i < samples; i++, sample += slope)
|
||||
{
|
||||
UINT8 clock_state;
|
||||
|
||||
*buffer++ = sample;
|
||||
|
||||
chip->update_count++;
|
||||
|
||||
clock_state = current_clock_state(chip);
|
||||
|
||||
/* pull in next digit on the appropriate edge of the clock */
|
||||
if (is_active_clock_transition(chip, clock_state))
|
||||
{
|
||||
chip->digit = chip->new_digit;
|
||||
|
||||
process_digit(chip);
|
||||
}
|
||||
|
||||
chip->last_clock_state = clock_state;
|
||||
}
|
||||
}
|
||||
|
||||
/* software driven clock */
|
||||
else
|
||||
for (i = 0; i < samples; i++, sample += slope)
|
||||
*buffer++ = sample;
|
||||
}
|
||||
|
||||
|
||||
void hc55516_clock_w(device_t *device, int state)
|
||||
{
|
||||
hc55516_state *chip = get_safe_token(device);
|
||||
UINT8 clock_state = state ? TRUE : FALSE;
|
||||
|
||||
/* only makes sense for setups with a software driven clock */
|
||||
assert(!is_external_osciallator(chip));
|
||||
|
||||
/* speech clock changing? */
|
||||
if (is_active_clock_transition(chip, clock_state))
|
||||
{
|
||||
/* update the output buffer before changing the registers */
|
||||
chip->channel->update();
|
||||
|
||||
/* clear the update count */
|
||||
chip->update_count = 0;
|
||||
|
||||
process_digit(chip);
|
||||
}
|
||||
|
||||
/* update the clock */
|
||||
chip->last_clock_state = clock_state;
|
||||
}
|
||||
|
||||
|
||||
void hc55516_digit_w(device_t *device, int digit)
|
||||
{
|
||||
hc55516_state *chip = get_safe_token(device);
|
||||
|
||||
if (is_external_osciallator(chip))
|
||||
{
|
||||
chip->channel->update();
|
||||
chip->new_digit = digit & 1;
|
||||
}
|
||||
else
|
||||
chip->digit = digit & 1;
|
||||
}
|
||||
|
||||
|
||||
int hc55516_clock_state_r(device_t *device)
|
||||
{
|
||||
hc55516_state *chip = get_safe_token(device);
|
||||
|
||||
/* only makes sense for setups with an external oscillator */
|
||||
assert(is_external_osciallator(chip));
|
||||
|
||||
chip->channel->update();
|
||||
|
||||
return current_clock_state(chip);
|
||||
}
|
||||
|
||||
|
||||
const device_type HC55516 = &device_creator<hc55516_device>;
|
||||
@ -300,13 +29,26 @@ hc55516_device::hc55516_device(const machine_config &mconfig, const char *tag, d
|
||||
: device_t(mconfig, HC55516, "HC-55516", tag, owner, clock, "hc55516", __FILE__),
|
||||
device_sound_interface(mconfig, *this)
|
||||
{
|
||||
m_token = global_alloc_clear(hc55516_state);
|
||||
}
|
||||
hc55516_device::hc55516_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_sound_interface(mconfig, *this)
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_channel(NULL),
|
||||
m_active_clock_hi(0),
|
||||
m_shiftreg_mask(0),
|
||||
m_last_clock_state(0),
|
||||
m_digit(0),
|
||||
m_new_digit(0),
|
||||
m_shiftreg(0),
|
||||
m_curr_sample(0),
|
||||
m_next_sample(0),
|
||||
m_update_count(0),
|
||||
m_filter(0),
|
||||
m_integrator(0),
|
||||
m_charge(0),
|
||||
m_decay(0),
|
||||
m_leak(0)
|
||||
{
|
||||
m_token = global_alloc_clear(hc55516_state);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -325,7 +67,7 @@ void hc55516_device::device_config_complete()
|
||||
|
||||
void hc55516_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( hc55516 )(this);
|
||||
start_common(0x07, TRUE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -334,20 +76,9 @@ void hc55516_device::device_start()
|
||||
|
||||
void hc55516_device::device_reset()
|
||||
{
|
||||
DEVICE_RESET_NAME( hc55516 )(this);
|
||||
m_last_clock_state = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void hc55516_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");
|
||||
}
|
||||
|
||||
|
||||
const device_type MC3417 = &device_creator<mc3417_device>;
|
||||
|
||||
mc3417_device::mc3417_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
@ -361,17 +92,7 @@ mc3417_device::mc3417_device(const machine_config &mconfig, const char *tag, dev
|
||||
|
||||
void mc3417_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( mc3417 )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc3417_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");
|
||||
start_common(0x07, FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -388,15 +109,214 @@ mc3418_device::mc3418_device(const machine_config &mconfig, const char *tag, dev
|
||||
|
||||
void mc3418_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( mc3418 )(this);
|
||||
start_common(0x0f, FALSE);
|
||||
}
|
||||
|
||||
|
||||
void hc55516_device::start_common(UINT8 _shiftreg_mask, int _active_clock_hi)
|
||||
{
|
||||
/* compute the fixed charge, decay, and leak time constants */
|
||||
m_charge = pow(exp(-1.0), 1.0 / (FILTER_CHARGE_TC * 16000.0));
|
||||
m_decay = pow(exp(-1.0), 1.0 / (FILTER_DECAY_TC * 16000.0));
|
||||
m_leak = pow(exp(-1.0), 1.0 / (INTEGRATOR_LEAK_TC * 16000.0));
|
||||
|
||||
m_shiftreg_mask = _shiftreg_mask;
|
||||
m_active_clock_hi = _active_clock_hi;
|
||||
m_last_clock_state = 0;
|
||||
|
||||
/* create the stream */
|
||||
m_channel = machine().sound().stream_alloc(*this, 0, 1, SAMPLE_RATE, this);
|
||||
|
||||
save_item(NAME(m_last_clock_state));
|
||||
save_item(NAME(m_digit));
|
||||
save_item(NAME(m_new_digit));
|
||||
save_item(NAME(m_shiftreg));
|
||||
save_item(NAME(m_curr_sample));
|
||||
save_item(NAME(m_next_sample));
|
||||
save_item(NAME(m_update_count));
|
||||
save_item(NAME(m_filter));
|
||||
save_item(NAME(m_integrator));
|
||||
}
|
||||
|
||||
inline int hc55516_device::is_external_oscillator()
|
||||
{
|
||||
return clock() != 0;
|
||||
}
|
||||
|
||||
|
||||
inline int hc55516_device::is_active_clock_transition(int clock_state)
|
||||
{
|
||||
return (( m_active_clock_hi && !m_last_clock_state && clock_state) ||
|
||||
(!m_active_clock_hi && m_last_clock_state && !clock_state));
|
||||
}
|
||||
|
||||
|
||||
inline int hc55516_device::current_clock_state()
|
||||
{
|
||||
return ((UINT64)m_update_count * clock() * 2 / SAMPLE_RATE) & 0x01;
|
||||
}
|
||||
|
||||
|
||||
void hc55516_device::process_digit()
|
||||
{
|
||||
double integrator = m_integrator, temp;
|
||||
|
||||
/* shift the bit into the shift register */
|
||||
m_shiftreg = (m_shiftreg << 1) | m_digit;
|
||||
|
||||
/* move the estimator up or down a step based on the bit */
|
||||
if (m_digit)
|
||||
integrator += m_filter;
|
||||
else
|
||||
integrator -= m_filter;
|
||||
|
||||
/* simulate leakage */
|
||||
integrator *= m_leak;
|
||||
|
||||
/* if we got all 0's or all 1's in the last n bits, bump the step up */
|
||||
if (((m_shiftreg & m_shiftreg_mask) == 0) ||
|
||||
((m_shiftreg & m_shiftreg_mask) == m_shiftreg_mask))
|
||||
{
|
||||
m_filter = FILTER_MAX - ((FILTER_MAX - m_filter) * m_charge);
|
||||
|
||||
if (m_filter > FILTER_MAX)
|
||||
m_filter = FILTER_MAX;
|
||||
}
|
||||
|
||||
/* simulate decay */
|
||||
else
|
||||
{
|
||||
m_filter *= m_decay;
|
||||
|
||||
if (m_filter < FILTER_MIN)
|
||||
m_filter = FILTER_MIN;
|
||||
}
|
||||
|
||||
/* compute the sample as a 32-bit word */
|
||||
temp = integrator * SAMPLE_GAIN;
|
||||
m_integrator = integrator;
|
||||
|
||||
/* compress the sample range to fit better in a 16-bit word */
|
||||
if (temp < 0)
|
||||
m_next_sample = (int)(temp / (-temp * (1.0 / 32768.0) + 1.0));
|
||||
else
|
||||
m_next_sample = (int)(temp / (temp * (1.0 / 32768.0) + 1.0));
|
||||
}
|
||||
|
||||
void hc55516_device::clock_w(int state)
|
||||
{
|
||||
UINT8 clock_state = state ? TRUE : FALSE;
|
||||
|
||||
/* only makes sense for setups with a software driven clock */
|
||||
assert(!is_external_oscillator());
|
||||
|
||||
/* speech clock changing? */
|
||||
if (is_active_clock_transition(clock_state))
|
||||
{
|
||||
/* update the output buffer before changing the registers */
|
||||
m_channel->update();
|
||||
|
||||
/* clear the update count */
|
||||
m_update_count = 0;
|
||||
|
||||
process_digit();
|
||||
}
|
||||
|
||||
/* update the clock */
|
||||
m_last_clock_state = clock_state;
|
||||
}
|
||||
|
||||
|
||||
void hc55516_device::digit_w(int digit)
|
||||
{
|
||||
if (is_external_oscillator())
|
||||
{
|
||||
m_channel->update();
|
||||
m_new_digit = digit & 1;
|
||||
}
|
||||
else
|
||||
m_digit = digit & 1;
|
||||
}
|
||||
|
||||
|
||||
int hc55516_device::clock_state_r()
|
||||
{
|
||||
/* only makes sense for setups with an external oscillator */
|
||||
assert(is_external_oscillator());
|
||||
|
||||
m_channel->update();
|
||||
|
||||
return current_clock_state();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void hc55516_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
int i;
|
||||
INT32 sample, slope;
|
||||
|
||||
/* zero-length? bail */
|
||||
if (samples == 0)
|
||||
return;
|
||||
|
||||
if (!is_external_oscillator())
|
||||
{
|
||||
/* track how many samples we've updated without a clock */
|
||||
m_update_count += samples;
|
||||
if (m_update_count > SAMPLE_RATE / 32)
|
||||
{
|
||||
m_update_count = SAMPLE_RATE;
|
||||
m_next_sample = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the interpolation slope */
|
||||
sample = m_curr_sample;
|
||||
slope = ((INT32)m_next_sample - sample) / samples;
|
||||
m_curr_sample = m_next_sample;
|
||||
|
||||
if (is_external_oscillator())
|
||||
{
|
||||
/* external oscillator */
|
||||
for (i = 0; i < samples; i++, sample += slope)
|
||||
{
|
||||
UINT8 clock_state;
|
||||
|
||||
*buffer++ = sample;
|
||||
|
||||
m_update_count++;
|
||||
|
||||
clock_state = current_clock_state();
|
||||
|
||||
/* pull in next digit on the appropriate edge of the clock */
|
||||
if (is_active_clock_transition(clock_state))
|
||||
{
|
||||
m_digit = m_new_digit;
|
||||
|
||||
process_digit();
|
||||
}
|
||||
|
||||
m_last_clock_state = clock_state;
|
||||
}
|
||||
}
|
||||
|
||||
/* software driven clock */
|
||||
else
|
||||
for (i = 0; i < samples; i++, sample += slope)
|
||||
*buffer++ = sample;
|
||||
}
|
||||
|
||||
void mc3417_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
hc55516_device::sound_stream_update(stream, inputs, outputs, samples);
|
||||
}
|
||||
|
||||
void mc3418_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");
|
||||
hc55516_device::sound_stream_update(stream, inputs, outputs, samples);
|
||||
}
|
||||
|
@ -3,27 +3,23 @@
|
||||
#ifndef __HC55516_H__
|
||||
#define __HC55516_H__
|
||||
|
||||
|
||||
|
||||
/* sets the digit (0 or 1) */
|
||||
void hc55516_digit_w(device_t *device, int digit);
|
||||
|
||||
/* sets the clock state (0 or 1, clocked on the rising edge) */
|
||||
void hc55516_clock_w(device_t *device, int state);
|
||||
|
||||
/* returns whether the clock is currently LO or HI */
|
||||
int hc55516_clock_state_r(device_t *device);
|
||||
|
||||
class hc55516_device : public device_t,
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
hc55516_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
hc55516_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
~hc55516_device() { global_free(m_token); }
|
||||
~hc55516_device() {}
|
||||
|
||||
// access to legacy token
|
||||
void *token() const { assert(m_token != NULL); return m_token; }
|
||||
/* sets the digit (0 or 1) */
|
||||
void digit_w(int digit);
|
||||
|
||||
/* sets the clock state (0 or 1, clocked on the rising edge) */
|
||||
void clock_w(int state);
|
||||
|
||||
/* returns whether the clock is currently LO or HI */
|
||||
int clock_state_r();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete();
|
||||
@ -32,9 +28,35 @@ protected:
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
private:
|
||||
|
||||
void start_common(UINT8 _shiftreg_mask, int _active_clock_hi);
|
||||
|
||||
// internal state
|
||||
void *m_token;
|
||||
sound_stream *m_channel;
|
||||
int m_active_clock_hi;
|
||||
UINT8 m_shiftreg_mask;
|
||||
|
||||
UINT8 m_last_clock_state;
|
||||
UINT8 m_digit;
|
||||
UINT8 m_new_digit;
|
||||
UINT8 m_shiftreg;
|
||||
|
||||
INT16 m_curr_sample;
|
||||
INT16 m_next_sample;
|
||||
|
||||
UINT32 m_update_count;
|
||||
|
||||
double m_filter;
|
||||
double m_integrator;
|
||||
|
||||
double m_charge;
|
||||
double m_decay;
|
||||
double m_leak;
|
||||
|
||||
inline int is_external_oscillator();
|
||||
inline int is_active_clock_transition(int clock_state);
|
||||
inline int current_clock_state();
|
||||
void process_digit();
|
||||
};
|
||||
|
||||
extern const device_type HC55516;
|
||||
|
@ -103,7 +103,7 @@ struct exidy_sound_state
|
||||
int m_has_sh8253;
|
||||
|
||||
/* 5220/CVSD variables */
|
||||
device_t *m_cvsd;
|
||||
hc55516_device *m_cvsd;
|
||||
tms5220_device *m_tms;
|
||||
pia6821_device *m_pia1;
|
||||
|
||||
@ -851,7 +851,7 @@ static DEVICE_START( venture_common_sh_start )
|
||||
state->m_pia1 = device->machine().device<pia6821_device>("pia1");
|
||||
|
||||
/* determine which sound hardware is installed */
|
||||
state->m_cvsd = device->machine().device("cvsd");
|
||||
state->m_cvsd = device->machine().device<hc55516_device>("cvsd");
|
||||
|
||||
/* 8253 */
|
||||
state->m_freq_to_step = (double)(1 << 24) / (double)SH8253_CLOCK;
|
||||
@ -975,7 +975,7 @@ static WRITE8_DEVICE_HANDLER( mtrap_voiceio_w )
|
||||
exidy_sound_state *state = get_safe_token(device);
|
||||
|
||||
if (!(offset & 0x10))
|
||||
hc55516_digit_w(state->m_cvsd, data & 1);
|
||||
state->m_cvsd->digit_w(data & 1);
|
||||
|
||||
if (!(offset & 0x20))
|
||||
state->m_riot->portb_in_set(data & 1, 0xff);
|
||||
@ -996,7 +996,7 @@ static READ8_DEVICE_HANDLER( mtrap_voiceio_r )
|
||||
}
|
||||
|
||||
if (!(offset & 0x40))
|
||||
return hc55516_clock_state_r(state->m_cvsd) << 7;
|
||||
return state->m_cvsd->clock_state_r() << 7;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "cpu/i8085/i8085.h"
|
||||
#include "machine/6821pia.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/hc55516.h"
|
||||
#include "includes/redalert.h"
|
||||
#include "drivlgcy.h"
|
||||
|
||||
@ -162,13 +161,13 @@ WRITE8_MEMBER(redalert_state::redalert_voice_command_w)
|
||||
|
||||
WRITE_LINE_MEMBER(redalert_state::sod_callback)
|
||||
{
|
||||
hc55516_digit_w(machine().device("cvsd"), state);
|
||||
m_cvsd->digit_w(state);
|
||||
}
|
||||
|
||||
|
||||
READ_LINE_MEMBER(redalert_state::sid_callback)
|
||||
{
|
||||
return hc55516_clock_state_r(machine().device("cvsd"));
|
||||
return m_cvsd->clock_state_r();
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,8 +168,8 @@ WRITE8_MEMBER(williams_cvsd_sound_device::talkback_w)
|
||||
|
||||
WRITE8_MEMBER(williams_cvsd_sound_device::cvsd_digit_clock_clear_w)
|
||||
{
|
||||
hc55516_digit_w(m_hc55516, data);
|
||||
hc55516_clock_w(m_hc55516, 0);
|
||||
m_hc55516->digit_w(data);
|
||||
m_hc55516->clock_w(0);
|
||||
}
|
||||
|
||||
|
||||
@ -179,7 +179,7 @@ WRITE8_MEMBER(williams_cvsd_sound_device::cvsd_digit_clock_clear_w)
|
||||
|
||||
WRITE8_MEMBER(williams_cvsd_sound_device::cvsd_clock_set_w)
|
||||
{
|
||||
hc55516_clock_w(m_hc55516, 1);
|
||||
m_hc55516->clock_w(1);
|
||||
}
|
||||
|
||||
|
||||
@ -524,8 +524,8 @@ WRITE8_MEMBER(williams_narc_sound_device::slave_sync_w)
|
||||
|
||||
WRITE8_MEMBER(williams_narc_sound_device::cvsd_digit_clock_clear_w)
|
||||
{
|
||||
hc55516_digit_w(m_hc55516, data);
|
||||
hc55516_clock_w(m_hc55516, 0);
|
||||
m_hc55516->digit_w(data);
|
||||
m_hc55516->clock_w(0);
|
||||
}
|
||||
|
||||
|
||||
@ -535,7 +535,7 @@ WRITE8_MEMBER(williams_narc_sound_device::cvsd_digit_clock_clear_w)
|
||||
|
||||
WRITE8_MEMBER(williams_narc_sound_device::cvsd_clock_set_w)
|
||||
{
|
||||
hc55516_clock_w(m_hc55516, 1);
|
||||
m_hc55516->clock_w(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
m_cpu_0(*this, "cpu0"),
|
||||
m_cpu_1(*this, "cpu1"),
|
||||
m_nsc(*this, "nsc"),
|
||||
m_msm(*this, "msm") { }
|
||||
m_msm(*this, "msm"),
|
||||
m_cvsd(*this, "cvsd") { }
|
||||
|
||||
/* sound-related */
|
||||
// Jangou CVSD Sound
|
||||
@ -62,8 +63,9 @@ public:
|
||||
/* devices */
|
||||
required_device<cpu_device> m_cpu_0;
|
||||
optional_device<cpu_device> m_cpu_1;
|
||||
device_t *m_cvsd;
|
||||
optional_device<cpu_device> m_nsc;
|
||||
optional_device<msm5205_device> m_msm;
|
||||
optional_device<hc55516_device> m_cvsd;
|
||||
|
||||
/* video-related */
|
||||
UINT8 m_pen_data[0x10];
|
||||
@ -99,7 +101,6 @@ public:
|
||||
UINT8 jangou_gfx_nibble( UINT16 niboffset );
|
||||
void plot_jangou_gfx_pixel( UINT8 pix, int x, int y );
|
||||
DECLARE_WRITE_LINE_MEMBER(jngolady_vclk_cb);
|
||||
optional_device<msm5205_device> m_msm;
|
||||
};
|
||||
|
||||
|
||||
@ -338,7 +339,7 @@ WRITE8_MEMBER(jangou_state::cvsd_w)
|
||||
TIMER_CALLBACK_MEMBER(jangou_state::cvsd_bit_timer_callback)
|
||||
{
|
||||
/* Data is shifted out at the MSB */
|
||||
hc55516_digit_w(m_cvsd, (m_cvsd_shiftreg >> 7) & 1);
|
||||
m_cvsd->digit_w((m_cvsd_shiftreg >> 7) & 1);
|
||||
m_cvsd_shiftreg <<= 1;
|
||||
|
||||
/* Trigger an IRQ for every 8 shifted bits */
|
||||
@ -922,8 +923,6 @@ static SOUND_START( jangou )
|
||||
|
||||
MACHINE_START_MEMBER(jangou_state,common)
|
||||
{
|
||||
m_cvsd = machine().device("cvsd");
|
||||
|
||||
save_item(NAME(m_pen_data));
|
||||
save_item(NAME(m_blit_data));
|
||||
save_item(NAME(m_mux_data));
|
||||
|
@ -424,14 +424,14 @@ WRITE_LINE_MEMBER( s11_state::pias_ca2_w )
|
||||
{
|
||||
// speech clock
|
||||
if(m_hc55516)
|
||||
hc55516_clock_w(m_hc55516, state);
|
||||
m_hc55516->clock_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( s11_state::pias_cb2_w )
|
||||
{
|
||||
// speech data
|
||||
if(m_hc55516)
|
||||
hc55516_digit_w(m_hc55516, state);
|
||||
m_hc55516->digit_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( s11_state::dac_r )
|
||||
|
@ -152,13 +152,13 @@ MACHINE_RESET_MEMBER( s11b_state, s11b )
|
||||
WRITE8_MEMBER( s11b_state::bg_speech_clock_w )
|
||||
{
|
||||
// pulses clock input?
|
||||
hc55516_clock_w(m_bg_hc55516, 1);
|
||||
hc55516_clock_w(m_bg_hc55516, 0);
|
||||
m_bg_hc55516->clock_w(1);
|
||||
m_bg_hc55516->clock_w(0);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( s11b_state::bg_speech_digit_w )
|
||||
{
|
||||
hc55516_digit_w(m_bg_hc55516, data);
|
||||
m_bg_hc55516->digit_w(data);
|
||||
}
|
||||
|
||||
static const pia6821_interface pia21_intf =
|
||||
|
@ -429,13 +429,13 @@ READ_LINE_MEMBER( s6_state::pias_cb1_r )
|
||||
WRITE_LINE_MEMBER( s6_state::pias_cb2_w )
|
||||
{
|
||||
// speech clock
|
||||
hc55516_clock_w(m_hc55516, state);
|
||||
m_hc55516->clock_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( s6_state::pias_ca2_w )
|
||||
{
|
||||
// speech data
|
||||
hc55516_digit_w(m_hc55516, state);
|
||||
m_hc55516->digit_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( s6_state::dac_r )
|
||||
|
@ -432,13 +432,13 @@ READ_LINE_MEMBER( s6a_state::pias_cb1_r )
|
||||
WRITE_LINE_MEMBER( s6a_state::pias_cb2_w )
|
||||
{
|
||||
// speech clock
|
||||
hc55516_clock_w(m_hc55516, state);
|
||||
m_hc55516->clock_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( s6a_state::pias_ca2_w )
|
||||
{
|
||||
// speech data
|
||||
hc55516_digit_w(m_hc55516, state);
|
||||
m_hc55516->digit_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( s6a_state::dac_r )
|
||||
|
@ -426,13 +426,13 @@ static const pia6821_interface pia30_intf =
|
||||
WRITE_LINE_MEMBER( s7_state::pias_cb2_w )
|
||||
{
|
||||
// speech clock
|
||||
hc55516_clock_w(m_hc55516, state);
|
||||
m_hc55516->clock_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( s7_state::pias_ca2_w )
|
||||
{
|
||||
// speech data
|
||||
hc55516_digit_w(m_hc55516, state);
|
||||
m_hc55516->digit_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( s7_state::dac_r )
|
||||
|
@ -344,13 +344,13 @@ READ_LINE_MEMBER( s9_state::pias_ca1_r )
|
||||
WRITE_LINE_MEMBER( s9_state::pias_ca2_w )
|
||||
{
|
||||
// speech clock
|
||||
hc55516_clock_w(m_hc55516, state);
|
||||
m_hc55516->clock_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( s9_state::pias_cb2_w )
|
||||
{
|
||||
// speech data
|
||||
hc55516_digit_w(m_hc55516, state);
|
||||
m_hc55516->digit_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( s9_state::dac_r )
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "sound/hc55516.h"
|
||||
|
||||
class redalert_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -17,14 +19,21 @@ public:
|
||||
m_video_control(*this, "video_control"),
|
||||
m_bitmap_color(*this, "bitmap_color"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu") { }
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_cvsd(*this, "cvsd") { }
|
||||
|
||||
UINT8 m_ay8910_latch_1;
|
||||
UINT8 m_ay8910_latch_2;
|
||||
|
||||
required_shared_ptr<UINT8> m_bitmap_videoram;
|
||||
required_shared_ptr<UINT8> m_charmap_videoram;
|
||||
required_shared_ptr<UINT8> m_video_control;
|
||||
required_shared_ptr<UINT8> m_bitmap_color;
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
optional_device<hc55516_device> m_cvsd;
|
||||
|
||||
UINT8 *m_bitmap_colorram;
|
||||
UINT8 m_control_xor;
|
||||
DECLARE_READ8_MEMBER(redalert_interrupt_clear_r);
|
||||
@ -52,8 +61,6 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(demoneye_ay8910_data_w);
|
||||
void get_pens(pen_t *pens);
|
||||
void get_panther_pens(pen_t *pens);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
};
|
||||
/*----------- defined in audio/redalert.c -----------*/
|
||||
|
||||
|
@ -96,7 +96,7 @@ const pia6821_interface lottofun_pia_0_intf =
|
||||
const pia6821_interface sinistar_snd_pia_intf =
|
||||
{
|
||||
/*inputs : A/B,CA/B1,CA/B2 */ DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL,
|
||||
/*outputs: A/B,CA/B2 */ DEVCB_DEVICE_MEMBER("wmsdac", dac_device, write_unsigned8), DEVCB_NULL, DEVCB_DEVICE_LINE("cvsd", hc55516_digit_w), DEVCB_DEVICE_LINE("cvsd", hc55516_clock_w),
|
||||
/*outputs: A/B,CA/B2 */ DEVCB_DEVICE_MEMBER("wmsdac", dac_device, write_unsigned8), DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER("cvsd", hc55516_device, digit_w), DEVCB_DEVICE_LINE_MEMBER("cvsd", hc55516_device, clock_w),
|
||||
/*irqs : A/B */ DEVCB_DRIVER_LINE_MEMBER(williams_state,williams_snd_irq), DEVCB_DRIVER_LINE_MEMBER(williams_state,williams_snd_irq)
|
||||
};
|
||||
|
||||
|
@ -417,7 +417,7 @@ static MC6852_INTERFACE( ssda_intf )
|
||||
0,
|
||||
0,
|
||||
DEVCB_NULL,
|
||||
DEVCB_DEVICE_LINE(HC55516_TAG, hc55516_digit_w),
|
||||
DEVCB_DEVICE_LINE_MEMBER(HC55516_TAG, hc55516_device, digit_w),
|
||||
DEVCB_DRIVER_LINE_MEMBER(victor9k_state, ssda_irq_w),
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
|
Loading…
Reference in New Issue
Block a user