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
UINT8 threecom3c505_device::read_data_port()
{
	UINT8 data;
	UINT16 data_length = m_rx_data_buffer.get_length();
	// DomainOS will read  words (i.e. even number of bytes); must handle packets with odd byte length
	UINT16 even_data_length = (data_length + 1) & ~1;

	if (m_rx_data_index < even_data_length)
	{
		// eventually prepend data length (for CMD_MC_E1_RESPONSE)
		data = m_rx_data_index == -2 ? (data_length & 0xff) : //
				m_rx_data_index == -1 ? (data_length << 8) : //
						m_rx_data_buffer.get(m_rx_data_index);

		m_rx_data_index++;

		if (m_rx_data_index == even_data_length)
		{
			m_status &= ~HRDY; /* data register no longer ready */
			m_rx_data_buffer.log("Rx Data");
			m_rx_data_buffer.reset();
			set_command_pending(2);
		}
	}
	else
	{
		// FIXME: should never happen
		data = 0xff;
		LOG(("read_data_port: unexpected reading data at index %04x)", m_rx_data_index));
	}
	return data;
}
Exemple #3
0
void threecom3c505_device::do_receive_command()
{
	// receive pending and no other command is pending
	if (m_rx_pending > 0 && !m_command_pending)
	{
		if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.is_empty())
		{
			m_rx_fifo.get(&m_rx_data_buffer);
		}

		// receive data available ?
		if (m_rx_data_buffer.get_length() > 0)
		{
			LOG2(("do_receive_command - data_length=%x rx_pending=%d",
							m_rx_data_buffer.get_length(), m_rx_pending));

			m_rx_pending--;
			set_command_pending(1);

			// preset receive response PCB
			memcpy(&m_response, &m_rcv_response, sizeof(m_rcv_response));

//          m_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
//          m_response.length = 16;
//          m_response.data.rcv_resp.buf_ofs = htole16(0);
//          m_response.data.rcv_resp.buf_seg = htole16(0);
//          m_response.data.rcv_resp.buf_len = htole16(buf_len);

			// htole16 and friends are not portable beyond Linux.  It's named differently on *BSD and differently again on OS X.  Avoid!
			m_response.data.rcv_resp.pkt_len = uint16_to_le(m_rx_data_buffer.get_length());
			m_response.data.rcv_resp.timeout = 0; // successful completion
			m_response.data.rcv_resp.status  = uint16_to_le(m_rx_data_buffer.get_length() > 0 ? 0 : 0xffff);
			m_response.data.rcv_resp.timetag = 0; // TODO: time tag

			// compute and check no of bytes to be DMA'ed (must be even)
			UINT16 buf_len = uint16_from_le(m_response.data.rcv_resp.buf_len) & ~1;
			if (m_rx_data_buffer.get_length() > buf_len)
			{
				LOG1(("do_receive_command !!! buffer size too small (%d < %d)", buf_len, m_rx_data_buffer.get_length()));
				m_response.data.rcv_resp.pkt_len = uint16_to_le(buf_len);
				m_response.data.rcv_resp.status = 0xffff;
			}
			else
			{
				buf_len = (m_rx_data_buffer.get_length() + 1) & ~1;
				m_response.data.rcv_resp.buf_len = uint16_to_le(buf_len);
			}

			m_response_length = m_response.length + 2;
			m_response_index = 0;

			m_status |= ACRF; /* set adapter command register full */
			if (m_control & CMDE)
			{
				set_interrupt(ASSERT_LINE);
			}
		}
	}
}
Exemple #4
0
UINT8 threecom3c505_device::read_data_port(){
	UINT8 data;
	UINT16 data_length = m_rx_data_buffer.get_length();
	// DomainOS will read  words (i.e. even number of bytes); must handle packets with odd byte length
	UINT16 even_data_length = (data_length+1) & ~1;

	if (m_rx_data_index < even_data_length)
	{
		// eventually prepend data length (for CMD_MC_E1_RESPONSE)
		data = m_rx_data_index == -2 ? (data_length & 0xff) : //
				m_rx_data_index == -1 ? (data_length << 8) : //
				m_rx_data_buffer.get(m_rx_data_index);

		m_rx_data_index++;

		if (m_rx_data_index == even_data_length)
		{
			m_status &= ~HRDY; /* data register no longer ready */
			m_rx_data_buffer.log("Rx Data");
			m_rx_data_buffer.reset();
//          set_command_pending(0);
			m_wait_for_ack = 1;
		}
	}

#if 0
	else if (m_rx_data_index == data_length && (data_length & 1))
	{
		// data length is odd, pad with 0 to next even size
		data = 0;
		m_rx_data_index++;
		LOG(("!!!: padding 3C505 Rx Data with odd data length %2x with value %02x", data_length, data));
	}
#endif

	else
	{
		// FIXME: should never happen
		data = 0xff;
		m_status &= ~HRDY; /* data register no longer ready */
		set_command_pending(0);
		LOG(("UNEXPECTED: reading 3C505 data Register as %02x (data_length=%02x)", data, data_length));
	}
	return data;
}
Exemple #5
0
void threecom3c505_device::write_command_port(UINT8 data)
{
	LOG2(("writing 3C505 command port %02x - m_status=%02x m_control=%02x m_command_index=%02x",
			data, m_status, m_control, m_command_index));

	if (m_command_index == 0)
	{
		switch (data)
		{
		case 0:
			LOG2(("!!! writing 3C505 Command Register = %02x", data));
			// spurious data; reset?
			break;

		case CMD_TRANSMIT_PACKET_F9:
			// read data length from data port (not from command port)
			m_tx_data_buffer.reset();
			m_status |= HRDY; /* data register ready */
			m_command_buffer[m_command_index++] = data;
			set_command_pending(1);
			break;

		default:
			m_command_buffer[m_command_index++] = data;
			set_command_pending(1);
			break;
		}
	}
	else if ((m_control & HSF_PCB_MASK) != HSF_PCB_END)
	{
		m_command_buffer[m_command_index++] = data;
	}
	else
	{
		m_status &= ~ASF_PCB_MASK;
		m_status |= (data == m_command_index) ? ASF_PCB_END : ASF_PCB_NAK;

		log_command();

		switch (m_command_buffer[0])
		{
		case CMD_TRANSMIT_PACKET_18:
			// read transmit data into m_tx_data_buffer
			m_tx_data_buffer.reset();
			m_tx_data_length = m_command_buffer[2] + (m_command_buffer[3] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		case CMD_TRANSMIT_PACKET:
			// read transmit data into m_tx_data_buffer
			m_tx_data_buffer.reset();
			m_tx_data_length = m_command_buffer[6] + (m_command_buffer[7] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		case CMD_DOWNLOAD_PROGRAM:
			// read program data into m_program_buffer
			m_program_buffer.reset();
			m_program_length = m_command_buffer[2] + (m_command_buffer[3] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		case CMD_NETWORK_STATISTICS: // 0x0a
		case CMD_EXECUTE_PROGRAM: // 0x0e
		case CMD_ADAPTER_INFO: // 0x11
			// delay command execution
			m_do_command_timer->adjust(attotime::from_usec(100));
			break;

		default:
			do_command();
			break;
		}
	}

	m_status |= HCRE; /* command register empty */
}
Exemple #6
0
void threecom3c505_device::do_command()
{
	pcb_struct &command_pcp = (pcb_struct &) m_command_buffer;

	// default to successful completion
	m_response.command = command_pcp.command + CMD_RESPONSE_OFFSET;
	m_response.length = 1;
	m_response.data.failed = 0; // successful completion

	switch (command_pcp.command)
	{
	case CMD_RESET: // 0x00
		// FIXME: should never occur
		break;

	case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01
		// TODO
		break;

	case CMD_CONFIGURE_82586: // 0x02
		m_i82586_config = command_pcp.data.raw[0] + (command_pcp.data.raw[1] << 8);
		break;

	case CMD_RECEIVE_PACKET: // 0x08
		// preset response PCB from the Receive Command PCB
		m_rcv_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
		m_rcv_response.length = sizeof(struct Rcv_resp);
		m_rcv_response.data.rcv_resp.buf_ofs = command_pcp.data.rcv_pkt.buf_ofs;
		m_rcv_response.data.rcv_resp.buf_seg = command_pcp.data.rcv_pkt.buf_seg;
		m_rcv_response.data.rcv_resp.buf_len = command_pcp.data.rcv_pkt.buf_len;
		m_rcv_response.data.rcv_resp.pkt_len = 0;
		m_rcv_response.data.rcv_resp.timeout = 0;
		m_rcv_response.data.rcv_resp.status = 0;
		m_rcv_response.data.rcv_resp.timetag = 0L; // TODO

		m_rx_pending++;
		set_command_pending(0);
		return;
		// break;

	case CMD_TRANSMIT_PACKET_F9:
		m_response.command = CMD_TRANSMIT_PACKET_COMPLETE;
		// fall through

	case CMD_TRANSMIT_PACKET: // 0x09
	case CMD_TRANSMIT_PACKET_18: // 0x18
		m_response.length = sizeof(struct Xmit_resp);
		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;

		// FIXME: hack?
		m_status |= ASF_PCB_END;
		break;

	case CMD_NETWORK_STATISTICS: // 0x0a
		m_response.length = sizeof(struct Netstat);
		m_response.data.netstat.tot_recv = uint16_to_le(m_netstat.tot_recv);
		m_response.data.netstat.tot_xmit = uint16_to_le(m_netstat.tot_xmit);
		m_response.data.netstat.err_CRC = uint16_to_le(m_netstat.err_CRC);
		m_response.data.netstat.err_align = uint16_to_le(m_netstat.err_align);
		m_response.data.netstat.err_res = uint16_to_le(m_netstat.err_res);
		m_response.data.netstat.err_ovrrun = uint16_to_le(m_netstat.err_ovrrun);
		break;

	case CMD_ADAPTER_INFO: // 0x11
		m_response.length = sizeof(struct Info);
		// FIXME: using demo data
		m_response.data.info.minor_vers = 1;
		m_response.data.info.major_vers = 2;
		m_response.data.info.ROM_cksum = uint16_to_le(3);
		m_response.data.info.RAM_sz = uint16_to_le(4);
		m_response.data.info.free_ofs = uint16_to_le(5);
		m_response.data.info.free_seg = uint16_to_le(6);
		break;

	case CMD_LOAD_MULTICAST_LIST:// 0x0b
		if (command_pcp.length > sizeof(m_multicast_list)
				|| (command_pcp.length % ETHERNET_ADDR_SIZE) != 0)
		{
			LOG(("CMD_LOAD_MULTICAST_LIST - unexpected data size %d", command_pcp.length));
		}
		else
		{
			memset(m_multicast_list, 0, sizeof(m_multicast_list));
			memcpy(m_multicast_list, command_pcp.data.multicast, command_pcp.length- 2);
			set_filter_list();
		}
		break;

	case CMD_SET_STATION_ADDRESS: // 0x10
		if (command_pcp.length != sizeof(m_station_address))
		{
			LOG(("CMD_SET_STATION_ADDRESS - unexpected data size %d", command_pcp.length));
			memset(m_station_address, 0, sizeof(m_station_address));
		}
		else
		{
			memcpy(m_station_address, command_pcp.data.eth_addr, command_pcp.length);
		}
		set_filter_list();
		set_mac((char *) m_station_address);
		break;

	case CMD_MC_17: // 0x17
		m_microcode_running = 1;
		break;

	case CMD_DOWNLOAD_PROGRAM: // 0x0d
		UINT16 mc_version = m_program_buffer.get_word(1);
		switch (mc_version)
		{
		case APOLLO_MC_VERSION_SR10_2:
		case APOLLO_MC_VERSION_SR10_4:
			m_microcode_version = mc_version;
			break;
		default:
			m_microcode_version = 0;
			LOG(("CMD_DOWNLOAD_PROGRAM - unexpected microcode version %04x", mc_version));
			break;
		}
		// return microcode version as program id
		m_response.length = 2;
		m_response.data.raw[0] = m_microcode_version & 0xff;
		m_response.data.raw[1] = (m_microcode_version >> 8) & 0xff;
		break;
	}

	m_response_index = 0;
	m_response_length = m_response.length + 2;

	m_status |= ACRF; /* set adapter command register full */
	if (m_control & CMDE)
	{
		set_interrupt(ASSERT_LINE);
	}
}
Exemple #7
0
void threecom3c505_device::write_control_port(UINT8 data)
{
	switch (data & (ATTN | FLSH))
	{
	case ATTN:
		LOG2(("write_control_port %02x - Soft Reset", data));
		// TODO: soft reset
		break;

	case FLSH:
		LOG2(("write_control_port %02x - Flush Data Register", data));
		// flush data register
		if (data & DIR_)
		{
			m_status &= ~HRDY; /* data register not ready */
		}
		else
		{
			// download to adapter
			m_status |= HRDY; /* data register ready */

			// flush data register (reset tx data fifo)
			// m_tx_data_length = 0;
			m_tx_data_buffer.reset();
		}
		break;

	case ATTN | FLSH:
		LOG2(("write_control_port %02x - Reset Adapter", data));
		device_reset();
		break;

	case 0:
		LOG2(("write_control_port %02x", data));

		// end reset
		if ((m_control & (ATTN | FLSH)) == (ATTN | FLSH))
		{
			m_status |= ASF_PCB_END;
			m_status |= HRDY; /* 20 byte data fifo is empty */
		}

		if (data == DIR_)
		{
			// why?? dex ether 20 expects HRDY
			m_status |= HRDY; /* data register ready */
		}
		break;
	}

	// propagate DIR_ from Control to Status register
	m_status = (m_status & ~DIR_) | (data & DIR_);

	switch (data & HSF_PCB_MASK)
	{
	case HSF_PCB_ACK: // HSF1
		if (m_wait_for_ack)
		{
			set_command_pending(0);
		}
		break;

	case HSF_PCB_END: // (HSF2|HSF1)
		m_status &= ~ACRF; /* adapter command register is not full */
		// fall through

	case HSF_PCB_NAK: // HSF2
		if (m_microcode_running)
		{
			if (m_wait_for_nak)
			{
				set_command_pending(0);
			}
			m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
		}
		break;

	default: // 0
		m_command_index = 0;
		m_status |= HCRE; /* host command register is empty */
		break;
	}

	m_control = data;
}
Exemple #8
0
UINT8 threecom3c505_device::read_command_port()
{
	UINT8 data;

	// the interrupt request is cleared when the Command Register is read
	set_interrupt(CLEAR_LINE);

	if (m_response_index == 0)
	{
		data = m_response.command;
	}
	else if (m_response_index == 1)
	{
		data = m_response.length;
	}
	else if (m_response_index < m_response_length)
	{
		data = m_response.data.raw[m_response_index - 2];
	}
	else if (m_response_index == m_response_length)
	{
		data = m_response.length + 2;
	}
	else if (m_response_index == m_response_length + 1 /*&& m_microcode_running*/)
	{
		// FIXME: special for SR10.4 microcode, content doesn't matter?
		data = 0; // ?
		m_response_index++;

		m_status &= ~ACRF; /* the adapter command register is no longer full */

		LOG2(("read_command_port: !!! reading 3C505 Command Register = %02x - m_status=%02x m_control=%02x",
						data, m_status, m_control));

		// wait for nak in control register
		set_command_pending(2);
	}
	else
	{
		// should never happen
		data = 0; // 0xff;
		LOG(("read_command_port: unexpected reading Command Register at index %04x", m_response_index));
	}

	if (m_response_index <= m_response_length + 1)
	{
		if (++m_response_index == m_response_length)
		{
			m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_END;
		}
		else if (m_response_index == m_response_length + 1)
		{
			log_response();

			switch (m_response.command)
			{
			case CMD_MC_E1_RESPONSE:
				m_status |= HRDY; /* data register ready */
				// prepend data length
				m_rx_data_index = -2;
				break;

			case CMD_RECEIVE_PACKET_COMPLETE:
				m_status |= HRDY; /* data register ready */
				m_rx_data_index = 0;
				break;

			case CMD_TRANSMIT_PACKET_COMPLETE:
			case CMD_TRANSMIT_PACKET_18_COMPLETE:
				m_netstat.tot_xmit++;

				if (!send(m_tx_data_buffer.get_data(),  m_tx_data_buffer.get_length()))
				{
					// FIXME: failed to send the Ethernet packet
					LOG(("read_command_port(): !!! failed to send Ethernet packet"));
				}

				if (tx_data != NULL && //
						(*tx_data)(this, m_tx_data_buffer.get_data(), m_tx_data_buffer.get_length()) == 0)
				{
					// FIXME: failed to transmit the Ethernet packet
					LOG(("read_command_port(): !!! failed to transmit Ethernet packet"));
				}

				m_tx_data_buffer.reset();
				if (m_command_buffer[0] != CMD_TRANSMIT_PACKET_F9)
				{
					set_command_pending(2);
				}
				break;

			case CMD_DOWNLOAD_PROGRAM_RESPONSE:
				m_program_buffer.reset();
				set_command_pending(2);
				break;

			default:
				set_command_pending(2);
				break;
			}
		}
	}
	return data;
}
Exemple #9
0
void threecom3c505_device::write_command_port( UINT8 data)
{
	LOG2(("writing 3C505 command port %02x - m_status=%02x m_control=%02x m_command_index=%02x", data, m_status, m_control, m_command_index));

	if ((m_control & HSF_PCB_MASK) != HSF_PCB_END)
	{
		m_command_buffer[m_command_index++] = data;
		m_status |= HCRE; /* command register empty */

		if (m_command_index == 1)
		{
			switch (data)
			{
			case 0:
				// spurious data; set command register empty
				m_command_index = 0;
				m_status |= HCRE;
				break;

			case CMD_MC_F9:
//          case CMD_MC_FA:
				// read data length from data port (not from command port)
				m_tx_data_buffer.reset();
				m_status |= HRDY; /* data register ready */
				set_command_pending(1);
				break;

			default:
				set_command_pending(1);
				break;
			}
		}
	}
	else
	{
		m_status &= ~ASF_PCB_MASK;
		m_status |= (data == m_command_index) ? ASF_PCB_END : ASF_PCB_NAK;

		log_command();

		switch (m_command_buffer[0])
		{
		case CMD_TRANSMIT_PACKET_18:
			// read transmit data into m_tx_data_buffer
			m_tx_data_buffer.reset();
			m_tx_data_length = m_command_buffer[2] + (m_command_buffer[3] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		case CMD_TRANSMIT_PACKET:
			// read transmit data into m_tx_data_buffer
			m_tx_data_buffer.reset();
			m_tx_data_length = m_command_buffer[6] + (m_command_buffer[7] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		case CMD_DOWNLOAD_PROGRAM:
			// read program data into m_program_buffer
			m_program_buffer.reset();
			m_program_length = m_command_buffer[2] + (m_command_buffer[3] << 8);
			m_status |= HRDY; /* data register ready */
			break;

		default:
			do_command();
			break;
		}
	}
}
Exemple #10
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;
		}
	}
}
Exemple #11
0
void threecom3c505_device::write_control_port( UINT8 data)
{
	// if (m_device->machine->firstcpu->safe_pcbase() == 0x3C4BAD48) verbose = 3;
	// if (m_device->machine->firstcpu->safe_pcbase() == 0x010464DC) verbose = 3;

	if (verbose <= 2 && (data & (DMAE | TCEN /*| CMDE*/)) != 0)
	{
		// dma or interrupts enabled
		LOG1(("writing 3C505 Control Register at offset %02x = %02x", PORT_CONTROL, data));
	}

	m_status = (m_status & ~DIR_) | (data & DIR_);

	switch (data & HSF_PCB_MASK)
	{
	case HSF_PCB_ACK: // HSF1
		if (m_wait_for_ack)
		{
			set_command_pending(0);
		}
		break;
	case HSF_PCB_NAK: // HSF2
		if (m_microcode_running)
		{
			m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
		}
		break;
	case HSF_PCB_END: // (HSF2|HSF1)
		m_status &= ~(ATTN | DMAE | ASF_PCB_MASK);
		if (m_microcode_running)
		{
			m_status = (m_status & ~ASF_PCB_MASK) | ASF_PCB_ACK;
		}
		break;
	default: // 0
		m_command_index = 0;
		m_status |= HCRE; /* command register empty */

		if (m_command_buffer[0] == CMD_MC_F9)
		{
			m_mc_f9_pending = 1;
//-         verbose = 2;
		}

		if (data == 0x00)
		{
			// hardware reset
			m_status |= HRDY; /* data register ready */
			// flush data register (reset tx data fifo)
			m_tx_data_length = 0;
			// FIXME: Don't do this (but why?)
			// m_tx_data_buffer.reset();
		}
		else if (data == DIR_)
		{
			// why?? dex ether 20 expects HRDY
			// m_status &= ~HRDY; /* data register not ready */
			m_status |= HRDY; /* data register ready */
		}
		else if (data & FLSH)
		{
			if (data & DIR_)
			{
				m_status &= ~HRDY; /* data register not ready */
			}
			else
			{
				// flush data register (reset tx data fifo)
//              m_tx_data_length = 0;
				m_tx_data_buffer.reset();
				m_status |= HRDY; /* data register ready */
			}
		}
		break;
	}

	if ((m_control & (ATTN | FLSH)) == (ATTN | FLSH) && (data & (ATTN | FLSH)) == 0)
	{
		m_status |= ASF_PCB_END;
	}

	if (m_mc_f9_pending == 2)
	{
		m_mc_f9_pending = 0;
		set_command_pending(0);
	}

	m_control = data;
}