From 81cccebb1fa12ecd338d014d5f5c6308b5ad2b7f Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 4 Mar 2020 10:07:56 -0500 Subject: ym2151: Add YM2164 variant and emulate some known differences --- src/devices/bus/msx_cart/yamaha.cpp | 13 ++++++++--- src/devices/bus/msx_cart/yamaha.h | 2 +- src/devices/sound/ym2151.cpp | 45 +++++++++++++++++++++++++++++++++++-- src/devices/sound/ym2151.h | 24 ++++++++++++++++++-- src/mame/drivers/fb01.cpp | 2 +- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/devices/bus/msx_cart/yamaha.cpp b/src/devices/bus/msx_cart/yamaha.cpp index a306ba9c070..34c87e88a9e 100644 --- a/src/devices/bus/msx_cart/yamaha.cpp +++ b/src/devices/bus/msx_cart/yamaha.cpp @@ -4,9 +4,6 @@ Yamaha SFG01/SFG05 emulation -TODO: -- Use a real YM2164 implementation for SFG05 - **************************************************************************/ #include "emu.h" @@ -71,6 +68,16 @@ void msx_cart_sfg_device::device_add_mconfig(machine_config &config) MIDI_PORT(config, "mdin", midiin_slot, "midiin").rxd_handler().set("ym2148", FUNC(ym2148_device::write_rxd)); } +void msx_cart_sfg05_device::device_add_mconfig(machine_config &config) +{ + msx_cart_sfg_device::device_add_mconfig(config); + + YM2164(config.replace(), m_ym2151, XTAL(3'579'545)); + m_ym2151->irq_handler().set(FUNC(msx_cart_sfg05_device::ym2151_irq_w)); + m_ym2151->add_route(0, "lspeaker", 0.80); + m_ym2151->add_route(1, "rspeaker", 0.80); +} + ROM_START( msx_sfg01 ) ROM_REGION(0x4000, "sfg", 0) diff --git a/src/devices/bus/msx_cart/yamaha.h b/src/devices/bus/msx_cart/yamaha.h index e5072dc5dcf..b326bc3b20c 100644 --- a/src/devices/bus/msx_cart/yamaha.h +++ b/src/devices/bus/msx_cart/yamaha.h @@ -31,7 +31,6 @@ protected: IRQ_CALLBACK_MEMBER(irq_callback); -private: DECLARE_WRITE_LINE_MEMBER(ym2151_irq_w); DECLARE_WRITE_LINE_MEMBER(ym2148_irq_w); @@ -61,6 +60,7 @@ class msx_cart_sfg05_device : public msx_cart_sfg_device public: msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; }; diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp index f6284aa0360..64b02822644 100644 --- a/src/devices/sound/ym2151.cpp +++ b/src/devices/sound/ym2151.cpp @@ -5,6 +5,7 @@ #include "ym2151.h" DEFINE_DEVICE_TYPE(YM2151, ym2151_device, "ym2151", "Yamaha YM2151 OPM") +DEFINE_DEVICE_TYPE(YM2164, ym2164_device, "ym2164", "Yamaha YM2164 OPP") #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ @@ -407,6 +408,21 @@ void ym2151_device::calculate_timers() } } +void ym2164_device::calculate_timers() +{ + /* calculate timers' deltas */ + for (int i=0; i<1024; i++) + { + /* ASG 980324: changed to compute both tim_A_tab and timer_A_time */ + timer_A_time[i] = clocks_to_attotime(64 * (1024 - i)); + } + for (int i=0; i<256; i++) + { + /* ASG 980324: changed to compute both tim_B_tab and timer_B_time */ + timer_B_time[i] = clocks_to_attotime(2048 * (256 - i)); + } +} + void ym2151_device::YM2151Operator::key_on(uint32_t key_set, uint32_t eg_cnt) { if (!key) @@ -910,6 +926,16 @@ void ym2151_device::write_reg(int r, int v) } } +void ym2164_device::write_reg(int r, int v) +{ + if (r < 0x08) + logerror("%s: Writing %02X to undocumented register %d\n", machine().describe_context(), v, r); + else if (r == 0x09) + ym2151_device::write_reg(0x01, v); + else + ym2151_device::write_reg(r, v); +} + void ym2151_device::device_post_load() { for (int j=0; j<8; j++) @@ -1662,8 +1688,8 @@ void ym2151_device::advance() // ym2151_device - constructor //------------------------------------------------- -ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, YM2151, tag, owner, clock), +ym2151_device::ym2151_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock), device_sound_interface(mconfig, *this), m_stream(nullptr), m_lastreg(0), @@ -1673,6 +1699,21 @@ ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, dev { } +ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ym2151_device(mconfig, YM2151, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// ym2164_device - constructor +//------------------------------------------------- + +ym2164_device::ym2164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ym2151_device(mconfig, YM2164, tag, owner, clock) +{ +} + //------------------------------------------------- // read - read from the device diff --git a/src/devices/sound/ym2151.h b/src/devices/sound/ym2151.h index 562c6bb10a2..ee32c6f3ed6 100644 --- a/src/devices/sound/ym2151.h +++ b/src/devices/sound/ym2151.h @@ -66,6 +66,8 @@ public: protected: // device-level overrides + ym2151_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; @@ -75,6 +77,9 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void calculate_timers(); + virtual void write_reg(int r, int v); + private: enum { TIMER_IRQ_A_OFF, @@ -208,8 +213,11 @@ private: emu_timer *timer_A, *timer_A_irq_off; emu_timer *timer_B, *timer_B_irq_off; +protected: attotime timer_A_time[1024]; /* timer A times for MAME */ attotime timer_B_time[256]; /* timer B times for MAME */ + +private: int irqlinestate; uint32_t timer_A_index; /* timer A index */ @@ -250,12 +258,10 @@ private: bool m_reset_active; void init_tables(); - void calculate_timers(); void envelope_KONKOFF(YM2151Operator * op, int v); void set_connect(YM2151Operator *om1, int cha, int v); void advance(); void advance_eg(); - void write_reg(int r, int v); void chan_calc(unsigned int chan); void chan7_calc(); int op_calc(YM2151Operator * OP, unsigned int env, signed int pm); @@ -263,9 +269,23 @@ private: void refresh_EG(YM2151Operator * op); }; +// ======================> ym2164_device + +class ym2164_device : public ym2151_device +{ +public: + // construction/destruction + ym2164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void calculate_timers() override; + virtual void write_reg(int r, int v) override; +}; + // device type definition DECLARE_DEVICE_TYPE(YM2151, ym2151_device) +DECLARE_DEVICE_TYPE(YM2164, ym2164_device) #endif // MAME_SOUND_YM2151_H diff --git a/src/mame/drivers/fb01.cpp b/src/mame/drivers/fb01.cpp index 9eb6095e118..30ceae0127d 100644 --- a/src/mame/drivers/fb01.cpp +++ b/src/mame/drivers/fb01.cpp @@ -218,7 +218,7 @@ void fb01_state::fb01(machine_config &config) SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - ym2151_device &ym2164(YM2151(config, "ym2164", XTAL(4'000'000))); + ym2164_device &ym2164(YM2164(config, "ym2164", XTAL(4'000'000))); ym2164.irq_handler().set(FUNC(fb01_state::ym2164_irq_w)); ym2164.add_route(0, "lspeaker", 1.00); ym2164.add_route(1, "rspeaker", 1.00); -- cgit v1.2.3