summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit0f205b5db472ee6e3743ec96605ad57f02818b50 (patch)
tree8bc95b00bc6e6e00268dad15a9192ad7f7800433
parentdf10451c060e484bea606009e248c58a82309c56 (diff)
mc146818: improve update in progress handling
-rw-r--r--src/devices/machine/mc146818.cpp54
-rw-r--r--src/devices/machine/mc146818.h13
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