diff options
author | Patrick Mackinlay <pmackinlay@hotmail.com> | 2021-03-25 13:21:29 +0700 |
---|---|---|
committer | Patrick Mackinlay <pmackinlay@hotmail.com> | 2021-03-25 13:21:29 +0700 |
commit | 0f205b5db472ee6e3743ec96605ad57f02818b50 (patch) | |
tree | 8bc95b00bc6e6e00268dad15a9192ad7f7800433 | |
parent | df10451c060e484bea606009e248c58a82309c56 (diff) |
mc146818: improve update in progress handling
-rw-r--r-- | src/devices/machine/mc146818.cpp | 54 | ||||
-rw-r--r-- | src/devices/machine/mc146818.h | 13 |
2 files changed, 51 insertions, 16 deletions
diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp index cbce9ced926..c7597a2fbea 100644 --- a/src/devices/machine/mc146818.cpp +++ b/src/devices/machine/mc146818.cpp @@ -22,6 +22,7 @@ // device type definition DEFINE_DEVICE_TYPE(MC146818, mc146818_device, "mc146818", "MC146818 RTC") +DEFINE_DEVICE_TYPE(DS1287, ds1287_device, "ds1287", "DS1287 RTC") //------------------------------------------------- // mc146818_device - constructor @@ -30,6 +31,21 @@ DEFINE_DEVICE_TYPE(MC146818, mc146818_device, "mc146818", "MC146818 RTC") mc146818_device::mc146818_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : mc146818_device(mconfig, MC146818, tag, owner, clock) { + switch (clock) + { + case 4'194'304: + case 1'048'576: + m_tuc = 248; + break; + case 32'768: + m_tuc = 1984; + break; + } +} + +ds1287_device::ds1287_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mc146818_device(mconfig, DS1287, tag, owner, clock) +{ } mc146818_device::mc146818_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) @@ -37,7 +53,7 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type device_nvram_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_index(0), - m_last_refresh(attotime::zero), m_clock_timer(nullptr), m_periodic_timer(nullptr), + m_clock_timer(nullptr), m_update_timer(nullptr), m_periodic_timer(nullptr), m_write_irq(*this), m_write_sqw(*this), m_century_index(-1), @@ -46,7 +62,8 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type m_binary(false), m_hour(false), m_binyear(false), - m_sqw_state(false) + m_sqw_state(false), + m_tuc(0) { } @@ -57,8 +74,8 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type void mc146818_device::device_start() { m_data = make_unique_clear<uint8_t[]>(data_size()); - m_last_refresh = machine().time(); m_clock_timer = timer_alloc(TIMER_CLOCK); + m_update_timer = timer_alloc(TIMER_UPDATE); m_periodic_timer = timer_alloc(TIMER_PERIODIC); m_write_irq.resolve_safe(); @@ -111,6 +128,15 @@ void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int par case TIMER_CLOCK: if (!(m_data[REG_B] & REG_B_SET)) { + m_data[REG_A] |= REG_A_UIP; + + m_update_timer->adjust(attotime::from_usec(244)); + } + break; + + case TIMER_UPDATE: + if (!param) + { /// TODO: find out how the real chip deals with updates when binary/bcd values are already outside the normal range int seconds = get_seconds() + 1; if (seconds < 60) @@ -195,12 +221,19 @@ void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int par m_data[REG_C] |= REG_C_AF; } - // set the update-ended interrupt Flag UF - m_data[REG_C] |= REG_C_UF; - update_irq(); - - m_last_refresh = machine().time(); + // defer the update end sequence if update cycle time is non-zero + if (m_tuc) + { + m_update_timer->adjust(attotime::from_usec(m_tuc), 1); + break; + } } + + // clear update in progress and set update ended + m_data[REG_A] &= ~REG_A_UIP; + m_data[REG_C] |= REG_C_UF; + + update_irq(); break; } } @@ -627,11 +660,6 @@ uint8_t mc146818_device::internal_read(offs_t offset) { case REG_A: data = m_data[REG_A]; - // Update In Progress (UIP) time for 32768 Hz is 244+1984usec - /// TODO: support other dividers - /// TODO: don't set this if update is stopped - if ((machine().time() - m_last_refresh) < attotime::from_usec(244+1984)) - data |= REG_A_UIP; break; case REG_C: diff --git a/src/devices/machine/mc146818.h b/src/devices/machine/mc146818.h index 83d45292dbc..96acaa7fc62 100644 --- a/src/devices/machine/mc146818.h +++ b/src/devices/machine/mc146818.h @@ -157,12 +157,12 @@ protected: uint8_t m_index; std::unique_ptr<uint8_t[]> m_data; - attotime m_last_refresh; - static const device_timer_id TIMER_CLOCK = 0; - static const device_timer_id TIMER_PERIODIC = 1; + static const device_timer_id TIMER_UPDATE = 1; + static const device_timer_id TIMER_PERIODIC = 2; emu_timer *m_clock_timer; + emu_timer *m_update_timer; emu_timer *m_periodic_timer; devcb_write_line m_write_irq; @@ -170,10 +170,17 @@ protected: int m_century_index, m_epoch; bool m_use_utc, m_binary, m_hour, m_binyear; bool m_sqw_state; + unsigned m_tuc; // update cycle time }; +class ds1287_device : public mc146818_device +{ +public: + ds1287_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; // device type definition DECLARE_DEVICE_TYPE(MC146818, mc146818_device) +DECLARE_DEVICE_TYPE(DS1287, ds1287_device) #endif // MAME_MACHINE_MC146818_H |