1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Microelectronic-Marin E050-16 Real Time Clock emulation
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "e0516.h"
11 
12 
13 
14 //**************************************************************************
15 //  MACROS / CONSTANTS
16 //**************************************************************************
17 
18 #define LOG 0
19 
20 
21 // states
22 enum
23 {
24 	STATE_ADDRESS = 0,
25 	STATE_DATA
26 };
27 
28 
29 
30 //**************************************************************************
31 //  LIVE DEVICE
32 //**************************************************************************
33 
34 // device type definition
35 DEFINE_DEVICE_TYPE(E0516, e0516_device, "e0516", "E05-16 RTC")
36 
37 //-------------------------------------------------
38 //  e0516_device - constructor
39 //-------------------------------------------------
40 
e0516_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)41 e0516_device::e0516_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
42 	: device_t(mconfig, E0516, tag, owner, clock)
43 	, device_rtc_interface(mconfig, *this)
44 	, 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)
45 	, m_timer(nullptr)
46 {
47 }
48 
49 
50 //-------------------------------------------------
51 //  device_start - device-specific startup
52 //-------------------------------------------------
53 
device_start()54 void e0516_device::device_start()
55 {
56 	// allocate timers
57 	m_timer = timer_alloc();
58 	m_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
59 
60 	// state saving
61 	save_item(NAME(m_cs));
62 	save_item(NAME(m_clk));
63 	save_item(NAME(m_data_latch));
64 	save_item(NAME(m_reg_latch));
65 	save_item(NAME(m_read_write));
66 	save_item(NAME(m_state));
67 	save_item(NAME(m_bits));
68 	save_item(NAME(m_dio));
69 }
70 
71 
72 //-------------------------------------------------
73 //  device_timer - handler timer events
74 //-------------------------------------------------
75 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)76 void e0516_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
77 {
78 	advance_seconds();
79 }
80 
81 
82 //-------------------------------------------------
83 //  cs_w - chip select input
84 //-------------------------------------------------
85 
WRITE_LINE_MEMBER(e0516_device::cs_w)86 WRITE_LINE_MEMBER( e0516_device::cs_w )
87 {
88 	if (LOG) logerror("E05-16 '%s' CS %u\n", tag(), state);
89 
90 	m_cs = state;
91 
92 	if (m_cs)
93 	{
94 		m_data_latch = 0;
95 		m_reg_latch = 0;
96 		m_bits = 0;
97 		m_state = STATE_ADDRESS;
98 	}
99 }
100 
101 
102 //-------------------------------------------------
103 //  clk_w - serial clock input
104 //-------------------------------------------------
105 
WRITE_LINE_MEMBER(e0516_device::clk_w)106 WRITE_LINE_MEMBER( e0516_device::clk_w )
107 {
108 	if (LOG) logerror("E05-16 '%s' CLK %u\n", tag(), state);
109 
110 	m_clk = state;
111 
112 	if (m_cs || m_clk) return;
113 
114 	m_bits++;
115 
116 	if (m_state == STATE_ADDRESS)
117 	{
118 		if (LOG) logerror("E05-16 '%s' Command Bit %u\n", tag(), m_dio);
119 
120 		// command
121 		m_reg_latch |= m_dio << 3;
122 		m_reg_latch >>= 1;
123 
124 		if (m_bits == 4)
125 		{
126 			m_state = STATE_DATA;
127 			m_bits = 0;
128 
129 			if (BIT(m_reg_latch, 0))
130 			{
131 				// load register value to data latch
132 				m_data_latch = convert_to_bcd(get_clock_register(m_reg_latch >> 1));
133 			}
134 		}
135 	}
136 	else
137 	{
138 		// data
139 		if (BIT(m_reg_latch, 0))
140 		{
141 			// read
142 			if (LOG) logerror("E05-16 '%s' Data Bit OUT %u\n", tag(), m_dio);
143 
144 			m_dio = BIT(m_data_latch, 0);
145 			m_data_latch >>= 1;
146 		}
147 		else
148 		{
149 			// write
150 			if (LOG) logerror("E05-16 '%s' Data Bit IN %u\n", tag(), m_dio);
151 
152 			m_data_latch |= m_dio << 7;
153 			m_data_latch >>= 1;
154 		}
155 
156 		if (m_bits == 8)
157 		{
158 			m_state = STATE_ADDRESS;
159 			m_bits = 0;
160 
161 			if (!BIT(m_reg_latch, 0))
162 			{
163 				// write latched data to register
164 				set_clock_register(m_reg_latch >> 1, bcd_to_integer(m_data_latch));
165 			}
166 		}
167 	}
168 }
169 
170 
171 //-------------------------------------------------
172 //  dio_w - serial data input
173 //-------------------------------------------------
174 
WRITE_LINE_MEMBER(e0516_device::dio_w)175 WRITE_LINE_MEMBER( e0516_device::dio_w )
176 {
177 	if (LOG) logerror("E05-16 '%s' DIO %u\n", tag(), state);
178 
179 	m_dio = state;
180 }
181 
182 
183 //-------------------------------------------------
184 //  do_r - serial data output
185 //-------------------------------------------------
186 
READ_LINE_MEMBER(e0516_device::dio_r)187 READ_LINE_MEMBER( e0516_device::dio_r )
188 {
189 	return m_dio;
190 }
191 
192 
193 //-------------------------------------------------
194 //  rtc_clock_updated -
195 //-------------------------------------------------
196 
rtc_clock_updated(int year,int month,int day,int day_of_week,int hour,int minute,int second)197 void e0516_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
198 {
199 }
200