summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/e0516.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/e0516.cpp')
-rw-r--r--src/devices/machine/e0516.cpp259
1 files changed, 207 insertions, 52 deletions
diff --git a/src/devices/machine/e0516.cpp b/src/devices/machine/e0516.cpp
index a5d029afe27..abf3d181048 100644
--- a/src/devices/machine/e0516.cpp
+++ b/src/devices/machine/e0516.cpp
@@ -15,14 +15,17 @@
// MACROS / CONSTANTS
//**************************************************************************
-#define LOG 0
+//#define VERBOSE 1
+#include "logmacro.h"
// states
enum
{
STATE_ADDRESS = 0,
- STATE_DATA
+ STATE_HI_Z,
+ STATE_DATA_READ,
+ STATE_DATA_WRITE
};
@@ -38,11 +41,24 @@ DEFINE_DEVICE_TYPE(E0516, e0516_device, "e0516", "E05-16 RTC")
// e0516_device - constructor
//-------------------------------------------------
-e0516_device::e0516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, E0516, tag, owner, clock)
- , device_rtc_interface(mconfig, *this)
- , m_cs(0), m_clk(0), m_data_latch(0), m_reg_latch(0), m_read_write(0), m_state(0), m_bits(0), m_dio(0)
- , m_timer(nullptr)
+e0516_device::e0516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, E0516, tag, owner, clock),
+ device_rtc_interface(mconfig, *this),
+ m_read_outsel(*this, 1),
+ m_write_sec(*this),
+ m_write_min(*this),
+ m_write_hrs(*this),
+ m_write_day(*this),
+ m_cs(1),
+ m_clk(0),
+ m_cycle(0),
+ m_data_latch(0),
+ m_reg_latch(0),
+ m_state(STATE_ADDRESS),
+ m_bits_left(4),
+ m_dio(0),
+ m_reset(1),
+ m_timer(nullptr)
{
}
@@ -54,28 +70,33 @@ e0516_device::e0516_device(const machine_config &mconfig, const char *tag, devic
void e0516_device::device_start()
{
// allocate timers
- m_timer = timer_alloc();
+ m_timer = timer_alloc(FUNC(e0516_device::timer_tick), this);
m_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
// state saving
save_item(NAME(m_cs));
save_item(NAME(m_clk));
+ save_item(NAME(m_cycle));
save_item(NAME(m_data_latch));
save_item(NAME(m_reg_latch));
- save_item(NAME(m_read_write));
save_item(NAME(m_state));
- save_item(NAME(m_bits));
+ save_item(NAME(m_bits_left));
save_item(NAME(m_dio));
+ save_item(NAME(m_reset));
}
//-------------------------------------------------
-// device_timer - handler timer events
+// timer_tick - call into dirtc at 1Hz to
+// increment the seconds counter
//-------------------------------------------------
-void e0516_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(e0516_device::timer_tick)
{
- advance_seconds();
+ if (m_reset)
+ {
+ advance_seconds();
+ }
}
@@ -83,19 +104,31 @@ void e0516_device::device_timer(emu_timer &timer, device_timer_id id, int param,
// cs_w - chip select input
//-------------------------------------------------
-WRITE_LINE_MEMBER( e0516_device::cs_w )
+void e0516_device::cs_w(int state)
{
- if (LOG) logerror("E05-16 '%s' CS %u\n", tag(), state);
-
- m_cs = state;
+ if (m_cs != state)
+ {
+ LOG("E05-16 '%s' CS %u\n", tag(), state);
+ }
- if (m_cs)
+ if (!m_cs && state)
{
+ if ((m_state == STATE_DATA_WRITE) && (m_bits_left == 0) && (get_address() != 7))
+ {
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), get_address(), m_data_latch);
+
+ // write latched data to register
+ set_clock_register(get_address(), bcd_to_integer(m_data_latch));
+ }
+
+ m_cycle = 0;
m_data_latch = 0;
m_reg_latch = 0;
- m_bits = 0;
+ m_bits_left = 4;
m_state = STATE_ADDRESS;
}
+
+ m_cs = state;
}
@@ -103,65 +136,155 @@ WRITE_LINE_MEMBER( e0516_device::cs_w )
// clk_w - serial clock input
//-------------------------------------------------
-WRITE_LINE_MEMBER( e0516_device::clk_w )
+void e0516_device::clk_w(int state)
{
- if (LOG) logerror("E05-16 '%s' CLK %u\n", tag(), state);
-
+ if (m_cs) return;
+ if (m_clk == state) return;
m_clk = state;
- if (m_cs || m_clk) return;
+ if (m_clk) {
+ m_cycle++;
+ LOG("E05-16 '%s' CLK %u\n", tag(), m_cycle);
+ }
+
+ if (!m_bits_left) return;
+
+ if (!m_clk && (m_state == STATE_HI_Z))
+ {
+ m_state = STATE_DATA_READ;
+ return;
+ }
+
+ if (!m_clk && (m_state != STATE_DATA_READ)) return;
+ if (m_clk && (m_state == STATE_DATA_READ)) return;
- m_bits++;
+ m_bits_left--;
+ if ((m_state == STATE_DATA_READ) && (m_bits_left == 56) && !m_read_outsel()) return;
if (m_state == STATE_ADDRESS)
{
- if (LOG) logerror("E05-16 '%s' Command Bit %u\n", tag(), m_dio);
+ LOG("E05-16 '%s' Command Bit %u\n", tag(), m_dio);
// command
- m_reg_latch |= m_dio << 3;
- m_reg_latch >>= 1;
+ m_reg_latch <<= 1;
+ m_reg_latch |= m_dio;
+ m_reg_latch &= 0x0f;
- if (m_bits == 4)
+ if (m_bits_left == 0)
{
- m_state = STATE_DATA;
- m_bits = 0;
-
if (BIT(m_reg_latch, 0))
{
- // load register value to data latch
- m_data_latch = convert_to_bcd(get_clock_register(m_reg_latch >> 1));
+ m_state = STATE_DATA_READ;
+
+ if (get_address() == 7)
+ {
+ LOG("E05-16 '%s' Continuous Read-Out Mode\n", tag());
+
+ // continuous read-out mode
+ m_bits_left = 56;
+
+ // load all register values to data latch
+ m_data_latch = convert_to_bcd(get_clock_register(RTC_SECOND));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_DAY_OF_WEEK));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_YEAR));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_MONTH));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_DAY));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_MINUTE));
+ m_data_latch <<= 8;
+ m_data_latch = (m_data_latch & ~0xff) | convert_to_bcd(get_clock_register(RTC_HOUR));
+ }
+ else
+ {
+ LOG("E05-16 '%s' Read Register %u\n", tag(), get_address());
+
+ m_bits_left = 8;
+
+ // load register value to data latch
+ m_data_latch = convert_to_bcd(get_clock_register(get_address()));
+ }
+
+ if (!m_read_outsel())
+ {
+ m_state = STATE_HI_Z;
+ }
+ }
+ else
+ {
+ m_state = STATE_DATA_WRITE;
+
+ if (get_address() == 7)
+ {
+ LOG("E05-16 '%s' Continuous Write-In Mode\n", tag());
+
+ // continuous write-in mode
+ m_bits_left = 56;
+ }
+ else
+ {
+ LOG("E05-16 '%s' Write Register %u\n", tag(), get_address());
+
+ m_bits_left = 8;
+ }
}
}
}
else
{
// data
- if (BIT(m_reg_latch, 0))
+ if (m_state == STATE_DATA_READ)
{
// read
- if (LOG) logerror("E05-16 '%s' Data Bit OUT %u\n", tag(), m_dio);
-
m_dio = BIT(m_data_latch, 0);
m_data_latch >>= 1;
+
+ LOG("E05-16 '%s' Data Bit OUT %u\n", tag(), m_dio);
}
else
{
// write
- if (LOG) logerror("E05-16 '%s' Data Bit IN %u\n", tag(), m_dio);
-
- m_data_latch |= m_dio << 7;
- m_data_latch >>= 1;
- }
+ LOG("E05-16 '%s' Data Bit IN %u\n", tag(), m_dio);
- if (m_bits == 8)
- {
- m_state = STATE_ADDRESS;
- m_bits = 0;
+ m_data_latch <<= 1;
+ m_data_latch |= m_dio;
- if (!BIT(m_reg_latch, 0))
+ if (get_address() == 7)
{
- // write latched data to register
- set_clock_register(m_reg_latch >> 1, bcd_to_integer(m_data_latch));
+ switch (m_bits_left)
+ {
+ case 48:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_HOUR, m_data_latch & 0xff);
+ set_clock_register(RTC_HOUR, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 40:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_MINUTE, m_data_latch & 0xff);
+ set_clock_register(RTC_MINUTE, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 32:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_DAY, m_data_latch & 0xff);
+ set_clock_register(RTC_DAY, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 24:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_MONTH, m_data_latch & 0xff);
+ set_clock_register(RTC_MONTH, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 16:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_YEAR, m_data_latch & 0xff);
+ set_clock_register(RTC_YEAR, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 8:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_DAY_OF_WEEK, m_data_latch & 0xff);
+ set_clock_register(RTC_DAY_OF_WEEK, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ case 0:
+ LOG("E05-16 '%s' Write Register %u : %02x\n", tag(), RTC_SECOND, m_data_latch & 0xff);
+ set_clock_register(RTC_SECOND, bcd_to_integer(m_data_latch & 0xff));
+ break;
+ }
}
}
}
@@ -172,11 +295,14 @@ WRITE_LINE_MEMBER( e0516_device::clk_w )
// dio_w - serial data input
//-------------------------------------------------
-WRITE_LINE_MEMBER( e0516_device::dio_w )
+void e0516_device::dio_w(int state)
{
- if (LOG) logerror("E05-16 '%s' DIO %u\n", tag(), state);
+ LOG("E05-16 '%s' DIO %u\n", tag(), state);
- m_dio = state;
+ if ((m_state != STATE_DATA_READ) && (m_state != STATE_HI_Z))
+ {
+ m_dio = state;
+ }
}
@@ -184,13 +310,42 @@ WRITE_LINE_MEMBER( e0516_device::dio_w )
// do_r - serial data output
//-------------------------------------------------
-READ_LINE_MEMBER( e0516_device::dio_r )
+int e0516_device::dio_r()
{
+ if (m_cs || (m_state == STATE_HI_Z))
+ {
+ // high impedance
+ return 0;
+ }
+
return m_dio;
}
//-------------------------------------------------
+// reset_w - reset input
+//-------------------------------------------------
+
+void e0516_device::reset_w(int state)
+{
+ LOG("E05-16 '%s' RESET %u\n", tag(), state);
+
+ if (m_reset && !state)
+ {
+ set_clock_register(RTC_SECOND, 0);
+ set_clock_register(RTC_MINUTE, 0);
+ set_clock_register(RTC_HOUR, 0);
+ set_clock_register(RTC_DAY, 1);
+ set_clock_register(RTC_MONTH, 1);
+ set_clock_register(RTC_DAY_OF_WEEK, 1);
+ set_clock_register(RTC_YEAR, 0);
+ }
+
+ m_reset = state;
+}
+
+
+//-------------------------------------------------
// rtc_clock_updated -
//-------------------------------------------------