metro.cpp: Fix random hanging in gunmast (and probably other games with uPD7810 sound) by not syncing on each shift (nw)

This commit is contained in:
AJR 2020-03-08 11:57:50 -04:00
parent 26bf946fda
commit da9b4c7190
2 changed files with 25 additions and 38 deletions

View File

@ -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);

View File

@ -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;