ay8910.c: Provide chip-specific details (number of outputs, number of usable IO ports) in constructor for each variant (nw)

This commit is contained in:
Alex W. Jackson 2014-05-06 23:42:49 +00:00
parent 1f70685652
commit dd63231a1a
5 changed files with 66 additions and 82 deletions

View File

@ -187,9 +187,7 @@ WRITE8_MEMBER( ym2203_device::write_port_w )
const device_type YM2203 = &device_creator<ym2203_device>; const device_type YM2203 = &device_creator<ym2203_device>;
ym2203_device::ym2203_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym2203_device::ym2203_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, YM2203, "YM2203", tag, owner, clock, "ym2203", __FILE__), : ay8910_device(mconfig, YM2203, "YM2203", tag, owner, clock, PSG_TYPE_YM, 3, 2, "ym2203", __FILE__),
m_irq_handler(*this) m_irq_handler(*this)
{ {
m_flags = AY8910_LEGACY_OUTPUT;
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }

View File

@ -133,9 +133,7 @@ void ym2608_device::device_start()
void *pcmbufa; void *pcmbufa;
int pcmsizea; int pcmsizea;
m_irq_handler.resolve(); m_irq_handler.resolve();
/* FIXME: Force to use single output */
/* Timer Handler set */ /* Timer Handler set */
m_timer[0] = timer_alloc(0); m_timer[0] = timer_alloc(0);
@ -186,11 +184,9 @@ WRITE8_MEMBER( ym2608_device::write )
const device_type YM2608 = &device_creator<ym2608_device>; const device_type YM2608 = &device_creator<ym2608_device>;
ym2608_device::ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym2608_device::ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, YM2608, "YM2608", tag, owner, clock, "ym2608", __FILE__), : ay8910_device(mconfig, YM2608, "YM2608", tag, owner, clock, PSG_TYPE_YM, 1, 2, "ym2608", __FILE__),
m_irq_handler(*this) m_irq_handler(*this)
{ {
m_flags = AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT;
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }
ROM_START( ym2608 ) ROM_START( ym2608 )

View File

@ -205,19 +205,15 @@ WRITE8_MEMBER( ym2610_device::write )
const device_type YM2610 = &device_creator<ym2610_device>; const device_type YM2610 = &device_creator<ym2610_device>;
ym2610_device::ym2610_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym2610_device::ym2610_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, YM2610, "YM2610", tag, owner, clock, "ym2610", __FILE__), : ay8910_device(mconfig, YM2610, "YM2610", tag, owner, clock, PSG_TYPE_YM, 1, 0, "ym2610", __FILE__),
m_irq_handler(*this) m_irq_handler(*this)
{ {
m_flags = AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT;
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }
ym2610_device::ym2610_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) ym2610_device::ym2610_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: ay8910_device(mconfig, type, name, tag, owner, clock, shortname, source), : ay8910_device(mconfig, type, name, tag, owner, clock, PSG_TYPE_YM, 1, 0, shortname, source),
m_irq_handler(*this) m_irq_handler(*this)
{ {
m_flags = AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT;
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }
const device_type YM2610B = &device_creator<ym2610b_device>; const device_type YM2610B = &device_creator<ym2610b_device>;
@ -225,6 +221,4 @@ const device_type YM2610B = &device_creator<ym2610b_device>;
ym2610b_device::ym2610b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym2610b_device::ym2610b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ym2610_device(mconfig, YM2610B, "YM2610B", tag, owner, clock, "ym2610b", __FILE__) : ym2610_device(mconfig, YM2610B, "YM2610B", tag, owner, clock, "ym2610b", __FILE__)
{ {
m_flags = AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT;
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }

View File

@ -24,8 +24,6 @@
TODO: TODO:
* The AY8930 has an extended mode which is currently * The AY8930 has an extended mode which is currently
not emulated. not emulated.
* The YMZ284 only has one 1 output channel (mixed chan A,B,C).
This should be forced.
* YM2610 & YM2608 will need a separate flag in their config structures * YM2610 & YM2608 will need a separate flag in their config structures
to distinguish between legacy and discrete mode. to distinguish between legacy and discrete mode.
@ -453,14 +451,16 @@ void ay8910_device::ay8910_write_reg(int r, int v)
((m_last_enable & 0x40) != (m_regs[AY_ENABLE] & 0x40))) ((m_last_enable & 0x40) != (m_regs[AY_ENABLE] & 0x40)))
{ {
/* write out 0xff if port set to input */ /* write out 0xff if port set to input */
m_port_a_write_cb((offs_t)0, (m_regs[AY_ENABLE] & 0x40) ? m_regs[AY_PORTA] : 0xff); if (!m_port_a_write_cb.isnull())
m_port_a_write_cb((offs_t)0, (m_regs[AY_ENABLE] & 0x40) ? m_regs[AY_PORTA] : 0xff);
} }
if ((m_last_enable == -1) || if ((m_last_enable == -1) ||
((m_last_enable & 0x80) != (m_regs[AY_ENABLE] & 0x80))) ((m_last_enable & 0x80) != (m_regs[AY_ENABLE] & 0x80)))
{ {
/* write out 0xff if port set to input */ /* write out 0xff if port set to input */
m_port_b_write_cb((offs_t)0, (m_regs[AY_ENABLE] & 0x80) ? m_regs[AY_PORTB] : 0xff); if (!m_port_b_write_cb.isnull())
m_port_b_write_cb((offs_t)0, (m_regs[AY_ENABLE] & 0x80) ? m_regs[AY_PORTB] : 0xff);
} }
m_last_enable = m_regs[AY_ENABLE]; m_last_enable = m_regs[AY_ENABLE];
break; break;
@ -714,42 +714,29 @@ void ay8910_device::ay8910_statesave()
void ay8910_device::device_start() void ay8910_device::device_start()
{ {
device_type chip_type = type();
int master_clock = clock(); int master_clock = clock();
m_port_a_read_cb.resolve_safe(0); if (m_ioports < 1 && !(m_port_a_read_cb.isnull() && m_port_a_write_cb.isnull()))
m_port_b_read_cb.resolve_safe(0); fatalerror("Device '%s' is a %s and has no port A!", tag(), name());
m_port_a_write_cb.resolve_safe();
m_port_b_write_cb.resolve_safe(); if (m_ioports < 2 && !(m_port_b_read_cb.isnull() && m_port_b_write_cb.isnull()))
fatalerror("Device '%s' is a %s and has no port B!", tag(), name());
m_port_a_read_cb.resolve();
m_port_b_read_cb.resolve();
m_port_a_write_cb.resolve();
m_port_b_write_cb.resolve();
if ((m_flags & AY8910_SINGLE_OUTPUT) != 0) if ((m_flags & AY8910_SINGLE_OUTPUT) != 0)
{ {
logerror("AY-3-8910/YM2149 using single output!\n"); logerror("%s device '%s' using single output!\n", name(), tag());
m_streams = 1; m_streams = 1;
} }
else
m_streams = 3;
// FIXME: this doesn't belong here, it should be an input pin exposed via devcb2
if (chip_type == AY8910 || chip_type == AY8912 || chip_type == AY8913 || chip_type == AY8914 || chip_type == AY8930) if (type() == YM2149 && (m_flags & YM2149_PIN26_LOW))
{ {
m_step = 2; master_clock /= 2;
m_par = &ay8910_param;
m_par_env = &ay8910_param;
m_zero_is_off = 0; /* FIXME: Remove after verification that off=vol(0) */
m_env_step_mask = 0x0F;
}
else
{
m_step = 1;
m_par = &ym2149_param;
m_par_env = &ym2149_param_env;
m_zero_is_off = 0;
m_env_step_mask = 0x1F;
/* YM2149 master clock divider? */
if (m_flags & YM2149_PIN26_LOW)
master_clock /= 2;
} }
build_mixer_table(); build_mixer_table();
@ -970,7 +957,8 @@ const device_type AY8910 = &device_creator<ay8910_device>;
ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, AY8910, "AY-3-8910A", tag, owner, clock, "ay8910", __FILE__), : device_t(mconfig, AY8910, "AY-3-8910A", tag, owner, clock, "ay8910", __FILE__),
device_sound_interface(mconfig, *this), device_sound_interface(mconfig, *this),
m_streams(0), m_streams(3),
m_ioports(2),
m_ready(0), m_ready(0),
m_channel(NULL), m_channel(NULL),
m_register_latch(0), m_register_latch(0),
@ -985,11 +973,11 @@ ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, dev
m_attack(0), m_attack(0),
m_holding(0), m_holding(0),
m_rng(0), m_rng(0),
m_env_step_mask(0), m_env_step_mask(0x0f),
m_step(0), m_step(2),
m_zero_is_off(0), m_zero_is_off(0), // FIXME: Remove after verification that off=vol(0)
m_par(NULL), m_par(&ay8910_param),
m_par_env(NULL), m_par_env(&ay8910_param),
m_flags(AY8910_LEGACY_OUTPUT), m_flags(AY8910_LEGACY_OUTPUT),
m_port_a_read_cb(*this), m_port_a_read_cb(*this),
m_port_b_read_cb(*this), m_port_b_read_cb(*this),
@ -1006,10 +994,12 @@ ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, dev
m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads
} }
ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,
psg_type_t psg_type, int streams, int ioports, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source), : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
device_sound_interface(mconfig, *this), device_sound_interface(mconfig, *this),
m_streams(0), m_streams(streams),
m_ioports(ioports),
m_ready(0), m_ready(0),
m_channel(NULL), m_channel(NULL),
m_register_latch(0), m_register_latch(0),
@ -1024,11 +1014,11 @@ ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, co
m_attack(0), m_attack(0),
m_holding(0), m_holding(0),
m_rng(0), m_rng(0),
m_env_step_mask(0), m_env_step_mask(psg_type == PSG_TYPE_AY ? 0x0f : 0x1f),
m_step(0), m_step( psg_type == PSG_TYPE_AY ? 2 : 1),
m_zero_is_off(0), m_zero_is_off( psg_type == PSG_TYPE_AY ? 0 : 0), // FIXME: Remove after verification that off=vol(0)
m_par(NULL), m_par( psg_type == PSG_TYPE_AY ? &ay8910_param : &ym2149_param),
m_par_env(NULL), m_par_env( psg_type == PSG_TYPE_AY ? &ay8910_param : &ym2149_param_env),
m_flags(AY8910_LEGACY_OUTPUT), m_flags(AY8910_LEGACY_OUTPUT),
m_port_a_read_cb(*this), m_port_a_read_cb(*this),
m_port_b_read_cb(*this), m_port_b_read_cb(*this),
@ -1048,7 +1038,7 @@ ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, co
const device_type AY8912 = &device_creator<ay8912_device>; const device_type AY8912 = &device_creator<ay8912_device>;
ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, AY8912, "AY-3-8912A", tag, owner, clock, "ay8912", __FILE__) : ay8910_device(mconfig, AY8912, "AY-3-8912A", tag, owner, clock, PSG_TYPE_AY, 3, 1, "ay8912", __FILE__)
{ {
} }
@ -1056,7 +1046,7 @@ ay8912_device::ay8912_device(const machine_config &mconfig, const char *tag, dev
const device_type AY8913 = &device_creator<ay8913_device>; const device_type AY8913 = &device_creator<ay8913_device>;
ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, AY8913, "AY-3-8913A", tag, owner, clock, "ay8913", __FILE__) : ay8910_device(mconfig, AY8913, "AY-3-8913A", tag, owner, clock, PSG_TYPE_AY, 3, 0, "ay8913", __FILE__)
{ {
} }
@ -1064,7 +1054,7 @@ ay8913_device::ay8913_device(const machine_config &mconfig, const char *tag, dev
const device_type AY8914 = &device_creator<ay8914_device>; const device_type AY8914 = &device_creator<ay8914_device>;
ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, AY8914, "AY-3-8914", tag, owner, clock, "ay8914", __FILE__) : ay8910_device(mconfig, AY8914, "AY-3-8914", tag, owner, clock, PSG_TYPE_AY, 3, 2, "ay8914", __FILE__)
{ {
} }
@ -1072,7 +1062,7 @@ ay8914_device::ay8914_device(const machine_config &mconfig, const char *tag, dev
const device_type AY8930 = &device_creator<ay8930_device>; const device_type AY8930 = &device_creator<ay8930_device>;
ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, AY8930, "AY8930", tag, owner, clock, "ay8930", __FILE__) : ay8910_device(mconfig, AY8930, "AY8930", tag, owner, clock, PSG_TYPE_AY, 3, 2, "ay8930", __FILE__)
{ {
} }
@ -1080,11 +1070,7 @@ ay8930_device::ay8930_device(const machine_config &mconfig, const char *tag, dev
const device_type YM2149 = &device_creator<ym2149_device>; const device_type YM2149 = &device_creator<ym2149_device>;
ym2149_device::ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym2149_device::ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ay8910_device(mconfig, YM2149, "YM2149", tag, owner, clock, "ym2149", __FILE__) : ay8910_device(mconfig, YM2149, "YM2149", tag, owner, clock, PSG_TYPE_YM, 3, 2, "ym2149", __FILE__)
{
}
ym2149_device::ym2149_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: ay8910_device(mconfig, type, name, tag, owner, clock, shortname, source)
{ {
} }
@ -1092,7 +1078,7 @@ ym2149_device::ym2149_device(const machine_config &mconfig, device_type type, co
const device_type YM3439 = &device_creator<ym3439_device>; const device_type YM3439 = &device_creator<ym3439_device>;
ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ym2149_device(mconfig, YM3439, "YM3439", tag, owner, clock, "ym3429", __FILE__) : ay8910_device(mconfig, YM3439, "YM3439", tag, owner, clock, PSG_TYPE_YM, 3, 2, "ym3429", __FILE__)
{ {
} }
@ -1100,7 +1086,7 @@ ym3439_device::ym3439_device(const machine_config &mconfig, const char *tag, dev
const device_type YMZ284 = &device_creator<ymz284_device>; const device_type YMZ284 = &device_creator<ymz284_device>;
ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ym2149_device(mconfig, YMZ284, "YMZ284", tag, owner, clock, "ymz284", __FILE__) : ay8910_device(mconfig, YMZ284, "YMZ284", tag, owner, clock, PSG_TYPE_YM, 1, 0, "ymz284", __FILE__)
{ {
} }
@ -1108,6 +1094,6 @@ ymz284_device::ymz284_device(const machine_config &mconfig, const char *tag, dev
const device_type YMZ294 = &device_creator<ymz294_device>; const device_type YMZ294 = &device_creator<ymz294_device>;
ymz294_device::ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) ymz294_device::ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: ym2149_device(mconfig, YMZ294, "YMZ294", tag, owner, clock, "ymz294", __FILE__) : ay8910_device(mconfig, YMZ294, "YMZ294", tag, owner, clock, PSG_TYPE_YM, 1, 0, "ymz294", __FILE__)
{ {
} }

View File

@ -91,9 +91,18 @@ class ay8910_device : public device_t,
public device_sound_interface public device_sound_interface
{ {
public: public:
ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); enum psg_type_t
ay8910_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); {
PSG_TYPE_AY,
PSG_TYPE_YM
};
// construction/destruction
ay8910_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
ay8910_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner,
UINT32 clock, psg_type_t psg_type, int streams, int ioports, const char *shortname, const char *source);
// static configuration helpers
static void set_flags(device_t &device, int flags) { downcast<ay8910_device &>(device).m_flags = flags; } static void set_flags(device_t &device, int flags) { downcast<ay8910_device &>(device).m_flags = flags; }
static void set_resistors_load(device_t &device, int res_load0, int res_load1, int res_load2) { downcast<ay8910_device &>(device).m_res_load[0] = res_load0; downcast<ay8910_device &>(device).m_res_load[1] = res_load1; downcast<ay8910_device &>(device).m_res_load[2] = res_load2; } static void set_resistors_load(device_t &device, int res_load0, int res_load1, int res_load2) { downcast<ay8910_device &>(device).m_res_load[0] = res_load0; downcast<ay8910_device &>(device).m_res_load[1] = res_load1; downcast<ay8910_device &>(device).m_res_load[2] = res_load2; }
template<class _Object> static devcb2_base &set_port_a_read_callback(device_t &device, _Object object) { return downcast<ay8910_device &>(device).m_port_a_read_cb.set_callback(object); } template<class _Object> static devcb2_base &set_port_a_read_callback(device_t &device, _Object object) { return downcast<ay8910_device &>(device).m_port_a_read_cb.set_callback(object); }
@ -134,17 +143,19 @@ protected:
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private:
// internal helpers
inline UINT16 mix_3D(); inline UINT16 mix_3D();
void ay8910_write_reg(int r, int v); void ay8910_write_reg(int r, int v);
void build_mixer_table(); void build_mixer_table();
void ay8910_statesave(); void ay8910_statesave();
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
// internal state // internal state
int m_streams; int m_streams;
int m_ioports;
int m_ready; int m_ready;
sound_stream *m_channel; sound_stream *m_channel;
INT32 m_register_latch; INT32 m_register_latch;
@ -219,12 +230,11 @@ class ym2149_device : public ay8910_device
{ {
public: public:
ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
ym2149_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
}; };
extern const device_type YM2149; extern const device_type YM2149;
class ym3439_device : public ym2149_device class ym3439_device : public ay8910_device
{ {
public: public:
ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
@ -232,7 +242,7 @@ public:
extern const device_type YM3439; extern const device_type YM3439;
class ymz284_device : public ym2149_device class ymz284_device : public ay8910_device
{ {
public: public:
ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
@ -240,7 +250,7 @@ public:
extern const device_type YMZ284; extern const device_type YMZ284;
class ymz294_device : public ym2149_device class ymz294_device : public ay8910_device
{ {
public: public:
ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);