static void apollo_pic_set_irq_line(device_t *device, int irq, int state) { // don't log PTM interrupts if (irq != APOLLO_IRQ_PTM) { DLOG1(("apollo_pic_set_irq_line: irq=%d state=%d", irq, state)); } switch (irq) { case 0: pic8259_ir0_w(get_pic8259_master(device), state); break; case 1: pic8259_ir1_w(get_pic8259_master(device), state); break; case 2: pic8259_ir2_w(get_pic8259_master(device), state); break; case 3: pic8259_ir3_w(get_pic8259_master(device), state); break; case 4: pic8259_ir4_w(get_pic8259_master(device), state); break; case 5: pic8259_ir5_w(get_pic8259_master(device), state); break; case 6: pic8259_ir6_w(get_pic8259_master(device), state); break; case 7: pic8259_ir7_w(get_pic8259_master(device), state); break; case 8: pic8259_ir0_w(get_pic8259_slave(device), state); break; case 9: pic8259_ir1_w(get_pic8259_slave(device), state); break; case 10: pic8259_ir2_w(get_pic8259_slave(device), state); break; case 11: pic8259_ir3_w(get_pic8259_slave(device), state); break; case 12: pic8259_ir4_w(get_pic8259_slave(device), state); break; case 13: pic8259_ir5_w(get_pic8259_slave(device), state); break; case 14: pic8259_ir6_w(get_pic8259_slave(device), state); break; case 15: pic8259_ir7_w(get_pic8259_slave(device), state); break; } }
static WRITE_LINE_DEVICE_HANDLER( apollo_pic8259_slave_set_int_line ) { static int interrupt_line = -1; if (state != interrupt_line) { DLOG1(("apollo_pic8259_slave_set_int_line: %x", state)); interrupt_line = state; apollo_pic_set_irq_line(device, 3, state); } }
int apollo_eth_setfilter(device_t *device, int node_id) { /* tcpdump -i eth0 -dd ether dst 08:00:1e:01:ae:a5 or ether dst 09:00:1e:00:00:00 or ether dst 09:00:1e:00:00:01 or ether broadcast (000) ld [2] (001) jeq #0x1e01aea5 jt 2 jf 4 (002) ldh [0] (003) jeq #0x800 jt 11 jf 12 (004) jeq #0x1e000000 jt 6 jf 5 (005) jeq #0x1e000001 jt 6 jf 8 (006) ldh [0] (007) jeq #0x900 jt 11 jf 12 (008) jeq #0xffffffff jt 9 jf 12 (009) ldh [0] (010) jeq #0xffff jt 11 jf 12 (011) ret #65535 (012) ret #0 */ static struct sock_filter bpf_code[]= { { 0x20, 0, 0, 0x00000002 }, { 0x15, 0, 2, 0x1e01aea5 }, { 0x28, 0, 0, 0x00000000 }, { 0x15, 7, 8, 0x00000800 }, { 0x15, 1, 0, 0x1e000000 }, { 0x15, 0, 2, 0x1e000001 }, { 0x28, 0, 0, 0x00000000 }, { 0x15, 3, 4, 0x00000900 }, { 0x15, 0, 3, 0xffffffff }, { 0x28, 0, 0, 0x00000000 }, { 0x15, 0, 1, 0x0000ffff }, { 0x6, 0, 0, 0x0000ffff }, { 0x6, 0, 0, 0x00000000 } }; if (eth_socket != -1) { struct sock_fprog filter; filter.len = sizeof(bpf_code) / sizeof(sock_filter); filter.filter = bpf_code; // set node id in filter bpf_code[1].k = (bpf_code[1].k & 0xff000000) | (node_id & 0x00ffffff); /* Attach the filter to the socket */ if (setsockopt(eth_socket, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0) { DLOG(("apollo_eth_setfilter: failed with error %d (%s)", errno, strerror(errno))); return 0; } else { DLOG1(("apollo_eth_setfilter: set filter for node id %x", node_id & 0x00ffffff)); } } return 1; }
INPUT_PORTS_END /*------------------------------------------------- device start callback -------------------------------------------------*/ static DEVICE_START(apollo_config) { DLOG1(("start apollo_config")); }
static WRITE_LINE_DEVICE_HANDLER( apollo_pic8259_master_set_int_line ) { static int interrupt_line = -1; if (state != interrupt_line) { DLOG1(("apollo_pic8259_master_set_int_line: %x", state)); } interrupt_line = state; if (apollo_is_dn3000()) { apollo_csr_set_status_register(APOLLO_CSR_SR_INTERRUPT_PENDING, state ? APOLLO_CSR_SR_INTERRUPT_PENDING : 0); } else { // set bit Interrupt Pending in Cache Status Register apollo_set_cache_status_register(0x10, state ? 0x10 : 0x00); } device->machine().device(MAINCPU)->execute().set_input_line_and_vector(M68K_IRQ_6,state ? ASSERT_LINE : CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); }
static int apollo_eth_receive_packet(device_t *device) { u_char rx_buffer[ETH_BUFFER_SIZE]; int packet_len; do { packet_len = recv(eth_socket, rx_buffer, sizeof(rx_buffer), MSG_TRUNC); } while (packet_len == -1 && errno == EINTR); /* Check if an error occurred */ if (packet_len == -1) { switch (errno) { case EAGAIN: return 0; /* no packet there */ case ENETDOWN: // The device on which we're capturing went away. DLOG1(("apollo_eth_receive_packet: the interface went down (error %d - %s)", errno, strerror(errno))); return -1; default: DLOG(("apollo_eth_receive_packet: recv failed (error %d - %s)", errno, strerror(errno))); return -1; } } else if (packet_len > sizeof(rx_buffer)) { DLOG(("apollo_eth_receive_packet: data size (%d) exceeds rx buffer size (%d)!!!", packet_len, sizeof(rx_buffer))); return -1; } log_data(device, "apollo_eth_receive_packet", rx_buffer, packet_len); /* Call the user supplied callback function */ if (rx_callback != NULL) { // threecom3c505_receive(device, tx_data_buffer, tx_data_length); (*rx_callback)(device, rx_buffer, packet_len); } return 1; }
void apollo_eth_init(device_t *device, apollo_eth_receive rx_data) { rx_callback = rx_data; eth_if_name = ETH_INTERFACE_NAME; eth_if_index = -1; memset(eth_hw_address, 0 , sizeof(eth_hw_address)); // Note: Only processes with effective UID 0 or the CAP_NET_RAW capability may open packet sockets. // see also: man 7 packet eth_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (eth_socket == -1) { if (errno == EPERM) { DLOG(("apollo_eth_init: %s - Ethernet access disabled", strerror(errno))); } else { DLOG1(("apollo_eth_init: socket failed (error %d - %s)", errno, strerror(errno))); } } else { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, eth_if_name, sizeof(ifr.ifr_name)); // Get interface index if (ioctl(eth_socket, SIOCGIFINDEX, &ifr) == -1) { DLOG(("apollo_eth_init: interface %s not found (error %d - %s)", eth_if_name, errno, strerror(errno))); close(eth_socket); eth_socket = -1; } else { eth_if_index = ifr.ifr_ifindex; // Get hardware address memset(&ifr, 0, sizeof(ifr)); (void) strncpy(ifr.ifr_name, eth_if_name, sizeof(ifr.ifr_name)); if (ioctl(eth_socket, SIOCGIFHWADDR, (char *) &ifr) < 0) { DLOG(("apollo_eth_init: SIOCGIFHWADDR failed for %s (error %d - %s)", eth_if_name, errno, strerror(errno))); } else { memcpy(eth_hw_address, ifr.ifr_hwaddr.sa_data, sizeof(eth_hw_address)); } struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = eth_if_index; sll.sll_protocol = htons(ETH_P_ALL); if (bind(eth_socket, (struct sockaddr *) &sll, sizeof(sll)) == -1) { DLOG(("apollo_eth_init: bind to interface %s failed (error %d - %s)", eth_if_name, errno, strerror(errno))); close(eth_socket); eth_socket = -1; } else { struct packet_mreq mr; memset(&mr, 0, sizeof(mr)); mr.mr_ifindex = eth_if_index; mr.mr_type = PACKET_MR_PROMISC; if (setsockopt(eth_socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) { DLOG(("apollo_eth_init: failed to set promiscuous mode (error %d - %s)", errno, strerror(errno))); close(eth_socket); eth_socket = -1; } else { // Set the socket buffer size to the specified value. // by default request 2M for the ring buffer int rx_bufsize = 2*1024*1024; if (setsockopt(eth_socket, SOL_SOCKET, SO_RCVBUF, &rx_bufsize, sizeof(rx_bufsize)) == -1) { DLOG(("apollo_eth_init: failed to set buffer size (error %d - %s)", errno, strerror(errno))); close(eth_socket); eth_socket = -1; } else { device->machine().scheduler().timer_set(attotime::from_msec(1), FUNC(receive_interrupt), 0, device); } } } } } }
static WRITE_LINE_DEVICE_HANDLER( apollo_dma8237_out_eop ) { pc_fdc_at_device *fdc = device->machine().device<pc_fdc_at_device>(APOLLO_FDC_TAG); DLOG1(("dma out eop state %02x", state)); fdc->tc_w(!state); sc499_set_tc_state(&device->machine(), state); }
static WRITE8_DEVICE_HANDLER( apollo_dma8237_wdc_dack_w ) { DLOG1(("dma wdc dack write %02x (not used, not emulated!)", data)); // omti8621_dack_w(device->machine, data); }
static READ8_DEVICE_HANDLER( apollo_dma8237_wdc_dack_r ) { UINT8 data = 0xff; // omti8621_dack_r(device->machine); DLOG1(("dma wdc dack read %02x (not used, not emulated!)",data)); return data; }
static void apollo_dma_ctape_drq(device_t *device, int state) { DLOG1(("apollo_dma_ctape_drq: state=%x", state)); i8237_dreq1_w(get_device_dma8237_1(device), state); }
static DEVICE_RESET(apollo_config) { DLOG1(("reset apollo_config")); // load configuration config = device->machine().root_device().ioport("apollo_config")->read(); }