From debe1e0592e95cd56a9145b39a6b4e351a761f97 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 26 Apr 2025 21:59:42 +0200 Subject: [PATCH] pgm: use retry_access to sync on reads for 2-way sound comms --- src/mame/igs/pgm.cpp | 64 ++++++++++++++++++-------- src/mame/igs/pgm.h | 30 ++++++------ src/mame/igs/pgmprot_igs027a_type1.cpp | 2 + src/mame/igs/pgmprot_igs027a_type1.h | 1 - 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/src/mame/igs/pgm.cpp b/src/mame/igs/pgm.cpp index 9be1d26923c..a7c8977d6e4 100644 --- a/src/mame/igs/pgm.cpp +++ b/src/mame/igs/pgm.cpp @@ -222,19 +222,37 @@ void pgm_state::coin_counter_w(u16 data) machine().bookkeeping().coin_counter_w(3, data & 0x0008); } +bool pgm_state::z80_sync(int which) +{ + if (!machine().side_effects_disabled()) + { + // retry_access() forces the z80 to catch up before maincpu does the read + if (!m_z80_sync[which]) + m_maincpu->retry_access(); + + m_z80_sync[which] = !m_z80_sync[which]; + } + + return m_z80_sync[which]; +} + u8 pgm_state::z80_ram_r(offs_t offset) { + // 2 sync semaphores because of word access + z80_sync(offset & 1); return m_z80_mainram[offset]; } void pgm_state::z80_ram_w(offs_t offset, u8 data) { - const int pc = m_maincpu->pc(); + if (!z80_sync(offset & 1)) + { + const u32 pc = m_maincpu->pc(); + if (pc != 0xf12 && pc != 0xde2 && pc != 0x100c50 && pc != 0x100b20) + LOGZ80("Z80: write %04x, %02x (%06x)\n", offset, data, pc); - m_z80_mainram[offset] = data; - - if (pc != 0xf12 && pc != 0xde2 && pc != 0x100c50 && pc != 0x100b20) - LOGZ80("Z80: write %04x, %02x (%06x)\n", offset, data, m_maincpu->pc()); + m_z80_mainram[offset] = data; + } } void pgm_state::z80_reset_w(offs_t offset, u16 data, u16 mem_mask) @@ -260,17 +278,23 @@ void pgm_state::z80_ctrl_w(offs_t offset, u16 data, u16 mem_mask) LOGZ80("Z80: ctrl %04x @ %04x (%06x)\n", data, mem_mask, m_maincpu->pc()); } -void pgm_state::m68k_l1_w(u8 data) +template +u8 pgm_state::m68k_latch_r() +{ + return z80_sync(0) ? 0 : m_soundlatch[N]->read(); +} + +void pgm_state::m68k_latch1_w(u8 data) { LOGZ80("SL 1 m68.w %02x (%06x) IRQ\n", data, m_maincpu->pc()); - m_soundlatch->write(data); + m_soundlatch[0]->write(data); m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); } -void pgm_state::z80_l3_w(u8 data) +void pgm_state::z80_latch3_w(u8 data) { LOGZ80("SL 3 z80.w %02x (%04x)\n", data, m_soundcpu->pc()); - m_soundlatch3->write(data); + m_soundlatch[2]->write(data); } @@ -286,9 +310,9 @@ void pgm_state::pgm_z80_mem(address_map &map) void pgm_state::pgm_z80_io(address_map &map) { map(0x8000, 0x8003).rw("ics", FUNC(ics2115_device::read), FUNC(ics2115_device::write)); - map(0x8100, 0x81ff).r(m_soundlatch3, FUNC(generic_latch_8_device::read)).w(FUNC(pgm_state::z80_l3_w)); - map(0x8200, 0x82ff).rw(m_soundlatch, FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); - map(0x8400, 0x84ff).rw("soundlatch2", FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); + map(0x8100, 0x81ff).r(m_soundlatch[2], FUNC(generic_latch_8_device::read)).w(FUNC(pgm_state::z80_latch3_w)); + map(0x8200, 0x82ff).rw(m_soundlatch[0], FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); + map(0x8400, 0x84ff).rw(m_soundlatch[1], FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); } /*** 68000 (main CPU) + variants for protection devices **********************/ @@ -310,12 +334,12 @@ void pgm_state::pgm_base_mem(address_map &map) //map(0xb06000, 0xb06001) Foreground scroll X? //map(0xb0e000, 0xb0e001) Unknown #1 - map(0xc00003, 0xc00003).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w(FUNC(pgm_state::m68k_l1_w)); - map(0xc00005, 0xc00005).rw("soundlatch2", FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); + map(0xc00003, 0xc00003).rw(FUNC(pgm_state::m68k_latch_r<0>), FUNC(pgm_state::m68k_latch1_w)); + map(0xc00005, 0xc00005).r(FUNC(pgm_state::m68k_latch_r<1>)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write)); map(0xc00007, 0xc00007).rw("rtc", FUNC(v3021_device::read), FUNC(v3021_device::write)); map(0xc00008, 0xc00009).w(FUNC(pgm_state::z80_reset_w)); map(0xc0000a, 0xc0000b).w(FUNC(pgm_state::z80_ctrl_w)); - map(0xc0000d, 0xc0000d).rw(m_soundlatch3, FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write)); + map(0xc0000d, 0xc0000d).r(FUNC(pgm_state::m68k_latch_r<2>)).w(m_soundlatch[2], FUNC(generic_latch_8_device::write)); map(0xc08000, 0xc08001).portr("P1P2"); map(0xc08002, 0xc08003).portr("P3P4"); @@ -445,6 +469,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(pgm_state::interrupt) void pgm_state::machine_reset() { + m_z80_sync[0] = m_z80_sync[1] = false; m_soundcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } @@ -453,8 +478,9 @@ u16 pgm_state::sprites_r(offs_t offset) return m_mainram[offset]; } -void pgm_state::video_start() +void pgm_state::machine_start() { + save_item(NAME(m_z80_sync)); } void pgm_state::screen_vblank(int state) @@ -497,9 +523,9 @@ void pgm_state::pgmbase(machine_config &config) /*sound hardware */ SPEAKER(config, "mono").front_center(); - GENERIC_LATCH_8(config, m_soundlatch); - GENERIC_LATCH_8(config, "soundlatch2"); - GENERIC_LATCH_8(config, m_soundlatch3); + GENERIC_LATCH_8(config, m_soundlatch[0]); + GENERIC_LATCH_8(config, m_soundlatch[1]); + GENERIC_LATCH_8(config, m_soundlatch[2]); IGS023_VIDEO(config, m_video, 0); m_video->set_palette(m_palette); diff --git a/src/mame/igs/pgm.h b/src/mame/igs/pgm.h index 17bfb2ba045..e603af5c260 100644 --- a/src/mame/igs/pgm.h +++ b/src/mame/igs/pgm.h @@ -37,12 +37,10 @@ public: , m_z80_mainram(*this, "z80_mainram") , m_soundcpu(*this, "soundcpu") , m_palette(*this, "palette") - , m_soundlatch(*this, "soundlatch") - , m_soundlatch3(*this, "soundlatch3") + , m_soundlatch(*this, "soundlatch%u", 1) , m_ics(*this, "ics") , m_video(*this, "igs023") { - m_irq4_disabled = 0; } void init_pgm(); @@ -52,8 +50,8 @@ public: void pgmbase(machine_config &config); protected: + virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; - virtual void video_start() override ATTR_COLD; // memory pointers required_shared_ptr m_mainram; @@ -64,8 +62,7 @@ protected: // devices required_device m_maincpu; - // hack - int m_irq4_disabled = 0; + int m_irq4_disabled = 0; // hack void pgm_base_mem(address_map &map) ATTR_COLD; void pgm_mem(address_map &map) ATTR_COLD; @@ -74,23 +71,24 @@ private: // memory pointers required_shared_ptr m_z80_mainram; - - // devices - required_device m_soundcpu; - required_device m_palette; - required_device m_soundlatch; - required_device m_soundlatch3; - required_device m_ics; - required_device m_video; + required_device m_soundcpu; + required_device m_palette; + required_device_array m_soundlatch; + required_device m_ics; + required_device m_video; + + bool m_z80_sync[2] = { }; void coin_counter_w(u16 data); + bool z80_sync(int which); u8 z80_ram_r(offs_t offset); void z80_ram_w(offs_t offset, u8 data); void z80_reset_w(offs_t offset, u16 data, u16 mem_mask = ~0); void z80_ctrl_w(offs_t offset, u16 data, u16 mem_mask = ~0); - void m68k_l1_w(u8 data); - void z80_l3_w(u8 data); + template u8 m68k_latch_r(); + void m68k_latch1_w(u8 data); + void z80_latch3_w(u8 data); void screen_vblank(int state); TIMER_DEVICE_CALLBACK_MEMBER(interrupt); diff --git a/src/mame/igs/pgmprot_igs027a_type1.cpp b/src/mame/igs/pgmprot_igs027a_type1.cpp index 07bd5e1ef86..e841e97d63f 100644 --- a/src/mame/igs/pgmprot_igs027a_type1.cpp +++ b/src/mame/igs/pgmprot_igs027a_type1.cpp @@ -187,6 +187,8 @@ void pgm_arm_type1_state::cavepgm_mem(address_map &map) void pgm_arm_type1_state::machine_start() { + pgm_state::machine_start(); + save_item(NAME(m_value0)); save_item(NAME(m_value1)); save_item(NAME(m_valuekey)); diff --git a/src/mame/igs/pgmprot_igs027a_type1.h b/src/mame/igs/pgmprot_igs027a_type1.h index bbfb98e0825..f1c2afa25c0 100644 --- a/src/mame/igs/pgmprot_igs027a_type1.h +++ b/src/mame/igs/pgmprot_igs027a_type1.h @@ -70,7 +70,6 @@ private: optional_shared_ptr m_arm7_shareram; optional_device m_prot; - DECLARE_MACHINE_START(pgm_arm_type1); u32 arm7_type1_protlatch_r(); void arm7_type1_protlatch_w(offs_t offset, u32 data, u32 mem_mask);