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