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
|
#ifndef _N68681_H
#define _N68681_H
#define MCFG_DUARTN68681_ADD(_tag, _clock, _config) \
MCFG_DEVICE_ADD(_tag, DUARTN68681, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define MCFG_DUARTN68681_REPLACE(_tag, _clock, _config) \
MCFG_DEVICE_REPLACE(_tag, DUARTN68681, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define MCFG_DUART68681_CHANNEL_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, DUART68681CHANNEL, 0)
// forward declaration
class duartn68681_device;
struct duartn68681_config
{
devcb_write_line m_out_irq_cb;
devcb_write_line m_out_a_tx_cb;
devcb_write_line m_out_b_tx_cb;
devcb_read8 m_in_port_cb;
devcb_write8 m_out_port_cb;
/* clocks for external baud rates */
INT32 ip3clk, ip4clk, ip5clk, ip6clk;
};
#define MC68681_RX_FIFO_SIZE 3
// forward declaration
class duartn68681_device;
// n68681 channel class
class duart68681_channel : public device_t, public device_serial_interface
{
public:
duart68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_serial overrides
virtual void rcv_complete(); // Rx completed receiving byte
virtual void tra_complete(); // Tx completed sending byte
virtual void tra_callback(); // Tx send bit
void input_callback(UINT8 state);
UINT8 read_chan_reg(int reg);
void write_chan_reg(int reg, UINT8 data);
void update_interrupts();
UINT8 read_rx_fifo();
void ACR_updated();
private:
/* Registers */
UINT8 CR; /* Command register */
UINT8 CSR; /* Clock select register */
UINT8 MR1; /* Mode register 1 */
UINT8 MR2; /* Mode register 2 */
UINT8 MR_ptr; /* Mode register pointer */
UINT8 SR; /* Status register */
/* State */
int tx_baud_rate, rx_baud_rate;
/* Receiver */
UINT8 rx_enabled;
UINT8 rx_fifo[MC68681_RX_FIFO_SIZE];
int rx_fifo_read_ptr;
int rx_fifo_write_ptr;
int rx_fifo_num;
int m_ch;
/* Transmitter */
UINT8 tx_enabled;
UINT8 tx_data;
UINT8 tx_ready;
duartn68681_device *m_uart;
void write_MR(UINT8 data);
void write_CR(UINT8 data);
void write_TX(UINT8 data);
void recalc_framing();
};
class duartn68681_device : public device_t, public duartn68681_config
{
friend class duart68681_channel;
public:
duartn68681_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
required_device<duart68681_channel> m_chanA;
required_device<duart68681_channel> m_chanB;
// API
DECLARE_READ8_HANDLER(read);
DECLARE_WRITE8_HANDLER(write);
UINT8 get_irq_vector() { return IVR; }
DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((UINT8)state); }
DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((UINT8)state); }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual machine_config_constructor device_mconfig_additions() const;
private:
TIMER_CALLBACK_MEMBER( duart_timer_callback );
/* registers */
UINT8 ACR; /* Auxiliary Control Register */
UINT8 IMR; /* Interrupt Mask Register */
UINT8 ISR; /* Interrupt Status Register */
UINT8 IVR; /* Interrupt Vector Register */
UINT8 OPCR; /* Output Port Conf. Register */
UINT8 OPR; /* Output Port Register */
PAIR CTR; /* Counter/Timer Preset Value */
/* state */
UINT8 IP_last_state; /* last state of IP bits */
/* timer */
UINT8 half_period;
emu_timer *duart_timer;
double duart68681_get_ct_rate();
UINT16 duart68681_get_ct_count();
void duart68681_start_ct(int count);
int calc_baud(int ch, UINT8 data);
int get_ch(duart68681_channel *ch) { return (ch == m_chanA) ? 0 : 1; }
void clear_ISR_bits(int mask);
void set_ISR_bits(int mask);
void update_interrupts();
duart68681_channel *get_channel(int chan);
devcb_resolved_write_line m_out_irq_func;
devcb_resolved_write_line m_out_a_tx_func;
devcb_resolved_write_line m_out_b_tx_func;
devcb_resolved_read8 m_in_port_func;
devcb_resolved_write8 m_out_port_func;
};
extern const device_type DUARTN68681;
extern const device_type DUART68681CHANNEL;
#endif //_N68681_H
|