src/mess/machine/3c505.c
| r15073 | r15074 | |
| 107 | 107 | enum |
| 108 | 108 | { |
| 109 | 109 | /* host PCB commands */ |
| 110 | CMD_RESET = 0x00, |
| 110 | 111 | CMD_CONFIGURE_ADAPTER_MEMORY = 0x01, |
| 111 | 112 | CMD_CONFIGURE_82586 = 0x02, |
| 112 | 113 | CMD_STATION_ADDRESS = 0x03, |
| r15073 | r15074 | |
| 132 | 133 | CMD_MC_FA =0xfa, |
| 133 | 134 | |
| 134 | 135 | /*adapter PCB commands */ |
| 136 | CMD_RESET_RESPONSE = 0x30, |
| 135 | 137 | CMD_CONFIGURE_ADAPTER_RESPONSE = 0x31, |
| 136 | 138 | CMD_CONFIGURE_82586_RESPONSE = 0x32, |
| 137 | 139 | CMD_ADDRESS_RESPONSE = 0x33, |
| r15073 | r15074 | |
| 236 | 238 | m_control = 0; |
| 237 | 239 | m_command_index = 0; |
| 238 | 240 | m_command_pending = 0; |
| 241 | m_mc_f9_pending = 0; |
| 242 | m_wait_for_ack = 0; |
| 239 | 243 | m_rx_data_index = 0; |
| 240 | 244 | m_rx_pending = 0; |
| 241 | 245 | m_tx_data_length = 0; |
| r15073 | r15074 | |
| 244 | 248 | m_microcode_running = 0; |
| 245 | 249 | m_microcode_version = 0; |
| 246 | 250 | m_i82586_config = 0; |
| 251 | |
| 252 | // FIXME: test data |
| 253 | m_netstat.tot_recv = 1; |
| 254 | m_netstat.tot_xmit = 2; |
| 255 | m_netstat.err_CRC = 3; |
| 256 | m_netstat.err_align = 4; |
| 257 | m_netstat.err_res = 5; |
| 258 | m_netstat.err_ovrrun = 6; |
| 259 | |
| 247 | 260 | memset(m_station_address, 0 , sizeof(m_station_address)); |
| 248 | 261 | memset(m_multicast_list, 0 , sizeof(m_multicast_list)); |
| 249 | 262 | set_filter_list(); |
| r15073 | r15074 | |
| 432 | 445 | if (setfilter != NULL) |
| 433 | 446 | { |
| 434 | 447 | int node_id = (((m_station_address[3] << 8) + m_station_address[4]) << 8) + m_station_address[5]; |
| 435 | | LOG1(("set_filter_list node_id=%x",node_id)); |
| 448 | LOG2(("set_filter_list node_id=%x",node_id)); |
| 436 | 449 | (*setfilter)(this, node_id); |
| 437 | 450 | } |
| 438 | 451 | |
| r15073 | r15074 | |
| 446 | 459 | { |
| 447 | 460 | if (state != irq_state) |
| 448 | 461 | { |
| 449 | | LOG1(("set_interrupt(%d)",state)); |
| 462 | LOG2(("set_interrupt(%d)",state)); |
| 450 | 463 | if (set_irq != NULL) |
| 451 | 464 | { |
| 452 | 465 | (*set_irq)(this, state); |
| r15073 | r15074 | |
| 476 | 489 | logerror("%s: Command ", cpu_context()); |
| 477 | 490 | switch (m_command_buffer[0]) |
| 478 | 491 | { |
| 492 | case CMD_RESET: // 0x00 |
| 493 | logerror("CMD_RESET"); |
| 494 | break; |
| 479 | 495 | case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01 |
| 480 | 496 | logerror("CMD_CONFIGURE_ADAPTER_MEMORY"); |
| 481 | 497 | break; |
| r15073 | r15074 | |
| 517 | 533 | break; |
| 518 | 534 | |
| 519 | 535 | case CMD_MC_F8: // 0xf8 |
| 520 | | logerror("CMD_MC_F8"); |
| 536 | logerror("!!! CMD_MC_F8"); |
| 521 | 537 | break; |
| 522 | 538 | case CMD_MC_F9: // 0xf9 |
| 523 | 539 | logerror("CMD_MC_F9"); |
| 524 | 540 | break; |
| 525 | 541 | case CMD_MC_FA: // 0xfa |
| 526 | | logerror("CMD_MC_FA"); |
| 542 | logerror("!!! CMD_MC_FA"); |
| 527 | 543 | break; |
| 528 | 544 | |
| 529 | 545 | default: |
| r15073 | r15074 | |
| 533 | 549 | switch (m_command_buffer[0]) |
| 534 | 550 | { |
| 535 | 551 | case CMD_MC_F9: // 0xf9 |
| 536 | | // logerror(" (%02x, length=00)", m_command_buffer[0]); |
| 552 | logerror(" (%02x, length=00)", m_command_buffer[0]); |
| 537 | 553 | break; |
| 538 | 554 | |
| 539 | 555 | default: |
| r15073 | r15074 | |
| 557 | 573 | logerror("%s: Response ", cpu_context()); |
| 558 | 574 | switch (m_response.command) |
| 559 | 575 | { |
| 576 | case CMD_RESET_RESPONSE: // 0x30 |
| 577 | logerror("CMD_RESET_RESPONSE"); |
| 578 | break; |
| 560 | 579 | case CMD_CONFIGURE_ADAPTER_RESPONSE: // 0x31 |
| 561 | 580 | logerror("CMD_CONFIGURE_ADAPTER_RESPONSE"); |
| 562 | 581 | break; |
| r15073 | r15074 | |
| 594 | 613 | logerror("CMD_TRANSMIT_PACKET_18_COMPLETE"); |
| 595 | 614 | break; |
| 596 | 615 | case CMD_MC_E1_RESPONSE: // 0xe1 |
| 597 | | logerror("CMD_MC_E1_RESPONSE"); |
| 616 | logerror("!!! CMD_MC_E1_RESPONSE"); |
| 598 | 617 | break; |
| 599 | 618 | case CMD_MC_E2_RESPONSE: // 0xe2 |
| 600 | | logerror("CMD_MC_E2_RESPONSE"); |
| 619 | logerror("!!! CMD_MC_E2_RESPONSE"); |
| 601 | 620 | break; |
| 602 | 621 | default: |
| 603 | 622 | logerror("!!! Unexpected Response !!!"); |
| r15073 | r15074 | |
| 658 | 677 | void threecom3c505_device::set_command_pending(int onoff) |
| 659 | 678 | { |
| 660 | 679 | m_command_pending = onoff; |
| 661 | | LOG1(("set_command_pending %d m_rx_pending=%d m_rx_data_buffer.get_length()=%x%s", m_command_pending, m_rx_pending, m_rx_data_buffer.get_length(), onoff ? "" :"\n")); |
| 680 | LOG2(("set_command_pending %d m_rx_pending=%d m_rx_data_buffer.get_length()=%x%s", |
| 681 | m_command_pending, m_rx_pending, m_rx_data_buffer.get_length(), onoff ? "" :"\n")); |
| 662 | 682 | |
| 683 | //- verbose = onoff ? 1 : 2; |
| 684 | |
| 663 | 685 | if (!m_command_pending) |
| 664 | 686 | { |
| 665 | 687 | // clear previous command byte |
| 666 | 688 | m_command_buffer[0] = 0; |
| 667 | 689 | |
| 690 | m_mc_f9_pending = 0; |
| 691 | m_wait_for_ack = 0; |
| 692 | |
| 668 | 693 | if (m_rx_pending > 0 && m_rx_data_buffer.get_length() > 0) |
| 669 | 694 | { |
| 670 | 695 | m_rx_pending--; |
| 671 | 696 | m_command_pending = 1; |
| 672 | 697 | |
| 673 | | LOG1(("set_command_pending %d m_rx_pending=%d", m_command_pending, m_rx_pending)); |
| 698 | LOG2(("set_command_pending %d m_rx_pending=%d", m_command_pending, m_rx_pending)); |
| 674 | 699 | |
| 675 | 700 | do_receive_command(); |
| 676 | 701 | } |
| r15073 | r15074 | |
| 690 | 715 | |
| 691 | 716 | switch (m_command_buffer[0]) |
| 692 | 717 | { |
| 718 | case CMD_RESET: // 0x00 |
| 719 | // FIXME: |
| 720 | // device_reset(); |
| 721 | break; |
| 722 | |
| 693 | 723 | case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01 |
| 694 | 724 | m_i82586_config = m_program_buffer.get_word(1); |
| 695 | 725 | break; |
| 696 | 726 | |
| 697 | | // case CMD_MC_F8: |
| 698 | 727 | case CMD_RECEIVE_PACKET: // 0x08 |
| 699 | 728 | if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.get(&m_rx_data_buffer)) |
| 700 | 729 | { |
| 730 | // receive data not yet available |
| 701 | 731 | m_rx_pending++; |
| 702 | 732 | set_command_pending(0); |
| 703 | 733 | } |
| r15073 | r15074 | |
| 708 | 738 | return; |
| 709 | 739 | // break; |
| 710 | 740 | |
| 711 | | // case CMD_MC_F8: |
| 712 | | case CMD_MC_F9: |
| 713 | | // case CMD_MC_FA: |
| 714 | | // FIXME: |
| 741 | case CMD_MC_F9: |
| 715 | 742 | m_response.command = CMD_TRANSMIT_PACKET_COMPLETE; |
| 716 | | // break; |
| 743 | // fall through |
| 717 | 744 | |
| 718 | 745 | case CMD_TRANSMIT_PACKET: // 0x09 |
| 719 | 746 | case CMD_TRANSMIT_PACKET_18: // 0x18 |
| r15073 | r15074 | |
| 732 | 759 | |
| 733 | 760 | case CMD_NETWORK_STATISTICS: // 0x0a |
| 734 | 761 | m_response.length = sizeof(struct Netstat); |
| 735 | | // FIXME: replace test data; must be LSB first! |
| 736 | | m_response.data.netstat.tot_recv = 1; |
| 737 | | m_response.data.netstat.tot_xmit = 2; |
| 738 | | m_response.data.netstat.err_CRC = 3; |
| 739 | | m_response.data.netstat.err_align = 4; |
| 740 | | m_response.data.netstat.err_res = 5; |
| 741 | | m_response.data.netstat.err_ovrrun = 6; |
| 762 | // response data must be LSB first! |
| 763 | m_response.data.netstat.tot_recv = lsb_first(m_netstat.tot_recv); |
| 764 | m_response.data.netstat.tot_xmit = lsb_first(m_netstat.tot_xmit); |
| 765 | m_response.data.netstat.err_CRC = lsb_first(m_netstat.err_CRC); |
| 766 | m_response.data.netstat.err_align = lsb_first(m_netstat.err_align); |
| 767 | m_response.data.netstat.err_res = lsb_first(m_netstat.err_res); |
| 768 | m_response.data.netstat.err_ovrrun = lsb_first(m_netstat.err_ovrrun); |
| 742 | 769 | break; |
| 743 | 770 | |
| 744 | 771 | case CMD_ADAPTER_INFO: // 0x11 |
| r15073 | r15074 | |
| 800 | 827 | case CMD_EXECUTE_PROGRAM: // 0x0e |
| 801 | 828 | case CMD_ADAPTER_INFO: // 0x11 |
| 802 | 829 | // interrupt later |
| 803 | | m_timer->adjust( attotime::from_msec(10)); |
| 830 | m_timer->adjust( attotime::from_msec(5)); |
| 804 | 831 | break; |
| 805 | 832 | |
| 806 | 833 | default: |
| r15073 | r15074 | |
| 837 | 864 | |
| 838 | 865 | void threecom3c505_device::recv_cb(UINT8 *data, int length) |
| 839 | 866 | { |
| 867 | |
| 840 | 868 | if (length < ETHERNET_ADDR_SIZE || !ethernet_packet_is_for_me(data)) |
| 841 | 869 | { |
| 842 | 870 | // skip packet |
| 843 | 871 | } |
| 844 | | // else if (m_command_pending && m_command_buffer[0] == CMD_MC_F9) |
| 845 | | // { |
| 846 | | // LOG(("recv_cb: data_length=%x !!!! skipped data while CMD_MC_F9 is pending!", length)); |
| 847 | | // } |
| 848 | 872 | else if (!m_rx_fifo.put(data, length)) |
| 849 | 873 | { |
| 874 | m_netstat.tot_recv++; |
| 875 | m_netstat.err_ovrrun++; |
| 850 | 876 | // fifo overrun |
| 851 | 877 | LOG1(("recv_cb: data_length=%x !!! RX FIFO OVERRUN !!!", length)); |
| 878 | |
| 852 | 879 | } |
| 853 | 880 | else |
| 854 | 881 | { |
| 855 | | LOG1(("recv_cb: data_length=%x m_rx_pending=%d", length, m_rx_pending)); |
| 882 | m_netstat.tot_recv++; |
| 883 | LOG2(("recv_cb: data_length=%x m_rx_pending=%d", length, m_rx_pending)); |
| 856 | 884 | |
| 857 | 885 | if (m_rx_data_buffer.get_length() == 0) |
| 858 | 886 | { |
| 859 | 887 | m_rx_fifo.get(&m_rx_data_buffer); |
| 860 | 888 | } |
| 861 | 889 | |
| 862 | | // if (m_command_pending && m_command_buffer[0] == CMD_MC_F9) |
| 863 | | // { |
| 864 | | // verbose = 2; |
| 865 | | // } |
| 866 | | |
| 867 | 890 | if (!m_command_pending && m_rx_pending > 0 |
| 868 | 891 | && m_rx_data_buffer.get_length() > 0) |
| 869 | 892 | { |
| r15073 | r15074 | |
| 871 | 894 | set_command_pending(1); |
| 872 | 895 | do_receive_command(); |
| 873 | 896 | } |
| 874 | | |
| 875 | | // guessing! |
| 876 | | // else if (m_control & CMDE) |
| 877 | | // { |
| 878 | | // m_status |= ACRF; /* adapter command register full */ |
| 879 | | // |
| 880 | | // LOG(("recv_cb - set_interrupt(%d)",ASSERT_LINE)); |
| 881 | | // set_interrupt(ASSERT_LINE); |
| 882 | | // } |
| 883 | 897 | } |
| 884 | 898 | } |
| 885 | 899 | |
| r15073 | r15074 | |
| 913 | 927 | // spurious data; set command register empty |
| 914 | 928 | m_command_index = 0; |
| 915 | 929 | m_status |= HCRE; |
| 916 | | // verbose = 2; |
| 917 | 930 | break; |
| 918 | 931 | |
| 919 | 932 | case CMD_MC_F9: |
| r15073 | r15074 | |
| 997 | 1010 | |
| 998 | 1011 | LOG2(("FIXME: reading 3C505 Command Register at offset %02x with index %02x = %02x", |
| 999 | 1012 | PORT_COMMAND, m_response_index, data)); |
| 1013 | |
| 1014 | if (m_mc_f9_pending == 1) |
| 1015 | { |
| 1016 | m_mc_f9_pending++; |
| 1017 | } |
| 1000 | 1018 | } |
| 1001 | 1019 | else |
| 1002 | 1020 | { |
| r15073 | r15074 | |
| 1036 | 1054 | |
| 1037 | 1055 | case CMD_TRANSMIT_PACKET_COMPLETE: |
| 1038 | 1056 | case CMD_TRANSMIT_PACKET_18_COMPLETE: |
| 1057 | m_netstat.tot_xmit++; |
| 1058 | |
| 1039 | 1059 | if(!send(m_tx_data_buffer.get_data(), m_tx_data_buffer.get_length())) |
| 1040 | 1060 | { |
| 1041 | 1061 | // FIXME: failed to send the ethernet packet |
| r15073 | r15074 | |
| 1050 | 1070 | } |
| 1051 | 1071 | |
| 1052 | 1072 | m_tx_data_buffer.reset(); |
| 1053 | | set_command_pending(0); |
| 1073 | if (m_command_buffer[0] != CMD_MC_F9) |
| 1074 | { |
| 1075 | // set_command_pending(0); |
| 1076 | m_wait_for_ack = 1; |
| 1077 | } |
| 1054 | 1078 | break; |
| 1055 | 1079 | |
| 1056 | 1080 | case CMD_DOWNLOAD_PROGRAM_RESPONSE: |
| 1057 | 1081 | m_program_buffer.reset(); |
| 1058 | | set_command_pending(0); |
| 1082 | // set_command_pending(0); |
| 1083 | m_wait_for_ack = 1; |
| 1059 | 1084 | break; |
| 1060 | 1085 | |
| 1061 | 1086 | default: |
| 1062 | | set_command_pending(0); |
| 1087 | // set_command_pending(0); |
| 1088 | m_wait_for_ack = 1; |
| 1063 | 1089 | break; |
| 1064 | 1090 | } |
| 1065 | 1091 | } |
| r15073 | r15074 | |
| 1198 | 1224 | m_status &= ~HRDY; /* data register no longer ready */ |
| 1199 | 1225 | m_rx_data_buffer.log("Rx Data"); |
| 1200 | 1226 | m_rx_data_buffer.reset(); |
| 1201 | | set_command_pending(0); |
| 1227 | // set_command_pending(0); |
| 1228 | m_wait_for_ack = 1; |
| 1202 | 1229 | } |
| 1203 | 1230 | } |
| 1204 | 1231 | |
| r15073 | r15074 | |
| 1239 | 1266 | switch (data & HSF_PCB_MASK) |
| 1240 | 1267 | { |
| 1241 | 1268 | case HSF_PCB_ACK: // HSF1 |
| 1269 | if (m_wait_for_ack) |
| 1270 | { |
| 1271 | set_command_pending(0); |
| 1272 | } |
| 1242 | 1273 | break; |
| 1243 | 1274 | case HSF_PCB_NAK: // HSF2 |
| 1244 | 1275 | if (m_microcode_running) |
| r15073 | r15074 | |
| 1257 | 1288 | m_command_index = 0; |
| 1258 | 1289 | m_status |= HCRE; /* command register empty */ |
| 1259 | 1290 | |
| 1291 | if (m_command_buffer[0] == CMD_MC_F9) |
| 1292 | { |
| 1293 | m_mc_f9_pending = 1; |
| 1294 | //- verbose = 2; |
| 1295 | } |
| 1296 | |
| 1260 | 1297 | if (data == 0x00) |
| 1261 | 1298 | { |
| 1262 | 1299 | // hardware reset |
| r15073 | r15074 | |
| 1294 | 1331 | m_status |= ASF_PCB_END; |
| 1295 | 1332 | } |
| 1296 | 1333 | |
| 1334 | if (m_mc_f9_pending == 2) |
| 1335 | { |
| 1336 | m_mc_f9_pending = 0; |
| 1337 | set_command_pending(0); |
| 1338 | } |
| 1339 | |
| 1297 | 1340 | m_control = data; |
| 1298 | 1341 | } |
| 1299 | 1342 | |