modernised TMS5220 [smf]

This commit is contained in:
smf- 2013-05-14 10:21:05 +00:00
parent 25cb3c0cda
commit d700c1f372
42 changed files with 1018 additions and 2868 deletions

4
.gitattributes vendored
View File

@ -1402,6 +1402,8 @@ src/emu/machine/smc91c9x.c svneol=native#text/plain
src/emu/machine/smc91c9x.h svneol=native#text/plain
src/emu/machine/smpc.c svneol=native#text/plain
src/emu/machine/smpc.h svneol=native#text/plain
src/emu/machine/spchrom.c svneol=native#text/plain
src/emu/machine/spchrom.h svneol=native#text/plain
src/emu/machine/stvcd.c svneol=native#text/plain
src/emu/machine/tc009xlvc.c svneol=native#text/plain
src/emu/machine/tc009xlvc.h svneol=native#text/plain
@ -5927,8 +5929,6 @@ src/mess/audio/mea8000.c svneol=native#text/plain
src/mess/audio/mea8000.h svneol=native#text/plain
src/mess/audio/socrates.c svneol=native#text/plain
src/mess/audio/socrates.h svneol=native#text/plain
src/mess/audio/spchroms.c svneol=native#text/plain
src/mess/audio/spchroms.h svneol=native#text/plain
src/mess/audio/special.c svneol=native#text/plain
src/mess/audio/svision.c svneol=native#text/plain
src/mess/audio/tvc.c svneol=native#text/plain

115
src/emu/machine/spchrom.c Normal file
View File

@ -0,0 +1,115 @@
/*
spchroms.c - This is an emulator for "typical" speech ROMs from TI, as used by TI99/4(a).
In order to support its speech processor, TI designed some ROMs with a 1-bit data bus
and 4-bit address bus (multiplexed 5 times to provide a 18-bit address).
A fairly complete description of such a ROM (tms6100) is found in the tms5220 datasheet.
One notable thing is that the address is a byte address (*NOT* a bit address).
This file is designed to be interfaced with the tms5220 core.
Interfacing it with the tms5110 would make sense, too.
*/
#include "emu.h"
#include "spchrom.h"
#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */
// device type definition
const device_type SPEECHROM = &device_creator<speechrom_device>;
speechrom_device::speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, SPEECHROM, "SPEECHROM", tag, owner, clock),
m_speechROMaddr(0),
m_load_pointer(0),
m_ROM_bits_count(0)
{
}
/*
Read 'count' bits serially from speech ROM
*/
int speechrom_device::read(int count)
{
int val;
if (m_load_pointer)
{ /* first read after load address is ignored */
m_load_pointer = 0;
count--;
}
if (m_speechROMaddr < m_speechROMlen)
if (count < m_ROM_bits_count)
{
m_ROM_bits_count -= count;
val = (m_speechrom_data[m_speechROMaddr] >> m_ROM_bits_count) & (0xFF >> (8 - count));
}
else
{
val = ((int) m_speechrom_data[m_speechROMaddr]) << 8;
m_speechROMaddr = (m_speechROMaddr + 1) & TMS5220_ADDRESS_MASK;
if (m_speechROMaddr < m_speechROMlen)
val |= m_speechrom_data[m_speechROMaddr];
m_ROM_bits_count += 8 - count;
val = (val >> m_ROM_bits_count) & (0xFF >> (8 - count));
}
else
val = 0;
return val;
}
/*
Write an address nibble to speech ROM
*/
void speechrom_device::load_address(int data)
{
/* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
This code does not care about this. */
m_speechROMaddr = ( (m_speechROMaddr & ~(0xf << m_load_pointer))
| (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
m_load_pointer += 4;
m_ROM_bits_count = 8;
}
/*
Perform a read and branch command
*/
void speechrom_device::read_and_branch()
{
/* tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
there is a bus contention. This code does not care about this. */
if (m_speechROMaddr < m_speechROMlen-1)
m_speechROMaddr = (m_speechROMaddr & 0x3c000UL)
| (((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8)
| m_speechrom_data[m_speechROMaddr+1]) & 0x3fffUL);
else if (m_speechROMaddr == m_speechROMlen-1)
m_speechROMaddr = (m_speechROMaddr & 0x3c000UL)
| ((((unsigned long) m_speechrom_data[m_speechROMaddr]) << 8) & 0x3fffUL);
else
m_speechROMaddr = (m_speechROMaddr & 0x3c000UL);
m_ROM_bits_count = 8;
}
void speechrom_device::device_start()
{
memory_region *region = memregion(tag());
if (region == NULL)
{
throw emu_fatalerror("No region for device '%s'\n", tag());
}
m_speechrom_data = region->base();
m_speechROMlen = region->bytes();
save_item(NAME(m_speechROMaddr));
save_item(NAME(m_load_pointer));
save_item(NAME(m_ROM_bits_count));
}

37
src/emu/machine/spchrom.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Voice Synthesis Memory
*
*/
#ifndef __SPCHROMS_H
#define __SPCHROMS_H
#include "emu.h"
class speechrom_device : public device_t
{
public:
// construction/destruction
speechrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
/// TODO: implement bus behaviour
int read(int count);
void load_address(int data);
void read_and_branch();
// device-level overrides
virtual void device_start();
private:
UINT8 *m_speechrom_data; /* pointer to speech ROM data */
unsigned long m_speechROMlen; /* length of data pointed by speechrom_data, from 0 to 2^18 */
unsigned long m_speechROMaddr; /* 18 bit pointer in ROM */
int m_load_pointer; /* which 4-bit nibble will be affected by load address */
int m_ROM_bits_count; /* current bit position in ROM */
};
// device type definition
extern const device_type SPEECHROM;
#endif

View File

@ -644,7 +644,7 @@ $(SOUNDOBJ)/tms5110.o: $(SOUNDSRC)/tms5110r.c
# Texas Instruments TMS5200-series speech synthesizers
#-------------------------------------------------
ifneq ($(filter TMS5220,$(SOUNDS)),)
SOUNDOBJS += $(SOUNDOBJ)/tms5220.o
SOUNDOBJS += $(SOUNDOBJ)/tms5220.o $(EMUMACHINE)/spchrom.o
endif
$(SOUNDOBJ)/tms5220.o: $(SOUNDSRC)/tms5110r.c

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,11 @@
#ifndef __TMS5220_H__
#define __TMS5220_H__
#include "devlegcy.h"
#include "emu.h"
#include "machine/spchrom.h"
/* HACK: if defined, uses impossibly perfect 'straight line' interpolation */
#undef PERFECT_INTERPOLATION_HACK
#define FIFO_SIZE 16
@ -11,35 +15,16 @@
/* usually 640000 for 8000 Hz sample rate or */
/* usually 800000 for 10000 Hz sample rate. */
struct tms5220_interface
{
devcb_write_line irq_func; /* IRQ callback function, active low, i.e. state=0 */
devcb_write_line readyq_func; /* Ready callback function, active low, i.e. state=0 */
/* IRQ callback function, active low, i.e. state=0 */
#define MCFG_TMS52XX_IRQ_HANDLER(_devcb) \
devcb = &tms5220_device::set_irq_handler(*device, DEVCB2_##_devcb);
int (*read)(device_t *device, int count); /* speech ROM read callback */
void (*load_address)(device_t *device, int data); /* speech ROM load address callback */
void (*read_and_branch)(device_t *device); /* speech ROM read and branch callback */
};
/* Ready callback function, active low, i.e. state=0 */
#define MCFG_TMS52XX_READYQ_HANDLER(_devcb) \
devcb = &tms5220_device::set_readyq_handler(*device, DEVCB2_##_devcb);
/* Control lines - once written to will switch interface into
* "true" timing behaviour.
*/
/* all lines with suffix q are active low! */
WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w );
WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w );
DECLARE_WRITE8_DEVICE_HANDLER( tms5220_data_w );
DECLARE_READ8_DEVICE_HANDLER( tms5220_status_r );
READ_LINE_DEVICE_HANDLER( tms5220_readyq_r );
READ_LINE_DEVICE_HANDLER( tms5220_intq_r );
double tms5220_time_to_ready(device_t *device);
void tms5220_set_frequency(device_t *device, int frequency);
#define MCFG_TMS52XX_SPEECHROM(_tag) \
tms5220_device::set_speechrom_tag(*device, _tag);
class tms5220_device : public device_t,
public device_sound_interface
@ -47,21 +32,175 @@ class tms5220_device : public device_t,
public:
tms5220_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
tms5220_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
~tms5220_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
// static configuration helpers
template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<tms5220_device &>(device).m_irq_handler.set_callback(object); }
template<class _Object> static devcb2_base &set_readyq_handler(device_t &device, _Object object) { return downcast<tms5220_device &>(device).m_readyq_handler.set_callback(object); }
static void set_speechrom_tag(device_t &device, const char *_tag) { downcast<tms5220_device &>(device).m_speechrom_tag = _tag; }
/* Control lines - once written to will switch interface into
* "true" timing behaviour.
*/
/* all lines with suffix q are active low! */
WRITE_LINE_MEMBER( rsq_w );
WRITE_LINE_MEMBER( wsq_w );
DECLARE_WRITE8_MEMBER( data_w );
DECLARE_READ8_MEMBER( status_r );
READ_LINE_MEMBER( readyq_r );
READ_LINE_MEMBER( intq_r );
double time_to_ready();
void set_frequency(int frequency);
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
void set_variant(int variant);
private:
void register_for_save_states();
void data_write(int data);
void update_status_and_ints();
int extract_bits(int count);
int status_read();
int ready_read();
int cycles_to_ready();
int int_read();
void process(INT16 *buffer, unsigned int size);
INT32 lattice_filter();
void process_command(unsigned char cmd);
void parse_frame();
void set_interrupt_state(int state);
void update_ready_state();
// internal state
void *m_token;
/* coefficient tables */
int m_variant; /* Variant of the 5xxx - see tms5110r.h */
/* coefficient tables */
const struct tms5100_coeffs *m_coeff;
/* these contain data that describes the 128-bit data FIFO */
UINT8 m_fifo[FIFO_SIZE];
UINT8 m_fifo_head;
UINT8 m_fifo_tail;
UINT8 m_fifo_count;
UINT8 m_fifo_bits_taken;
/* these contain global status bits */
UINT8 m_speaking_now; /* True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.*/
UINT8 m_speak_external; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */
UINT8 m_talk_status; /* If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts. */
UINT8 m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */
UINT8 m_buffer_empty; /* If 1, FIFO is empty */
UINT8 m_irq_pin; /* state of the IRQ pin (output) */
UINT8 m_ready_pin; /* state of the READY pin (output) */
/* these contain data describing the current and previous voice frames */
#define OLD_FRAME_SILENCE_FLAG m_OLDE // 1 if E=0, 0 otherwise.
#define OLD_FRAME_UNVOICED_FLAG m_OLDP // 1 if P=0 (unvoiced), 0 if voiced
UINT8 m_OLDE;
UINT8 m_OLDP;
#define NEW_FRAME_STOP_FLAG (m_new_frame_energy_idx == 0xF) // 1 if this is a stop (Energy = 0xF) frame
#define NEW_FRAME_SILENCE_FLAG (m_new_frame_energy_idx == 0) // ditto as above
#define NEW_FRAME_UNVOICED_FLAG (m_new_frame_pitch_idx == 0) // ditto as above
UINT8 m_new_frame_energy_idx;
UINT8 m_new_frame_pitch_idx;
UINT8 m_new_frame_k_idx[10];
/* these are all used to contain the current state of the sound generation */
#ifndef PERFECT_INTERPOLATION_HACK
INT16 m_current_energy;
INT16 m_current_pitch;
INT16 m_current_k[10];
INT16 m_target_energy;
INT16 m_target_pitch;
INT16 m_target_k[10];
#else
UINT8 m_old_frame_energy_idx;
UINT8 m_old_frame_pitch_idx;
UINT8 m_old_frame_k_idx[10];
INT32 m_current_energy;
INT32 m_current_pitch;
INT32 m_current_k[10];
INT32 m_target_energy;
INT32 m_target_pitch;
INT32 m_target_k[10];
#endif
UINT16 m_previous_energy; /* needed for lattice filter to match patent */
UINT8 m_subcycle; /* contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B */
UINT8 m_subc_reload; /* contains 1 for normal speech, 0 when SPKSLOW is active */
UINT8 m_PC; /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */
/* TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */
UINT8 m_IP; /* the current interpolation period */
UINT8 m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */
UINT8 m_tms5220c_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */
UINT16 m_pitch_count; /* pitch counter; provides chirp rom address */
INT32 m_u[11];
INT32 m_x[10];
UINT16 m_RNG; /* the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13 */
INT16 m_excitation_data;
/* R Nabet : These have been added to emulate speech Roms */
UINT8 m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */
UINT8 m_data_register; /* data register, used by read command */
UINT8 m_RDB_flag; /* whether we should read data register or status register */
/* io_ready: page 3 of the datasheet specifies that READY will be asserted until
* data is available or processed by the system.
*/
UINT8 m_io_ready;
/* flag for "true" timing involving rs/ws */
UINT8 m_true_timing;
/* rsws - state, rs bit 1, ws bit 0 */
UINT8 m_rs_ws;
UINT8 m_read_latch;
UINT8 m_write_latch;
/* The TMS52xx has two different ways of providing output data: the
analog speaker pin (which was usually used) and the Digital I/O pin.
The internal DAC used to feed the analog pin is only 8 bits, and has the
funny clipping/clamping logic, while the digital pin gives full 10 bit
resolution of the output data.
TODO: add a way to set/reset this other than the FORCE_DIGITAL define
*/
UINT8 m_digital_select;
sound_stream *m_stream;
int m_clock;
emu_timer *m_timer_io_ready;
/* callbacks */
devcb2_write_line m_irq_handler;
devcb2_write_line m_readyq_handler;
const char *m_speechrom_tag;
speechrom_device *m_speechrom;
};
extern const device_type TMS5220;
@ -73,9 +212,6 @@ public:
protected:
// device-level overrides
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);
};
extern const device_type TMS5220C;
@ -87,9 +223,6 @@ public:
protected:
// device-level overrides
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);
};
extern const device_type TMC0285;
@ -101,213 +234,8 @@ public:
protected:
// device-level overrides
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);
};
extern const device_type TMS5200;
/***************************************************************************
New class implementation
Michael Zapf, June 2012
***************************************************************************/
extern const device_type TMS5220N;
extern const device_type TMS5220CN;
extern const device_type TMC0285N;
extern const device_type TMS5200N;
struct tms52xx_config
{
devcb_write_line irq_func; // IRQ callback function, active low, i.e. state=0 (TODO: change to ASSERT/CLEAR)
devcb_write_line readyq_func; // Ready callback function, active low, i.e. state=0
devcb_read8 read_mem; // speech ROM read callback
devcb_write8 load_address; // speech ROM load address callback
devcb_write8 read_and_branch; // speech ROM read and branch callback
};
// Change back from 5220n to 5220 when all client drivers will be converted
class tms52xx_device : public device_t, public device_sound_interface
{
public:
tms52xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, const struct tms5100_coeffs* coeffs, const int var, device_t *owner, UINT32 clock);
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
DECLARE_WRITE_LINE_MEMBER( rsq_w );
DECLARE_WRITE_LINE_MEMBER( wsq_w );
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( read );
DECLARE_READ_LINE_MEMBER( readyq );
DECLARE_READ_LINE_MEMBER( intq );
double time_to_ready();
protected:
virtual void device_start();
virtual void device_reset();
private:
// Methods
void set_interrupt_state(int state);
void register_for_save_states();
void update_ready_state();
void set_frequency(int frequency);
void process(INT16 *buffer, unsigned int size);
void data_write(int data);
void update_status_and_ints();
void parse_frame();
int extract_bits(int count);
int status_read();
int cycles_to_ready();
INT32 lattice_filter();
void process_command(unsigned char cmd);
inline bool ready_read();
inline int int_read();
// coefficient tables
const int m_variant; // Variant of the 5xxx - see tms5110r.h
// coefficient tables
const struct tms5100_coeffs *m_coeff;
// callbacks
devcb_resolved_write_line m_irq_func;
devcb_resolved_write_line m_readyq_func;
devcb_resolved_read8 m_read_mem;
devcb_resolved_write8 m_load_address;
devcb_resolved_write8 m_read_and_branch;
// these contain data that describes the 128-bit data FIFO
UINT8 m_fifo[FIFO_SIZE];
UINT8 m_fifo_head;
UINT8 m_fifo_tail;
int m_fifo_count;
int m_fifo_bits_taken;
// these contain global status bits
bool m_speaking_now; // True only if actual speech is being generated right now. Is set when a speak vsm command happens OR when speak external happens and buffer low becomes nontrue; Is cleared when speech halts after the last stop frame or the last frame after talk status is otherwise cleared.
bool m_speak_external; // If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO.
bool m_talk_status; // If 1, TS status bit is 1, i.e. speak or speak external is in progress and we have not encountered a stop frame yet; talk_status differs from speaking_now in that speaking_now is set as soon as a speak or speak external command is started; talk_status does NOT go active until after 8 bytes are written to the fifo on a speak external command, otherwise the two are the same. TS is cleared by 3 things: 1. when a STOP command has just been processed as a new frame in the speech stream; 2. if the fifo runs out in speak external mode; 3. on power-up/during a reset command; When it gets cleared, speak_external is also cleared, an interrupt is generated, and speaking_now will be cleared when the next frame starts.
bool m_buffer_low; // If 1, FIFO has less than 8 bytes in it
bool m_buffer_empty; // If 1, FIFO is empty
int m_irq_pin; // state of the IRQ pin (output)
int m_ready_pin; // state of the READY pin (output)
// these contain data describing the current and previous voice frames
#define M_OLD_FRAME_SILENCE_FLAG m_OLDE // 1 if E=0, 0 otherwise.
#define M_OLD_FRAME_UNVOICED_FLAG m_OLDP // 1 if P=0 (unvoiced), 0 if voiced
bool m_OLDE;
bool m_OLDP;
#define M_NEW_FRAME_STOP_FLAG (m_new_frame_energy_idx == 0xF) // 1 if this is a stop (Energy = 0xF) frame
#define M_NEW_FRAME_SILENCE_FLAG (m_new_frame_energy_idx == 0) // ditto as above
#define M_NEW_FRAME_UNVOICED_FLAG (m_new_frame_pitch_idx == 0) // ditto as above
int m_new_frame_energy_idx;
int m_new_frame_pitch_idx;
int m_new_frame_k_idx[10];
// these are all used to contain the current state of the sound generation
#ifndef PERFECT_INTERPOLATION_HACK
INT16 m_current_energy;
INT16 m_current_pitch;
INT16 m_current_k[10];
INT16 m_target_energy;
INT16 m_target_pitch;
INT16 m_target_k[10];
#else
int m_old_frame_energy_idx;
int m_old_frame_pitch_idx;
int m_old_frame_k_idx[10];
INT32 m_current_energy;
INT32 m_current_pitch;
INT32 m_current_k[10];
INT32 m_target_energy;
INT32 m_target_pitch;
INT32 m_target_k[10];
#endif
UINT16 m_previous_energy; // needed for lattice filter to match patent
int m_subcycle; // contains the current subcycle for a given PC: 0 is A' (only used on SPKSLOW mode on 51xx), 1 is A, 2 is B
int m_subc_reload; // contains 1 for normal speech, 0 when SPKSLOW is active
int m_PC; // current parameter counter (what param is being interpolated), ranges from 0 to 12
// TODO/NOTE: the current interpolation period, counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1
int m_IP; // the current interpolation period
bool m_inhibit; // If 1, interpolation is inhibited until the DIV1 period
UINT8 m_tms5220c_rate; // only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command
UINT16 m_pitch_count; // pitch counter; provides chirp rom address
INT32 m_u[11];
INT32 m_x[10];
UINT16 m_RNG; // the random noise generator configuration is: 1 + x + x^3 + x^4 + x^13
INT16 m_excitation_data;
// R Nabet : These have been added to emulate speech Roms
bool m_schedule_dummy_read; // set after each load address, so that next read operation is preceded by a dummy read
UINT8 m_data_register; // data register, used by read command
bool m_RDB_flag; // whether we should read data register or status register
// io_ready: page 3 of the datasheet specifies that READY will be asserted until
// data is available or processed by the system.
int m_io_ready;
// flag for "true" timing involving rs/ws
bool m_true_timing;
// rsws - state, rs bit 1, ws bit 0
int m_rs_ws;
UINT8 m_read_latch;
UINT8 m_write_latch;
// The TMS52xx has two different ways of providing output data: the
// analog speaker pin (which was usually used) and the Digital I/O pin.
// The internal DAC used to feed the analog pin is only 8 bits, and has the
// funny clipping/clamping logic, while the digital pin gives full 12? bit
// resolution of the output data.
// TODO: add a way to set/reset this other than the FORCE_DIGITAL define
bool m_digital_select;
sound_stream *m_stream;
emu_timer *m_ready_timer;
};
class tms5220n_device : public tms52xx_device
{
public:
tms5220n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms5220cn_device : public tms52xx_device
{
public:
tms5220cn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tmc0285n_device : public tms52xx_device
{
public:
tmc0285n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms5200n_device : public tms52xx_device
{
public:
tms5200n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
#endif /* __TMS5220_H__ */

View File

@ -59,7 +59,7 @@ static UINT16 test_mask;
static pokey_device *pokey;
static ym2151_device *ym2151;
static device_t *tms5220;
static tms5220_device *tms5220;
static okim6295_device *oki6295;
static okim6295_device *oki6295_l, *oki6295_r;
@ -138,7 +138,7 @@ void atarijsa_init(running_machine &machine, const char *testport, int testmask)
bank_source_data = &rgn[0x10000];
/* determine which sound hardware is installed */
tms5220 = machine.device("tms");
tms5220 = machine.device<tms5220_device>("tms");
ym2151 = machine.device<ym2151_device>("ymsnd");
pokey = machine.device<pokey_device>("pokey");
oki6295 = machine.device<okim6295_device>("adpcm");
@ -231,7 +231,7 @@ static READ8_HANDLER( jsa1_io_r )
if (!(space.machine().root_device().ioport(test_port)->read() & test_mask)) result ^= 0x80;
if (atarigen->m_cpu_to_sound_ready) result ^= 0x40;
if (atarigen->m_sound_to_cpu_ready) result ^= 0x20;
if ((tms5220 != NULL) && (tms5220_readyq_r(tms5220) == 0))
if ((tms5220 != NULL) && (tms5220->readyq_r() == 0))
result |= 0x10;
else
result &= ~0x10;
@ -269,7 +269,7 @@ static WRITE8_HANDLER( jsa1_io_w )
case 0x200: /* /VOICE */
if (tms5220 != NULL)
tms5220_data_w(tms5220, space, 0, data);
tms5220->data_w(space, 0, data);
break;
case 0x202: /* /WRP */
@ -291,10 +291,10 @@ static WRITE8_HANDLER( jsa1_io_w )
if (tms5220 != NULL)
{
int count;
tms5220_wsq_w(tms5220, (data&0x02)>>1);
tms5220_rsq_w(tms5220, (data&0x04)>>2);
tms5220->wsq_w((data&0x02)>>1);
tms5220->rsq_w((data&0x04)>>2);
count = 5 | ((data >> 2) & 2);
tms5220_set_frequency(tms5220, JSA_MASTER_CLOCK*2 / (16 - count));
tms5220->set_frequency(JSA_MASTER_CLOCK*2 / (16 - count));
}
/* reset the YM2151 if needed */

View File

@ -1410,7 +1410,7 @@ static SOUND_RESET( demon_sound )
state->m_last_portb_write = 0xff;
/* turn off channel A on AY8910 #0 because it is used as a low-pass filter */
ay8910_set_volume(machine.device("ay1"), 0, 0);
machine.device<ay8910_device>("ay1")->set_volume(0, 0);
}

View File

@ -103,7 +103,7 @@ struct exidy_sound_state
/* 5220/CVSD variables */
device_t *m_cvsd;
device_t *m_tms;
tms5220_device *m_tms;
pia6821_device *m_pia1;
/* sound streaming variables */
@ -533,7 +533,7 @@ static WRITE8_DEVICE_HANDLER( r6532_porta_w )
if (state->m_tms != NULL)
{
logerror("(%f)%s:TMS5220 data write = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_riot->porta_out_get());
tms5220_data_w(state->m_tms, space, 0, data);
state->m_tms->data_w(space, 0, data);
}
}
@ -542,8 +542,8 @@ static READ8_DEVICE_HANDLER( r6532_porta_r )
exidy_sound_state *state = get_safe_token(device);
if (state->m_tms != NULL)
{
logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), tms5220_status_r(state->m_tms, space, 0));
return tms5220_status_r(state->m_tms, space, 0);
logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_tms->status_r(space, 0));
return state->m_tms->status_r(space, 0);
}
else
return 0xff;
@ -554,8 +554,8 @@ static WRITE8_DEVICE_HANDLER( r6532_portb_w )
exidy_sound_state *state = get_safe_token(device);
if (state->m_tms != NULL)
{
tms5220_rsq_w(state->m_tms, data & 0x01);
tms5220_wsq_w(state->m_tms, (data >> 1) & 0x01);
state->m_tms->rsq_w(data & 0x01);
state->m_tms->wsq_w((data >> 1) & 0x01);
}
}
@ -567,8 +567,8 @@ static READ8_DEVICE_HANDLER( r6532_portb_r )
if (state->m_tms != NULL)
{
newdata &= ~0x0c;
if (tms5220_readyq_r(state->m_tms)) newdata |= 0x04;
if (tms5220_intq_r(state->m_tms)) newdata |= 0x08;
if (state->m_tms->readyq_r()) newdata |= 0x04;
if (state->m_tms->intq_r()) newdata |= 0x08;
}
return newdata;
}
@ -1126,7 +1126,7 @@ static DEVICE_START( victory_sound )
device->save_item(NAME(state->m_victory_sound_response_ack_clk));
DEVICE_START_CALL(venture_common_sh_start);
state->m_tms = device->machine().device("tms");
state->m_tms = device->machine().device<tms5220_device>("tms");
}

View File

@ -139,8 +139,8 @@ WRITE8_MEMBER(jedi_state::speech_strobe_w)
if ((new_speech_strobe_state != m_speech_strobe_state) && new_speech_strobe_state)
{
device_t *tms = machine().device("tms");
tms5220_data_w(tms, space, 0, *m_speech_data);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
tms5220->data_w(space, 0, *m_speech_data);
}
m_speech_strobe_state = new_speech_strobe_state;
}
@ -148,7 +148,8 @@ WRITE8_MEMBER(jedi_state::speech_strobe_w)
READ8_MEMBER(jedi_state::speech_ready_r)
{
return (tms5220_readyq_r(machine().device("tms"))) << 7;
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
return (tms5220->readyq_r()) << 7;
}

View File

@ -372,12 +372,12 @@ WRITE8_MEMBER(midway_ssio_device::portb1_w)
void midway_ssio_device::update_volumes()
{
ay8910_set_volume(m_ay0, 0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][0]]);
ay8910_set_volume(m_ay0, 1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][1]]);
ay8910_set_volume(m_ay0, 2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][2]]);
ay8910_set_volume(m_ay1, 0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][0]]);
ay8910_set_volume(m_ay1, 1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][1]]);
ay8910_set_volume(m_ay1, 2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][2]]);
m_ay0->set_volume(0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][0]]);
m_ay0->set_volume(1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][1]]);
m_ay0->set_volume(2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[0][2]]);
m_ay1->set_volume(0, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][0]]);
m_ay1->set_volume(1, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][1]]);
m_ay1->set_volume(2, m_mute ? 0 : m_ayvolume_lookup[m_duty_cycle[1][2]]);
}
@ -1198,7 +1198,7 @@ WRITE8_MEMBER(midway_squawk_n_talk_device::portb2_w)
// write strobe -- pass the current command to the TMS5200
if (((data ^ m_tms_strobes) & 0x02) && !(data & 0x02))
{
tms5220_data_w(m_tms5200, space, offset, m_tms_command);
m_tms5200->data_w(space, offset, m_tms_command);
// DoT expects the ready line to transition on a command/write here, so we oblige
m_pia1->ca2_w(1);
@ -1208,7 +1208,7 @@ WRITE8_MEMBER(midway_squawk_n_talk_device::portb2_w)
// read strobe -- read the current status from the TMS5200
else if (((data ^ m_tms_strobes) & 0x01) && !(data & 0x01))
{
m_pia1->porta_w(tms5220_status_r(m_tms5200, space, offset));
m_pia1->porta_w(m_tms5200->status_r(space, offset));
// DoT expects the ready line to transition on a command/write here, so we oblige
m_pia1->ca2_w(1);

View File

@ -34,17 +34,18 @@ READ8_MEMBER(starwars_state::r6532_porta_r)
/* Note: bit 4 is always set to avoid sound self test */
UINT8 olddata = m_riot->porta_in_get();
return (olddata & 0xc0) | 0x10 | (tms5220_readyq_r(machine().device("tms")) << 2);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
return (olddata & 0xc0) | 0x10 | (tms5220->readyq_r() << 2);
}
WRITE8_MEMBER(starwars_state::r6532_porta_w)
{
device_t *device = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
/* handle 5220 read */
tms5220_rsq_w(device, (data & 2)>>1);
tms5220->rsq_w((data & 2)>>1);
/* handle 5220 write */
tms5220_wsq_w(device, (data & 1)>>0);
tms5220->wsq_w((data & 1)>>0);
}
@ -57,9 +58,9 @@ WRITE_LINE_MEMBER(starwars_state::snd_interrupt)
const riot6532_interface starwars_riot6532_intf =
{
DEVCB_DRIVER_MEMBER(starwars_state,r6532_porta_r),
DEVCB_DEVICE_HANDLER("tms", tms5220_status_r),
DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r),
DEVCB_DRIVER_MEMBER(starwars_state,r6532_porta_w),
DEVCB_DEVICE_HANDLER("tms", tms5220_data_w),
DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w),
DEVCB_DRIVER_LINE_MEMBER(starwars_state,snd_interrupt)
};

View File

@ -394,37 +394,37 @@ READ8_MEMBER(atarisy1_state::switch_6502_r)
WRITE8_MEMBER(atarisy1_state::via_pa_w)
{
device_t *device = machine().device("tms");
tms5220_data_w(device, space, 0, data);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
tms5220->data_w(space, 0, data);
}
READ8_MEMBER(atarisy1_state::via_pa_r)
{
device_t *device = machine().device("tms");
return tms5220_status_r(device, space, 0);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
return tms5220->status_r(space, 0);
}
WRITE8_MEMBER(atarisy1_state::via_pb_w)
{
device_t *device = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
/* write strobe */
tms5220_wsq_w(device, data & 1);
tms5220->wsq_w(data & 1);
/* read strobe */
tms5220_rsq_w(device, (data & 2)>>1);
tms5220->rsq_w((data & 2)>>1);
/* bit 4 is connected to an up-counter, clocked by SYCLKB */
data = 5 | ((data >> 3) & 2);
tms5220_set_frequency(device, ATARI_CLOCK_14MHz/2 / (16 - data));
tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / (16 - data));
}
READ8_MEMBER(atarisy1_state::via_pb_r)
{
device_t *device = machine().device("tms");
return (tms5220_readyq_r(device) << 2) | (tms5220_intq_r(device) << 3);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
return (tms5220->readyq_r() << 2) | (tms5220->intq_r() << 3);
}

View File

@ -350,7 +350,7 @@ READ8_MEMBER(atarisy2_state::switch_6502_r)
if (m_cpu_to_sound_ready) result |= 0x01;
if (m_sound_to_cpu_ready) result |= 0x02;
if ((m_has_tms5220) && (tms5220_readyq_r(machine().device("tms")) == 0))
if ((m_has_tms5220) && (machine().device<tms5220_device>("tms")->readyq_r() == 0))
result &= ~0x04;
if (!(ioport("1801")->read() & 0x80)) result |= 0x10;
@ -363,7 +363,7 @@ WRITE8_MEMBER(atarisy2_state::switch_6502_w)
if (m_has_tms5220)
{
data = 12 | ((data >> 5) & 1);
tms5220_set_frequency(machine().device("tms"), MASTER_CLOCK/4 / (16 - data) / 2);
machine().device<tms5220_device>("tms")->set_frequency(MASTER_CLOCK/4 / (16 - data) / 2);
}
}
@ -736,7 +736,7 @@ WRITE8_MEMBER(atarisy2_state::tms5220_w)
{
if (m_has_tms5220)
{
tms5220_data_w(machine().device("tms"), space, 0, data);
machine().device<tms5220_device>("tms")->data_w(space, 0, data);
}
}
@ -744,7 +744,7 @@ WRITE8_MEMBER(atarisy2_state::tms5220_strobe_w)
{
if (m_has_tms5220)
{
tms5220_wsq_w(machine().device("tms"), 1-(offset & 1));
machine().device<tms5220_device>("tms")->wsq_w(1-(offset & 1));
}
}
@ -3178,7 +3178,7 @@ DRIVER_INIT_MEMBER(atarisy2_state,paperboy)
m_pedal_count = 0;
m_has_tms5220 = 1;
tms5220_rsq_w(machine().device("tms"), 1); // /RS is tied high on sys2 hw
machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
}
@ -3191,7 +3191,7 @@ DRIVER_INIT_MEMBER(atarisy2_state,720)
m_pedal_count = -1;
m_has_tms5220 = 1;
tms5220_rsq_w(machine().device("tms"), 1); // /RS is tied high on sys2 hw
machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
}
@ -3233,7 +3233,7 @@ DRIVER_INIT_MEMBER(atarisy2_state,apb)
m_pedal_count = 2;
m_has_tms5220 = 1;
tms5220_rsq_w(machine().device("tms"), 1); // /RS is tied high on sys2 hw
machine().device<tms5220_device>("tms")->rsq_w(1); // /RS is tied high on sys2 hw
}

View File

@ -30,7 +30,6 @@
#include "machine/6840ptm.h"
#include "machine/nvram.h"
#include "sound/dac.h"
#include "sound/tms5220.h"
#include "includes/esripsys.h"
@ -521,10 +520,10 @@ READ8_MEMBER(esripsys_state::tms5220_r)
if (offset == 0)
{
/* TMS5220 core returns status bits in D7-D6 */
UINT8 status = tms5220_status_r(m_tms, space, 0);
UINT8 status = m_tms->status_r(space, 0);
status = ((status & 0x80) >> 5) | ((status & 0x40) >> 5) | ((status & 0x20) >> 5);
return (tms5220_readyq_r(m_tms) << 7) | (tms5220_intq_r(m_tms) << 6) | status;
return (m_tms->readyq_r() << 7) | (m_tms->intq_r() << 6) | status;
}
return 0xff;
@ -536,12 +535,12 @@ WRITE8_MEMBER(esripsys_state::tms5220_w)
if (offset == 0)
{
m_tms_data = data;
tms5220_data_w(m_tms, space, 0, m_tms_data);
m_tms->data_w(space, 0, m_tms_data);
}
#if 0
if (offset == 1)
{
tms5220_data_w(m_tms, space, 0, m_tms_data);
m_tms->data_w(space, 0, m_tms_data);
}
#endif
}

View File

@ -351,7 +351,8 @@ WRITE8_MEMBER(firefox_state::sound_to_main_w)
READ8_MEMBER(firefox_state::riot_porta_r)
{
device_t *tms = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
/* bit 7 = MAINFLAG */
/* bit 6 = SOUNDFLAG */
/* bit 5 = PA5 */
@ -361,18 +362,18 @@ READ8_MEMBER(firefox_state::riot_porta_r)
/* bit 1 = TMS /read */
/* bit 0 = TMS /write */
return (m_main_to_sound_flag << 7) | (m_sound_to_main_flag << 6) | 0x10 | (tms5220_readyq_r(tms) << 2);
return (m_main_to_sound_flag << 7) | (m_sound_to_main_flag << 6) | 0x10 | (tms5220->readyq_r() << 2);
}
WRITE8_MEMBER(firefox_state::riot_porta_w)
{
device_t *tms = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
/* handle 5220 read */
tms5220_rsq_w(tms, (data>>1) & 1);
tms5220->rsq_w((data>>1) & 1);
/* handle 5220 write */
tms5220_wsq_w(tms, data & 1);
tms5220->wsq_w(data & 1);
}
WRITE_LINE_MEMBER(firefox_state::riot_irq)
@ -695,9 +696,9 @@ GFXDECODE_END
static const riot6532_interface riot_intf =
{
DEVCB_DRIVER_MEMBER(firefox_state,riot_porta_r),
DEVCB_DEVICE_HANDLER("tms", tms5220_status_r),
DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r),
DEVCB_DRIVER_MEMBER(firefox_state,riot_porta_w),
DEVCB_DEVICE_HANDLER("tms", tms5220_data_w),
DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w),
DEVCB_DRIVER_LINE_MEMBER(firefox_state,riot_irq)
};

View File

@ -207,8 +207,9 @@ WRITE16_MEMBER(gauntlet_state::sound_reset_w)
if (m_sound_reset_val & 1)
{
machine().device("ymsnd")->reset();
machine().device("tms")->reset();
tms5220_set_frequency(machine().device("tms"), ATARI_CLOCK_14MHz/2 / 11);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
tms5220->reset();
tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / 11);
set_ym2151_volume(0);
set_pokey_volume(0);
set_tms5220_volume(0);
@ -227,11 +228,12 @@ WRITE16_MEMBER(gauntlet_state::sound_reset_w)
READ8_MEMBER(gauntlet_state::switch_6502_r)
{
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
int temp = 0x30;
if (m_cpu_to_sound_ready) temp ^= 0x80;
if (m_sound_to_cpu_ready) temp ^= 0x40;
if (!tms5220_readyq_r(machine().device("tms"))) temp ^= 0x20;
if (!tms5220->readyq_r()) temp ^= 0x20;
if (!(ioport("803008")->read() & 0x0008)) temp ^= 0x10;
return temp;
@ -246,7 +248,7 @@ READ8_MEMBER(gauntlet_state::switch_6502_r)
WRITE8_MEMBER(gauntlet_state::sound_ctl_w)
{
device_t *tms = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
switch (offset & 7)
{
case 0: /* music reset, bit D7, low reset */
@ -254,16 +256,16 @@ WRITE8_MEMBER(gauntlet_state::sound_ctl_w)
break;
case 1: /* speech write, bit D7, active low */
tms5220_wsq_w(tms, data >> 7);
tms5220->wsq_w(data >> 7);
break;
case 2: /* speech reset, bit D7, active low */
tms5220_rsq_w(tms, data >> 7);
tms5220->rsq_w(data >> 7);
break;
case 3: /* speech squeak, bit D7 */
data = 5 | ((data >> 6) & 2);
tms5220_set_frequency(tms, ATARI_CLOCK_14MHz/2 / (16 - data));
tms5220->set_frequency(ATARI_CLOCK_14MHz/2 / (16 - data));
break;
}
}
@ -342,7 +344,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, gauntlet_state )
AM_RANGE(0x1030, 0x103f) AM_MIRROR(0x27c0) AM_READWRITE(switch_6502_r, sound_ctl_w)
AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x27c0) AM_DEVREADWRITE("pokey", pokey_device, read, write)
AM_RANGE(0x1810, 0x1811) AM_MIRROR(0x27ce) AM_DEVREADWRITE("ymsnd", ym2151_device, read, write)
AM_RANGE(0x1820, 0x182f) AM_MIRROR(0x27c0) AM_DEVWRITE_LEGACY("tms", tms5220_data_w)
AM_RANGE(0x1820, 0x182f) AM_MIRROR(0x27c0) AM_DEVWRITE("tms", tms5220_device, data_w)
AM_RANGE(0x1830, 0x183f) AM_MIRROR(0x27c0) AM_READWRITE(m6502_irq_ack_r, m6502_irq_ack_w)
AM_RANGE(0x4000, 0xffff) AM_ROM
ADDRESS_MAP_END

View File

@ -163,7 +163,7 @@ INPUT_PORTS_END
void icecold_state::machine_reset()
{
// CH-C is used for generate a 30hz clock
ay8910_set_volume(m_ay8910_0, 2, 0);
m_ay8910_0->set_volume(2, 0);
m_rmotor = m_lmotor = 10;
m_sint = 0;

View File

@ -552,8 +552,8 @@ static ADDRESS_MAP_START( looping_sound_map, AS_PROGRAM, 8, looping_state )
AM_RANGE(0x3c00, 0x3c00) AM_MIRROR(0x00f4) AM_DEVREADWRITE("aysnd", ay8910_device, data_r, address_w)
AM_RANGE(0x3c02, 0x3c02) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("aysnd", ay8910_device, data_w)
AM_RANGE(0x3c03, 0x3c03) AM_MIRROR(0x00f6) AM_NOP
AM_RANGE(0x3e00, 0x3e00) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("tms", tms5220n_device, write)
AM_RANGE(0x3e02, 0x3e02) AM_MIRROR(0x00f4) AM_DEVREAD("tms", tms5220n_device, read) AM_WRITENOP
AM_RANGE(0x3e00, 0x3e00) AM_MIRROR(0x00f4) AM_READNOP AM_DEVWRITE("tms", tms5220_device, data_w)
AM_RANGE(0x3e02, 0x3e02) AM_MIRROR(0x00f4) AM_DEVREAD("tms", tms5220_device, status_r) AM_WRITENOP
AM_RANGE(0x3e03, 0x3e03) AM_MIRROR(0x00f6) AM_NOP
ADDRESS_MAP_END
@ -612,12 +612,6 @@ GFXDECODE_END
*
*************************************/
static const tms52xx_config tms5220interface =
{
DEVCB_DRIVER_LINE_MEMBER(looping_state,looping_spcint), // IRQ
DEVCB_NULL // READYQ
};
static const ay8910_interface ay8910_config =
{
AY8910_LEGACY_OUTPUT,
@ -676,8 +670,8 @@ static MACHINE_CONFIG_START( looping, looping_state )
MCFG_SOUND_CONFIG(ay8910_config)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20)
MCFG_SOUND_ADD("tms", TMS5220N, TMS_CLOCK)
MCFG_SOUND_CONFIG(tms5220interface)
MCFG_SOUND_ADD("tms", TMS5220, TMS_CLOCK)
MCFG_TMS52XX_IRQ_HANDLER(WRITELINE(looping_state, looping_spcint))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MCFG_DAC_ADD("dac")

View File

@ -795,8 +795,8 @@ READ8_MEMBER(maygay1b_state::latch_st_lo)
READ8_MEMBER(maygay1b_state::m1_meter_r)
{
device_t *ay8910 = machine().device("aysnd");
return ~ay8910_read_ym(ay8910);
ay8910_device *ay8910 = machine().device<ay8910_device>("aysnd");
return ~ay8910->data_r(space, offset);
}
static ADDRESS_MAP_START( m1_memmap, AS_PROGRAM, 8, maygay1b_state )

View File

@ -957,11 +957,6 @@ const namco_06xx_config topracern_namco_06xx_intf =
"maincpu", "51xx", NULL, NULL, NULL
};
static const tms52xx_config tms_intf =
{
DEVCB_NULL
};
static MACHINE_CONFIG_START( topracern, polepos_state )
/* basic machine hardware */
@ -1030,10 +1025,9 @@ static MACHINE_CONFIG_DERIVED( polepos2bi, topracern )
MCFG_CPU_PROGRAM_MAP(sound_z80_bootleg_map)
MCFG_CPU_IO_MAP(sound_z80_bootleg_iomap)
MCFG_SOUND_ADD("tms", TMS5220N, 600000) /* ? Mhz */
MCFG_SOUND_ADD("tms", TMS5220, 600000) /* ? Mhz */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.80)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.80)
MCFG_SOUND_CONFIG(tms_intf)
MACHINE_CONFIG_END

View File

@ -240,11 +240,6 @@ static GFXDECODE_START( portrait )
GFXDECODE_ENTRY( "gfx1", 0x00000, tile_layout, 0, 0x800/8 )
GFXDECODE_END
static const tms52xx_config tms_intf =
{
DEVCB_NULL
};
static MACHINE_CONFIG_START( portrait, portrait_state )
MCFG_CPU_ADD("maincpu", Z80, 4000000) /* 4 MHz ? */
@ -270,9 +265,8 @@ static MACHINE_CONFIG_START( portrait, portrait_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("tms", TMS5200N, 640000)
MCFG_SOUND_ADD("tms", TMS5200, 640000)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MCFG_SOUND_CONFIG(tms_intf)
MACHINE_CONFIG_END

View File

@ -46,7 +46,7 @@ public:
m_maincpu(*this, "maincpu"),
m_dsp(*this, "dsp") { }
required_device<tms5220n_device> m_tms;
required_device<tms5220_device> m_tms;
int m_control_num;
required_shared_ptr<UINT16> m_shared_ram;
UINT8 m_nvram[0x800];
@ -400,11 +400,6 @@ static const riot6532_interface tomcat_riot6532_intf =
DEVCB_NULL // connected to IRQ line of 6502
};
static const tms52xx_config tms_intf =
{
DEVCB_NULL
};
static MACHINE_CONFIG_START( tomcat, tomcat_state )
MCFG_CPU_ADD("maincpu", M68010, XTAL_12MHz / 2)
MCFG_CPU_PROGRAM_MAP(tomcat_map)
@ -444,10 +439,9 @@ static MACHINE_CONFIG_START( tomcat, tomcat_state )
MCFG_POKEY_ADD("pokey2", XTAL_14_31818MHz / 8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.20)
MCFG_SOUND_ADD("tms", TMS5220N, 325000)
MCFG_SOUND_ADD("tms", TMS5220, 325000)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50)
MCFG_SOUND_CONFIG(tms_intf)
MCFG_YM2151_ADD("ymsnd", XTAL_14_31818MHz / 4)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.60)

View File

@ -96,7 +96,7 @@ WRITE8_MEMBER(zaccaria_state::ay8910_port0a_w)
/* 150 below to scale to volume 100 */
v = (150 * table[ba]) / (4700 + table[ba]);
//printf("dac1w %02d %04d\n", ba, v);
ay8910_set_volume(machine().device("ay2"), 1, v);
machine().device<ay8910_device>("ay2")->set_volume(1, v);
}
@ -160,12 +160,12 @@ INTERRUPT_GEN_MEMBER(zaccaria_state::zaccaria_cb1_toggle)
WRITE8_MEMBER(zaccaria_state::zaccaria_port1b_w)
{
device_t *tms = machine().device("tms");
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
// bit 0 = /RS
tms5220_rsq_w(tms, (data >> 0) & 0x01);
tms5220->rsq_w((data >> 0) & 0x01);
// bit 1 = /WS
tms5220_wsq_w(tms, (data >> 1) & 0x01);
tms5220->wsq_w((data >> 1) & 0x01);
// bit 3 = "ACS" (goes, inverted, to input port 6 bit 3)
m_acs = ~data & 0x08;
@ -546,13 +546,13 @@ static const pia6821_interface pia_0_config =
static const pia6821_interface pia_1_config =
{
DEVCB_DEVICE_HANDLER("tms", tms5220_status_r), /* port A in */
DEVCB_DEVICE_MEMBER("tms", tms5220_device, status_r), /* port A in */
DEVCB_NULL, /* port B in */
DEVCB_NULL, /* line CA1 in */
DEVCB_NULL, /* line CB1 in */ // tms5220_intq_r, handled below in tms5220_config
DEVCB_NULL, /* line CA2 in */ // tms5220_readyq_r, "
DEVCB_NULL, /* line CB2 in */
DEVCB_DEVICE_HANDLER("tms", tms5220_data_w), /* port A out */
DEVCB_DEVICE_MEMBER("tms", tms5220_device, data_w), /* port A out */
DEVCB_DRIVER_MEMBER(zaccaria_state,zaccaria_port1b_w), /* port B out */
DEVCB_NULL, /* line CA2 out */
DEVCB_NULL, /* port CB2 out */
@ -560,12 +560,6 @@ static const pia6821_interface pia_1_config =
DEVCB_NULL /* IRQB */
};
static const tms5220_interface tms5220_config =
{
DEVCB_DEVICE_LINE_MEMBER("pia1", pia6821_device, cb1_w), /* IRQ handler */
DEVCB_DEVICE_LINE_MEMBER("pia1", pia6821_device, ca2_w) /* READYQ handler */
};
INTERRUPT_GEN_MEMBER(zaccaria_state::vblank_irq)
{
if(m_nmi_mask)
@ -622,7 +616,8 @@ static MACHINE_CONFIG_START( zaccaria, zaccaria_state )
/* There is no xtal, the clock is obtained from a RC oscillator as shown in the TMS5220 datasheet (R=100kOhm C=22pF) */
/* 162kHz measured on pin 3 20 minutesa fter power on. Clock would then be 162*4=648kHz. */
MCFG_SOUND_ADD("tms", TMS5200, 649200) /* ROMCLK pin measured at 162.3Khz, OSC is exactly *4 of that) */
MCFG_SOUND_CONFIG(tms5220_config)
MCFG_TMS52XX_IRQ_HANDLER(DEVWRITELINE("pia1", pia6821_device, cb1_w))
MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE("pia1", pia6821_device, ca2_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
MACHINE_CONFIG_END

View File

@ -11,6 +11,7 @@
#include "cpu/esrip/esrip.h"
#include "sound/dac.h"
#include "sound/tms5220.h"
/* TODO */
#define ESRIPSYS_PIXEL_CLOCK (XTAL_25MHz / 2)
@ -48,7 +49,7 @@ public:
required_device<esrip_device> m_videocpu;
required_device<cpu_device> m_gamecpu;
required_device<cpu_device> m_soundcpu;
required_device<device_t> m_tms;
required_device<tms5220_device> m_tms;
UINT8 m_g_iodata;
UINT8 m_g_ioaddr;

View File

@ -23,7 +23,7 @@ public:
m_subcpu(*this, "sub"),
m_subcpu2(*this, "sub2") { }
optional_device<tms5220n_device> m_tms;
optional_device<tms5220_device> m_tms;
UINT8 m_steer_last;
UINT8 m_steer_delta;
INT16 m_steer_accum;

View File

@ -11,7 +11,7 @@ public:
m_spriteram(*this, "spriteram"),
m_maincpu(*this, "maincpu") { }
required_device<tms5200n_device> m_tms;
required_device<tms5200_device> m_tms;
required_shared_ptr<UINT8> m_bgvideoram;
required_shared_ptr<UINT8> m_fgvideoram;
int m_scroll;

View File

@ -203,7 +203,8 @@ WRITE8_MEMBER(mhavoc_state::mhavoc_rom_banksel_w)
CUSTOM_INPUT_MEMBER(mhavoc_state::tms5220_r)
{
return tms5220_readyq_r(machine().device("tms")) ? 1 : 0;
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
return tms5220->readyq_r() ? 1 : 0;
}
CUSTOM_INPUT_MEMBER(mhavoc_state::mhavoc_bit67_r)
@ -308,8 +309,8 @@ WRITE8_MEMBER(mhavoc_state::mhavocrv_speech_data_w)
WRITE8_MEMBER(mhavoc_state::mhavocrv_speech_strobe_w)
{
device_t *tms = machine().device("tms");
tms5220_data_w(tms, space, 0, m_speech_write_buffer);
tms5220_device *tms5220 = machine().device<tms5220_device>("tms");
tms5220->data_w(space, 0, m_speech_write_buffer);
}
/*************************************

View File

@ -1,111 +0,0 @@
/*
spchroms.c - This is an emulator for "typical" speech ROMs from TI, as used by TI99/4(a).
In order to support its speech processor, TI designed some ROMs with a 1-bit data bus
and 4-bit address bus (multiplexed 5 times to provide a 18-bit address).
A fairly complete description of such a ROM (tms6100) is found in the tms5220 datasheet.
One notable thing is that the address is a byte address (*NOT* a bit address).
This file is designed to be interfaced with the tms5220 core.
Interfacing it with the tms5110 would make sense, too.
*/
#include "emu.h"
#include "spchroms.h"
static UINT8 *speechrom_data = NULL; /* pointer to speech ROM data */
static unsigned long speechROMlen = 0; /* length of data pointed by speechrom_data, from 0 to 2^18 */
static unsigned long speechROMaddr; /* 18 bit pointer in ROM */
#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */
static int load_pointer = 0; /* which 4-bit nibble will be affected by load address */
static int ROM_bits_count; /* current bit position in ROM */
/*
set the speech ROMs
*/
void spchroms_config(running_machine &machine, const spchroms_interface *intf)
{
if (intf->memory_region == NULL)
{ /* no speech ROM */
speechrom_data = NULL;
speechROMlen = 0;
}
else
{ /* speech ROM */
speechrom_data = machine.root_device().memregion(intf->memory_region)->base();
/* take region length */
speechROMlen = machine.root_device().memregion(intf->memory_region)->bytes();
}
}
/*
Read 'count' bits serially from speech ROM
*/
int spchroms_read(device_t *device, int count)
{
int val;
if (load_pointer)
{ /* first read after load address is ignored */
load_pointer = 0;
count--;
}
if (speechROMaddr < speechROMlen)
if (count < ROM_bits_count)
{
ROM_bits_count -= count;
val = (speechrom_data[speechROMaddr] >> ROM_bits_count) & (0xFF >> (8 - count));
}
else
{
val = ((int) speechrom_data[speechROMaddr]) << 8;
speechROMaddr = (speechROMaddr + 1) & TMS5220_ADDRESS_MASK;
if (speechROMaddr < speechROMlen)
val |= speechrom_data[speechROMaddr];
ROM_bits_count += 8 - count;
val = (val >> ROM_bits_count) & (0xFF >> (8 - count));
}
else
val = 0;
return val;
}
/*
Write an address nibble to speech ROM
*/
void spchroms_load_address(device_t *device, int data)
{
/* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
This code does not care about this. */
speechROMaddr = ( (speechROMaddr & ~(0xf << load_pointer))
| (((unsigned long) (data & 0xf)) << load_pointer) ) & TMS5220_ADDRESS_MASK;
load_pointer += 4;
ROM_bits_count = 8;
}
/*
Perform a read and branch command
*/
void spchroms_read_and_branch(device_t *device)
{
/* tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
there is a bus contention. This code does not care about this. */
if (speechROMaddr < speechROMlen-1)
speechROMaddr = (speechROMaddr & 0x3c000UL)
| (((((unsigned long) speechrom_data[speechROMaddr]) << 8)
| speechrom_data[speechROMaddr+1]) & 0x3fffUL);
else if (speechROMaddr == speechROMlen-1)
speechROMaddr = (speechROMaddr & 0x3c000UL)
| ((((unsigned long) speechrom_data[speechROMaddr]) << 8) & 0x3fffUL);
else
speechROMaddr = (speechROMaddr & 0x3c000UL);
ROM_bits_count = 8;
}

View File

@ -1,15 +0,0 @@
#ifndef __SPCHROMS_H
#define __SPCHROMS_H
struct spchroms_interface
{
const char *memory_region; /* memory region where the speech ROM is. NULL means no speech ROM */
};
void spchroms_config(running_machine &machine, const spchroms_interface *intf);
int spchroms_read(device_t *device, int count);
void spchroms_load_address(device_t *device, int data);
void spchroms_read_and_branch(device_t *device);
#endif

View File

@ -54,7 +54,7 @@ TODO:
#include "cpu/tms7000/tms7000.h"
#include "video/tms3556.h"
#include "sound/tms5220.h"
#include "audio/spchroms.h"
#include "machine/spchrom.h"
//#include "imagedev/cartslot.h"
//#include "imagedev/cassette.h"
@ -74,7 +74,6 @@ public:
required_device<tms5220c_device> m_tms5220c;
virtual void machine_start();
virtual void machine_reset();
DECLARE_READ8_MEMBER( mailbox_wx319_r );
DECLARE_WRITE8_MEMBER( mailbox_wx318_w );
@ -281,9 +280,9 @@ READ8_MEMBER(exelv_state::tms7041_porta_r)
logerror("tms7041_porta_r\n");
data |= (m_tms7020_portb & 0x01 ) ? 0x04 : 0x00;
data |= tms5220_intq_r(m_tms5220c) ? 0x08 : 0x00;
data |= m_tms5220c->intq_r() ? 0x08 : 0x00;
data |= (m_tms7020_portb & 0x02) ? 0x10 : 0x00;
data |= tms5220_readyq_r(m_tms5220c) ? 0x80 : 0x00;
data |= m_tms5220c->readyq_r() ? 0x80 : 0x00;
return data;
}
@ -319,8 +318,8 @@ WRITE8_MEMBER(exelv_state::tms7041_portb_w)
{
logerror("tms7041_portb_w: data = 0x%02x\n", data);
tms5220_wsq_w(m_tms5220c, (data & 0x01) ? 1 : 0);
tms5220_rsq_w(m_tms5220c, (data & 0x02) ? 1 : 0);
m_tms5220c->wsq_w((data & 0x01) ? 1 : 0);
m_tms5220c->rsq_w((data & 0x02) ? 1 : 0);
m_maincpu->set_input_line(TMS7000_IRQ1_LINE, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE);
@ -381,7 +380,7 @@ WRITE8_MEMBER(exelv_state::tms7041_portd_w)
{
logerror("tms7041_portd_w: data = 0x%02x\n", data);
tms5220_data_w(m_tms5220c, space, 0, BITSWAP8(data,0,1,2,3,4,5,6,7));
m_tms5220c->data_w(space, 0, BITSWAP8(data,0,1,2,3,4,5,6,7));
m_tms7041_portd = data;
}
@ -475,16 +474,6 @@ static INPUT_PORTS_START(exelv)
INPUT_PORTS_END
static const tms5220_interface exl100_tms5220_interface =
{
DEVCB_NULL, /* no IRQ callback */
DEVCB_NULL, /* no Ready callback */
spchroms_read, /* speech ROM read handler */
spchroms_load_address, /* speech ROM load address handler */
spchroms_read_and_branch /* speech ROM read and branch handler */
};
void exelv_state::palette_init()
{
int i, red, green, blue;
@ -519,12 +508,6 @@ void exelv_state::machine_start()
save_item(NAME(m_wx319));
}
void exelv_state::machine_reset()
{
static const spchroms_interface exelv_speech_intf = {"tms5220c"};
spchroms_config(machine(), &exelv_speech_intf);
}
static MACHINE_CONFIG_START( exl100, exelv_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", TMS7000_EXL, XTAL_4_9152MHz) /* TMS7020 */
@ -557,10 +540,12 @@ static MACHINE_CONFIG_START( exl100, exelv_state )
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
/* sound */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000)
MCFG_SOUND_CONFIG(exl100_tms5220_interface)
MCFG_TMS52XX_SPEECHROM("vsm")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MACHINE_CONFIG_END
@ -597,10 +582,12 @@ static MACHINE_CONFIG_START( exeltel, exelv_state )
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
/* sound */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000)
MCFG_SOUND_CONFIG(exl100_tms5220_interface)
MCFG_TMS52XX_SPEECHROM("vsm")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MACHINE_CONFIG_END
@ -618,7 +605,7 @@ ROM_START(exl100)
ROM_REGION(0x10000, "user1", ROMREGION_ERASEFF) /* cartridge area */
/* is this correct for exl100? */
ROM_REGION(0x8000, "tms5220c", 0)
ROM_REGION(0x8000, "vsm", 0)
ROM_LOAD("cm62312.bin", 0x0000, 0x4000, CRC(93b817de) SHA1(03863087a071b8f22d36a52d18243f1c33e17ff7)) /* system speech ROM */
ROM_END
@ -636,7 +623,7 @@ ROM_START(exeltel)
ROM_SYSTEM_BIOS( 1, "spanish", "Spanish" )
ROMX_LOAD("amper.bin", 0x0000, 0x10000, CRC(45af256c) SHA1(3bff16542f8ac55b9841084ea38034132459facb), ROM_BIOS(2)) /* Spanish system rom */
ROM_REGION(0x8000, "tms5220c", 0)
ROM_REGION(0x8000, "vsm", 0)
ROM_LOAD("cm62312.bin", 0x0000, 0x4000, CRC(93b817de) SHA1(03863087a071b8f22d36a52d18243f1c33e17ff7)) /* system speech ROM */
ROM_END

View File

@ -64,7 +64,7 @@ static ADDRESS_MAP_START( mpf1b_io_map, AS_IO, 8, mpf1_state )
AM_RANGE(0x00, 0x03) AM_MIRROR(0x3c) AM_DEVREADWRITE(I8255A_TAG, i8255_device, read, write)
AM_RANGE(0x40, 0x43) AM_MIRROR(0x3c) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write)
AM_RANGE(0x80, 0x83) AM_MIRROR(0x3c) AM_DEVREADWRITE(Z80PIO_TAG, z80pio_device, read, write)
AM_RANGE(0xfe, 0xfe) AM_MIRROR(0x01) AM_DEVREADWRITE_LEGACY(TMS5220_TAG, tms5220_status_r, tms5220_data_w)
AM_RANGE(0xfe, 0xfe) AM_MIRROR(0x01) AM_DEVREADWRITE(TMS5220_TAG, tms5220_device, status_r, data_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( mpf1p_io_map, AS_IO, 8, mpf1_state )
@ -317,19 +317,6 @@ static const cassette_interface mpf1_cassette_interface =
NULL
};
/* TMS5220 Interface */
static const tms5220_interface mpf1_tms5220_intf =
{
DEVCB_NULL, /* no IRQ callback */
DEVCB_NULL, /* no Ready callback */
#if 1
spchroms_read, /* speech ROM read handler */
spchroms_load_address, /* speech ROM load address handler */
spchroms_read_and_branch /* speech ROM read and branch handler */
#endif
};
/* Machine Initialization */
TIMER_DEVICE_CALLBACK_MEMBER(mpf1_state::check_halt_callback)
@ -404,7 +391,6 @@ static MACHINE_CONFIG_START( mpf1b, mpf1_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MCFG_SOUND_ADD(TMS5220_TAG, TMS5220, 680000L)
MCFG_SOUND_CONFIG(mpf1_tms5220_intf)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MCFG_TIMER_DRIVER_ADD_PERIODIC("halt_timer", mpf1_state, check_halt_callback, attotime::from_hz(1))

View File

@ -126,8 +126,8 @@ WRITE8_MEMBER( pes_state::rsws_w )
#ifdef DEBUG_PORTS
logerror("port0 write: RSWS states updated: /RS: %d, /WS: %d\n", m_rsstate, m_wsstate);
#endif
tms5220_rsq_w(state->m_speech, m_rsstate);
tms5220_wsq_w(state->m_speech, m_wsstate);
state->m_speech->rsq_w(m_rsstate);
state->m_speech->wsq_w(m_wsstate);
}
WRITE8_MEMBER( pes_state::port1_w )
@ -136,7 +136,7 @@ WRITE8_MEMBER( pes_state::port1_w )
#ifdef DEBUG_PORTS
logerror("port1 write: tms5220 data written: %02X\n", data);
#endif
tms5220_data_w(state->m_speech, space, 0, data);
state->m_speech->data_w(space, 0, data);
}
@ -144,7 +144,7 @@ READ8_MEMBER( pes_state::port1_r )
{
UINT8 data = 0xFF;
pes_state *state = machine().driver_data<pes_state>();
data = tms5220_status_r(state->m_speech, space, 0);
data = state->m_speech->status_r(space, 0);
#ifdef DEBUG_PORTS
logerror("port1 read: tms5220 data read: 0x%02X\n", data);
#endif
@ -186,8 +186,8 @@ READ8_MEMBER( pes_state::port3_r )
{
data |= 0x10; // set RTS bit
}
data |= (tms5220_intq_r(state->m_speech)<<2);
data |= (tms5220_readyq_r(state->m_speech)<<3);
data |= (state->m_speech->intq_r()<<2);
data |= (state->m_speech->readyq_r()<<3);
#ifdef DEBUG_PORTS
logerror("port3 read: returning 0x%02X: ", data);
logerror("RXD: %d; ", BIT(data,0));

View File

@ -5,7 +5,7 @@
#include "emu.h"
#include "audio/spchroms.h"
#include "machine/spchrom.h"
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
#include "imagedev/cassette.h"

View File

@ -79,7 +79,7 @@ UINT8 a2bus_echoii_device::read_c0nx(address_space &space, UINT8 offset)
switch (offset)
{
case 0:
return 0x1f | tms5220_status_r(m_tms, space, 0);
return 0x1f | m_tms->status_r(space, 0);
}
return 0;
@ -90,7 +90,7 @@ void a2bus_echoii_device::write_c0nx(address_space &space, UINT8 offset, UINT8 d
switch (offset)
{
case 0:
tms5220_data_w(m_tms, space, offset, data);
m_tms->data_w(space, offset, data);
break;
}
}

View File

@ -545,7 +545,7 @@ UINT8 a2bus_echoplus_device::read_c0nx(address_space &space, UINT8 offset)
switch (offset)
{
case 0:
return 0x1f | tms5220_status_r(m_tms, space, 0);
return 0x1f | m_tms->status_r(space, 0);
}
return 0;
@ -556,7 +556,7 @@ void a2bus_echoplus_device::write_c0nx(address_space &space, UINT8 offset, UINT8
switch (offset)
{
case 0:
tms5220_data_w(m_tms, space, offset, data);
m_tms->data_w(space, offset, data);
break;
}
}

View File

@ -2707,7 +2707,7 @@ void rmnimbus_state::rmni_sound_reset()
//device_t *ay8910 = machine().device(AY8910_TAG);
device_t *msm5205 = machine().device(MSM5205_TAG);
//ay8910_reset_ym(ay8910);
//ay8910->reset();
msm5205_reset_w(msm5205, 1);
m_last_playmode=MSM5205_S48_4B;

View File

@ -20,14 +20,13 @@
#include "spchsyn.h"
#include "sound/wave.h"
#include "machine/spchrom.h"
#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */
#define VERBOSE 1
#define LOG logerror
#define SPEECHROM_TAG "speechrom"
#define REAL_TIMING 0
/****************************************************************************/
@ -108,7 +107,7 @@ READ8Z_MEMBER( ti_speech_synthesizer_device::readz )
if ((offset & m_select_mask)==m_select_value)
{
machine().device("maincpu")->execute().adjust_icount(-(18+3)); /* this is just a minimum, it can be more */
*value = m_vsp->read(space, offset, 0xff) & 0xff;
*value = m_vsp->status_r(space, offset, 0xff) & 0xff;
if (VERBOSE>4) LOG("spchsyn: read value = %02x\n", *value);
}
}
@ -126,7 +125,7 @@ WRITE8_MEMBER( ti_speech_synthesizer_device::write )
/* when there are 15 bytes in FIFO. It should be 16. Of course, if */
/* it were the case, we would need to store the value on the bus, */
/* which would be more complex. */
if (!m_vsp->readyq())
if (!m_vsp->readyq_r())
{
attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready());
int cycles_to_ready = machine().device<cpu_device>("maincpu")->attotime_to_cycles(time_to_ready);
@ -136,104 +135,11 @@ WRITE8_MEMBER( ti_speech_synthesizer_device::write )
machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
}
if (VERBOSE>4) LOG("spchsyn: write value = %02x\n", data);
m_vsp->write(space, offset, data);
m_vsp->data_w(space, offset, data);
}
}
#endif
/****************************************************************************
Callbacks from TMS5220
*****************************************************************************/
/*
Read 'count' bits serially from speech ROM. The offset is used as the count.
*/
READ8_MEMBER( ti_speech_synthesizer_device::spchrom_read )
{
int val;
int count = offset;
if (m_load_pointer != 0)
{ // first read after load address is ignored
m_load_pointer = 0;
count--;
}
if (m_sprom_address < m_sprom_length)
{
if (count < m_rombits_count)
{
m_rombits_count -= count;
val = (m_speechrom[m_sprom_address] >> m_rombits_count) & (0xFF >> (8 - count));
}
else
{
val = ((int)m_speechrom[m_sprom_address]) << 8;
m_sprom_address = (m_sprom_address + 1) & TMS5220_ADDRESS_MASK;
if (m_sprom_address < m_sprom_length)
val |= m_speechrom[m_sprom_address];
m_rombits_count += 8 - count;
val = (val >> m_rombits_count) & (0xFF >> (8 - count));
}
}
else
val = 0;
return val;
}
/*
Write an address nibble to speech ROM. The address nibble is in the data,
the offset is ignored.
*/
WRITE8_MEMBER( ti_speech_synthesizer_device::spchrom_load_address )
{
// tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
// This code does not care about this.
m_sprom_address = ((m_sprom_address & ~(0xf << m_load_pointer))
| (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
m_load_pointer += 4;
m_rombits_count = 8;
}
/*
Perform a read and branch command. We do not use the offset or data parameter.
*/
WRITE8_MEMBER( ti_speech_synthesizer_device::spchrom_read_and_branch )
{
// tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
// there is a bus contention. This code does not care about this. */
if (m_sprom_address < m_sprom_length-1)
m_sprom_address = (m_sprom_address & 0x3c000UL)
| (((((unsigned long) m_speechrom[m_sprom_address]) << 8)
| m_speechrom[m_sprom_address+1]) & 0x3fffUL);
else if (m_sprom_address == m_sprom_length-1)
m_sprom_address = (m_sprom_address & 0x3c000UL)
| ((((unsigned long) m_speechrom[m_sprom_address]) << 8) & 0x3fffUL);
else
m_sprom_address = (m_sprom_address & 0x3c000UL);
m_rombits_count = 8;
}
/****************************************************************************/
/*
Callback interface instance
*/
static const tms52xx_config ti99_4x_tms5200interface =
{
DEVCB_NULL, // no IRQ callback
DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, speech_ready),
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_read), // speech ROM read handler
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_load_address), // speech ROM load address handler
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, spchrom_read_and_branch) // speech ROM read and branch handler
};
/****************************************************************************/
WRITE_LINE_MEMBER( ti_speech_synthesizer_device::speech_ready )
@ -260,17 +166,11 @@ void ti_speech_synthesizer_device::device_start()
void ti_speech_synthesizer_device::device_config_complete()
{
m_vsp = subdevice<tmc0285n_device>("speechsyn");
m_vsp = subdevice<tmc0285_device>("speechsyn");
}
void ti_speech_synthesizer_device::device_reset()
{
m_speechrom = memregion(SPEECHROM_TAG)->base();
m_sprom_length = memregion(SPEECHROM_TAG)->bytes();
m_sprom_address = 0;
m_load_pointer = 0;
m_rombits_count = 0;
if (m_genmod)
{
m_select_mask = 0x1ffc01;
@ -284,14 +184,17 @@ void ti_speech_synthesizer_device::device_reset()
}
MACHINE_CONFIG_FRAGMENT( ti99_speech )
MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("speechsyn", TMC0285N, 640000L)
MCFG_SOUND_CONFIG(ti99_4x_tms5200interface)
MCFG_SOUND_ADD("speechsyn", TMC0285, 640000L)
MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, ti_speech_synthesizer_device, speech_ready))
MCFG_TMS52XX_SPEECHROM("vsm")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_CONFIG_END
ROM_START( ti99_speech )
ROM_REGION(0x8000, SPEECHROM_TAG, 0)
ROM_REGION(0x8000, "vsm", 0)
ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
ROM_END

View File

@ -41,13 +41,7 @@ protected:
virtual void device_config_complete();
private:
tmc0285n_device *m_vsp;
UINT8 *m_speechrom; // pointer to speech ROM data
int m_load_pointer; // which 4-bit nibble will be affected by load address
int m_rombits_count; // current bit position in ROM
UINT32 m_sprom_address; // 18 bit pointer in ROM
UINT32 m_sprom_length; // length of data pointed by speechrom_data, from 0 to 2^18
tmc0285_device *m_vsp;
};
#endif

View File

@ -13,6 +13,7 @@
#include "speech8.h"
#include "sound/wave.h"
#include "machine/spchrom.h"
#define TMS5220_ADDRESS_MASK 0x3FFFFUL /* 18-bit mask for tms5220 address */
@ -20,7 +21,6 @@
#define LOG logerror
#define SPEECHSYN_TAG "speechsyn"
#define SPEECHROM_TAG "speechrom"
#define REAL_TIMING 0
@ -31,7 +31,6 @@
ti998_spsyn_device::ti998_spsyn_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: bus8z_device(mconfig, TI99_SPEECH8, "TI-99/8 Speech synthesizer (onboard)", tag, owner, clock, "ti99_speech8", __FILE__)
, m_load_pointer(0)
{
}
@ -73,7 +72,7 @@ READ8Z_MEMBER( ti998_spsyn_device::readz )
if ((offset & m_select_mask)==m_select_value)
{
machine().device("maincpu")->execute().adjust_icount(-(18+3)); /* this is just a minimum, it can be more */
*value = m_vsp->read(space, offset, 0xff) & 0xff;
*value = m_vsp->status_r(space, offset, 0xff) & 0xff;
if (VERBOSE>4) LOG("speech8: read value = %02x\n", *value);
}
}
@ -91,7 +90,7 @@ WRITE8_MEMBER( ti998_spsyn_device::write )
/* when there are 15 bytes in FIFO. It should be 16. Of course, if */
/* it were the case, we would need to store the value on the bus, */
/* which would be more complex. */
if (!m_vsp->readyq())
if (!m_vsp->readyq_r())
{
attotime time_to_ready = attotime::from_double(m_vsp->time_to_ready());
int cycles_to_ready = machine().device<cpu_device>("maincpu")->attotime_to_cycles(time_to_ready);
@ -101,102 +100,11 @@ WRITE8_MEMBER( ti998_spsyn_device::write )
machine().scheduler().timer_set(attotime::zero, FUNC_NULL);
}
if (VERBOSE>4) LOG("speech8: write value = %02x\n", data);
m_vsp->write(space, offset, data);
m_vsp->data_w(space, offset, data);
}
}
#endif
/****************************************************************************
Callbacks from TMS5220
*****************************************************************************/
/*
Read 'count' bits serially from speech ROM
*/
READ8_MEMBER( ti998_spsyn_device::spchrom_read )
{
int val;
int count = offset;
if (m_load_pointer != 0)
{ // first read after load address is ignored
m_load_pointer = 0;
count--;
}
if (m_sprom_address < m_sprom_length)
{
if (count < m_rombits_count)
{
m_rombits_count -= count;
val = (m_speechrom[m_sprom_address] >> m_rombits_count) & (0xFF >> (8 - count));
}
else
{
val = ((int)m_speechrom[m_sprom_address]) << 8;
m_sprom_address = (m_sprom_address + 1) & TMS5220_ADDRESS_MASK;
if (m_sprom_address < m_sprom_length)
val |= m_speechrom[m_sprom_address];
m_rombits_count += 8 - count;
val = (val >> m_rombits_count) & (0xFF >> (8 - count));
}
}
else
val = 0;
return val;
}
/*
Write an address nibble to speech ROM
*/
WRITE8_MEMBER( ti998_spsyn_device::spchrom_load_address )
{
// tms5220 data sheet says that if we load only one 4-bit nibble, it won't work.
// This code does not care about this.
m_sprom_address = ((m_sprom_address & ~(0xf << m_load_pointer))
| (((unsigned long) (data & 0xf)) << m_load_pointer) ) & TMS5220_ADDRESS_MASK;
m_load_pointer += 4;
m_rombits_count = 8;
}
/*
Perform a read and branch command
*/
WRITE8_MEMBER( ti998_spsyn_device::spchrom_read_and_branch )
{
// tms5220 data sheet says that if more than one speech ROM (tms6100) is present,
// there is a bus contention. This code does not care about this. */
if (m_sprom_address < m_sprom_length-1)
m_sprom_address = (m_sprom_address & 0x3c000UL)
| (((((unsigned long) m_speechrom[m_sprom_address]) << 8)
| m_speechrom[m_sprom_address+1]) & 0x3fffUL);
else if (m_sprom_address == m_sprom_length-1)
m_sprom_address = (m_sprom_address & 0x3c000UL)
| ((((unsigned long) m_speechrom[m_sprom_address]) << 8) & 0x3fffUL);
else
m_sprom_address = (m_sprom_address & 0x3c000UL);
m_rombits_count = 8;
}
/*****************************************************************************/
/*
Callback interface instance
*/
static const tms52xx_config ti99_8_tms5200interface =
{
DEVCB_NULL, // no IRQ callback
DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, speech8_ready),
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_read), // speech ROM read handler
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_load_address), // speech ROM load address handler
DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ti998_spsyn_device, spchrom_read_and_branch) // speech ROM read and branch handler
};
/**************************************************************************/
WRITE_LINE_MEMBER( ti998_spsyn_device::speech8_ready )
@ -219,17 +127,11 @@ void ti998_spsyn_device::device_start()
{
const speech8_config *conf = reinterpret_cast<const speech8_config *>(static_config());
m_ready.resolve(conf->ready, *this);
m_vsp = subdevice<tms5220n_device>(SPEECHSYN_TAG);
m_vsp = subdevice<tms5220_device>(SPEECHSYN_TAG);
}
void ti998_spsyn_device::device_reset()
{
m_speechrom = memregion(SPEECHROM_TAG)->base();
m_sprom_length = memregion(SPEECHROM_TAG)->bytes();
m_sprom_address = 0;
m_load_pointer = 0;
m_rombits_count = 0;
m_select_mask = 0xfc01;
m_select_value = 0x9000;
if (VERBOSE>4) LOG("speech8: reset\n");
@ -237,14 +139,17 @@ void ti998_spsyn_device::device_reset()
// Unlike the TI-99/4A, the 99/8 uses the TMS5220
MACHINE_CONFIG_FRAGMENT( ti998_speech )
MCFG_DEVICE_ADD("vsm", SPEECHROM, 0)
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD(SPEECHSYN_TAG, TMS5220N, 640000L)
MCFG_SOUND_CONFIG(ti99_8_tms5200interface)
MCFG_SOUND_ADD(SPEECHSYN_TAG, TMS5220, 640000L)
MCFG_TMS52XX_READYQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, ti998_spsyn_device, speech8_ready))
MCFG_TMS52XX_SPEECHROM("vsm")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_CONFIG_END
ROM_START( ti998_speech )
ROM_REGION(0x8000, SPEECHROM_TAG, 0)
ROM_REGION(0x8000, "vsm", 0)
ROM_LOAD_OPTIONAL("spchrom.bin", 0x0000, 0x8000, BAD_DUMP CRC(58b155f7) SHA1(382292295c00dff348d7e17c5ce4da12a1d87763)) /* system speech ROM */
ROM_END

View File

@ -53,12 +53,12 @@ protected:
virtual machine_config_constructor device_mconfig_additions() const;
private:
tms5220n_device *m_vsp;
UINT8 *m_speechrom; // pointer to speech ROM data
int m_load_pointer; // which 4-bit nibble will be affected by load address
int m_rombits_count; // current bit position in ROM
UINT32 m_sprom_address; // 18 bit pointer in ROM
UINT32 m_sprom_length; // length of data pointed by speechrom_data, from 0 to 2^18
tms5220_device *m_vsp;
// UINT8 *m_speechrom; // pointer to speech ROM data
// int m_load_pointer; // which 4-bit nibble will be affected by load address
// int m_rombits_count; // current bit position in ROM
// UINT32 m_sprom_address; // 18 bit pointer in ROM
// UINT32 m_sprom_length; // length of data pointed by speechrom_data, from 0 to 2^18
// Ready line to the CPU
devcb_resolved_write_line m_ready;

View File

@ -509,7 +509,6 @@ $(MESSOBJ)/mame.a: \
$(MESSOBJ)/shared.a: \
$(MESS_AUDIO)/mea8000.o \
$(MESS_AUDIO)/spchroms.o \
$(MESS_MACHINE)/3c503.o \
$(MESS_MACHINE)/68561mpcc.o \
$(MESS_MACHINE)/8530scc.o \