summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/msm58321.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/msm58321.cpp')
-rw-r--r--src/devices/machine/msm58321.cpp108
1 files changed, 67 insertions, 41 deletions
diff --git a/src/devices/machine/msm58321.cpp b/src/devices/machine/msm58321.cpp
index 97bd2a55f09..550645b5255 100644
--- a/src/devices/machine/msm58321.cpp
+++ b/src/devices/machine/msm58321.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Curt Coder
+// copyright-holders:Curt Coder,Sven Schnelle
/**********************************************************************
OKI MSM58321RS Real Time Clock/Calendar emulation
@@ -10,9 +10,7 @@
TODO:
- - leap year
- - test
- - reference registers
+ - non gregorian leap year
*/
@@ -105,21 +103,13 @@ inline int msm58321_device::read_counter(int counter)
{
data += (h10 & 3) * 10;
}
+ else if (h10 & H10_PM)
+ {
+ data += 12 + (h10 & 1) * 10;
+ }
else
{
data += (h10 & 1) * 10;
-
- if (h10 & H10_PM)
- {
- if (data != 12)
- {
- data += 12;
- }
- }
- else if (data == 12)
- {
- data = 0;
- }
}
}
else
@@ -139,8 +129,7 @@ inline void msm58321_device::write_counter(int address, int data)
{
int flag = 0;
- switch (address)
- {
+ switch (address) {
case REGISTER_H1:
flag = m_reg[REGISTER_H10] & H10_24;
if (!flag)
@@ -151,10 +140,8 @@ inline void msm58321_device::write_counter(int address, int data)
flag = H10_PM;
}
- if (data == 0)
- {
+ if ((m_reg[REGISTER_H10] & H10_PM) && data == 0)
data = 12;
- }
}
break;
@@ -200,9 +187,9 @@ msm58321_device::msm58321_device(const machine_config &mconfig, const char *tag,
m_stop(0),
m_test(0),
m_cs1(0),
- m_address(0xf)
+ m_address(0xf),
+ m_reg{}
{
- memset(m_reg, 0x00, sizeof(m_reg));
}
@@ -221,12 +208,16 @@ void msm58321_device::device_start()
// allocate timers
m_clock_timer = timer_alloc(TIMER_CLOCK);
- m_clock_timer->adjust(clocks_to_attotime(32768), 0, clocks_to_attotime(32768));
+ m_clock_timer->adjust(clocks_to_attotime(32768/1024), 0, clocks_to_attotime(32768/1024));
// busy signal active period is approximately 427 µs
m_busy_timer = timer_alloc(TIMER_BUSY);
m_busy_timer->adjust(clocks_to_attotime(32768 - 14), 0, clocks_to_attotime(32768));
+ // standard signal active period is approximately 122 µs
+ m_standard_timer = timer_alloc(TIMER_STANDARD);
+ m_standard_timer->adjust(clocks_to_attotime(32768-4), 0, clocks_to_attotime(32768));
+
// state saving
save_item(NAME(m_cs2));
save_item(NAME(m_write));
@@ -258,12 +249,29 @@ void msm58321_device::device_timer(emu_timer &timer, device_timer_id id, int par
switch (id)
{
case TIMER_CLOCK:
- if (!m_stop)
- advance_seconds();
- if (!m_busy)
+
+ if (m_khz_ctr & 1)
{
- m_busy = 1;
- m_busy_handler(m_busy);
+ m_reg[REGISTER_REF0] |= 1;
+ m_reg[REGISTER_REF1] |= 1;
+ } else {
+ m_reg[REGISTER_REF0] &= ~1;
+ m_reg[REGISTER_REF1] &= ~1;
+ }
+
+ if (++m_khz_ctr >= 1024)
+ {
+ m_khz_ctr = 0;
+ if (!m_stop)
+ {
+ advance_seconds();
+ }
+
+ if (!m_busy)
+ {
+ m_busy = 1;
+ m_busy_handler(m_busy);
+ }
}
break;
@@ -274,9 +282,29 @@ void msm58321_device::device_timer(emu_timer &timer, device_timer_id id, int par
m_busy_handler(m_busy);
}
break;
+ case TIMER_STANDARD:
+ m_reg[REGISTER_REF0] = 0x0e;
+ m_reg[REGISTER_REF1] = 0x0e;
+ break;
}
}
+void msm58321_device::update_standard()
+{
+ uint8_t reg = 0;
+
+ if (m_reg[REGISTER_S1] == 0)
+ reg |= 1 << 1;
+
+ if (m_reg[REGISTER_MI1] == 0)
+ reg |= 1 << 2;
+
+ if (m_reg[REGISTER_H1] == 0)
+ reg |= 1 << 3;
+
+ m_reg[REGISTER_REF0] = (reg ^ 0x0e) | (m_khz_ctr & 1);
+ m_reg[REGISTER_REF1] = m_reg[REGISTER_REF0];
+}
//-------------------------------------------------
// rtc_clock_updated -
@@ -291,7 +319,7 @@ void msm58321_device::rtc_clock_updated(int year, int month, int day, int day_of
write_counter(REGISTER_H1, hour);
write_counter(REGISTER_MI1, minute);
write_counter(REGISTER_S1, second);
-
+ update_standard();
update_output();
}
@@ -319,7 +347,7 @@ void msm58321_device::nvram_default()
void msm58321_device::nvram_read(emu_file &file)
{
- file.read(m_reg, sizeof(m_reg));
+ file.read(m_reg.data(), m_reg.size());
clock_updated();
}
@@ -332,7 +360,7 @@ void msm58321_device::nvram_read(emu_file &file)
void msm58321_device::nvram_write(emu_file &file)
{
- file.write(m_reg, sizeof(m_reg));
+ file.write(m_reg.data(), m_reg.size());
}
//-------------------------------------------------
@@ -350,13 +378,9 @@ void msm58321_device::update_output()
case REGISTER_RESET:
data = 0;
break;
-
- case REGISTER_REF0:
- case REGISTER_REF1:
- // TODO: output reference values
- data = 0;
+ case REGISTER_W:
+ data = m_reg[m_address] - 1;
break;
-
default:
data = m_reg[m_address];
break;
@@ -434,15 +458,17 @@ void msm58321_device::update_input()
default:
LOG("MSM58321 Register Write %s (%01x): %01x\n", reg_name(m_address), m_address, data);
-
+ m_khz_ctr = 0;
switch (m_address)
{
case REGISTER_S10:
case REGISTER_MI10:
- case REGISTER_W:
+
m_reg[m_address] = data & 7;
break;
-
+ case REGISTER_W:
+ m_reg[m_address] = (data & 7) + 1;
+ break;
case REGISTER_H10:
if (data & H10_24)
{