summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/dc7085.h
blob: 282683ac2dfdc0083a48cb6c5084eec9e6d151d4 (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
// license:BSD-3-Clause
// copyright-holders:R. Belmont

#ifndef MAME_MACHINE_DC7085_H
#define MAME_MACHINE_DC7085_H

#pragma once

#include "diserial.h"

#define DC7085_RX_FIFO_SIZE (64)

// forward declaration
class dc7085_device;

class dc7085_channel : public device_t, public device_serial_interface
{
public:
	dc7085_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

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

	// device_serial overrides
	virtual void rcv_complete() override;    // Rx completed receiving byte
	virtual void tra_complete() override;    // Tx completed sending byte
	virtual void tra_callback() override;    // Tx send bit

	void set_baud_rate(int baud);
	void set_format(int data_bits, int parity, int stop_bits);
	void clear();
	void set_tx_enable(bool bEnabled);
	void set_rx_enable(bool bEnabled);
	void write_TX(uint8_t data);
	bool is_tx_ready()
	{
		if (!tx_enabled)
		{
			return false;
		}

		return tx_ready ? true : false;
	}

private:
	/* Receiver */
	u8 rx_enabled;

	/* Shared */
	int baud_rate;
	int m_ch;

	/* Transmitter */
	u8 tx_enabled;
	u8 tx_data;
	u8 tx_ready;

	dc7085_device *m_base;
};

class dc7085_device : public device_t
{
	friend class dc7085_channel;

public:
	required_device<dc7085_channel> m_chan0, m_chan1, m_chan2, m_chan3;

	dc7085_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void map(address_map &map);

	auto int_cb() { return m_int_cb.bind(); }
	auto ch0_tx_cb() { return write_0_tx.bind(); }
	auto ch1_tx_cb() { return write_1_tx.bind(); }
	auto ch2_tx_cb() { return write_2_tx.bind(); }
	auto ch3_tx_cb() { return write_3_tx.bind(); }

protected:
	// standard device_interface overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_add_mconfig(machine_config &config) override;

	void rx_fifo_push(uint16_t data, uint16_t errors);
	void recalc_irqs();

	devcb_write_line m_int_cb;
	devcb_write_line write_0_tx, write_1_tx, write_2_tx, write_3_tx;

	u16 m_status;

	u16 status_r();
	u16 rxbuffer_r();
	u16 txparams_r();
	u16 modem_status_r();
	void control_w(u16 data);
	void lineparams_w(u16 data);
	void txparams_w(u16 data);
	void txdata_w(u16 data);

	int get_ch(dc7085_channel *ch)
	{
		if (ch == m_chan0)
		{
			return 0;
		}
		else if (ch == m_chan1)
		{
			return 1;
		}
		else if (ch == m_chan2)
		{
			return 2;
		}

		return 3;
	}

private:
	u16 rx_fifo[DC7085_RX_FIFO_SIZE];
	int rx_fifo_read_ptr;
	int rx_fifo_write_ptr;
	int rx_fifo_num;

	enum control_status_mask : u16
	{
		CTRL_TRDY           = 0x8000,
		CTRL_TX_IRQ_ENABLE  = 0x4000,
		CTRL_LINE_MASK      = 0x0300,
		CTRL_RX_DONE        = 0x0080,
		CTRL_RX_IRQ_ENABLE  = 0x0040,
		CTRL_MASTER_SCAN    = 0x0020,
		CTRL_MASTER_CLEAR   = 0x0010,
		CTRL_LOOPBACK       = 0x0008
	};

	enum rx_buffer_mask : u16
	{
		RXMASK_DATA_VALID   = 0x8000,
		RXMASK_OVERRUN_ERR  = 0x4000,
		RXMASK_FRAMING_ERR  = 0x2000,
		RXMASK_PARITY_ERR   = 0x1000,
		RXMASK_LINE_MASK    = 0x0300,
		RXMASK_DATA_MASK    = 0x00ff
	};

	enum line_param_mask : u16
	{
		LPARAM_RX_ENABLE    = 0x1000,
		LPARAM_BAUD_MASK    = 0x0f00,
		LPARAM_ODD_PARITY   = 0x0080,
		LPARAM_PARITY_ENB   = 0x0040,
		LPARAM_STOP_BITS    = 0x0020,
		LPARAM_CHARLEN_MASK = 0x0018,
		LPARAM_LINE_MASK    = 0x0003
	};

	enum tx_control_mask : u16
	{
		TXCTRL_DTR2         = 0x0400,
		TXCTRL_LINE3_ENB    = 0x0008,
		TXCTRL_LINE2_ENB    = 0x0004,
		TXCTRL_LINE1_ENB    = 0x0002,
		TXCTRL_LINE0_ENB    = 0x0001
	};

	enum modem_status_mask : u16
	{
		MSTAT_DSR2          = 0x0400
	};

	enum tx_data_mask : u16
	{
		TXDATA_LINE3_BREAK  = 0x0800,
		TXDATA_LINE2_BREAK  = 0x0400,
		TXDATA_LINE1_BREAK  = 0x0200,
		TXDATA_LINE0_BREAK  = 0x0100,
		TXDATA_DATA_MASK    = 0x00ff
	};
};

DECLARE_DEVICE_TYPE(DC7085, dc7085_device)
DECLARE_DEVICE_TYPE(DC7085_CHANNEL, dc7085_channel)

#endif // MAME_MACHINE_DC7085_H