summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Mike <mike.harris@gmail.com>2023-04-13 13:38:27 -0700
committer GitHub <noreply@github.com>2023-04-14 06:38:27 +1000
commitc0b57d30f0ce39c445190fe4e27bec6c57ebb137 (patch)
treea5d03fa6a90e114de0fa21312cc90497503297b8 /src
parentb56409dbc2e83e666cc767de0c55d937edea38e2 (diff)
namco/namco06.cpp: Quantise timer to clock frequency (#11069)
Diffstat (limited to 'src')
-rw-r--r--src/mame/namco/namco06.cpp58
-rw-r--r--src/mame/namco/namco06.h2
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;