From 885b63b00d5f93050337514cbf9adf318a7f5b61 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sun, 15 Apr 2018 23:03:54 +0200 Subject: [PATCH] hp9k_3xx: workaround double exception during r-m-w operations The m68k emulation code throws two buserror exception during r-m-w opcodes like ori #$0x40, (0x1234).b. This confuses the HP bootrom. Work around that by storing the last read buserror address and compare it with the write address. if they are the same, ignore the buserror. Signed-off-by: Sven Schnelle --- src/mame/drivers/hp9k_3xx.cpp | 46 ++++++++++++++--------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/mame/drivers/hp9k_3xx.cpp b/src/mame/drivers/hp9k_3xx.cpp index 9af80b9fff4..ccab6ace245 100644 --- a/src/mame/drivers/hp9k_3xx.cpp +++ b/src/mame/drivers/hp9k_3xx.cpp @@ -153,10 +153,10 @@ public: void hp9k3xx_common(address_map &map); void iocpu_map(address_map &map); private: - bool m_in_buserr; bool m_hil_read; uint8_t m_hil_data; uint8_t m_latch_data; + uint32_t m_lastpc; }; uint32_t hp9k3xx_state::hp_medres_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -293,53 +293,43 @@ INPUT_PORTS_END void hp9k3xx_state::machine_reset() { - m_in_buserr = false; } READ16_MEMBER(hp9k3xx_state::buserror16_r) { - if (!m_in_buserr) - { - m_in_buserr = true; - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_in_buserr = false; - } + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + m_lastpc = machine().device("maincpu")->pc(); return 0; } WRITE16_MEMBER(hp9k3xx_state::buserror16_w) { - if (!m_in_buserr) - { - m_in_buserr = true; - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_in_buserr = false; + if (m_lastpc == machine().device("maincpu")->pc()) { + logerror("%s: ignoring r-m-w double bus error\n", __FUNCTION__); + return; } + + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); } READ32_MEMBER(hp9k3xx_state::buserror_r) { - if (!m_in_buserr) - { - m_in_buserr = true; - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_in_buserr = false; - } + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + m_lastpc = machine().device("maincpu")->pc(); return 0; } WRITE32_MEMBER(hp9k3xx_state::buserror_w) { - if (!m_in_buserr) - { - m_in_buserr = true; - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_in_buserr = false; + if (m_lastpc == machine().device("maincpu")->pc()) { + logerror("%s: ignoring r-m-w double bus error\n", __FUNCTION__); + return; } + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); } WRITE8_MEMBER(hp9k3xx_state::iocpu_port1_w)