branches/alto2/src/emu/cpu/alto2/a2ether.c
| r26372 | r26373 | |
| 290 | 290 | return; |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | | /* |
| 294 | | * IDR (input data ready) conditions to wakeup the Ether task (AND): |
| 293 | /** |
| 294 | * IDR (input data ready) conditions to wakeup the Ether task |
| 295 | * signal meaining |
| 296 | * -------------------------------------- |
| 295 | 297 | * IBUSY input busy |
| 296 | 298 | * BNNE buffer next nearly empty |
| 297 | 299 | * BNE buffer nearly empty |
| 298 | 300 | * ETAC ether task active |
| 299 | 301 | * |
| 300 | | * IDR' = (IBUSY & (BNNE & (BNE' & ETAC')')')' |
| 302 | ************************************************************ |
| 303 | * +----+ |
| 304 | * BNE' >----|NAND| (i1) +----+ |
| 305 | * | o-------|NAND| (i2) +----+ |
| 306 | * ETAC' >----| | | o-------|NAND| |
| 307 | * +----+ ·---| | | o-----> IDR' |
| 308 | * | +----+ ·---| | |
| 309 | * +---+ | | +----+ |
| 310 | * BNNE' >----|INVo----· | |
| 311 | * +---+ | |
| 312 | * | |
| 313 | * IBUSY >--------------------------· |
| 314 | * |
| 315 | ************************************************************ |
| 301 | 316 | */ |
| 302 | | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_rd + m_eth.fifo_wr]; |
| 303 | | UINT8 etac = m_task == task_ether ? 0 : 1; |
| 304 | | UINT8 idr = GET_ETH_IBUSY(st) & ~(~BNNE(a49) & ~(BNE(a49) & etac)); |
| 305 | | if (idr) { |
| 317 | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd]; |
| 318 | UINT8 ETAC = m_task == task_ether ? 0 : 1; |
| 319 | UINT8 i1 = ~(BNE(a49) & ETAC); |
| 320 | UINT8 i2 = ~(~BNNE(a49) & i1); |
| 321 | UINT8 IDR = ~(GET_ETH_IBUSY(st) & i2); |
| 322 | if (0 == IDR) { |
| 306 | 323 | m_task_wakeup |= 1 << task_ether; |
| 307 | | LOG((LOG_ETH,0,"input data ready\n")); |
| 324 | LOG((LOG_ETH,0,"IDR (input data ready)\n")); |
| 308 | 325 | return; |
| 309 | 326 | } |
| 310 | 327 | |
| 311 | | /* |
| 312 | | * ODR (output data ready) conditions to wakeup the Ether task: |
| 313 | | * WLF write latch filled(?) |
| 328 | /** |
| 329 | * ODR (output data ready) conditions to wakeup the Ether task |
| 330 | * signal meaining |
| 331 | * -------------------------------------- |
| 332 | * WLF write latch full(?) |
| 314 | 333 | * BF buffer (FIFO) full |
| 315 | 334 | * OEOT output end of transmission |
| 316 | 335 | * OBUSY output busy |
| 336 | ************************************************************ |
| 337 | * +----+ |
| 338 | * WLF' >----|NAND| (o1) +----+ |
| 339 | * | o---------|NAND| |
| 340 | * BF' >----| | | | |
| 341 | * +----+ ·------| o----> ODR' |
| 342 | * | | | |
| 343 | * | ·---| | |
| 344 | * OEOT' >------------· | +----+ |
| 345 | * | |
| 346 | * | |
| 347 | * OBUSY >---------------· |
| 317 | 348 | * |
| 318 | | * ODR' = (OBUSY & OEOT' & (BF' & WLF')')' |
| 349 | ************************************************************ |
| 319 | 350 | */ |
| 320 | | UINT8 odr = GET_ETH_OBUSY(st) & ~(~GET_ETH_OEOT(st) & ~(BF(a49) & ~GET_ETH_WLF(st))); |
| 321 | | if (odr) { |
| 351 | UINT8 o1 = ~(~GET_ETH_WLF(st) & BF(a49)); |
| 352 | UINT8 ODR = ~(GET_ETH_OBUSY(st) & ~GET_ETH_OEOT(st) & o1); |
| 353 | if (0 == ODR) { |
| 322 | 354 | m_task_wakeup |= 1 << task_ether; |
| 323 | | LOG((LOG_ETH,0,"output data ready\n")); |
| 355 | LOG((LOG_ETH,0,"ODR (output data ready)\n")); |
| 324 | 356 | return; |
| 325 | 357 | } |
| 326 | 358 | |
| r26372 | r26373 | |
| 474 | 506 | m_eth.fifo[m_eth.fifo_wr] = data; |
| 475 | 507 | m_eth.fifo_wr = (m_eth.fifo_wr + 1) % ALTO2_ETHER_FIFO_SIZE; |
| 476 | 508 | |
| 477 | | // PUT_ETH_WLF(m_eth.status, 1); // set WLF (write latch full)? |
| 509 | PUT_ETH_IT(m_eth.status, 1); // set IT (input shift register full ...)? |
| 478 | 510 | |
| 479 | | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_rd + m_eth.fifo_wr]; |
| 511 | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd]; |
| 480 | 512 | if (0 == BF(a49)) |
| 481 | 513 | PUT_ETH_IDL(m_eth.status, 1); // fifo is overrun: set input data late flip flop |
| 482 | 514 | |
| r26372 | r26373 | |
| 521 | 553 | m_eth.tx_crc = f9401_7(m_eth.tx_crc, data); |
| 522 | 554 | m_eth.fifo_rd = (m_eth.fifo_rd + 1) % ALTO2_ETHER_FIFO_SIZE; |
| 523 | 555 | |
| 524 | | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_rd + m_eth.fifo_wr]; |
| 556 | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd]; |
| 525 | 557 | if (0 == BE(a49)) { |
| 526 | 558 | // the FIFO is empty now: clear the OBUSY and WLF flip flops |
| 527 | 559 | PUT_ETH_OBUSY(m_eth.status, 0); |
| r26372 | r26373 | |
| 583 | 615 | * @brief ethernet input look function |
| 584 | 616 | * |
| 585 | 617 | * Gates the contents of the FIFO to BUS[0-15], but does not |
| 586 | | * increment the read pointer; |
| 618 | * increment the read pointer |
| 587 | 619 | */ |
| 588 | 620 | void alto2_cpu_device::f1_early_eilfct() |
| 589 | 621 | { |
| r26372 | r26373 | |
| 608 | 640 | */ |
| 609 | 641 | void alto2_cpu_device::f1_early_epfct() |
| 610 | 642 | { |
| 611 | | UINT16 r = ~X_RDBITS(m_eth.status,16,10,15) & 0177777; |
| 643 | UINT16 r = 0177777; |
| 644 | UINT16 st = m_eth.status; |
| 612 | 645 | m_eth.status = 0; |
| 613 | 646 | m_eth.tx_count = 0; |
| 614 | | eth_wakeup(); |
| 615 | 647 | |
| 648 | X_WRBITS(r,16,10,10,~GET_ETH_IDL(st)); // BUS[10] = IDL (input data late) |
| 649 | X_WRBITS(r,16,11,11,~GET_ETH_COLL(st)); // BUS[11] = COLL (collision) |
| 650 | X_WRBITS(r,16,12,12,~GET_ETH_CRC(st)); // BUS[12] = CRC (CRC error) |
| 651 | X_WRBITS(r,16,13,13,~GET_ETH_ICMD(st)); // BUS[13] = ICMD (input command) |
| 652 | X_WRBITS(r,16,14,14,~GET_ETH_OCMD(st)); // BUS[13] = OCMD (output command) |
| 653 | X_WRBITS(r,16,15,15,~GET_ETH_IT(st)); // BUS[13] = IT (input ???) |
| 654 | m_bus &= r; |
| 655 | |
| 616 | 656 | LOG((LOG_ETH,3, " ←EPFCT; BUS[8-15] = STATUS (%#o)\n", r)); |
| 617 | 657 | LOG((LOG_ETH,5, " IDL' : %u\n", GET_ETH_IDL(r))); |
| 618 | 658 | LOG((LOG_ETH,5, " COLL' : %u\n", GET_ETH_COLL(r))); |
| r26372 | r26373 | |
| 620 | 660 | LOG((LOG_ETH,5, " ICMD' : %u\n", GET_ETH_ICMD(r))); |
| 621 | 661 | LOG((LOG_ETH,5, " OCMD' : %u\n", GET_ETH_OCMD(r))); |
| 622 | 662 | LOG((LOG_ETH,5, " IT' : %u\n", GET_ETH_IT(r))); |
| 623 | | |
| 624 | | m_bus &= r; |
| 663 | eth_wakeup(); |
| 625 | 664 | } |
| 626 | 665 | |
| 627 | 666 | /** |
| r26372 | r26373 | |
| 674 | 713 | PUT_ETH_OBUSY(m_eth.status, 1); // set OBUSY (output busy) |
| 675 | 714 | eth_wakeup(); |
| 676 | 715 | // if the FIFO is full, stop wakeup and kick off the timer |
| 677 | | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_rd + m_eth.fifo_wr]; |
| 716 | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd]; |
| 678 | 717 | if (0 == BF(a49)) { |
| 679 | 718 | m_task_wakeup &= ~(1 << task_ether); |
| 680 | 719 | m_eth.tx_timer->adjust(attotime::from_usec(5.44), 0); |
| r26372 | r26373 | |
| 682 | 721 | } |
| 683 | 722 | |
| 684 | 723 | /** |
| 685 | | * @brief f2_eosfct late: ethernet output start function |
| 724 | * @brief ethernet output start function |
| 686 | 725 | * |
| 687 | 726 | * Sets the OBUSY flip flop in the interface, starting data |
| 688 | 727 | * wakeups to fill the FIFO for output. When the FIFO is full, |
| r26372 | r26373 | |
| 698 | 737 | } |
| 699 | 738 | |
| 700 | 739 | /** |
| 701 | | * @brief f2_erbfct late: ethernet reset branch function |
| 740 | * @brief ethernet reset branch function |
| 702 | 741 | * |
| 703 | 742 | * This command dispatch function merges the ICMD and OCMD flip flops |
| 704 | 743 | * into NEXT[6-7]. These flip flops are the means of communication |
| r26372 | r26373 | |
| 737 | 776 | * @brief ethernet branch function |
| 738 | 777 | * |
| 739 | 778 | * ORs a 1 into NEXT[6] if a collision is detected. |
| 740 | | * ORs a 1 into NEXT[7] if an input data late is detected, |
| 741 | | * or a SIO with AC0[14-15] non-zero is issued, |
| 742 | | * or if the transmitter is gone |
| 743 | | * or if the receiver is gone. |
| 779 | * ORs a 1 into NEXT[7] if |
| 780 | * an input data late is detected, |
| 781 | * or a SIO with AC0[14-15] non-zero is issued (ICMD or OCMD), |
| 782 | * or if the receiver is gone (IGONE) |
| 783 | * or if the transmitter is gone (OGONE). |
| 744 | 784 | */ |
| 745 | 785 | void alto2_cpu_device::f2_late_ebfct() |
| 746 | 786 | { |
| r26372 | r26373 | |
| 757 | 797 | } |
| 758 | 798 | |
| 759 | 799 | /** |
| 760 | | * @brief f2_ecbfct late: ethernet countdown branch function |
| 800 | * @brief ethernet countdown branch function |
| 761 | 801 | * |
| 762 | 802 | * The BE' (buffer empty) signal is output D0 of PROM a49 |
| 763 | 803 | * ORs a one into NEXT[7] if the FIFO is not empty. |
| r26372 | r26373 | |
| 765 | 805 | void alto2_cpu_device::f2_late_ecbfct() |
| 766 | 806 | { |
| 767 | 807 | UINT16 r = 0; |
| 768 | | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_rd + m_eth.fifo_wr]; |
| 808 | UINT8 a49 = m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd]; |
| 769 | 809 | X_WRBITS(r,10,7,7,~BE(a49)); |
| 770 | 810 | LOG((LOG_ETH,3, " ECBFCT; NEXT[7] = FIFO %sempty (%#o | %#o)\n", r ? "not " : "is ", m_next2, r)); |
| 771 | 811 | m_next2 |= r; |
| 772 | 812 | } |
| 773 | 813 | |
| 774 | 814 | /** |
| 775 | | * @brief f2_eisfct late: ethernet input start function |
| 815 | * @brief ethernet input start function |
| 776 | 816 | * |
| 777 | 817 | * Sets the IBUSY flip flop in the interface, causing it to hunt |
| 778 | 818 | * for the beginning of a packet: silence on the Ether followed |
| r26372 | r26373 | |
| 831 | 871 | m_eth.tx_timer->reset(); |
| 832 | 872 | |
| 833 | 873 | m_eth.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::rx_breath_of_life),this)); |
| 834 | | if (m_eth.breath_of_life) |
| 835 | | m_eth.rx_timer->adjust(attotime::from_seconds(m_eth.breath_of_life), 0); |
| 836 | | else |
| 837 | | m_eth.rx_timer->reset(); |
| 874 | m_eth.rx_timer->reset(); |
| 838 | 875 | } |
| 839 | 876 | |
| 840 | 877 | void alto2_cpu_device::exit_ether() |
| r26372 | r26373 | |
| 864 | 901 | if (config) |
| 865 | 902 | m_eth.breath_of_life = breath_of_life_sec[(config->read() >> 4) & 7]; |
| 866 | 903 | logerror("Ethernet breath_of_life %d sec\n", m_eth.breath_of_life); |
| 904 | if (m_eth.breath_of_life) |
| 905 | m_eth.rx_timer->adjust(attotime::from_seconds(m_eth.breath_of_life), 0); |
| 867 | 906 | } |