summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z180/z180asci.h
blob: 975297cce8f8efd31a08150bee49097b16f906e0 (plain) (blame)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
/*********************************************************************

    z180asci.h

*********************************************************************/

#ifndef MAME_CPU_Z180_Z180ASCI_H
#define MAME_CPU_Z180_Z180ASCI_H

#pragma once

//**************************************************************************
//  z180asci_channel_base
//**************************************************************************

class z180asci_channel_base : public device_t
{
public:
	// inline configuration
	auto txa_handler() { return m_txa_handler.bind(); }
	auto rts_handler() { return m_rts_handler.bind(); }
	auto cka_handler() { return m_cka_handler.bind(); }

	uint8_t cntla_r();
	uint8_t cntlb_r();
	uint8_t stat_r();
	uint8_t tdr_r();
	uint8_t rdr_r();
	uint8_t asext_r();
	uint8_t astcl_r();
	uint8_t astch_r();
	void cntla_w(uint8_t data);
	void cntlb_w(uint8_t data);
	virtual void stat_w(uint8_t data) = 0;
	void tdr_w(uint8_t data);
	void rdr_w(uint8_t data);
	virtual void asext_w(uint8_t data);
	void astcl_w(uint8_t data);
	void astch_w(uint8_t data);

	DECLARE_WRITE_LINE_MEMBER( rxa_wr );
	DECLARE_WRITE_LINE_MEMBER( cts_wr );
	DECLARE_WRITE_LINE_MEMBER( dcd_wr );
	DECLARE_WRITE_LINE_MEMBER( cka_wr );

	virtual void state_add(device_state_interface &parent) = 0;

	int check_interrupt() { return m_irq; }
	void clear_interrupt() { m_irq = 0; }
protected:
	z180asci_channel_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock, const int id, const bool ext);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_resolve_objects() override;
	virtual void device_clock_changed() override;

	void transmit_edge();
	void receive_edge();
	void set_fifo_data(uint8_t data, uint8_t error);
	void prepare_tsr();
	void update_received();
	void update_total_bits();

	enum serial_state
	{
		STATE_START,
		STATE_DATA,
		STATE_WAIT,
		STATE_BREAK
	};


	void output_txa(int txa);
	void output_rts(int rts);
	TIMER_CALLBACK_MEMBER(rcv_clock) { receive_edge(); }
	TIMER_CALLBACK_MEMBER(tra_clock) { transmit_edge(); }

	emu_timer *m_rcv_clock;
	emu_timer *m_tra_clock;
	attotime m_bit_rate;
	attotime m_sample_rate;

	devcb_write_line m_txa_handler;
	devcb_write_line m_rts_handler;
	devcb_write_line m_cka_handler;

	uint8_t   m_asci_cntla;                  // ASCI control register A
	uint8_t   m_asci_cntlb;                  // ASCI control register B
	uint8_t   m_asci_stat;                   // ASCI status register
	uint8_t   m_asci_tdr;                    // ASCI transmit data register
	uint8_t   m_asci_rdr;                    // ASCI receive data register
	uint8_t   m_asci_ext;                    // ASCI extension control register
	PAIR16    m_asci_tc;                     // ASCI time constant

	uint16_t  m_tsr;
	uint16_t  m_rsr;
	uint8_t   m_data_fifo[4];
	uint8_t   m_error_fifo[4];
	uint8_t   m_fifo_wr;
	uint8_t   m_fifo_rd;

	uint8_t   m_cts;
	uint8_t   m_dcd;
	uint8_t   m_irq;
	uint8_t   m_txa;
	uint8_t   m_rxa;
	uint8_t   m_rts;

	uint32_t  m_divisor;

	uint8_t   m_clock_state;
	uint8_t   m_tx_state;
	uint8_t   m_rx_state;
	uint8_t   m_rx_bits;

	uint8_t   m_tx_counter;
	uint8_t   m_rx_counter;
	uint8_t   m_rx_count_to;
	uint8_t   m_rx_total_bits;

	bool m_rx_enabled;

	const int  m_id;
	const bool m_ext;
};

//**************************************************************************
//  z180asci_channel_0
//**************************************************************************

class z180asci_channel_0 : public z180asci_channel_base
{
public:
	// construction/destruction
	z180asci_channel_0(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock);

	void stat_w(uint8_t data) override;
	void asext_w(uint8_t data) override;
	void state_add(device_state_interface &parent) override;
protected:
	z180asci_channel_0(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock, const bool ext);
	// device-level overrides
	virtual void device_reset() override;
};

//**************************************************************************
//  z180asci_channel_1
//**************************************************************************

class z180asci_channel_1 : public z180asci_channel_base
{
public:
	// construction/destruction
	z180asci_channel_1(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock);

	void stat_w(uint8_t data) override;
	void asext_w(uint8_t data) override;
	void state_add(device_state_interface &parent) override;
protected:
	z180asci_channel_1(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock, const bool ext);
	// device-level overrides
	virtual void device_reset() override;
};

//**************************************************************************
//  z180asci_ext_channel_0
//**************************************************************************

class z180asci_ext_channel_0 : public z180asci_channel_0
{
public:
	// construction/destruction
	z180asci_ext_channel_0(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock);
};

//**************************************************************************
//  z180asci_ext_channel_1
//**************************************************************************

class z180asci_ext_channel_1 : public z180asci_channel_1
{
public:
	// construction/destruction
	z180asci_ext_channel_1(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock);
};

//**************************************************************************
//  DEVICE TYPE DEFINITIONS
//**************************************************************************

DECLARE_DEVICE_TYPE(Z180ASCI_CHANNEL_0, z180asci_channel_0)
DECLARE_DEVICE_TYPE(Z180ASCI_CHANNEL_1, z180asci_channel_1)

DECLARE_DEVICE_TYPE(Z180ASCI_EXT_CHANNEL_0, z180asci_ext_channel_0)
DECLARE_DEVICE_TYPE(Z180ASCI_EXT_CHANNEL_1, z180asci_ext_channel_1)

#endif // MAME_CPU_Z180_Z180ASCI_H