diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ffe7582f5..3b3c23cf8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static +LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcap 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 8cf8e94a3..f922dea9a 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -42,14 +42,14 @@ int cdrom_ioctl_do_log = 0; void cdrom_ioctl_log(const char *format, ...) { #ifdef ENABLE_CDROM_LOG - if (cdrom_ioctl_do_log) - { + if (cdrom_ioctl_do_log) + { va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); fflush(stdout); - } + } #endif } @@ -534,11 +534,33 @@ static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_bl if (no_length_check) { - return 65534; + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + default: + return 65534; + } } switch (cdb[0]) { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); case 0x08: case 0x28: case 0xa8: diff --git a/src/cdrom.c b/src/cdrom.c index 20068125f..a71ba8b60 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -212,14 +212,14 @@ int cdrom_do_log = 0; void cdrom_log(const char *format, ...) { #ifdef ENABLE_CDROM_LOG - if (cdrom_do_log) - { + if (cdrom_do_log) + { va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); fflush(stdout); - } + } #endif } @@ -1857,6 +1857,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_TOC_PMA_ATIP: cdrom[id].toctimes++; + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); @@ -1864,19 +1868,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - max_len = cdb[8] + (cdb[7] << 8); - len = cdbufferb[0] + (cdbufferb[1] << 8); - len += 2; - if (max_len < len) - { - max_len -= 2; - cdbufferb[0] = max_len >> 8; - cdbufferb[1] = max_len & 0xff; - len = max_len + 2; - } + len = alloc_length; } } else @@ -2238,11 +2236,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - cdbufferb[0] = 0; - cdbufferb[1] = 32; - len = 34; + len = alloc_length; } } else @@ -2278,12 +2278,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - cdbufferb[0] = 0; - cdbufferb[1] = 34; - len = 36; + len = alloc_length; } } else @@ -2400,20 +2401,21 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[1] = 0x13; break; } - if (len == 65534) + switch(cdb[3]) { - switch(cdb[3]) - { - case 0: - len = 4; - break; - case 1: - len = 16; - break; - default: - len = 24; - break; - } + case 0: + alloc_length = 4; + break; + case 1: + alloc_length = 16; + break; + default: + alloc_length = 24; + break; + } + if (alloc_length < len) + { + len = alloc_length; } } else diff --git a/src/lpt.c b/src/lpt.c index 251c56a4a..1d29b7d9a 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -65,31 +65,33 @@ uint8_t lpt2_read(uint16_t port, void *priv) return 0xff; } +uint16_t lpt_addr[2] = { 0x378, 0x278 }; + void lpt_init() { io_sethandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); io_sethandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + lpt_addr[0] = 0x378; + lpt_addr[1] = 0x378; } void lpt1_init(uint16_t port) { io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + lpt_addr[0] = port; } void lpt1_remove() { - io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + io_removehandler(lpt_addr[0], 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); } void lpt2_init(uint16_t port) { io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + lpt_addr[1] = port; } void lpt2_remove() { - io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + io_removehandler(lpt_addr[1], 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } void lpt2_remove_ams() diff --git a/src/ne2000.c b/src/ne2000.c index 3694a06e7..ec5140559 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -48,32 +48,10 @@ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #define NETBLOCKING 0 //we won't block our pcap -static HINSTANCE net_hLib = 0; /* handle to DLL */ -static char* net_lib_name = "wpcap.dll"; pcap_t *net_pcap; -typedef pcap_t* (__cdecl * PCAP_OPEN_LIVE)(const char *, int, int, int, char *); -typedef int (__cdecl * PCAP_SENDPACKET)(pcap_t* handle, const u_char* msg, int len); -typedef int (__cdecl * PCAP_SETNONBLOCK)(pcap_t *, int, char *); -typedef const u_char*(__cdecl *PCAP_NEXT)(pcap_t *, struct pcap_pkthdr *); -typedef const char*(__cdecl *PCAP_LIB_VERSION)(void); -typedef void (__cdecl *PCAP_CLOSE)(pcap_t *); -typedef int (__cdecl *PCAP_GETNONBLOCK)(pcap_t *p, char *errbuf); -typedef int (__cdecl *PCAP_COMPILE)(pcap_t *p, struct bpf_program *fp, const char *str, int optimize, bpf_u_int32 netmask); -typedef int (__cdecl *PCAP_SETFILTER)(pcap_t *p, struct bpf_program *fp); - -PCAP_LIB_VERSION _pcap_lib_version; -PCAP_OPEN_LIVE _pcap_open_live; -PCAP_SENDPACKET _pcap_sendpacket; -PCAP_SETNONBLOCK _pcap_setnonblock; -PCAP_NEXT _pcap_next; -PCAP_CLOSE _pcap_close; -PCAP_GETNONBLOCK _pcap_getnonblock; -PCAP_COMPILE _pcap_compile; -PCAP_SETFILTER _pcap_setfilter; queueADT slirpq; int net_slirp_inited=0; -int net_is_slirp=1; //by default we go with slirp int net_is_pcap=0; //and pretend pcap is dead. int fizz=0; void slirp_tic(); @@ -93,150 +71,158 @@ uint8_t rtl8029as_eeprom[128]; typedef struct ne2000_t { - // - // ne2k register state + // + // ne2k register state - // - // Page 0 - // - // Command Register - 00h read/write - struct CR_t { - int stop; // STP - Software Reset command - int start; // START - start the NIC - int tx_packet; // TXP - initiate packet transmission - uint8_t rdma_cmd; // RD0,RD1,RD2 - Remote DMA command - uint8_t pgsel; // PS0,PS1 - Page select - } CR; - // Interrupt Status Register - 07h read/write - struct ISR_t { - int pkt_rx; // PRX - packet received with no errors - int pkt_tx; // PTX - packet transmitted with no errors - int rx_err; // RXE - packet received with 1 or more errors - int tx_err; // TXE - packet tx'd " " " " " - int overwrite; // OVW - rx buffer resources exhausted - int cnt_oflow; // CNT - network tally counter MSB's set - int rdma_done; // RDC - remote DMA complete - int reset; // RST - reset status - } ISR; - // Interrupt Mask Register - 0fh write - struct IMR_t { - int rx_inte; // PRXE - packet rx interrupt enable - int tx_inte; // PTXE - packet tx interrput enable - int rxerr_inte; // RXEE - rx error interrupt enable - int txerr_inte; // TXEE - tx error interrupt enable - int overw_inte; // OVWE - overwrite warn int enable - int cofl_inte; // CNTE - counter o'flow int enable - int rdma_inte; // RDCE - remote DMA complete int enable - int reserved; // D7 - reserved - } IMR; - // Data Configuration Register - 0eh write - struct DCR_t { - int wdsize; // WTS - 8/16-bit select - int endian; // BOS - byte-order select - int longaddr; // LAS - long-address select - int loop; // LS - loopback select - int auto_rx; // AR - auto-remove rx packets with remote DMA - uint8_t fifo_size; // FT0,FT1 - fifo threshold - } DCR; - // Transmit Configuration Register - 0dh write - struct TCR_t { - int crc_disable; // CRC - inhibit tx CRC - uint8_t loop_cntl; // LB0,LB1 - loopback control - int ext_stoptx; // ATD - allow tx disable by external mcast - int coll_prio; // OFST - backoff algorithm select - uint8_t reserved; // D5,D6,D7 - reserved - } TCR; - // Transmit Status Register - 04h read - struct TSR_t { - int tx_ok; // PTX - tx complete without error - int reserved; // D1 - reserved - int collided; // COL - tx collided >= 1 times - int aborted; // ABT - aborted due to excessive collisions - int no_carrier; // CRS - carrier-sense lost - int fifo_ur; // FU - FIFO underrun - int cd_hbeat; // CDH - no tx cd-heartbeat from transceiver - int ow_coll; // OWC - out-of-window collision - } TSR; - // Receive Configuration Register - 0ch write - struct RCR_t { - int errors_ok; // SEP - accept pkts with rx errors - int runts_ok; // AR - accept < 64-byte runts - int broadcast; // AB - accept eth broadcast address - int multicast; // AM - check mcast hash array - int promisc; // PRO - accept all packets - int monitor; // MON - check pkts, but don't rx - uint8_t reserved; // D6,D7 - reserved - } RCR; - // Receive Status Register - 0ch read - struct RSR_t { - int rx_ok; // PRX - rx complete without error - int bad_crc; // CRC - Bad CRC detected - int bad_falign; // FAE - frame alignment error - int fifo_or; // FO - FIFO overrun - int rx_missed; // MPA - missed packet error - int rx_mbit; // PHY - unicast or mcast/bcast address match - int rx_disabled; // DIS - set when in monitor mode - int deferred; // DFR - collision active - } RSR; + // + // Page 0 + // + // Command Register - 00h read/write + struct CR_t + { + int stop; // STP - Software Reset command + int start; // START - start the NIC + int tx_packet; // TXP - initiate packet transmission + uint8_t rdma_cmd; // RD0,RD1,RD2 - Remote DMA command + uint8_t pgsel; // PS0,PS1 - Page select + } CR; + // Interrupt Status Register - 07h read/write + struct ISR_t + { + int pkt_rx; // PRX - packet received with no errors + int pkt_tx; // PTX - packet transmitted with no errors + int rx_err; // RXE - packet received with 1 or more errors + int tx_err; // TXE - packet tx'd " " " " " + int overwrite; // OVW - rx buffer resources exhausted + int cnt_oflow; // CNT - network tally counter MSB's set + int rdma_done; // RDC - remote DMA complete + int reset; // RST - reset status + } ISR; + // Interrupt Mask Register - 0fh write + struct IMR_t + { + int rx_inte; // PRXE - packet rx interrupt enable + int tx_inte; // PTXE - packet tx interrput enable + int rxerr_inte; // RXEE - rx error interrupt enable + int txerr_inte; // TXEE - tx error interrupt enable + int overw_inte; // OVWE - overwrite warn int enable + int cofl_inte; // CNTE - counter o'flow int enable + int rdma_inte; // RDCE - remote DMA complete int enable + int reserved; // D7 - reserved + } IMR; + // Data Configuration Register - 0eh write + struct DCR_t + { + int wdsize; // WTS - 8/16-bit select + int endian; // BOS - byte-order select + int longaddr; // LAS - long-address select + int loop; // LS - loopback select + int auto_rx; // AR - auto-remove rx packets with remote DMA + uint8_t fifo_size; // FT0,FT1 - fifo threshold + } DCR; + // Transmit Configuration Register - 0dh write + struct TCR_t + { + int crc_disable; // CRC - inhibit tx CRC + uint8_t loop_cntl; // LB0,LB1 - loopback control + int ext_stoptx; // ATD - allow tx disable by external mcast + int coll_prio; // OFST - backoff algorithm select + uint8_t reserved; // D5,D6,D7 - reserved + } TCR; + // Transmit Status Register - 04h read + struct TSR_t + { + int tx_ok; // PTX - tx complete without error + int reserved; // D1 - reserved + int collided; // COL - tx collided >= 1 times + int aborted; // ABT - aborted due to excessive collisions + int no_carrier; // CRS - carrier-sense lost + int fifo_ur; // FU - FIFO underrun + int cd_hbeat; // CDH - no tx cd-heartbeat from transceiver + int ow_coll; // OWC - out-of-window collision + } TSR; + // Receive Configuration Register - 0ch write + struct RCR_t + { + int errors_ok; // SEP - accept pkts with rx errors + int runts_ok; // AR - accept < 64-byte runts + int broadcast; // AB - accept eth broadcast address + int multicast; // AM - check mcast hash array + int promisc; // PRO - accept all packets + int monitor; // MON - check pkts, but don't rx + uint8_t reserved; // D6,D7 - reserved + } RCR; + // Receive Status Register - 0ch read + struct RSR_t + { + int rx_ok; // PRX - rx complete without error + int bad_crc; // CRC - Bad CRC detected + int bad_falign; // FAE - frame alignment error + int fifo_or; // FO - FIFO overrun + int rx_missed; // MPA - missed packet error + int rx_mbit; // PHY - unicast or mcast/bcast address match + int rx_disabled; // DIS - set when in monitor mode + int deferred; // DFR - collision active + } RSR; - uint16_t local_dma; // 01,02h read ; current local DMA addr - uint8_t page_start; // 01h write ; page start register - uint8_t page_stop; // 02h write ; page stop register - uint8_t bound_ptr; // 03h read/write ; boundary pointer - uint8_t tx_page_start; // 04h write ; transmit page start register - uint8_t num_coll; // 05h read ; number-of-collisions register - uint16_t tx_bytes; // 05,06h write ; transmit byte-count register - uint8_t fifo; // 06h read ; FIFO - uint16_t remote_dma; // 08,09h read ; current remote DMA addr - uint16_t remote_start; // 08,09h write ; remote start address register - uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register - uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) - uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) - uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) + uint16_t local_dma; // 01,02h read ; current local DMA addr + uint8_t page_start; // 01h write ; page start register + uint8_t page_stop; // 02h write ; page stop register + uint8_t bound_ptr; // 03h read/write ; boundary pointer + uint8_t tx_page_start; // 04h write ; transmit page start register + uint8_t num_coll; // 05h read ; number-of-collisions register + uint16_t tx_bytes; // 05,06h write ; transmit byte-count register + uint8_t fifo; // 06h read ; FIFO + uint16_t remote_dma; // 08,09h read ; current remote DMA addr + uint16_t remote_start; // 08,09h write ; remote start address register + uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register + uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) + uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) + uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) - // - // Page 1 - // - // Command Register 00h (repeated) - // - uint8_t physaddr[6]; // 01-06h read/write ; MAC address - uint8_t curr_page; // 07h read/write ; current page register - uint8_t mchash[8]; // 08-0fh read/write ; multicast hash array + // + // Page 1 + // + // Command Register 00h (repeated) + // + uint8_t physaddr[6]; // 01-06h read/write ; MAC address + uint8_t curr_page; // 07h read/write ; current page register + uint8_t mchash[8]; // 08-0fh read/write ; multicast hash array - // - // Page 2 - diagnostic use only - // - // Command Register 00h (repeated) - // - // Page Start Register 01h read (repeated) - // Page Stop Register 02h read (repeated) - // Current Local DMA Address 01,02h write (repeated) - // Transmit Page start address 04h read (repeated) - // Receive Configuration Register 0ch read (repeated) - // Transmit Configuration Register 0dh read (repeated) - // Data Configuration Register 0eh read (repeated) - // Interrupt Mask Register 0fh read (repeated) - // - uint8_t rempkt_ptr; // 03h read/write ; remote next-packet pointer - uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer - uint16_t address_cnt; // 06,07h read/write ; address counter + // + // Page 2 - diagnostic use only + // + // Command Register 00h (repeated) + // + // Page Start Register 01h read (repeated) + // Page Stop Register 02h read (repeated) + // Current Local DMA Address 01,02h write (repeated) + // Transmit Page start address 04h read (repeated) + // Receive Configuration Register 0ch read (repeated) + // Transmit Configuration Register 0dh read (repeated) + // Data Configuration Register 0eh read (repeated) + // Interrupt Mask Register 0fh read (repeated) + // + uint8_t rempkt_ptr; // 03h read/write ; remote next-packet pointer + uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer + uint16_t address_cnt; // 06,07h read/write ; address counter - // - // Page 3 - should never be modified. - // + // + // Page 3 - should never be modified. + // - // Novell ASIC state - uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes - uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory + // Novell ASIC state + uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes + uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory - // ne2k internal state - uint32_t base_address; - int base_irq; - int tx_timer_index; - int tx_timer_active; + // ne2k internal state + uint32_t base_address; + int base_irq; + int tx_timer_index; + int tx_timer_active; + + rom_t bios_rom; - rom_t bios_rom; - } ne2000_t; int disable_netbios = 0; @@ -251,92 +237,92 @@ int ne2000_do_log = 0; void ne2000_log(const char *format, ...) { #ifdef ENABLE_NE2000_LOG - if (ne2000_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } + if (ne2000_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } #endif } static void ne2000_setirq(ne2000_t *ne2000, int irq) { - ne2000->base_irq = irq; + ne2000->base_irq = irq; } + // // reset - restore state to power-up, cancelling all i/o // static void ne2000_reset(void *p, int reset) { - ne2000_t *ne2000 = (ne2000_t *)p; - int i; + ne2000_t *ne2000 = (ne2000_t *)p; + int i; - ne2000_log("ne2000 reset\n"); + ne2000_log("ne2000 reset\n"); - // Initialise the mac address area by doubling the physical address - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; + // Initialise the mac address area by doubling the physical address + ne2000->macaddr[0] = ne2000->physaddr[0]; + ne2000->macaddr[1] = ne2000->physaddr[0]; + ne2000->macaddr[2] = ne2000->physaddr[1]; + ne2000->macaddr[3] = ne2000->physaddr[1]; + ne2000->macaddr[4] = ne2000->physaddr[2]; + ne2000->macaddr[5] = ne2000->physaddr[2]; + ne2000->macaddr[6] = ne2000->physaddr[3]; + ne2000->macaddr[7] = ne2000->physaddr[3]; + ne2000->macaddr[8] = ne2000->physaddr[4]; + ne2000->macaddr[9] = ne2000->physaddr[4]; + ne2000->macaddr[10] = ne2000->physaddr[5]; + ne2000->macaddr[11] = ne2000->physaddr[5]; - // ne2k signature - for (i = 12; i < 32; i++) - ne2000->macaddr[i] = 0x57; + // ne2k signature + for (i = 12; i < 32; i++) + { + ne2000->macaddr[i] = 0x57; + } - // Zero out registers and memory - memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); - memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); - memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); - memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); - memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); - memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); - //memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); - memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); - ne2000->tx_timer_active = 0; - ne2000->local_dma = 0; - ne2000->page_start = 0; - ne2000->page_stop = 0; - ne2000->bound_ptr = 0; - ne2000->tx_page_start = 0; - ne2000->num_coll = 0; - ne2000->tx_bytes = 0; - ne2000->fifo = 0; - ne2000->remote_dma = 0; - ne2000->remote_start = 0; - ne2000->remote_bytes = 0; - ne2000->tallycnt_0 = 0; - ne2000->tallycnt_1 = 0; - ne2000->tallycnt_2 = 0; + // Zero out registers and memory + memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); + memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); + memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); + memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); + memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); + memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); + // memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); + memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); + ne2000->tx_timer_active = 0; + ne2000->local_dma = 0; + ne2000->page_start = 0; + ne2000->page_stop = 0; + ne2000->bound_ptr = 0; + ne2000->tx_page_start = 0; + ne2000->num_coll = 0; + ne2000->tx_bytes = 0; + ne2000->fifo = 0; + ne2000->remote_dma = 0; + ne2000->remote_start = 0; + ne2000->remote_bytes = 0; + ne2000->tallycnt_0 = 0; + ne2000->tallycnt_1 = 0; + ne2000->tallycnt_2 = 0; - //memset( & ne2000->physaddr, 0, sizeof(ne2000->physaddr)); - //memset( & ne2000->mchash, 0, sizeof(ne2000->mchash)); - ne2000->curr_page = 0; + ne2000->curr_page = 0; - ne2000->rempkt_ptr = 0; - ne2000->localpkt_ptr = 0; - ne2000->address_cnt = 0; + ne2000->rempkt_ptr = 0; + ne2000->localpkt_ptr = 0; + ne2000->address_cnt = 0; - memset( & ne2000->mem, 0, sizeof(ne2000->mem)); + memset( & ne2000->mem, 0, sizeof(ne2000->mem)); - // Set power-up conditions - ne2000->CR.stop = 1; - ne2000->CR.rdma_cmd = 4; - ne2000->ISR.reset = 1; - ne2000->DCR.longaddr = 1; - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - //DEV_pic_lower_irq(ne2000->base_irq); + // Set power-up conditions + ne2000->CR.stop = 1; + ne2000->CR.rdma_cmd = 4; + ne2000->ISR.reset = 1; + ne2000->DCR.longaddr = 1; + picint(1 << ne2000->base_irq); + picintc(1 << ne2000->base_irq); } #include "bswap.h" @@ -349,11 +335,11 @@ uint32_t ne2000_read_cr(ne2000_t *ne2000) { uint32_t val; - val = (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); + val = (((ne2000->CR.pgsel & 0x03) << 6) | + ((ne2000->CR.rdma_cmd & 0x07) << 3) | + (ne2000->CR.tx_packet << 2) | + (ne2000->CR.start << 1) | + (ne2000->CR.stop)); ne2000_log("%s: read CR returns 0x%02x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); return val; } @@ -363,13 +349,15 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000_log("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); // Validate remote-DMA - if ((value & 0x38) == 0x00) { + if ((value & 0x38) == 0x00) + { ne2000_log("CR write - invalid rDMA value 0\n"); value |= 0x20; /* dma_cmd == 4 is a safe default */ } // Check for s/w reset - if (value & 0x01) { + if (value & 0x01) + { ne2000->ISR.reset = 1; ne2000->CR.stop = 1; } else { @@ -380,7 +368,8 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) // If start command issued, the RST bit in the ISR // must be cleared - if ((value & 0x02) && !ne2000->CR.start) { + if ((value & 0x02) && !ne2000->CR.start) + { ne2000->ISR.reset = 0; } @@ -388,7 +377,8 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000->CR.pgsel = (value & 0xc0) >> 6; // Check for send-packet command - if (ne2000->CR.rdma_cmd == 3) { + if (ne2000->CR.rdma_cmd == 3) + { // Set up DMA read from receive ring ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); @@ -396,52 +386,66 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) } // Check for start-tx - if ((value & 0x04) && ne2000->TCR.loop_cntl) { - if (ne2000->TCR.loop_cntl != 1) { - ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } else { - ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], - ne2000->tx_bytes); + if ((value & 0x04) && ne2000->TCR.loop_cntl) + { + if (ne2000->TCR.loop_cntl != 1) + { + ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); } - } else if (value & 0x04) { - if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) { - if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ - return; /* Solaris9 probe */ - ne2000_log("CR write - tx start, dev in reset\n"); + else + { + ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + } + } + else if (value & 0x04) + { + if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) + { + if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ + { + return; /* Solaris9 probe */ + } + ne2000_log("CR write - tx start, dev in reset\n"); } if (ne2000->tx_bytes == 0) + { ne2000_log("CR write - tx start, tx bytes == 0\n"); + } // Send the packet to the system driver ne2000->CR.tx_packet = 1; - if(net_is_slirp) + if(!net_is_pcap) { slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); ne2000_log("ne2000 slirp sending packet\n"); } - if(net_is_pcap && net_pcap!=NULL) + else if (net_is_pcap && (net_pcap != NULL)) { - _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); ne2000_log("ne2000 pcap sending packet\n"); } // some more debug if (ne2000->tx_timer_active) - ne2000_log("CR write, tx timer still active\n"); + { + ne2000_log("CR write, tx timer still active\n"); + } ne2000_tx_event(ne2000, value); - } + } // Linux probes for an interrupt by setting up a remote-DMA read // of 0 bytes with remote-DMA completion interrupts enabled. // Detect this here if (ne2000->CR.rdma_cmd == 0x01 && ne2000->CR.start && - ne2000->remote_bytes == 0) { + ne2000->remote_bytes == 0) + { ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); } } } @@ -457,57 +461,73 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) { - uint32_t retval = 0; + uint32_t retval = 0; - if ((io_len == 2) && (address & 0x1)) - ne2000_log("unaligned chipmem word read\n"); + if ((io_len == 2) && (address & 0x1)) + { + ne2000_log("unaligned chipmem word read\n"); + } - // ROM'd MAC address - if ((address >=0) && (address <= 31)) { - retval = ne2000->macaddr[address % 32]; - if ((io_len == 2) || (io_len == 4)) { - retval |= (ne2000->macaddr[(address + 1) % 32] << 8); - } - if (io_len == 4) { - retval |= (ne2000->macaddr[(address + 2) % 32] << 16); - retval |= (ne2000->macaddr[(address + 3) % 32] << 24); - } - return (retval); - } + // ROM'd MAC address + if ((address >=0) && (address <= 31)) + { + retval = ne2000->macaddr[address % 32]; + if ((io_len == 2) || (io_len == 4)) + { + retval |= (ne2000->macaddr[(address + 1) % 32] << 8); + } + if (io_len == 4) + { + retval |= (ne2000->macaddr[(address + 2) % 32] << 16); + retval |= (ne2000->macaddr[(address + 3) % 32] << 24); + } + return (retval); + } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - retval = ne2000->mem[address - BX_NE2K_MEMSTART]; - if ((io_len == 2) || (io_len == 4)) { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); - } - if (io_len == 4) { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); - } - return (retval); - } + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + { + retval = ne2000->mem[address - BX_NE2K_MEMSTART]; + if ((io_len == 2) || (io_len == 4)) + { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); + } + if (io_len == 4) + { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); + } + return (retval); + } - ne2000_log("out-of-bounds chipmem read, %04X\n", address); + ne2000_log("out-of-bounds chipmem read, %04X\n", address); - return (0xff); + return (0xff); } void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { - if ((io_len == 2) && (address & 0x1)) - ne2000_log("unaligned chipmem word write\n"); + if ((io_len == 2) && (address & 0x1)) + { + ne2000_log("unaligned chipmem word write\n"); + } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; - if ((io_len == 2) || (io_len == 4)) { - ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; - } - if (io_len == 4) { - ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; - ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; - } - } else - ne2000_log("out-of-bounds chipmem write, %04X\n", address); + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + { + ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; + if ((io_len == 2) || (io_len == 4)) + { + ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; + } + if (io_len == 4) + { + ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; + ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; + } + } + else + { + ne2000_log("out-of-bounds chipmem write, %04X\n", address); + } } // @@ -522,115 +542,146 @@ void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, un // uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - uint32_t retval = 0; + uint32_t retval = 0; - switch (offset) { - case 0x0: // Data register - // - // A read remote-DMA command must have been issued, - // and the source-address and length registers must - // have been initialised. - // - if (io_len > ne2000->remote_bytes) { - ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); - //return 0; - } + switch (offset) + { + case 0x0: // Data register + // + // A read remote-DMA command must have been issued, + // and the source-address and length registers must + // have been initialised. + // + if (io_len > ne2000->remote_bytes) + { + ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); + } - ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); - retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); - // - // The 8390 bumps the address and decreases the byte count - // by the selected word size after every access, not by - // the amount of data requested by the host (io_len). - // - if (io_len == 4) { - ne2000->remote_dma += io_len; - } else { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_dma == ne2000->page_stop << 8) { - ne2000->remote_dma = ne2000->page_start << 8; - } - // keep s.remote_bytes from underflowing - if (ne2000->remote_bytes > ne2000->DCR.wdsize) - if (io_len == 4) { - ne2000->remote_bytes -= io_len; - } else { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - else - ne2000->remote_bytes = 0; + ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); + retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); + // + // The 8390 bumps the address and decreases the byte count + // by the selected word size after every access, not by + // the amount of data requested by the host (io_len). + // + if (io_len == 4) + { + ne2000->remote_dma += io_len; + } + else + { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - } - } - break; + if (ne2000->remote_dma == ne2000->page_stop << 8) + { + ne2000->remote_dma = ne2000->page_start << 8; + } - case 0xf: // Reset register - ne2000_reset(ne2000, BX_RESET_SOFTWARE); - break; + // keep s.remote_bytes from underflowing + if (ne2000->remote_bytes > ne2000->DCR.wdsize) + { + if (io_len == 4) + { + ne2000->remote_bytes -= io_len; + } + else + { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } + } + else + { + ne2000->remote_bytes = 0; + } - default: - ne2000_log("asic read invalid address %04x\n", (unsigned) offset); - break; - } + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) + { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); + } + } + break; - return (retval); + case 0xf: // Reset register + ne2000_reset(ne2000, BX_RESET_SOFTWARE); + break; + + default: + ne2000_log("asic read invalid address %04x\n", (unsigned) offset); + break; + } + + return (retval); } void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); - switch (offset) { - case 0x0: // Data register - see asic_read for a description + ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); + switch (offset) + { + case 0x0: // Data register - see asic_read for a description + if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) + { + ne2000_log("dma write length %d on byte mode operation\n", io_len); + break; + } + if (ne2000->remote_bytes == 0) + { + ne2000_log("dma write, byte count 0\n"); + } - if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) { - ne2000_log("dma write length %d on byte mode operation\n", io_len); - break; - } - if (ne2000->remote_bytes == 0) { - ne2000_log("dma write, byte count 0\n"); - } + ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); + if (io_len == 4) + { + ne2000->remote_dma += io_len; + } + else + { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } - ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); - if (io_len == 4) { - ne2000->remote_dma += io_len; - } else { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_dma == ne2000->page_stop << 8) { - ne2000->remote_dma = ne2000->page_start << 8; - } + if (ne2000->remote_dma == ne2000->page_stop << 8) + { + ne2000->remote_dma = ne2000->page_start << 8; + } - if (io_len == 4) { - ne2000->remote_bytes -= io_len; - } else { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) - ne2000->remote_bytes = 0; + if (io_len == 4) + { + ne2000->remote_bytes -= io_len; + } + else + { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - } - } - break; + if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) + { + ne2000->remote_bytes = 0; + } - case 0xf: // Reset register - // end of reset pulse - break; + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) + { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); + } + } + break; - default: // this is invalid, but happens under win95 device detection - ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); - break; - } + case 0xf: // Reset register + // end of reset pulse + break; + + default: // this is invalid, but happens under win95 device detection + ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); + break; + } } // @@ -639,311 +690,346 @@ void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsign // uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - uint8_t value = 0; + uint8_t value = 0; - if (io_len > 1) { - ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, - io_len); /* encountered with win98 hardware probe */ - return value; - } + if (io_len > 1) + { + ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, io_len); /* encountered with win98 hardware probe */ + return value; + } - switch (offset) { - case 0x1: // CLDA0 - value = (ne2000->local_dma & 0xff); - break; + switch (offset) + { + case 0x1: // CLDA0 + value = (ne2000->local_dma & 0xff); + break; - case 0x2: // CLDA1 - value = (ne2000->local_dma >> 8); - break; + case 0x2: // CLDA1 + value = (ne2000->local_dma >> 8); + break; - case 0x3: // BNRY - value = ne2000->bound_ptr; - break; + case 0x3: // BNRY + value = ne2000->bound_ptr; + break; - case 0x4: // TSR - value = ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); - break; + case 0x4: // TSR + value = ((ne2000->TSR.ow_coll << 7) | + (ne2000->TSR.cd_hbeat << 6) | + (ne2000->TSR.fifo_ur << 5) | + (ne2000->TSR.no_carrier << 4) | + (ne2000->TSR.aborted << 3) | + (ne2000->TSR.collided << 2) | + (ne2000->TSR.tx_ok)); + break; - case 0x5: // NCR - value = ne2000->num_coll; - break; + case 0x5: // NCR + value = ne2000->num_coll; + break; - case 0x6: // FIFO - // reading FIFO is only valid in loopback mode - ne2000_log("reading FIFO not supported yet\n"); - value = ne2000->fifo; - break; + case 0x6: // FIFO + // reading FIFO is only valid in loopback mode + ne2000_log("reading FIFO not supported yet\n"); + value = ne2000->fifo; + break; - case 0x7: // ISR - value = ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - break; + case 0x7: // ISR + value = ((ne2000->ISR.reset << 7) | + (ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + break; - case 0x8: // CRDA0 - value = (ne2000->remote_dma & 0xff); - break; + case 0x8: // CRDA0 + value = (ne2000->remote_dma & 0xff); + break; - case 0x9: // CRDA1 - value = (ne2000->remote_dma >> 8); - break; + case 0x9: // CRDA1 + value = (ne2000->remote_dma >> 8); + break; - case 0xa: // reserved / RTL8029ID0 - if (network_card_current == 2) { - value = 0x50; - } else { - ne2000_log("reserved read - page 0, 0xa\n"); - value = 0xff; - } - break; + case 0xa: // reserved / RTL8029ID0 + if (network_card_current == 2) + { + value = 0x50; + } + else + { + ne2000_log("reserved read - page 0, 0xa\n"); + value = 0xff; + } + break; - case 0xb: // reserved / RTL8029ID1 - if (network_card_current == 2) { - value = 0x43; - } else { - ne2000_log("reserved read - page 0, 0xb\n"); - value = 0xff; - } - break; + case 0xb: // reserved / RTL8029ID1 + if (network_card_current == 2) + { + value = 0x43; + } + else + { + ne2000_log("reserved read - page 0, 0xb\n"); + value = 0xff; + } + break; - case 0xc: // RSR - value = ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); - break; + case 0xc: // RSR + value = ((ne2000->RSR.deferred << 7) | + (ne2000->RSR.rx_disabled << 6) | + (ne2000->RSR.rx_mbit << 5) | + (ne2000->RSR.rx_missed << 4) | + (ne2000->RSR.fifo_or << 3) | + (ne2000->RSR.bad_falign << 2) | + (ne2000->RSR.bad_crc << 1) | + (ne2000->RSR.rx_ok)); + break; - case 0xd: // CNTR0 - value = ne2000->tallycnt_0; - break; + case 0xd: // CNTR0 + value = ne2000->tallycnt_0; + break; - case 0xe: // CNTR1 - value = ne2000->tallycnt_1; - break; + case 0xe: // CNTR1 + value = ne2000->tallycnt_1; + break; - case 0xf: // CNTR2 - value = ne2000->tallycnt_2; - break; + case 0xf: // CNTR2 + value = ne2000->tallycnt_2; + break; - default: - ne2000_log("page 0 register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 0 register 0x%02x out of range\n", offset); + break; + } - ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); - return value; + ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); + return value; } void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - uint8_t value2; + uint8_t value2; - // It appears to be a common practice to use outw on page0 regs... + // It appears to be a common practice to use outw on page0 regs... - // break up outw into two outb's - if (io_len == 2) { - ne2000_page0_write(ne2000, offset, (value & 0xff), 1); - if (offset < 0x0f) { - ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); - } - return; - } + // break up outw into two outb's + if (io_len == 2) + { + ne2000_page0_write(ne2000, offset, (value & 0xff), 1); + if (offset < 0x0f) + { + ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); + } + return; + } - ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); + ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); - switch (offset) { - case 0x1: // PSTART - ne2000->page_start = value; - break; + switch (offset) + { + case 0x1: // PSTART + ne2000->page_start = value; + break; - case 0x2: // PSTOP - ne2000->page_stop = value; - break; + case 0x2: // PSTOP + ne2000->page_stop = value; + break; - case 0x3: // BNRY - ne2000->bound_ptr = value; - break; + case 0x3: // BNRY + ne2000->bound_ptr = value; + break; - case 0x4: // TPSR - ne2000->tx_page_start = value; - break; + case 0x4: // TPSR + ne2000->tx_page_start = value; + break; - case 0x5: // TBCR0 - // Clear out low byte and re-insert - ne2000->tx_bytes &= 0xff00; - ne2000->tx_bytes |= (value & 0xff); - break; + case 0x5: // TBCR0 + // Clear out low byte and re-insert + ne2000->tx_bytes &= 0xff00; + ne2000->tx_bytes |= (value & 0xff); + break; - case 0x6: // TBCR1 - // Clear out high byte and re-insert - ne2000->tx_bytes &= 0x00ff; - ne2000->tx_bytes |= ((value & 0xff) << 8); - break; + case 0x6: // TBCR1 + // Clear out high byte and re-insert + ne2000->tx_bytes &= 0x00ff; + ne2000->tx_bytes |= ((value & 0xff) << 8); + break; - case 0x7: // ISR - value &= 0x7f; // clear RST bit - status-only bit - // All other values are cleared iff the ISR bit is 1 - ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); - ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); - ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); - ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); - ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); - ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value == 0) - picintc(1 << ne2000->base_irq); - break; + case 0x7: // ISR + value &= 0x7f; // clear RST bit - status-only bit + // All other values are cleared iff the ISR bit is 1 + ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); + ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); + ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); + ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); + ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); + ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); + ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); + value = ((ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + value &= ((ne2000->IMR.rdma_inte << 6) | + (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | + (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | + (ne2000->IMR.tx_inte << 1) | + (ne2000->IMR.rx_inte)); + if (value == 0) + { + picintc(1 << ne2000->base_irq); + } + break; - case 0x8: // RSAR0 - // Clear out low byte and re-insert - ne2000->remote_start &= 0xff00; - ne2000->remote_start |= (value & 0xff); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x8: // RSAR0 + // Clear out low byte and re-insert + ne2000->remote_start &= 0xff00; + ne2000->remote_start |= (value & 0xff); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0x9: // RSAR1 - // Clear out high byte and re-insert - ne2000->remote_start &= 0x00ff; - ne2000->remote_start |= ((value & 0xff) << 8); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x9: // RSAR1 + // Clear out high byte and re-insert + ne2000->remote_start &= 0x00ff; + ne2000->remote_start |= ((value & 0xff) << 8); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0xa: // RBCR0 - // Clear out low byte and re-insert - ne2000->remote_bytes &= 0xff00; - ne2000->remote_bytes |= (value & 0xff); - break; + case 0xa: // RBCR0 + // Clear out low byte and re-insert + ne2000->remote_bytes &= 0xff00; + ne2000->remote_bytes |= (value & 0xff); + break; - case 0xb: // RBCR1 - // Clear out high byte and re-insert - ne2000->remote_bytes &= 0x00ff; - ne2000->remote_bytes |= ((value & 0xff) << 8); - break; + case 0xb: // RBCR1 + // Clear out high byte and re-insert + ne2000->remote_bytes &= 0x00ff; + ne2000->remote_bytes |= ((value & 0xff) << 8); + break; - case 0xc: // RCR - // Check if the reserved bits are set - if (value & 0xc0) - ne2000_log("RCR write, reserved bits set\n"); + case 0xc: // RCR + // Check if the reserved bits are set + if (value & 0xc0) + { + ne2000_log("RCR write, reserved bits set\n"); + } - // Set all other bit-fields - ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); - ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); - ne2000->RCR.broadcast = ((value & 0x04) == 0x04); - ne2000->RCR.multicast = ((value & 0x08) == 0x08); - ne2000->RCR.promisc = ((value & 0x10) == 0x10); - ne2000->RCR.monitor = ((value & 0x20) == 0x20); + // Set all other bit-fields + ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); + ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); + ne2000->RCR.broadcast = ((value & 0x04) == 0x04); + ne2000->RCR.multicast = ((value & 0x08) == 0x08); + ne2000->RCR.promisc = ((value & 0x10) == 0x10); + ne2000->RCR.monitor = ((value & 0x20) == 0x20); - // Monitor bit is a little suspicious... - if (value & 0x20) - ne2000_log("RCR write, monitor bit set!\n"); - break; + // Monitor bit is a little suspicious... + if (value & 0x20) + { + ne2000_log("RCR write, monitor bit set!\n"); + } + break; - case 0xd: // TCR - // Check reserved bits - if (value & 0xe0) - ne2000_log("TCR write, reserved bits set\n"); + case 0xd: // TCR + // Check reserved bits + if (value & 0xe0) + { + ne2000_log("TCR write, reserved bits set\n"); + } - // Test loop mode (not supported) - if (value & 0x06) { - ne2000->TCR.loop_cntl = (value & 0x6) >> 1; - ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } else { - ne2000->TCR.loop_cntl = 0; - } + // Test loop mode (not supported) + if (value & 0x06) + { + ne2000->TCR.loop_cntl = (value & 0x6) >> 1; + ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); + } + else + { + ne2000->TCR.loop_cntl = 0; + } - // Inhibit-CRC not supported. - if (value & 0x01) - ne2000_log("TCR write, inhibit-CRC not supported\n"); + // Inhibit-CRC not supported. + if (value & 0x01) + { + ne2000_log("TCR write, inhibit-CRC not supported\n"); + } - // Auto-transmit disable very suspicious - if (value & 0x08) - ne2000_log("TCR write, auto transmit disable not supported\n"); + // Auto-transmit disable very suspicious + if (value & 0x08) + { + ne2000_log("TCR write, auto transmit disable not supported\n"); + } - // Allow collision-offset to be set, although not used - ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); - break; + // Allow collision-offset to be set, although not used + ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); + break; - case 0xe: // DCR - // the loopback mode is not suppported yet - if (!(value & 0x08)) { - ne2000_log("DCR write, loopback mode selected\n"); - } - // It is questionable to set longaddr and auto_rx, since they - // aren't supported on the ne2000. Print a warning and continue - if (value & 0x04) - ne2000_log("DCR write - LAS set ???\n"); - if (value & 0x10) - ne2000_log("DCR write - AR set ???\n"); + case 0xe: // DCR + // the loopback mode is not suppported yet + if (!(value & 0x08)) + { + ne2000_log("DCR write, loopback mode selected\n"); + } + // It is questionable to set longaddr and auto_rx, since they + // aren't supported on the ne2000. Print a warning and continue + if (value & 0x04) + { + ne2000_log("DCR write - LAS set ???\n"); + } + if (value & 0x10) + { + ne2000_log("DCR write - AR set ???\n"); + } - // Set other values. - ne2000->DCR.wdsize = ((value & 0x01) == 0x01); - ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? - ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? - ne2000->DCR.fifo_size = (value & 0x50) >> 5; - break; + // Set other values. + ne2000->DCR.wdsize = ((value & 0x01) == 0x01); + ne2000->DCR.endian = ((value & 0x02) == 0x02); + ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? + ne2000->DCR.loop = ((value & 0x08) == 0x08); + ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? + ne2000->DCR.fifo_size = (value & 0x50) >> 5; + break; - case 0xf: // IMR - // Check for reserved bit - if (value & 0x80) - ne2000_log("IMR write, reserved bit set\n"); + case 0xf: // IMR + // Check for reserved bit + if (value & 0x80) + { + ne2000_log("IMR write, reserved bit set\n"); + } - // Set other values - ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); - ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); - ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); - ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); - ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); - ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); - ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - value2 = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - if (((value & value2) & 0x7f) == 0) { - picintc(1 << ne2000->base_irq); - } else { - picint(1 << ne2000->base_irq); - } - break; + // Set other values + ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); + ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); + ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); + ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); + ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); + ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); + ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); + value2 = ((ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + if (((value & value2) & 0x7f) == 0) + { + picintc(1 << ne2000->base_irq); + } + else + { + picint(1 << ne2000->base_irq); + } + break; - default: - ne2000_log("page 0 write, bad register 0x%02x\n", offset); - break; - } + default: + ne2000_log("page 0 write, bad register 0x%02x\n", offset); + break; + } } // @@ -952,84 +1038,76 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); + ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); - switch (offset) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - return (ne2000->physaddr[offset - 1]); - break; + switch (offset) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + return (ne2000->physaddr[offset - 1]); - case 0x7: // CURR - ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); - return (ne2000->curr_page); + case 0x7: // CURR + ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); + return (ne2000->curr_page); - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - return (ne2000->mchash[offset - 8]); - break; + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + return (ne2000->mchash[offset - 8]); - default: - ne2000_log("page 1 read register 0x%02x out of range\n", offset); - break; - } - - return (0); + default: + ne2000_log("page 1 read register 0x%02x out of range\n", offset); + return 0; + } } void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, - io_len, value); + ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - switch (offset) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - ne2000->physaddr[offset - 1] = value; - if (offset == 6) { - ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", - ne2000->physaddr[0], - ne2000->physaddr[1], - ne2000->physaddr[2], - ne2000->physaddr[3], - ne2000->physaddr[4], - ne2000->physaddr[5]); - } - break; + switch (offset) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + ne2000->physaddr[offset - 1] = value; + if (offset == 6) + { + ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", ne2000->physaddr[0], ne2000->physaddr[1], ne2000->physaddr[2], ne2000->physaddr[3], ne2000->physaddr[4], ne2000->physaddr[5]); + } + break; - case 0x7: // CURR - ne2000->curr_page = value; - break; + case 0x7: // CURR + ne2000->curr_page = value; + break; - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000->mchash[offset - 8] = value; - break; + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ne2000->mchash[offset - 8] = value; + break; - default: - ne2000_log("page 1 write register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 1 write register 0x%02x out of range\n", offset); + break; + } } // @@ -1038,136 +1116,137 @@ void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); + ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); - switch (offset) { - case 0x1: // PSTART - return (ne2000->page_start); + switch (offset) + { + case 0x1: // PSTART + return (ne2000->page_start); - case 0x2: // PSTOP - return (ne2000->page_stop); + case 0x2: // PSTOP + return (ne2000->page_stop); - case 0x3: // Remote Next-packet pointer - return (ne2000->rempkt_ptr); + case 0x3: // Remote Next-packet pointer + return (ne2000->rempkt_ptr); - case 0x4: // TPSR - return (ne2000->tx_page_start); + case 0x4: // TPSR + return (ne2000->tx_page_start); - case 0x5: // Local Next-packet pointer - return (ne2000->localpkt_ptr); + case 0x5: // Local Next-packet pointer + return (ne2000->localpkt_ptr); - case 0x6: // Address counter (upper) - return (ne2000->address_cnt >> 8); + case 0x6: // Address counter (upper) + return (ne2000->address_cnt >> 8); - case 0x7: // Address counter (lower) - return (ne2000->address_cnt & 0xff); + case 0x7: // Address counter (lower) + return (ne2000->address_cnt & 0xff); - case 0x8: // Reserved - case 0x9: - case 0xa: - case 0xb: - ne2000_log("reserved read - page 2, register 0x%02x\n", offset); - return (0xff); + case 0x8: // Reserved + case 0x9: + case 0xa: + case 0xb: + ne2000_log("reserved read - page 2, register 0x%02x\n", offset); + return (0xff); - case 0xc: // RCR - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); + case 0xc: // RCR + return ((ne2000->RCR.monitor << 5) | + (ne2000->RCR.promisc << 4) | + (ne2000->RCR.multicast << 3) | + (ne2000->RCR.broadcast << 2) | + (ne2000->RCR.runts_ok << 1) | + (ne2000->RCR.errors_ok)); - case 0xd: // TCR - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); + case 0xd: // TCR + return ((ne2000->TCR.coll_prio << 4) | + (ne2000->TCR.ext_stoptx << 3) | + ((ne2000->TCR.loop_cntl & 0x3) << 1) | + (ne2000->TCR.crc_disable)); - case 0xe: // DCR - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); + case 0xe: // DCR + return (((ne2000->DCR.fifo_size & 0x3) << 5) | + (ne2000->DCR.auto_rx << 4) | + (ne2000->DCR.loop << 3) | + (ne2000->DCR.longaddr << 2) | + (ne2000->DCR.endian << 1) | + (ne2000->DCR.wdsize)); - case 0xf: // IMR - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); + case 0xf: // IMR + return ((ne2000->IMR.rdma_inte << 6) | + (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | + (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | + (ne2000->IMR.tx_inte << 1) | + (ne2000->IMR.rx_inte)); - default: - ne2000_log("page 2 register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 2 register 0x%02x out of range\n", offset); + break; + } - return (0); + return (0); } void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - // Maybe all writes here should be BX_PANIC()'d, since they - // affect internal operation, but let them through for now - // and print a warning. - ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, - io_len, value); + // Maybe all writes here should be BX_PANIC()'d, since they + // affect internal operation, but let them through for now + // and print a warning. + ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - switch (offset) { - case 0x1: // CLDA0 - // Clear out low byte and re-insert - ne2000->local_dma &= 0xff00; - ne2000->local_dma |= (value & 0xff); - break; + switch (offset) + { + case 0x1: // CLDA0 + // Clear out low byte and re-insert + ne2000->local_dma &= 0xff00; + ne2000->local_dma |= (value & 0xff); + break; - case 0x2: // CLDA1 - // Clear out high byte and re-insert - ne2000->local_dma &= 0x00ff; - ne2000->local_dma |= ((value & 0xff) << 8); - break; + case 0x2: // CLDA1 + // Clear out high byte and re-insert + ne2000->local_dma &= 0x00ff; + ne2000->local_dma |= ((value & 0xff) << 8); + break; - case 0x3: // Remote Next-pkt pointer - ne2000->rempkt_ptr = value; - break; + case 0x3: // Remote Next-pkt pointer + ne2000->rempkt_ptr = value; + break; - case 0x4: - ne2000_log("page 2 write to reserved register 0x04\n"); - break; + case 0x4: + ne2000_log("page 2 write to reserved register 0x04\n"); + break; - case 0x5: // Local Next-packet pointer - ne2000->localpkt_ptr = value; - break; + case 0x5: // Local Next-packet pointer + ne2000->localpkt_ptr = value; + break; - case 0x6: // Address counter (upper) - // Clear out high byte and re-insert - ne2000->address_cnt &= 0x00ff; - ne2000->address_cnt |= ((value & 0xff) << 8); - break; + case 0x6: // Address counter (upper) + // Clear out high byte and re-insert + ne2000->address_cnt &= 0x00ff; + ne2000->address_cnt |= ((value & 0xff) << 8); + break; - case 0x7: // Address counter (lower) - // Clear out low byte and re-insert - ne2000->address_cnt &= 0xff00; - ne2000->address_cnt |= (value & 0xff); - break; + case 0x7: // Address counter (lower) + // Clear out low byte and re-insert + ne2000->address_cnt &= 0xff00; + ne2000->address_cnt |= (value & 0xff); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000_log("page 2 write to reserved register 0x%02x\n", offset); - break; + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ne2000_log("page 2 write to reserved register 0x%02x\n", offset); + break; - default: - ne2000_log("page 2 write, illegal register 0x%02x\n", offset); - break; - } + default: + ne2000_log("page 2 write, illegal register 0x%02x\n", offset); + break; + } } // @@ -1175,48 +1254,48 @@ void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - if (network_card_current == 2) { - switch (offset) { - case 0x3: // CONFIG0 - return (0); - case 0x5: // CONFIG2 - return (0x40); - case 0x6: // CONFIG3 - return (0x40); - default: - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } - } else { - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } + if (network_card_current == 2) + { + switch (offset) + { + case 0x3: // CONFIG0 + return (0); + case 0x5: // CONFIG2 + return (0x40); + case 0x6: // CONFIG3 + return (0x40); + default: + ne2000_log("page 3 read register 0x%02x attempted\n", offset); + return (0); + } + } + else + { + ne2000_log("page 3 read register 0x%02x attempted\n", offset); + return (0); + } } void ne2000_page3_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("page 3 write register 0x%02x attempted\n", offset); - return; -} - -void ne2000_tx_timer(void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_log("tx_timer\n"); - ne2000->CR.tx_packet = 0; - ne2000->TSR.tx_ok = 1; - ne2000->ISR.pkt_tx = 1; - // Generate an interrupt if not masked - if (ne2000->IMR.tx_inte) { - picint(1 << ne2000->base_irq); - } - ne2000->tx_timer_active = 0; + ne2000_log("page 3 write register 0x%02x attempted\n", offset); + return; } void ne2000_tx_event(void *p, uint32_t val) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_tx_timer(ne2000); + ne2000_t *ne2000 = (ne2000_t *)p; + + ne2000_log("tx_timer\n"); + ne2000->CR.tx_packet = 0; + ne2000->TSR.tx_ok = 1; + ne2000->ISR.pkt_tx = 1; + // Generate an interrupt if not masked + if (ne2000->IMR.tx_inte) + { + picint(1 << ne2000->base_irq); + } + ne2000->tx_timer_active = 0; } // @@ -1226,79 +1305,91 @@ void ne2000_tx_event(void *p, uint32_t val) // uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) { - ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); - uint32_t retval = 0; - int offset = address - ne2000->base_address; + ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); + uint32_t retval = 0; + int offset = address - ne2000->base_address; - if (offset >= 0x10) { - retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); - } else if (offset == 0x00) { - retval = ne2000_read_cr(ne2000); - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - retval = ne2000_page0_read(ne2000, offset, io_len); - break; + if (offset >= 0x10) + { + retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); + } + else if (offset == 0x00) + { + retval = ne2000_read_cr(ne2000); + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + retval = ne2000_page0_read(ne2000, offset, io_len); + break; - case 0x01: - retval = ne2000_page1_read(ne2000, offset, io_len); - break; + case 0x01: + retval = ne2000_page1_read(ne2000, offset, io_len); + break; - case 0x02: - retval = ne2000_page2_read(ne2000, offset, io_len); - break; + case 0x02: + retval = ne2000_page2_read(ne2000, offset, io_len); + break; - case 0x03: - retval = ne2000_page3_read(ne2000, offset, io_len); - break; + case 0x03: + retval = ne2000_page3_read(ne2000, offset, io_len); + break; - default: - ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - break; - } - } + default: + ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + break; + } + } - return (retval); + return (retval); } void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { - ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); - int offset = address - ne2000->base_address; + ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); + int offset = address - ne2000->base_address; - // - // The high 16 bytes of i/o space are for the ne2000 asic - - // the low 16 bytes are for the DS8390, with the current - // page being selected by the PS0,PS1 registers in the - // command register - // - if (offset >= 0x10) { - ne2000_asic_write(ne2000, offset - 0x10, value, io_len); - } else if (offset == 0x00) { - ne2000_write_cr(ne2000, value); - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - ne2000_page0_write(ne2000, offset, value, io_len); - break; + // + // The high 16 bytes of i/o space are for the ne2000 asic - + // the low 16 bytes are for the DS8390, with the current + // page being selected by the PS0,PS1 registers in the + // command register + // + if (offset >= 0x10) + { + ne2000_asic_write(ne2000, offset - 0x10, value, io_len); + } + else if (offset == 0x00) + { + ne2000_write_cr(ne2000, value); + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + ne2000_page0_write(ne2000, offset, value, io_len); + break; - case 0x01: - ne2000_page1_write(ne2000, offset, value, io_len); - break; + case 0x01: + ne2000_page1_write(ne2000, offset, value, io_len); + break; - case 0x02: - ne2000_page2_write(ne2000, offset, value, io_len); - break; + case 0x02: + ne2000_page2_write(ne2000, offset, value, io_len); + break; - case 0x03: - ne2000_page3_write(ne2000, offset, value, io_len); - break; + case 0x03: + ne2000_page3_write(ne2000, offset, value, io_len); + break; - default: - ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; - } - } + default: + ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; + } + } } /* @@ -1308,22 +1399,26 @@ void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned i static int mcast_index(const void *dst) { #define POLYNOMIAL 0x04c11db6 - unsigned long crc = 0xffffffffL; - int carry, i, j; - unsigned char b; - unsigned char *ep = (unsigned char *) dst; + unsigned long crc = 0xffffffffL; + int carry, i, j; + unsigned char b; + unsigned char *ep = (unsigned char *) dst; - for (i = 6; --i >= 0;) { - b = *ep++; - for (j = 8; --j >= 0;) { - carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); - crc <<= 1; - b >>= 1; - if (carry) - crc = ((crc ^ POLYNOMIAL) | carry); - } - } - return (crc >> 26); + for (i = 6; --i >= 0;) + { + b = *ep++; + for (j = 8; --j >= 0;) + { + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); + crc <<= 1; + b >>= 1; + if (carry) + { + crc = ((crc ^ POLYNOMIAL) | carry); + } + } + } + return (crc >> 26); #undef POLYNOMIAL } @@ -1336,149 +1431,157 @@ static int mcast_index(const void *dst) */ void ne2000_rx_frame(void *p, const void *buf, int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - int pages; - int avail; - int idx; - int wrapped; - int nextpage; - uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *) buf; - uint8_t *startptr; - static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; + int pages; + int avail; + int idx; + int wrapped; + int nextpage; + uint8_t pkthdr[4]; + uint8_t *pktbuf = (uint8_t *) buf; + uint8_t *startptr; + static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; - if(io_len != 60) { - ne2000_log("rx_frame with length %d\n", io_len); - } + if(io_len != 60) + { + ne2000_log("rx_frame with length %d\n", io_len); + } - //LOG_MSG("stop=%d, pagestart=%x, dcr_loop=%x, tcr_loopcntl=%x", - // ne2000->CR.stop, ne2000->page_start, - // ne2000->DCR.loop, ne2000->TCR.loop_cntl); - if ((ne2000->CR.stop != 0) || - (ne2000->page_start == 0) /*|| - ((ne2000->DCR.loop == 0) && - (ne2000->TCR.loop_cntl != 0))*/) { - return; - } + if ((ne2000->CR.stop != 0) || + (ne2000->page_start == 0)) + { + return; + } - // Add the pkt header + CRC to the length, and work - // out how many 256-byte pages the frame would occupy - pages = (io_len + 4 + 4 + 255)/256; + // Add the pkt header + CRC to the length, and work + // out how many 256-byte pages the frame would occupy + pages = (io_len + 4 + 4 + 255)/256; - if (ne2000->curr_page < ne2000->bound_ptr) { - avail = ne2000->bound_ptr - ne2000->curr_page; - } else { - avail = (ne2000->page_stop - ne2000->page_start) - - (ne2000->curr_page - ne2000->bound_ptr); - wrapped = 1; - } + if (ne2000->curr_page < ne2000->bound_ptr) + { + avail = ne2000->bound_ptr - ne2000->curr_page; + } + else + { + avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->bound_ptr); + wrapped = 1; + } - // Avoid getting into a buffer overflow condition by not attempting - // to do partial receives. The emulation to handle this condition - // seems particularly painful. - if ((avail < pages) + // Avoid getting into a buffer overflow condition by not attempting + // to do partial receives. The emulation to handle this condition + // seems particularly painful. + if ((avail < pages) #if BX_NE2K_NEVER_FULL_RING - || (avail == pages) + || (avail == pages) #endif - ) { - ne2000_log("no space\n"); - return; - } + ) + { + ne2000_log("no space\n"); + return; + } - if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) { - ne2000_log("rejected small packet, length %d\n", io_len); - return; - } - // some computers don't care... - if (io_len < 60) io_len=60; + if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) + { + ne2000_log("rejected small packet, length %d\n", io_len); + return; + } + // some computers don't care... + if (io_len < 60) + { + io_len=60; + } - // Do address filtering if not in promiscuous mode - if (! ne2000->RCR.promisc) { - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (buf+4); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (bcast_addr); - mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); - // if (!memcmp(buf, bcast_addr, 6)) { - if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { - if (!ne2000->RCR.broadcast) { - return; - } - } else if (pktbuf[0] & 0x01) { - if (! ne2000->RCR.multicast) { - return; - } - idx = mcast_index(buf); - if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) { - return; - } - } else if (0 != memcmp(buf, ne2000->physaddr, 6)) { - return; - } - } else { - ne2000_log("rx_frame promiscuous receive\n"); - } + // Do address filtering if not in promiscuous mode + if (! ne2000->RCR.promisc) + { + /* Received. */ + mac_cmp32[0] = *(uint32_t *) (buf); + mac_cmp16[0] = *(uint16_t *) (buf+4); + /* Local. */ + mac_cmp32[1] = *(uint32_t *) (bcast_addr); + mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); + if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) + { + if (!ne2000->RCR.broadcast) + { + return; + } + } + else if (pktbuf[0] & 0x01) + { + if (! ne2000->RCR.multicast) + { + return; + } + idx = mcast_index(buf); + if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) + { + return; + } + } + else if (0 != memcmp(buf, ne2000->physaddr, 6)) + { + return; + } + } + else + { + ne2000_log("rx_frame promiscuous receive\n"); + } - ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", - io_len, - pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], - pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); - nextpage = ne2000->curr_page + pages; - if (nextpage >= ne2000->page_stop) { - nextpage -= ne2000->page_stop - ne2000->page_start; - } + nextpage = ne2000->curr_page + pages; + if (nextpage >= ne2000->page_stop) + { + nextpage -= ne2000->page_stop - ne2000->page_start; + } - // Setup packet header - pkthdr[0] = 0; // rx status - old behavior - pkthdr[0] = 1; // Probably better to set it all the time - // rather than set it to 0, which is clearly wrong. - if (pktbuf[0] & 0x01) { - pkthdr[0] |= 0x20; // rx status += multicast packet - } - pkthdr[1] = nextpage; // ptr to next packet - pkthdr[2] = (io_len + 4) & 0xff; // length-low - pkthdr[3] = (io_len + 4) >> 8; // length-hi + // Setup packet header + pkthdr[0] = 0; // rx status - old behavior + pkthdr[0] = 1; // Probably better to set it all the time + // rather than set it to 0, which is clearly wrong. + if (pktbuf[0] & 0x01) + { + pkthdr[0] |= 0x20; // rx status += multicast packet + } + pkthdr[1] = nextpage; // ptr to next packet + pkthdr[2] = (io_len + 4) & 0xff; // length-low + pkthdr[3] = (io_len + 4) >> 8; // length-hi - // copy into buffer, update curpage, and signal interrupt if config'd - startptr = & ne2000->mem[ne2000->curr_page * 256 - - BX_NE2K_MEMSTART]; - if ((nextpage > ne2000->curr_page) || - ((ne2000->curr_page + pages) == ne2000->page_stop)) { - // memcpy(startptr, pkthdr, 4); - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, io_len); - ne2000->curr_page = nextpage; - } else { - int endbytes = (ne2000->page_stop - ne2000->curr_page) - * 256; - // memcpy(startptr, pkthdr, 4); - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, endbytes - 4); - startptr = & ne2000->mem[ne2000->page_start * 256 - - BX_NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), - io_len - endbytes + 8); - ne2000->curr_page = nextpage; - } + // copy into buffer, update curpage, and signal interrupt if config'd + startptr = & ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; + if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) + { + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, io_len); + ne2000->curr_page = nextpage; + } + else + { + int endbytes = (ne2000->page_stop - ne2000->curr_page) * 256; + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, endbytes - 4); + startptr = & ne2000->mem[ne2000->page_start * 256 - BX_NE2K_MEMSTART]; + memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); + ne2000->curr_page = nextpage; + } - ne2000->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) { - ne2000->RSR.rx_mbit = 1; - } + ne2000->RSR.rx_ok = 1; + if (pktbuf[0] & 0x80) + { + ne2000->RSR.rx_mbit = 1; + } - ne2000->ISR.pkt_rx = 1; - - if (ne2000->IMR.rx_inte) { - //LOG_MSG("packet rx interrupt"); - picint(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); - } //else LOG_MSG("no packet rx interrupt"); + ne2000->ISR.pkt_rx = 1; + if (ne2000->IMR.rx_inte) + { + picint(1 << ne2000->base_irq); + } } uint8_t ne2000_readb(uint16_t addr, void *p) @@ -1491,9 +1594,13 @@ uint16_t ne2000_readw(uint16_t addr, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; if (ne2000->DCR.wdsize & 1) + { return ne2000_read(ne2000, addr, 2); + } else - return ne2000_read(ne2000, addr, 1); + { + return ne2000_read(ne2000, addr, 1); + } } uint32_t ne2000_readl(uint16_t addr, void *p) @@ -1512,9 +1619,13 @@ void ne2000_writew(uint16_t addr, uint16_t val, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; if (ne2000->DCR.wdsize & 1) + { ne2000_write(ne2000, addr, val, 2); + } else + { ne2000_write(ne2000, addr, val, 1); + } } void ne2000_writel(uint16_t addr, uint32_t val, void *p) @@ -1532,32 +1643,35 @@ void ne2000_poller(void *p) uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; - - int res; -if(net_is_slirp) { - while(QueuePeek(slirpq)>0) - { - qp=QueueDelete(slirpq); - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - free(qp); - return; - } - ne2000_rx_frame(ne2000,&qp->data,qp->len); - ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); - free(qp); - } + int res; + if (!net_is_pcap) + { + while(QueuePeek(slirpq) > 0) + { + qp=QueueDelete(slirpq); + if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) + { + free(qp); + return; + } + ne2000_rx_frame(ne2000,&qp->data,qp->len); + ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); + free(qp); + } fizz++; - if(fizz>1200){fizz=0;slirp_tic();} - }//end slirp -if(net_is_pcap && net_pcap!=NULL) - { + if (fizz>1200) + { + fizz=0;slirp_tic(); + } + }//end slirp + else if (net_is_pcap && (net_pcap != NULL)) + { if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) { return; } - data=_pcap_next(net_pcap,&h); - if(data==0x0) + data=pcap_next(net_pcap,&h); + if(data==0x0) { return; } @@ -1567,18 +1681,12 @@ if(net_is_pcap && net_pcap!=NULL) /* Local. */ mac_cmp32[1] = *(uint32_t *) (maclocal); mac_cmp16[1] = *(uint16_t *) (maclocal+4); - // if((memcmp(data+6,maclocal,6))==0) - /* if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) - { - ne2000_log("ne2000 we just saw ourselves\n"); - } - else { */ if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { // ne2000_log("ne2000 pcap received a frame %d bytes\n",h.caplen); ne2000_rx_frame(ne2000,data,h.caplen); } - } + } } typedef union @@ -1599,64 +1707,85 @@ uint32_t bios_mask = 0; void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) { - old_base_addr = addr; - io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + old_base_addr = addr; + io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); } void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) { - io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); } uint8_t ne2000_pci_read(int func, int addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *) p; + ne2000_t *ne2000 = (ne2000_t *) p; - // ne2000_log("NE2000 PCI read %08X\n", addr); - switch (addr) - { - case 0x00:/* case 0x2C:*/ return 0xec; - case 0x01:/* case 0x2D:*/ return 0x10; + // ne2000_log("NE2000 PCI read %08X\n", addr); + switch (addr) + { + case 0x00: + return 0xec; + case 0x01: + return 0x10; - case 0x02:/* case 0x2E:*/ return 0x29; - case 0x03:/* case 0x2F:*/ return 0x80; + case 0x02: + return 0x29; + case 0x03: + return 0x80; - case 0x2C: return 0xF4; - case 0x2D: return 0x1A; - case 0x2E: return 0x00; - case 0x2F: return 0x11; + case 0x2C: + return 0xF4; + case 0x2D: + return 0x1A; + case 0x2E: + return 0x00; + case 0x2F: + return 0x11; - case 0x04: - return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return ne2000_pci_regs[0x05]; + case 0x04: + return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return ne2000_pci_regs[0x05]; - case 0x07: return 2; + case 0x07: + return 2; - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0B: return ne2000_pci_regs[0x0B]; + case 0x0B: + return ne2000_pci_regs[0x0B]; - case 0x10: return 1; /*I/O space*/ - case 0x11: return ne2000_pci_bar[0].addr_regs[1]; - case 0x12: return ne2000_pci_bar[0].addr_regs[2]; - case 0x13: return ne2000_pci_bar[0].addr_regs[3]; + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return ne2000_pci_bar[0].addr_regs[1]; + case 0x12: + return ne2000_pci_bar[0].addr_regs[2]; + case 0x13: + return ne2000_pci_bar[0].addr_regs[3]; - case 0x30: return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - // case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & 0xE0) | 0x18; - case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; - case 0x32: return ne2000_pci_bar[1].addr_regs[2]; - case 0x33: return ne2000_pci_bar[1].addr_regs[3]; + case 0x30: + return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; + case 0x32: + return ne2000_pci_bar[1].addr_regs[2]; + case 0x33: + return ne2000_pci_bar[1].addr_regs[3]; - case 0x3C: return ne2000_pci_regs[0x3C]; - case 0x3D: return ne2000_pci_regs[0x3D]; - } - return 0; + case 0x3C: + return ne2000_pci_regs[0x3C]; + case 0x3D: + return ne2000_pci_regs[0x3D]; + } + return 0; } void ne2000_update_bios(ne2000_t *ne2000) @@ -1682,63 +1811,57 @@ void ne2000_update_bios(ne2000_t *ne2000) void ne2000_pci_write(int func, int addr, uint8_t val, void *p) { - ne2000_t *ne2000 = (ne2000_t *) p; + ne2000_t *ne2000 = (ne2000_t *) p; - // ne2000_log("ne2000_pci_write: addr=%02x val=%02x\n", addr, val); - switch (addr) - { - case 0x04: - if (val & PCI_COMMAND_IO) - { - ne2000_io_remove(ne2000->base_address, ne2000); - ne2000_io_set(ne2000->base_address, ne2000); - } - else - { - ne2000_io_remove(ne2000->base_address, ne2000); - } - ne2000_pci_regs[addr] = val; - break; + switch (addr) + { + case 0x04: + ne2000_io_remove(ne2000->base_address, ne2000); + if (val & PCI_COMMAND_IO) + { + ne2000_io_set(ne2000->base_address, ne2000); + } + ne2000_pci_regs[addr] = val; + break; - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ - ne2000_io_remove(ne2000->base_address, ne2000); - /* Then let's set the PCI regs. */ - ne2000_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; - /* If the base is below 0x280, return. */ - /* Log the new base. */ - ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); - /* We're done, so get out of the here. */ - return; - - case 0x30: case 0x31: case 0x32: case 0x33: - ne2000_pci_bar[1].addr_regs[addr & 3] = val; - ne2000_pci_bar[1].addr_regs[1] &= bios_mask; - bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; - ne2000_pci_bar[1].addr &= 0xffffe000; - ne2000_pci_bar[1].addr |= 0x1801; - ne2000_update_bios(ne2000); - return; + case 0x10: + val &= 0xfc; + val |= 1; + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O, if old base was >= 0x280. */ + ne2000_io_remove(ne2000->base_address, ne2000); + /* Then let's set the PCI regs. */ + ne2000_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; + /* Log the new base. */ + ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); + /* We're done, so get out of the here. */ + return; -/* Commented out until an APIC controller is emulated for the PIIX3, - otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ + case 0x30: case 0x31: case 0x32: case 0x33: + ne2000_pci_bar[1].addr_regs[addr & 3] = val; + ne2000_pci_bar[1].addr_regs[1] &= bios_mask; + bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; + ne2000_pci_bar[1].addr &= 0xffffe000; + ne2000_pci_bar[1].addr |= 0x1801; + ne2000_update_bios(ne2000); + return; + + /* Commented out until an APIC controller is emulated for the PIIX3, + otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ #if 0 - case 0x3C: - ne2000_pci_regs[addr] = val; - if (val != 0xFF) - { - ne2000_log("NE2000 IRQ now: %i\n", val); - ne2000_setirq(ne2000, val); - } - return; + case 0x3C: + ne2000_pci_regs[addr] = val; + if (val != 0xFF) + { + ne2000_log("NE2000 IRQ now: %i\n", val); + ne2000_setirq(ne2000, val); + } + return; #endif - } + } } void ne2000_rom_init(ne2000_t *ne2000, char *s) @@ -1773,220 +1896,78 @@ void ne2000_rom_init(ne2000_t *ne2000, char *s) rom_init(&ne2000->bios_rom, s, 0xd0000, bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); } +static char errbuf[32768]; + void *ne2000_init() -{ - int rc; - int config_net_type; - int net_type; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); - memset(ne2000, 0, sizeof(ne2000_t)); - - ne2000->base_address = device_get_config_int("addr"); - disable_netbios = device_get_config_int("disable_netbios"); - ne2000_setirq(ne2000, device_get_config_int("irq")); - - //net_type - //0 pcap - //1 slirp - // - config_net_type = device_get_config_int("net_type"); - // net_is_slirp = config_get_int(NULL, "net_type", 1); - /* Network type is now specified in device config. */ - net_is_slirp = config_net_type ? 1 : 0; - net_is_pcap = config_net_type ? 0 : 1; - if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) - { - net_is_pcap = 0; - net_is_slirp = 1; - } - pclog("net_is_pcap = %i, net_is_slirp = %i\n", net_is_pcap, net_is_slirp); - - // ne2000_log("ne2000 pcap device %s\n",config_get_string(NULL,"pcap_device","nothing")); - - ne2000_io_set(ne2000->base_address, ne2000); - memcpy(ne2000->physaddr, maclocal, 6); - - if (!disable_netbios) - ne2000_rom_init(ne2000, "roms/ne2000.rom"); - - ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); - - ne2000_log("ne2000 isa init 0x%X %d\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,device_get_config_int("irq"),net_is_slirp,net_is_pcap); - - //need a switch statment for more network types. - - if ( net_is_slirp ) { - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if ( rc == 0 ) - { - ne2000_log("ne2000 slirp initalized!\n"); - - net_slirp_inited=1; - slirpq = QueueCreate(); - net_is_slirp=1; - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else { - net_slirp_inited=0; - net_is_slirp=0; - } - } - if ( net_is_pcap ) { //pcap - char errbuf[32768]; - - ne2000_log("ne2000 initalizing libpcap\n"); - net_is_slirp=0; - net_hLib = LoadLibraryA(net_lib_name); - if(net_hLib==0) - { - ne2000_log("ne2000 Failed to load %s\n",net_lib_name); - net_is_pcap=0; - //return; - } - _pcap_lib_version =(PCAP_LIB_VERSION)GetProcAddress(net_hLib,"pcap_lib_version"); - _pcap_open_live=(PCAP_OPEN_LIVE)GetProcAddress(net_hLib,"pcap_open_live"); - _pcap_sendpacket=(PCAP_SENDPACKET)GetProcAddress(net_hLib,"pcap_sendpacket"); - _pcap_setnonblock=(PCAP_SETNONBLOCK)GetProcAddress(net_hLib,"pcap_setnonblock"); - _pcap_next=(PCAP_NEXT)GetProcAddress(net_hLib,"pcap_next"); - _pcap_close=(PCAP_CLOSE)GetProcAddress(net_hLib,"pcap_close"); - _pcap_getnonblock=(PCAP_GETNONBLOCK)GetProcAddress(net_hLib,"pcap_getnonblock"); - _pcap_compile=(PCAP_COMPILE)GetProcAddress(net_hLib,"pcap_compile"); - _pcap_setfilter=(PCAP_SETFILTER)GetProcAddress(net_hLib,"pcap_setfilter"); - - if(_pcap_lib_version && _pcap_open_live && _pcap_sendpacket && _pcap_setnonblock && _pcap_next && _pcap_close && _pcap_getnonblock) - { - ne2000_log("ne2000 Pcap version [%s]\n",_pcap_lib_version()); - - //if((net_pcap=_pcap_open_live("\\Device\\NPF_{0CFA803F-F443-4BB9-A83A-657029A98195}",1518,1,15,errbuf))==0) - if((net_pcap=_pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; return(ne2000); //YUCK!!! - } - } - else { - ne2000_log("%d %d %d %d %d %d %d\n",_pcap_lib_version, _pcap_open_live,_pcap_sendpacket,_pcap_setnonblock,_pcap_next,_pcap_close,_pcap_getnonblock); - net_is_pcap=1; - } - - //Time to check that we are in non-blocking mode. - rc=_pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc=_pcap_setnonblock(net_pcap,1,errbuf); - if(rc==0) { //no errors! - ne2000_log(".."); - rc=_pcap_getnonblock(net_pcap,errbuf); - if(rc==1) { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else{ - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - }//end set nonblock - else{ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if( net_is_pcap ) { - if(_pcap_compile && _pcap_setfilter) { //we can do this! - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); - - //I'm doing a MAC level filter so TCP/IP doesn't matter. - if (_pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else { - ne2000_log("..."); - if (_pcap_setfilter(net_pcap, &fp) == -1) { - ne2000_log("\nError installing pcap filter.\n"); - }//end of set_filter failure - else { - ne2000_log("...!\n"); - } - } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - //scanf(filter_exp); //pause - } - else - { - ne2000_log("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); - net_is_pcap=0; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } - } //end pcap setup - - //timer_add(slirp_tic,&delay,TIMER_ALWAYS_ENABLED,NULL); - //timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); -ne2000_log("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); -//exit(0); -return ne2000; -} - -void *rtl8029as_init() { int rc; int config_net_type; int net_type; int irq; + int pcap_device_available = 0; + int is_rtl8029as = 0; ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); + if (PCI && (network_card_current == 2)) + { + is_rtl8029as = 1; + } + else + { + network_card_current = 1; + is_rtl8029as = 0; + } + + if (is_rtl8029as) + { + ne2000->base_address = 0x340; + } + else + { + ne2000->base_address = device_get_config_int("addr"); + } + disable_netbios = device_get_config_int("disable_netbios"); - + irq = device_get_config_int("irq"); ne2000_setirq(ne2000, irq); - //net_type - //0 pcap - //1 slirp - // config_net_type = device_get_config_int("net_type"); - // net_is_slirp = config_get_int(NULL, "net_type", 1); /* Network type is now specified in device config. */ - net_is_slirp = config_net_type ? 1 : 0; net_is_pcap = config_net_type ? 0 : 1; if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) { net_is_pcap = 0; - net_is_slirp = 1; + pcap_device_available = 0; } - pclog("net_is_pcap = %i, net_is_slirp = %i\n", net_is_pcap, net_is_slirp); - - // ne2000_log("ne2000 pcap device %s\n",config_get_string(NULL,"pcap_device","nothing")); - - pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + else + { + pcap_device_available = 1; + } + ne2000_log("net_is_pcap = %i\n", net_is_pcap); + if (is_rtl8029as) + { + pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + } + + ne2000_io_set(ne2000->base_address, ne2000); + + memcpy(ne2000->physaddr, maclocal, 6); + if (!disable_netbios) { - ne2000_rom_init(ne2000, "roms/rtl8029as.rom"); + ne2000_rom_init(ne2000, "roms/ne2000.rom"); - if (PCI) mem_mapping_disable(&ne2000->bios_rom.mapping); + if (is_rtl8029as) + { + mem_mapping_disable(&ne2000->bios_rom.mapping); + } } - + + if (is_rtl8029as) + { ne2000_pci_regs[0x04] = 1; ne2000_pci_regs[0x05] = 0; @@ -2020,411 +2001,398 @@ void *rtl8029as_init() rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; - - ne2000->base_address = 0x340; - ne2000_io_set(ne2000->base_address, ne2000); - - memcpy(ne2000->physaddr, maclocal, 6); + } - ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); + ne2000_reset(ne2000, BX_RESET_HARDWARE); + vlan_handler(ne2000_poller, ne2000); - ne2000_log("ne2000 pci init 0x%X\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,net_is_slirp,net_is_pcap); + ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); //need a switch statment for more network types. - - if ( net_is_slirp ) { - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if ( rc == 0 ) + if (!net_is_pcap) + { +initialize_slirp: + ne2000_log("ne2000 initalizing SLiRP\n"); + net_is_pcap=0; + rc=slirp_init(); + ne2000_log("ne2000 slirp_init returned: %d\n",rc); + if (!rc) { - ne2000_log("ne2000 slirp initalized!\n"); + ne2000_log("ne2000 slirp initalized!\n"); - net_slirp_inited=1; - slirpq = QueueCreate(); - net_is_slirp=1; - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else { - net_slirp_inited=0; - net_is_slirp=0; - } - } - if ( net_is_pcap ) { //pcap - char errbuf[32768]; + net_slirp_inited = 1; + slirpq = QueueCreate(); + fizz=0; + ne2000_log("ne2000 slirpq is %x\n",&slirpq); + } + else + { + net_slirp_inited = 0; + if (pcap_device_available) + { + net_is_pcap = 1; + goto initialize_pcap; + } + else + { + ne2000_log("Neither SLiRP nor PCap is available on your host, disabling network adapter...\n"); + free(ne2000); + network_card_current = 0; + resetpchard(); + return NULL; + } + } + } + else + { +initialize_pcap: + ne2000_log("ne2000 initalizing libpcap\n"); - ne2000_log("ne2000 initalizing libpcap\n"); - net_is_slirp=0; - net_hLib = LoadLibraryA(net_lib_name); - if(net_hLib==0) - { - ne2000_log("ne2000 Failed to load %s\n",net_lib_name); - net_is_pcap=0; - //return; - } - _pcap_lib_version =(PCAP_LIB_VERSION)GetProcAddress(net_hLib,"pcap_lib_version"); - _pcap_open_live=(PCAP_OPEN_LIVE)GetProcAddress(net_hLib,"pcap_open_live"); - _pcap_sendpacket=(PCAP_SENDPACKET)GetProcAddress(net_hLib,"pcap_sendpacket"); - _pcap_setnonblock=(PCAP_SETNONBLOCK)GetProcAddress(net_hLib,"pcap_setnonblock"); - _pcap_next=(PCAP_NEXT)GetProcAddress(net_hLib,"pcap_next"); - _pcap_close=(PCAP_CLOSE)GetProcAddress(net_hLib,"pcap_close"); - _pcap_getnonblock=(PCAP_GETNONBLOCK)GetProcAddress(net_hLib,"pcap_getnonblock"); - _pcap_compile=(PCAP_COMPILE)GetProcAddress(net_hLib,"pcap_compile"); - _pcap_setfilter=(PCAP_SETFILTER)GetProcAddress(net_hLib,"pcap_setfilter"); - - if(_pcap_lib_version && _pcap_open_live && _pcap_sendpacket && _pcap_setnonblock && _pcap_next && _pcap_close && _pcap_getnonblock) - { - ne2000_log("ne2000 Pcap version [%s]\n",_pcap_lib_version()); + ne2000_log("ne2000 Pcap version [%s]\n",pcap_lib_version()); - //if((net_pcap=_pcap_open_live("\\Device\\NPF_{0CFA803F-F443-4BB9-A83A-657029A98195}",1518,1,15,errbuf))==0) - if((net_pcap=_pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; return(ne2000); //YUCK!!! - } - } - else { - ne2000_log("%d %d %d %d %d %d %d\n",_pcap_lib_version, _pcap_open_live,_pcap_sendpacket,_pcap_setnonblock,_pcap_next,_pcap_close,_pcap_getnonblock); - net_is_pcap=1; - } + if((net_pcap=pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) + { + ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); + net_is_pcap=0; + return(ne2000); // YUCK!!! + } - //Time to check that we are in non-blocking mode. - rc=_pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc=_pcap_setnonblock(net_pcap,1,errbuf); - if(rc==0) { //no errors! - ne2000_log(".."); - rc=_pcap_getnonblock(net_pcap,errbuf); - if(rc==1) { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else{ - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - }//end set nonblock - else{ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if( net_is_pcap ) { - if(_pcap_compile && _pcap_setfilter) { //we can do this! - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); + //Time to check that we are in non-blocking mode. + rc=pcap_getnonblock(net_pcap,errbuf); + ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); + switch(rc) + { + case 0: + ne2000_log("ne2000 Setting interface to non-blocking mode.."); + rc = pcap_setnonblock(net_pcap,1,errbuf); + if (rc==0) + { // no errors! + ne2000_log(".."); + rc=pcap_getnonblock(net_pcap,errbuf); + if(rc == 1) + { + ne2000_log("..!",rc); + net_is_pcap=1; + } + else + { + ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap=0; + } + } // end set nonblock + else + { + ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} + ne2000_log("\n"); + break; + case 1: + ne2000_log("non blocking\n"); + break; + default: + ne2000_log("this isn't right!!!\n"); + net_is_pcap=0; + break; + } + if (net_is_pcap) + { + struct bpf_program fp; + char filter_exp[255]; + ne2000_log("ne2000 Building packet filter..."); + sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); - //I'm doing a MAC level filter so TCP/IP doesn't matter. - if (_pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else { - ne2000_log("..."); - if (_pcap_setfilter(net_pcap, &fp) == -1) { - ne2000_log("\nError installing pcap filter.\n"); - }//end of set_filter failure - else { - ne2000_log("...!\n"); - } - } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - //scanf(filter_exp); //pause - } - else - { - ne2000_log("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); - net_is_pcap=0; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } - } //end pcap setup + //I'm doing a MAC level filter so TCP/IP doesn't matter. + if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) + { + ne2000_log("\nne2000 Couldn't compile filter\n"); + } + else + { + ne2000_log("..."); + if (pcap_setfilter(net_pcap, &fp) == -1) + { + ne2000_log("\nError installing pcap filter.\n"); + }//end of set_filter failure + else + { + ne2000_log("...!\n"); + } + } + ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); + } + else + { + pcap_device_available = 0; + goto initialize_slirp; + } + ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); + } // end pcap setup - //timer_add(slirp_tic,&delay,TIMER_ALWAYS_ENABLED,NULL); - //timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); -ne2000_log("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); -//exit(0); -return ne2000; + ne2000_log("ne2000 is_pcap %d\n", net_is_pcap); + return ne2000; } - void ne2000_close(void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_io_remove(ne2000->base_address, ne2000); - free(ne2000); - - if(net_is_slirp) { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - ne2000_log("ne2000 exiting slirp\n"); - } - if(net_is_pcap && net_pcap!=NULL) - { - _pcap_close(net_pcap); - FreeLibrary(net_hLib); - ne2000_log("ne2000 closing pcap\n"); - } - ne2000_log("ne2000 close\n"); + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_io_remove(ne2000->base_address, ne2000); + free(ne2000); + + if(!net_is_pcap) + { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited=0; + ne2000_log("ne2000 exiting slirp\n"); + } + else if (net_is_pcap && (net_pcap != NULL)) + { + pcap_close(net_pcap); + ne2000_log("ne2000 closing pcap\n"); + } + ne2000_log("ne2000 close\n"); } static device_config_t ne2000_config[] = { - { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x320", - .value = 0x320 - }, - { - .description = "0x340", - .value = 0x340 - }, - { - .description = "0x360", - .value = 0x360 - }, - { - .description = "0x380", - .value = 0x380 - }, - { - .description = "" - } - }, - .default_int = 0x300 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "PCap", - .value = 0 - }, - { - .description = "SLiRP", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .type = -1 - } + { + .name = "addr", + .description = "Address", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x280", + .value = 0x280 + }, + { + .description = "0x300", + .value = 0x300 + }, + { + .description = "0x320", + .value = 0x320 + }, + { + .description = "0x340", + .value = 0x340 + }, + { + .description = "0x360", + .value = 0x360 + }, + { + .description = "0x380", + .value = 0x380 + }, + { + .description = "" + } + }, + .default_int = 0x300 + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "" + } + }, + .default_int = 10 + }, + { + .name = "net_type", + .description = "Network type", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "PCap", + .value = 0 + }, + { + .description = "SLiRP", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "disable_netbios", + .description = "Network bios", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Enabled", + .value = 0 + }, + { + .description = "Disabled", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .type = -1 + } }; static device_config_t rtl8029as_config[] = { - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "PCap", - .value = 0 - }, - { - .description = "SLiRP", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .type = -1 - } + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "" + } + }, + .default_int = 10 + }, + { + .name = "net_type", + .description = "Network type", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "PCap", + .value = 0 + }, + { + .description = "SLiRP", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "disable_netbios", + .description = "Network bios", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Enabled", + .value = 0 + }, + { + .description = "Disabled", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .type = -1 + } }; device_t ne2000_device = { - "Novell NE2000", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - ne2000_config + "Novell NE2000", + 0, + ne2000_init, + ne2000_close, + NULL, + NULL, + NULL, + NULL, + ne2000_config }; device_t rtl8029as_device = { - "Realtek RTL8029AS", - 0, - rtl8029as_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - rtl8029as_config + "Realtek RTL8029AS", + 0, + ne2000_init, + ne2000_close, + NULL, + NULL, + NULL, + NULL, + rtl8029as_config }; - //SLIRP stuff int slirp_can_output(void) { -return net_slirp_inited; + return net_slirp_inited; } void slirp_output (const unsigned char *pkt, int pkt_len) { -struct queuepacket *p; -p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); -p->len=pkt_len; -memcpy(p->data,pkt,pkt_len); -QueueEnter(slirpq,p); -ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); + struct queuepacket *p; + p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); + p->len=pkt_len; + memcpy(p->data,pkt,pkt_len); + QueueEnter(slirpq,p); + ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); } // Instead of calling this and crashing some times @@ -2432,28 +2400,32 @@ ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); // 60Hz clock which seems to do the job. void slirp_tic() { - int ret2,nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int timeout; - nfds=-1; + int ret2,nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int timeout; + nfds=-1; - if(net_slirp_inited) - { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); //this can crash + if(net_slirp_inited) + { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); // this can crash + + if(timeout<0) + { + timeout=500; + } - if(timeout<0) - timeout=500; - tv.tv_sec=0; - tv.tv_usec = timeout; //basilisk default 10000 + tv.tv_sec=0; + tv.tv_usec = timeout; // basilisk default 10000 - ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if(ret2>=0){ - slirp_select_poll(&rfds, &wfds, &xfds); - } - //ne2000_log("ne2000 slirp_tic()\n"); - }//end if slirp inited + ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + if(ret2>=0) + { + slirp_select_poll(&rfds, &wfds, &xfds); + } + //ne2000_log("ne2000 slirp_tic()\n"); + } // end if slirp inited } diff --git a/src/nethandler.c b/src/nethandler.c index b926d1cbe..76e239de5 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -14,6 +14,7 @@ #include "ne2000.h" #include "timer.h" +#include "thread.h" int network_card_current = 0; static int network_card_last = 0; @@ -83,19 +84,95 @@ void vlan_handler(void (*poller)(void *p), void *p) vlan_handlers_num++; } +static thread_t *network_thread_h; +static event_t *network_event; + +static int network_thread_initialized = 0; +static int network_thread_enable = 0; + +static void network_thread(void *param) +{ + int c; + + // pclog("Network thread\n"); + + while(1) + { + // pclog("Waiting...\n"); + thread_wait_event(network_event, -1); + + // pclog("Processing\n"); + + for (c = 0; c < vlan_handlers_num; c++) + vlan_handlers[c].poller(vlan_handlers[c].priv); + } +} + +void network_thread_init() +{ + pclog("network_thread_init()\n"); + + if (network_card_current) + { + pclog("Thread enabled...\n"); + + network_event = thread_create_event(); + network_thread_h = thread_create(network_thread, NULL); + } + + network_thread_enable = network_card_current ? 1 : 0; + network_thread_initialized = 1; +} + +void network_thread_reset() +{ + if(!network_thread_initialized) + { + network_thread_init(); + return; + } + + pclog("network_thread_reset()\n"); + if (network_card_current && !network_thread_enable) + { + pclog("Thread enabled (disabled before...\n"); + network_event = thread_create_event(); + network_thread_h = thread_create(network_thread, NULL); + } + else if (!network_card_current && network_thread_enable) + { + pclog("Thread disabled (enabled before...\n"); + thread_destroy_event(network_event); + thread_kill(network_thread_h); + network_thread_h = NULL; + } + + network_thread_enable = network_card_current ? 1 : 0; +} + void vlan_poller(void *priv) { int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); + vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 15000.0)); - for (c = 0; c < vlan_handlers_num; c++) - vlan_handlers[c].poller(vlan_handlers[c].priv); + if (network_thread_enable && vlan_handlers_num) + { + // pclog("Setting thread event...\n"); + thread_set_event(network_event); + } } void vlan_reset() { - timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); + pclog("vlan_reset()\n"); + + if (network_card_current) + { + pclog("Adding timer...\n"); + + timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); + } vlan_handlers_num = 0; } diff --git a/src/pc.c b/src/pc.c index ab4e2f7b6..915232cef 100644 --- a/src/pc.c +++ b/src/pc.c @@ -315,11 +315,14 @@ void initpc(int argc, char *argv[]) td0_init(); imd_init(); +#if 0 if (network_card_current != 0) { vlan_reset(); //NETWORK } network_card_init(network_card_current); + network_thread_init(); +#endif disc_load(0, discfns[0]); disc_load(1, discfns[1]); @@ -442,6 +445,7 @@ void resetpchard() vlan_reset(); //NETWORK } network_card_init(network_card_current); + network_thread_reset(); for (i = 0; i < CDROM_NUM; i++) { diff --git a/src/pc87306.c b/src/pc87306.c index cb67e05e7..e3e930117 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -19,7 +19,7 @@ static int pc87306_locked; static int pc87306_curreg; static uint8_t pc87306_regs[29]; -static uint8_t pc87306_gpio[2] = {0xFF, 0xFF}; +static uint8_t pc87306_gpio[2] = {0xFF, 0xFB}; static uint8_t tries; static uint16_t lpt_port; static int power_down = 0; @@ -29,10 +29,7 @@ void pc87306_gpio_init(); void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) { - if (port & 1) - { - return; - } + // pclog("GPIO: Writing %02X on port: %04X\n", val, port); pc87306_gpio[port & 1] = val; } @@ -167,13 +164,17 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { if (tries) { + if ((pc87306_curreg == 0) && (val == 8)) + { + val = 0x4b; + } if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; tries = 0; if ((pc87306_curreg == 0x19) && !(pc87306_regs[0x1B] & 0x40)) { return; } - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18)) + if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)/* && (pc87306_curreg != 0x18)*/) { if (pc87306_curreg == 0) { @@ -183,8 +184,8 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { pc87306_gpio_remove(); } - pc87306_regs[pc87306_curreg] = val; // pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); + pc87306_regs[pc87306_curreg] = val; goto process_value; } } @@ -237,7 +238,7 @@ process_value: break; case 1: - if (valxor & 1) + if (valxor & 3) { lpt1_remove(); if (pc87306_regs[0] & 1) @@ -248,22 +249,26 @@ process_value: if (valxor & 0xcc) { - serial1_remove(); - if (pc87306_regs[0] & 2) { serial1_handler(); } + else + { + serial1_remove(); + } } if (valxor & 0xf0) { - serial2_remove(); - if (pc87306_regs[0] & 4) { serial2_handler(); } + else + { + serial2_remove(); + } } break; case 2: @@ -344,11 +349,8 @@ process_value: } break; case 0x1C: - // if (valxor & 0x25) if (valxor) { - serial1_remove(); - serial2_remove(); if (pc87306_regs[0] & 2) { serial1_handler(); @@ -364,10 +366,7 @@ process_value: uint8_t pc87306_gpio_read(uint16_t port, void *priv) { - if (port & 1) - { - return 0xfb; /* Bit 2 clear, since we don't emulate the on-board audio. */ - } + // pclog("Read GPIO on port: %04X (%04X:%04X)\n", port, CS, cpu_state.pc); return pc87306_gpio[port & 1]; } @@ -393,14 +392,9 @@ uint8_t pc87306_read(uint16_t port, void *priv) } else if (pc87306_curreg == 8) { - // pclog("PC87306: Read ID at data register, index 08\n"); + // pclog("PC87306: Read ID at data register, index 08 (%04X:%04X)\n", CS, cpu_state.pc); return 0x70; } - else if (pc87306_curreg == 5) - { - // pclog("PC87306: Read value %02X at data register, index 05\n", pc87306_regs[pc87306_curreg] | 4); - return pc87306_regs[pc87306_curreg] | 4; - } else { // pclog("PC87306: Read value %02X at data register, index %02X\n", pc87306_regs[pc87306_curreg], pc87306_curreg); @@ -433,10 +427,11 @@ void pc87306_reset(void) pc87306_regs[0] = 0x4B; pc87306_regs[1] = 0x01; - pc87306_regs[3] = 2; - pc87306_regs[5] = 0xD; + pc87306_regs[3] = 0x01; + pc87306_regs[5] = 0x0D; pc87306_regs[8] = 0x70; - pc87306_regs[9] = 0xFF; + pc87306_regs[9] = 0xC0; + pc87306_regs[0xB] = 0x80; pc87306_regs[0xF] = 0x1E; pc87306_regs[0x12] = 0x30; pc87306_regs[0x19] = 0xEF; @@ -449,12 +444,13 @@ void pc87306_reset(void) fdc_update_densel_polarity(1); fdc_update_max_track(85); fdc_remove(); - fdc_add(0x3f0, 0); + fdc_set_base(0x3f0, 0); fdd_swap = 0; serial1_remove(); serial2_remove(); serial1_handler(); serial2_handler(); + pc87306_gpio_init(); } void pc87306_init() diff --git a/src/serial.c b/src/serial.c index e753aa1cf..da41b00f9 100644 --- a/src/serial.c +++ b/src/serial.c @@ -85,6 +85,7 @@ uint8_t serial_read_fifo(SERIAL *serial) void serial_write(uint16_t addr, uint8_t val, void *p) { SERIAL *serial = (SERIAL *)p; + // pclog("Serial: Write value %02X on port: %04X\n", val, addr); // pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr&7) { @@ -169,7 +170,7 @@ uint8_t serial_read(uint16_t addr, void *p) { SERIAL *serial = (SERIAL *)p; uint8_t temp = 0; -// pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins); + // pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, cpu_state.pc, mousedelay, ins); switch (addr&7) { case 0: @@ -228,6 +229,7 @@ uint8_t serial_read(uint16_t addr, void *p) break; } // pclog("%02X\n",temp); + // pclog("Serial: Read value %02X on port: %04X\n", temp, addr); return temp; } @@ -245,6 +247,9 @@ void serial_recieve_callback(void *p) } } +uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; +int serial_irq[2] = { 4, 3 }; + /*Tandy might need COM1 at 2f8*/ void serial1_init(uint16_t addr, int irq) { @@ -253,6 +258,8 @@ void serial1_init(uint16_t addr, int irq) serial1.irq = irq; serial1.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + serial_addr[0] = addr; + serial_irq[0] = irq; } void serial1_set(uint16_t addr, int irq) { @@ -260,18 +267,12 @@ void serial1_set(uint16_t addr, int irq) io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); serial1.irq = irq; // pclog("serial1_set(%04X, %02X)\n", addr, irq); + serial_addr[0] = addr; + serial_irq[0] = irq; } void serial1_remove() { - io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } void serial2_init(uint16_t addr, int irq) @@ -281,6 +282,8 @@ void serial2_init(uint16_t addr, int irq) serial2.irq = irq; serial2.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + serial_addr[1] = addr; + serial_irq[1] = irq; } void serial2_set(uint16_t addr, int irq) { @@ -288,16 +291,10 @@ void serial2_set(uint16_t addr, int irq) io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); serial2.irq = irq; // pclog("serial2_set(%04X, %02X)\n", addr, irq); + serial_addr[1] = addr; + serial_irq[1] = irq; } void serial2_remove() { - io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/sound_dbopl.cc b/src/sound_dbopl.cc index 13f87df44..8f7463357 100644 --- a/src/sound_dbopl.cc +++ b/src/sound_dbopl.cc @@ -84,18 +84,18 @@ void opl_timer_over(int nr, int timer) void opl_write(int nr, uint16_t addr, uint8_t val) { if (!(addr & 1)) - { - if (!opl[nr].is_opl3) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; - else - opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; - } + { + if (!opl[nr].is_opl3 || !opl3_type) + opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; + else + opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; + } else { - if (!opl[nr].is_opl3) - opl[nr].chip.WriteReg(opl[nr].addr, val); - else - OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); + if (!opl[nr].is_opl3 || !opl3_type) + opl[nr].chip.WriteReg(opl[nr].addr, val); + else + OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); switch (opl[nr].addr) { diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 172a6e17e..17a1f3dec 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -964,8 +964,8 @@ enum enum { - BLTCMD_SRC_TILED = (1 << 10), - BLTCMD_DST_TILED = (1 << 12) + BLTCMD_SRC_TILED = (1 << 14), + BLTCMD_DST_TILED = (1 << 15) }; #define TEXTUREMODE_MASK 0x3ffff000 @@ -1086,7 +1086,9 @@ static void voodoo_recalc(voodoo_t *voodoo) voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; if (voodoo->fbiInit6 & (1 << 30)) - voodoo->fbiInit1 += 1; + voodoo->block_width += 1; + if (voodoo->fbiInit1 & (1 << 24)) + voodoo->block_width += 32; voodoo->row_width = voodoo->block_width * 32 * 2; /* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); @@ -2714,7 +2716,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood goto next_line; state->fb_mem = fb_mem = &voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = &voodoo->fb_mem[params->aux_offset + (real_y * voodoo->row_width)]; + state->aux_mem = aux_mem = &voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; if (voodoo_output) pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2); @@ -3100,7 +3102,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_RGB_WMASK) fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) aux_mem[x] = new_depth; } } @@ -3769,6 +3771,7 @@ static void blit_start(voodoo_t *voodoo) { uint16_t src_dat = src[src_x]; uint16_t dst_dat = dst[dst_x]; + int rop = 0; if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { @@ -3776,8 +3779,31 @@ static void blit_start(voodoo_t *voodoo) dst_y < voodoo->bltClipLowY || dst_y > voodoo->bltClipHighY) goto skip_pixel_blit; } - - MIX(src_dat, dst_dat, voodoo->bltRop[3]); + + if (voodoo->bltCommand & BLIT_SRC_CHROMA) + { + int r = (src_dat >> 11); + int g = (src_dat >> 5) & 0x3f; + int b = src_dat & 0x1f; + + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && + g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && + b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) + { + int r = (dst_dat >> 11); + int g = (dst_dat >> 5) & 0x3f; + int b = dst_dat & 0x1f; + + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && + g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && + b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } + + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); dst[dst_x] = dst_dat; skip_pixel_blit: @@ -3855,7 +3881,7 @@ skip_pixel_fill: size_x = voodoo->bltSizeX & 0x1ff; } - dst = (uint64_t *)&voodoo->fb_mem[dst_y*512*8 + dst_x*8]; + dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; for (x = 0; x <= size_x; x++) dst[x] = dat64; @@ -4429,12 +4455,28 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_clipLeftRight: - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipRight = val & 0xfff; + voodoo->params.clipLeft = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipRight = val & 0x3ff; + voodoo->params.clipLeft = (val >> 16) & 0x3ff; + } break; case SST_clipLowYHighY: - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipHighY = val & 0xfff; + voodoo->params.clipLowY = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipHighY = val & 0x3ff; + voodoo->params.clipLowY = (val >> 16) & 0x3ff; + } break; case SST_nopCMD: @@ -6285,7 +6327,7 @@ static void fifo_thread(void *param) break; default: - fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); } end_time = timer_read(); diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 8d3cc7271..855830a78 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -434,7 +434,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0c); addbyte(0x82); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ addbyte(5+5+4+4); @@ -607,7 +607,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xe8); addbyte(0xd3); /*SHR EBX, CL*/ addbyte(0xeb); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0x85); /*TEST EAX, EAX*/ addbyte(0xc0); @@ -634,7 +634,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); } - if (state->clamp_t) + if (state->clamp_t[tmu]) { addbyte(0x85); /*TEST EBX, EBX*/ addbyte(0xdb); @@ -2980,7 +2980,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index d10f3bbcc..f0aba4a59 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -227,8 +227,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV ECX, [ECX+EAX*4]*/ addbyte(0x0c); addbyte(0x81); - addbyte(0xbd); /*MOV EBP, 1*/ - addlong(1); + addbyte(0xbd); /*MOV EBP, 8*/ + addlong(8); addbyte(0x28); /*SUB DL, CL*/ addbyte(0xca); addbyte(0xd3); /*SHL EBP, CL*/ @@ -236,9 +236,6 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0xc1); /*SHL EBP, 3*/ - addbyte(0xe5); - addbyte(3); addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); @@ -416,7 +413,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0c); addbyte(0x82); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ addbyte(5+5+4+4); @@ -2972,7 +2969,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); diff --git a/src/x86seg.c b/src/x86seg.c index a6db3f8ac..e19775b24 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2036,20 +2036,16 @@ void pmodeiret(int is32) addr=seg&~7; if (seg&4) { - if (addr>=ldt.limit) - { - // pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; + pclog("TS LDT %04X %04X IRET\n",seg,gdt.limit); + x86ts(NULL,seg&~3); + return; } else { if (addr>=gdt.limit) { // pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); - x86gpf(NULL,seg&~3); + x86ts(NULL,seg&~3); return; } addr+=gdt.base;