blob: b23481bc087dbddd968faaac61df9a6d03484e8d [file] [log] [blame]
Franklin Weia855d622017-01-21 15:18:31 -05001// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2// Ken Silverman's official web site: "http://www.advsys.net/ken"
3// See the included license file "BUILDLIC.TXT" for license info.
4// This file has been modified from Ken Silverman's original release
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include "platform.h"
11
12extern long getcrc(char *buffer, short bufleng);
13extern void processreservedmessage(short tempbufleng, char *datempbuf);
14extern void initcrc(void);
15extern int comon(void);
16extern void comoff(void);
17extern int neton(void);
18extern void netoff(void);
19extern void startcom(void);
20extern int netinitconnection (long newconnectnum, char *newcompaddr);
21extern void installbicomhandlers(void);
22extern void uninstallbicomhandlers(void);
23
24#define COMBUFSIZ 16384
25#define COMCODEBYTES 384
26#define COMCODEOFFS 14
27#define NETCODEBYTES 384
28#define MAXPLAYERS 16
29#define ESC1 0x83
30#define ESC2 0x8f
31#define NETBACKPACKETS 4
32#define MAXIPXSIZ 546
33
34#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat])
35
36char syncstate = 0, hangup = 1;
37static char multioption = 0, comrateoption = 0;
38
39 //COM & NET variables
40short numplayers = 0, myconnectindex = 0;
41short connecthead, connectpoint2[MAXPLAYERS];
42char syncbuf[MAXIPXSIZ];
43long syncbufleng, outbufindex[128], outcnt;
44long myconnectnum, otherconnectnum, mypriority;
45long crctable[256];
46
47 //COM ONLY variables
48long comnum, comvect, comspeed, comtemp, comi, comescape, comreset;
Franklin Weia855d622017-01-21 15:18:31 -050049volatile unsigned char *inbuf, *outbuf, *comerror, *incnt, *comtype;
50volatile unsigned char *comresend;
51volatile short *inbufplc, *inbufend, *outbufplc, *outbufend, *comport;
Franklin Weia855d622017-01-21 15:18:31 -050052
53 //NET ONLY variables
54short socket = 0x4949;
55char compaddr[MAXPLAYERS][12], mycompaddr[12];
56char netincnt[MAXPLAYERS], netoutcnt[MAXPLAYERS];
57char getmess[MAXIPXSIZ];
58char omessout[MAXPLAYERS][NETBACKPACKETS][MAXIPXSIZ];
59short omessleng[MAXPLAYERS][NETBACKPACKETS];
60short omessconnectindex[MAXPLAYERS][NETBACKPACKETS];
61short omessnum[MAXPLAYERS];
62long connectnum[MAXPLAYERS], rmoffset32, rmsegment16, neti;
63volatile char *ecbget, *ecbput, *ipxin, *ipxout, *messin, *messout;
64volatile char *tempinbuf, *tempoutbuf, *rmnethandler, *netinbuf;
65volatile short *netinbufplc, *netinbufend;
66static char rmnetbuffer[NETCODEBYTES] =
67{
68 0xfb,0x2e,0x8a,0x26,0x62,0x00,0x2e,0xa0,0x63,0x00,
69 0x83,0xe8,0x1e,0x2e,0x8b,0x1e,0xe2,0x06,0x2e,0x88,
70 0x87,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x2e,0x88,
71 0xa7,0xe4,0x06,0x43,0x81,0xe3,0xff,0x3f,0x33,0xf6,
72 0x2e,0x8a,0x8c,0xa0,0x00,0x46,0x2e,0x88,0x8f,0xe4,
73 0x06,0x43,0x81,0xe3,0xff,0x3f,0x3b,0xf0,0x72,0xec,
74 0x2e,0x89,0x1e,0xe2,0x06,0xbb,0x04,0x00,0x8c,0xc8,
75 0x8e,0xc0,0xbe,0x00,0x00,0xcd,0x7a,0xcb,
76};
77static long my7a = 0;
78
Franklin Weia855d622017-01-21 15:18:31 -050079long convalloc32 (long size)
80{
Franklin Weia855d622017-01-21 15:18:31 -050081 fprintf (stderr, "%s, line %d; convalloc32() called\n", __FILE__,
82 __LINE__);
83 return 0;
Franklin Weia855d622017-01-21 15:18:31 -050084}
85
Franklin Weia855d622017-01-21 15:18:31 -050086long simulateint(char intnum, long daeax, long daebx, long daecx, long daedx, long daesi, long daedi)
87{
Franklin Weia855d622017-01-21 15:18:31 -050088 fprintf(stderr, "%s line %d; simulateint() called\n",__FILE__,__LINE__);
89 return 0;
Franklin Weia855d622017-01-21 15:18:31 -050090}
91
92void initmultiplayers(char damultioption, char dacomrateoption, char dapriority)
93{
94 long i;
95
96 multioption = damultioption;
97 comrateoption = dacomrateoption;
98
99 connecthead = 0;
100 for(i=MAXPLAYERS-1;i>=0;i--)
101 connectpoint2[i] = -1, connectnum[i] = 0x7fffffff;
102
103 mypriority = dapriority;
104
105 initcrc();
106
107 if ((multioption >= 1) && (multioption <= 4))
108 {
109 comnum = multioption;
110 switch(dacomrateoption&15)
111 {
112 case 0: comspeed = 2400; break;
113 case 1: comspeed = 4800; break;
114 case 2: comspeed = 9600; break;
115 case 3: comspeed = 14400; break;
116 case 4: comspeed = 19200; break;
117 case 5: comspeed = 28800; break;
118 }
119 comon();
120 }
121 if (multioption >= 5)
122 {
123 if ((i = neton()) != 0)
124 {
125 if (i == -1) printf("IPX driver not found\n");
126 if (i == -2) printf("Socket could not be opened\n");
127 exit(0);
128 }
129 }
130 numplayers = 1;
131}
132
133void uninitmultiplayers()
134{
135 if (numplayers > 0)
136 {
137 if ((multioption >= 1) && (multioption <= 4)) comoff();
138 if (multioption >= 5) netoff(); //Uninstall before timer
139 }
140}
141
142int neton(void)
143{
144 long i, j;
145
146 if ((simulateint(0x2f,(long)0x7a00,0L,0L,0L,0L,0L)&255) != 255) return(-1);
Franklin Weia855d622017-01-21 15:18:31 -0500147
148 //Special stuff for WATCOM C
149 if ((rmoffset32 = convalloc32(1380L+NETCODEBYTES+COMBUFSIZ)) == 0)
150 { printf("Can't allocate memory for IPX\n"); exit; }
151 rmsegment16 = (rmoffset32>>4);
152
153 i = rmoffset32;
154 ecbget = (char *)i; i += 48;
155 ecbput = (char *)i; i += 48;
156 ipxin = (char *)i; i += 32;
157 ipxout = (char *)i; i += 32;
158 messin = (char *)i; i += 560;
159 messout = (char *)i; i += 560;
160 tempinbuf = (char *)i; i += 16;
161 tempoutbuf = (char *)i; i += 80;
162 rmnethandler = (char *)i; i += NETCODEBYTES;
163 netinbufplc = (short *)i; i += 2;
164 netinbufend = (short *)i; i += 2;
165 netinbuf = (char *)i; i += COMBUFSIZ;
166 memcpy((void *)rmnethandler,(void *)rmnetbuffer,NETCODEBYTES);
167
168 simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
169 if ((simulateint(0x7a,(long)0xff,0L,0L,(long)socket,0L,0L)&255) != 0) return(-2); //Opensocket
170
171 simulateint(0x7a,0L,9L,0L,0L,(long)tempoutbuf,0L); //Getinternetworkaddress
172 memcpy((void *)&mycompaddr[0],(void *)&tempoutbuf[0],10);
173 mycompaddr[10] = (socket&255);
174 mycompaddr[11] = (socket>>8);
175 myconnectnum = ((long)tempoutbuf[6])+(((long)tempoutbuf[7])<<8)+(((long)(tempoutbuf[8]^tempoutbuf[9]))<<16)+(((long)mypriority)<<24);
176
177 netinitconnection(myconnectnum,mycompaddr);
178
179 ecbget[8] = 1; ecbput[8] = 0;
180 *netinbufplc = 0; *netinbufend = 0;
181
182 for(i=MAXPLAYERS-1;i>=0;i--) netincnt[i] = 0, netoutcnt[i] = 0;
183
184 for(i=0;i<MAXPLAYERS;i++)
185 {
186 omessnum[i] = 0;
187 for(j=NETBACKPACKETS-1;j>=0;j--)
188 {
189 omessleng[i][j] = 0;
190 omessconnectindex[i][j] = 0;
191 }
192 }
193
194 //Netlisten
195 for(i=0;i<30;i++) ipxin[i] = 0;
196 for(i=0;i<48;i++) ecbget[i] = 0;
197 ecbget[4] = (char)(((long)rmnethandler-rmoffset32)&255), ecbget[5] = (char)(((long)rmnethandler-rmoffset32)>>8);
198 ecbget[6] = (char)(rmsegment16&255), ecbget[7] = (char)(rmsegment16>>8);
199 ecbget[10] = (socket&255), ecbget[11] = (socket>>8);
200 ecbget[34] = 2, ecbget[35] = 0;
201 ecbget[36] = (char)(((long)ipxin-rmoffset32)&255), ecbget[37] = (char)(((long)ipxin-rmoffset32)>>8);
202 ecbget[38] = (char)(rmsegment16&255), ecbget[39] = (char)(rmsegment16>>8);
203 ecbget[40] = 30, ecbget[41] = 0;
204 ecbget[42] = (char)(((long)messin-rmoffset32)&255), ecbget[43] = (char)(((long)messin-rmoffset32)>>8);
205 ecbget[44] = (char)(rmsegment16&255), ecbget[45] = (char)(rmsegment16>>8);
206 ecbget[46] = (MAXIPXSIZ&255), ecbget[47] = (MAXIPXSIZ>>8);
207 simulateint(0x7a,0L,(long)0x4,0L,0L,(long)ecbget,0L); //Receivepacket
208
209 return(0);
210}
211
212int comon()
213{
214 long divisor, cnt;
215 short *ptr;
216
217 if ((comnum < 1) || (comnum > 4)) return(-1);
218 //comvect = 0xb+(comnum&1);
219 comvect = ((comrateoption>>4)+0x8+2);
220 installbicomhandlers();
221
222 *incnt = 0; outcnt = 0;
223 *inbufplc = 0; *inbufend = 0; *outbufplc = 0; *outbufend = 0;
224
225 ptr = (short *)(0x400L+(long)((comnum-1)<<1));
226 *comport = *ptr;
227 if (*comport == 0)
228 {
229 switch(comnum)
230 {
231 case 1: *comport = 0x3f8; break;
232 case 2: *comport = 0x2f8; break;
233 case 3: *comport = 0x3e8; break;
234 case 4: *comport = 0x2e8; break;
235 }
236 if ((inp((*comport)+5)&0x60) != 0x60) { *comport = 0; return(-1); }
237 }
238 if ((comspeed <= 0) || (comspeed > 115200)) return(-1);
239
240 // Baud-Setting,?,?,Parity O/E,Parity Off/On, Stop-1/2,Bits-5/6/7/8
241 // 0x0b is odd parity,1 stop bit, 8 bits
242
Franklin Weia855d622017-01-21 15:18:31 -0500243 koutp((*comport)+3,0x80); //enable latch registers
244 divisor = 115200 / comspeed;
245 koutp((*comport)+0,divisor&255); //# = 115200 / bps
246 koutp((*comport)+1,divisor>>8);
247 koutp((*comport)+3,0x03); //0x03 = n,8,1
248
249 koutp((*comport)+2,0x87); //check for a 16550 0=1,64=4,128=8,192=14
250 if ((kinp((*comport)+2)&0xf8) == 0xc0)
251 {
252 *comtype = 16;
253 }
254 else
255 {
256 *comtype = 1;
257 koutp((*comport)+2,0);
258 }
259 cnt = *comtype; //Clear any junk already in FIFO
260 while (((kinp((*comport)+5)&0x1) > 0) && (cnt > 0))
261 { kinp(*comport); cnt--; }
262
263 koutp((*comport)+4,0x0b); //setup for interrupts (modem control)
264 koutp((*comport)+1,0); //com interrupt disable
265 koutp(0x21,kinp(0x21)&(255-(1<<(comvect&7)))); //Unmask vector
266 kinp((*comport)+6);
267 kinp((*comport)+5);
268 kinp((*comport)+0);
269 kinp((*comport)+2);
270 koutp((*comport)+1,0x03); //com interrupt enable
271 koutp(0x20,0x20);
272
273 comescape = 0; comreset = 0;
274 *comerror = 0; *comresend = 0;
Franklin Weia855d622017-01-21 15:18:31 -0500275
276 syncbufleng = 0;
277
278 return(0);
279}
280
281void netoff()
282{
283 if (my7a) *(long *)(0x7a<<2) = 0L;
284 simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
285}
286
287void comoff()
288{
289 long i;
290
291 i = 1048576;
292 while ((*outbufplc != *outbufend) && (i >= 0))
293 {
294 startcom();
295 i--;
296 }
297
Franklin Weia855d622017-01-21 15:18:31 -0500298 koutp(0x21,kinp(0x21)|(1<<(comvect&7))); //Mask vector
299 if (hangup != 0)
300 {
301 koutp((*comport)+1,0);
302 koutp((*comport)+4,0);
303 }
Franklin Weia855d622017-01-21 15:18:31 -0500304 uninstallbicomhandlers();
305}
306
307void netsend (short otherconnectindex, short messleng)
308{
309 long i;
310
311 i = 32767;
312 while ((ecbput[8] != 0) && (i > 0)) i--;
313 for(i=0;i<30;i++) ipxout[i] = 0;
314 for(i=0;i<48;i++) ecbput[i] = 0;
315 ipxout[5] = 4;
316 if (otherconnectindex < 0)
317 {
318 memcpy((void *)&ipxout[6],(void *)&compaddr[0][0],4);
319 ipxout[10] = 0xff, ipxout[11] = 0xff, ipxout[12] = 0xff;
320 ipxout[13] = 0xff, ipxout[14] = 0xff, ipxout[15] = 0xff;
321 ipxout[16] = (socket&255), ipxout[17] = (socket>>8);
322 }
323 else
324 {
325 memcpy((void *)&ipxout[6],(void *)&compaddr[otherconnectindex][0],12);
326 }
327
328 ecbput[10] = (socket&255), ecbput[11] = (socket>>8);
329 if (otherconnectindex < 0)
330 {
331 ecbput[28] = 0xff, ecbput[29] = 0xff, ecbput[30] = 0xff;
332 ecbput[31] = 0xff, ecbput[32] = 0xff, ecbput[33] = 0xff;
333 }
334 else
335 {
336 memcpy((void *)&ecbput[28],(void *)&compaddr[otherconnectindex][4],6);
337 }
338
339 ecbput[34] = 2, ecbput[35] = 0;
340 ecbput[36] = (char)(((long)ipxout-rmoffset32)&255), ecbput[37] = (char)(((long)ipxout-rmoffset32)>>8);
341 ecbput[38] = (char)(rmsegment16&255), ecbput[39] = (char)(rmsegment16>>8);
342 ecbput[40] = 30, ecbput[41] = 0;
343 ecbput[42] = (char)(((long)messout-rmoffset32)&255), ecbput[43] = (char)(((long)messout-rmoffset32)>>8);
344 ecbput[44] = (char)(rmsegment16&255), ecbput[45] = (char)(rmsegment16>>8);
345 ecbput[46] = (char)(messleng&255), ecbput[47] = (char)(messleng>>8);
346 simulateint(0x7a,0L,(long)0x3,0L,0L,(long)ecbput,0L); //Sendpacket
347}
348
349void comsend(char ch)
350{
351 if (ch == ESC1)
352 {
353 outbuf[*outbufend] = ESC1; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
354 ch = 128;
355 }
356 else if (ch == ESC2)
357 {
358 outbuf[*outbufend] = ESC1; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
359 ch = 129;
360 }
361 outbuf[*outbufend] = ch; *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1));
362}
363
364void startcom()
365{
366 if ((kinp((*comport)+5)&0x40) == 0) return;
367
368 if (*comresend != 0)
369 {
370 if (*comresend == 2) koutp(*comport,ESC1);
371 if (*comresend == 1) koutp(*comport,ESC2);
372 *comresend = (*comresend) - 1;
373 }
374 else if (*comerror != 0)
375 {
376 if (*comerror == 2) koutp(*comport,ESC1);
377 if (*comerror == 1) koutp(*comport,*incnt);
378 *comerror = (*comerror) - 1;
379 }
380 else if (*outbufplc != *outbufend)
381 {
382 koutp(*comport,(long)outbuf[*outbufplc]);
383 *outbufplc = (((*outbufplc)+1)&(COMBUFSIZ-1));
384 }
385}
386
387void interrupt far comhandler(void)
388{
389 do
390 {
391 comtemp = (kinp((*comport)+2)&7);
392 if (comtemp == 2)
393 {
394 for(comi=(*comtype);comi>0;comi--)
395 {
396 if (*comresend != 0)
397 {
398 if (*comresend == 2) koutp(*comport,ESC1);
399 if (*comresend == 1) koutp(*comport,ESC2);
400 *comresend = (*comresend) - 1;
401 continue;
402 }
403 if (*comerror != 0)
404 {
405 if (*comerror == 2) koutp(*comport,ESC1);
406 if (*comerror == 1) koutp(*comport,*incnt);
407 *comerror = (*comerror) - 1;
408 continue;
409 }
410 if (*outbufplc != *outbufend)
411 {
412 koutp(*comport,(long)outbuf[*outbufplc]);
413 *outbufplc = (((*outbufplc)+1)&(COMBUFSIZ-1));
414 continue;
415 }
416 break;
417 }
418 }
419 else if (comtemp == 4)
420 {
421 do
422 {
423 //comtemp = (rand()&255);
424 //if (comtemp == 17)
425 // inbuf[*inbufend] = 17;
426 //else
427 inbuf[*inbufend] = (char)kinp(*comport);
428
429 //if (comtemp != 11) *inbufend = (((*inbufend)+1)&(COMBUFSIZ-1));
430 //if (comtemp == 24)
431 //{
432 // inbuf[*inbufend] = 17;
433 *inbufend = (((*inbufend)+1)&(COMBUFSIZ-1));
434 //}
435 //comtemp = 4;
436
437 } while ((*comtype == 16) && ((kinp((*comport)+5)&1) > 0));
438 }
439 }
440 while ((comtemp&1) == 0);
441 koutp(0x20,0x20);
442}
443
444int netinitconnection (long newconnectnum, char *newcompaddr)
445{
446 long i, j, k, newindex, templong;
447 char tempchar;
448
449 //Check to see if connection number already initialized
450 for(i=0;i<MAXPLAYERS;i++)
451 if (connectnum[i] == newconnectnum) return(-1);
452
453 //Find blank place to put new connection number
454 newindex = 0;
455 while (connectnum[newindex] != 0x7fffffff)
456 {
457 newindex++;
458 if (newindex >= MAXPLAYERS) return(-1); //Out of space! (more than 16 players)
459 }
460
461 //Insert connection number on connection number list
462 numplayers++;
463 connectnum[newindex] = newconnectnum;
464
465 //Getinternetworkaddress
466 memcpy((void *)&compaddr[newindex][0],(void *)newcompaddr,10);
467 compaddr[newindex][10] = (socket&255);
468 compaddr[newindex][11] = (socket>>8);
469
470 //Sort connection numbers
471 for(i=1;i<MAXPLAYERS;i++)
472 for(j=0;j<i;j++)
473 if (connectnum[i] < connectnum[j])
474 {
475 templong = connectnum[i], connectnum[i] = connectnum[j], connectnum[j] = templong;
476 for(k=0;k<12;k++) tempchar = compaddr[i][k], compaddr[i][k] = compaddr[j][k], compaddr[j][k] = tempchar;
477 }
478
479 //Rebuild linked list, MAKING SURE that the linked list goes through
480 // the players in the same order on all computers!
481 connecthead = 0;
482 for(i=0;i<numplayers-1;i++) connectpoint2[i] = i+1;
483 connectpoint2[numplayers-1] = -1;
484
485 for(i=0;i<numplayers;i++)
486 if (connectnum[i] == myconnectnum) myconnectindex = i;
487
488 return(1);
489}
490
491void netuninitconnection(short goneindex)
492{
493 long i, j, k=0;
494
495 connectnum[goneindex] = 0x7fffffff; numplayers--;
496
497 j = 0;
498 for(i=0;i<MAXPLAYERS;i++)
499 if (connectnum[i] != 0x7fffffff)
500 {
501 if (j == 0) connecthead = i; else connectpoint2[k] = i;
502 k = i; j++;
503 }
504 connectpoint2[k] = -1;
505}
506
507void sendpacket (short otherconnectindex, unsigned char *bufptr, short messleng)
508{
509 long i, j, k, l;
510
511 if (multioption <= 0) return;
512 if (multioption < 5)
513 {
514 //Allow initial incnt/outcnt syncing
515 if ((bufptr[0] == 253) || (bufptr[0] == 254)) outcnt = 0;
516
517 outbufindex[outcnt] = *outbufend;
518
519 comsend(((messleng&1)<<7)+outcnt);
520 for(i=0;i<messleng;i++) comsend(bufptr[i]);
521 if ((comrateoption&15) > 0)
522 {
523 i = getcrc(bufptr,messleng);
524 updatecrc16(i,(((messleng&1)<<7)+outcnt));
525 comsend(i&255); comsend(i>>8);
526 }
527 outbuf[*outbufend] = ESC2, *outbufend = (((*outbufend)+1)&(COMBUFSIZ-1)); //Not raw
528
529 startcom();
530 outcnt = ((outcnt+1)&127);
531 }
532 else
533 {
534 i = 262144; //Wait for last packet to be sent
535 while ((i > 0) && (ecbput[8] != 0)) i--;
536
537 messout[0] = myconnectindex; j = 1;
538
539 if ((unsigned char) bufptr[0] >= 200)
540 {
541 //Allow initial incnt/outcnt syncing
542 for(i=0;i<MAXPLAYERS;i++) netoutcnt[i] = 0;
543 messout[j++] = 0xfe;
544 for(i=0;i<messleng;i++) messout[j++] = bufptr[i];
545 netsend(otherconnectindex,j);
546 return;
547 }
548
549 //Copy new packet into omess fifo
550 if (otherconnectindex < 0)
551 {
552 for(k=connecthead;k>=0;k=connectpoint2[k])
553 if (k != myconnectindex)
554 {
555 omessconnectindex[k][omessnum[k]] = -1;
556 omessleng[k][omessnum[k]] = messleng;
557 for(i=0;i<messleng;i++) omessout[k][omessnum[k]][i] = bufptr[i];
558 }
559 }
560 else
561 {
562 omessconnectindex[otherconnectindex][omessnum[otherconnectindex]] = otherconnectindex;
563 omessleng[otherconnectindex][omessnum[otherconnectindex]] = messleng;
564 for(i=0;i<messleng;i++) omessout[otherconnectindex][omessnum[otherconnectindex]][i] = bufptr[i];
565 }
566
567 //Put last 4 packets into 1 big packet
568 for(l=0;l<NETBACKPACKETS;l++)
569 {
570 //k = omess index
571 k = ((omessnum[otherconnectindex]-l)&(NETBACKPACKETS-1));
572
573 if (omessconnectindex[otherconnectindex][k] < 0)
574 {
575 messout[j++] = 255;
576 for(i=connecthead;i>=0;i=connectpoint2[i])
577 if (i != myconnectindex)
578 messout[j++] = ((netoutcnt[i]-l)&255);
579 }
580 else
581 {
582 messout[j++] = otherconnectindex;
583 messout[j++] = ((netoutcnt[otherconnectindex]-l)&255);
584 }
585 messout[j++] = (omessleng[otherconnectindex][k]&255);
586 messout[j++] = ((omessleng[otherconnectindex][k]>>8)&255);
587 for(i=0;i<omessleng[otherconnectindex][k];i++)
588 messout[j++] = omessout[otherconnectindex][k][i];
589 }
590
591 //SEND!!!
592 netsend(otherconnectindex,j);
593
594
595 //Increment outcnt and omessnum counters
596 if (otherconnectindex < 0)
597 {
598 for(i=connecthead;i>=0;i=connectpoint2[i])
599 if (i != myconnectindex)
600 {
601 netoutcnt[i]++;
602 omessnum[i] = ((omessnum[i]+1)&(NETBACKPACKETS-1));
603 }
604 }
605 else
606 {
607 netoutcnt[otherconnectindex]++;
608 omessnum[otherconnectindex] = ((omessnum[otherconnectindex]+1)&(NETBACKPACKETS-1));
609 }
610 }
611}
612
613short getpacket (short *otherconnectindex, char *bufptr)
614{
615 char toindex, bad, totbad;
616 short i, j=0, k, messleng, submessleng;
617
618 if (multioption <= 0) return(0);
619 if (multioption < 5)
620 {
621 *otherconnectindex = (myconnectindex^1);
622
623 bad = 0;
624 while (*inbufplc != *inbufend)
625 {
626 i = (short)inbuf[*inbufplc], *inbufplc = (((*inbufplc)+1)&(COMBUFSIZ-1));
627
628 if (i != ESC2)
629 {
630 if (i == ESC1) { comescape++; continue; }
631 if (comescape != 0)
632 {
633 comescape--;
634 if ((i < 128) && (*comresend == 0) && (((i-outcnt)&127) > 4))
635 {
636 *comresend = 2;
637 *outbufplc = outbufindex[i];
638 startcom();
639 continue;
640 }
641 if (syncbufleng < MAXIPXSIZ)
642 {
643 if (i == 128) { syncbuf[syncbufleng++] = ESC1; continue; }
644 if (i == 129) { syncbuf[syncbufleng++] = ESC2; continue; }
645 }
646 }
647 if (syncbufleng < MAXIPXSIZ) syncbuf[syncbufleng++] = i;
648 continue;
649 }
650
651 if (comescape != 0)
652 {
653 comescape = 0; comreset = 0; *comerror = 0;
654 syncbufleng = 0;
655 continue;
656 }
657
658 messleng = syncbufleng-3+(((comrateoption&15)==0)<<1);
659 if ((syncbuf[0]&127) != *incnt)
660 {
661 bad |= 1; //Packetcnt error
662 if ((*incnt == 1) && (syncbuf[1] == 254)) //Prevent 2 Masters!
663 myconnectindex = (myconnectnum<otherconnectnum);
664 }
665 if (((syncbuf[0]&128)>>7) != (messleng&1)) bad |= 2; //messleng error
666 for(i=0;i<messleng;i++) bufptr[i] = syncbuf[i+1];
667 if ((comrateoption&15) > 0)
668 {
669 i = getcrc(bufptr,messleng);
670 updatecrc16(i,syncbuf[0]);
671 if (((unsigned short)i) != ((long)syncbuf[syncbufleng-2])+((long)syncbuf[syncbufleng-1]<<8))
672 bad |= 2; //CRC error
673 }
674
675 syncbufleng = 0;
676 if (bad != 0)
677 {
678 //Don't send reset again if outbufplc is not before incnt!
679 if ((bad == 1) && ((((syncbuf[0]&127)-(*incnt))&127) >= 124))
680 {
681 bad = 0;
682 continue;
683 }
684
685 bad = 0;
686 if (comreset != 0) comreset--;
687 if (((*comerror)|comreset) == 0)
688 {
689 *comerror = 2; comreset = 2;
690 startcom();
691 }
692 continue;
693 }
694
695 *incnt = (((*incnt)+1)&127);
696 if ((messleng > 0) && (bufptr[0] >= 200)) //200-255 are messages for engine's use only
697 processreservedmessage(messleng,bufptr);
698
699 comescape = 0; comreset = 0; *comerror = 0;
700 return(messleng);
701 }
702 return(0);
703 }
704 else
705 {
706 if (*netinbufplc == *netinbufend) return(0);
707
708 messleng = (short)netinbuf[*netinbufplc] + (((short)netinbuf[((*netinbufplc)+1)&(COMBUFSIZ-1)])<<8);
709 for(i=0;i<messleng;i++)
710 getmess[i] = netinbuf[((*netinbufplc)+i+2)&(COMBUFSIZ-1)];
711
712 k = 0; *otherconnectindex = getmess[k++];
713
714 for(totbad=0;totbad<NETBACKPACKETS;totbad++) //Number of sub-packets per packet
715 {
716 toindex = getmess[k++];
717 if (toindex == 0xfe)
718 {
719 netincnt[*otherconnectindex] = 0; // (>= 200) && ( <= 254)
720 submessleng = messleng-2; // Submessleng not necessary
721 }
722 else
723 {
724 if (toindex == 0xff)
725 {
726 for(i=connecthead;i>=0;i=connectpoint2[i])
727 if (i != *otherconnectindex)
728 {
729 if (i == myconnectindex) j = getmess[k];
730 k++;
731 }
732 }
733 else
734 j = getmess[k++];
735
736 if (j != netincnt[*otherconnectindex])
737 {
738 submessleng = (short)getmess[k]+(((short)getmess[k+1])<<8);
739 k += submessleng+2;
740 continue;
741 }
742 netincnt[*otherconnectindex]++;
743
744 submessleng = (short)getmess[k]+(((short)getmess[k+1])<<8); k += 2;
745 }
746 for(i=0;i<submessleng;i++) bufptr[i] = getmess[k++];
747
748 if (totbad == 0)
749 {
750 //Increment inbufplc only if first sub-message is read
751 *netinbufplc = (((*netinbufplc)+messleng+2)&(COMBUFSIZ-1));
752 if ((submessleng > 0) && (bufptr[0] >= 200)) //200-255 are messages for engine's use only
753 {
754 if (bufptr[0] >= 253)
755 {
756 processreservedmessage(submessleng,bufptr);
757 if ((bufptr[0] == 253) || (bufptr[0] == 254)) return(0);
758 }
759 return(submessleng);
760 }
761 }
762 if (*otherconnectindex == myconnectindex) return(0);
763 return(submessleng); //Got good packet
764 }
765
766 syncstate++; //DON'T WANT TO GET HERE!!!
767 //Increment inbufplc to make it not continuously screw up!
768 *netinbufplc = (((*netinbufplc)+messleng+2)&(COMBUFSIZ-1));
769 }
770 return(0);
771}
772
773void initcrc(void)
774{
775 long i, j, k, a;
776
777 for(j=0;j<256;j++) //Calculate CRC table
778 {
779 k = (j<<8); a = 0;
780 for(i=7;i>=0;i--)
781 {
782 if (((k^a)&0x8000) > 0)
783 a = ((a<<1)&65535) ^ 0x1021; //0x1021 = genpoly
784 else
785 a = ((a<<1)&65535);
786 k = ((k<<1)&65535);
787 }
788 crctable[j] = (a&65535);
789 }
790}
791
792long getcrc(char *buffer, short bufleng)
793{
794 long i, j;
795
796 j = 0;
797 for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]);
798 return(j&65535);
799}
800
801void installbicomhandlers(void)
802{
Franklin Weia855d622017-01-21 15:18:31 -0500803 fprintf (stderr,"%s, line %d; installbicomhandlers() called\n",
804 __FILE__, __LINE__);
Franklin Weia855d622017-01-21 15:18:31 -0500805}
806
807void uninstallbicomhandlers(void)
808{
Franklin Weia855d622017-01-21 15:18:31 -0500809 fprintf (stderr, "%s line %d; uninstallbicomhandlers() called\n",
810 __FILE__, __LINE__);
Franklin Weia855d622017-01-21 15:18:31 -0500811}
812
813void processreservedmessage(short tempbufleng, char *datempbuf)
814{
815 long i, j, k, daotherconnectnum, templong;
816
817 switch(datempbuf[0])
818 {
819 //[253] (login, if myconnectnum's lowest, then respond with packet type 254)
820 case 253:
821 if (multioption < 5)
822 {
823 otherconnectnum = ((long)datempbuf[1])+(((long)datempbuf[2])<<8)+(((long)datempbuf[3])<<16)+(((long)datempbuf[4])<<24);
824
825 datempbuf[0] = 254;
826 sendpacket(-1,datempbuf,1);
827
828 myconnectindex = 0;
829 connecthead = 0; connectpoint2[0] = 1; connectpoint2[1] = -1;
830 numplayers = 2;
831 }
832 else if (multioption >= 5)
833 {
834 daotherconnectnum = ((long)datempbuf[1])+((long)(datempbuf[2]<<8))+((long)(datempbuf[3]<<16))+((long)(datempbuf[4]<<24));
835 if (daotherconnectnum != myconnectnum)
836 {
837 netinitconnection(daotherconnectnum,&datempbuf[5]);
838
839 if ((myconnectindex == connecthead) || ((connectnum[connecthead] == daotherconnectnum) && (myconnectindex == connectpoint2[connecthead])))
840 {
841 datempbuf[0] = 254;
842 j = 1;
843 for(i=0;i<MAXPLAYERS;i++)
844 if ((connectnum[i] != 0x7fffffff) && (connectnum[i] != daotherconnectnum))
845 {
846 datempbuf[j++] = (connectnum[i]&255);
847 datempbuf[j++] = ((connectnum[i]>>8)&255);
848 datempbuf[j++] = ((connectnum[i]>>16)&255);
849 datempbuf[j++] = ((connectnum[i]>>24)&255);
850
851 for(k=0;k<10;k++)
852 datempbuf[j++] = compaddr[i][k];
853 }
854
855 //While this doesn't have to be a broadcast, sending
856 //this info again makes good error correction
857 sendpacket(-1,datempbuf,j);
858
859 for(i=0;i<MAXPLAYERS;i++)
860 if (connectnum[i] == daotherconnectnum)
861 {
862 sendpacket((short)i,datempbuf,j);
863 break;
864 }
865 }
866 }
867 }
868 break;
869 case 254: //[254][connectnum][connectnum]...(Packet type 253 response)
870 if (multioption < 5)
871 {
872 myconnectindex = 1;
873 connecthead = 0; connectpoint2[0] = 1; connectpoint2[1] = -1;
874 numplayers = 2;
875 }
876 else if (multioption >= 5)
877 {
878 j = 1;
879 while (j < tempbufleng)
880 {
881 templong = ((long)datempbuf[j])+((long)(datempbuf[j+1]<<8))+((long)(datempbuf[j+2]<<16))+((long)(datempbuf[j+3]<<24));
882 netinitconnection(templong,&datempbuf[j+4]);
883 j += 14;
884 }
885 }
886 break;
887 case 255:
888 if (multioption >= 5)
889 netuninitconnection(datempbuf[1]);
890 break;
891 }
892}
893
894void sendlogon(void)
895{
896 long i;
897 char tempbuf[16];
898
899 if (multioption <= 0)
900 return;
901
902 tempbuf[0] = 253;
903 if (multioption < 5)
904 {
905 tempbuf[1] = kinp(0x40);
906 tempbuf[2] = kinp(0x40);
907 tempbuf[3] = kinp(0x40);
908 tempbuf[4] = mypriority;
909 myconnectnum = ((long)tempbuf[1])+(((long)tempbuf[2])<<8)+(((long)tempbuf[3])<<16)+(((long)mypriority)<<24);
910 sendpacket(-1,tempbuf,5);
911 }
912 else
913 {
914 tempbuf[1] = (myconnectnum&255);
915 tempbuf[2] = ((myconnectnum>>8)&255);
916 tempbuf[3] = ((myconnectnum>>16)&255);
917 tempbuf[4] = ((myconnectnum>>24)&255);
918 for(i=0;i<10;i++)
919 tempbuf[i+5] = mycompaddr[i];
920
921 sendpacket(-1,tempbuf,15);
922 }
923}
924
925void sendlogoff(void)
926{
927 char tempbuf[16];
928 long i;
929
930 if ((numplayers <= 1) || (multioption <= 0)) return;
931
932 tempbuf[0] = 255;
933 if (multioption < 5)
934 {
935 sendpacket(-1,tempbuf,1);
936 }
937 else
938 {
939 tempbuf[1] = myconnectindex;
940 for(i=connecthead;i>=0;i=connectpoint2[i])
941 if (i != myconnectindex)
942 sendpacket(i,tempbuf,2);
943 }
944}
945
946int getoutputcirclesize(void)
947{
948 if ((multioption >= 1) && (multioption <= 4))
949 {
950 startcom();
951 return(((*outbufend)-(*outbufplc)+COMBUFSIZ)&(COMBUFSIZ-1));
952 }
953 return(0);
954}
955
956int setsocket(short newsocket)
957{
958 long i;
959
960 if (multioption < 5)
961 {
962 socket = newsocket;
963 return(0);
964 }
965
966 simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
967
968 socket = newsocket;
969
970 simulateint(0x7a,0L,(long)0x1,0L,(long)socket,0L,0L); //Closesocket
971 if ((simulateint(0x7a,(long)0xff,0L,0L,(long)socket,0L,0L)&255) != 0) return(-2); //Opensocket
972 mycompaddr[10] = (socket&255);
973 mycompaddr[11] = (socket>>8);
974 ecbget[10] = (socket&255);
975 ecbget[11] = (socket>>8);
976 for(i=0;i<MAXPLAYERS;i++)
977 {
978 compaddr[i][10] = (socket&255);
979 compaddr[i][11] = (socket>>8);
980 }
981 return(0);
982}