summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/generalplus_gpl_timebase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/generalplus_gpl_timebase.cpp')
-rw-r--r--src/devices/machine/generalplus_gpl_timebase.cpp163
1 files changed, 43 insertions, 120 deletions
diff --git a/src/devices/machine/generalplus_gpl_timebase.cpp b/src/devices/machine/generalplus_gpl_timebase.cpp
index 838ea14400f..ff0fddf2a04 100644
--- a/src/devices/machine/generalplus_gpl_timebase.cpp
+++ b/src/devices/machine/generalplus_gpl_timebase.cpp
@@ -14,39 +14,47 @@ DEFINE_DEVICE_TYPE(GPL_TIMEBASE, gpl_timebase_device, "gpl_timebase", "Generalpl
gpl_timebase_device::gpl_timebase_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, GPL_TIMEBASE, tag, owner, clock),
- m_timebase_a(*this, "timebase_a"),
- m_timebase_b(*this, "timebase_b"),
- m_timebase_c(*this, "timebase_c"),
+ m_timebasetimer(*this, { "timebase_a", "timebase_b", "timebase_c" }),
m_updateirqs_cb(*this)
{
}
void gpl_timebase_device::device_start()
{
- save_item(NAME(m_timebasea_ctrl));
- save_item(NAME(m_timebaseb_ctrl));
- save_item(NAME(m_timebasec_ctrl));
+ save_item(NAME(m_timebase_ctrl));
save_item(NAME(m_timebase_reset));
}
void gpl_timebase_device::device_reset()
{
- m_timebasea_ctrl = 0x0000;
- m_timebaseb_ctrl = 0x0000;
- m_timebasec_ctrl = 0x0000;
+ m_timebase_ctrl[0] = 0x0000;
+ m_timebase_ctrl[1] = 0x0000;
+ m_timebase_ctrl[2] = 0x0000;
m_timebase_reset = 0x0000;
}
+attotime gpl_timebase_device::get_timer_period(int timer, int ctrlval)
+{
+ int which = (timer << 2) | ctrlval;
+
+ if (which != 0) // timebase_a, fequency 0 is 'off'
+ {
+ int period = 1 << (which - 1);
+ return attotime::from_hz(period);
+ }
+
+ return attotime::never;
+}
// Timebase ('fixed' frequency timers)
// (each can select from 3 different frequencies, different for each timer)
-
-TIMER_DEVICE_CALLBACK_MEMBER( gpl_timebase_device::timebase_a_cb )
+template<u16 Timer>
+TIMER_DEVICE_CALLBACK_MEMBER( gpl_timebase_device::timebase_cb )
{
- // sets bit 15 in m_timebasec_ctrl, also visible (as read only) in P_INT_Status2, bit 8
+ // sets bit 15 in m_timebase_ctrl[2], also visible (as read only) in P_INT_Status2, bit 8
// uses IRQ7 (FIQ option not available)
- m_timebasea_ctrl |= 0x8000;
+ m_timebase_ctrl[Timer] |= 0x8000;
m_updateirqs_cb(1);
}
@@ -70,127 +78,34 @@ TIMER_DEVICE_CALLBACK_MEMBER( gpl_timebase_device::timebase_a_cb )
// 1 TMBAS[1]
// 0 TMBAS[0] 00 = Reserved, 01 = 1Hz, 10 = 2Hz, 11 = 4Hz
-u16 gpl_timebase_device::timebasea_ctrl_r()
-{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebasea_ctrl_r\n", machine().describe_context());
- return m_timebasea_ctrl;
-}
-
-void gpl_timebase_device::timebasea_ctrl_w(u16 data)
-{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebasea_ctrl_w %04x\n", machine().describe_context(), data);
-
- if (data & 0x8000)
- {
- m_timebasea_ctrl = data & 0x7fff;
- m_updateirqs_cb(1);
- }
- else
- {
- m_timebasea_ctrl = data;
- }
-
- if ((m_timebasea_ctrl & 0x6000) == 0x6000)
- {
- switch (m_timebasea_ctrl & 0x0003)
- {
- case 0x00: m_timebase_a->adjust(attotime::never); break; // invalid
- case 0x01: m_timebase_a->adjust(attotime::from_hz(1)); break;
- case 0x02: m_timebase_a->adjust(attotime::from_hz(2)); break;
- case 0x03: m_timebase_a->adjust(attotime::from_hz(4)); break;
- }
- }
- else
- {
- m_timebase_a->adjust(attotime::never);
- }
-}
-
-TIMER_DEVICE_CALLBACK_MEMBER( gpl_timebase_device::timebase_b_cb )
-{
- // sets bit 15 in m_timebaseb_ctrl, also visible (as read only) in P_INT_Status2, bit 9
- // uses IRQ7 (FIQ option not available)
- m_timebaseb_ctrl |= 0x8000;
- m_updateirqs_cb(1);
-}
-
-u16 gpl_timebase_device::timebaseb_ctrl_r()
+template<u16 Timer> u16 gpl_timebase_device::timebase_ctrl_r()
{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebaseb_ctrl_r\n", machine().describe_context());
- return m_timebaseb_ctrl;
+ LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebase%c_ctrl_r\n", machine().describe_context(), 'a'+Timer);
+ return m_timebase_ctrl[Timer];
}
-void gpl_timebase_device::timebaseb_ctrl_w(u16 data)
+template<u16 Timer> void gpl_timebase_device::timebase_ctrl_w(u16 data)
{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebaseb_ctrl_w %04x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebase%c_ctrl_w %04x\n", machine().describe_context(), 'a'+Timer, data);
if (data & 0x8000)
{
- m_timebaseb_ctrl = data & 0x7fff;
+ m_timebase_ctrl[Timer] = data & 0x7fff;
m_updateirqs_cb(1);
}
else
{
- m_timebaseb_ctrl = data;
+ m_timebase_ctrl[Timer] = data;
}
- if ((m_timebaseb_ctrl & 0x6000) == 0x6000)
+ if (m_timebase_ctrl[Timer] & 0x2000)
{
- switch (m_timebaseb_ctrl & 0x0003)
- {
- case 0x00: m_timebase_b->adjust(attotime::from_hz(8)); break;
- case 0x01: m_timebase_b->adjust(attotime::from_hz(16)); break;
- case 0x02: m_timebase_b->adjust(attotime::from_hz(32)); break;
- case 0x03: m_timebase_b->adjust(attotime::from_hz(64)); break;
- }
+ attotime period = get_timer_period(Timer, m_timebase_ctrl[Timer] & 0x0003);
+ m_timebasetimer[Timer]->adjust(period, 0, period);
}
else
{
- m_timebase_b->adjust(attotime::never);
- }
-}
-
-TIMER_DEVICE_CALLBACK_MEMBER( gpl_timebase_device::timebase_c_cb )
-{
- // sets bit 15 in m_timebasec_ctrl, also visible (as read only) in P_INT_Status2, bit 10
- // uses IRQ6 (FIQ option not available)
- m_timebasec_ctrl |= 0x8000;
- m_updateirqs_cb(1);
-}
-
-u16 gpl_timebase_device::timebasec_ctrl_r()
-{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebasec_ctrl_r\n", machine().describe_context());
- return m_timebasec_ctrl;
-}
-
-void gpl_timebase_device::timebasec_ctrl_w(u16 data)
-{
- LOGMASKED(LOG_TIMEBASE, "%s:sunplus_gcm394_base_device::timebasec_ctrl_w %04x\n", machine().describe_context(), data);
-
- if (data & 0x8000)
- {
- m_timebasec_ctrl = data & 0x7fff;
- m_updateirqs_cb(1);
- }
- else
- {
- m_timebasec_ctrl = data;
- }
-
- if ((m_timebasec_ctrl & 0x6000) == 0x6000)
- {
- switch (m_timebasec_ctrl & 0x0003)
- {
- case 0x00: m_timebase_c->adjust(attotime::from_hz(128)); break;
- case 0x01: m_timebase_c->adjust(attotime::from_hz(256)); break;
- case 0x02: m_timebase_c->adjust(attotime::from_hz(512)); break;
- case 0x03: m_timebase_c->adjust(attotime::from_hz(1024)); break;
- }
- }
- else
- {
- m_timebase_c->adjust(attotime::never);
+ m_timebasetimer[Timer]->adjust(attotime::never);
}
}
@@ -200,9 +115,17 @@ void gpl_timebase_device::timebase_reset_w(u16 data)
m_timebase_reset = data;
}
+u16 gpl_timebase_device::timebasea_ctrl_r() { return timebase_ctrl_r<0>(); }
+u16 gpl_timebase_device::timebaseb_ctrl_r() { return timebase_ctrl_r<1>(); }
+u16 gpl_timebase_device::timebasec_ctrl_r() { return timebase_ctrl_r<2>(); }
+
+void gpl_timebase_device::timebasea_ctrl_w(u16 data) { timebase_ctrl_w<0>(data); }
+void gpl_timebase_device::timebaseb_ctrl_w(u16 data) { timebase_ctrl_w<1>(data); }
+void gpl_timebase_device::timebasec_ctrl_w(u16 data) { timebase_ctrl_w<2>(data); }
+
void gpl_timebase_device::device_add_mconfig(machine_config &config)
{
- TIMER(config, "timebase_a").configure_generic(FUNC(gpl_timebase_device::timebase_a_cb));
- TIMER(config, "timebase_b").configure_generic(FUNC(gpl_timebase_device::timebase_b_cb));
- TIMER(config, "timebase_c").configure_generic(FUNC(gpl_timebase_device::timebase_c_cb));
+ TIMER(config, "timebase_a").configure_generic(FUNC(gpl_timebase_device::timebase_cb<0>));
+ TIMER(config, "timebase_b").configure_generic(FUNC(gpl_timebase_device::timebase_cb<1>));
+ TIMER(config, "timebase_c").configure_generic(FUNC(gpl_timebase_device::timebase_cb<2>));
}