diff options
Diffstat (limited to 'trunk/src/emu/machine/e0516.c')
-rw-r--r-- | trunk/src/emu/machine/e0516.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/e0516.c b/trunk/src/emu/machine/e0516.c new file mode 100644 index 00000000000..dcfeab3b0ad --- /dev/null +++ b/trunk/src/emu/machine/e0516.c @@ -0,0 +1,274 @@ +/********************************************************************** + + E05-16 Real Time Clock emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "emu.h" +#include "e0516.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 + + +// states +enum +{ + STATE_ADDRESS = 0, + STATE_DATA +}; + + +// registers +enum +{ + SECOND = 0, + MINUTE, + HOUR, + DAY, + MONTH, + DAY_OF_WEEK, + YEAR, + ALL +}; + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// advance_seconds - +//------------------------------------------------- + +inline void e0516_device::advance_seconds() +{ + m_register[SECOND]++; + + if (m_register[SECOND] == 60) + { + m_register[SECOND] = 0; + m_register[MINUTE]++; + } + + if (m_register[MINUTE] == 60) + { + m_register[MINUTE] = 0; + m_register[HOUR]++; + } + + if (m_register[HOUR] == 24) + { + m_register[HOUR] = 0; + m_register[DAY]++; + m_register[DAY_OF_WEEK]++; + } + + if (m_register[DAY_OF_WEEK] == 8) + { + m_register[DAY_OF_WEEK] = 1; + } + + if (m_register[DAY] == 32) + { + m_register[DAY] = 1; + m_register[MONTH]++; + } + + if (m_register[MONTH] == 13) + { + m_register[MONTH] = 1; + m_register[YEAR]++; + } +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +// device type definition +const device_type E0516 = &device_creator<e0516_device>; + +//------------------------------------------------- +// e0516_device - constructor +//------------------------------------------------- + +e0516_device::e0516_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, E0516, "E05-16", tag, owner, clock), + device_rtc_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void e0516_device::device_start() +{ + // allocate timers + m_timer = timer_alloc(); + 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_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_dio)); + save_item(NAME(m_register)); +} + + +//------------------------------------------------- +// device_start - device-specific reset +//------------------------------------------------- + +void e0516_device::device_reset() +{ +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void e0516_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + advance_seconds(); +} + + +//------------------------------------------------- +// rtc_set_time - called to initialize the RTC to +// a known state +//------------------------------------------------- + +void e0516_device::rtc_set_time(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_register[YEAR] = year; + m_register[MONTH] = month; + m_register[DAY] = day; + m_register[DAY_OF_WEEK] = day_of_week + 1; + m_register[HOUR] = hour; + m_register[MINUTE] = minute; + m_register[SECOND] = second; +} + + +//------------------------------------------------- +// cs_w - chip select input +//------------------------------------------------- + +WRITE_LINE_MEMBER( e0516_device::cs_w ) +{ + m_cs = state; + + if (m_cs) + { + m_data_latch = 0; + m_reg_latch = 0; + m_bits = 0; + m_state = STATE_ADDRESS; + } +} + + +//------------------------------------------------- +// clk_w - serial clock input +//------------------------------------------------- + +WRITE_LINE_MEMBER( e0516_device::clk_w ) +{ + m_clk = state; + + if (m_cs || m_clk) return; + + m_bits++; + + if (m_state == STATE_ADDRESS) + { + if (LOG) logerror("E05-16 '%s' Command Bit %u\n", tag(), m_dio); + + // command + m_reg_latch |= m_dio << 3; + m_reg_latch >>= 1; + + if (m_bits == 4) + { + m_state = STATE_DATA; + m_bits = 0; + + if (BIT(m_reg_latch, 0)) + { + // load register value to data latch + m_data_latch = m_register[m_reg_latch >> 1]; + } + } + } + else + { + // data + if (BIT(m_reg_latch, 0)) + { + // 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; + } + 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; + } + + if (m_bits == 8) + { + m_state = STATE_ADDRESS; + m_bits = 0; + + if (!BIT(m_reg_latch, 0)) + { + // write latched data to register + m_register[m_reg_latch >> 1] = m_data_latch; + } + } + } +} + + +//------------------------------------------------- +// dio_w - serial data input +//------------------------------------------------- + +WRITE_LINE_MEMBER( e0516_device::dio_w ) +{ + m_dio = state; +} + + +//------------------------------------------------- +// do_r - serial data output +//------------------------------------------------- + +READ_LINE_MEMBER( e0516_device::dio_r ) +{ + return m_dio; +} |