From 1f93af5dafb8b7abc52a97128a28b693647b4546 Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 3 Feb 2023 22:01:15 -0500 Subject: RTC interface updates - dp8573, mc146818, mm58274c, rtc65271, s3520cf, smpc, timekpr: Use device_rtc_interface to acquire base time - device_rtc_interface: Add machine configuration option for synchronizing to UTC instead of local time (was previously only an option for mc146818, and always enabled for dp8573) - mc146818: Eliminate the set_binary_time configuration parameter - mm58274c: Correct operator precedence in calculating m_clk_set; allow disabling side effects of status read --- src/devices/machine/dp8573.cpp | 23 +++++------- src/devices/machine/dp8573.h | 10 ++++- src/devices/machine/mc146818.cpp | 44 +++++++++------------- src/devices/machine/mc146818.h | 17 +++++---- src/devices/machine/mm58274c.cpp | 54 +++++++++++++-------------- src/devices/machine/mm58274c.h | 10 ++++- src/devices/machine/rtc65271.cpp | 79 ++++++++++++++++++++-------------------- src/devices/machine/rtc65271.h | 11 +++++- src/devices/machine/s3520cf.cpp | 23 ++++++------ src/devices/machine/s3520cf.h | 10 ++++- src/devices/machine/smpc.cpp | 28 ++++++++------ src/devices/machine/smpc.h | 9 ++++- src/devices/machine/timekpr.cpp | 25 +++++++------ src/devices/machine/timekpr.h | 9 ++++- src/emu/dirtc.cpp | 6 ++- src/emu/dirtc.h | 5 +++ src/mame/sgi/4dpi.cpp | 2 +- src/mame/sgi/hpc1.cpp | 2 +- src/mame/siemens/pcd.cpp | 1 - 19 files changed, 205 insertions(+), 163 deletions(-) diff --git a/src/devices/machine/dp8573.cpp b/src/devices/machine/dp8573.cpp index f862bec4deb..032be31038b 100644 --- a/src/devices/machine/dp8573.cpp +++ b/src/devices/machine/dp8573.cpp @@ -23,6 +23,7 @@ DEFINE_DEVICE_TYPE(DP8573, dp8573_device, "dp8573", "DP8573 Real-Time Clock") dp8573_device::dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, DP8573, tag, owner, clock) , device_nvram_interface(mconfig, *this) + , device_rtc_interface(mconfig, *this) , m_intr_cb(*this) , m_mfo_cb(*this) { @@ -42,27 +43,23 @@ void dp8573_device::device_start() m_mfo_cb.resolve_safe(); memset(m_ram, 0, 32); - sync_time(); m_tscr = 0; m_timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1)); } -void dp8573_device::sync_time() +void dp8573_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) { - system_time systime; - machine().base_datetime(systime); - m_millis = 0; m_ram[REG_HUNDREDTH] = 0; - m_ram[REG_SECOND] = time_helper::make_bcd(systime.utc_time.second); - m_ram[REG_MINUTE] = time_helper::make_bcd(systime.utc_time.minute); - m_ram[REG_HOUR] = time_helper::make_bcd(systime.utc_time.hour); - m_ram[REG_DAY] = time_helper::make_bcd(systime.utc_time.mday); - m_ram[REG_MONTH] = time_helper::make_bcd(systime.utc_time.month + 1); - m_ram[REG_YEAR] = time_helper::make_bcd(systime.utc_time.year % 100); - m_ram[REG_DAYOFWEEK] = time_helper::make_bcd(systime.utc_time.weekday + 1); + m_ram[REG_SECOND] = time_helper::make_bcd(second); + m_ram[REG_MINUTE] = time_helper::make_bcd(minute); + m_ram[REG_HOUR] = time_helper::make_bcd(hour); + m_ram[REG_DAY] = time_helper::make_bcd(day); + m_ram[REG_MONTH] = time_helper::make_bcd(month); + m_ram[REG_YEAR] = time_helper::make_bcd(year); + m_ram[REG_DAYOFWEEK] = time_helper::make_bcd(day_of_week); m_pfr = 0; @@ -343,7 +340,6 @@ u8 dp8573_device::read(offs_t offset) void dp8573_device::nvram_default() { memset(m_ram, 0, 32); - sync_time(); } bool dp8573_device::nvram_read(util::read_stream &file) @@ -352,7 +348,6 @@ bool dp8573_device::nvram_read(util::read_stream &file) if (file.read(m_ram, 32, actual) || actual != 32) return false; - sync_time(); return true; } diff --git a/src/devices/machine/dp8573.h b/src/devices/machine/dp8573.h index 1730884e1b4..7cc873d47d1 100644 --- a/src/devices/machine/dp8573.h +++ b/src/devices/machine/dp8573.h @@ -11,7 +11,9 @@ #pragma once -class dp8573_device : public device_t, public device_nvram_interface +#include "dirtc.h" + +class dp8573_device : public device_t, public device_nvram_interface, public device_rtc_interface { public: dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner) @@ -37,7 +39,11 @@ protected: virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; - void sync_time(); + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return false; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + void save_registers(); void set_interrupt(uint8_t mask); void clear_interrupt(uint8_t mask); diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp index c5cabdfd528..f1b7ffa97a0 100644 --- a/src/devices/machine/mc146818.cpp +++ b/src/devices/machine/mc146818.cpp @@ -52,6 +52,7 @@ ds1287_device::ds1287_device(const machine_config &mconfig, const char *tag, dev mc146818_device::mc146818_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), device_nvram_interface(mconfig, *this), + device_rtc_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_index(0), m_clock_timer(nullptr), @@ -61,10 +62,8 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type m_write_sqw(*this), m_century_index(-1), m_epoch(0), - m_use_utc(false), m_binary(false), m_hour(false), - m_binyear(false), m_sqw_state(false), m_tuc(0) { @@ -265,7 +264,6 @@ void mc146818_device::nvram_default() if(m_hour) m_data[REG_B] |= REG_B_24_12; - set_base_datetime(); update_timer(); update_irq(); } @@ -283,7 +281,6 @@ bool mc146818_device::nvram_read(util::read_stream &file) if (file.read(&m_data[0], size, actual) || actual != size) return false; - set_base_datetime(); update_timer(); update_irq(); @@ -454,36 +451,29 @@ void mc146818_device::set_century(int century) //------------------------------------------------- -// set_base_datetime - update clock with real time +// rtc_clock_updated - update clock with real time //------------------------------------------------- -void mc146818_device::set_base_datetime() +void mc146818_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) { - system_time systime; - system_time::full_time current_time; - - machine().base_datetime(systime); - - current_time = (m_use_utc) ? systime.utc_time: systime.local_time; - // logerror("mc146818_set_base_datetime %02d/%02d/%02d %02d:%02d:%02d\n", -// current_time.year % 100, current_time.month + 1, current_time.mday, -// current_time.hour,current_time.minute, current_time.second); - - set_seconds(current_time.second); - set_minutes(current_time.minute); - set_hours(current_time.hour); - set_dayofweek(current_time.weekday + 1); - set_dayofmonth(current_time.mday); - set_month(current_time.month + 1); - - if(m_binyear) - set_year((current_time.year - m_epoch) % (m_data[REG_B] & REG_B_DM ? 0x100 : 100)); // pcd actually depends on this +// year, month, day, +// hour, minute, second); + + set_seconds(second); + set_minutes(minute); + set_hours(hour); + set_dayofweek(day_of_week); + set_dayofmonth(day); + set_month(month); + + if (m_epoch != 0) + set_year((year - m_epoch) % (m_data[REG_B] & REG_B_DM ? 0x100 : 100)); // pcd actually depends on this else - set_year((current_time.year - m_epoch) % 100); + set_year(year % 100); if (m_century_index >= 0) - set_century(current_time.year / 100); + set_century(year / 100); } diff --git a/src/devices/machine/mc146818.h b/src/devices/machine/mc146818.h index 44eb0a54337..b352c2894e8 100644 --- a/src/devices/machine/mc146818.h +++ b/src/devices/machine/mc146818.h @@ -16,9 +16,12 @@ #pragma once +#include "dirtc.h" + class mc146818_device : public device_t, - public device_nvram_interface + public device_nvram_interface, + public device_rtc_interface { public: // construction/destruction @@ -31,13 +34,9 @@ public: // The MC146818 doesn't have century support (some variants do), but when syncing the date & time at startup we can optionally store the century. void set_century_index(int century_index) { assert(!century_count_enabled()); m_century_index = century_index; } - // The MC146818 doesn't have UTC support, but when syncing the data & time at startup we can use UTC instead of local time. - void set_use_utc(bool use_utc) { m_use_utc = use_utc; } - void set_binary(bool binary) { m_binary = binary; } void set_24hrs(bool hour) { m_hour = hour; } void set_epoch(int epoch) { m_epoch = epoch; } - void set_binary_year(int bin) { m_binyear = bin; } // read/write access uint8_t read(offs_t offset); @@ -59,6 +58,11 @@ protected: virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return m_epoch != 0 || m_century_index >= 0; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + static constexpr unsigned char ALARM_DONTCARE = 0xc0; static constexpr unsigned char HOURS_PM = 0x80; @@ -132,7 +136,6 @@ protected: // internal helpers int to_ram(int a) const; int from_ram(int a) const; - void set_base_datetime(); void update_irq(); void update_timer(); virtual int get_timer_bypass() const; @@ -167,7 +170,7 @@ protected: devcb_write_line m_write_irq; devcb_write_line m_write_sqw; int m_century_index, m_epoch; - bool m_use_utc, m_binary, m_hour, m_binyear; + bool m_binary, m_hour; bool m_sqw_state; unsigned m_tuc; // update cycle time }; diff --git a/src/devices/machine/mm58274c.cpp b/src/devices/machine/mm58274c.cpp index cfc50472653..cc054767a73 100644 --- a/src/devices/machine/mm58274c.cpp +++ b/src/devices/machine/mm58274c.cpp @@ -49,6 +49,7 @@ DEFINE_DEVICE_TYPE(MM58274C, mm58274c_device, "mm58274c", "National Semiconducto mm58274c_device::mm58274c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MM58274C, tag, owner, clock) + , device_rtc_interface(mconfig, *this) , m_mode24(0) , m_day1(0) { @@ -65,6 +66,9 @@ void mm58274c_device::device_start() m_increment_rtc->adjust(attotime::zero, 0, attotime::from_msec(100)); m_interrupt_timer = timer_alloc(FUNC(mm58274c_device::rtc_interrupt_cb), this); + m_status = 0; + m_control = 0; + // register for state saving save_item(NAME(m_mode24)); save_item(NAME(m_day1)); @@ -90,48 +94,41 @@ void mm58274c_device::device_start() } //------------------------------------------------- -// device_reset - device-specific reset +// rtc_clock_updated - update clock with real time //------------------------------------------------- -void mm58274c_device::device_reset() +void mm58274c_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) { - system_time systime; - - /* get the current date/time from the core */ - machine().current_datetime(systime); - - m_clk_set = systime.local_time.year & 3 << 2; + m_clk_set = (year & 3) << 2; if (m_mode24) m_clk_set |= clk_set_24; /* The clock count starts on 1st January 1900 */ - m_wday = 1 + ((systime.local_time.weekday - m_day1) % 7); - m_years1 = (systime.local_time.year / 10) % 10; - m_years2 = systime.local_time.year % 10; - m_months1 = (systime.local_time.month + 1) / 10; - m_months2 = (systime.local_time.month + 1) % 10; - m_days1 = systime.local_time.mday / 10; - m_days2 = systime.local_time.mday % 10; + m_wday = 1 + ((day_of_week - 1 - m_day1 + 7) % 7); + m_years1 = (year / 10) % 10; + m_years2 = year % 10; + m_months1 = month / 10; + m_months2 = month % 10; + m_days1 = day / 10; + m_days2 = day % 10; if (!m_mode24) { /* 12-hour mode */ - if (systime.local_time.hour > 12) + if (hour > 12) { - systime.local_time.hour -= 12; + hour -= 12; m_clk_set |= clk_set_pm; } - if (systime.local_time.hour == 0) - systime.local_time.hour = 12; + if (hour == 0) + hour = 12; } - m_hours1 = systime.local_time.hour / 10; - m_hours2 = systime.local_time.hour % 10; - m_minutes1 = systime.local_time.minute / 10; - m_minutes2 = systime.local_time.minute % 10; - m_seconds1 = systime.local_time.second / 10; - m_seconds2 = systime.local_time.second % 10; + m_hours1 = hour / 10; + m_hours2 = hour % 10; + m_minutes1 = minute / 10; + m_minutes2 = minute % 10; + m_seconds1 = second / 10; + m_seconds2 = second % 10; m_tenths = 0; - m_status = 0; - m_control = 0; } @@ -162,7 +159,8 @@ uint8_t mm58274c_device::read(offs_t offset) { case 0x00: /* Control Register */ reply = m_status; - m_status = 0; + if (!machine().side_effects_disabled()) + m_status = 0; break; case 0x01: /* Tenths of Seconds */ diff --git a/src/devices/machine/mm58274c.h b/src/devices/machine/mm58274c.h index c6fcbee3c46..4f2d302a204 100644 --- a/src/devices/machine/mm58274c.h +++ b/src/devices/machine/mm58274c.h @@ -3,11 +3,13 @@ #ifndef MAME_MACHINE_MM58274C_H #define MAME_MACHINE_MM58274C_H +#include "dirtc.h" + /*************************************************************************** MACROS ***************************************************************************/ -class mm58274c_device : public device_t +class mm58274c_device : public device_t, public device_rtc_interface { public: mm58274c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -25,7 +27,11 @@ public: protected: // device-level overrides virtual void device_start() override; - virtual void device_reset() override; + + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return false; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; private: // internal state diff --git a/src/devices/machine/rtc65271.cpp b/src/devices/machine/rtc65271.cpp index dc7aad8d210..424c3e8ace4 100644 --- a/src/devices/machine/rtc65271.cpp +++ b/src/devices/machine/rtc65271.cpp @@ -219,50 +219,50 @@ bool rtc65271_device::nvram_read(util::read_stream &file) m_regs[reg_D] |= reg_D_VRT; /* the data was backed up successfully */ /*m_dirty = false;*/ - { - system_time systime; - - /* get the current date/time from the core */ - machine().current_datetime(systime); + return true; +} - /* set clock registers */ - m_regs[reg_second] = systime.local_time.second; - m_regs[reg_minute] = systime.local_time.minute; - if (m_regs[reg_B] & reg_B_24h) - /* 24-hour mode */ - m_regs[reg_hour] = systime.local_time.hour; - else - { /* 12-hour mode */ - if (systime.local_time.hour >= 12) - { - m_regs[reg_hour] = 0x80; - systime.local_time.hour -= 12; - } - else - { - m_regs[reg_hour] = 0; - } +//------------------------------------------------- +// rtc_clock_updated - update clock with real time +//------------------------------------------------- - // Firebeat indicates non-BCD 12-hour mode has 0-based hour, so 12 AM is 0x00 and 12 PM is 0x80 - m_regs[reg_hour] |= systime.local_time.hour; // ? systime.local_time.hour : 12; +void rtc65271_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + /* set clock registers */ + m_regs[reg_second] = second; + m_regs[reg_minute] = minute; + if (m_regs[reg_B] & reg_B_24h) + /* 24-hour mode */ + m_regs[reg_hour] = hour; + else + { /* 12-hour mode */ + if (hour >= 12) + { + m_regs[reg_hour] = 0x80; + hour -= 12; } - m_regs[reg_weekday] = systime.local_time.weekday + 1; - m_regs[reg_monthday] = systime.local_time.mday; - m_regs[reg_month] = systime.local_time.month + 1; - m_regs[reg_year] = systime.local_time.year % 100; - if (! (m_regs[reg_B] & reg_B_DM)) - { /* BCD mode */ - m_regs[reg_second] = binary_to_BCD(m_regs[reg_second]); - m_regs[reg_minute] = binary_to_BCD(m_regs[reg_minute]); - m_regs[reg_hour] = (m_regs[reg_hour] & 0x80) | binary_to_BCD(m_regs[reg_hour] & 0x7f); - /*m_regs[reg_weekday] = binary_to_BCD(m_regs[reg_weekday]);*/ - m_regs[reg_monthday] = binary_to_BCD(m_regs[reg_monthday]); - m_regs[reg_month] = binary_to_BCD(m_regs[reg_month]); - m_regs[reg_year] = binary_to_BCD(m_regs[reg_year]); + else + { + m_regs[reg_hour] = 0; } - } - return true; + // Firebeat indicates non-BCD 12-hour mode has 0-based hour, so 12 AM is 0x00 and 12 PM is 0x80 + m_regs[reg_hour] |= hour; // ? hour : 12; + } + m_regs[reg_weekday] = day_of_week; + m_regs[reg_monthday] = day; + m_regs[reg_month] = month; + m_regs[reg_year] = year % 100; + if (! (m_regs[reg_B] & reg_B_DM)) + { /* BCD mode */ + m_regs[reg_second] = binary_to_BCD(m_regs[reg_second]); + m_regs[reg_minute] = binary_to_BCD(m_regs[reg_minute]); + m_regs[reg_hour] = (m_regs[reg_hour] & 0x80) | binary_to_BCD(m_regs[reg_hour] & 0x7f); + /*m_regs[reg_weekday] = binary_to_BCD(m_regs[reg_weekday]);*/ + m_regs[reg_monthday] = binary_to_BCD(m_regs[reg_monthday]); + m_regs[reg_month] = binary_to_BCD(m_regs[reg_month]); + m_regs[reg_year] = binary_to_BCD(m_regs[reg_year]); + } } //------------------------------------------------- @@ -672,6 +672,7 @@ DEFINE_DEVICE_TYPE(RTC65271, rtc65271_device, "rtc65271", "Epson RTC-65271 RTC") rtc65271_device::rtc65271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, RTC65271, tag, owner, clock) , device_nvram_interface(mconfig, *this) + , device_rtc_interface(mconfig, *this) , m_interrupt_cb(*this) , m_default_data(*this, DEVICE_SELF) { diff --git a/src/devices/machine/rtc65271.h b/src/devices/machine/rtc65271.h index a3d77bf3fa9..d19b6ee36f2 100644 --- a/src/devices/machine/rtc65271.h +++ b/src/devices/machine/rtc65271.h @@ -9,11 +9,14 @@ #pragma once +#include "dirtc.h" + // ======================> rtc65271_device class rtc65271_device : public device_t, - public device_nvram_interface + public device_nvram_interface, + public device_rtc_interface { public: // construction/destruction @@ -34,11 +37,17 @@ public: protected: // device-level overrides virtual void device_start() override; + // device_nvram_interface overrides virtual void nvram_default() override; virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return false; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + private: void field_interrupts(); diff --git a/src/devices/machine/s3520cf.cpp b/src/devices/machine/s3520cf.cpp index 86676ca3d2b..2466c1ee69f 100644 --- a/src/devices/machine/s3520cf.cpp +++ b/src/devices/machine/s3520cf.cpp @@ -44,6 +44,7 @@ s3520cf_device::s3520cf_device(const machine_config &mconfig, const char *tag, d s3520cf_device::s3520cf_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) , device_nvram_interface(mconfig, *this) + , device_rtc_interface(mconfig, *this) , m_region(*this, DEVICE_SELF) , m_dir(0), m_latch(0), m_reset_line(0), m_read_latch(0), m_bitstream(0), m_stream_pos(0), m_mode(0), m_sysr(0), m_cntrl1(0), m_cntrl2(0) { @@ -108,17 +109,6 @@ void s3520cf_device::device_start() m_timer = timer_alloc(FUNC(s3520cf_device::timer_callback), this); m_timer->adjust(attotime::from_hz(clock() / XTAL(32'768)), 0, attotime::from_hz(clock() / XTAL(32'768))); - system_time systime; - machine().base_datetime(systime); - - m_rtc.day = ((systime.local_time.mday / 10)<<4) | ((systime.local_time.mday % 10) & 0xf); - m_rtc.month = (((systime.local_time.month+1) / 10) << 4) | (((systime.local_time.month+1) % 10) & 0xf); - m_rtc.wday = systime.local_time.weekday; - m_rtc.year = (((systime.local_time.year % 100)/10)<<4) | ((systime.local_time.year % 10) & 0xf); - m_rtc.hour = ((systime.local_time.hour / 10)<<4) | ((systime.local_time.hour % 10) & 0xf); - m_rtc.min = ((systime.local_time.minute / 10)<<4) | ((systime.local_time.minute % 10) & 0xf); - m_rtc.sec = ((systime.local_time.second / 10)<<4) | ((systime.local_time.second % 10) & 0xf); - save_item(NAME(m_dir)); save_item(NAME(m_latch)); save_item(NAME(m_reset_line)); @@ -189,6 +179,17 @@ bool s3520cf_device::nvram_write(util::write_stream &file) return !file.write(m_nvdata, 15, actual) && actual == 15; } +void s3520cf_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_rtc.day = ((day / 10)<<4) | ((day % 10) & 0xf); + m_rtc.month = ((month / 10) << 4) | ((month % 10) & 0xf); + m_rtc.wday = day_of_week - 1; + m_rtc.year = (((year % 100)/10)<<4) | ((year % 10) & 0xf); + m_rtc.hour = ((hour / 10)<<4) | ((hour % 10) & 0xf); + m_rtc.min = ((minute / 10)<<4) | ((minute % 10) & 0xf); + m_rtc.sec = ((second / 10)<<4) | ((second % 10) & 0xf); +} + //------------------------------------------------- // rtc_read - used to route RTC reading registers //------------------------------------------------- diff --git a/src/devices/machine/s3520cf.h b/src/devices/machine/s3520cf.h index 5c8f0c8614b..a7343290c79 100644 --- a/src/devices/machine/s3520cf.h +++ b/src/devices/machine/s3520cf.h @@ -11,6 +11,8 @@ Seiko/Epson S-3520CF #pragma once +#include "dirtc.h" + //************************************************************************** // TYPE DEFINITIONS @@ -19,7 +21,8 @@ Seiko/Epson S-3520CF // ======================> s3520cf_device class s3520cf_device : public device_t, - public device_nvram_interface + public device_nvram_interface, + public device_rtc_interface { public: // construction/destruction @@ -51,6 +54,11 @@ protected: virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return false; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + optional_memory_region m_region; inline u8 rtc_read(u8 offset); diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp index 7161d97b7f9..ddbe8d6aaab 100644 --- a/src/devices/machine/smpc.cpp +++ b/src/devices/machine/smpc.cpp @@ -205,6 +205,7 @@ void smpc_hle_device::smpc_regs(address_map &map) smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SMPC_HLE, tag, owner, clock) , device_memory_interface(mconfig, *this) + , device_rtc_interface(mconfig, *this) , m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(smpc_hle_device::smpc_regs), this)) , m_mini_nvram(*this, "smem") , m_mshres(*this) @@ -244,9 +245,6 @@ void smpc_hle_device::device_add_mconfig(machine_config &config) void smpc_hle_device::device_start() { - system_time systime; - machine().base_datetime(systime); - // check if SMEM has valid data via byte 4 in the array, if not then simulate a battery backup fail // (-> call the RTC / Language select menu for Saturn) m_mini_nvram->set_base(&m_smem, 5); @@ -289,14 +287,6 @@ void smpc_hle_device::device_start() m_rtc_timer = timer_alloc(FUNC(smpc_hle_device::handle_rtc_increment), this); m_intback_timer = timer_alloc(FUNC(smpc_hle_device::intback_continue_request), this); m_sndres_timer = timer_alloc(FUNC(smpc_hle_device::sound_reset), this); - - m_rtc_data[0] = DectoBCD(systime.local_time.year / 100); - m_rtc_data[1] = DectoBCD(systime.local_time.year % 100); - m_rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); - m_rtc_data[3] = DectoBCD(systime.local_time.mday); - m_rtc_data[4] = DectoBCD(systime.local_time.hour); - m_rtc_data[5] = DectoBCD(systime.local_time.minute); - m_rtc_data[6] = DectoBCD(systime.local_time.second); } @@ -328,6 +318,22 @@ void smpc_hle_device::device_reset() m_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } + +//------------------------------------------------- +// rtc_clock_updated - update clock with real time +//------------------------------------------------- + +void smpc_hle_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_rtc_data[0] = DectoBCD(year / 100); + m_rtc_data[1] = DectoBCD(year % 100); + m_rtc_data[2] = ((day_of_week - 1) << 4) | month; + m_rtc_data[3] = DectoBCD(day); + m_rtc_data[4] = DectoBCD(hour); + m_rtc_data[5] = DectoBCD(minute); + m_rtc_data[6] = DectoBCD(second); +} + device_memory_interface::space_config_vector smpc_hle_device::memory_space_config() const { return space_config_vector { diff --git a/src/devices/machine/smpc.h b/src/devices/machine/smpc.h index 60b461b6ad3..26f43176a7d 100644 --- a/src/devices/machine/smpc.h +++ b/src/devices/machine/smpc.h @@ -14,6 +14,7 @@ #include "screen.h" #include "bus/sat_ctrl/ctrl.h" #include "machine/nvram.h" +#include "dirtc.h" //************************************************************************** @@ -23,7 +24,8 @@ // ======================> smpc_hle_device class smpc_hle_device : public device_t, - public device_memory_interface + public device_memory_interface, + public device_rtc_interface { public: // construction/destruction @@ -88,6 +90,11 @@ protected: virtual void device_reset() override; virtual space_config_vector memory_space_config() const override; + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return true; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + private: const address_space_config m_space_config; diff --git a/src/devices/machine/timekpr.cpp b/src/devices/machine/timekpr.cpp index 5825aa72100..c3bbf6211cd 100644 --- a/src/devices/machine/timekpr.cpp +++ b/src/devices/machine/timekpr.cpp @@ -91,6 +91,7 @@ inline int counter_from_ram(u8 const *data, s32 offset, u8 unmap = 0) timekeeper_device::timekeeper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size) : device_t(mconfig, type, tag, owner, clock) , device_nvram_interface(mconfig, *this) + , device_rtc_interface(mconfig, *this) , m_reset_cb(*this) , m_irq_cb(*this) , m_default_data(*this, DEVICE_SELF) @@ -200,19 +201,7 @@ mk48t12_device::mk48t12_device(const machine_config &mconfig, const char *tag, d void timekeeper_device::device_start() { - system_time systime; - - machine().base_datetime(systime); - m_control = 0; - m_seconds = time_helper::make_bcd(systime.local_time.second); - m_minutes = time_helper::make_bcd(systime.local_time.minute); - m_hours = time_helper::make_bcd(systime.local_time.hour); - m_day = time_helper::make_bcd(systime.local_time.weekday + 1); - m_date = time_helper::make_bcd(systime.local_time.mday); - m_month = time_helper::make_bcd(systime.local_time.month + 1); - m_year = time_helper::make_bcd(systime.local_time.year % 100); - m_century = time_helper::make_bcd(systime.local_time.year / 100); m_data.resize(m_size); save_item(NAME(m_control)); @@ -244,6 +233,18 @@ void timekeeper_device::device_reset() { } +void timekeeper_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_seconds = time_helper::make_bcd(second); + m_minutes = time_helper::make_bcd(minute); + m_hours = time_helper::make_bcd(hour); + m_day = time_helper::make_bcd(day_of_week); + m_date = time_helper::make_bcd(day); + m_month = time_helper::make_bcd(month); + m_year = time_helper::make_bcd(year % 100); + m_century = time_helper::make_bcd(year / 100); +} + void timekeeper_device::counters_to_ram() { counter_to_ram(&m_data[0], m_offset_control, m_control); diff --git a/src/devices/machine/timekpr.h b/src/devices/machine/timekpr.h index 9d6d04fafb4..1db8f44faf8 100644 --- a/src/devices/machine/timekpr.h +++ b/src/devices/machine/timekpr.h @@ -19,7 +19,7 @@ #pragma once - +#include "dirtc.h" //************************************************************************** @@ -29,7 +29,7 @@ // ======================> timekeeper_device -class timekeeper_device : public device_t, public device_nvram_interface +class timekeeper_device : public device_t, public device_nvram_interface, public device_rtc_interface { public: void write(offs_t offset, u8 data); @@ -52,6 +52,11 @@ protected: virtual bool nvram_read(util::read_stream &file) override; virtual bool nvram_write(util::write_stream &file) override; + // device_rtc_interface overrides + virtual bool rtc_feature_y2k() const override { return m_offset_century != -1; } + virtual bool rtc_feature_leap_year() const override { return true; } + virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override; + TIMER_CALLBACK_MEMBER(timer_tick); TIMER_CALLBACK_MEMBER(watchdog_callback); devcb_write_line m_reset_cb; diff --git a/src/emu/dirtc.cpp b/src/emu/dirtc.cpp index f3c61dede01..bf1a9366578 100644 --- a/src/emu/dirtc.cpp +++ b/src/emu/dirtc.cpp @@ -30,6 +30,7 @@ static const int DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, device_rtc_interface::device_rtc_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "rtc") + , m_use_utc(false) { } @@ -78,8 +79,9 @@ void device_rtc_interface::set_time(bool update, int year, int month, int day, i void device_rtc_interface::set_current_time(const system_time &systime) { - set_time(true, systime.local_time.year, systime.local_time.month + 1, systime.local_time.mday, systime.local_time.weekday + 1, - systime.local_time.hour, systime.local_time.minute, systime.local_time.second); + const system_time::full_time &time = m_use_utc ? systime.utc_time : systime.local_time; + set_time(true, time.year, time.month + 1, time.mday, time.weekday + 1, + time.hour, time.minute, time.second); } diff --git a/src/emu/dirtc.h b/src/emu/dirtc.h index 89a08deb830..e76a8d3dba3 100644 --- a/src/emu/dirtc.h +++ b/src/emu/dirtc.h @@ -47,6 +47,9 @@ public: device_rtc_interface(const machine_config &mconfig, device_t &device); virtual ~device_rtc_interface(); + // use UTC instead of local time when syncing at startup + void set_use_utc(bool use_utc) { m_use_utc = use_utc; } + void set_time(bool update, int year, int month, int day, int day_of_week, int hour, int minute, int second); void set_current_time(const system_time &systime); @@ -72,6 +75,8 @@ protected: virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) = 0; int m_register[7]; + + bool m_use_utc; }; // iterator diff --git a/src/mame/sgi/4dpi.cpp b/src/mame/sgi/4dpi.cpp index 3899f737fe4..b49cd7016e0 100644 --- a/src/mame/sgi/4dpi.cpp +++ b/src/mame/sgi/4dpi.cpp @@ -664,7 +664,7 @@ void pi4d2x_state::common(machine_config &config) EEPROM_93C56_16BIT(config, m_eeprom); - DP8573(config, m_rtc); // DP8572AN + DP8573(config, m_rtc).set_use_utc(true); // DP8572AN PIT8254(config, m_pit); m_pit->set_clk<2>(3.6864_MHz_XTAL); diff --git a/src/mame/sgi/hpc1.cpp b/src/mame/sgi/hpc1.cpp index 8c60331dca9..84af54e244b 100644 --- a/src/mame/sgi/hpc1.cpp +++ b/src/mame/sgi/hpc1.cpp @@ -184,7 +184,7 @@ void hpc1_device::device_add_mconfig(machine_config &config) NSCSI_CONNECTOR(config, "scsibus:6", scsi_devices, nullptr, false); NSCSI_CONNECTOR(config, "scsibus:7", scsi_devices, nullptr, false); - DP8573(config, m_rtc); + DP8573(config, m_rtc).set_use_utc(true); PIT8254(config, m_pit, 0); m_pit->set_clk<0>(1000000); diff --git a/src/mame/siemens/pcd.cpp b/src/mame/siemens/pcd.cpp index 1f48b74e1d9..b32c23901da 100644 --- a/src/mame/siemens/pcd.cpp +++ b/src/mame/siemens/pcd.cpp @@ -529,7 +529,6 @@ void pcd_state::pcd(machine_config &config) MC146818(config, m_rtc, 32.768_kHz_XTAL); m_rtc->irq().set(m_pic1, FUNC(pic8259_device::ir7_w)); m_rtc->set_binary(true); - m_rtc->set_binary_year(true); m_rtc->set_epoch(1900); m_rtc->set_24hrs(true); -- cgit v1.2.3