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>
