From da9b4c719096822b2dc04aac09a89843912db3c9 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 8 Mar 2020 11:57:50 -0400 Subject: metro.cpp: Fix random hanging in gunmast (and probably other games with uPD7810 sound) by not syncing on each shift (nw) --- src/mame/drivers/metro.cpp | 59 +++++++++++++++++----------------------------- src/mame/includes/metro.h | 4 +++- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/mame/drivers/metro.cpp b/src/mame/drivers/metro.cpp index 832a17fa3ca..37acb9c31e3 100644 --- a/src/mame/drivers/metro.cpp +++ b/src/mame/drivers/metro.cpp @@ -301,22 +301,28 @@ WRITE_LINE_MEMBER(metro_state::puzzlet_vblank_irq) READ_LINE_MEMBER(metro_state::rxd_r) { - uint8_t data = m_soundlatch->read(); + uint8_t data = m_sound_data; - m_soundlatch->write(data >> 1); + // TODO: shift on SCK falling edges + m_sound_data >>= 1; return data & 1; } -WRITE8_MEMBER(metro_state::soundlatch_w) +WRITE8_MEMBER(metro_state::sound_data_w) { - m_soundlatch->write(data & 0xff); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(metro_state::sound_data_sync), this), data); m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); // seen rxd_r m_maincpu->spin_until_interrupt(); m_busy_sndcpu = 1; } +TIMER_CALLBACK_MEMBER(metro_state::sound_data_sync) +{ + m_sound_data = param; +} + READ8_MEMBER(metro_state::soundstatus_r) { @@ -659,7 +665,7 @@ void metro_state::daitorid_map(address_map &map) map(0x400000, 0x47ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map)); map(0x4788a3, 0x4788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x4788a4, 0x4788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x4788a9, 0x4788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x4788a9, 0x4788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0x800000, 0x80ffff).ram().mirror(0x0f0000); // RAM (mirrored) map(0xc00000, 0xc00001).portr("IN0"); map(0xc00001, 0xc00001).w(FUNC(metro_state::soundstatus_w)); // To Sound CPU @@ -681,7 +687,7 @@ void metro_state::dharma_map(address_map &map) map(0x800000, 0x87ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map)); map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8788a9, 0x8788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xc00000, 0xc00001).portr("IN0"); map(0xc00001, 0xc00001).w(FUNC(metro_state::soundstatus_w)); // To Sound CPU map(0xc00002, 0xc00003).portr("IN1"); // @@ -708,7 +714,7 @@ void metro_state::karatour_map(address_map &map) map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8788a9, 0x8788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xf00000, 0xf0ffff).ram().mirror(0x0f0000); // RAM (mirrored) } @@ -726,7 +732,7 @@ void metro_state::kokushi_map(address_map &map) map(0x800000, 0x87ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map)); map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8788a9, 0x8788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xc00000, 0xc00001).portr("IN0"); map(0xc00001, 0xc00001).w(FUNC(metro_state::soundstatus_w)); // To Sound CPU map(0xc00002, 0xc00003).portr("IN1"); // Inputs @@ -746,7 +752,7 @@ void metro_state::lastfort_map(address_map &map) map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8788a9, 0x8788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xc00001, 0xc00001).rw(FUNC(metro_state::soundstatus_r), FUNC(metro_state::soundstatus_w)); // From / To Sound CPU map(0xc00003, 0xc00003).w(FUNC(metro_state::coin_lockout_1word_w)); // Coin Lockout map(0xc00004, 0xc00005).portr("IN0"); // Inputs @@ -773,7 +779,7 @@ void metro_state::lastforg_map(address_map &map) map(0x880000, 0x8fffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0x8f88a3, 0x8f88a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8f88a4, 0x8f88a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8f88a9, 0x8f88a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8f88a9, 0x8f88a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xc00000, 0xc0ffff).ram().mirror(0x0f0000); // RAM (mirrored) } @@ -967,7 +973,7 @@ void metro_state::pangpoms_map(address_map &map) map(0x400000, 0x47ffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0x4788a3, 0x4788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x4788a4, 0x4788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x4788a9, 0x4788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x4788a9, 0x4788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0x800001, 0x800001).rw(FUNC(metro_state::soundstatus_r), FUNC(metro_state::soundstatus_w)); // From / To Sound CPU map(0x800002, 0x800003).nopr(); map(0x800003, 0x800003).w(FUNC(metro_state::coin_lockout_1word_w)); // Coin Lockout @@ -998,7 +1004,7 @@ void metro_state::poitto_map(address_map &map) map(0xc00000, 0xc7ffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0xc788a9, 0xc788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU } @@ -1021,7 +1027,7 @@ void metro_state::skyalert_map(address_map &map) map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map)); map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0x8788a9, 0x8788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU map(0xc00000, 0xc0ffff).ram().mirror(0x0f0000); // RAM (mirrored) } @@ -1043,7 +1049,7 @@ void metro_state::pururun_map(address_map &map) map(0xc00000, 0xc7ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map)); map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0xc788a9, 0xc788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU } @@ -1064,7 +1070,7 @@ void metro_state::toride2g_map(address_map &map) map(0xc00000, 0xc7ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map)); map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable - map(0xc788a9, 0xc788a9).w(FUNC(metro_state::soundlatch_w)); // To Sound CPU + map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU } @@ -2994,6 +3000,7 @@ void metro_state::machine_start() save_item(NAME(m_blitter_bit)); save_item(NAME(m_irq_line)); save_item(NAME(m_requested_int)); + save_item(NAME(m_sound_data)); save_item(NAME(m_soundstatus)); save_item(NAME(m_porta)); save_item(NAME(m_portb)); @@ -3187,8 +3194,6 @@ void metro_state::daitorid(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - ym2151_device &ymsnd(YM2151(config, "ymsnd", 3.579545_MHz_XTAL)); ymsnd.irq_handler().set_inputline(m_audiocpu, UPD7810_INTF2); ymsnd.add_route(ALL_OUTPUTS, "mono", 0.80); @@ -3232,8 +3237,6 @@ void metro_state::dharma(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // sample rate = M6295 clock / 132 m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3258,8 +3261,6 @@ void metro_state::karatour(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // was /128.. so pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3284,8 +3285,6 @@ void metro_state::sankokushi(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // was /128.. so pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3311,8 +3310,6 @@ void metro_state::lastfort(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_LOW); // sample rate = M6295 clock / 165 m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3336,8 +3333,6 @@ void metro_state::lastforg(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // was /128.. so pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3462,8 +3457,6 @@ void metro_state::pangpoms(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // was /128.. so pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3488,8 +3481,6 @@ void metro_state::poitto(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // was /128.. so pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3514,8 +3505,6 @@ void metro_state::pururun(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - ym2151_device &ymsnd(YM2151(config, "ymsnd", 3.579545_MHz_XTAL)); /* Confirmed match to reference video */ ymsnd.irq_handler().set_inputline(m_audiocpu, UPD7810_INTF2); ymsnd.add_route(ALL_OUTPUTS, "mono", 0.80); @@ -3541,8 +3530,6 @@ void metro_state::skyalert(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_LOW); // sample rate = M6295 clock / 165 m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); @@ -3568,8 +3555,6 @@ void metro_state::toride2g(machine_config &config) /* sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - OKIM6295(config, m_oki, 24_MHz_XTAL/20, okim6295_device::PIN7_HIGH); // clock frequency & pin 7 not verified m_oki->add_route(ALL_OUTPUTS, "mono", 0.10); diff --git a/src/mame/includes/metro.h b/src/mame/includes/metro.h index cafc5701c94..aa8c8546299 100644 --- a/src/mame/includes/metro.h +++ b/src/mame/includes/metro.h @@ -110,7 +110,8 @@ private: void irq_cause_w(offs_t offset, u8 data); uint8_t irq_vector_r(offs_t offset); DECLARE_WRITE16_MEMBER(mouja_irq_timer_ctrl_w); - DECLARE_WRITE8_MEMBER(soundlatch_w); + DECLARE_WRITE8_MEMBER(sound_data_w); + TIMER_CALLBACK_MEMBER(sound_data_sync); DECLARE_READ8_MEMBER(soundstatus_r); DECLARE_WRITE8_MEMBER(soundstatus_w); template DECLARE_WRITE8_MEMBER(upd7810_rombank_w); @@ -227,6 +228,7 @@ private: emu_timer *m_karatour_irq_timer; /* sound related */ + uint8_t m_sound_data; uint16_t m_soundstatus; int m_porta; int m_portb; -- cgit v1.2.3