Exemple #1
0
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();
		}
	}
}
Exemple #2
0
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();
		}
	}
}
Exemple #3
0
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;
	}

}
Exemple #4
0
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;
		}
	}
}