summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2020-03-08 11:57:50 -0400
committer AJR <ajrhacker@users.noreply.github.com>2020-03-08 11:58:43 -0400
commitda9b4c719096822b2dc04aac09a89843912db3c9 (patch)
tree92ea75b23cf0b5d2ad378dcbdb5ed81740a92d6d /src/mame
parent26bf946fda0e5f1c8d7baa916249372058b4772c (diff)
metro.cpp: Fix random hanging in gunmast (and probably other games with uPD7810 sound) by not syncing on each shift (nw)
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/drivers/metro.cpp59
-rw-r--r--src/mame/includes/metro.h4
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<int Mask> 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;