1 // license:BSD-3-Clause
2 // copyright-holders:smf
3 #include "emu.h"
4 #include "znmcu.h"
5 
6 DEFINE_DEVICE_TYPE(ZNMCU, znmcu_device, "znmcu", "Sony ZN MCU")
7 
znmcu_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)8 znmcu_device::znmcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
9 	device_t(mconfig, ZNMCU, tag, owner, clock),
10 	m_dsw_handler(*this),
11 	m_analog1_handler(*this),
12 	m_analog2_handler(*this),
13 	m_dataout_handler(*this),
14 	m_dsr_handler(*this),
15 	m_select(1),
16 	m_clk(1),
17 	m_bit(0),
18 	m_byte(0),
19 	m_databytes(0)
20 {
21 }
22 
device_start()23 void znmcu_device::device_start()
24 {
25 	m_dsw_handler.resolve_safe(0xff);
26 	m_analog1_handler.resolve_safe(0xff);
27 	m_analog2_handler.resolve_safe(0xff);
28 	m_dataout_handler.resolve_safe();
29 	m_dsr_handler.resolve_safe();
30 
31 	m_mcu_timer = timer_alloc(0);
32 
33 	m_dataout_handler(1);
34 	m_dsr_handler(1);
35 
36 	save_item(NAME(m_select));
37 	save_item(NAME(m_clk));
38 	save_item(NAME(m_bit));
39 	save_item(NAME(m_byte));
40 	save_item(NAME(m_databytes));
41 	save_item(NAME(m_send));
42 
43 	memset(m_send, 0, sizeof(m_send));
44 }
45 
WRITE_LINE_MEMBER(znmcu_device::write_select)46 WRITE_LINE_MEMBER(znmcu_device::write_select)
47 {
48 	if (m_select != state)
49 	{
50 		if (!state)
51 		{
52 			m_bit = 0;
53 			m_byte = 0;
54 			m_mcu_timer->adjust(attotime::from_usec(50), 0);
55 		}
56 		else
57 		{
58 			m_dataout_handler(1);
59 			m_dsr_handler(1);
60 			m_mcu_timer->adjust(attotime::never);
61 		}
62 
63 		m_select = state;
64 	}
65 }
66 
WRITE_LINE_MEMBER(znmcu_device::write_clock)67 WRITE_LINE_MEMBER(znmcu_device::write_clock)
68 {
69 	if (m_clk != state)
70 	{
71 		if (!state && !m_select)
72 		{
73 			uint8_t data = 0;
74 			if (m_byte <= m_databytes && m_byte < MaxBytes)
75 			{
76 				data = m_send[m_byte];
77 			}
78 
79 			int dataout = ((data >> m_bit) & 1);
80 			m_dataout_handler(dataout);
81 
82 			m_bit++;
83 			if (m_bit == 8)
84 			{
85 				if (m_byte < m_databytes)
86 				{
87 					m_mcu_timer->adjust(attotime::from_usec(50), 0);
88 				}
89 
90 				m_bit = 0;
91 				m_byte++;
92 			}
93 		}
94 
95 		m_clk = state;
96 	}
97 }
98 
device_timer(emu_timer & timer,device_timer_id tid,int param,void * ptr)99 void znmcu_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
100 {
101 	m_dsr_handler(param);
102 
103 	if (!param)
104 	{
105 		if (m_byte == 0)
106 		{
107 			m_databytes = 2;
108 			m_send[0] = (m_databytes << 4) | (m_dsw_handler() & 0xf);
109 			m_send[1] = m_analog1_handler();
110 			m_send[2] = m_analog2_handler();
111 		}
112 
113 		m_mcu_timer->adjust(attotime::from_usec(5), 1);
114 	}
115 }
116