void threecom3c505_device::recv_cb(UINT8 *data, int length) { if (length < ETHERNET_ADDR_SIZE || !ethernet_packet_is_for_me(data)) { // skip packet } else if (!m_rx_fifo.put(data, length)) { m_netstat.tot_recv++; m_netstat.err_ovrrun++; // fifo overrun LOG1(("recv_cb: data_length=%x !!! RX FIFO OVERRUN !!!", length)); } else { m_netstat.tot_recv++; LOG2(("recv_cb: data_length=%x m_rx_pending=%d", length, m_rx_pending)); if (m_rx_data_buffer.get_length() == 0) { m_rx_fifo.get(&m_rx_data_buffer); } if (!m_command_pending && m_rx_pending > 0 && m_rx_data_buffer.get_length() > 0) { m_rx_pending--; set_command_pending(1); do_receive_command(); } } }
void threecom3c505_device::set_command_pending(int onoff) { m_command_pending = onoff; LOG2(("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")); //- verbose = onoff ? 1 : 2; if (!m_command_pending) { // clear previous command byte m_command_buffer[0] = 0; m_mc_f9_pending = 0; m_wait_for_ack = 0; if (m_rx_pending > 0 && m_rx_data_buffer.get_length() > 0) { m_rx_pending--; m_command_pending = 1; LOG2(("set_command_pending %d m_rx_pending=%d", m_command_pending, m_rx_pending)); do_receive_command(); } } }
void threecom3c505_device::set_command_pending(int state) { LOG2(("set_command_pending %d -> %d m_wait_for_ack=%d m_wait_for_nak=%d m_rx_pending=%d%s", m_command_pending, state, m_wait_for_ack, m_wait_for_nak, m_rx_pending, state ? "" :"\n")); //- verbose = onoff ? 1 : 2; switch (state) { case 0: // command is no longer pending m_command_pending = 0; // clear previous command byte m_command_buffer[0] = 0; m_wait_for_ack = 0; m_wait_for_nak = 0; do_receive_command(); break; case 1: // command is pending m_command_pending = 1; break; case 2: // wait for nak/ack if (m_microcode_running && m_microcode_version == APOLLO_MC_VERSION_SR10_4) { m_wait_for_nak = 1; } else { m_wait_for_ack = 1; } break; default: LOG(("set_command_pending %d unexpected" , state)); break; } }
void threecom3c505_device::do_command() { // default to successful completion m_response.command = m_command_buffer[0] + CMD_RESPONSE_OFFSET; m_response.length = 1; m_response.data.failed = 0; // successful completion switch (m_command_buffer[0]) { case CMD_RESET: // 0x00 // FIXME: // device_reset(); break; case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01 m_i82586_config = m_program_buffer.get_word(1); break; case CMD_RECEIVE_PACKET: // 0x08 if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.get(&m_rx_data_buffer)) { // receive data not yet available m_rx_pending++; set_command_pending(0); } else { do_receive_command(); } return; // break; case CMD_MC_F9: m_response.command = CMD_TRANSMIT_PACKET_COMPLETE; // fall through case CMD_TRANSMIT_PACKET: // 0x09 case CMD_TRANSMIT_PACKET_18: // 0x18 m_response.length = 8; m_response.data.xmit_resp.buf_ofs = 0; m_response.data.xmit_resp.buf_seg = 0; m_response.data.xmit_resp.c_stat = 0; // successful completion m_response.data.xmit_resp.status = 0; break; case CMD_EXECUTE_PROGRAM: // 0x0e m_response.length = 0; m_microcode_running = 1; m_microcode_version = m_program_buffer.get_word(1); break; case CMD_NETWORK_STATISTICS: // 0x0a m_response.length = sizeof(struct Netstat); // response data must be LSB first! m_response.data.netstat.tot_recv = lsb_first(m_netstat.tot_recv); m_response.data.netstat.tot_xmit = lsb_first(m_netstat.tot_xmit); m_response.data.netstat.err_CRC = lsb_first(m_netstat.err_CRC); m_response.data.netstat.err_align = lsb_first(m_netstat.err_align); m_response.data.netstat.err_res = lsb_first(m_netstat.err_res); m_response.data.netstat.err_ovrrun = lsb_first(m_netstat.err_ovrrun); break; case CMD_ADAPTER_INFO: // 0x11 m_response.length = sizeof(struct Info); // FIXME: replace test data; must be LSB first! m_response.data.info.minor_vers = 1; m_response.data.info.major_vers = 2; m_response.data.info.ROM_cksum = lsb_first(3); m_response.data.info.RAM_sz = lsb_first(4); m_response.data.info.free_ofs = lsb_first(5); m_response.data.info.free_seg = lsb_first(6); break; case CMD_LOAD_MULTICAST_LIST:// 0x0b if (m_command_buffer[1] > sizeof(m_multicast_list) || (m_command_buffer[1] % ETHERNET_ADDR_SIZE) != 0) { LOG(("CMD_LOAD_MULTICAST_LIST - !!! unexpected data size %d !!!", m_command_buffer[1])); } else { memset(m_multicast_list, 0 , sizeof(m_multicast_list)); memcpy(m_multicast_list, m_command_buffer+2 , m_command_buffer[1]-2); set_filter_list(); } break; case CMD_SET_STATION_ADDRESS: // 0x10 if (m_command_buffer[1] != sizeof(m_station_address)) { LOG(("CMD_SET_STATION_ADDRESS - !!! unexpected data size %d !!!", m_command_buffer[1])); memset(m_station_address, 0 , sizeof(m_station_address)); } else { memcpy(m_station_address, m_command_buffer+2 , m_command_buffer[1]); } set_filter_list(); set_mac((char *)m_station_address); break; case CMD_CONFIGURE_82586: // 0x02 case CMD_DOWNLOAD_PROGRAM: // 0x0d case CMD_MC_17: // 0x17 default: break; } m_response_index = 0; m_response_length = m_response.length + 2; m_status |= ACRF; /* adapter command register full */ if (m_control & CMDE) { switch (m_command_buffer[0]) { case CMD_NETWORK_STATISTICS: // 0x0a case CMD_DOWNLOAD_PROGRAM: // 0xd case CMD_EXECUTE_PROGRAM: // 0x0e case CMD_ADAPTER_INFO: // 0x11 // interrupt later m_timer->adjust( attotime::from_msec(5)); break; default: // interrupt at once set_interrupt(ASSERT_LINE); break; } } }