(MESS) sp0256: modernized the SP0256 Narrator Speech Processor sound device. [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2013-05-26 07:30:32 +00:00
parent 20c279899c
commit 6950e11340
10 changed files with 435 additions and 441 deletions

File diff suppressed because it is too large Load Diff

View File

@ -49,39 +49,43 @@
#ifndef __SP0256_H__ #ifndef __SP0256_H__
#define __SP0256_H__ #define __SP0256_H__
#include "devlegcy.h"
struct lpc12_t
{
int rpt, cnt; /* Repeat counter, Period down-counter. */
UINT32 per, rng; /* Period, Amplitude, Random Number Generator */
int amp;
INT16 f_coef[6]; /* F0 through F5. */
INT16 b_coef[6]; /* B0 through B5. */
INT16 z_data[6][2]; /* Time-delay data for the filter stages. */
UINT8 r[16]; /* The encoded register set. */
int interp;
};
struct sp0256_interface struct sp0256_interface
{ {
devcb_write_line lrq_callback; devcb_write_line m_lrq_cb;
devcb_write_line sby_callback; devcb_write_line m_sby_cb;
}; };
void sp0256_bitrevbuff(UINT8 *buffer, unsigned int start, unsigned int length);
void sp0256_set_clock(device_t *device, int clock);
DECLARE_WRITE8_DEVICE_HANDLER( sp0256_ALD_w );
READ_LINE_DEVICE_HANDLER( sp0256_lrq_r );
READ_LINE_DEVICE_HANDLER( sp0256_sby_r );
DECLARE_READ16_DEVICE_HANDLER( spb640_r );
DECLARE_WRITE16_DEVICE_HANDLER( spb640_w );
class sp0256_device : public device_t, class sp0256_device : public device_t,
public device_sound_interface public device_sound_interface,
public sp0256_interface
{ {
public: public:
sp0256_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); sp0256_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~sp0256_device() { global_free(m_token); } ~sp0256_device() { }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
DECLARE_WRITE8_MEMBER(ald_w);
DECLARE_READ_LINE_MEMBER(lrq_r);
DECLARE_READ_LINE_MEMBER(sby_r);
DECLARE_READ16_MEMBER(spb640_r);
DECLARE_WRITE16_MEMBER(spb640_w);
TIMER_CALLBACK_MEMBER(set_lrq_timer_proc); TIMER_CALLBACK_MEMBER(set_lrq_timer_proc);
void set_clock(int clock);
void bitrevbuff(UINT8 *buffer, unsigned int start, unsigned int length);
protected: protected:
// device-level overrides // device-level overrides
virtual void device_config_complete(); virtual void device_config_complete();
@ -91,8 +95,39 @@ protected:
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private: private:
// internal state UINT32 getb(int len);
void *m_token; void micro();
sound_stream *m_stream; /* MAME core sound stream */
devcb_resolved_write_line m_drq; /* Data request callback */
devcb_resolved_write_line m_sby; /* Standby callback */
int m_sby_line; /* Standby line state */
int m_cur_len; /* Fullness of current sound buffer. */
int m_silent; /* Flag: SP0256 is silent. */
INT16 *m_scratch; /* Scratch buffer for audio. */
UINT32 m_sc_head; /* Head pointer into scratch circular buf */
UINT32 m_sc_tail; /* Tail pointer into scratch circular buf */
struct lpc12_t m_filt; /* 12-pole filter */
int m_lrq; /* Load ReQuest. == 0 if we can accept a load */
int m_ald; /* Address LoaD. < 0 if no command pending. */
int m_pc; /* Microcontroller's PC value. */
int m_stack; /* Microcontroller's PC stack. */
int m_fifo_sel; /* True when executing from FIFO. */
int m_halted; /* True when CPU is halted. */
UINT32 m_mode; /* Mode register. */
UINT32 m_page; /* Page set by SETPAGE */
UINT32 m_fifo_head; /* FIFO head pointer (where new data goes). */
UINT32 m_fifo_tail; /* FIFO tail pointer (where data comes from). */
UINT32 m_fifo_bitp; /* FIFO bit-pointer (for partial decles). */
UINT16 m_fifo[64]; /* The 64-decle FIFO. */
UINT8 *m_rom; /* 64K ROM. */
emu_timer *m_lrq_timer; emu_timer *m_lrq_timer;
}; };

View File

@ -160,8 +160,7 @@ WRITE8_MEMBER(sauro_state::flip_screen_w)
WRITE8_MEMBER(sauro_state::adpcm_w) WRITE8_MEMBER(sauro_state::adpcm_w)
{ {
device_t *device = machine().device("speech"); m_sp0256->ald_w(space, 0, data);
sp0256_ALD_w(device, space, 0, data);
} }
static ADDRESS_MAP_START( sauro_map, AS_PROGRAM, 8, sauro_state ) static ADDRESS_MAP_START( sauro_map, AS_PROGRAM, 8, sauro_state )

View File

@ -1,8 +1,13 @@
#include "sound/sp0256.h"
class sauro_state : public driver_device class sauro_state : public driver_device
{ {
public: public:
sauro_state(const machine_config &mconfig, device_type type, const char *tag) sauro_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_sp0256(*this, "speech"),
m_spriteram(*this, "spriteram"), m_spriteram(*this, "spriteram"),
m_videoram(*this, "videoram"), m_videoram(*this, "videoram"),
m_colorram(*this, "colorram"), m_colorram(*this, "colorram"),
@ -10,6 +15,7 @@ public:
m_colorram2(*this, "colorram2"), m_colorram2(*this, "colorram2"),
m_maincpu(*this, "maincpu") { } m_maincpu(*this, "maincpu") { }
optional_device<sp0256_device> m_sp0256;
required_shared_ptr<UINT8> m_spriteram; required_shared_ptr<UINT8> m_spriteram;
required_shared_ptr<UINT8> m_videoram; required_shared_ptr<UINT8> m_videoram;
required_shared_ptr<UINT8> m_colorram; required_shared_ptr<UINT8> m_colorram;

View File

@ -578,7 +578,6 @@ static const sp0256_interface sp0256_intf =
READ8_MEMBER(ace_state::sby_r) READ8_MEMBER(ace_state::sby_r)
{ {
device_t *device = machine().device(SP0256AL2_TAG);
/* /*
bit description bit description
@ -594,12 +593,11 @@ READ8_MEMBER(ace_state::sby_r)
*/ */
return sp0256_sby_r(device); return m_sp0256->sby_r();
} }
WRITE8_MEMBER(ace_state::ald_w) WRITE8_MEMBER(ace_state::ald_w)
{ {
device_t *device = machine().device(SP0256AL2_TAG);
/* /*
bit description bit description
@ -617,7 +615,7 @@ WRITE8_MEMBER(ace_state::ald_w)
if (!BIT(data, 6)) if (!BIT(data, 6))
{ {
sp0256_ALD_w(device, space, 0, data & 0x3f); m_sp0256->ald_w(space, 0, data & 0x3f);
} }
} }

View File

@ -695,7 +695,7 @@ INPUT_PORTS_END
static ADDRESS_MAP_START(intv_mem, AS_PROGRAM, 16, intv_state) static ADDRESS_MAP_START(intv_mem, AS_PROGRAM, 16, intv_state)
AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w ) AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE_LEGACY("sp0256_speech", spb640_r, spb640_w ) /* Intellivoice */ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w ) AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff ) AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w ) AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
@ -712,7 +712,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( intv2_mem , AS_PROGRAM, 16, intv_state) static ADDRESS_MAP_START( intv2_mem , AS_PROGRAM, 16, intv_state)
AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w ) AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE_LEGACY("sp0256_speech", spb640_r, spb640_w ) /* Intellivoice */ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w ) AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff ) AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w ) AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )
@ -730,7 +730,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( intvecs_mem , AS_PROGRAM, 16, intv_state) static ADDRESS_MAP_START( intvecs_mem , AS_PROGRAM, 16, intv_state)
AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w ) AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE_LEGACY("sp0256_speech", spb640_r, spb640_w ) /* Intellivoice */ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
// AM_RANGE(0x00E0, 0x00E3) AM_READWRITE( intv_ecs_uart_r, intv_ecs_uart_w ) // AM_RANGE(0x00E0, 0x00E3) AM_READWRITE( intv_ecs_uart_r, intv_ecs_uart_w )
AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE8("ay8914.2", ay8914_device, read, write, 0x00ff ) /* ecs psg */ AM_RANGE(0x00f0, 0x00ff) AM_DEVREADWRITE8("ay8914.2", ay8914_device, read, write, 0x00ff ) /* ecs psg */
AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w ) AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
@ -754,7 +754,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( intvkbd_mem , AS_PROGRAM, 16, intv_state) static ADDRESS_MAP_START( intvkbd_mem , AS_PROGRAM, 16, intv_state)
AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w ) AM_RANGE(0x0000, 0x003f) AM_READWRITE( intv_stic_r, intv_stic_w )
AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE_LEGACY("sp0256_speech", spb640_r, spb640_w ) /* Intellivoice */ AM_RANGE(0x0080, 0x0081) AM_DEVREADWRITE("sp0256_speech", sp0256_device, spb640_r, spb640_w) /* Intellivoice */
AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w ) AM_RANGE(0x0100, 0x01ef) AM_READWRITE( intv_ram8_r, intv_ram8_w )
AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff ) AM_RANGE(0x01f0, 0x01ff) AM_DEVREADWRITE8("ay8914.1", ay8914_device, read, write, 0x00ff )
AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w ) AM_RANGE(0x0200, 0x035f) AM_READWRITE( intv_ram16_r, intv_ram16_w )

View File

@ -344,7 +344,7 @@ WRITE_LINE_MEMBER(odyssey2_state::the_voice_lrq_callback)
READ8_MEMBER(odyssey2_state::t0_read) READ8_MEMBER(odyssey2_state::t0_read)
{ {
return sp0256_lrq_r( m_sp0256 ) ? 0 : 1; return m_sp0256->lrq_r() ? 0 : 1;
} }
@ -445,7 +445,7 @@ WRITE8_MEMBER(odyssey2_state::io_write)
if ( data & 0x20 ) if ( data & 0x20 )
{ {
logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1 ); logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1 );
sp0256_ALD_w( m_sp0256, space, 0, offset & 0x7F ); m_sp0256->ald_w(space, 0, offset & 0x7f);
} }
else else
{ {

View File

@ -28,8 +28,9 @@ public:
m_cassette(*this, "cassette"), m_cassette(*this, "cassette"),
m_centronics(*this, CENTRONICS_TAG), m_centronics(*this, CENTRONICS_TAG),
m_ram(*this, RAM_TAG), m_ram(*this, RAM_TAG),
m_video_ram(*this, "video_ram"), m_sp0256(*this, SP0256AL2_TAG),
m_char_ram(*this, "char_ram"){ } m_video_ram(*this, "video_ram"),
m_char_ram(*this, "char_ram"){ }
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<i8255_device> m_ppi; required_device<i8255_device> m_ppi;
@ -37,6 +38,7 @@ public:
required_device<cassette_image_device> m_cassette; required_device<cassette_image_device> m_cassette;
required_device<centronics_device> m_centronics; required_device<centronics_device> m_centronics;
required_device<ram_device> m_ram; required_device<ram_device> m_ram;
required_device<sp0256_device> m_sp0256;
virtual void machine_start(); virtual void machine_start();

View File

@ -155,7 +155,7 @@ void c64_currah_speech_cartridge_device::set_osc1(int voice, int intonation)
int dotclock = m_slot->dotclock(); int dotclock = m_slot->dotclock();
// TODO intonation and correct dividers // TODO intonation and correct dividers
sp0256_set_clock(m_nsp, dotclock / (2 << voice)); m_nsp->set_clock(dotclock / (2 << voice));
} }
@ -223,7 +223,7 @@ UINT8 c64_currah_speech_cartridge_device::c64_cd_r(address_space &space, offs_t
*/ */
data = sp0256_sby_r(m_nsp) << 7; data = m_nsp->sby_r() << 7;
} }
if (!space.debugger_access() && (offset == 0xa7f0)) if (!space.debugger_access() && (offset == 0xa7f0))
@ -264,6 +264,6 @@ void c64_currah_speech_cartridge_device::c64_cd_w(address_space &space, offs_t o
set_osc1(voice, intonation); set_osc1(voice, intonation);
sp0256_ALD_w(m_nsp, space, 0, data & 0x3f); m_nsp->ald_w(space, 0, data & 0x3f);
} }
} }

View File

@ -45,7 +45,7 @@ READ8_MEMBER(cpc_ssa1_device::ssa1_r)
WRITE8_MEMBER(cpc_ssa1_device::ssa1_w) WRITE8_MEMBER(cpc_ssa1_device::ssa1_w)
{ {
sp0256_ALD_w(m_sp0256_device,space, 0,data); m_sp0256_device->ald_w(space, 0, data);
} }
READ8_MEMBER(cpc_dkspeech_device::dkspeech_r) READ8_MEMBER(cpc_dkspeech_device::dkspeech_r)
@ -62,7 +62,7 @@ READ8_MEMBER(cpc_dkspeech_device::dkspeech_r)
WRITE8_MEMBER(cpc_dkspeech_device::dkspeech_w) WRITE8_MEMBER(cpc_dkspeech_device::dkspeech_w)
{ {
sp0256_ALD_w(m_sp0256_device,space, 0,data & 0x3f); m_sp0256_device->ald_w(space, 0, data & 0x3f);
} }
WRITE_LINE_MEMBER(cpc_ssa1_device::lrq_cb) WRITE_LINE_MEMBER(cpc_ssa1_device::lrq_cb)