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