1177 lines
31 KiB
C
1177 lines
31 KiB
C
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||
|
// See the included license file "BUILDLIC.TXT" for license info.
|
||
|
// This file has been modified from Ken Silverman's original release
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "platform.h"
|
||
|
|
||
|
extern long getcrc(char *buffer, short bufleng);
|
||
|
extern void processreservedmessage(short tempbufleng, char *datempbuf);
|
||
|
extern void initcrc(void);
|
||
|
extern int comon(void);
|
||
|
extern void comoff(void);
|
||
|
extern int neton(void);
|
||
|
extern void netoff(void);
|
||
|
extern void startcom(void);
|
||
|
extern int netinitconnection (long newconnectnum, char *newcompaddr);
|
||
|
extern void installbicomhandlers(void);
|
||
|
extern void uninstallbicomhandlers(void);
|
||
|
|
||
|
#define COMBUFSIZ 16384
|
||
|
#define COMCODEBYTES 384
|
||
|
#define COMCODEOFFS 14
|
||
|
#define NETCODEBYTES 384
|
||
|
#define MAXPLAYERS 16
|
||
|
#define ESC1 0x83
|
||
|
#define ESC2 0x8f
|
||
|
#define NETBACKPACKETS 4
|
||
|
#define MAXIPXSIZ 546
|
||
|
|
||
|
#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat])
|
||
|
|
||
|
char syncstate = 0, hangup = 1;
|
||
|
static char multioption = 0, comrateoption = 0;
|
||
|
|
||
|
//COM & NET variables
|
||
|
short numplayers = 0, myconnectindex = 0;
|
||
|
short connecthead, connectpoint2[MAXPLAYERS];
|
||
|
char syncbuf[MAXIPXSIZ];
|
||
|
long syncbufleng, outbufindex[128], outcnt;
|
||
|
long myconnectnum, otherconnectnum, mypriority;
|
||
|
long crctable[256];
|
||
|
|
||
|
//COM ONLY variables
|
||
|
long comnum, comvect, comspeed, comtemp, comi, comescape, comreset;
|
||
|
#ifdef PLATFORM_DOS // !!! this is a real mess. --ryan.
|
||
|
static void interrupt far comhandler(void);
|
||
|
static unsigned short orig_pm_sel, orig_rm_seg, orig_rm_off;
|
||
|
static unsigned long orig_pm_off;
|
||
|
#endif
|
||
|
volatile unsigned char *inbuf, *outbuf, *comerror, *incnt, *comtype;
|
||
|
volatile unsigned char *comresend;
|
||
|
volatile short *inbufplc, *inbufend, *outbufplc, *outbufend, *comport;
|
||
|
#ifdef PLATFORM_DOS // !!! this is a real mess. --ryan.
|
||
|
static char rmbuffer[COMCODEBYTES] = //See realcom.asm
|
||
|
{
|
||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
|
0x00,0x00,0x00,0x00,0x50,0x53,0x66,0x51,0x52,0x2e,
|
||
|
0x8b,0x16,0x08,0x00,0x83,0xc2,0x02,0xec,0x24,0x07,
|
||
|
0x8a,0xe0,0x80,0xfc,0x02,0x74,0x08,0x80,0xfc,0x04,
|
||
|
0x74,0x62,0xe9,0x89,0x00,0x2e,0x8b,0x16,0x08,0x00,
|
||
|
0x2e,0x8a,0x0e,0x0a,0x00,0x80,0xe9,0x01,0x78,0x7a,
|
||
|
0x2e,0x80,0x3e,0x0c,0x00,0x01,0x7c,0x10,0x74,0x04,
|
||
|
0xb0,0x83,0xeb,0x02,0xb0,0x8f,0xee,0x2e,0xfe,0x0e,
|
||
|
0x0c,0x00,0xeb,0xe3,0x2e,0x80,0x3e,0x0b,0x00,0x01,
|
||
|
0x7c,0x12,0x74,0x04,0xb0,0x83,0xeb,0x04,0x2e,0xa0,
|
||
|
0x0d,0x00,0xee,0x2e,0xfe,0x0e,0x0b,0x00,0xeb,0xc9,
|
||
|
0x2e,0x8b,0x1e,0x04,0x00,0x2e,0x3b,0x1e,0x06,0x00,
|
||
|
0x74,0x3c,0x2e,0x8a,0x87,0x80,0x41,0xee,0x43,0x81,
|
||
|
0xe3,0xff,0x3f,0x2e,0x89,0x1e,0x04,0x00,0xeb,0xab,
|
||
|
0x2e,0x8b,0x16,0x08,0x00,0xec,0x2e,0x8b,0x1e,0x02,
|
||
|
0x00,0x2e,0x88,0x87,0x80,0x01,0x43,0x81,0xe3,0xff,
|
||
|
0x3f,0x2e,0x89,0x1e,0x02,0x00,0x2e,0x80,0x3e,0x0a,
|
||
|
0x00,0x10,0x75,0x08,0x83,0xc2,0x05,0xec,0xa8,0x01,
|
||
|
0x75,0xd6,0xf6,0xc4,0x01,0x0f,0x84,0x56,0xff,0xb0,
|
||
|
0x20,0xe6,0x20,0x5a,0x66,0x59,0x5b,0x58,0xcf,
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
//NET ONLY variables
|
||
|
short socket = 0x4949;
|
||
|
char compaddr[MAXPLAYERS][12], mycompaddr[12];
|
||
|
char netincnt[MAXPLAYERS], netoutcnt[MAXPLAYERS];
|
||
|
char getmess[MAXIPXSIZ];
|
||
|
char omessout[MAXPLAYERS][NETBACKPACKETS][MAXIPXSIZ];
|
||
|
short omessleng[MAXPLAYERS][NETBACKPACKETS];
|
||
|
short omessconnectindex[MAXPLAYERS][NETBACKPACKETS];
|
||
|
short omessnum[MAXPLAYERS];
|
||
|
long connectnum[MAXPLAYERS], rmoffset32, rmsegment16, neti;
|
||
|
volatile char *ecbget, *ecbput, *ipxin, *ipxout, *messin, *messout;
|
||
|
volatile char *tempinbuf, *tempoutbuf, *rmnethandler, *netinbuf;
|
||
|
volatile short *netinbufplc, *netinbufend;
|
||
|
static char rmnetbuffer[NETCODEBYTES] =
|
||
|
{
|
||
|
0xfb,0x2e,0x8a,0x26,0x62,0x00,0x2e,0xa0,0x63,0x00,
|
||
|
0x83,0xe8,0x1e,0x2e,0x8b,0x1e,0xe2,0x06,0x2e,0x88,
|
||
|
0x87,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x2e,0x88,
|
||
|
0xa7,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x33,0xf6,
|
||
|
0x2e,0x8a,0x8c,0xa0,0x00,0x46,0x2e,0x88,0x8f,0xe4,
|
||
|
0x06,0x43,0x81,0xe3,0xff,0x3f,0x3b,0xf0,0x72,0xec,
|
||
|
0x2e,0x89,0x1e,0xe2,0x06,0xbb,0x04,0x00,0x8c,0xc8,
|
||
|
0x8e,0xc0,0xbe,0x00,0x00,0xcd,0x7a,0xcb,
|
||
|
};
|
||
|
static long my7a = 0;
|
||
|
|
||
|
#ifdef PLATFORM_DOS
|
||
|
#pragma aux koutp =\
|
||
|
"out dx, al",\
|
||
|
parm [edx][eax]\
|
||
|
|
||
|
#pragma aux kinp =\
|
||
|
"in al, dx",\
|
||
|
parm [edx]
|
||
|
#endif
|
||
|
|
||
|
long convalloc32 (long size)
|
||
|
{
|
||
|
#ifdef PLATFORM_DOS
|
||
|
union REGS r;
|
||
|
|
||
|
r.x.eax = 0x0100; //DPMI allocate DOS memory
|
||
|
r.x.ebx = ((size+15)>>4); //Number of paragraphs requested
|
||
|
int386(0x31,&r,&r);
|
||
|
|
||
|
if (r.x.cflag != 0) return ((long)0); //Failed
|
||
|
return ((long)((r.x.eax&0xffff)<<4)); //Returns full 32-bit offset
|
||
|
#else
|
||
|
fprintf (stderr, "%s, line %d; convalloc32() called\n", __FILE__,
|
||
|
__LINE__);
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef PLATFORM_DOS
|
||
|
#pragma aux fixregistersaftersimulate =\
|
||
|
"cld",\
|
||
|
"push ds",\
|
||
|
"pop es",\
|
||
|
|
||
|
static struct rminfo
|
||
|
{
|
||
|
long EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX;
|
||
|
short flags, ES, DS, FS, GS, IP, CS, SP, SS;
|
||
|
} RMI;
|
||
|
#endif
|
||
|
|
||
|
long simulateint(char intnum, long daeax, long daebx, long daecx, long daedx, long daesi, long daedi)
|
||
|
{
|
||
|
#ifdef PLATFORM_DOS
|
||
|
union REGS regs;
|
||
|
struct SREGS sregs;
|
||
|
|
||
|
memset(&RMI,0,sizeof(RMI)); // Set up real-mode call structure
|
||
|
memset(&sregs,0,sizeof(sregs));
|
||
|
|
||
|
RMI.EAX = daeax;
|
||
|
RMI.EBX = daebx;
|
||
|
RMI.ECX = daecx;
|
||
|
RMI.EDX = daedx;
|
||
|
RMI.ESI = daesi-rmoffset32;
|
||
|
RMI.EDI = daedi-rmoffset32;
|
||
|
RMI.DS = rmsegment16;
|
||
|
RMI.ES = rmsegment16;
|
||
|
|
||
|
regs.w.ax = 0x0300; // Use DMPI call 300h to issue the DOS interrupt
|
||
|
regs.h.bl = intnum;
|
||
|
regs.h.bh = 0;
|
||
|
regs.w.cx = 0;
|
||
|
sregs.es = FP_SEG(&RMI);
|
||
|
regs.x.edi = FP_OFF(&RMI);
|
||
|
int386x(0x31,®s,®s,&sregs);
|
||
|
|
||
|
fixregistersaftersimulate();
|
||
|
|
||
|
return(RMI.EAX);
|
||
|
#else
|
||
|
fprintf(stderr, "%s line %d; simulateint() called\n",__FILE__,__LINE__);
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void initmultiplayers(char damultioption, char dacomrateoption, char dapriority)
|
||
|
{
|
||
|
long i;
|
||
|
|
||
|
multioption = damultioption;
|
||
|
comrateoption = dacomrateoption;
|
||
|
|
||
|
connecthead = 0;
|
||
|
for(i=MAXPLAYERS-1;i>=0;i--)
|
||
|
connectpoint2[i] = -1, connectnum[i] = 0x7fffffff;
|
||
|
|
||
|
mypriority = dapriority;
|
||
|
|
||
|
initcrc();
|
||
|
|
||
|
if ((multioption >= 1) && (multioption <= 4))
|
||
|
{
|
||
|
comnum = multioption;
|
||
|
switch(dacomrateoption&15)
|
||
|
{
|
||
|
case 0: comspeed = 2400; break;
|
||
|
case 1: comspeed = 4800; break;
|
||
|
case 2: comspeed = 9600; break;
|
||
|
case 3: comspeed = 14400; break;
|
||
|
case 4: comspeed = 19200; break;
|
||
|
case 5: comspeed = 28800; break;
|
||
|
}
|
||
|
comon();
|
||
|
}
|
||
|
if (multioption >= 5)
|
||
|
{
|
||
|
if ((i = neton()) != 0)
|
||
|
{
|
||
|
if (i == -1) printf("IPX driver not found\n");
|
||
|
if (i == -2) printf("Socket could not be opened\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
numplayers = 1;
|
||
|
}
|
||
|
|
||
|
void uninitmultiplayers()
|
||
|
{
|
||
|
if (numplayers > 0)
|
||
|
{
|
||
|
if ((multioption >= 1) && (multioption <= 4)) comoff();
|
||
|
if (multioption >= 5) netoff(); //Uninstall before timer
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int neton(void)
|
||
|
{
|
||
|
long i, j;
|
||
|
|
||
|
if ((simulateint(0x2f,(long)0x7a00,0L,0L,0L,0L,0L)&255) != 255) return(-1);
|
||
|
if (*(long *)(0x7a<<2) == 0)
|
||
|
{
|
||
|
#ifdef PLATFORM_DOS
|
||
|
printf("Faking int 0x7a to call IPX entry at: %4x:%4x\n",RMI.ES,RMI.EDI&65535);
|
||
|
my7a = convalloc32(16L);
|
||
|
*(short *)((0x7a<<2)+0) = (my7a&15);
|
||
|
*(short *)((0x7a<<2)+2) = (my7a>>4);
|
||
|
|
||
|
*(char *)(my7a+0) = 0x2e; //call far ptr [L1]
|
||
|
*(char *)(my7a+1) = 0x9a;
|
||
|
*(long *)(my7a+2) = 7L;
|
||
|
*(char *)(my7a+6) = 0xcf; //iret
|
||
|
*(short *)(my7a+7) = (RMI.EDI&65535); //L1: ipxoff
|
||
|
*(short *)(my7a+9) = RMI.ES; // ipxseg
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//Special stuff for WATCOM C
|
||
|
if ((rmoffset32 = convalloc32(1380L+NETCODEBYTES+COMBUFSIZ)) == 0)
|
||
|
{ printf("Can't allocate memory for IPX\n"); exit; }
|
||
|
rmsegment16 = (rmoffset32>>4);
|
||
|
|
||
|
i = rmoffset32;
|
||
|
ecbget = (char *)i; i += 48;
|
||
|
ecbput = (char *)i; i += 48;
|
||
|
ipxin = (char *)i; i += 32;
|
||
|
ipxout = (char *)i; i += 32;
|
||
|
messin = (char *)i; i += 560;
|
||
|
messout = (char *)i; i += 560;
|
||
|
tempinbuf = (char *)i; i += 16;
|
||
|
tempoutbuf = (char *)i; i += 80;
|
||
|
rmnethandler = (char *)i; i += NETCODEBYTES;
|
||
|
netinbufplc = (short *)i; i += 2;
|
||
|
netinbufend = (short *)i; i += 2;
|
||
|
netinbuf = (char *)i; i += COMBUFSIZ;
|
||
|
memcpy((void *)rmnethandler,(void *)rmnetbuffer,NETCODEBYTES);
|
||
|
|
||
|
simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
|
||
|
if ((simulateint(0x7a,(long)0xff,0L,0L,(long)socket,0L,0L)&255) != 0) return(-2); //Opensocket
|
||
|
|
||
|
simulateint(0x7a,0L,9L,0L,0L,(long)tempoutbuf,0L); //Getinternetworkaddress
|
||
|
memcpy((void *)&mycompaddr[0],(void *)&tempoutbuf[0],10);
|
||
|
mycompaddr[10] = (socket&255);
|
||
|
mycompaddr[11] = (socket>>8);
|
||
|
myconnectnum = ((long)tempoutbuf[6])+(((long)tempoutbuf[7])<<8)+(((long)(tempoutbuf[8]^tempoutbuf[9]))<<16)+(((long)mypriority)<<24);
|
||
|
|
||
|
netinitconnection(myconnectnum,mycompaddr);
|
||
|
|
||
|
ecbget[8] = 1; ecbput[8] = 0;
|
||
|
*netinbufplc = 0; *netinbufend = 0;
|
||
|
|
||
|
for(i=MAXPLAYERS-1;i>=0;i--) netincnt[i] = 0, netoutcnt[i] = 0;
|
||
|
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
{
|
||
|
omessnum[i] = 0;
|
||
|
for(j=NETBACKPACKETS-1;j>=0;j--)
|
||
|
{
|
||
|
omessleng[i][j] = 0;
|
||
|
omessconnectindex[i][j] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Netlisten
|
||
|
for(i=0;i<30;i++) ipxin[i] = 0;
|
||
|
for(i=0;i<48;i++) ecbget[i] = 0;
|
||
|
ecbget[4] = (char)(((long)rmnethandler-rmoffset32)&255), ecbget[5] = (char)(((long)rmnethandler-rmoffset32)>>8);
|
||
|
ecbget[6] = (char)(rmsegment16&255), ecbget[7] = (char)(rmsegment16>>8);
|
||
|
ecbget[10] = (socket&255), ecbget[11] = (socket>>8);
|
||
|
ecbget[34] = 2, ecbget[35] = 0;
|
||
|
ecbget[36] = (char)(((long)ipxin-rmoffset32)&255), ecbget[37] = (char)(((long)ipxin-rmoffset32)>>8);
|
||
|
ecbget[38] = (char)(rmsegment16&255), ecbget[39] = (char)(rmsegment16>>8);
|
||
|
ecbget[40] = 30, ecbget[41] = 0;
|
||
|
ecbget[42] = (char)(((long)messin-rmoffset32)&255), ecbget[43] = (char)(((long)messin-rmoffset32)>>8);
|
||
|
ecbget[44] = (char)(rmsegment16&255), ecbget[45] = (char)(rmsegment16>>8);
|
||
|
ecbget[46] = (MAXIPXSIZ&255), ecbget[47] = (MAXIPXSIZ>>8);
|
||
|
simulateint(0x7a,0L,(long)0x4,0L,0L,(long)ecbget,0L); //Receivepacket
|
||
|
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
int comon()
|
||
|
{
|
||
|
long divisor, cnt;
|
||
|
short *ptr;
|
||
|
|
||
|
if ((comnum < 1) || (comnum > 4)) return(-1);
|
||
|
//comvect = 0xb+(comnum&1);
|
||
|
comvect = ((comrateoption>>4)+0x8+2);
|
||
|
installbicomhandlers();
|
||
|
|
||
|
*incnt = 0; outcnt = 0;
|
||
|
*inbufplc = 0; *inbufend = 0; *outbufplc = 0; *outbufend = 0;
|
||
|
|
||
|
ptr = (short *)(0x400L+(long)((comnum-1)<<1));
|
||
|
*comport = *ptr;
|
||
|
if (*comport == 0)
|
||
|
{
|
||
|
switch(comnum)
|
||
|
{
|
||
|
case 1: *comport = 0x3f8; break;
|
||
|
case 2: *comport = 0x2f8; break;
|
||
|
case 3: *comport = 0x3e8; break;
|
||
|
case 4: *comport = 0x2e8; break;
|
||
|
}
|
||
|
if ((inp((*comport)+5)&0x60) != 0x60) { *comport = 0; return(-1); }
|
||
|
}
|
||
|
if ((comspeed <= 0) || (comspeed > 115200)) return(-1);
|
||
|
|
||
|
// Baud-Setting,?,?,Parity O/E,Parity Off/On, Stop-1/2,Bits-5/6/7/8
|
||
|
// 0x0b is odd parity,1 stop bit, 8 bits
|
||
|
|
||
|
#ifdef PLATFORM_DOS
|
||
|
_disable();
|
||
|
#endif
|
||
|
koutp((*comport)+3,0x80); //enable latch registers
|
||
|
divisor = 115200 / comspeed;
|
||
|
koutp((*comport)+0,divisor&255); //# = 115200 / bps
|
||
|
koutp((*comport)+1,divisor>>8);
|
||
|
koutp((*comport)+3,0x03); //0x03 = n,8,1
|
||
|
|
||
|
koutp((*comport)+2,0x87); //check for a 16550 0=1,64=4,128=8,192=14
|
||
|
if ((kinp((*comport)+2)&0xf8) == 0xc0)
|
||
|
{
|
||
|
*comtype = 16;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*comtype = 1;
|
||
|
koutp((*comport)+2,0);
|
||
|
}
|
||
|
cnt = *comtype; //Clear any junk already in FIFO
|
||
|
while (((kinp((*comport)+5)&0x1) > 0) && (cnt > 0))
|
||
|
{ kinp(*comport); cnt--; }
|
||
|
|
||
|
koutp((*comport)+4,0x0b); //setup for interrupts (modem control)
|
||
|
koutp((*comport)+1,0); //com interrupt disable
|
||
|
koutp(0x21,kinp(0x21)&(255-(1<<(comvect&7)))); //Unmask vector
|
||
|
kinp((*comport)+6);
|
||
|
kinp((*comport)+5);
|
||
|
kinp((*comport)+0);
|
||
|
kinp((*comport)+2);
|
||
|
koutp((*comport)+1,0x03); //com interrupt enable
|
||
|
koutp(0x20,0x20);
|
||
|
|
||
|
comescape = 0; comreset = 0;
|
||
|
*comerror = 0; *comresend = 0;
|
||
|
#ifdef PLATFORM_DOS
|
||
|
_enable();
|
||
|
#endif
|
||
|
|
||
|
syncbufleng = 0;
|
||
|
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
void netoff()
|
||
|
{
|
||
|
if (my7a) *(long *)(0x7a<<2) = 0L;
|
||
|
simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
|
||
|
}
|
||
|
|
||
|
void comoff()
|
||
|
{
|
||
|
long i;
|
||
|
|
||
|
i = 1048576;
|
||
|
while ((*outbufplc != *outbufend) && (i >= 0))
|
||
|
{
|
||
|
startcom();
|
||
|
i--;
|
||
|
}
|
||
|
|
||
|
#ifdef PLATFORM_DOS
|
||
|
_disable();
|
||
|
#endif
|
||
|
koutp(0x21,kinp(0x21)|(1<<(comvect&7))); //Mask vector
|
||
|
if (hangup != 0)
|
||
|
{
|
||
|
koutp((*comport)+1,0);
|
||
|
koutp((*comport)+4,0);
|
||
|
}
|
||
|
#ifdef PLATFORM_DOS
|
||
|
_enable();
|
||
|
#endif
|
||
|
uninstallbicomhandlers();
|
||
|
}
|
||
|
|
||
|
void netsend (short otherconnectindex, short messleng)
|
||
|
{
|
||
|
long i;
|
||
|
|
||
|
i = 32767;
|
||
|
while ((ecbput[8] != 0) && (i > 0)) i--;
|
||
|
for(i=0;i<30;i++) ipxout[i] = 0;
|
||
|
for(i=0;i<48;i++) ecbput[i] = 0;
|
||
|
ipxout[5] = 4;
|
||
|
if (otherconnectindex < 0)
|
||
|
{
|
||
|
memcpy((void *)&ipxout[6],(void *)&compaddr[0][0],4);
|
||
|
ipxout[10] = 0xff, ipxout[11] = 0xff, ipxout[12] = 0xff;
|
||
|
ipxout[13] = 0xff, ipxout[14] = 0xff, ipxout[15] = 0xff;
|
||
|
ipxout[16] = (socket&255), ipxout[17] = (socket>>8);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memcpy((void *)&ipxout[6],(void *)&compaddr[otherconnectindex][0],12);
|
||
|
}
|
||
|
|
||
|
ecbput[10] = (socket&255), ecbput[11] = (socket>>8);
|
||
|
if (otherconnectindex < 0)
|
||
|
{
|
||
|
ecbput[28] = 0xff, ecbput[29] = 0xff, ecbput[30] = 0xff;
|
||
|
ecbput[31] = 0xff, ecbput[32] = 0xff, ecbput[33] = 0xff;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memcpy((void *)&ecbput[28],(void *)&compaddr[otherconnectindex][4],6);
|
||
|
}
|
||
|
|
||
|
ecbput[34] = 2, ecbput[35] = 0;
|
||
|
ecbput[36] = (char)(((long)ipxout-rmoffset32)&255), ecbput[37] = (char)(((long)ipxout-rmoffset32)>>8);
|
||
|
ecbput[38] = (char)(rmsegment16&255), ecbput[39] = (char)(rmsegment16>>8);
|
||
|
ecbput[40] = 30, ecbput[41] = 0;
|
||
|
ecbput[42] = (char)(((long)messout-rmoffset32)&255), ecbput[43] = (char)(((long)messout-rmoffset32)>>8);
|
||
|
ecbput[44] = (char)(rmsegment16&255), ecbput[45] = (char)(rmsegment16>>8);
|
||
|
ecbput[46] = (char)(messleng&255), ecbput[47] = (char)(messleng>>8);
|
||
|
simulateint(0x7a,0L,(long)0x3,0L,0L,(long)ecbput,0L); //Sendpacket
|
||
|
}
|
||
|
|
||
|
void comsend(char ch)
|
||
|
{
|
||
|
if (ch == ESC1)
|
||
|
{
|
||
|
outbuf[*outbufend] = ESC1; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
|
||
|
ch = 128;
|
||
|
}
|
||
|
else if (ch == ESC2)
|
||
|
{
|
||
|
outbuf[*outbufend] = ESC1; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
|
||
|
ch = 129;
|
||
|
}
|
||
|
outbuf[*outbufend] = ch; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
|
||
|
}
|
||
|
|
||
|
void startcom()
|
||
|
{
|
||
|
if ((kinp((*comport)+5)&0x40) == 0) return;
|
||
|
|
||
|
if (*comresend != 0)
|
||
|
{
|
||
|
if (*comresend == 2) koutp(*comport,ESC1);
|
||
|
if (*comresend == 1) koutp(*comport,ESC2);
|
||
|
*comresend = (*comresend) - 1;
|
||
|
}
|
||
|
else if (*comerror != 0)
|
||
|
{
|
||
|
if (*comerror == 2) koutp(*comport,ESC1);
|
||
|
if (*comerror == 1) koutp(*comport,*incnt);
|
||
|
*comerror = (*comerror) - 1;
|
||
|
}
|
||
|
else if (*outbufplc != *outbufend)
|
||
|
{
|
||
|
koutp(*comport,(long)outbuf[*outbufplc]);
|
||
|
*outbufplc = (((*outbufplc)+1)&(COMBUFSIZ-1));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void interrupt far comhandler(void)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
comtemp = (kinp((*comport)+2)&7);
|
||
|
if (comtemp == 2)
|
||
|
{
|
||
|
for(comi=(*comtype);comi>0;comi--)
|
||
|
{
|
||
|
if (*comresend != 0)
|
||
|
{
|
||
|
if (*comresend == 2) koutp(*comport,ESC1);
|
||
|
if (*comresend == 1) koutp(*comport,ESC2);
|
||
|
*comresend = (*comresend) - 1;
|
||
|
continue;
|
||
|
}
|
||
|
if (*comerror != 0)
|
||
|
{
|
||
|
if (*comerror == 2) koutp(*comport,ESC1);
|
||
|
if (*comerror == 1) koutp(*comport,*incnt);
|
||
|
*comerror = (*comerror) - 1;
|
||
|
continue;
|
||
|
}
|
||
|
if (*outbufplc != *outbufend)
|
||
|
{
|
||
|
koutp(*comport,(long)outbuf[*outbufplc]);
|
||
|
*outbufplc = (((*outbufplc)+1)&(COMBUFSIZ-1));
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (comtemp == 4)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
//comtemp = (rand()&255);
|
||
|
//if (comtemp == 17)
|
||
|
// inbuf[*inbufend] = 17;
|
||
|
//else
|
||
|
inbuf[*inbufend] = (char)kinp(*comport);
|
||
|
|
||
|
//if (comtemp != 11) *inbufend = (((*inbufend)+1)&(COMBUFSIZ-1));
|
||
|
//if (comtemp == 24)
|
||
|
//{
|
||
|
// inbuf[*inbufend] = 17;
|
||
|
*inbufend = (((*inbufend)+1)&(COMBUFSIZ-1));
|
||
|
//}
|
||
|
//comtemp = 4;
|
||
|
|
||
|
} while ((*comtype == 16) && ((kinp((*comport)+5)&1) > 0));
|
||
|
}
|
||
|
}
|
||
|
while ((comtemp&1) == 0);
|
||
|
koutp(0x20,0x20);
|
||
|
}
|
||
|
|
||
|
int netinitconnection (long newconnectnum, char *newcompaddr)
|
||
|
{
|
||
|
long i, j, k, newindex, templong;
|
||
|
char tempchar;
|
||
|
|
||
|
//Check to see if connection number already initialized
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
if (connectnum[i] == newconnectnum) return(-1);
|
||
|
|
||
|
//Find blank place to put new connection number
|
||
|
newindex = 0;
|
||
|
while (connectnum[newindex] != 0x7fffffff)
|
||
|
{
|
||
|
newindex++;
|
||
|
if (newindex >= MAXPLAYERS) return(-1); //Out of space! (more than 16 players)
|
||
|
}
|
||
|
|
||
|
//Insert connection number on connection number list
|
||
|
numplayers++;
|
||
|
connectnum[newindex] = newconnectnum;
|
||
|
|
||
|
//Getinternetworkaddress
|
||
|
memcpy((void *)&compaddr[newindex][0],(void *)newcompaddr,10);
|
||
|
compaddr[newindex][10] = (socket&255);
|
||
|
compaddr[newindex][11] = (socket>>8);
|
||
|
|
||
|
//Sort connection numbers
|
||
|
for(i=1;i<MAXPLAYERS;i++)
|
||
|
for(j=0;j<i;j++)
|
||
|
if (connectnum[i] < connectnum[j])
|
||
|
{
|
||
|
templong = connectnum[i], connectnum[i] = connectnum[j], connectnum[j] = templong;
|
||
|
for(k=0;k<12;k++) tempchar = compaddr[i][k], compaddr[i][k] = compaddr[j][k], compaddr[j][k] = tempchar;
|
||
|
}
|
||
|
|
||
|
//Rebuild linked list, MAKING SURE that the linked list goes through
|
||
|
// the players in the same order on all computers!
|
||
|
connecthead = 0;
|
||
|
for(i=0;i<numplayers-1;i++) connectpoint2[i] = i+1;
|
||
|
connectpoint2[numplayers-1] = -1;
|
||
|
|
||
|
for(i=0;i<numplayers;i++)
|
||
|
if (connectnum[i] == myconnectnum) myconnectindex = i;
|
||
|
|
||
|
return(1);
|
||
|
}
|
||
|
|
||
|
void netuninitconnection(short goneindex)
|
||
|
{
|
||
|
long i, j, k=0;
|
||
|
|
||
|
connectnum[goneindex] = 0x7fffffff; numplayers--;
|
||
|
|
||
|
j = 0;
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
if (connectnum[i] != 0x7fffffff)
|
||
|
{
|
||
|
if (j == 0) connecthead = i; else connectpoint2[k] = i;
|
||
|
k = i; j++;
|
||
|
}
|
||
|
connectpoint2[k] = -1;
|
||
|
}
|
||
|
|
||
|
void sendpacket (short otherconnectindex, unsigned char *bufptr, short messleng)
|
||
|
{
|
||
|
long i, j, k, l;
|
||
|
|
||
|
if (multioption <= 0) return;
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
//Allow initial incnt/outcnt syncing
|
||
|
if ((bufptr[0] == 253) || (bufptr[0] == 254)) outcnt = 0;
|
||
|
|
||
|
outbufindex[outcnt] = *outbufend;
|
||
|
|
||
|
comsend(((messleng&1)<<7)+outcnt);
|
||
|
for(i=0;i<messleng;i++) comsend(bufptr[i]);
|
||
|
if ((comrateoption&15) > 0)
|
||
|
{
|
||
|
i = getcrc(bufptr,messleng);
|
||
|
updatecrc16(i,(((messleng&1)<<7)+outcnt));
|
||
|
comsend(i&255); comsend(i>>8);
|
||
|
}
|
||
|
outbuf[*outbufend] = ESC2, *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1)); //Not raw
|
||
|
|
||
|
startcom();
|
||
|
outcnt = ((outcnt+1)&127);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
i = 262144; //Wait for last packet to be sent
|
||
|
while ((i > 0) && (ecbput[8] != 0)) i--;
|
||
|
|
||
|
messout[0] = myconnectindex; j = 1;
|
||
|
|
||
|
if ((unsigned char) bufptr[0] >= 200)
|
||
|
{
|
||
|
//Allow initial incnt/outcnt syncing
|
||
|
for(i=0;i<MAXPLAYERS;i++) netoutcnt[i] = 0;
|
||
|
messout[j++] = 0xfe;
|
||
|
for(i=0;i<messleng;i++) messout[j++] = bufptr[i];
|
||
|
netsend(otherconnectindex,j);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//Copy new packet into omess fifo
|
||
|
if (otherconnectindex < 0)
|
||
|
{
|
||
|
for(k=connecthead;k>=0;k=connectpoint2[k])
|
||
|
if (k != myconnectindex)
|
||
|
{
|
||
|
omessconnectindex[k][omessnum[k]] = -1;
|
||
|
omessleng[k][omessnum[k]] = messleng;
|
||
|
for(i=0;i<messleng;i++) omessout[k][omessnum[k]][i] = bufptr[i];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
omessconnectindex[otherconnectindex][omessnum[otherconnectindex]] = otherconnectindex;
|
||
|
omessleng[otherconnectindex][omessnum[otherconnectindex]] = messleng;
|
||
|
for(i=0;i<messleng;i++) omessout[otherconnectindex][omessnum[otherconnectindex]][i] = bufptr[i];
|
||
|
}
|
||
|
|
||
|
//Put last 4 packets into 1 big packet
|
||
|
for(l=0;l<NETBACKPACKETS;l++)
|
||
|
{
|
||
|
//k = omess index
|
||
|
k = ((omessnum[otherconnectindex]-l)&(NETBACKPACKETS-1));
|
||
|
|
||
|
if (omessconnectindex[otherconnectindex][k] < 0)
|
||
|
{
|
||
|
messout[j++] = 255;
|
||
|
for(i=connecthead;i>=0;i=connectpoint2[i])
|
||
|
if (i != myconnectindex)
|
||
|
messout[j++] = ((netoutcnt[i]-l)&255);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
messout[j++] = otherconnectindex;
|
||
|
messout[j++] = ((netoutcnt[otherconnectindex]-l)&255);
|
||
|
}
|
||
|
messout[j++] = (omessleng[otherconnectindex][k]&255);
|
||
|
messout[j++] = ((omessleng[otherconnectindex][k]>>8)&255);
|
||
|
for(i=0;i<omessleng[otherconnectindex][k];i++)
|
||
|
messout[j++] = omessout[otherconnectindex][k][i];
|
||
|
}
|
||
|
|
||
|
//SEND!!!
|
||
|
netsend(otherconnectindex,j);
|
||
|
|
||
|
|
||
|
//Increment outcnt and omessnum counters
|
||
|
if (otherconnectindex < 0)
|
||
|
{
|
||
|
for(i=connecthead;i>=0;i=connectpoint2[i])
|
||
|
if (i != myconnectindex)
|
||
|
{
|
||
|
netoutcnt[i]++;
|
||
|
omessnum[i] = ((omessnum[i]+1)&(NETBACKPACKETS-1));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
netoutcnt[otherconnectindex]++;
|
||
|
omessnum[otherconnectindex] = ((omessnum[otherconnectindex]+1)&(NETBACKPACKETS-1));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
short getpacket (short *otherconnectindex, char *bufptr)
|
||
|
{
|
||
|
char toindex, bad, totbad;
|
||
|
short i, j=0, k, messleng, submessleng;
|
||
|
|
||
|
if (multioption <= 0) return(0);
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
*otherconnectindex = (myconnectindex^1);
|
||
|
|
||
|
bad = 0;
|
||
|
while (*inbufplc != *inbufend)
|
||
|
{
|
||
|
i = (short)inbuf[*inbufplc], *inbufplc = (((*inbufplc)+1)&(COMBUFSIZ-1));
|
||
|
|
||
|
if (i != ESC2)
|
||
|
{
|
||
|
if (i == ESC1) { comescape++; continue; }
|
||
|
if (comescape != 0)
|
||
|
{
|
||
|
comescape--;
|
||
|
if ((i < 128) && (*comresend == 0) && (((i-outcnt)&127) > 4))
|
||
|
{
|
||
|
*comresend = 2;
|
||
|
*outbufplc = outbufindex[i];
|
||
|
startcom();
|
||
|
continue;
|
||
|
}
|
||
|
if (syncbufleng < MAXIPXSIZ)
|
||
|
{
|
||
|
if (i == 128) { syncbuf[syncbufleng++] = ESC1; continue; }
|
||
|
if (i == 129) { syncbuf[syncbufleng++] = ESC2; continue; }
|
||
|
}
|
||
|
}
|
||
|
if (syncbufleng < MAXIPXSIZ) syncbuf[syncbufleng++] = i;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (comescape != 0)
|
||
|
{
|
||
|
comescape = 0; comreset = 0; *comerror = 0;
|
||
|
syncbufleng = 0;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
messleng = syncbufleng-3+(((comrateoption&15)==0)<<1);
|
||
|
if ((syncbuf[0]&127) != *incnt)
|
||
|
{
|
||
|
bad |= 1; //Packetcnt error
|
||
|
if ((*incnt == 1) && (syncbuf[1] == 254)) //Prevent 2 Masters!
|
||
|
myconnectindex = (myconnectnum<otherconnectnum);
|
||
|
}
|
||
|
if (((syncbuf[0]&128)>>7) != (messleng&1)) bad |= 2; //messleng error
|
||
|
for(i=0;i<messleng;i++) bufptr[i] = syncbuf[i+1];
|
||
|
if ((comrateoption&15) > 0)
|
||
|
{
|
||
|
i = getcrc(bufptr,messleng);
|
||
|
updatecrc16(i,syncbuf[0]);
|
||
|
if (((unsigned short)i) != ((long)syncbuf[syncbufleng-2])+((long)syncbuf[syncbufleng-1]<<8))
|
||
|
bad |= 2; //CRC error
|
||
|
}
|
||
|
|
||
|
syncbufleng = 0;
|
||
|
if (bad != 0)
|
||
|
{
|
||
|
//Don't send reset again if outbufplc is not before incnt!
|
||
|
if ((bad == 1) && ((((syncbuf[0]&127)-(*incnt))&127) >= 124))
|
||
|
{
|
||
|
bad = 0;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
bad = 0;
|
||
|
if (comreset != 0) comreset--;
|
||
|
if (((*comerror)|comreset) == 0)
|
||
|
{
|
||
|
*comerror = 2; comreset = 2;
|
||
|
startcom();
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
*incnt = (((*incnt)+1)&127);
|
||
|
if ((messleng > 0) && (bufptr[0] >= 200)) //200-255 are messages for engine's use only
|
||
|
processreservedmessage(messleng,bufptr);
|
||
|
|
||
|
comescape = 0; comreset = 0; *comerror = 0;
|
||
|
return(messleng);
|
||
|
}
|
||
|
return(0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (*netinbufplc == *netinbufend) return(0);
|
||
|
|
||
|
messleng = (short)netinbuf[*netinbufplc] + (((short)netinbuf[((*netinbufplc)+1)&(COMBUFSIZ-1)])<<8);
|
||
|
for(i=0;i<messleng;i++)
|
||
|
getmess[i] = netinbuf[((*netinbufplc)+i+2)&(COMBUFSIZ-1)];
|
||
|
|
||
|
k = 0; *otherconnectindex = getmess[k++];
|
||
|
|
||
|
for(totbad=0;totbad<NETBACKPACKETS;totbad++) //Number of sub-packets per packet
|
||
|
{
|
||
|
toindex = getmess[k++];
|
||
|
if (toindex == 0xfe)
|
||
|
{
|
||
|
netincnt[*otherconnectindex] = 0; // (>= 200) && ( <= 254)
|
||
|
submessleng = messleng-2; // Submessleng not necessary
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (toindex == 0xff)
|
||
|
{
|
||
|
for(i=connecthead;i>=0;i=connectpoint2[i])
|
||
|
if (i != *otherconnectindex)
|
||
|
{
|
||
|
if (i == myconnectindex) j = getmess[k];
|
||
|
k++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
j = getmess[k++];
|
||
|
|
||
|
if (j != netincnt[*otherconnectindex])
|
||
|
{
|
||
|
submessleng = (short)getmess[k]+(((short)getmess[k+1])<<8);
|
||
|
k += submessleng+2;
|
||
|
continue;
|
||
|
}
|
||
|
netincnt[*otherconnectindex]++;
|
||
|
|
||
|
submessleng = (short)getmess[k]+(((short)getmess[k+1])<<8); k += 2;
|
||
|
}
|
||
|
for(i=0;i<submessleng;i++) bufptr[i] = getmess[k++];
|
||
|
|
||
|
if (totbad == 0)
|
||
|
{
|
||
|
//Increment inbufplc only if first sub-message is read
|
||
|
*netinbufplc = (((*netinbufplc)+messleng+2)&(COMBUFSIZ-1));
|
||
|
if ((submessleng > 0) && (bufptr[0] >= 200)) //200-255 are messages for engine's use only
|
||
|
{
|
||
|
if (bufptr[0] >= 253)
|
||
|
{
|
||
|
processreservedmessage(submessleng,bufptr);
|
||
|
if ((bufptr[0] == 253) || (bufptr[0] == 254)) return(0);
|
||
|
}
|
||
|
return(submessleng);
|
||
|
}
|
||
|
}
|
||
|
if (*otherconnectindex == myconnectindex) return(0);
|
||
|
return(submessleng); //Got good packet
|
||
|
}
|
||
|
|
||
|
syncstate++; //DON'T WANT TO GET HERE!!!
|
||
|
//Increment inbufplc to make it not continuously screw up!
|
||
|
*netinbufplc = (((*netinbufplc)+messleng+2)&(COMBUFSIZ-1));
|
||
|
}
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
void initcrc(void)
|
||
|
{
|
||
|
long i, j, k, a;
|
||
|
|
||
|
for(j=0;j<256;j++) //Calculate CRC table
|
||
|
{
|
||
|
k = (j<<8); a = 0;
|
||
|
for(i=7;i>=0;i--)
|
||
|
{
|
||
|
if (((k^a)&0x8000) > 0)
|
||
|
a = ((a<<1)&65535) ^ 0x1021; //0x1021 = genpoly
|
||
|
else
|
||
|
a = ((a<<1)&65535);
|
||
|
k = ((k<<1)&65535);
|
||
|
}
|
||
|
crctable[j] = (a&65535);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
long getcrc(char *buffer, short bufleng)
|
||
|
{
|
||
|
long i, j;
|
||
|
|
||
|
j = 0;
|
||
|
for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]);
|
||
|
return(j&65535);
|
||
|
}
|
||
|
|
||
|
void installbicomhandlers(void)
|
||
|
{
|
||
|
#ifdef PLATFORM_DOS
|
||
|
union REGS r;
|
||
|
struct SREGS sr;
|
||
|
long lowp;
|
||
|
void far *fh;
|
||
|
|
||
|
//Get old protected mode handler
|
||
|
r.x.eax = 0x3500+comvect; /* DOS get vector (INT 0Ch) */
|
||
|
sr.ds = sr.es = 0;
|
||
|
int386x(0x21,&r,&r,&sr);
|
||
|
orig_pm_sel = (unsigned short)sr.es;
|
||
|
orig_pm_off = r.x.ebx;
|
||
|
|
||
|
//Get old real mode handler
|
||
|
r.x.eax = 0x0200; /* DPMI get real mode vector */
|
||
|
r.h.bl = comvect;
|
||
|
int386(0x31,&r,&r);
|
||
|
orig_rm_seg = (unsigned short)r.x.ecx;
|
||
|
orig_rm_off = (unsigned short)r.x.edx;
|
||
|
|
||
|
//Allocate memory in low memory to store real mode handler
|
||
|
if ((lowp = convalloc32(COMCODEBYTES+(COMBUFSIZ<<1))) == 0)
|
||
|
{ printf("Can't allocate conventional memory.\n"); exit; }
|
||
|
|
||
|
inbufplc = (short *)(lowp+0);
|
||
|
inbufend = (short *)(lowp+2);
|
||
|
outbufplc = (short *)(lowp+4);
|
||
|
outbufend = (short *)(lowp+6);
|
||
|
comport = (short *)(lowp+8);
|
||
|
comtype = (char *)(lowp+10);
|
||
|
comerror = (char *)(lowp+11);
|
||
|
comresend = (char *)(lowp+12);
|
||
|
incnt = (char *)(lowp+13);
|
||
|
inbuf = (char *)(lowp+COMCODEBYTES);
|
||
|
outbuf = (char *)(lowp+COMCODEBYTES+COMBUFSIZ);
|
||
|
|
||
|
memcpy((void *)lowp,(void *)rmbuffer,COMCODEBYTES);
|
||
|
|
||
|
//Set new protected mode handler
|
||
|
r.x.eax = 0x2500+comvect; /* DOS set vector (INT 0Ch) */
|
||
|
fh = (void far *)comhandler;
|
||
|
r.x.edx = FP_OFF(fh);
|
||
|
sr.ds = FP_SEG(fh); //DS:EDX == &handler
|
||
|
sr.es = 0;
|
||
|
int386x(0x21,&r,&r,&sr);
|
||
|
|
||
|
//Set new real mode handler (must be after setting protected mode)
|
||
|
r.x.eax = 0x0201;
|
||
|
r.h.bl = comvect; //CX:DX == real mode &handler
|
||
|
r.x.ecx = ((lowp>>4)&0xffff); //D32realseg
|
||
|
r.x.edx = COMCODEOFFS; //D32realoff
|
||
|
int386(0x31,&r,&r);
|
||
|
#else
|
||
|
fprintf (stderr,"%s, line %d; installbicomhandlers() called\n",
|
||
|
__FILE__, __LINE__);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void uninstallbicomhandlers(void)
|
||
|
{
|
||
|
#ifdef PLATFORM_DOS
|
||
|
union REGS r;
|
||
|
struct SREGS sr;
|
||
|
|
||
|
//restore old protected mode handler
|
||
|
r.x.eax = 0x2500+comvect; /* DOS set vector (INT 0Ch) */
|
||
|
r.x.edx = orig_pm_off;
|
||
|
sr.ds = orig_pm_sel; /* DS:EDX == &handler */
|
||
|
sr.es = 0;
|
||
|
int386x(0x21,&r,&r,&sr);
|
||
|
|
||
|
//restore old real mode handler
|
||
|
r.x.eax = 0x0201; /* DPMI set real mode vector */
|
||
|
r.h.bl = comvect;
|
||
|
r.x.ecx = (unsigned long)orig_rm_seg; //CX:DX == real mode &handler
|
||
|
r.x.edx = (unsigned long)orig_rm_off;
|
||
|
int386(0x31,&r,&r);
|
||
|
#else
|
||
|
fprintf (stderr, "%s line %d; uninstallbicomhandlers() called\n",
|
||
|
__FILE__, __LINE__);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void processreservedmessage(short tempbufleng, char *datempbuf)
|
||
|
{
|
||
|
long i, j, k, daotherconnectnum, templong;
|
||
|
|
||
|
switch(datempbuf[0])
|
||
|
{
|
||
|
//[253] (login, if myconnectnum's lowest, then respond with packet type 254)
|
||
|
case 253:
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
otherconnectnum = ((long)datempbuf[1])+(((long)datempbuf[2])<<8)+(((long)datempbuf[3])<<16)+(((long)datempbuf[4])<<24);
|
||
|
|
||
|
datempbuf[0] = 254;
|
||
|
sendpacket(-1,datempbuf,1);
|
||
|
|
||
|
myconnectindex = 0;
|
||
|
connecthead = 0; connectpoint2[0] = 1; connectpoint2[1] = -1;
|
||
|
numplayers = 2;
|
||
|
}
|
||
|
else if (multioption >= 5)
|
||
|
{
|
||
|
daotherconnectnum = ((long)datempbuf[1])+((long)(datempbuf[2]<<8))+((long)(datempbuf[3]<<16))+((long)(datempbuf[4]<<24));
|
||
|
if (daotherconnectnum != myconnectnum)
|
||
|
{
|
||
|
netinitconnection(daotherconnectnum,&datempbuf[5]);
|
||
|
|
||
|
if ((myconnectindex == connecthead) || ((connectnum[connecthead] == daotherconnectnum) && (myconnectindex == connectpoint2[connecthead])))
|
||
|
{
|
||
|
datempbuf[0] = 254;
|
||
|
j = 1;
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
if ((connectnum[i] != 0x7fffffff) && (connectnum[i] != daotherconnectnum))
|
||
|
{
|
||
|
datempbuf[j++] = (connectnum[i]&255);
|
||
|
datempbuf[j++] = ((connectnum[i]>>8)&255);
|
||
|
datempbuf[j++] = ((connectnum[i]>>16)&255);
|
||
|
datempbuf[j++] = ((connectnum[i]>>24)&255);
|
||
|
|
||
|
for(k=0;k<10;k++)
|
||
|
datempbuf[j++] = compaddr[i][k];
|
||
|
}
|
||
|
|
||
|
//While this doesn't have to be a broadcast, sending
|
||
|
//this info again makes good error correction
|
||
|
sendpacket(-1,datempbuf,j);
|
||
|
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
if (connectnum[i] == daotherconnectnum)
|
||
|
{
|
||
|
sendpacket((short)i,datempbuf,j);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 254: //[254][connectnum][connectnum]...(Packet type 253 response)
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
myconnectindex = 1;
|
||
|
connecthead = 0; connectpoint2[0] = 1; connectpoint2[1] = -1;
|
||
|
numplayers = 2;
|
||
|
}
|
||
|
else if (multioption >= 5)
|
||
|
{
|
||
|
j = 1;
|
||
|
while (j < tempbufleng)
|
||
|
{
|
||
|
templong = ((long)datempbuf[j])+((long)(datempbuf[j+1]<<8))+((long)(datempbuf[j+2]<<16))+((long)(datempbuf[j+3]<<24));
|
||
|
netinitconnection(templong,&datempbuf[j+4]);
|
||
|
j += 14;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 255:
|
||
|
if (multioption >= 5)
|
||
|
netuninitconnection(datempbuf[1]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sendlogon(void)
|
||
|
{
|
||
|
long i;
|
||
|
char tempbuf[16];
|
||
|
|
||
|
if (multioption <= 0)
|
||
|
return;
|
||
|
|
||
|
tempbuf[0] = 253;
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
tempbuf[1] = kinp(0x40);
|
||
|
tempbuf[2] = kinp(0x40);
|
||
|
tempbuf[3] = kinp(0x40);
|
||
|
tempbuf[4] = mypriority;
|
||
|
myconnectnum = ((long)tempbuf[1])+(((long)tempbuf[2])<<8)+(((long)tempbuf[3])<<16)+(((long)mypriority)<<24);
|
||
|
sendpacket(-1,tempbuf,5);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tempbuf[1] = (myconnectnum&255);
|
||
|
tempbuf[2] = ((myconnectnum>>8)&255);
|
||
|
tempbuf[3] = ((myconnectnum>>16)&255);
|
||
|
tempbuf[4] = ((myconnectnum>>24)&255);
|
||
|
for(i=0;i<10;i++)
|
||
|
tempbuf[i+5] = mycompaddr[i];
|
||
|
|
||
|
sendpacket(-1,tempbuf,15);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sendlogoff(void)
|
||
|
{
|
||
|
char tempbuf[16];
|
||
|
long i;
|
||
|
|
||
|
if ((numplayers <= 1) || (multioption <= 0)) return;
|
||
|
|
||
|
tempbuf[0] = 255;
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
sendpacket(-1,tempbuf,1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tempbuf[1] = myconnectindex;
|
||
|
for(i=connecthead;i>=0;i=connectpoint2[i])
|
||
|
if (i != myconnectindex)
|
||
|
sendpacket(i,tempbuf,2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int getoutputcirclesize(void)
|
||
|
{
|
||
|
if ((multioption >= 1) && (multioption <= 4))
|
||
|
{
|
||
|
startcom();
|
||
|
return(((*outbufend)-(*outbufplc)+COMBUFSIZ)&(COMBUFSIZ-1));
|
||
|
}
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
int setsocket(short newsocket)
|
||
|
{
|
||
|
long i;
|
||
|
|
||
|
if (multioption < 5)
|
||
|
{
|
||
|
socket = newsocket;
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
|
||
|
|
||
|
socket = newsocket;
|
||
|
|
||
|
simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
|
||
|
if ((simulateint(0x7a,(long)0xff,0L,0L,(long)socket,0L,0L)&255) != 0) return(-2); //Opensocket
|
||
|
mycompaddr[10] = (socket&255);
|
||
|
mycompaddr[11] = (socket>>8);
|
||
|
ecbget[10] = (socket&255);
|
||
|
ecbget[11] = (socket>>8);
|
||
|
for(i=0;i<MAXPLAYERS;i++)
|
||
|
{
|
||
|
compaddr[i][10] = (socket&255);
|
||
|
compaddr[i][11] = (socket>>8);
|
||
|
}
|
||
|
return(0);
|
||
|
}
|