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