Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Oct 1996 16:42:24 +0600 (ESD)
From:      "Serge A. Babkin" <babkin@hq.icb.chel.su>
To:        hackers@freebsd.org, jkh@time.cdrom.com, wollman@freebsd.org, asami@freebsd.org
Subject:   Networking for PCEMU (2/2)
Message-ID:  <199610241042.QAA09211@hq.icb.chel.su>

next in thread | raw e-mail | index | archive | help
Part 2:
(patch for PCEMU)


*** README.NET	Thu Oct 24 19:36:17 1996
--- README.NET	Thu Oct 24 16:13:58 1996
***************
*** 0 ****
--- 1,40 ----
+ README.NET - guide for the FreeBSD PCEMU networking support
+ 
+ To get the network support you'll need to do:
+ 
+ 1. Install these networking patches for PCEMU
+ 
+ 2. Install the loe driver and run PSEMU as described in
+ /usr/share/FAQ/Text/loe.FAQ
+ 
+ Comments on internals.
+ 
+ The packet drivers is on interrupt 0x60. If you look at the
+ sources you can see that this interrupt is installed twice.
+ The first time is used just to install the piece of code
+ used in the callback when getting a packet from network. It
+ is:
+ 
+ 	callbios <nethandler_ret>
+ 	iret
+ 
+ The second installs the real interrupt handler. It is:
+ 
+ 	jmp short label
+ 	nop
+ 	db "PKT DRVR",0
+ 	db "FreeBSD Loopback Ethernet",0
+ 	callbios <nethandler>
+ 	<standard end-of-interrupt sequence>
+ 
+ The interrupt 0x61 is used to call the callback function. This
+ interrupt is generated at receiving a packet from the network.
+ It is just:
+ 
+ 	callbios <nethandler_call>
+ 
+ It never returns directly because the handler sets the return
+ address to the address of "callbios <nethandler_ret>" and
+ jumps to the callback function.
+ 
+ Serge A.Babkin <babkin@hq.icb.chel.su>
*** network.c	Thu Oct 24 19:36:17 1996
--- network.c	Thu Oct 24 15:43:56 1996
***************
*** 0 ****
--- 1,439 ----
+ /*
+  * Copyright (c) 1996
+  *	Serge A. Babkin.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  *
+  * Network support for PCEMU
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <sys/param.h>
+ #include <sys/socket.h>
+ #include <sys/sockio.h>
+ #include <net/if.h>
+ 
+ #include "global.h"
+ #include "network.h"
+ #include "cpu.h"
+ 
+ #undef NETDEBUG
+ 
+ #ifdef NETDEBUG
+ #	define DFPRINT(x)	fprintf x
+ #else
+ #	define DFPRINT(x)
+ #endif
+ 
+ static struct receivers {
+ 	unsigned short type;
+ 	short seg;
+ 	short off;
+ 	char inuse;
+ 	}
+ 	receivers[100];
+ 
+ int netretseg, netretoff;
+ 
+ int hasnet=0; /* flag: do we have a network interface ? */
+ int netfile; /* network interface file descriptor */
+ 
+ int network_pending=0;  /* interrupt request on line 0x61 */
+ 
+ static char pktbuf[2000];
+ static int pktlen=0;
+ static int netbufc= -1;
+ 
+ static struct ifreq ifr;
+ static char broadaddr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+ 
+ static WORD savewregs[8];
+ static unsigned savesregs[4];
+ 
+ void
+ netinit(fname)
+ 	char *fname;
+ {
+ 	int c;
+ 
+ 	if(( netfile=open(fname, O_RDWR) )<0) {
+ 		fprintf(stderr,"%s: ",progname);
+ 		perror("Unable to open network file");
+ 		exit(1);
+ 	}
+ 
+ 	if( fcntl(netfile, F_SETFL, O_NDELAY)<0 ) {
+ 		fprintf(stderr,"%s: ",progname);
+ 		perror("Unable to set nodelay mode");
+ 		exit(1);
+ 	}
+ 
+ 	if( ioctl(netfile, SIOCGIFADDR, &ifr)<0 ) {
+ 		fprintf(stderr,"%s: ",progname);
+ 		perror("Unable to get Ethernet address");
+ 		exit(1);
+ 	}
+ 	DFPRINT((stderr,"%s: Ethernet address %s\n", progname,
+ 		ether_ntoa(ifr.ifr_addr.sa_data) ));
+ 
+ 	for(c=0; c<100; c++)
+ 		receivers[c].inuse=0;
+ 
+ 	hasnet=1;
+ }
+ 
+ void
+ nethandler()
+ {
+ 	unsigned type;
+ 	int c;
+ 	register unsigned tmp, tmp1;
+ 
+ 
+ 	if(pktlen>0)
+ 		return;
+ 
+ nextpacket:
+ 
+ 	if(( pktlen=read(netfile,pktbuf,2000) )>0) {
+ 		type=*(unsigned short *)(pktbuf+12);
+ 
+ 		DFPRINT((stderr,"%s: got %d bytes from network, type=0x%X\n",
+ 			progname,pktlen,ntohs(type) ));
+ 
+ 		/* check if the packet is our own broadcast then drop it */
+ 		if(!memcmp(pktbuf+6, ifr.ifr_addr.sa_data,6)
+ 		&& !memcmp(pktbuf, broadaddr, 6) ) {
+ 			goto nextpacket;
+ 		}
+ 
+ 		if(ntohs(type)<=0x5EE) {
+ 			DFPRINT((stderr,"%s: 802.3 packet converted to IPX\n",progname));
+ 			type=htons(0xFFFF);
+ 			}
+ 
+ 		for(c=0; c<100 && (!receivers[c].inuse || receivers[c].type!=type); 
+ 			c++);
+ 
+ 		if(c>=100) {
+ 			DFPRINT((stderr,"%s: no handler for this type\n",progname));
+ 			goto nextpacket; /* no handler */
+ 			}
+ 
+ 		netbufc=c;
+ 
+ 		if(type==0xffff) { /* PDIPX don't understand the broadcast address */
+ 			DFPRINT((stderr,"%s: workaround for PDIPX\n",progname));
+ 			for(c=0; c<6; c++)
+ 				pktbuf[c]=ifr.ifr_addr.sa_data[c];
+ 		}
+ 
+ 		DFPRINT((stderr,"%s: set up network interrupt\n",progname));
+ 		network_pending=1;
+ 	}
+ 
+ 	if(pktlen<0 && errno!=EAGAIN) {
+ 		fprintf(stderr,"%s: ",progname);
+ 		perror("reading network");
+ 		fprintf(stderr,"%s: network disabled\n",progname);
+ 		hasnet=0;
+ 		close(netfile);
+ 	}
+ }
+ 
+ void 
+ nethandler_call()
+ {
+ 	unsigned type;
+ 	int tmp;
+ 	int c;
+ 
+ 	if(pktlen==0) {
+ 		fprintf(stderr,"%s: erroneous call of nethandler_call\n",progname);
+ 		exit(1);
+ 		return;
+ 	}
+ 
+ #if 0
+ 	DFPRINT((stderr,"%s: SS=0x%x SP=0x%x\n",progname,
+ 		sregs[CS],ChangeE(wregs[SP]) ));
+ 	DFPRINT((stderr,"%s: return address in stack 0x%x:0x%x\n",progname,
+ 		GetMemW(c_stack,ChangeE(wregs[SP])+2),
+ 		GetMemW(c_stack,ChangeE(wregs[SP])) ));
+ #endif
+ 
+ 	for(c=0; c<8; c++)
+ 		savewregs[c]=wregs[c];
+ 	for(c=0; c<4; c++)
+ 		savesregs[c]=sregs[c];
+ 
+ 	/* set up parameters */
+ 	wregs[BX]=netbufc;
+ 	wregs[AX]=0;
+ 	wregs[CX]=ChangeE(pktlen);
+ 
+ 	/* set up return adress */
+ 	tmp=(WORD)(ReadWord(&wregs[SP])-2);
+ 	PutMemW(c_stack,tmp, netretseg);
+ 	tmp-=2;
+ 	PutMemW(c_stack,tmp, ChangeE(netretoff));
+ 	WriteWord(&wregs[SP],tmp);
+ 
+ 	/* call receiver */
+ 	sregs[CS]=receivers[netbufc].seg;
+ 	c_cs=SegToMemPtr(CS);
+ 	ip=ChangeE(receivers[netbufc].off);
+ 
+ 	DFPRINT((stderr,"%s: called handler (1st)\n",progname));
+ 
+ 	PIC_EOI();
+ }
+ 
+ void 
+ nethandler_ret()
+ {
+ 	int seg,off;
+ 	int c;
+ 
+ 	if(pktlen==0) {
+ 		fprintf(stderr,"%s: erroneous call of nethandler_ret\n",progname);
+ 		exit(1);
+ 		return;
+ 	}
+ 
+ 	disable();
+ 
+ #if 0
+ 	DFPRINT((stderr,"%s: SS=0x%x SP=0x%x\n",progname,
+ 		sregs[CS],ChangeE(wregs[SP]) ));
+ 	DFPRINT((stderr,"%s: return address in stack 0x%x:0x%x\n",progname,
+ 		GetMemW(c_stack,ChangeE(wregs[SP])+2),
+ 		GetMemW(c_stack,ChangeE(wregs[SP])) ));
+ #endif
+ 
+ 	if(netbufc>=0) {  /* 1st return */
+ 		DFPRINT((stderr,"%s: handler returned (1st)\n",progname));
+ 		seg=sregs[ES] & 0xffff;
+ 		off=ChangeE(wregs[DI]) & 0xffff;
+ 
+ 		if(seg==0 && off==0) { /* throw packet */
+ 			pktlen=0;
+ 			netbufc= -1;
+ 			DFPRINT((stderr,"%s: handler requested to drop packet\n",progname));
+ 		} else {
+ 			register unsigned tmp, tmp1;
+ 
+ 			/* set up parameters */
+ 			memcpy(memory+(seg<<4)+off, pktbuf, pktlen);
+ 			sregs[DS]=sregs[ES];
+ 			c_ds=SegToMemPtr(DS);
+ 			wregs[SI]=wregs[DI];
+ 			wregs[BX]=netbufc;
+ 			wregs[AX]=ChangeE(1);
+ 			wregs[CX]=ChangeE(pktlen);
+ 
+ 			/* set up return adress */
+ 			tmp=(WORD)(ReadWord(&wregs[SP])-2);
+ 			PutMemW(c_stack,tmp, netretseg);
+ 			tmp-=2;
+ 			PutMemW(c_stack,tmp, ChangeE(netretoff));
+ 			WriteWord(&wregs[SP],tmp);
+ 
+ 			/* call receiver */
+ 			sregs[CS]=receivers[netbufc].seg;
+ 			c_cs=SegToMemPtr(CS);
+ 			ip=ChangeE(receivers[netbufc].off);
+ 
+ 			/* mark state */
+ 			netbufc= -1;
+ 			DFPRINT((stderr,"%s: called handler (2nd)\n",progname));
+ 		}
+ 	} else {
+ 		pktlen=0;
+ 
+ 		DFPRINT((stderr,"%s: handler returned (2nd)\n",progname));
+ 
+ 		for(c=0; c<8; c++)
+ 			wregs[c]=savewregs[c];
+ 		for(c=0; c<4; c++)
+ 			sregs[c]=savesregs[c];
+ 
+ 		c_cs = SegToMemPtr(CS);
+ 		c_ds = SegToMemPtr(DS);
+ 		c_es = SegToMemPtr(ES);
+ 		c_stack = c_ss = SegToMemPtr(SS);
+ 	}
+ 
+ 	enable();
+ }
+ 
+ void
+ int_pktdrv()
+ {
+ 	int error;
+ 	int c;
+ 	int type;
+ 	char wribuf[2000];
+ 	unsigned wrilen;
+ 
+ 	if(!hasnet) {
+ 		CF=1;
+ 		*bregs[DH]=PKT_BAD_COMMAND;
+ 		DFPRINT((stderr,"%s: no network, packet driver disabled\n",progname));
+ 		return;
+ 	}
+ 
+ 	DFPRINT((stderr,"%s: packet driver called (%d)\n",progname,*bregs[AH]));
+ 	switch(*bregs[AH]) {
+ 	case 1: /* driver_info */
+ 		if(*bregs[AL]!=255) {
+ 			CF=1;
+ 			*bregs[DH]=PKT_BAD_COMMAND;
+ 			DFPRINT((stderr,"%s: bad command AL=0x%x\n",progname,*bregs[AL]));
+ 		} else {
+ 			CF=0;
+ 			wregs[BX]=ChangeE(1);  /* version */
+ 			*bregs[CH]=1; /* class */
+ 			wregs[DX]=1; /* type */
+ 			*bregs[CL]=1; /* number */
+ 			sregs[DS]=sregs[CS];  /* name */
+ 			c_ds=SegToMemPtr(DS);
+ 			*bregs[SI]=ChangeE( ip - (6+26) );
+ 			*bregs[AL]=1; /* functionality */
+ 		}
+ 		break;
+ 	case 2:/* access_type */
+ 		error=0;
+ 		if(*bregs[AL]!=1 && *bregs[AL]!=11) { /* EthII or 802.3 */
+ 			error=PKT_NO_CLASS;
+ 			DFPRINT((stderr,"%s: no class 0x%x\n",progname,*bregs[AL]));
+ 		}
+ #if 0
+ 		if(wregs[BX]!=0 && wregs[BX]!=0xffff) {
+ 			error=PKT_NO_TYPE;
+ 			DFPRINT((stderr,"%s: no type 0x%x\n",progname,ChangeE(wregs[BX]) ));
+ 		}
+ 		if(*bregs[DL]!=0) {
+ 			error=PKT_NO_NUMBER;
+ 			DFPRINT((stderr,"%s: no card 0x%x\n",progname,*bregs[DL]));
+ 		}
+ #endif
+ 		if(wregs[CX]!=ChangeE(2)) { /* only 2-byte EtherII types */
+ 			error=PKT_BAD_TYPE;
+ 			DFPRINT((stderr,"%s: %d-byte address is wrong\n",progname,
+ 				ChangeE(wregs[CX]) ));
+ 		}
+ 
+ 		type=GetMemW(c_ds,ChangeE(wregs[SI]));
+ 		for(c=0; c<100 && !error; c++)
+ 			if(receivers[c].inuse && receivers[c].type==type) {
+ 				error=PKT_TYPE_INUSE;
+ 				DFPRINT((stderr,"%s: type 0x%x is already in use\n",
+ 					progname,ntohs(type) ));
+ 			}
+ 
+ 		if(!error) {
+ 			for(c=0; c<100 && receivers[c].inuse; c++);
+ 			if(c>=100) {
+ 				error=PKT_NO_SPACE;
+ 				DFPRINT((stderr,"%s: no space\n", progname));
+ 			}
+ 		}
+ 
+ 		if(error) {
+ 			CF=1;
+ 			*bregs[DH]=error;
+ 			break;
+ 		}
+ 
+ 		receivers[c].inuse=1;
+ 		receivers[c].type=type;
+ 		receivers[c].seg=sregs[ES];
+ 		receivers[c].off=wregs[DI];
+ 
+ 		wregs[AX]=c;
+ 		CF=0;
+ 		DFPRINT((stderr,"%s: successfully bound type 0x%x\n",
+ 			progname,ntohs(type) ));
+ 		break;
+ 	case 3: /* release_type */
+ 		c=wregs[BX];
+ 		if(c<100 && c>=0 && receivers[c].inuse) {
+ 			receivers[c].inuse=0;
+ 			CF=0;
+ 			DFPRINT((stderr,"%s: successfully released type 0x%x\n",
+ 				progname,ntohs(receivers[c].type)));
+ 		} else {
+ 			CF=1;
+ 			*bregs[DH]=PKT_BAD_HANDLE;
+ 			DFPRINT((stderr,"%s: bad handle %d\n",progname,c));
+ 		}
+ 		break;
+ 	case 4: /* send_pkt */
+ 		wrilen=ChangeE(wregs[CX]);
+ 		if(wrilen>1518 || wrilen<14) { /* packet has wrong size for Ethernet */
+ 			CF=1;
+ 			*bregs[DH]=PKT_CANT_SEND;
+ 			DFPRINT((stderr,"%s: packet size is wrong: %d bytes \n",
+ 				progname,wrilen));
+ 		}
+ 		type=GetMemW(c_ds, ChangeE(wregs[SI]+12));
+ 		if(type==0) {
+ 			PutMemW(c_ds, ChangeE(wregs[SI])+12, htons(wrilen-14) );
+ 			DFPRINT((stderr,"%s: sending packet of type 0, converted to IPX \n",
+ 				progname));
+ 		}
+ 		memcpy(wribuf, c_ds+ChangeE(wregs[SI]), wrilen);
+ 		if( write(netfile, wribuf, wrilen)<0 ) {
+ 			fprintf(stderr,"%s: ",progname);
+ 			perror("Cant' write to network");
+ 			CF=1;
+ 			*bregs[DH]=PKT_CANT_SEND;
+ 		} else {
+ 			CF=0;
+ 			DFPRINT((stderr,"%s: send packet of %d bytes \n",
+ 				progname,wrilen));
+ 		}
+ 		break;
+ 	case 5: /* terminate */
+ 		CF=1;
+ 		*bregs[DH]=PKT_CANT_TERMINATE;
+ 		DFPRINT((stderr,"%s: can't terminate\n",progname));
+ 		break;
+ 	case 6: /* get_address */
+ 		if(ChangeE(wregs[CX])<6) {
+ 			CF=1;
+ 			*bregs[DH]=PKT_NO_SPACE;
+ 			DFPRINT((stderr,"%s: address needs more than %d bytes\n",
+ 				progname, ChangeE(wregs[CX]) ));
+ 		} else {
+ 			memcpy(c_es+ChangeE(wregs[DI]), ifr.ifr_addr.sa_data, 6);
+ 			wregs[CX]=ChangeE(6);
+ 			CF=0;
+ 			DFPRINT((stderr,"%s: successfully got address\n",progname));
+ 		}
+ 		break;
+ 	case 7: /* reset_interface */
+ 		CF=1;
+ 		*bregs[DH]=PKT_CANT_RESET;
+ 		break;
+ 	default:
+ 		CF=1;
+ 		*bregs[DH]=PKT_BAD_COMMAND;
+ 		DFPRINT((stderr,"%s: bad command\n",progname));
+ 		break;
+ 	}
+ }
*** network.h	Thu Oct 24 19:36:17 1996
--- network.h	Thu Oct 24 15:43:33 1996
***************
*** 0 ****
--- 1,49 ----
+ /*
+  * Copyright (c) 1996
+  *	Serge A. Babkin.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  *
+  * Network support for PCEMU
+  *
+  */
+ 
+ extern int hasnet; /* flag: do we have a network interface ? */
+ extern int netfile; /* network interface file descriptor */
+ 
+ extern int netretseg, netretoff; /* address of network return routine */
+ 
+ extern int network_pending;  /* intrrupt request on line 0x61 */
+ 
+ /* packet driver error codes */
+ 
+ #define PKT_BAD_HANDLE	1
+ #define PKT_NO_CLASS	2
+ #define PKT_NO_TYPE	3
+ #define PKT_NO_NUMBER	4
+ #define PKT_BAD_TYPE	5
+ #define PKT_NO_MULTICAST	6
+ #define PKT_CANT_TERMINATE	7
+ #define PKT_BAD_MODE	8
+ #define PKT_NO_SPACE	9
+ #define PKT_TYPE_INUSE	10
+ #define PKT_BAD_COMMAND	11
+ #define PKT_CANT_SEND	12
+ #define PKT_CANT_SET	13
+ #define PKT_BAD_ADDRESS	14
+ #define PKT_CANT_RESET	15
+ 
+ 
+ void netinit(char *fname);
+ void nethandler(void);
+ void nethandler_call(void);
+ void nethandler_ret(void);
+ void int_pktdrv(void);
*** Makefile	Tue Oct 22 16:26:57 1996
--- Makefile	Tue Oct 22 14:16:19 1996
***************
*** 66,87 ****
  LFLAGS  = -L$(XROOT)/lib
  LIBRARIES = -lXext -lX11
  OFILES  = main.o cpu.o bios.o vga.o vgahard.o debugger.o xstuff.o \
!           hardware.o mfs.o
  PROGNAME    = pcemu
  GLOBAL_DEP  = Makefile global.h mytypes.h
  
  all: $(PROGNAME)
  
  cpu.o:	$(GLOBAL_DEP) cpu.h instr.h debugger.h hardware.h
! main.o: $(GLOBAL_DEP) bios.h xstuff.h hardware.h
  bios.o: $(GLOBAL_DEP) bios.h cpu.h vga.h vgahard.h debugger.h hardware.h \
!         keytabs.h mfs_link.h
  vga.o:	$(GLOBAL_DEP) bios.h cpu.h vga.h vgahard.h hardware.h
  vgahard.o: $(GLOBAL_DEP) vgahard.h xstuff.h hardware.h
  debugger.o: $(GLOBAL_DEP) cpu.h debugger.h disasm.h vgahard.h
  xstuff.o: $(GLOBAL_DEP) vgahard.h xstuff.h icon.h hardware.h
! hardware.o: $(GLOBAL_DEP) cpu.h vgahard.h debugger.h hardware.h
  mfs.o: $(GLOBAL_DEP) cpu.h mfs.h mfs_link.h
  
  .c.o:
  	$(CC) $(CFLAGS) $(OPTIONS) -c $<
--- 66,88 ----
  LFLAGS  = -L$(XROOT)/lib
  LIBRARIES = -lXext -lX11
  OFILES  = main.o cpu.o bios.o vga.o vgahard.o debugger.o xstuff.o \
!           hardware.o mfs.o network.o
  PROGNAME    = pcemu
  GLOBAL_DEP  = Makefile global.h mytypes.h
  
  all: $(PROGNAME)
  
  cpu.o:	$(GLOBAL_DEP) cpu.h instr.h debugger.h hardware.h
! main.o: $(GLOBAL_DEP) bios.h xstuff.h hardware.h network.h
  bios.o: $(GLOBAL_DEP) bios.h cpu.h vga.h vgahard.h debugger.h hardware.h \
!         keytabs.h mfs_link.h network.h
  vga.o:	$(GLOBAL_DEP) bios.h cpu.h vga.h vgahard.h hardware.h
  vgahard.o: $(GLOBAL_DEP) vgahard.h xstuff.h hardware.h
  debugger.o: $(GLOBAL_DEP) cpu.h debugger.h disasm.h vgahard.h
  xstuff.o: $(GLOBAL_DEP) vgahard.h xstuff.h icon.h hardware.h
! hardware.o: $(GLOBAL_DEP) cpu.h vgahard.h debugger.h hardware.h network.h
  mfs.o: $(GLOBAL_DEP) cpu.h mfs.h mfs_link.h
+ network.o:	$(GLOBAL_DEP) network.h
  
  .c.o:
  	$(CC) $(CFLAGS) $(OPTIONS) -c $<
*** bios.c	Fri Jun 24 17:39:47 1994
--- bios.c	Tue Oct 22 14:38:23 1996
***************
*** 30,35 ****
--- 30,36 ----
  #include "debugger.h"
  #include "vgahard.h"
  #include "hardware.h"
+ #include "network.h"
  
  #define BIOS
  
***************
*** 1114,1119 ****
--- 1115,1131 ----
      {
          0x06,0x57,0x50,0xb8,0x0c,0x12,0xcd,0x2f,0x58,0x5f,0x07,0xcf
      };
+ 	static BYTE pktdrvret[] =
+ 	{
+ 		0xcf
+ 	};
+ 	static BYTE pktdrvcode[] =
+ 	{
+ 		0xeb,0x24,0x90,0x50,0x4b,0x54,0x20,0x44,0x52,0x56,0x52,0x00,
+ 		0x46,0x72,0x65,0x65,0x42,0x53,0x44,0x20,0x4c,0x6f,0x6f,0x70,
+ 		0x62,0x61,0x63,0x6b,0x20,0x45,0x74,0x68,0x65,0x72,0x6e,0x65,
+ 		0x74,0x00
+ 	};
  
      unsigned equip = 0;
      int i;
***************
*** 1173,1178 ****
--- 1185,1197 ----
      set_int(0x18, NULL, 0, int_basic, afterint, sizeof afterint);
      set_int(0x19, NULL, 0, int_reboot, afterint, sizeof afterint);
      set_int(0x1a, NULL, 0, int_time, afterint, sizeof afterint);
+ 
+ 	netretseg=0xf000;
+ 	netretoff=pos;
+     set_int(0x60, NULL, 0, nethandler_ret, pktdrvret, sizeof pktdrvret);
+     set_int(0x60, pktdrvcode, sizeof pktdrvcode, int_pktdrv,
+ 		afterint, sizeof afterint);
+     set_int(0x61, NULL, 0, nethandler_call, NULL, 0);
  
      set_int(0xe6, NULL, 0, int_e6, afterint, sizeof afterint);
      set_int(0xe7, inte7code, sizeof inte7code, NULL, NULL, 0);
*** hardware.c	Wed Jun 22 20:24:50 1994
--- hardware.c	Tue Oct 22 14:03:50 1996
***************
*** 23,28 ****
--- 23,29 ----
  #include "hardware.h"
  #include "cpu.h"
  #include "vgahard.h"
+ #include "network.h"
  
  #ifdef DEBUGGER
  #    include "debugger.h"
***************
*** 81,86 ****
--- 82,99 ----
              int_blocked = 9;
          }
      }
+ 	else if (network_pending)
+ 	{
+         PIC_inservice = PIC_NETWORK;
+ 		network_pending=0;
+         if (IF)
+             int_pending = 0x61;
+         else
+         {
+             D2(printf("INTR blocked: IF disabled\n"););
+             int_blocked = 0x61;
+         }
+ 	}
  }
  
  
***************
*** 209,214 ****
--- 222,230 ----
          PIC_flagint(PIC_TIMER);
          int8_counter = TIMER_MULT;
      }
+ 
+ 	if(hasnet)
+ 		nethandler();
  
      PIC_interrupt();
  
*** main.c	Tue Oct 22 16:26:55 1996
--- main.c	Sun Oct 20 20:14:40 1996
***************
*** 27,32 ****
--- 27,33 ----
  #include "xstuff.h"
  #include "hardware.h"
  #include "vgahard.h"
+ #include "network.h"
  
  BYTE *memory;
  char *progname;
***************
*** 112,120 ****
  
  void main(int argc, char **argv)
  {
      progname = (progname = strrchr(argv[0],'/')) ? progname : argv[0];
  
! #ifndef BOOT    
      FILE *f1;
      if (argc != 2)
      {
--- 113,136 ----
  
  void main(int argc, char **argv)
  {
+ 	int opt;
+ 
      progname = (progname = strrchr(argv[0],'/')) ? progname : argv[0];
  
! #ifdef BOOT    
! 	while(( opt=getopt(argc,argv,"n:") )!=EOF) {
! 		switch(opt) {
! 		case 'n':
! 			netinit(optarg);
! 			break;
! 		default:
! 			fprintf(stderr,"Usage:\n   %s [-n network-file]\n",progname);
! 			exit(1);
! 		}
! 	}
! 	argc-=optind;
! 	argv+=optind;
! #else
      FILE *f1;
      if (argc != 2)
      {
*** hardware.h	Wed Jun 22 20:24:50 1994
--- hardware.h	Tue Oct 22 14:01:01 1996
***************
*** 19,24 ****
--- 19,25 ----
  
  #define PIC_TIMER    1
  #define PIC_KEYBOARD 2
+ #define PIC_NETWORK	4
  
  #define TICKSPERSEC (1193180.0/65536.0)
  



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610241042.QAA09211>