summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/tms5110.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/tms5110.cpp')
-rw-r--r--src/devices/sound/tms5110.cpp178
1 files changed, 69 insertions, 109 deletions
diff --git a/src/devices/sound/tms5110.cpp b/src/devices/sound/tms5110.cpp
index b7bef7f741e..e2d77d130fc 100644
--- a/src/devices/sound/tms5110.cpp
+++ b/src/devices/sound/tms5110.cpp
@@ -149,13 +149,10 @@ static int16_t clip_analog(int16_t cliptemp);
void tms5110_device::new_int_write(uint8_t rc, uint8_t m0, uint8_t m1, uint8_t addr)
{
- if (!m_m0_cb.isnull())
- m_m0_cb(m0);
- if (!m_m1_cb.isnull())
- m_m1_cb(m1);
- if (!m_addr_cb.isnull())
- m_addr_cb((offs_t)0, addr);
- if (!m_romclk_cb.isnull())
+ m_m0_cb(m0);
+ m_m1_cb(m1);
+ m_addr_cb(offs_t(0), addr);
+ if (!m_romclk_cb.isunset())
{
//printf("rc %d\n", rc);
m_romclk_cb(rc);
@@ -176,7 +173,7 @@ uint8_t tms5110_device::new_int_read()
new_int_write(0, 1, 0, 0); // romclk 0, m0 1, m1 0, addr bus nybble = 0/open bus
new_int_write(1, 0, 0, 0); // romclk 1, m0 0, m1 0, addr bus nybble = 0/open bus
new_int_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus
- if (!m_data_cb.isnull())
+ if (!m_data_cb.isunset())
return m_data_cb();
if (DEBUG_5110) logerror("WARNING: CALLBACK MISSING, RETURNING 0!\n");
return 0;
@@ -240,6 +237,7 @@ void tms5110_device::register_for_save_states()
save_item(NAME(m_romclk_hack_state));
}
+
/**********************************************************************************************
printbits helper function: takes a long int input and prints the resulting bits to stderr
@@ -280,11 +278,11 @@ static void printbits(long data, int num)
/******************************************************************************************
- extract_bits -- extract a specific number of bits from the VSM
+ read_bits -- read a specific number of bits from the VSM
******************************************************************************************/
-int tms5110_device::extract_bits(int count)
+int tms5110_device::read_bits(int count)
{
int val = 0;
if (DEBUG_5110) logerror("requesting %d bits", count);
@@ -310,7 +308,6 @@ void tms5110_device::perform_dummy_read()
-
/**********************************************************************************************
tms5110_process -- fill the buffer with a specific number of samples
@@ -588,6 +585,7 @@ void tms5110_device::process(int16_t *buffer, unsigned int size)
}
}
+
/**********************************************************************************************
clip_analog -- clips the 14 bit return value from the lattice filter to its final 10 bit value (-512 to 511), and upshifts/range extends this to 16 bits
@@ -598,7 +596,8 @@ static int16_t clip_analog(int16_t cliptemp)
{
/* clipping, just like the patent shows:
* the top 10 bits of this result are visible on the digital output IO pin.
- * next, if the top 3 bits of the 14 bit result are all the same, the lowest of those 3 bits plus the next 7 bits are the signed analog output, otherwise the low bits are all forced to match the inverse of the topmost bit, i.e.:
+ * next, if the top 3 bits of the 14 bit result are all the same, the lowest of those 3 bits plus the next 7 bits are the signed analog output,
+ * otherwise the low bits are all forced to match the inverse of the topmost bit, i.e.:
* 1x xxxx xxxx xxxx -> 0b10000000
* 11 1bcd efgh xxxx -> 0b1bcdefgh
* 00 0bcd efgh xxxx -> 0b0bcdefgh
@@ -636,6 +635,7 @@ static int16_t clip_analog(int16_t cliptemp)
output, this makes almost no difference in the computation.
**********************************************************************************************/
+
static int32_t matrix_multiply(int32_t a, int32_t b)
{
int32_t result;
@@ -651,6 +651,7 @@ static int32_t matrix_multiply(int32_t a, int32_t b)
return result;
}
+
/**********************************************************************************************
lattice_filter -- executes one 'full run' of the lattice filter on a specific byte of
@@ -727,7 +728,6 @@ int32_t tms5110_device::lattice_filter()
-
/******************************************************************************************
PDC_set -- set Processor Data Clock. Execute CTL_pins command on hi-lo transition.
@@ -849,7 +849,7 @@ void tms5110_device::PDC_set(int data)
fprintf(stderr,"actually reading a bit now\n");
#endif
m_CTL_buffer >>= 1;
- m_CTL_buffer |= (extract_bits(1)<<3);
+ m_CTL_buffer |= (read_bits(1)<<3);
m_CTL_buffer &= 0xF;
}
break;
@@ -927,7 +927,7 @@ void tms5110_device::parse_frame()
m_uv_zpar = m_zpar = 0;
// attempt to extract the energy index
- m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits);
+ m_new_frame_energy_idx = read_bits(m_coeff->energy_bits);
#ifdef DEBUG_PARSE_FRAME_DUMP
printbits(m_new_frame_energy_idx,m_coeff->energy_bits);
fprintf(stderr," ");
@@ -937,13 +937,13 @@ void tms5110_device::parse_frame()
if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15))
return;
- rep_flag = extract_bits(1);
+ rep_flag = read_bits(1);
#ifdef DEBUG_PARSE_FRAME_DUMP
printbits(rep_flag, 1);
fprintf(stderr," ");
#endif
- m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits);
+ m_new_frame_pitch_idx = read_bits(m_coeff->pitch_bits);
#ifdef DEBUG_PARSE_FRAME_DUMP
printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits);
fprintf(stderr," ");
@@ -957,7 +957,7 @@ void tms5110_device::parse_frame()
// extract first 4 K coefficients
for (i = 0; i < 4; i++)
{
- m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
+ m_new_frame_k_idx[i] = read_bits(m_coeff->kbits[i]);
#ifdef DEBUG_PARSE_FRAME_DUMP
printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
fprintf(stderr," ");
@@ -974,7 +974,7 @@ void tms5110_device::parse_frame()
// If we got here, we need the remaining 6 K's
for (i = 4; i < m_coeff->num_k; i++)
{
- m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]);
+ m_new_frame_k_idx[i] = read_bits(m_coeff->kbits[i]);
#ifdef DEBUG_PARSE_FRAME_DUMP
printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]);
fprintf(stderr," ");
@@ -987,29 +987,6 @@ void tms5110_device::parse_frame()
}
-#if 0
-/*This is an example word TEN taken from the TMS5110A datasheet*/
-static const unsigned int example_word_TEN[619]={
-/* 1*/1,0,0,0, 0, 0,0,0,0,0, 1,1,0,0,0, 0,0,0,1,0, 0,1,1,1, 0,1,0,1,
-/* 2*/1,0,0,0, 0, 0,0,0,0,0, 1,0,0,1,0, 0,0,1,1,0, 0,0,1,1, 0,1,0,1,
-/* 3*/1,1,0,0, 0, 1,0,0,0,0, 1,0,1,0,0, 0,1,0,1,0, 0,1,0,0, 1,0,1,0, 1,0,0,0, 1,0,0,1, 0,1,0,1, 0,0,1, 0,1,0, 0,1,1,
-/* 4*/1,1,1,0, 0, 0,1,1,1,1, 1,0,1,0,1, 0,1,1,1,0, 0,1,0,1, 0,1,1,1, 0,1,1,1, 1,0,1,1, 1,0,1,0, 0,1,1, 0,1,0, 0,1,1,
-/* 5*/1,1,1,0, 0, 1,0,0,0,0, 1,0,1,0,0, 0,1,1,1,0, 0,1,0,1, 1,0,1,0, 1,0,0,0, 1,1,0,0, 1,0,1,1, 1,0,0, 0,1,0, 0,1,1,
-/* 6*/1,1,1,0, 0, 1,0,0,0,1, 1,0,1,0,1, 0,1,1,0,1, 0,1,1,0, 0,1,1,1, 0,1,1,1, 1,0,1,0, 1,0,1,0, 1,1,0, 0,0,1, 1,0,0,
-/* 7*/1,1,1,0, 0, 1,0,0,1,0, 1,0,1,1,1, 0,1,1,1,0, 0,1,1,1, 0,1,1,1, 0,1,0,1, 0,1,1,0, 1,0,0,1, 1,1,0, 0,1,0, 0,1,1,
-/* 8*/1,1,1,0, 1, 1,0,1,0,1,
-/* 9*/1,1,1,0, 0, 1,1,0,0,1, 1,0,1,1,1, 0,1,0,1,1, 1,0,1,1, 0,1,1,1, 0,1,0,0, 1,0,0,0, 1,0,0,0, 1,1,0, 0,1,1, 0,1,1,
-/*10*/1,1,0,1, 0, 1,1,0,1,0, 1,0,1,0,1, 0,1,1,0,1, 1,0,1,1, 0,1,0,1, 0,1,0,0, 1,0,0,0, 1,0,1,0, 1,1,0, 0,1,0, 1,0,0,
-/*11*/1,0,1,1, 0, 1,1,0,1,1, 1,0,0,1,1, 1,0,0,1,0, 0,1,1,0, 0,0,1,1, 0,1,0,1, 1,0,0,1, 1,0,1,0, 1,0,0, 0,1,1, 0,1,1,
-/*12*/1,0,0,0, 0, 1,1,1,0,0, 1,0,0,1,1, 0,0,1,1,0, 0,1,0,0, 0,1,1,0, 1,1,0,0, 0,1,0,1, 1,0,0,0, 1,0,0, 0,1,0, 1,0,1,
-/*13*/0,1,1,1, 1, 1,1,1,0,1,
-/*14*/0,1,1,1, 0, 1,1,1,1,0, 1,0,0,1,1, 0,0,1,1,1, 0,1,0,1, 0,1,0,1, 1,1,0,0, 0,1,1,1, 1,0,0,0, 1,0,0, 0,1,0, 1,0,1,
-/*15*/0,1,1,0, 0, 1,1,1,1,0, 1,0,1,0,1, 0,0,1,1,0, 0,1,0,0, 0,0,1,1, 1,1,0,0, 1,0,0,1, 0,1,1,1, 1,0,1, 0,1,0, 1,0,1,
-/*16*/1,1,1,1
-};
-#endif
-
-
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@@ -1040,18 +1017,11 @@ void tms5110_device::device_start()
fatalerror("Unknown variant in tms5110_create\n");
}
- /* resolve lines */
- m_m0_cb.resolve();
- m_m1_cb.resolve();
- m_romclk_cb.resolve();
- m_addr_cb.resolve();
- m_data_cb.resolve();
-
/* initialize a stream */
- m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80);
+ m_stream = stream_alloc(0, 1, clock() / 80);
m_state = CTL_STATE_INPUT; /* most probably not defined */
- m_romclk_hack_timer = timer_alloc(0);
+ m_romclk_hack_timer = timer_alloc(FUNC(tms5110_device::romclk_hack_toggle), this);
register_for_save_states();
}
@@ -1108,6 +1078,10 @@ void tms5110_device::device_reset()
m_next_is_address = false;
m_address = 0;
m_addr_bit = 0;
+
+ m_romclk_hack_timer->adjust(attotime::never);
+ m_romclk_hack_timer_started = false;
+ m_romclk_hack_state = false;
}
@@ -1115,11 +1089,12 @@ void tms5110_device::device_reset()
/******************************************************************************
tms5110_ctl_w -- write Control Command to the sound chip
-commands like Speech, Reset, etc., are loaded into the chip via the CTL pins
+
+ commands like Speech, Reset, etc., are loaded into the chip via the CTL pins
******************************************************************************/
-WRITE8_MEMBER( tms5110_device::ctl_w )
+void tms5110_device::ctl_w(uint8_t data)
{
/* bring up to date first */
m_stream->update();
@@ -1133,7 +1108,7 @@ WRITE8_MEMBER( tms5110_device::ctl_w )
******************************************************************************/
-WRITE_LINE_MEMBER( tms5110_device::pdc_w )
+void tms5110_device::pdc_w(int state)
{
/* bring up to date first */
m_stream->update();
@@ -1159,7 +1134,7 @@ WRITE_LINE_MEMBER( tms5110_device::pdc_w )
******************************************************************************/
-READ8_MEMBER( tms5110_device::ctl_r )
+uint8_t tms5110_device::ctl_r()
{
/* bring up to date first */
m_stream->update();
@@ -1180,25 +1155,23 @@ READ8_MEMBER( tms5110_device::ctl_r )
}
}
-READ8_MEMBER( m58817_device::status_r )
+uint8_t m58817_device::status_r()
{
/* bring up to date first */
m_stream->update();
- return (TALK_STATUS() << 0); /*CTL1 = still talking ? */
+ return (TALK_STATUS() << 0); /* CTL1 = still talking ? */
}
-/******************************************************************************
-
- tms5110_romclk_hack_r -- read status of romclk
-
-******************************************************************************/
-
-void tms5110_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(tms5110_device::romclk_hack_toggle)
{
m_romclk_hack_state = !m_romclk_hack_state;
}
-READ_LINE_MEMBER( tms5110_device::romclk_hack_r )
+//-------------------------------------------------
+// romclk_hack_r - read status of romclk
+//-------------------------------------------------
+
+int tms5110_device::romclk_hack_r()
{
/* bring up to date first */
m_stream->update();
@@ -1215,32 +1188,25 @@ READ_LINE_MEMBER( tms5110_device::romclk_hack_r )
/******************************************************************************
- tms5110_update -- update the sound chip so that it is in sync with CPU execution
+ sound_stream_update -- update the sound chip so that it is in sync with CPU execution
******************************************************************************/
-//-------------------------------------------------
-// sound_stream_update - handle a stream update
-//-------------------------------------------------
-
-void tms5110_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void tms5110_device::sound_stream_update(sound_stream &stream)
{
int16_t sample_data[MAX_SAMPLE_CHUNK];
- stream_sample_t *buffer = outputs[0];
/* loop while we still have samples to generate */
- while (samples)
+ for (int sampindex = 0; sampindex < stream.samples(); )
{
- int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples;
- int index;
+ int length = stream.samples() - sampindex;
+ if (length > MAX_SAMPLE_CHUNK)
+ length = MAX_SAMPLE_CHUNK;
/* generate the samples and copy to the target buffer */
process(sample_data, length);
- for (index = 0; index < length; index++)
- *buffer++ = sample_data[index];
-
- /* account for the samples */
- samples -= length;
+ for (int index = 0; index < length; index++)
+ stream.put_int(0, sampindex++, sample_data[index], 32768);
}
}
@@ -1248,7 +1214,7 @@ void tms5110_device::sound_stream_update(sound_stream &stream, stream_sample_t *
/******************************************************************************
- tms5110_set_frequency -- adjusts the playback frequency
+ device_clock_changed -- adjusts the playback frequency
******************************************************************************/
@@ -1324,7 +1290,7 @@ void tmsprom_device::update_prom_cnt()
m_prom_cnt &= 0x0f;
}
-void tmsprom_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(tmsprom_device::update_romclk)
{
/* only 16 bytes needed ... The original dump is bad. This
* is what is needed to get speech to work. The prom data has
@@ -1334,10 +1300,8 @@ void tmsprom_device::device_timer(emu_timer &timer, device_timer_id id, int para
* static const int prom[16] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00,
* 0x02, 0x00, 0x40, 0x00, 0x04, 0x06, 0x04, 0x84 };
*/
- uint16_t ctrl;
-
update_prom_cnt();
- ctrl = (m_prom[m_prom_cnt] | 0x200);
+ uint16_t ctrl = (m_prom[m_prom_cnt] | 0x200);
//if (m_enable && m_prom_cnt < 0x10) printf("ctrl %04x, enable %d cnt %d\n", ctrl, m_enable, m_prom_cnt);
m_prom_cnt = ((m_prom_cnt + 1) & 0x0f) | (m_prom_cnt & 0x10);
@@ -1357,11 +1321,7 @@ void tmsprom_device::device_timer(emu_timer &timer, device_timer_id id, int para
void tmsprom_device::device_start()
{
- /* resolve lines */
- m_pdc_cb.resolve_safe();
- m_ctl_cb.resolve_safe();
-
- m_romclk_timer = timer_alloc(0);
+ m_romclk_timer = timer_alloc(FUNC(tmsprom_device::update_romclk), this);
m_romclk_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()));
m_bit = 0;
@@ -1374,7 +1334,7 @@ void tmsprom_device::device_start()
register_for_save_states();
}
-WRITE_LINE_MEMBER( tmsprom_device::m0_w )
+void tmsprom_device::m0_w(int state)
{
/* falling edge counts */
if (m_m0 && !state)
@@ -1385,24 +1345,24 @@ WRITE_LINE_MEMBER( tmsprom_device::m0_w )
m_m0 = state;
}
-READ_LINE_MEMBER( tmsprom_device::data_r )
+int tmsprom_device::data_r()
{
return (m_rom[m_base_address + m_address] >> m_bit) & 0x01;
}
-WRITE8_MEMBER( tmsprom_device::rom_csq_w )
+void tmsprom_device::rom_csq_w(offs_t offset, uint8_t data)
{
if (!data)
m_base_address = offset * m_rom_size;
}
-WRITE8_MEMBER( tmsprom_device::bit_w )
+void tmsprom_device::bit_w(uint8_t data)
{
m_bit = data;
}
-WRITE_LINE_MEMBER( tmsprom_device::enable_w )
+void tmsprom_device::enable_w(int state)
{
if (state != m_enable)
{
@@ -1452,7 +1412,7 @@ tms5110_device::tms5110_device(const machine_config &mconfig, device_type type,
, m_m0_cb(*this)
, m_m1_cb(*this)
, m_addr_cb(*this)
- , m_data_cb(*this)
+ , m_data_cb(*this, 0)
, m_romclk_cb(*this)
{
}
@@ -1509,18 +1469,18 @@ m58817_device::m58817_device(const machine_config &mconfig, const char *tag, dev
DEFINE_DEVICE_TYPE(TMSPROM, tmsprom_device, "tmsprom", "TMSPROM")
tmsprom_device::tmsprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, TMSPROM, tag, owner, clock),
- m_rom(*this, DEVICE_SELF),
- m_prom(*this, finder_base::DUMMY_TAG, 0x20),
- m_rom_size(0),
- m_pdc_bit(0),
- m_ctl1_bit(0),
- m_ctl2_bit(0),
- m_ctl4_bit(0),
- m_ctl8_bit(0),
- m_reset_bit(0),
- m_stop_bit(0),
- m_pdc_cb(*this),
- m_ctl_cb(*this)
+ : device_t(mconfig, TMSPROM, tag, owner, clock)
+ , m_rom(*this, DEVICE_SELF)
+ , m_prom(*this, finder_base::DUMMY_TAG)
+ , m_rom_size(0)
+ , m_pdc_bit(0)
+ , m_ctl1_bit(0)
+ , m_ctl2_bit(0)
+ , m_ctl4_bit(0)
+ , m_ctl8_bit(0)
+ , m_reset_bit(0)
+ , m_stop_bit(0)
+ , m_pdc_cb(*this)
+ , m_ctl_cb(*this)
{
}