trunk/src/emu/machine/mc68901.c
| r26687 | r26688 | |
| 176 | 176 | const int mc68901_device::PRESCALER[] = { 0, 4, 10, 16, 50, 64, 100, 200 }; |
| 177 | 177 | |
| 178 | 178 | |
| 179 | | #define TXD(_data) m_out_so_func(_data); |
| 180 | | |
| 181 | | |
| 182 | 179 | //************************************************************************** |
| 183 | 180 | // INLINE HELPERS |
| 184 | 181 | //************************************************************************** |
| r26687 | r26688 | |
| 222 | 219 | } |
| 223 | 220 | } |
| 224 | 221 | |
| 225 | | inline void mc68901_device::tx_buffer_empty() |
| 226 | | { |
| 227 | | if (m_ier & IR_XMIT_BUFFER_EMPTY) |
| 228 | | { |
| 229 | | take_interrupt(IR_XMIT_BUFFER_EMPTY); |
| 230 | | } |
| 231 | | } |
| 232 | | |
| 233 | | inline void mc68901_device::tx_error() |
| 234 | | { |
| 235 | | if (m_ier & IR_XMIT_ERROR) |
| 236 | | { |
| 237 | | take_interrupt(IR_XMIT_ERROR); |
| 238 | | } |
| 239 | | else |
| 240 | | { |
| 241 | | tx_buffer_empty(); |
| 242 | | } |
| 243 | | } |
| 244 | | |
| 245 | | inline int mc68901_device::get_parity_bit(UINT8 b) |
| 246 | | { |
| 247 | | b ^= b >> 4; |
| 248 | | b ^= b >> 2; |
| 249 | | b ^= b >> 1; |
| 250 | | return b & 1; |
| 251 | | } |
| 252 | | |
| 253 | | inline void mc68901_device::serial_receive() |
| 254 | | { |
| 255 | | int rxd; |
| 256 | | |
| 257 | | if (!(m_rsr & RSR_RCV_ENABLE)) return; |
| 258 | | |
| 259 | | rxd = m_in_si_func(); |
| 260 | | |
| 261 | | switch (m_rx_state) |
| 262 | | { |
| 263 | | case SERIAL_START: |
| 264 | | if (!rxd) |
| 265 | | { |
| 266 | | m_rsr |= RSR_CHAR_IN_PROGRESS; |
| 267 | | m_rx_bits = 0; |
| 268 | | m_rx_buffer = 0; |
| 269 | | m_rx_state = SERIAL_DATA; |
| 270 | | m_next_rsr = RSR_BREAK; |
| 271 | | } |
| 272 | | break; |
| 273 | | |
| 274 | | case SERIAL_DATA: |
| 275 | | if ((m_next_rsr & RSR_BREAK) && (rxd == 1) && m_rsr_read) |
| 276 | | { |
| 277 | | m_next_rsr &= ~RSR_BREAK; |
| 278 | | } |
| 279 | | |
| 280 | | m_rx_buffer >>= 1; |
| 281 | | m_rx_buffer |= (rxd << 7); |
| 282 | | m_rx_bits++; |
| 283 | | |
| 284 | | if (m_rx_bits == m_rxtx_word) |
| 285 | | { |
| 286 | | if (m_rxtx_word < 8) |
| 287 | | { |
| 288 | | m_rx_buffer >>= (8 - m_rxtx_word); |
| 289 | | } |
| 290 | | |
| 291 | | m_rsr &= ~RSR_CHAR_IN_PROGRESS; |
| 292 | | |
| 293 | | if (m_ucr & UCR_PARITY_ENABLED) |
| 294 | | { |
| 295 | | m_rx_state = SERIAL_PARITY; |
| 296 | | } |
| 297 | | else |
| 298 | | { |
| 299 | | m_rx_state = SERIAL_STOP; |
| 300 | | } |
| 301 | | } |
| 302 | | break; |
| 303 | | |
| 304 | | case SERIAL_PARITY: |
| 305 | | m_rx_parity = rxd; |
| 306 | | |
| 307 | | if (m_rx_parity != (get_parity_bit(m_rx_buffer) ^ ((m_ucr & UCR_PARITY_EVEN) >> 1))) |
| 308 | | { |
| 309 | | m_next_rsr |= RSR_PARITY_ERROR; |
| 310 | | } |
| 311 | | |
| 312 | | m_rx_state = SERIAL_STOP; |
| 313 | | break; |
| 314 | | |
| 315 | | case SERIAL_STOP: |
| 316 | | if (rxd == 1) |
| 317 | | { |
| 318 | | if (!((m_rsr & RSR_SYNC_STRIP_ENABLE) && (m_rx_buffer == m_scr))) |
| 319 | | { |
| 320 | | if (!(m_rsr & RSR_OVERRUN_ERROR)) |
| 321 | | { |
| 322 | | if (m_rsr & RSR_BUFFER_FULL) |
| 323 | | { |
| 324 | | // incoming word received but last word in receive buffer has not been read |
| 325 | | m_next_rsr |= RSR_OVERRUN_ERROR; |
| 326 | | } |
| 327 | | else |
| 328 | | { |
| 329 | | // incoming word received and receive buffer is empty |
| 330 | | m_rsr |= RSR_BUFFER_FULL; |
| 331 | | m_udr = m_rx_buffer; |
| 332 | | rx_buffer_full(); |
| 333 | | } |
| 334 | | } |
| 335 | | } |
| 336 | | } |
| 337 | | else |
| 338 | | { |
| 339 | | if (m_rx_buffer) |
| 340 | | { |
| 341 | | // non-zero data word not followed by a stop bit |
| 342 | | m_next_rsr |= RSR_FRAME_ERROR; |
| 343 | | } |
| 344 | | } |
| 345 | | |
| 346 | | m_rx_state = SERIAL_START; |
| 347 | | break; |
| 348 | | } |
| 349 | | } |
| 350 | | |
| 351 | | |
| 352 | | inline void mc68901_device::tx_disabled() |
| 353 | | { |
| 354 | | switch (m_tsr & TSR_OUTPUT_MASK) |
| 355 | | { |
| 356 | | case TSR_OUTPUT_HI_Z: |
| 357 | | /* indeterminate state */ |
| 358 | | case TSR_OUTPUT_LOW: |
| 359 | | TXD(0); |
| 360 | | break; |
| 361 | | |
| 362 | | case TSR_OUTPUT_HIGH: |
| 363 | | case TSR_OUTPUT_LOOP: |
| 364 | | TXD(1); |
| 365 | | break; |
| 366 | | } |
| 367 | | } |
| 368 | | |
| 369 | | |
| 370 | | inline void mc68901_device::tx_starting() |
| 371 | | { |
| 372 | | if (m_tsr & TSR_XMIT_ENABLE) |
| 373 | | { |
| 374 | | /* enable transmitter */ |
| 375 | | TXD(1); |
| 376 | | m_xmit_state = XMIT_ON; |
| 377 | | } |
| 378 | | else |
| 379 | | { |
| 380 | | /* disable transmitter */ |
| 381 | | m_tsr |= TSR_END_OF_XMIT; |
| 382 | | m_xmit_state = XMIT_OFF; |
| 383 | | } |
| 384 | | } |
| 385 | | |
| 386 | | |
| 387 | | inline void mc68901_device::tx_break() |
| 388 | | { |
| 389 | | if (m_tsr & TSR_XMIT_ENABLE) |
| 390 | | { |
| 391 | | if (m_tsr & TSR_BREAK) |
| 392 | | { |
| 393 | | /* transmit break */ |
| 394 | | TXD(1); |
| 395 | | } |
| 396 | | else |
| 397 | | { |
| 398 | | /* enable transmitter */ |
| 399 | | m_xmit_state = XMIT_ON; |
| 400 | | } |
| 401 | | } |
| 402 | | else |
| 403 | | { |
| 404 | | /* disable transmitter */ |
| 405 | | m_tsr |= TSR_END_OF_XMIT; |
| 406 | | m_xmit_state = XMIT_OFF; |
| 407 | | } |
| 408 | | } |
| 409 | | |
| 410 | | |
| 411 | | inline void mc68901_device::tx_enabled() |
| 412 | | { |
| 413 | | switch (m_tx_state) |
| 414 | | { |
| 415 | | case SERIAL_START: |
| 416 | | if (m_tsr & TSR_UNDERRUN_ERROR) |
| 417 | | { |
| 418 | | /* buffer underrun condition */ |
| 419 | | if (m_tsr & TSR_XMIT_ENABLE) |
| 420 | | { |
| 421 | | /* transmit break */ |
| 422 | | TXD(1); |
| 423 | | } |
| 424 | | else |
| 425 | | { |
| 426 | | /* transmitter disabled */ |
| 427 | | tx_disabled(); |
| 428 | | } |
| 429 | | } |
| 430 | | else |
| 431 | | { |
| 432 | | if (m_tsr & TSR_BUFFER_EMPTY) |
| 433 | | { |
| 434 | | /* transmit buffer is empty, signal underrun error */ |
| 435 | | m_tsr |= TSR_UNDERRUN_ERROR; |
| 436 | | |
| 437 | | if (m_tsr & TSR_XMIT_ENABLE) |
| 438 | | { |
| 439 | | /* transmit break */ |
| 440 | | TXD(1); |
| 441 | | } |
| 442 | | else |
| 443 | | { |
| 444 | | /* transmitter disabled */ |
| 445 | | tx_disabled(); |
| 446 | | } |
| 447 | | } |
| 448 | | else |
| 449 | | { |
| 450 | | /* transmit start bit */ |
| 451 | | TXD(0); |
| 452 | | |
| 453 | | /* load transmit buffer */ |
| 454 | | m_tx_buffer = m_udr; |
| 455 | | m_tx_bits = 0; |
| 456 | | |
| 457 | | /* signal transmit buffer empty */ |
| 458 | | m_tsr |= TSR_BUFFER_EMPTY; |
| 459 | | tx_buffer_empty(); |
| 460 | | |
| 461 | | /* calculate parity */ |
| 462 | | m_tx_parity = get_parity_bit(m_tx_buffer); |
| 463 | | |
| 464 | | /* next bit is data */ |
| 465 | | m_tx_state = SERIAL_DATA; |
| 466 | | } |
| 467 | | } |
| 468 | | break; |
| 469 | | |
| 470 | | case SERIAL_DATA: |
| 471 | | /* transmit data bit */ |
| 472 | | TXD(m_tx_buffer & 0x01); |
| 473 | | |
| 474 | | /* shift transmit buffer */ |
| 475 | | m_tx_buffer >>= 1; |
| 476 | | m_tx_bits++; |
| 477 | | |
| 478 | | if (m_tx_bits == m_rxtx_word) |
| 479 | | { |
| 480 | | /* all data bits transferred */ |
| 481 | | if (m_ucr & UCR_PARITY_ENABLED) |
| 482 | | { |
| 483 | | /* next bit is parity */ |
| 484 | | m_tx_state = SERIAL_PARITY; |
| 485 | | } |
| 486 | | else |
| 487 | | { |
| 488 | | /* next bit is stop */ |
| 489 | | m_tx_state = SERIAL_STOP; |
| 490 | | } |
| 491 | | } |
| 492 | | break; |
| 493 | | |
| 494 | | case SERIAL_PARITY: |
| 495 | | if (m_rxtx_word < 8) |
| 496 | | { |
| 497 | | /* transmit user-defined parity bit from buffer */ |
| 498 | | TXD(m_tx_buffer & 0x01); |
| 499 | | } |
| 500 | | else |
| 501 | | { |
| 502 | | /* transmit calculated parity bit */ |
| 503 | | TXD(m_tx_parity ^ ((m_ucr & UCR_PARITY_EVEN) >> 1)); |
| 504 | | } |
| 505 | | |
| 506 | | /* next bit is stop */ |
| 507 | | m_tx_state = SERIAL_STOP; |
| 508 | | break; |
| 509 | | |
| 510 | | case SERIAL_STOP: |
| 511 | | /* transmit stop bit */ |
| 512 | | TXD(1); |
| 513 | | |
| 514 | | if (m_tsr & TSR_XMIT_ENABLE) |
| 515 | | { |
| 516 | | /* next bit is start */ |
| 517 | | m_tx_state = SERIAL_START; |
| 518 | | } |
| 519 | | else |
| 520 | | { |
| 521 | | if (m_tsr & TSR_AUTO_TURNAROUND) |
| 522 | | { |
| 523 | | /* enable transmitter */ |
| 524 | | m_tsr |= TSR_XMIT_ENABLE; |
| 525 | | |
| 526 | | /* next bit is start */ |
| 527 | | m_tx_state = SERIAL_START; |
| 528 | | } |
| 529 | | else |
| 530 | | { |
| 531 | | /* disable transmitter */ |
| 532 | | m_xmit_state = XMIT_OFF; |
| 533 | | m_tsr |= TSR_END_OF_XMIT; |
| 534 | | |
| 535 | | /* signal transmit error */ |
| 536 | | tx_error(); |
| 537 | | } |
| 538 | | } |
| 539 | | break; |
| 540 | | } |
| 541 | | } |
| 542 | | |
| 543 | | inline void mc68901_device::serial_transmit() |
| 544 | | { |
| 545 | | switch (m_xmit_state) |
| 546 | | { |
| 547 | | case XMIT_OFF: tx_disabled(); break; |
| 548 | | case XMIT_STARTING: tx_starting(); break; |
| 549 | | case XMIT_BREAK: tx_break(); break; |
| 550 | | case XMIT_ON: tx_enabled(); break; |
| 551 | | } |
| 552 | | } |
| 553 | | |
| 554 | | |
| 555 | 222 | inline void mc68901_device::timer_count(int index) |
| 556 | 223 | { |
| 557 | 224 | if (m_tmc[index] == 0x01) |
| r26687 | r26688 | |
| 691 | 358 | /* resolve callbacks */ |
| 692 | 359 | m_in_gpio_func.resolve(m_in_gpio_cb, *this); |
| 693 | 360 | m_out_gpio_func.resolve(m_out_gpio_cb, *this); |
| 694 | | m_in_si_func.resolve(m_in_si_cb, *this); |
| 695 | 361 | m_out_so_func.resolve(m_out_so_cb, *this); |
| 696 | 362 | m_out_tao_func.resolve(m_out_tao_cb, *this); |
| 697 | 363 | m_out_tbo_func.resolve(m_out_tbo_cb, *this); |
| r26687 | r26688 | |
| 835 | 501 | |
| 836 | 502 | void mc68901_device::rcv_callback() |
| 837 | 503 | { |
| 838 | | if (m_in_si_func.isnull()) |
| 839 | | receive_register_update_bit(get_in_data_bit()); |
| 840 | | else |
| 841 | | receive_register_update_bit(m_in_si_func()); |
| 504 | receive_register_update_bit(get_in_data_bit()); |
| 842 | 505 | } |
| 843 | 506 | |
| 844 | 507 | |
| r26687 | r26688 | |
| 1439 | 1102 | { |
| 1440 | 1103 | timer_input(TIMER_B, state); |
| 1441 | 1104 | } |
| 1105 | |
| 1106 | WRITE_LINE_MEMBER(mc68901_device::write_rx) |
| 1107 | { |
| 1108 | if (state) |
| 1109 | { |
| 1110 | input_callback(m_input_state | RX); |
| 1111 | } |
| 1112 | else |
| 1113 | { |
| 1114 | input_callback(m_input_state & ~RX); |
| 1115 | } |
| 1116 | } |
| 1117 | |
| 1118 | WRITE_LINE_MEMBER(mc68901_device::write_dsr) |
| 1119 | { |
| 1120 | if (state) |
| 1121 | { |
| 1122 | input_callback(m_input_state | DSR); |
| 1123 | } |
| 1124 | else |
| 1125 | { |
| 1126 | input_callback(m_input_state & ~DSR); |
| 1127 | } |
| 1128 | } |
trunk/src/emu/machine/mc68901.h
| r26687 | r26688 | |
| 87 | 87 | devcb_write_line m_out_tco_cb; |
| 88 | 88 | devcb_write_line m_out_tdo_cb; |
| 89 | 89 | |
| 90 | | devcb_read_line m_in_si_cb; |
| 91 | 90 | devcb_write_line m_out_so_cb; |
| 92 | 91 | devcb_write_line m_out_rr_cb; |
| 93 | 92 | devcb_write_line m_out_tr_cb; |
| r26687 | r26688 | |
| 122 | 121 | DECLARE_WRITE_LINE_MEMBER( tai_w ); |
| 123 | 122 | DECLARE_WRITE_LINE_MEMBER( tbi_w ); |
| 124 | 123 | |
| 124 | DECLARE_WRITE_LINE_MEMBER( write_rx ); |
| 125 | DECLARE_WRITE_LINE_MEMBER( write_dsr ); |
| 126 | |
| 125 | 127 | protected: |
| 126 | 128 | // device-level overrides |
| 127 | 129 | virtual void device_config_complete(); |
| r26687 | r26688 | |
| 140 | 142 | void take_interrupt(UINT16 mask); |
| 141 | 143 | void rx_buffer_full(); |
| 142 | 144 | void rx_error(); |
| 143 | | void tx_buffer_empty(); |
| 144 | | void tx_error(); |
| 145 | | int get_parity_bit(UINT8 b); |
| 146 | | void serial_receive(); |
| 147 | | void tx_disabled(); |
| 148 | | void tx_starting(); |
| 149 | | void tx_break(); |
| 150 | | void tx_enabled(); |
| 151 | | void serial_transmit(); |
| 152 | 145 | void timer_count(int index); |
| 153 | 146 | void timer_input(int index, int value); |
| 154 | 147 | void gpio_input(int bit, int state); |
| r26687 | r26688 | |
| 247 | 240 | |
| 248 | 241 | devcb_resolved_read8 m_in_gpio_func; |
| 249 | 242 | devcb_resolved_write8 m_out_gpio_func; |
| 250 | | devcb_resolved_read_line m_in_si_func; |
| 251 | 243 | devcb_resolved_write_line m_out_so_func; |
| 252 | 244 | devcb_resolved_write_line m_out_tao_func; |
| 253 | 245 | devcb_resolved_write_line m_out_tbo_func; |
trunk/src/mess/drivers/atarist.c
| r26687 | r26688 | |
| 1946 | 1946 | DEVCB_NULL, /* TBO */ |
| 1947 | 1947 | DEVCB_NULL, /* TCO */ |
| 1948 | 1948 | DEVCB_DRIVER_LINE_MEMBER(st_state, mfp_tdo_w), /* TDO */ |
| 1949 | | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, rx), |
| 1950 | 1949 | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, tx) |
| 1951 | 1950 | }; |
| 1952 | 1951 | |
| r26687 | r26688 | |
| 2013 | 2012 | DEVCB_NULL, /* TBO */ |
| 2014 | 2013 | DEVCB_NULL, /* TCO */ |
| 2015 | 2014 | DEVCB_DRIVER_LINE_MEMBER(st_state, mfp_tdo_w), /* TDO */ |
| 2016 | | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, rx), |
| 2017 | 2015 | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, tx) |
| 2018 | 2016 | }; |
| 2019 | 2017 | |
| r26687 | r26688 | |
| 2079 | 2077 | DEVCB_NULL, /* TBO */ |
| 2080 | 2078 | DEVCB_NULL, /* TCO */ |
| 2081 | 2079 | DEVCB_DRIVER_LINE_MEMBER(st_state, mfp_tdo_w), /* TDO */ |
| 2082 | | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, rx), |
| 2083 | 2080 | DEVCB_DEVICE_LINE_MEMBER(RS232_TAG, serial_port_device, tx) |
| 2084 | 2081 | }; |
| 2085 | 2082 | |
| r26687 | r26688 | |
| 2388 | 2385 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":1", atari_floppies, 0, st_state::floppy_formats) |
| 2389 | 2386 | |
| 2390 | 2387 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 2388 | |
| 2391 | 2389 | MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL) |
| 2390 | MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(MC68901_TAG, mc68901_device, write_rx)) |
| 2392 | 2391 | |
| 2393 | 2392 | MCFG_SERIAL_PORT_ADD("mdin", midiin_slot, "midiin") |
| 2394 | 2393 | MCFG_SERIAL_OUT_RX_HANDLER(WRITELINE(st_state, midi_rx_w)) |
| r26687 | r26688 | |
| 2446 | 2445 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":0", atari_floppies, "35dd", st_state::floppy_formats) |
| 2447 | 2446 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":1", atari_floppies, 0, st_state::floppy_formats) |
| 2448 | 2447 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 2448 | |
| 2449 | 2449 | MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL) |
| 2450 | MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(MC68901_TAG, mc68901_device, write_rx)) |
| 2450 | 2451 | |
| 2451 | 2452 | MCFG_SERIAL_PORT_ADD("mdin", midiin_slot, "midiin") |
| 2452 | 2453 | MCFG_SERIAL_OUT_RX_HANDLER(WRITELINE(st_state, midi_rx_w)) |
| r26687 | r26688 | |
| 2513 | 2514 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":0", atari_floppies, "35dd", st_state::floppy_formats) |
| 2514 | 2515 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":1", atari_floppies, 0, st_state::floppy_formats) |
| 2515 | 2516 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 2517 | |
| 2516 | 2518 | MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL) |
| 2519 | MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(MC68901_TAG, mc68901_device, write_rx)) |
| 2517 | 2520 | |
| 2518 | 2521 | MCFG_SERIAL_PORT_ADD("mdin", midiin_slot, "midiin") |
| 2519 | 2522 | MCFG_SERIAL_OUT_RX_HANDLER(WRITELINE(st_state, midi_rx_w)) |
| r26687 | r26688 | |
| 2590 | 2593 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":0", atari_floppies, "35dd", 0, st_state::floppy_formats) |
| 2591 | 2594 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG ":1", atari_floppies, 0, 0, st_state::floppy_formats) |
| 2592 | 2595 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 2593 | | MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL, NULL) |
| 2594 | 2596 | |
| 2597 | MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL) |
| 2598 | MCFG_SERIAL_OUT_RX_HANDLER(DEVWRITELINE(MC68901_TAG, mc68901_device, write_rx)) |
| 2599 | |
| 2595 | 2600 | MCFG_SERIAL_PORT_ADD("mdin", midiin_slot, "midiin") |
| 2596 | 2601 | MCFG_SERIAL_OUT_RX_HANDLER(WRITELINE(st_state, midi_rx_w)) |
| 2597 | 2602 | |