summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-05-02 20:31:45 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-05-02 20:31:47 -0400
commitc64715036876816db546e23f049afcc6a7561fa7 (patch)
tree5bd6f4d3dff57890f9a85da139e1b3a16b8d913f
parent46d30e2381ac1933b3a51ff20c9cc0ef168116c2 (diff)
MT #7309 (nw)
The situation here with interrupts being acknowledged at a time nominally preceding the condition that triggered them suggests a disturbingly general problem with MAME's CPU scheduling. However, it should only affect machines in which such interrupt vectors are calculated from free-running counters (as this hardware does) rather than the more normal priority encoding of latched requests.
-rw-r--r--src/mame/includes/mw8080bw.h2
-rw-r--r--src/mame/machine/mw8080bw.cpp7
2 files changed, 9 insertions, 0 deletions
diff --git a/src/mame/includes/mw8080bw.h b/src/mame/includes/mw8080bw.h
index e14515510a5..0aa65d4d0f6 100644
--- a/src/mame/includes/mw8080bw.h
+++ b/src/mame/includes/mw8080bw.h
@@ -187,6 +187,8 @@ private:
emu_timer *m_interrupt_timer;
emu_timer *m_maze_tone_timer;
+ attotime m_interrupt_time;
+
DECLARE_READ8_MEMBER(mw8080bw_shift_result_rev_r);
DECLARE_READ8_MEMBER(mw8080bw_reversable_shift_result_r);
DECLARE_WRITE8_MEMBER(mw8080bw_reversable_shift_count_w);
diff --git a/src/mame/machine/mw8080bw.cpp b/src/mame/machine/mw8080bw.cpp
index ae8b32dd8ff..cabace7c321 100644
--- a/src/mame/machine/mw8080bw.cpp
+++ b/src/mame/machine/mw8080bw.cpp
@@ -52,6 +52,8 @@ TIMER_CALLBACK_MEMBER(mw8080bw_state::interrupt_trigger)
m_maincpu->set_input_line(0, ASSERT_LINE);
+ m_interrupt_time = machine().time();
+
/* set up for next interrupt */
uint8_t next_counter;
int next_vblank;
@@ -74,6 +76,9 @@ TIMER_CALLBACK_MEMBER(mw8080bw_state::interrupt_trigger)
IRQ_CALLBACK_MEMBER(mw8080bw_state::interrupt_vector)
{
int vpos = m_screen->vpos();
+ // MAME scheduling quirks cause this to happen more often than you might think, in fact far too often
+ if (machine().time() < m_interrupt_time)
+ vpos++;
uint8_t counter = vpos_to_vysnc_chain_counter(vpos);
uint8_t vector = 0xc7 | ((counter & 0x40) >> 2) | ((~counter & 0x40) >> 3);
@@ -92,6 +97,8 @@ void mw8080bw_state::mw8080bw_start_interrupt_timer( )
{
int vpos = vysnc_chain_counter_to_vpos(MW8080BW_INT_TRIGGER_COUNT_1, MW8080BW_INT_TRIGGER_VBLANK_1);
m_interrupt_timer->adjust(m_screen->time_until_pos(vpos));
+
+ m_interrupt_time = attotime::zero;
}