SERSETUP.C 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. // sersetup.c
  2. #define DOOM2
  3. #include "sersetup.h"
  4. //#include "serstr.h"
  5. #include "ser_frch.h" // FRENCH VERSION
  6. #include "DoomNet.h"
  7. extern que_t inque, outque;
  8. void jump_start( void );
  9. extern int uart;
  10. int usemodem;
  11. char startup[256], shutdown[256], baudrate[256];
  12. extern int baudbits;
  13. void ModemCommand (char *str);
  14. int myargc;
  15. char **myargv;
  16. //======================================
  17. //
  18. // I_Error
  19. //
  20. //======================================
  21. void I_Error(char *string)
  22. {
  23. printf("%s\n",string);
  24. exit(1);
  25. }
  26. /*
  27. ================
  28. =
  29. = write_buffer
  30. =
  31. ================
  32. */
  33. void write_buffer( char *buffer, unsigned int count )
  34. {
  35. int i;
  36. // if this would overrun the buffer, throw everything else out
  37. if (outque.head-outque.tail+count > QUESIZE)
  38. outque.tail = outque.head;
  39. while (count--)
  40. write_byte (*buffer++);
  41. if ( INPUT( uart + LINE_STATUS_REGISTER ) & 0x40)
  42. jump_start();
  43. }
  44. /*
  45. =================
  46. =
  47. = Error
  48. =
  49. = For abnormal program terminations
  50. =
  51. =================
  52. */
  53. void Error (char *error, ...)
  54. {
  55. va_list argptr;
  56. if (usemodem)
  57. {
  58. printf ("\n");
  59. printf ("\n"STR_DROPDTR"\n");
  60. OUTPUT(uart+MODEM_CONTROL_REGISTER, INPUT(uart+MODEM_CONTROL_REGISTER)&~MCR_DTR);
  61. delay (1250);
  62. OUTPUT( uart + MODEM_CONTROL_REGISTER, INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR );
  63. ModemCommand("+++");
  64. delay (1250);
  65. ModemCommand(shutdown);
  66. delay (1250);
  67. }
  68. ShutdownPort ();
  69. if (vectorishooked)
  70. setvect (doomcom.intnum,olddoomvect);
  71. if (error)
  72. {
  73. va_start (argptr,error);
  74. vprintf (error,argptr);
  75. va_end (argptr);
  76. printf ("\n");
  77. exit (1);
  78. }
  79. printf (STR_CLEANEXIT"\n");
  80. exit (0);
  81. }
  82. /*
  83. ================
  84. =
  85. = ReadPacket
  86. =
  87. ================
  88. */
  89. #define MAXPACKET 512
  90. #define FRAMECHAR 0x70
  91. char packet[MAXPACKET];
  92. int packetlen;
  93. int inescape;
  94. int newpacket;
  95. boolean ReadPacket (void)
  96. {
  97. int c;
  98. // if the buffer has overflowed, throw everything out
  99. if (inque.head-inque.tail > QUESIZE - 4) // check for buffer overflow
  100. {
  101. inque.tail = inque.head;
  102. newpacket = true;
  103. return false;
  104. }
  105. if (newpacket)
  106. {
  107. packetlen = 0;
  108. newpacket = 0;
  109. }
  110. do
  111. {
  112. c = read_byte ();
  113. if (c < 0)
  114. return false; // haven't read a complete packet
  115. //printf ("%c",c);
  116. if (inescape)
  117. {
  118. inescape = false;
  119. if (c!=FRAMECHAR)
  120. {
  121. newpacket = 1;
  122. return true; // got a good packet
  123. }
  124. }
  125. else if (c==FRAMECHAR)
  126. {
  127. inescape = true;
  128. continue; // don't know yet if it is a terminator
  129. } // or a literal FRAMECHAR
  130. if (packetlen >= MAXPACKET)
  131. continue; // oversize packet
  132. packet[packetlen] = c;
  133. packetlen++;
  134. } while (1);
  135. }
  136. /*
  137. =============
  138. =
  139. = WritePacket
  140. =
  141. =============
  142. */
  143. void WritePacket (char *buffer, int len)
  144. {
  145. int b;
  146. char static localbuffer[MAXPACKET*2+2];
  147. b = 0;
  148. if (len > MAXPACKET)
  149. return;
  150. while (len--)
  151. {
  152. if (*buffer == FRAMECHAR)
  153. localbuffer[b++] = FRAMECHAR; // escape it for literal
  154. localbuffer[b++] = *buffer++;
  155. }
  156. localbuffer[b++] = FRAMECHAR;
  157. localbuffer[b++] = 0;
  158. write_buffer (localbuffer, b);
  159. }
  160. /*
  161. =============
  162. =
  163. = NetISR
  164. =
  165. =============
  166. */
  167. void interrupt NetISR (void)
  168. {
  169. if (doomcom.command == CMD_SEND)
  170. {
  171. //I_ColorBlack (0,0,63);
  172. WritePacket ((char *)&doomcom.data, doomcom.datalength);
  173. }
  174. else if (doomcom.command == CMD_GET)
  175. {
  176. //I_ColorBlack (63,63,0);
  177. if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
  178. {
  179. doomcom.remotenode = 1;
  180. doomcom.datalength = packetlen;
  181. memcpy (&doomcom.data, &packet, packetlen);
  182. }
  183. else
  184. doomcom.remotenode = -1;
  185. }
  186. //I_ColorBlack (0,0,0);
  187. }
  188. /*
  189. =================
  190. =
  191. = Connect
  192. =
  193. = Figures out who is player 0 and 1
  194. =================
  195. */
  196. void Connect (void)
  197. {
  198. struct time time;
  199. int oldsec;
  200. int localstage, remotestage;
  201. char str[20];
  202. char idstr[7];
  203. char remoteidstr[7];
  204. unsigned long idnum;
  205. int i;
  206. //
  207. // wait for a good packet
  208. //
  209. printf (STR_ATTEMPT"\n");
  210. //
  211. // build a (hopefully) unique id string by hashing up the current milliseconds
  212. // and the interrupt table
  213. //
  214. if (CheckParm ("-player1"))
  215. idnum = 0;
  216. else if (CheckParm ("-player2"))
  217. idnum = 999999;
  218. else
  219. {
  220. gettime (&time);
  221. idnum = time.ti_sec*100+time.ti_hund;
  222. for (i=0 ; i<512 ; i++)
  223. idnum += ((unsigned far *)0)[i];
  224. idnum %= 1000000;
  225. }
  226. idstr[0] = '0' + idnum/ 100000l;
  227. idnum -= (idstr[0]-'0')*100000l;
  228. idstr[1] = '0' + idnum/ 10000l;
  229. idnum -= (idstr[1]-'0')*10000l;
  230. idstr[2] = '0' + idnum/ 1000l;
  231. idnum -= (idstr[2]-'0')*1000l;
  232. idstr[3] = '0' + idnum/ 100l;
  233. idnum -= (idstr[3]-'0')*100l;
  234. idstr[4] = '0' + idnum/ 10l;
  235. idnum -= (idstr[4]-'0')*10l;
  236. idstr[5] = '0' + idnum;
  237. idstr[6] = 0;
  238. //
  239. // sit in a loop until things are worked out
  240. //
  241. // the packet is: ID000000_0
  242. // the first field is the idnum, the second is the acknowledge stage
  243. // ack stage starts out 0, is bumped to 1 after the other computer's id
  244. // is known, and is bumped to 2 after the other computer has raised to 1
  245. //
  246. oldsec = -1;
  247. localstage = remotestage = 0;
  248. do
  249. {
  250. while ( bioskey(1) )
  251. {
  252. if ( (bioskey (0) & 0xff) == 27)
  253. Error ("\n\n"STR_NETABORT);
  254. }
  255. if (ReadPacket ())
  256. {
  257. packet[packetlen] = 0;
  258. printf ("read : %s\n",packet);
  259. if (packetlen != 10)
  260. continue;
  261. if (strncmp(packet,"ID",2) )
  262. continue;
  263. if (!strncmp (packet+2,idstr,6))
  264. Error ("\n\n"STR_DUPLICATE);
  265. strncpy (remoteidstr,packet+2,6);
  266. remotestage = packet[9] - '0';
  267. localstage = remotestage+1;
  268. oldsec = -1;
  269. }
  270. gettime (&time);
  271. if (time.ti_sec != oldsec)
  272. {
  273. oldsec = time.ti_sec;
  274. sprintf (str,"ID%s_%i",idstr,localstage);
  275. WritePacket (str,strlen(str));
  276. printf ("wrote: %s\n",str);
  277. }
  278. } while (localstage < 2);
  279. //
  280. // decide who is who
  281. //
  282. if (strcmp(remoteidstr,idstr) > 0)
  283. doomcom.consoleplayer = 0;
  284. else
  285. doomcom.consoleplayer = 1;
  286. //
  287. // flush out any extras
  288. //
  289. while (ReadPacket ())
  290. ;
  291. }
  292. /*
  293. ==============
  294. =
  295. = ModemCommand
  296. =
  297. ==============
  298. */
  299. void ModemCommand (char *str)
  300. {
  301. int i,l;
  302. printf (STR_MODEMCMD,str);
  303. l = strlen(str);
  304. for (i=0 ; i<l ; i++)
  305. {
  306. write_buffer (str+i,1);
  307. printf ("%c",str[i]);
  308. delay (100);
  309. }
  310. write_buffer ("\r",1);
  311. printf ("\n");
  312. }
  313. /*
  314. ==============
  315. =
  316. = ModemResponse
  317. =
  318. = Waits for OK, RING, CONNECT, etc
  319. ==============
  320. */
  321. char response[80];
  322. void ModemResponse (char *resp)
  323. {
  324. int c;
  325. int respptr;
  326. do
  327. {
  328. printf (STR_MODEMRESP);
  329. respptr=0;
  330. do
  331. {
  332. while ( bioskey(1) )
  333. {
  334. if ( (bioskey (0) & 0xff) == 27)
  335. Error ("\n"STR_RESPABORT);
  336. }
  337. c = read_byte ();
  338. if (c==-1)
  339. continue;
  340. if (c=='\n' || respptr == 79)
  341. {
  342. response[respptr] = 0;
  343. printf ("%s\n",response);
  344. break;
  345. }
  346. if (c>=' ')
  347. {
  348. response[respptr] = c;
  349. respptr++;
  350. }
  351. } while (1);
  352. } while (strncmp(response,resp,strlen(resp)));
  353. }
  354. /*
  355. =============
  356. =
  357. = ReadLine
  358. =
  359. =============
  360. */
  361. void ReadLine (FILE *f, char *dest)
  362. {
  363. int c;
  364. do
  365. {
  366. c = fgetc (f);
  367. if (c == EOF || c == '\r' || c == '\n')
  368. break;
  369. *dest++ = c;
  370. } while (1);
  371. *dest = 0;
  372. }
  373. /*
  374. =============
  375. =
  376. = ReadModemCfg
  377. =
  378. =============
  379. */
  380. void ReadModemCfg (void)
  381. {
  382. int mcr;
  383. FILE *f;
  384. unsigned baud;
  385. f = fopen ("modem.cfg","r");
  386. if (!f)
  387. Error (STR_CANTREAD);
  388. ReadLine (f, startup);
  389. ReadLine (f, shutdown);
  390. ReadLine (f, baudrate);
  391. fclose (f);
  392. baud = atol(baudrate);
  393. if (baud)
  394. baudbits = 115200l/baud;
  395. usemodem = true;
  396. }
  397. /*
  398. =============
  399. =
  400. = Dial
  401. =
  402. =============
  403. */
  404. void Dial (void)
  405. {
  406. char cmd[80];
  407. int p;
  408. ModemCommand(startup);
  409. ModemResponse ("OK");
  410. printf ("\n"STR_DIALING"\n\n");
  411. p = CheckParm ("-dial");
  412. sprintf (cmd,"ATDT%s",myargv[p+1]);
  413. ModemCommand(cmd);
  414. ModemResponse (STR_CONNECT);
  415. doomcom.consoleplayer = 1;
  416. }
  417. /*
  418. =============
  419. =
  420. = Answer
  421. =
  422. =============
  423. */
  424. void Answer (void)
  425. {
  426. ModemCommand(startup);
  427. ModemResponse ("OK");
  428. printf ("\n"STR_WAITRING"\n\n");
  429. ModemResponse (STR_RING);
  430. ModemCommand ("ATA");
  431. ModemResponse (STR_CONNECT);
  432. doomcom.consoleplayer = 0;
  433. }
  434. //========================================================
  435. //
  436. // Find a Response File
  437. //
  438. //========================================================
  439. void FindResponseFile (void)
  440. {
  441. int i;
  442. #define MAXARGVS 100
  443. for (i = 1;i < myargc;i++)
  444. if (myargv[i][0] == '@')
  445. {
  446. FILE * handle;
  447. int size;
  448. int k;
  449. int index;
  450. int indexinfile;
  451. char *infile;
  452. char *file;
  453. char *moreargs[20];
  454. char *firstargv;
  455. // READ THE RESPONSE FILE INTO MEMORY
  456. handle = fopen (&myargv[i][1],"rb");
  457. if (!handle)
  458. I_Error (STR_NORESP);
  459. printf("Found response file \"%s\"!\n",strupr(&myargv[i][1]));
  460. fseek (handle,0,SEEK_END);
  461. size = ftell(handle);
  462. fseek (handle,0,SEEK_SET);
  463. file = malloc (size);
  464. fread (file,size,1,handle);
  465. fclose (handle);
  466. // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
  467. for (index = 0,k = i+1; k < myargc; k++)
  468. moreargs[index++] = myargv[k];
  469. firstargv = myargv[0];
  470. myargv = malloc(sizeof(char *)*MAXARGVS);
  471. memset(myargv,0,sizeof(char *)*MAXARGVS);
  472. myargv[0] = firstargv;
  473. infile = file;
  474. indexinfile = k = 0;
  475. indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
  476. do
  477. {
  478. myargv[indexinfile++] = infile+k;
  479. while(k < size &&
  480. ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
  481. k++;
  482. *(infile+k) = 0;
  483. while(k < size &&
  484. ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
  485. k++;
  486. } while(k < size);
  487. for (k = 0;k < index;k++)
  488. myargv[indexinfile++] = moreargs[k];
  489. myargc = indexinfile;
  490. // DISPLAY ARGS
  491. // printf("%d command-line args:\n",myargc);
  492. // for (k=1;k<myargc;k++)
  493. // printf("%s\n",myargv[k]);
  494. break;
  495. }
  496. }
  497. /*
  498. =================
  499. =
  500. = main
  501. =
  502. =================
  503. */
  504. void main(void)
  505. {
  506. int p;
  507. //
  508. // set network characteristics
  509. //
  510. doomcom.ticdup = 1;
  511. doomcom.extratics = 0;
  512. doomcom.numnodes = 2;
  513. doomcom.numplayers = 2;
  514. doomcom.drone = 0;
  515. printf("\n"
  516. "---------------------------------\n"
  517. #ifdef DOOM2
  518. STR_DOOMSERIAL"\n"
  519. #else
  520. "DOOM SERIAL DEVICE DRIVER v1.4\n"
  521. #endif
  522. "---------------------------------\n");
  523. myargc = _argc;
  524. myargv = _argv;
  525. FindResponseFile();
  526. //
  527. // allow override of automatic player ordering to allow a slower computer
  528. // to be set as player 1 allways
  529. //
  530. //
  531. // establish communications
  532. //
  533. baudbits = 0x08; // default to 9600 if not specified on cmd line
  534. // or in modem.cfg
  535. if (CheckParm ("-dial") || CheckParm ("-answer") )
  536. ReadModemCfg (); // may set baudbits
  537. //
  538. // allow command-line override of modem.cfg baud rate
  539. //
  540. if (CheckParm ("-9600")) baudbits = 0x0c;
  541. else if (CheckParm ("-14400")) baudbits = 0x08;
  542. else if (CheckParm ("-19200")) baudbits = 0x06;
  543. else if (CheckParm ("-38400")) baudbits = 0x03;
  544. else if (CheckParm ("-57600")) baudbits = 0x02;
  545. else if (CheckParm ("-115200")) baudbits = 0x01;
  546. InitPort ();
  547. if (CheckParm ("-dial"))
  548. Dial ();
  549. else if (CheckParm ("-answer"))
  550. Answer ();
  551. Connect ();
  552. //
  553. // launch DOOM
  554. //
  555. LaunchDOOM ();
  556. Error (NULL);
  557. }