mirror of
https://github.com/holub/mame
synced 2025-05-06 22:35:43 +03:00
(MESS) sp0256: modernized the SP0256 Narrator Speech Processor sound device. [Fabio Priuli]
This commit is contained in:
parent
20c279899c
commit
6950e11340
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user