diff options
author | 2023-04-13 13:38:27 -0700 | |
---|---|---|
committer | 2023-04-14 06:38:27 +1000 | |
commit | c0b57d30f0ce39c445190fe4e27bec6c57ebb137 (patch) | |
tree | a5d03fa6a90e114de0fa21312cc90497503297b8 /src | |
parent | b56409dbc2e83e666cc767de0c55d937edea38e2 (diff) |
namco/namco06.cpp: Quantise timer to clock frequency (#11069)
Diffstat (limited to 'src')
-rw-r--r-- | src/mame/namco/namco06.cpp | 58 | ||||
-rw-r--r-- | src/mame/namco/namco06.h | 2 |
2 files changed, 28 insertions, 32 deletions
diff --git a/src/mame/namco/namco06.cpp b/src/mame/namco/namco06.cpp index 9f37fafa94a..414f6f00843 100644 --- a/src/mame/namco/namco06.cpp +++ b/src/mame/namco/namco06.cpp @@ -102,12 +102,11 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::nmi_generate ) { // This timer runs at twice the clock, since we do work on both the - // rising and falling edge. - // - // During reads, the first NMI pulse is supressed to give the chip a - // cycle to write. + // rising and falling edges. + // m_timer_state == true is the falling clock edge + m_timer_state = !m_timer_state; - if (m_next_timer_state) + if (m_timer_state) { m_rw[0](0, BIT(m_control, 4)); m_rw[1](0, BIT(m_control, 4)); @@ -115,7 +114,11 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::nmi_generate ) m_rw[3](0, BIT(m_control, 4)); } - if (m_next_timer_state && !m_read_stretch) + // During reads, the first NMI pulse is supressed to give the chip a + // cycle to write. + + + if (m_timer_state && !m_read_stretch) { set_nmi(ASSERT_LINE); } @@ -125,12 +128,10 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::nmi_generate ) } m_read_stretch = false; - m_chipsel[0](0, BIT(m_control, 0) && m_next_timer_state); - m_chipsel[1](0, BIT(m_control, 1) && m_next_timer_state); - m_chipsel[2](0, BIT(m_control, 2) && m_next_timer_state); - m_chipsel[3](0, BIT(m_control, 3) && m_next_timer_state); - - m_next_timer_state = !m_next_timer_state; + m_chipsel[0](0, BIT(m_control, 0) && m_timer_state); + m_chipsel[1](0, BIT(m_control, 1) && m_timer_state); + m_chipsel[2](0, BIT(m_control, 2) && m_timer_state); + m_chipsel[3](0, BIT(m_control, 3) && m_timer_state); } uint8_t namco_06xx_device::data_r(offs_t offset) @@ -164,6 +165,7 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::write_sync ) logerror("%s: 06XX '%s' write in read mode %02x\n",machine().describe_context(),tag(),m_control); return; } + if (BIT(m_control, 0)) m_write[0](0, param); if (BIT(m_control, 1)) m_write[1](0, param); if (BIT(m_control, 2)) m_write[2](0, param); @@ -188,8 +190,9 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::ctrl_w_sync ) // The upper 3 control bits are the clock divider. if ((m_control & 0xe0) == 0) { + // If the divider is zero, stop the timer. m_nmi_timer->adjust(attotime::never); - m_next_timer_state = true; + m_timer_state = false; set_nmi(CLEAR_LINE); m_chipsel[0](0, CLEAR_LINE); m_chipsel[1](0, CLEAR_LINE); @@ -205,7 +208,9 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::ctrl_w_sync ) { set_nmi(CLEAR_LINE); m_read_stretch = true; - } else { + } + else + { m_read_stretch = false; } @@ -213,21 +218,12 @@ TIMER_CALLBACK_MEMBER( namco_06xx_device::ctrl_w_sync ) uint8_t num_shifts = (m_control & 0xe0) >> 5; uint8_t divisor = 1 << num_shifts; attotime period = attotime::from_hz(clock() / divisor) / 2; - // This delay should be the next falling clock. - // That's complicated to get, as it's derived from the master - // clock. The CPU uses this same clock, so writes will come at - // a specific pace. - // Instead, just approximate a quarter cycle. - // Xevious is very sensitive to this. It will bootloop if it - // isn't correct. - attotime delay = attotime::from_hz(clock()) / 4; // average of one clock - if (!m_next_timer_state) - { - // NMI is asserted, wait one additional clock to start - m_nmi_timer->adjust(delay + attotime::from_hz(clock() / divisor), 0, period); - } else { - m_nmi_timer->adjust(delay, 0, period); - } + + // Delay to the next falling clock edge + attotime now = machine().time(); + u64 total_ticks = now.as_ticks(clock()); + attotime delay = attotime::from_ticks(total_ticks + 1, clock()) - now; + m_nmi_timer->adjust(delay, 0, period); } } @@ -246,7 +242,7 @@ DEFINE_DEVICE_TYPE(NAMCO_06XX, namco_06xx_device, "namco06", "Namco 06xx") namco_06xx_device::namco_06xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, NAMCO_06XX, tag, owner, clock) , m_control(0) - , m_next_timer_state(false) + , m_timer_state(false) , m_read_stretch(false) , m_nmicpu(*this, finder_base::DUMMY_TAG) , m_chipsel(*this) @@ -271,7 +267,7 @@ void namco_06xx_device::device_start() m_nmi_timer = timer_alloc(FUNC(namco_06xx_device::nmi_generate), this); save_item(NAME(m_control)); - save_item(NAME(m_next_timer_state)); + save_item(NAME(m_timer_state)); save_item(NAME(m_read_stretch)); } diff --git a/src/mame/namco/namco06.h b/src/mame/namco/namco06.h index 20820a1d33d..ca5bc456925 100644 --- a/src/mame/namco/namco06.h +++ b/src/mame/namco/namco06.h @@ -39,7 +39,7 @@ private: // internal state emu_timer *m_nmi_timer = nullptr; uint8_t m_control; - bool m_next_timer_state; + bool m_timer_state; bool m_read_stretch; required_device<cpu_device> m_nmicpu; |