// I_pcnet.m #include #include "DoomDef.h" /* ============================================================================= IPX PACKET DRIVER ============================================================================= */ #define DPMI_INT 0x31 typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long LONG; typedef struct IPXPacketStructure { WORD PacketCheckSum; /* high-low */ WORD PacketLength; /* high-low */ BYTE PacketTransportControl; BYTE PacketType; BYTE dNetwork[4]; /* high-low */ BYTE dNode[6]; /* high-low */ BYTE dSocket[2]; /* high-low */ BYTE sNetwork[4]; /* high-low */ BYTE sNode[6]; /* high-low */ BYTE sSocket[2]; /* high-low */ } IPXPacket; typedef struct { BYTE network[4]; /* high-low */ BYTE node[6]; /* high-low */ } localadr_t; typedef struct ECBStructure { WORD Link[2]; /* offset-segment */ WORD ESRAddress[2]; /* offset-segment */ BYTE InUseFlag; BYTE CompletionCode; WORD ECBSocket; /* high-low */ BYTE IPXWorkspace[4]; /* N/A */ BYTE DriverWorkspace[12]; /* N/A */ BYTE ImmediateAddress[6]; /* high-low */ WORD FragmentCount; /* low-high */ // struct ECBFragment FragmentDescriptor[1]; WORD fAddress[2]; /* offset-segment */ WORD fSize; /* low-high */ } ECB; typedef struct { unsigned edi, esi, ebp, reserved, ebx, edx, ecx, eax; unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss; } dpmiregs_t; extern dpmiregs_t dpmiregs; int socketid = 0x869c; // broadcast socket number typedef struct { ECB ecb; IPXPacket ipx; netstruc_t data; int checksum; } packet_t; #define NUMPACKETS 10 packet_t *packets; // [NUMPACKETS] extern union REGS regs; // scratch for int calls extern struct SREGS segregs; unsigned enteripx[2]; #define REAL_OFF(x) ((unsigned)(x)&15) #define REAL_SEG(x) ((unsigned)(x)>>4) int localnetid, remotenetid; localadr_t *localipxadr; void DPMIInt (int i); //=========================================================================== int OpenSocket(short socketNumber) { regs.w.bx = 0; regs.h.al = 0; // longevity regs.w.dx = socketNumber; int386(0x7A,®s,®s); if (regs.h.al) I_Error ("OpenSocket: 0x%x",regs.h.al); return regs.w.dx; } void ListenForPacket(ECB *ecb) { memset (&dpmiregs,0,sizeof(dpmiregs)); dpmiregs.esi = REAL_OFF(ecb); dpmiregs.es = REAL_SEG(ecb); dpmiregs.ebx = 4; dpmiregs.ip = enteripx[0]; dpmiregs.cs = enteripx[1]; //printf ("listen\n"); DPMIInt (0x7a); //printf ("done\n"); if (dpmiregs.eax & 0xff) I_Error ("ListenForPacket: 0x%x",dpmiregs.eax&0xff); } void GetLocalAddress (void) { // // allocate dos memory for info // localipxadr = (localadr_t *)I_AllocLow (sizeof(localadr_t)); // // get the address from ipx // memset (&dpmiregs,0,sizeof(dpmiregs)); dpmiregs.esi = REAL_OFF(localipxadr); dpmiregs.es = REAL_SEG(localipxadr); dpmiregs.ebx = 9; dpmiregs.ip = enteripx[0]; dpmiregs.cs = enteripx[1]; DPMIInt (0x7a); if (dpmiregs.eax & 0xff) I_Error ("Get inet addr: 0x%x",dpmiregs.eax&0xff); localnetid = *(int *)localipxadr->node; localnetid ^= *(int *)&localipxadr->node[2]; printf ("localnetid: 0x%x\n",localnetid); } /* ==================== = = I_ShutdownNet = ==================== */ void I_ShutdownNet (void) { } /* ==================== = = I_InitNetwork = ==================== */ void I_InitNetwork (void) { int i,j; int socketnum; // // get IPX function address // memset(&dpmiregs,0,sizeof(dpmiregs)); dpmiregs.eax = 0x7a00; DPMIInt (0x2f); if ( (dpmiregs.eax&0xff) != 0xff) I_Error ("IPX not detected\n"); enteripx[0] = (dpmiregs.edi)&0xffff; enteripx[1] = dpmiregs.es; // printf ("ipxcall: 0x%x:0x%x\n",enteripx[1],enteripx[0]); // // allocate dos memory for packets // packets = (packet_t *)I_AllocLow (NUMPACKETS*sizeof(packet_t)); // // allocate a socket for sending and receiving // i = M_CheckParm ("-port"); if (i>0 && i>8) + ((socketid&255)<<8) ); // printf ("socketnum: 0x%x\n",socketnum); GetLocalAddress (); // // set up a receiving ECB // memset (packets,0,NUMPACKETS*sizeof(packet_t)); for (i=1 ; i>8; // // sync // //SendPacket (); // NetSync (); //getchar(); } /* ============== = = SendPacket = ============== */ void SendPacket (void) { int j, checksum; //printf ("send\n"); while (packets[0].ecb.InUseFlag) { //printf ("Send: inuse: 0x%x\n",packets[0].ecb.InUseFlag); } //printf ("not in use\n"); // put the data into an ipx packet memcpy (&packets[0].data, &netbuffer, sizeof(netbuffer)); checksum = 0; for (j=0 ; j