summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/generalplus_gpl951xx_rtc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/generalplus_gpl951xx_rtc.cpp')
-rw-r--r--src/devices/machine/generalplus_gpl951xx_rtc.cpp114
1 files changed, 108 insertions, 6 deletions
diff --git a/src/devices/machine/generalplus_gpl951xx_rtc.cpp b/src/devices/machine/generalplus_gpl951xx_rtc.cpp
index da303406d4a..da0414f5f46 100644
--- a/src/devices/machine/generalplus_gpl951xx_rtc.cpp
+++ b/src/devices/machine/generalplus_gpl951xx_rtc.cpp
@@ -6,7 +6,7 @@
#define LOG_RTC (1U << 1)
-#define VERBOSE (0)
+#define VERBOSE (LOG_RTC)
#include "logmacro.h"
@@ -36,10 +36,6 @@ inline void gpl951xx_rtc_device::writebyte(offs_t address, uint8_t data)
space().write_byte(address, data);
}
-void gpl951xx_rtc_device::device_validity_check(validity_checker &valid) const
-{
-}
-
void gpl951xx_rtc_device::device_start()
{
save_item(NAME(m_rtc_addr));
@@ -48,6 +44,15 @@ void gpl951xx_rtc_device::device_start()
save_item(NAME(m_reg40));
save_item(NAME(m_reg50));
+
+ save_item(NAME(m_loadcnt));
+ save_item(NAME(m_alarmdat));
+ save_item(NAME(m_timerval));
+
+ // not on reset? (should be saved as NV?)
+ m_loadcnt = 0;
+ m_alarmdat = 0;
+ m_timerval = 0;
}
void gpl951xx_rtc_device::device_reset()
@@ -60,24 +65,75 @@ void gpl951xx_rtc_device::device_reset()
m_reg50 = 0;
}
+// Reg00
+//
+// 4 Rtcclken
+// 3 Rtcrst
+// 2 Timerdir
+// 1 SWreset
+// 0 Busy
+
u8 gpl951xx_rtc_device::reg00_r()
{
LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg00_r\n", machine().describe_context());
return 0x00;
}
+// Reg01
+//
+// 3 Slow_clk
+// 2 Reserved
+// 1 Strong
+// 0 Reserved
+
u8 gpl951xx_rtc_device::reg01_r()
{
LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg01_r\n", machine().describe_context());
return 0x01;
}
+// Reg02
+//
+// 'reliable'
+
+u8 gpl951xx_rtc_device::reg02_r()
+{
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg02_r\n", machine().describe_context());
+ return m_reg02;
+}
+
+void gpl951xx_rtc_device::reg02_w(u8 data)
+{
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg02_w %02x\n", machine().describe_context(), data);
+ m_reg02 = data;
+}
+
+// Reg40
+//
+// 3 HalfSecint
+// 2 Rtcwakeup
+// 1 Alarmint
+// 0 Secint
+
+u8 gpl951xx_rtc_device::reg40_r()
+{
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg40_r\n", machine().describe_context());
+ return m_reg40;
+}
+
void gpl951xx_rtc_device::reg40_w(u8 data)
{
LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg40_w %02x\n", machine().describe_context(), data);
m_reg40 = data;
}
+// Reg50
+//
+// 3 HalfSecint_en
+// 2 Rtcwakeup_en
+// 1 Alarmint_en
+// 0 Secint_en
+
u8 gpl951xx_rtc_device::reg50_r()
{
LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::reg50_r\n", machine().describe_context());
@@ -90,13 +146,49 @@ void gpl951xx_rtc_device::reg50_w(u8 data)
m_reg50 = data;
}
+void gpl951xx_rtc_device::loadcnt_w(offs_t offset, u8 data)
+{
+ u64 bits = (u64)0xff << (8 * offset);
+ u64 databits = (u64)data << (8 * offset);
+ m_loadcnt = m_loadcnt & ~bits;
+ m_loadcnt |= databits;
+
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::loadcnt_w (offset %02x) %02x (loadcnt is now %08x%08x)\n", machine().describe_context(), offset, data, (u32)(m_loadcnt >> 32), (u32)(m_loadcnt & 0xffffffff));
+
+ // TODO: not sure this is how it's reloaded
+ if (offset == 5)
+ m_timerval = m_loadcnt;
+}
+
+void gpl951xx_rtc_device::alarmdat_w(offs_t offset, u8 data)
+{
+ u64 bits = (u64)0xff << (8 * offset);
+ u64 databits = (u64)data << (8 * offset);
+ m_alarmdat = m_alarmdat & ~bits;
+ m_alarmdat |= databits;
+
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::alarmdat_w (offset %02x) %02x (alarmdat is now %08x%08x)\n", machine().describe_context(), offset, data, (u32)(m_loadcnt >> 32), (u32)(m_loadcnt & 0xffffffff));
+}
+
+u8 gpl951xx_rtc_device::timerval_r(offs_t offset)
+{
+ LOGMASKED(LOG_RTC, "%s: gpl951xx_rtc_device::timerval_r (offset %02x)\n", machine().describe_context(), offset);
+ return m_timerval >> (offset * 8);
+}
+
void gpl951xx_rtc_device::rtc_regs(address_map &map)
{
if (!has_configured_map(0))
{
map(0x00, 0x00).r(FUNC(gpl951xx_rtc_device::reg00_r));
map(0x01, 0x01).r(FUNC(gpl951xx_rtc_device::reg01_r));
- map(0x40, 0x40).w(FUNC(gpl951xx_rtc_device::reg40_w));
+ map(0x02, 0x02).rw(FUNC(gpl951xx_rtc_device::reg02_r), FUNC(gpl951xx_rtc_device::reg02_w));
+
+ map(0x10, 0x15).w(FUNC(gpl951xx_rtc_device::loadcnt_w));
+ map(0x20, 0x25).w(FUNC(gpl951xx_rtc_device::alarmdat_w));
+ map(0x30, 0x35).r(FUNC(gpl951xx_rtc_device::timerval_r));
+
+ map(0x40, 0x40).rw(FUNC(gpl951xx_rtc_device::reg40_r), FUNC(gpl951xx_rtc_device::reg40_w));
map(0x50, 0x50).rw(FUNC(gpl951xx_rtc_device::reg50_r), FUNC(gpl951xx_rtc_device::reg50_w));
// 0x80 - 0x8f reserved
map(0x90, 0xff).ram();
@@ -149,3 +241,13 @@ void gpl951xx_rtc_device::rtc_request_w(u16 data)
if (data & 2)
m_read_dat = readbyte(m_rtc_addr);
}
+
+TIMER_DEVICE_CALLBACK_MEMBER( gpl951xx_rtc_device::rtc_cb )
+{
+ m_timerval++;
+}
+
+void gpl951xx_rtc_device::device_add_mconfig(machine_config &config)
+{
+ TIMER(config, "rtc_timer").configure_periodic(FUNC(gpl951xx_rtc_device::rtc_cb), attotime::from_hz(32768));
+}