1 // license:BSD-3-Clause
2 // copyright-holders:Joakim Larsson Edstrom
3 /***************************************************************************
4 
5     MPCC Multi-Protocol Communications Controller emulation
6 
7 ****************************************************************************
8                    _____   _____
9           UDS*   1|*    \_/     |48 IACK*
10         DTACK*   2|             |47 LDS*
11           RxD    3|             |46 DTC*
12           D10    4|             |45 D9                _____   _____
13           DTR*   5|             |44 CS*        A0   1|*    \_/     |40 IACK*
14           DSR*   6|             |43 DACK*   DTACK*  2|             |39 DS*
15           DCD*   7|             |42 GND       RxD*  3|             |38 DTC*
16           D11    8|             |41 D0        DTR*  4|             |37 CS*
17          RDSR*   9|             |40 D8        DSR*  5|             |36 DACK*
18            A1   10|             |39 D1        DCD*  6|             |35 GND
19           GND   11|             |38 D2       RDSR*  7|             |34 D0
20            A4   12|             |37 D3         A1   8|             |33 D1
21            A2   13|   R68561    |36 D4        GND   9|   R68560    |32 D2
22            A3   14|   R68561A   |35 D5         A4  10|   R68560A   |31 D3
23           RxC   15|             |34 D6         A2  11|             |30 D4
24           D12   16|             |33 D15        A3  12|             |29 D5
25           TxC   17|             |32 D7        RxC  13|             |28 D6
26          BCLK   18|             |31 RESET*    TxC  14|             |27 D7
27         EXTAL   19|             |30 CTS*     BCLK  15|             |26 RESET*
28          XTAL   20|             |29 Vcc     EXTAL  16|             |25 CTS*
29           D13   21|             |28 D14      XTAL  17|             |24 Vcc
30           R/W*  22|             |27 DONE*     R/W* 18|             |23 DONE*
31           IRQ*  23|             |26 TxD       IRQ* 19|             |22 TxD
32           RTS*  24|_____________|25 TDSR*     RTS* 20|_____________|21 TDSR*
33                   16 bit data bus                     8 bit data bus
34                 Also in 68 pin PLCE                Also in 44 pin PLCE
35 
36 ***************************************************************************/
37 
38 #ifndef MAME_MACHINE_68561MPCC_H
39 #define MAME_MACHINE_68561MPCC_H
40 
41 #include "diserial.h"
42 
43 //**************************************************************************
44 //  TYPE DEFINITIONS
45 //**************************************************************************
46 class mpcc_device : public device_t, public device_serial_interface
47 {
48 public:
49 	// construction/destruction
50 	mpcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
51 
configure_clocks(int rxc,int txc)52 	void configure_clocks(int rxc, int txc)
53 	{
54 		m_rxc = rxc;
55 		m_txc = txc;
56 	}
57 
out_txd_cb()58 	auto out_txd_cb() { return m_out_txd_cb.bind(); }
out_dtr_cb()59 	auto out_dtr_cb() { return m_out_dtr_cb.bind(); }
out_rts_cb()60 	auto out_rts_cb() { return m_out_rts_cb.bind(); }
out_rtxc_cb()61 	auto out_rtxc_cb() { return m_out_rtxc_cb.bind(); }
out_trxc_cb()62 	auto out_trxc_cb() { return m_out_trxc_cb.bind(); }
out_int_cb()63 	auto out_int_cb() { return m_out_int_cb.bind(); }
64 
65 	uint8_t read(offs_t offset);
66 	void write(offs_t offset, uint8_t data);
67 
68 	// interrupt acknowledge
69 	uint8_t iack(offs_t offset); // declared but not defined?
70 
71 	/* Callbacks to be called by others for signals driven by connected devices */
72 	DECLARE_WRITE_LINE_MEMBER( write_rx );
73 	DECLARE_WRITE_LINE_MEMBER( cts_w );
74 	DECLARE_WRITE_LINE_MEMBER( dsr_w );
75 	DECLARE_WRITE_LINE_MEMBER( dcd_w );
DECLARE_WRITE_LINE_MEMBER(rxc_w)76 	DECLARE_WRITE_LINE_MEMBER( rxc_w ) {} // { m_chanA->rxc_w(state); }
DECLARE_WRITE_LINE_MEMBER(txc_w)77 	DECLARE_WRITE_LINE_MEMBER( txc_w ) {} // { m_chanA->txc_w(state); }
78 
79 protected:
80 	mpcc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
81 
82 	// device-level overrides
83 	virtual void device_start() override;
84 	virtual void device_reset() override;
85 
86 	// device_serial_interface overrides
87 	virtual void tra_callback() override;
88 	virtual void tra_complete() override;
89 	virtual void rcv_callback() override;
90 	virtual void rcv_complete() override;
91 
92 	// serial device setup helpers
93 	uint32_t get_brg_rate();
94 	uint32_t get_tx_rate();
95 	uint32_t get_rx_rate();
96 	uint32_t get_clock_div();
97 	uint32_t get_word_length();
98 	stop_bits_t get_stop_bits();
99 	parity_t get_parity();
100 	void update_serial();
101 
102 	/*
103 	 * Interrupts
104 	 */
105 	void check_interrupts();
106 	void reset_interrupts();
107 	void update_interrupts(int source);
108 	void trigger_interrupt(int source);
109 	enum
110 	{
111 		INT_TX,         // TX int category, used for update of SR
112 		INT_TX_TDRA,    // Tx char available
113 		INT_TX_TFC,     // Tx frame complete
114 		INT_TX_TUNRN,   // Tx underrun detected
115 		INT_TX_TFERR,   // Tx frame error detected
116 		INT_RX,         // RX int category, used for update of SR
117 		INT_RX_RDA,     // Rx interrupt on Receiver Data Available
118 		INT_RX_EOF,     // Rx interrupt on End of frame
119 		INT_RX_CPERR,   // Rx interrupt on CRC or Parity error
120 		INT_RX_FRERR,   // Rx interrupt on Frame error
121 		INT_RX_ROVRN,   // Rx interrupt on Receiver overrun
122 		INT_RX_RAB,     // Rx interrupt on Abort/Break
123 		INT_SR,         // SR int category, used for update of SR
124 		INT_SR_CTS,     // Serial interface interrupt on CTS asserted
125 		INT_SR_DSR,     // Serial interface interrupt on DSR asserted
126 		INT_SR_DCD,     // Serial interface interrupt on DCD asserted
127 	};
128 
129 	enum
130 	{
131 		RX_INT_PRIO = 0x00, // Highest interrupt priority
132 		TX_INT_PRIO = 0x01,
133 		SR_INT_PRIO = 0x02  // Lowest interrupt priority
134 	};
135 
136 	enum
137 	{
138 		INT_NONE = 0x00, // No interrupts
139 		INT_REQ  = 0x01, // Interrupt requested
140 		INT_ACK  = 0x02  // Interrupt acknowledged
141 	};
142 
143 	// Variants in the MPCC family
144 	enum
145 	{
146 		TYPE_MPCC       = 0x001,
147 		TYPE_MPCC68560  = 0x002,
148 		TYPE_MPCC68560A = 0x004,
149 		TYPE_MPCC68561  = 0x008,
150 		TYPE_MPCC68561A = 0x010,
151 		SET_TYPE_A      = TYPE_MPCC68560A | TYPE_MPCC68561A
152 	};
153 
154 	// State variables
155 	uint32_t m_irq;
156 	uint32_t m_variant;
157 	uint32_t m_rxc;
158 	uint32_t m_txc;
159 	uint32_t m_brg_rate;
160 	uint32_t m_rcv;
161 	uint32_t m_rxd;
162 	uint32_t m_tra;
163 	uint32_t m_int_state[3]; // Three priority levels Rx, Tx and Serial interface
164 
165 	// Callbacks
166 	devcb_write_line    m_out_txd_cb;
167 	devcb_write_line    m_out_dtr_cb;
168 	devcb_write_line    m_out_rts_cb;
169 	devcb_write_line    m_out_rtxc_cb;
170 	devcb_write_line    m_out_trxc_cb;
171 
172 	devcb_write_line    m_out_int_cb;
173 
174 	/*
175 	 *  Register handling
176 	 */
177 	// RSR - Rx Status Register
178 	uint8_t m_rsr;
179 	uint8_t do_rsr();
180 	void do_rsr(uint8_t data);
181 	enum
182 	{
183 		REG_RSR_RDA     = 0x80, // Rx Data available
184 		REG_RSR_EOF     = 0x40, // End of frame detected (BOP and BSC modes)
185 		REG_RSR_RHW     = 0x20, // Odd number of frame data bytes reeived in 16 bit mode.
186 		REG_RSR_CPERR   = 0x10, // CRC or parity error detected
187 		REG_RSR_FRERR   = 0x08, // Frame error detected
188 		REG_RSR_ROVRN   = 0x04, // Rx overrun detected
189 		REG_RSR_RAB     = 0x02, // Rx Abort break detected
190 		REG_RSR_RIDLE   = 0x01, // Rx idle detcted (15+ high consecutive bits accounted for)
191 	};
192 
193 	// RCR - Rx Control Register
194 	uint8_t m_rcr;
195 	uint8_t do_rcr();
196 	void do_rcr(uint8_t data);
197 	enum
198 	{
199 		REG_RCR_RDSREN = 0x40, // Rx Data Service Request Enable (DMA)
200 		REG_RCR_DONEEN = 0x20, // DONE output enable
201 		REG_RCR_RSYNEN = 0x10, // RSYNEN output enable
202 		REG_RCR_STRSYN = 0x08, // STRIP SYN character (COP mode)
203 		REG_RCR_RABTEN = 0x02, // Receiver Abort Enable (BOP mode)
204 		REG_RCR_RRES   = 0x01, // Receiver Reset command/Enable
205 	};
206 
207 	uint8_t m_rdr;
208 	uint8_t do_rdr();
209 	// TODO: investigate if 4 x 16 bit wide FIFO is needed for 16 bit mode
210 	util::fifo<uint16_t, 8> m_rx_data_fifo;
211 
212 	// RIVNR - Rx Interrupt Vector Number Register
213 	uint8_t m_rivnr;
214 	uint8_t do_rivnr();
215 	void do_rivnr(uint8_t data);
216 
217 	// RIER - Rx Interrupt Enable Register
218 	uint8_t m_rier;
219 	uint8_t do_rier();
220 	void do_rier(uint8_t data);
221 	enum {
222 		REG_RIER_RDA    = 0x80, // Rx interrupt on Receiver Data Available
223 		REG_RIER_EOF    = 0x40, // Rx interrupt on End of frame
224 		REG_RIER_CPERR  = 0x10, // Rx interrupt on CRC or Parity error
225 		REG_RIER_FRERR  = 0x08, // Rx interrupt on Frame error
226 		REG_RIER_ROVRN  = 0x04, // Rx interrupt on Receiver overrun
227 		REG_RIER_RAB    = 0x02, // Rx interrupt on Abort/Break
228 	};
229 
230 	// TSR - Tx Status Register
231 	uint8_t m_tsr;
232 	uint8_t do_tsr();
233 	void do_tsr(uint8_t data);
234 	enum
235 	{
236 		REG_TSR_TDRA  = 0x80, // Tx Fifo Full or not
237 		REG_TSR_TFC   = 0x40, // Tx Frame Complete
238 		REG_TSR_TUNRN = 0x04, // Tx underrun
239 		REG_TSR_TFERR = 0x02, // Tx Frame Error
240 	};
241 
242 	// TCR - Tx Control Register
243 	uint8_t m_tcr;
244 	uint8_t do_tcr();
245 	void do_tcr(uint8_t data);
246 	enum
247 	{
248 		REG_TCR_TEN     = 0x80, // Tx enable
249 		REG_TCR_TDSREN  = 0x40, // DMA enable
250 		REG_TCR_TICS    = 0x20, // Tx Idle Char Select, 'A' variant differs
251 		REG_TCR_THW     = 0x10, // Indicates that last 16 bit word has only 8 bits, in 16 bits mode only
252 		REG_TCR_TLAST   = 0x08, // Indicates the last byte to be written in to TDR (BOP, BCS or COP)
253 		REG_TCR_TSYN    = 0x04, // SYN enable (BCS or COP)
254 		REG_TCR_TABT    = 0x02, // Abort command (BOP)
255 		REG_TCR_TRES    = 0x01, // Tx Reset command
256 	};
257 
258 	// TDR - Tx Data Register (write only)
259 	uint8_t m_tdr;
260 	void do_tdr(uint8_t data);
261 	// TODO: investigate if 4 x 16 bit wide FIFO is needed for 16 bit mode
262 	util::fifo<uint8_t, 8> m_tx_data_fifo;
263 
264 	// TIVNR - Tx Interrupt Vector Number Register
265 	uint8_t m_tivnr;
266 	uint8_t do_tivnr();
267 	void do_tivnr(uint8_t data);
268 
269 	// TIER - Tx Interrupt Enable Register
270 	uint8_t m_tier;
271 	uint8_t do_tier();
272 	void do_tier(uint8_t data);
273 	enum
274 	{
275 		REG_TIER_TDRA   = 0x80, // TX Character available interrupt
276 		REG_TIER_TFC    = 0x40, // TX Frame complete interrupt
277 		REG_TIER_TUNRN  = 0x04, // TX Underrun interrupt
278 		REG_TIER_TFERR  = 0x02, // TX Frame error interrupt
279 	};
280 
281 	// SISR - Serial Interface Status Register
282 	uint8_t m_sisr;
283 	uint8_t do_sisr();
284 	void do_sisr(uint8_t data);
285 	enum
286 	{
287 		REG_SISR_CTST   = 0x80, // Clear To Send Transition Status
288 		REG_SISR_DSRT   = 0x40, // Data Set Ready Transition Status
289 		REG_SISR_DCDT   = 0x20, // Data Carrier Detect Transition Status
290 		REG_SISR_CTSLVL = 0x10, // Clear To Send Level
291 		REG_SISR_DSRLVL = 0x08, // Data Set Ready Level
292 		REG_SISR_DCDLVL = 0x04, // Data Carrier Detect Level
293 	};
294 
295 	// SICR - Serial Interface Control Register
296 	uint8_t m_sicr;
297 	uint8_t do_sicr();
298 	void do_sicr(uint8_t data);
299 	enum
300 	{
301 		REG_SICR_RTSLVL = 0x80, // RTS level
302 		REG_SICR_DTRLVL = 0x40, // DTR level
303 		REG_SICR_ECHO   = 0x04, // Echo Mode
304 		REG_SICR_TEST   = 0x02, // Test Mode
305 	};
306 
307 	uint8_t m_sivnr;
308 
309 	// SIER - Serial interface Interrupt Enable
310 	uint8_t m_sier;
311 	uint8_t do_sier();
312 	void do_sier(uint8_t data);
313 	enum
314 	{
315 		REG_SIER_CTS    = 0x80,
316 		REG_SIER_DSR    = 0x40,
317 		REG_SIER_DCD    = 0x20,
318 	};
319 
320 	// PSR1 Protocol Selection Register 1
321 	uint8_t m_psr1;
322 	uint8_t do_psr1();
323 	void do_psr1(uint8_t data);
324 	enum
325 	{
326 		REG_PSR1_ADRZ       = 0x08, // Zero adress option (BOP) (A models only)
327 		REG_PSR1_IPARS      = 0x04, // IPARS option (COP)
328 		REG_PSR1_CTLEX      = 0x02, // Control field width 8/16 bit (BOP) (A models only)
329 		REG_PSR1_ADDEX      = 0x01, // Address extend option (BOP) (A models only)
330 	};
331 
332 	// PSR2 Protocol Selection Register 2
333 	uint8_t m_psr2;
334 	uint8_t do_psr2();
335 	void do_psr2(uint8_t data);
336 	enum
337 	{
338 		REG_PSR2_WDBYT      = 0x80, // 8/16 bit data bus selector
339 		REG_PSR2_STP_MSK    = 0x60, // Stop bits selection field
340 		REG_PSR2_STP_1      = 0x00, // 1   Stop bits
341 		REG_PSR2_STP_1_5    = 0x20, // 1.5 Stop bits
342 		REG_PSR2_STP_2      = 0x40, // 2   Stop bits
343 		REG_PSR2_CHLN_MSK   = 0x18, // char len selection field
344 		REG_PSR2_CHLN_5     = 0x00, // 5 bit char len
345 		REG_PSR2_CHLN_6     = 0x08, // 6 bit char len
346 		REG_PSR2_CHLN_7     = 0x10, // 7 bit char len
347 		REG_PSR2_CHLN_8     = 0x18, // 8 bit char len
348 		REG_PSR2_PSEL_MSK   = 0x07, // Protocol selection field
349 		REG_PSR2_PSEL_BOPP  = 0x00, // Protocol selection BOP Primary
350 		REG_PSR2_PSEL_BOPS  = 0x01, // Protocol selection BOP Secondary
351 		REG_PSR2_PSEL_RSV   = 0x02, // Protocol selection Reserved
352 		REG_PSR2_PSEL_COP   = 0x03, // Protocol selection COP
353 		REG_PSR2_PSEL_BCSE  = 0x04, // Protocol selection BCS EBCDIC
354 		REG_PSR2_PSEL_BCSA  = 0x05, // Protocol selection BCS ASCII
355 		REG_PSR2_PSEL_ASCII = 0x06, // Protocol selection ASYNC
356 		REG_PSR2_PSEL_ISOC  = 0x07, // Protocol selection ISOC
357 	};
358 
359 	uint8_t m_ar1;
360 	uint8_t m_ar2;
361 
362 
363 	// BRDR1 - Baud Rate Divisor Register 1 (Lo)
364 	uint8_t m_brdr1;
365 	uint8_t do_brdr1();
366 	void do_brdr1(uint8_t data);
367 
368 	// BRDR2 - Baud Rate Divisor Register 2 (Hi)
369 	uint8_t m_brdr2;
370 	uint8_t do_brdr2();
371 	void do_brdr2(uint8_t data);
372 
373 	// CCR - Clock Control Register
374 	uint8_t m_ccr;
375 	uint8_t do_ccr();
376 	void do_ccr(uint8_t data);
377 	enum
378 	{
379 		REG_CCR_PSCDIV      = 0x10, // Internal prescaler Divider x2 or x3
380 		REG_CCR_TCLO        = 0x08, // TxC input/output selection
381 		REG_CCR_RCLKIN      = 0x04, // RxC from internal/external source selection
382 		REG_CCR_CLKDIV_MSK  = 0x03, // External RxC prescaler Divider
383 		REG_CCR_CLKDIV_X1   = 0x00, // x1  - ISOC only
384 		REG_CCR_CLKDIV_X16  = 0x01, // x16 - ASYNC only
385 		REG_CCR_CLKDIV_X32  = 0x02, // x32 - ASYNC only
386 		REG_CCR_CLKDIV_X64  = 0x03, // x64 - ASYNC only
387 	};
388 
389 	// ECR - Error Control Regsiter
390 	uint8_t m_ecr;
391 	uint8_t do_ecr();
392 	void do_ecr(uint8_t data);
393 	enum
394 	{
395 		REG_ECR_PAREN   = 0x80, // Parity Enable
396 		REG_ECR_ODDPAR  = 0x40, // Odd/Even Parity
397 		REG_ECR_CFCRC   = 0x08, // CRC Enable
398 		REG_ECR_CRCPRE  = 0x04, // CRC Preset 0 (BSC) or 1 (BOP)
399 		REG_ECR_CRCSEL_MSK  = 0x03, // CRC Polynominal Selection Mask
400 		REG_ECR_CRCSEL_V41  = 0x00, // CCITT V.41 (BOP) CRC Polynomial
401 		REG_ECR_CRCSEL_C16  = 0x01, // CRC-16 (BSC) CRC Polynomial
402 		REG_ECR_CRCSEL_VRC  = 0x02, // VRC/LRC (BSC, ASCII, non-transp) CRC Polynomial
403 	};
404 
405 };
406 
407 class mpcc68560_device  : public mpcc_device
408 {
409 public:
mpcc68560_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,int rxc,int txc)410 	mpcc68560_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int rxc, int txc)
411 		: mpcc68560_device(mconfig, tag, owner, clock)
412 	{
413 		configure_clocks(rxc, txc);
414 	}
415 
416 	mpcc68560_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
417 };
418 
419 class mpcc68560a_device  : public mpcc_device
420 {
421 public:
mpcc68560a_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,int rxc,int txc)422 	mpcc68560a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int rxc, int txc)
423 		: mpcc68560a_device(mconfig, tag, owner, clock)
424 	{
425 		configure_clocks(rxc, txc);
426 	}
427 
428 	mpcc68560a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
429 };
430 
431 class mpcc68561_device  : public mpcc_device
432 {
433 public:
mpcc68561_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,int rxc,int txc)434 	mpcc68561_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int rxc, int txc)
435 		: mpcc68561_device(mconfig, tag, owner, clock)
436 	{
437 		configure_clocks(rxc, txc);
438 	}
439 
440 	mpcc68561_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
441 };
442 
443 class mpcc68561a_device  : public mpcc_device
444 {
445 public:
mpcc68561a_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock,int rxc,int txc)446 	mpcc68561a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int rxc, int txc)
447 		: mpcc68561a_device(mconfig, tag, owner, clock)
448 	{
449 		configure_clocks(rxc, txc);
450 	}
451 
452 	mpcc68561a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
453 };
454 
455 // device type definition
456 DECLARE_DEVICE_TYPE(MPCC,       mpcc_device)
457 DECLARE_DEVICE_TYPE(MPCC68560,  mpcc68560_device)
458 DECLARE_DEVICE_TYPE(MPCC68560A, mpcc68560a_device)
459 DECLARE_DEVICE_TYPE(MPCC68561,  mpcc68561_device)
460 DECLARE_DEVICE_TYPE(MPCC68561A, mpcc68561a_device)
461 
462 #endif // MAME_MACHINE_68561MPCC_H
463