From dd63231a1a8a1890e74eac5b8258fd6f16ac4851 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Tue, 6 May 2014 23:42:49 +0000 Subject: [PATCH] ay8910.c: Provide chip-specific details (number of outputs, number of usable IO ports) in constructor for each variant (nw) --- src/emu/sound/2203intf.c | 4 +- src/emu/sound/2608intf.c | 6 +-- src/emu/sound/2610intf.c | 10 +--- src/emu/sound/ay8910.c | 98 +++++++++++++++++----------------------- src/emu/sound/ay8910.h | 30 ++++++++---- 5 files changed, 66 insertions(+), 82 deletions(-) diff --git a/src/emu/sound/2203intf.c b/src/emu/sound/2203intf.c index a2eea6b73e8..df90c8402c2 100644 --- a/src/emu/sound/2203intf.c +++ b/src/emu/sound/2203intf.c @@ -187,9 +187,7 @@ WRITE8_MEMBER( ym2203_device::write_port_w ) const device_type YM2203 = &device_creator; 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_flags = AY8910_LEGACY_OUTPUT; - m_res_load[0] = m_res_load[1] = m_res_load[2] = 1000; //Default values for resistor loads } diff --git a/src/emu/sound/2608intf.c b/src/emu/sound/2608intf.c index ad60b7022b0..28625c9fa31 100644 --- a/src/emu/sound/2608intf.c +++ b/src/emu/sound/2608intf.c @@ -133,9 +133,7 @@ void ym2608_device::device_start() void *pcmbufa; int pcmsizea; - m_irq_handler.resolve(); - /* FIXME: Force to use single output */ /* Timer Handler set */ m_timer[0] = timer_alloc(0); @@ -186,11 +184,9 @@ WRITE8_MEMBER( ym2608_device::write ) const device_type YM2608 = &device_creator; 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_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 ) diff --git a/src/emu/sound/2610intf.c b/src/emu/sound/2610intf.c index 7423d346475..94c7ecf6594 100644 --- a/src/emu/sound/2610intf.c +++ b/src/emu/sound/2610intf.c @@ -205,19 +205,15 @@ WRITE8_MEMBER( ym2610_device::write ) const device_type YM2610 = &device_creator; 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_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) - : 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_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; @@ -225,6 +221,4 @@ const device_type YM2610B = &device_creator; 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__) { - 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 } diff --git a/src/emu/sound/ay8910.c b/src/emu/sound/ay8910.c index ee80981e61a..3652508df0a 100644 --- a/src/emu/sound/ay8910.c +++ b/src/emu/sound/ay8910.c @@ -24,8 +24,6 @@ TODO: * The AY8930 has an extended mode which is currently 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 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))) { /* 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) || ((m_last_enable & 0x80) != (m_regs[AY_ENABLE] & 0x80))) { /* 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]; break; @@ -714,42 +714,29 @@ void ay8910_device::ay8910_statesave() void ay8910_device::device_start() { - device_type chip_type = type(); int master_clock = clock(); - m_port_a_read_cb.resolve_safe(0); - m_port_b_read_cb.resolve_safe(0); - m_port_a_write_cb.resolve_safe(); - m_port_b_write_cb.resolve_safe(); + if (m_ioports < 1 && !(m_port_a_read_cb.isnull() && m_port_a_write_cb.isnull())) + fatalerror("Device '%s' is a %s and has no port A!", tag(), name()); + + 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) { - logerror("AY-3-8910/YM2149 using single output!\n"); + logerror("%s device '%s' using single output!\n", name(), tag()); m_streams = 1; } - else - m_streams = 3; - - if (chip_type == AY8910 || chip_type == AY8912 || chip_type == AY8913 || chip_type == AY8914 || chip_type == AY8930) + // FIXME: this doesn't belong here, it should be an input pin exposed via devcb2 + if (type() == YM2149 && (m_flags & YM2149_PIN26_LOW)) { - m_step = 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; + master_clock /= 2; } build_mixer_table(); @@ -970,7 +957,8 @@ const device_type AY8910 = &device_creator; 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_sound_interface(mconfig, *this), - m_streams(0), + m_streams(3), + m_ioports(2), m_ready(0), m_channel(NULL), m_register_latch(0), @@ -985,11 +973,11 @@ ay8910_device::ay8910_device(const machine_config &mconfig, const char *tag, dev m_attack(0), m_holding(0), m_rng(0), - m_env_step_mask(0), - m_step(0), - m_zero_is_off(0), - m_par(NULL), - m_par_env(NULL), + m_env_step_mask(0x0f), + m_step(2), + m_zero_is_off(0), // FIXME: Remove after verification that off=vol(0) + m_par(&ay8910_param), + m_par_env(&ay8910_param), m_flags(AY8910_LEGACY_OUTPUT), m_port_a_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 } -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_sound_interface(mconfig, *this), - m_streams(0), + m_streams(streams), + m_ioports(ioports), m_ready(0), m_channel(NULL), m_register_latch(0), @@ -1024,11 +1014,11 @@ ay8910_device::ay8910_device(const machine_config &mconfig, device_type type, co m_attack(0), m_holding(0), m_rng(0), - m_env_step_mask(0), - m_step(0), - m_zero_is_off(0), - m_par(NULL), - m_par_env(NULL), + m_env_step_mask(psg_type == PSG_TYPE_AY ? 0x0f : 0x1f), + m_step( psg_type == PSG_TYPE_AY ? 2 : 1), + m_zero_is_off( psg_type == PSG_TYPE_AY ? 0 : 0), // FIXME: Remove after verification that off=vol(0) + m_par( psg_type == PSG_TYPE_AY ? &ay8910_param : &ym2149_param), + m_par_env( psg_type == PSG_TYPE_AY ? &ay8910_param : &ym2149_param_env), m_flags(AY8910_LEGACY_OUTPUT), m_port_a_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::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::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::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::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::ym2149_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : ay8910_device(mconfig, YM2149, "YM2149", tag, owner, clock, "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) + : ay8910_device(mconfig, YM2149, "YM2149", tag, owner, clock, PSG_TYPE_YM, 3, 2, "ym2149", __FILE__) { } @@ -1092,7 +1078,7 @@ ym2149_device::ym2149_device(const machine_config &mconfig, device_type type, co const device_type YM3439 = &device_creator; 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::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::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__) { } diff --git a/src/emu/sound/ay8910.h b/src/emu/sound/ay8910.h index b42b205e4b4..4f6240611d8 100644 --- a/src/emu/sound/ay8910.h +++ b/src/emu/sound/ay8910.h @@ -91,9 +91,18 @@ class ay8910_device : public device_t, public device_sound_interface { public: - 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, const char *shortname, const char *source); + enum psg_type_t + { + 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(device).m_flags = flags; } static void set_resistors_load(device_t &device, int res_load0, int res_load1, int res_load2) { downcast(device).m_res_load[0] = res_load0; downcast(device).m_res_load[1] = res_load1; downcast(device).m_res_load[2] = res_load2; } template static devcb2_base &set_port_a_read_callback(device_t &device, _Object object) { return downcast(device).m_port_a_read_cb.set_callback(object); } @@ -134,17 +143,19 @@ protected: virtual void device_start(); 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(); void ay8910_write_reg(int r, int v); void build_mixer_table(); 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 int m_streams; + int m_ioports; int m_ready; sound_stream *m_channel; INT32 m_register_latch; @@ -219,12 +230,11 @@ class ym2149_device : public ay8910_device { public: 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; -class ym3439_device : public ym2149_device +class ym3439_device : public ay8910_device { public: ym3439_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); @@ -232,7 +242,7 @@ public: extern const device_type YM3439; -class ymz284_device : public ym2149_device +class ymz284_device : public ay8910_device { public: ymz284_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); @@ -240,7 +250,7 @@ public: extern const device_type YMZ284; -class ymz294_device : public ym2149_device +class ymz294_device : public ay8910_device { public: ymz294_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);