cvs.c: updated the driver to use modern speech rom reading. [Fabio Priuli]

tms5110.c: removed legacy handlers, now that no drivers use them anymore. [Fabio Priuli] 

tms5110: updated to use devcb2. nw.
This commit is contained in:
Fabio Priuli 2014-04-12 16:47:40 +00:00
parent 5e378738aa
commit 5bb0f4f4d7
12 changed files with 93 additions and 217 deletions

View File

@ -109,9 +109,6 @@ void tms6100_device::device_config_complete()
void tms6100_device::device_start()
{
//static const tms5110_interface dummy = { 0 };
//tms->intf = device->static_config ? (const tms5110_interface *)device->static_config : &dummy;
m_rom = *region();
// save device variables

View File

@ -265,17 +265,17 @@ static const int tune4[13*6] = {
static const int *const tunes[] = {NULL,tune1,tune2,tune3,tune4};
#define DECAY(voice) \
if( m_vol[voice] > VMIN ) \
if( m_vol[voice] > TMS36XX_VMIN ) \
{ \
/* decay of first voice */ \
m_vol_counter[voice] -= m_decay[voice]; \
while( m_vol_counter[voice] <= 0 ) \
{ \
m_vol_counter[voice] += samplerate; \
if( m_vol[voice]-- <= VMIN ) \
if( m_vol[voice]-- <= TMS36XX_VMIN ) \
{ \
m_frequency[voice] = 0; \
m_vol[voice] = VMIN; \
m_vol[voice] = TMS36XX_VMIN; \
break; \
} \
} \
@ -287,7 +287,7 @@ static const int *const tunes[] = {NULL,tune1,tune2,tune3,tune4};
m_frequency[m_shift+voice] = \
tunes[m_tune_num][m_tune_ofs*6+voice] * \
(m_basefreq << m_octave) / FSCALE; \
m_vol[m_shift+voice] = VMAX; \
m_vol[m_shift+voice] = TMS36XX_VMAX; \
}
#define TONE(voice) \
@ -361,7 +361,7 @@ void tms36xx_device::device_start()
{
if (m_decay_time[j] > 0)
{
m_decay[j+0] = m_decay[j+6] = VMAX / m_decay_time[j];
m_decay[j+0] = m_decay[j+6] = TMS36XX_VMAX / m_decay_time[j];
enable |= 0x41 << j;
}
}
@ -410,7 +410,7 @@ void tms36xx_device::sound_stream_update(sound_stream &stream, stream_sample_t *
if( (m_note_counter -= n) <= 0 )
{
m_note_counter += VMAX;
m_note_counter += TMS36XX_VMAX;
if (m_tune_ofs < m_tune_max)
{
/* shift to the other 'bank' of voices */

View File

@ -31,11 +31,8 @@
#define TMS3615 15 // Naughty Boy, Pleiads (13 notes, one output)
#define TMS3617 17 // Monster Bash (13 notes, six outputs)
#undef VMIN
#undef VMAX
#define VMIN 0x0000
#define VMAX 0x7fff
#define TMS36XX_VMIN 0x0000
#define TMS36XX_VMAX 0x7fff
// ======================> tms36xx_device
@ -68,7 +65,7 @@ public:
}
static void set_tune_speed(device_t &device, double speed)
{
downcast<tms36xx_device &>(device).m_speed = (speed > 0) ? VMAX / speed : VMAX;
downcast<tms36xx_device &>(device).m_speed = (speed > 0) ? TMS36XX_VMAX / speed : TMS36XX_VMAX;
}
static void set_decays(device_t &device, double decay_0, double decay_1, double decay_2, double decay_3, double decay_4, double decay_5)
{

View File

@ -110,16 +110,16 @@ void tms5110_device::set_variant(int variant)
void tms5110_device::new_int_write(UINT8 rc, UINT8 m0, UINT8 m1, UINT8 addr)
{
if (!m_m0_func.isnull())
m_m0_func(m0);
if (!m_m1_func.isnull())
m_m1_func(m1);
if (!m_addr_func.isnull())
m_addr_func(0, addr);
if (!m_romclk_func.isnull())
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())
{
//printf("rc %d\n", rc);
m_romclk_func(rc);
m_romclk_cb(rc);
}
}
@ -137,8 +137,8 @@ UINT8 tms5110_device::new_int_read()
new_int_write(0, 1, 0, 0);
new_int_write(1, 0, 0, 0);
new_int_write(0, 0, 0, 0);
if (!m_data_func.isnull())
return m_data_func();
if (!m_data_cb.isnull())
return m_data_cb();
return 0;
}
@ -232,19 +232,10 @@ int tms5110_device::extract_bits(int count)
void tms5110_device::request_bits(int no)
{
for (int i=0; i<no; i++)
for (int i = 0; i < no; i++)
{
if (m_M0_callback)
{
int data = (*m_M0_callback)(this);
FIFO_data_write(data);
}
else
{
//if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
UINT8 data = new_int_read();
FIFO_data_write(data);
}
UINT8 data = new_int_read();
FIFO_data_write(data);
}
}
@ -252,19 +243,8 @@ void tms5110_device::perform_dummy_read()
{
if (m_schedule_dummy_read)
{
if (m_M0_callback)
{
int data = (*m_M0_callback)(this);
if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data&1);
}
else
{
int data = new_int_read();
if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data&1);
//if (DEBUG_5110) logerror("-->ERROR: TMS5110 missing M0 callback function\n");
}
int data = new_int_read();
if (DEBUG_5110) logerror("TMS5110 performing dummy read; value read = %1i\n", data & 1);
m_schedule_dummy_read = FALSE;
}
}
@ -621,8 +601,6 @@ void tms5110_device::PDC_set(int data)
m_address = m_address | ((m_CTL_pins & 0x0F)<<m_addr_bit);
m_addr_bit = (m_addr_bit + 4) % 12;
m_schedule_dummy_read = TRUE;
if (m_set_load_address)
m_set_load_address(this, m_address);
new_int_write_addr(m_CTL_pins & 0x0F);
}
else
@ -838,76 +816,26 @@ static const unsigned int example_word_TEN[619]={
#endif
static int speech_rom_read_bit(device_t *device)
{
tms5110_device *tms5110 = (tms5110_device *) device;
return tms5110->_speech_rom_read_bit();
}
int tms5110_device::_speech_rom_read_bit()
{
int r;
if (m_speech_rom_bitnum<0)
r = 0;
else
r = (m_table[m_speech_rom_bitnum >> 3] >> (0x07 - (m_speech_rom_bitnum & 0x07))) & 1;
m_speech_rom_bitnum++;
return r;
}
static void speech_rom_set_addr(device_t *device, int addr)
{
tms5110_device *tms5110 = (tms5110_device *) device;
tms5110->_speech_rom_set_addr(addr);
}
void tms5110_device::_speech_rom_set_addr(int addr)
{
m_speech_rom_bitnum = addr * 8 - 1;
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void tms5110_device::device_start()
{
static const tms5110_interface dummy = { NULL, NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL};
assert_always(static_config() != NULL, "No config");
m_intf = static_config() ? (const tms5110_interface *)static_config() : &dummy;
m_table = *region();
set_variant(TMS5110_IS_5110A);
/* resolve lines */
m_m0_func.resolve(m_intf->m0_func, *this);
m_m1_func.resolve(m_intf->m1_func, *this);
m_romclk_func.resolve(m_intf->romclk_func, *this);
m_addr_func.resolve(m_intf->addr_func, *this);
m_data_func.resolve(m_intf->data_func, *this);
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);
if (m_table == NULL)
{
#if 0
assert_always(m_intf->M0_callback != NULL, "Missing _mandatory_ 'M0_callback' function pointer in the TMS5110 interface\n This function is used by TMS5110 to call for a single bits\n needed to generate the speech\n Aborting startup...\n");
#endif
m_M0_callback = m_intf->M0_callback;
m_set_load_address = m_intf->load_address;
}
else
{
m_M0_callback = speech_rom_read_bit;
m_set_load_address = speech_rom_set_addr;
}
m_state = CTL_STATE_INPUT; /* most probably not defined */
m_romclk_hack_timer = timer_alloc(0);
@ -1003,7 +931,7 @@ void tms5110_device::device_reset()
memset(m_x, 0, sizeof(m_x));
m_next_is_address = FALSE;
m_address = 0;
if (m_table != NULL || m_M0_callback != NULL)
if (m_table != NULL)
{
/* legacy interface */
m_schedule_dummy_read = TRUE;
@ -1356,25 +1284,26 @@ const device_type TMS5110 = &device_creator<tms5110_device>;
tms5110_device::tms5110_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TMS5110, "TMS5110", tag, owner, clock, "tms5110", __FILE__),
device_sound_interface(mconfig, *this)
device_sound_interface(mconfig, *this),
m_m0_cb(*this),
m_m1_cb(*this),
m_addr_cb(*this),
m_data_cb(*this),
m_romclk_cb(*this)
{
}
tms5110_device::tms5110_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_m0_cb(*this),
m_m1_cb(*this),
m_addr_cb(*this),
m_data_cb(*this),
m_romclk_cb(*this)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void tms5110_device::device_config_complete()
{
}
const device_type TMS5100 = &device_creator<tms5100_device>;

View File

@ -23,30 +23,35 @@
/* usually 640000 for 8000 Hz sample rate or */
/* usually 800000 for 10000 Hz sample rate. */
struct tms5110_interface
{
/* legacy interface */
int (*M0_callback)(device_t *device); /* function to be called when chip requests another bit */
void (*load_address)(device_t *device, int addr); /* speech ROM load address callback */
/* new rom controller interface */
devcb_write_line m0_func; /* the M0 line */
devcb_write_line m1_func; /* the M1 line */
devcb_write8 addr_func; /* Write to ADD1,2,4,8 - 4 address bits */
devcb_read_line data_func; /* Read one bit from ADD8/Data - voice data */
/* on a real chip rom_clk is running all the time
* Here, we only use it to properly emulate the protocol.
* Do not rely on it to be a timed signal.
*/
devcb_write_line romclk_func; /* rom clock - Only used to drive the data lines */
};
#define MCFG_TMS5110_M0_CB(_devcb) \
devcb = &tms5110_device::set_m0_callback(*device, DEVCB2_##_devcb);
#define MCFG_TMS5110_M1_CB(_devcb) \
devcb = &tms5110_device::set_m1_callback(*device, DEVCB2_##_devcb);
#define MCFG_TMS5110_ADDR_CB(_devcb) \
devcb = &tms5110_device::set_addr_callback(*device, DEVCB2_##_devcb);
#define MCFG_TMS5110_DATA_CB(_devcb) \
devcb = &tms5110_device::set_data_callback(*device, DEVCB2_##_devcb);
#define MCFG_TMS5110_ROMCLK_CB(_devcb) \
devcb = &tms5110_device::set_romclk_callback(*device, DEVCB2_##_devcb);
class tms5110_device : public device_t,
public device_sound_interface
public device_sound_interface
{
public:
tms5110_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
tms5110_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);
template<class _Object> static devcb2_base &set_m0_callback(device_t &device, _Object object) { return downcast<tms5110_device &>(device).m_m0_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_m1_callback(device_t &device, _Object object) { return downcast<tms5110_device &>(device).m_m1_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_addr_callback(device_t &device, _Object object) { return downcast<tms5110_device &>(device).m_addr_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_data_callback(device_t &device, _Object object) { return downcast<tms5110_device &>(device).m_data_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_romclk_callback(device_t &device, _Object object) { return downcast<tms5110_device &>(device).m_romclk_cb.set_callback(object); }
DECLARE_WRITE8_MEMBER( ctl_w );
DECLARE_READ8_MEMBER( ctl_r );
DECLARE_WRITE_LINE_MEMBER( pdc_w );
@ -65,7 +70,6 @@ public:
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
@ -76,6 +80,9 @@ protected:
void set_variant(int variant);
UINT8 m_talk_status;
sound_stream *m_stream;
private:
void new_int_write(UINT8 rc, UINT8 m0, UINT8 m1, UINT8 addr);
void new_int_write_addr(UINT8 addr);
@ -99,7 +106,8 @@ private:
UINT8 m_PDC;
UINT8 m_CTL_pins;
UINT8 m_speaking_now;
protected: UINT8 m_talk_status; private:
UINT8 m_state;
/* Rom interface */
@ -108,16 +116,15 @@ protected: UINT8 m_talk_status; private:
UINT8 m_schedule_dummy_read;
UINT8 m_addr_bit;
/* external callback */
int (*m_M0_callback)(device_t *);
void (*m_set_load_address)(device_t *, int);
/* callbacks */
devcb_resolved_write_line m_m0_func; /* the M0 line */
devcb_resolved_write_line m_m1_func; /* the M1 line */
devcb_resolved_write8 m_addr_func; /* Write to ADD1,2,4,8 - 4 address bits */
devcb_resolved_read_line m_data_func; /* Read one bit from ADD8/Data - voice data */
devcb_resolved_write_line m_romclk_func; /* rom clock - Only used to drive the data lines */
devcb2_write_line m_m0_cb; // the M0 line
devcb2_write_line m_m1_cb; // the M1 line
devcb2_write8 m_addr_cb; // Write to ADD1,2,4,8 - 4 address bits
devcb2_read_line m_data_cb; // Read one bit from ADD8/Data - voice data
// On a real chip rom_clk is running all the time
// Here, we only use it to properly emulate the protocol.
// Do not rely on it to be a timed signal.
devcb2_write_line m_romclk_cb; // rom clock - Only used to drive the data lines
/* these contain data describing the current and previous voice frames */
UINT16 m_old_energy;
@ -157,9 +164,7 @@ protected: UINT8 m_talk_status; private:
/* coefficient tables */
const struct tms5100_coeffs *m_coeff;
protected: sound_stream *m_stream; private:
emu_timer *m_romclk_hack_timer;
const tms5110_interface *m_intf;
const UINT8 *m_table;
};

View File

@ -1328,22 +1328,6 @@ static ADDRESS_MAP_START( dkong3_sound2_map, AS_PROGRAM, 8, dkong_state )
AM_RANGE(0xe000, 0xffff) AM_ROM
ADDRESS_MAP_END
/*************************************
*
* Sound interfaces
*
*************************************/
const tms5110_interface tms_interface = {
NULL,
NULL,
DEVCB_DEVICE_LINE_MEMBER("m58819", tms6100_device, tms6100_m0_w),
DEVCB_DEVICE_LINE_MEMBER("m58819", tms6100_device, tms6100_m1_w),
DEVCB_DEVICE_MEMBER("m58819", tms6100_device, tms6100_addr_w),
DEVCB_DEVICE_LINE_MEMBER("m58819", tms6100_device, tms6100_data_r),
DEVCB_DEVICE_LINE_MEMBER("m58819", tms6100_device, tms6100_romclock_w)
};
/*************************************
*
* Machine driver
@ -1408,9 +1392,12 @@ MACHINE_CONFIG_DERIVED( radarscp1_audio, radarscp_audio )
MCFG_DEVICE_ADD("m58819", M58819, 0)
MCFG_SOUND_ADD("tms", M58817, XTAL_640kHz)
MCFG_DEVICE_CONFIG(tms_interface)
MCFG_TMS5110_M0_CB(DEVWRITELINE("m58819", tms6100_device, tms6100_m0_w))
MCFG_TMS5110_M1_CB(DEVWRITELINE("m58819", tms6100_device, tms6100_m1_w))
MCFG_TMS5110_ADDR_CB(DEVWRITE8("m58819", tms6100_device, tms6100_addr_w))
MCFG_TMS5110_DATA_CB(DEVREADLINE("m58819", tms6100_device, tms6100_data_r))
MCFG_TMS5110_ROMCLK_CB(DEVWRITELINE("m58819", tms6100_device, tms6100_romclock_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END
MACHINE_CONFIG_FRAGMENT( dkongjr_audio )

View File

@ -41,9 +41,6 @@
*
****************************************************************************/
#undef VMIN
#undef VMAX
#define VMIN 0
#define VMAX 32767

View File

@ -9,9 +9,6 @@
#include "emu.h"
#include "audio/pleiads.h"
#undef VMIN
#undef VMAX
#define VMIN 0
#define VMAX 32767

View File

@ -325,20 +325,6 @@ static const tmsprom_interface prom_intf =
DEVCB_DEVICE_MEMBER("tms", tms5110_device, ctl_w) /* tms ctl func */
};
static const tms5110_interface ad2083_tms5110_interface =
{
/* legacy interface */
NULL, /* function to be called when chip requests another bit */
NULL, /* speech ROM load address callback */
/* new rom controller interface */
DEVCB_DEVICE_LINE_MEMBER("tmsprom", tmsprom_device, m0_w), /* the M0 line */
DEVCB_NULL, /* the M1 line */
DEVCB_NULL, /* Write to ADD1,2,4,8 - 4 address bits */
DEVCB_DEVICE_LINE_MEMBER("tmsprom", tmsprom_device, data_r), /* Read one bit from ADD8/Data - voice data */
DEVCB_NULL /* rom clock - Only used to drive the data lines */
};
MACHINE_CONFIG_FRAGMENT( ad2083_audio )
@ -359,6 +345,7 @@ MACHINE_CONFIG_FRAGMENT( ad2083_audio )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MCFG_SOUND_ADD("tms", TMS5110A, AD2083_TMS5110_CLOCK)
MCFG_SOUND_CONFIG(ad2083_tms5110_interface)
MCFG_TMS5110_M0_CB(DEVWRITELINE("tmsprom", tmsprom_device, m0_w))
MCFG_TMS5110_DATA_CB(DEVREADLINE("tmsprom", tmsprom_device, data_r))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

View File

@ -448,19 +448,6 @@ static const tmsprom_interface prom_intf =
DEVCB_DEVICE_MEMBER("tms", tms5110_device, ctl_w) /* tms ctl func */
};
static const tms5110_interface bagman_tms5110_interface =
{
/* legacy interface */
NULL, /* function to be called when chip requests another bit */
NULL, /* speech ROM load address callback */
/* new rom controller interface */
DEVCB_DEVICE_LINE_MEMBER("tmsprom", tmsprom_device, m0_w), /* the M0 line */
DEVCB_NULL, /* the M1 line */
DEVCB_NULL, /* Write to ADD1,2,4,8 - 4 address bits */
DEVCB_DEVICE_LINE_MEMBER("tmsprom", tmsprom_device, data_r), /* Read one bit from ADD8/Data - voice data */
DEVCB_NULL /* rom clock - Only used to drive the data lines */
};
INTERRUPT_GEN_MEMBER(bagman_state::vblank_irq)
{
if(m_irq_mask)
@ -501,7 +488,8 @@ static MACHINE_CONFIG_START( bagman, bagman_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
MCFG_SOUND_ADD("tms", TMS5110A, 640000)
MCFG_SOUND_CONFIG(bagman_tms5110_interface)
MCFG_TMS5110_M0_CB(DEVWRITELINE("tmsprom", tmsprom_device, m0_w))
MCFG_TMS5110_DATA_CB(DEVREADLINE("tmsprom", tmsprom_device, data_r))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

View File

@ -406,31 +406,22 @@ WRITE8_MEMBER(cvs_state::cvs_tms5110_pdc_w)
}
static int speech_rom_read_bit( device_t *device )
READ_LINE_MEMBER(cvs_state::speech_rom_read_bit)
{
cvs_state *state = device->machine().driver_data<cvs_state>();
UINT8 *ROM = state->memregion("speechdata")->base();
int bit;
UINT8 *ROM = memregion("speechdata")->base();
/* before reading the bit, clamp the address to the region length */
state->m_speech_rom_bit_address = state->m_speech_rom_bit_address & ((state->memregion("speechdata")->bytes() * 8) - 1);
bit = (ROM[state->m_speech_rom_bit_address >> 3] >> (state->m_speech_rom_bit_address & 0x07)) & 0x01;
m_speech_rom_bit_address &= ((memregion("speechdata")->bytes() * 8) - 1);
bit = BIT(ROM[m_speech_rom_bit_address >> 3], m_speech_rom_bit_address & 0x07);
/* prepare for next bit */
state->m_speech_rom_bit_address = state->m_speech_rom_bit_address + 1;
m_speech_rom_bit_address++;
return bit;
}
static const tms5110_interface tms5100_interface =
{
speech_rom_read_bit, /* M0 callback function. Called whenever chip requests a single bit of data */
NULL
};
/*************************************
*
* Inter-CPU communications
@ -1061,7 +1052,7 @@ static MACHINE_CONFIG_START( cvs, cvs_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MCFG_SOUND_ADD("tms", TMS5100, XTAL_640kHz)
MCFG_SOUND_CONFIG(tms5100_interface)
MCFG_TMS5110_DATA_CB(READLINE(cvs_state, speech_rom_read_bit))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

View File

@ -88,6 +88,7 @@ public:
UINT8 m_character_ram[3 * 0x800]; /* only half is used, but
by allocating twice the amount,
we can use the same gfx_layout */
DECLARE_READ_LINE_MEMBER(speech_rom_read_bit);
DECLARE_WRITE_LINE_MEMBER(write_s2650_flag);
DECLARE_READ8_MEMBER(cvs_input_r);
DECLARE_READ8_MEMBER(cvs_393hz_clock_r);