diff options
Diffstat (limited to 'src/devices/machine/generalplus_gpl951xx_rtc.cpp')
| -rw-r--r-- | src/devices/machine/generalplus_gpl951xx_rtc.cpp | 114 |
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)); +} |
