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