The source for the DOOM serial / model driver. master
authorTravis Bradshaw <travis.bradshaw@idsoftware.com>
Tue, 31 Jan 2012 21:57:38 +0000 (15:57 -0600)
committerTravis Bradshaw <travis.bradshaw@idsoftware.com>
Tue, 31 Jan 2012 21:57:38 +0000 (15:57 -0600)
sersrc/DOOMNET.C [new file with mode: 0644]
sersrc/DOOMNET.H [new file with mode: 0644]
sersrc/PORT.C [new file with mode: 0644]
sersrc/README.TXT [new file with mode: 0644]
sersrc/SERSETUP.C [new file with mode: 0644]
sersrc/SERSETUP.H [new file with mode: 0644]
sersrc/SERSTR.H [new file with mode: 0644]
sersrc/SER_FRCH.H [new file with mode: 0644]

diff --git a/sersrc/DOOMNET.C b/sersrc/DOOMNET.C
new file mode 100644 (file)
index 0000000..c027ec7
--- /dev/null
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <io.h>
+#include <stdlib.h>
+#include <string.h>
+#include <process.h>
+#include <dos.h>
+#include "doomnet.h"
+
+//#include "serstr.h"
+#include "ser_frch.h"          // FRENCH VERSION
+
+#define DOOM2
+
+extern int     myargc;
+extern char **myargv;
+
+doomcom_t      doomcom;
+int                    vectorishooked;
+void interrupt (*olddoomvect) (void);
+
+
+
+/*
+=================
+=
+= CheckParm
+=
+= Checks for the given parameter in the program's command line arguments
+=
+= Returns the argument number (1 to argc-1) or 0 if not present
+=
+=================
+*/
+
+int CheckParm (char *check)
+{
+       int             i;
+
+       for (i = 1;i<myargc;i++)
+               if ( !stricmp(check,myargv[i]) )
+                       return i;
+
+       return 0;
+}
+
+
+/*
+=============
+=
+= LaunchDOOM
+=
+These fields in doomcom should be filled in before calling:
+
+       short   numnodes;               // console is allways node 0
+       short   ticdup;                 // 1 = no duplication, 2-5 = dup for slow nets
+       short   extratics;              // 1 = send a backup tic in every packet
+
+       short   consoleplayer;  // 0-3 = player number
+       short   numplayers;             // 1-4
+       short   angleoffset;    // 1 = left, 0 = center, -1 = right
+       short   drone;                  // 1 = drone
+=============
+*/
+
+void LaunchDOOM (void)
+{
+       char    *newargs[99];
+       char    adrstring[10];
+       long    flatadr;
+       int             p;
+       unsigned char   far     *vector;
+
+// prepare for DOOM
+       doomcom.id = DOOMCOM_ID;
+
+// hook an interrupt vector
+       p= CheckParm ("-vector");
+
+       if (p)
+       {
+               doomcom.intnum = sscanf ("0x%x",_argv[p+1]);
+       }
+       else
+       {
+               for (doomcom.intnum = 0x60 ; doomcom.intnum <= 0x66 ; doomcom.intnum++)
+               {
+                       vector = *(char far * far *)(doomcom.intnum*4);
+                       if ( !vector || *vector == 0xcf )
+                               break;
+               }
+               if (doomcom.intnum == 0x67)
+               {
+                       printf (STR_WARNING);
+                       doomcom.intnum = 0x66;
+               }
+       }
+       printf (STR_COMM"\n",doomcom.intnum);
+
+       olddoomvect = getvect (doomcom.intnum);
+       setvect (doomcom.intnum,NetISR);
+       vectorishooked = 1;
+
+// build the argument list for DOOM, adding a -net &doomcom
+       memcpy (newargs, myargv, (myargc+1)*2);
+       newargs[myargc] = "-net";
+       flatadr = (long)_DS*16 + (unsigned)&doomcom;
+       sprintf (adrstring,"%lu",flatadr);
+       newargs[myargc+1] = adrstring;
+       newargs[myargc+2] = NULL;
+
+//     spawnv  (P_WAIT, "m:\\newdoom\\doom", newargs);
+       if (!access("doom2.exe",0))
+               spawnv  (P_WAIT, "doom2", newargs);
+       else
+               spawnv  (P_WAIT, "doom", newargs);
+
+       #ifdef DOOM2
+       printf (STR_RETURNED"\n");
+       #else
+       printf ("Returned from DOOM\n");
+       #endif
+
+
+}
+
+
diff --git a/sersrc/DOOMNET.H b/sersrc/DOOMNET.H
new file mode 100644 (file)
index 0000000..06007e6
--- /dev/null
@@ -0,0 +1,60 @@
+// doomnet.h
+
+
+#define PEL_WRITE_ADR   0x3c8
+#define PEL_DATA        0x3c9
+
+#define I_ColorBlack(r,g,b) {outp(PEL_WRITE_ADR,0);outp(PEL_DATA,r);outp(PEL_DATA,g);outp(PEL_DATA,b);};
+
+
+
+
+#define        MAXNETNODES             8                       // max computers in a game
+#define        MAXPLAYERS              4                       // 4 players max + drones
+
+
+#define        CMD_SEND        1
+#define        CMD_GET         2
+
+#define        DOOMCOM_ID              0x12345678l
+
+typedef struct
+{
+       long    id;
+       short   intnum;                 // DOOM executes an int to send commands
+
+// communication between DOOM and the driver
+       short   command;                // CMD_SEND or CMD_GET
+       short   remotenode;             // dest for send, set by get (-1 = no packet)
+       short   datalength;             // bytes in doomdata to be sent / bytes read
+
+// info common to all nodes
+       short   numnodes;               // console is allways node 0
+       short   ticdup;                 // 1 = no duplication, 2-5 = dup for slow nets
+       short   extratics;              // 1 = send a backup tic in every packet
+       short   deathmatch;             // 1 = deathmatch
+       short   savegame;               // -1 = new game, 0-5 = load savegame
+       short   episode;                // 1-3
+       short   map;                    // 1-9
+       short   skill;                  // 1-5
+
+// info specific to this node
+       short   consoleplayer;  // 0-3 = player number
+       short   numplayers;             // 1-4
+       short   angleoffset;    // 1 = left, 0 = center, -1 = right
+       short   drone;                  // 1 = drone
+
+// packet data to be sent
+       char    data[512];
+} doomcom_t;
+
+
+
+extern doomcom_t       doomcom;
+extern void interrupt (*olddoomvect) (void);
+extern int                     vectorishooked;
+
+int CheckParm (char *check);
+void LaunchDOOM (void);
+void interrupt NetISR (void);
+
diff --git a/sersrc/PORT.C b/sersrc/PORT.C
new file mode 100644 (file)
index 0000000..d9eb036
--- /dev/null
@@ -0,0 +1,428 @@
+// port.c
+
+#include "doomnet.h"
+#include "sersetup.h"
+//#include "serstr.h"
+#include "ser_frch.h"          // FRENCH VERSION
+
+
+void jump_start( void );
+
+void interrupt isr_8250 (void);
+void interrupt isr_16550 (void);
+
+union  REGS    regs;
+struct SREGS   sregs;
+
+que_t          inque, outque;
+
+
+int                    uart;                   // io address
+enum {UART_8250, UART_16550} uart_type;
+int                    irq;
+
+int                    modem_status = -1;
+int                    line_status = -1;
+
+void interrupt (*oldirqvect) (void);
+int                    irqintnum;
+
+int                    comport;
+
+int                    baudbits;
+
+
+/*
+==============
+=
+= GetUart
+=
+==============
+*/
+
+void GetUart (void)
+{
+       char   far *system_data;
+       static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
+       static int ISA_IRQs[] = {4,3,4,3};
+       static int MCA_uarts[] = {0x03f8,0x02f8,0x3220,0x3228};
+       static int MCA_IRQs[] = {4,3,3,3};
+       int             p;
+
+       if (CheckParm ("-com2"))
+               comport = 2;
+       else if (CheckParm ("-com3"))
+               comport = 3;
+       else if (CheckParm ("-com4"))
+               comport = 4;
+       else
+               comport = 1;
+
+       regs.h.ah = 0xc0;
+       int86x( 0x15, &regs, &regs, &sregs );
+       if ( regs.x.cflag )
+       {
+               irq = ISA_IRQs[ comport-1 ];
+               uart = ISA_uarts[ comport-1 ];
+               return;
+       }
+       system_data = ( char far *) ( ( (long) sregs.es << 16 ) + regs.x.bx );
+       if ( system_data[ 5 ] & 0x02 )
+       {
+               irq = MCA_IRQs[ comport-1 ];
+               uart = MCA_uarts[ comport-1 ];
+       }
+       else
+       {
+               irq = ISA_IRQs[ comport-1 ];
+               uart = ISA_uarts[ comport-1 ];
+       }
+
+       p = CheckParm ("-port");
+       if (p)
+               sscanf (_argv[p+1],"0x%x",&uart);
+       p = CheckParm ("-irq");
+       if (p)
+               sscanf (_argv[p+1],"%i",&irq);
+
+
+       printf (STR_PORTLOOK" 0x%x, irq %i\n",uart,irq);
+}
+
+
+
+
+/*
+===============
+=
+= InitPort
+=
+===============
+*/
+
+void InitPort (void)
+{
+       int mcr;
+       int     temp;
+       int     u;
+
+//
+// find the irq and io address of the port
+//
+       GetUart ();
+
+//
+// disable all uart interrupts
+//
+       OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
+
+//
+// init com port settings
+//
+
+       printf (STR_PORTSET"\n",115200l/baudbits);
+
+// set baud rate
+       OUTPUT(uart + LINE_CONTROL_REGISTER, 0x83);
+       OUTPUT(uart, baudbits);
+       OUTPUT(uart + 1, 0);
+
+// set line control register (N81)
+       OUTPUT(uart + LINE_CONTROL_REGISTER, 0x03);
+
+// set modem control register (OUT2+RTS+DTR)
+       OUTPUT( uart + MODEM_CONTROL_REGISTER,8+2+1);
+
+//
+// check for a 16550
+//
+       if (CheckParm("-8250"))
+       // allow a forced 8250
+       {
+               uart_type = UART_8250;
+               printf (STR_UART8250"\n\n");
+       }
+       else
+       {       
+               OUTPUT ( uart + FIFO_CONTROL_REGISTER,
+                       FCR_FIFO_ENABLE + FCR_TRIGGER_04 );
+               temp = INPUT( uart + INTERRUPT_ID_REGISTER );
+               if ( ( temp & 0xf8 ) == 0xc0 )
+               {
+                       uart_type = UART_16550;
+               }
+               else
+               {
+                       uart_type = UART_8250;
+                       OUTPUT( uart + FIFO_CONTROL_REGISTER, 0 );
+               }
+       }
+
+//
+// clear out any pending uart events
+//
+       printf (STR_CLEARPEND);
+       for (u=0 ; u<16 ; u++)          // clear an entire 16550 silo
+               INPUT( uart + RECEIVE_BUFFER_REGISTER );
+
+       do
+       {
+               switch( u = INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
+               {
+               case IIR_MODEM_STATUS_INTERRUPT :
+                       modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
+                       break;
+
+               case IIR_LINE_STATUS_INTERRUPT :
+                       line_status = INPUT( uart + LINE_STATUS_REGISTER );
+                       break;
+
+               case IIR_TX_HOLDING_REGISTER_INTERRUPT :
+                       break;
+
+               case IIR_RX_DATA_READY_INTERRUPT :
+                       INPUT( uart + RECEIVE_BUFFER_REGISTER );
+                       break;
+               }
+       } while (! (u&1) );
+
+
+//
+// hook the irq vector
+//
+       irqintnum = irq + 8;
+
+       oldirqvect = getvect (irqintnum);
+       if (uart_type == UART_16550)
+       {
+               setvect (irqintnum,isr_16550);
+               printf (STR_UART16550"\n\n");
+       }
+       else
+       {
+               setvect (irqintnum,isr_8250);
+               printf (STR_UART8250"\n\n");
+
+       }
+
+
+       OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) & ~(1<<irq) );
+
+       CLI();
+
+// enable RX and TX interrupts at the uart
+
+       OUTPUT( uart + INTERRUPT_ENABLE_REGISTER,IER_RX_DATA_READY + IER_TX_HOLDING_REGISTER_EMPTY);
+
+// enable interrupts through the interrupt controller
+
+       OUTPUT( 0x20, 0xc2 );
+
+       STI();
+}
+
+
+/*
+=============
+=
+= ShutdownPort
+=
+=============
+*/
+
+void ShutdownPort ( void )
+{
+       int             u;
+       
+       OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
+       OUTPUT( uart + MODEM_CONTROL_REGISTER, 0 );
+
+       for (u=0 ; u<16 ; u++)          // clear an entire 16550 silo
+               INPUT( uart + RECEIVE_BUFFER_REGISTER );
+
+       OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) | (1<<irq) );
+
+       setvect (irqintnum,oldirqvect);
+
+//
+// init com port settings to defaults
+//
+       regs.x.ax = 0xf3;               //f3= 9600 n 8 1
+       regs.x.dx = comport - 1;
+       int86 (0x14, &regs, &regs);
+}
+
+
+int read_byte( void )
+{
+       int     c;
+
+       if (inque.tail >= inque.head)
+               return -1;
+       c = inque.data[inque.tail&(QUESIZE-1)];
+       inque.tail++;
+       return c;
+}
+
+
+void write_byte( int c )
+{
+       outque.data[outque.head&(QUESIZE-1)] = c;
+       outque.head++;
+}
+
+
+
+//==========================================================================
+
+
+/*
+==============
+=
+= isr_8250
+=
+==============
+*/
+
+void interrupt isr_8250(void)
+{
+       int c;
+
+       while (1)
+       {
+               switch( INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
+               {
+// not enabled
+               case IIR_MODEM_STATUS_INTERRUPT :
+                       modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
+                       break;
+
+// not enabled
+               case IIR_LINE_STATUS_INTERRUPT :
+                       line_status = INPUT( uart + LINE_STATUS_REGISTER );
+                       break;
+
+//
+// transmit
+//
+               case IIR_TX_HOLDING_REGISTER_INTERRUPT :
+//I_ColorBlack (63,0,0);
+                       if (outque.tail < outque.head)
+                       {
+                               c = outque.data[outque.tail&(QUESIZE-1)];
+                               outque.tail++;
+                               OUTPUT( uart + TRANSMIT_HOLDING_REGISTER, c );
+                       }
+                       break;
+
+//
+// receive
+//
+               case IIR_RX_DATA_READY_INTERRUPT :
+//I_ColorBlack (0,63,0);
+                       c = INPUT( uart + RECEIVE_BUFFER_REGISTER );
+                       inque.data[inque.head&(QUESIZE-1)] = c;
+                       inque.head++;
+                       break;
+
+//
+// done
+//
+               default :
+//I_ColorBlack (0,0,0);
+                       OUTPUT( 0x20, 0x20 );
+                       return;
+               }
+       }
+}
+
+
+/*
+==============
+=
+= isr_16550
+=
+==============
+*/
+
+void interrupt isr_16550(void)
+{
+       int c;
+       int     count;
+
+       while (1)
+       {
+               switch( INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
+               {
+// not enabled
+               case IIR_MODEM_STATUS_INTERRUPT :
+                       modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
+                       break;
+
+// not enabled
+               case IIR_LINE_STATUS_INTERRUPT :
+                       line_status = INPUT( uart + LINE_STATUS_REGISTER );
+                       break;
+
+//
+// transmit
+//
+               case IIR_TX_HOLDING_REGISTER_INTERRUPT :
+//I_ColorBlack (63,0,0);
+                       count = 16;
+                       while (outque.tail < outque.head && count--)
+                       {
+                               c = outque.data[outque.tail&(QUESIZE-1)];
+                               outque.tail++;
+                               OUTPUT( uart + TRANSMIT_HOLDING_REGISTER, c );
+                       }
+                       break;
+
+//
+// receive
+//
+               case IIR_RX_DATA_READY_INTERRUPT :
+//I_ColorBlack (0,63,0);
+                       do
+                       {
+                               c = INPUT( uart + RECEIVE_BUFFER_REGISTER );
+                               inque.data[inque.head&(QUESIZE-1)] = c;
+                               inque.head++;
+                       } while (INPUT( uart + LINE_STATUS_REGISTER ) & LSR_DATA_READY );
+
+                       break;
+
+//
+// done
+//
+               default :
+//I_ColorBlack (0,0,0);
+                       OUTPUT( 0x20, 0x20 );
+                       return;
+               }
+       }
+}
+
+
+/*
+===============
+=
+= jump_start
+=
+= Start up the transmition interrupts by sending the first char
+===============
+*/
+
+void jump_start( void )
+{
+       int c;
+
+       if (outque.tail < outque.head)
+       {
+               c = outque.data [outque.tail&(QUESIZE-1)];
+               outque.tail++;
+               OUTPUT( uart, c );
+       }
+}
+
+
diff --git a/sersrc/README.TXT b/sersrc/README.TXT
new file mode 100644 (file)
index 0000000..94ce053
--- /dev/null
@@ -0,0 +1 @@
+This is the source for the DOOM serial / modem driver.
diff --git a/sersrc/SERSETUP.C b/sersrc/SERSETUP.C
new file mode 100644 (file)
index 0000000..eeee006
--- /dev/null
@@ -0,0 +1,680 @@
+// sersetup.c
+#define DOOM2
+#include "sersetup.h"
+//#include "serstr.h"
+#include "ser_frch.h"          // FRENCH VERSION
+#include "DoomNet.h"
+
+extern que_t           inque, outque;
+
+void jump_start( void );
+extern int     uart;
+
+int                    usemodem;
+char           startup[256], shutdown[256], baudrate[256];
+
+extern         int baudbits;
+
+void ModemCommand (char *str);
+
+int            myargc;
+char   **myargv;
+
+//======================================
+//
+// I_Error
+//
+//======================================
+void I_Error(char *string)
+{
+       printf("%s\n",string);
+       exit(1);
+}
+
+/*
+================
+=
+= write_buffer
+=
+================
+*/
+
+void write_buffer( char *buffer, unsigned int count )
+{
+       int     i;
+
+// if this would overrun the buffer, throw everything else out
+       if (outque.head-outque.tail+count > QUESIZE)
+               outque.tail = outque.head;
+
+       while (count--)
+               write_byte (*buffer++);
+
+       if ( INPUT( uart + LINE_STATUS_REGISTER ) & 0x40)
+               jump_start();
+}
+
+
+/*
+=================
+=
+= Error
+=
+= For abnormal program terminations
+=
+=================
+*/
+
+void Error (char *error, ...)
+{
+       va_list argptr;
+
+       if (usemodem)
+       {
+               printf ("\n");
+               printf ("\n"STR_DROPDTR"\n");
+
+               OUTPUT(uart+MODEM_CONTROL_REGISTER, INPUT(uart+MODEM_CONTROL_REGISTER)&~MCR_DTR);
+               delay (1250);
+               OUTPUT( uart + MODEM_CONTROL_REGISTER, INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR );
+               ModemCommand("+++");
+               delay (1250);
+               ModemCommand(shutdown);
+               delay (1250);
+
+       }
+
+       ShutdownPort ();
+
+       if (vectorishooked)
+               setvect (doomcom.intnum,olddoomvect);
+
+       if (error)
+       {
+               va_start (argptr,error);
+               vprintf (error,argptr);
+               va_end (argptr);
+               printf ("\n");
+               exit (1);
+       }
+
+       printf (STR_CLEANEXIT"\n");
+       exit (0);
+}
+
+
+/*
+================
+=
+= ReadPacket
+=
+================
+*/
+
+#define MAXPACKET      512
+#define        FRAMECHAR       0x70
+
+char   packet[MAXPACKET];
+int            packetlen;
+int            inescape;
+int            newpacket;
+
+boolean ReadPacket (void)
+{
+       int     c;
+
+// if the buffer has overflowed, throw everything out
+
+       if (inque.head-inque.tail > QUESIZE - 4)        // check for buffer overflow
+       {
+               inque.tail = inque.head;
+               newpacket = true;
+               return false;
+       }
+
+       if (newpacket)
+       {
+               packetlen = 0;
+               newpacket = 0;
+       }
+
+       do
+       {
+               c = read_byte ();
+               if (c < 0)
+                       return false;           // haven't read a complete packet
+//printf ("%c",c);
+               if (inescape)
+               {
+                       inescape = false;
+                       if (c!=FRAMECHAR)
+                       {
+                               newpacket = 1;
+                               return true;    // got a good packet
+                       }
+               }
+               else if (c==FRAMECHAR)
+               {
+                       inescape = true;
+                       continue;                       // don't know yet if it is a terminator
+               }                                               // or a literal FRAMECHAR
+
+               if (packetlen >= MAXPACKET)
+                       continue;                       // oversize packet
+               packet[packetlen] = c;
+               packetlen++;
+       } while (1);
+
+}
+
+
+/*
+=============
+=
+= WritePacket
+=
+=============
+*/
+
+
+
+void WritePacket (char *buffer, int len)
+{
+       int             b;
+       char    static localbuffer[MAXPACKET*2+2];
+
+       b = 0;
+       if (len > MAXPACKET)
+               return;
+
+       while (len--)
+       {
+               if (*buffer == FRAMECHAR)
+                       localbuffer[b++] = FRAMECHAR;   // escape it for literal
+               localbuffer[b++] = *buffer++;
+       }
+
+       localbuffer[b++] = FRAMECHAR;
+       localbuffer[b++] = 0;
+
+       write_buffer (localbuffer, b);
+}
+
+
+/*
+=============
+=
+= NetISR
+=
+=============
+*/
+
+void interrupt NetISR (void)
+{
+       if (doomcom.command == CMD_SEND)
+       {
+//I_ColorBlack (0,0,63);
+               WritePacket ((char *)&doomcom.data, doomcom.datalength);
+       }
+       else if (doomcom.command == CMD_GET)
+       {
+//I_ColorBlack (63,63,0);
+
+               if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
+               {
+                       doomcom.remotenode = 1;
+                       doomcom.datalength = packetlen;
+                       memcpy (&doomcom.data, &packet, packetlen);
+               }
+               else
+                       doomcom.remotenode = -1;
+
+       }
+//I_ColorBlack (0,0,0);
+}
+
+
+
+
+/*
+=================
+=
+= Connect
+=
+= Figures out who is player 0 and 1
+=================
+*/
+
+void Connect (void)
+{
+       struct time     time;
+       int                     oldsec;
+       int                     localstage, remotestage;
+       char            str[20];
+       char            idstr[7];
+       char            remoteidstr[7];
+       unsigned long           idnum;
+       int                     i;
+       
+//
+// wait for a good packet
+//
+       printf (STR_ATTEMPT"\n");
+
+//
+// build a (hopefully) unique id string by hashing up the current milliseconds
+// and the interrupt table
+//
+       if (CheckParm ("-player1"))
+               idnum = 0;
+       else if (CheckParm ("-player2"))
+               idnum = 999999;
+       else
+       {
+               gettime (&time);
+               idnum = time.ti_sec*100+time.ti_hund;
+               for (i=0 ; i<512 ; i++)
+                       idnum += ((unsigned far *)0)[i];
+               idnum %= 1000000;
+       }
+       
+       idstr[0] = '0' + idnum/ 100000l;
+       idnum -= (idstr[0]-'0')*100000l;
+       idstr[1] = '0' + idnum/ 10000l;
+       idnum -= (idstr[1]-'0')*10000l;
+       idstr[2] = '0' + idnum/ 1000l;
+       idnum -= (idstr[2]-'0')*1000l;
+       idstr[3] = '0' + idnum/ 100l;
+       idnum -= (idstr[3]-'0')*100l;
+       idstr[4] = '0' + idnum/ 10l;
+       idnum -= (idstr[4]-'0')*10l;
+       idstr[5] = '0' + idnum;
+       idstr[6] = 0;
+       
+//
+// sit in a loop until things are worked out
+//
+// the packet is:  ID000000_0
+// the first field is the idnum, the second is the acknowledge stage
+// ack stage starts out 0, is bumped to 1 after the other computer's id
+// is known, and is bumped to 2 after the other computer has raised to 1
+//
+       oldsec = -1;
+       localstage = remotestage = 0;
+
+       do
+       {
+               while ( bioskey(1) )
+               {
+                       if ( (bioskey (0) & 0xff) == 27)
+                               Error ("\n\n"STR_NETABORT);
+               }
+
+               if (ReadPacket ())
+               {
+                       packet[packetlen] = 0;
+                       printf ("read : %s\n",packet);
+                       if (packetlen != 10)
+                               continue;
+                       if (strncmp(packet,"ID",2) )
+                               continue;
+                       if (!strncmp (packet+2,idstr,6))
+                               Error ("\n\n"STR_DUPLICATE);
+                       strncpy (remoteidstr,packet+2,6);
+                               
+                       remotestage = packet[9] - '0';
+                       localstage = remotestage+1;
+                       oldsec = -1;
+               }
+
+               gettime (&time);
+               if (time.ti_sec != oldsec)
+               {
+                       oldsec = time.ti_sec;
+                       sprintf (str,"ID%s_%i",idstr,localstage);
+                       WritePacket (str,strlen(str));
+                       printf ("wrote: %s\n",str);
+               }
+
+       } while (localstage < 2);
+
+//
+// decide who is who
+//
+       if (strcmp(remoteidstr,idstr) > 0)
+               doomcom.consoleplayer = 0;
+       else
+               doomcom.consoleplayer = 1;
+       
+
+//
+// flush out any extras
+//
+       while (ReadPacket ())
+       ;
+}
+
+
+
+/*
+==============
+=
+= ModemCommand
+=
+==============
+*/
+
+void ModemCommand (char *str)
+{
+       int             i,l;
+       
+       printf (STR_MODEMCMD,str);
+       l = strlen(str);
+       for (i=0 ; i<l ; i++)
+       {
+               write_buffer (str+i,1);
+               printf ("%c",str[i]);
+               delay (100);
+       }
+
+       write_buffer ("\r",1);
+       printf ("\n");
+}
+
+
+/*
+==============
+=
+= ModemResponse
+=
+= Waits for OK, RING, CONNECT, etc
+==============
+*/
+
+char   response[80];
+
+void ModemResponse (char *resp)
+{
+       int             c;
+       int             respptr;
+
+       do
+       {
+               printf (STR_MODEMRESP);
+               respptr=0;
+               do
+               {
+                       while ( bioskey(1) )
+                       {
+                               if ( (bioskey (0) & 0xff) == 27)
+                                       Error ("\n"STR_RESPABORT);
+                       }
+                       c = read_byte ();
+                       if (c==-1)
+                               continue;
+                       if (c=='\n' || respptr == 79)
+                       {
+                               response[respptr] = 0;
+                               printf ("%s\n",response);
+                               break;
+                       }
+                       if (c>=' ')
+                       {
+                               response[respptr] = c;
+                               respptr++;
+                       }
+               } while (1);
+
+       } while (strncmp(response,resp,strlen(resp)));
+}
+
+
+/*
+=============
+=
+= ReadLine
+=
+=============
+*/
+
+void ReadLine (FILE *f, char *dest)
+{
+       int     c;
+
+       do
+       {
+               c = fgetc (f);
+               if (c == EOF || c == '\r' || c == '\n')
+                       break;
+               *dest++ = c;
+       } while (1);
+       *dest = 0;
+}
+
+
+/*
+=============
+=
+= ReadModemCfg
+=
+=============
+*/
+
+void ReadModemCfg (void)
+{
+       int             mcr;
+       FILE    *f;
+       unsigned        baud;
+
+       f = fopen ("modem.cfg","r");
+       if (!f)
+               Error (STR_CANTREAD);
+       ReadLine (f, startup);
+       ReadLine (f, shutdown);
+       ReadLine (f, baudrate);
+       fclose (f);
+
+       baud = atol(baudrate);
+       if (baud)
+               baudbits = 115200l/baud;
+
+       usemodem = true;
+}
+
+
+/*
+=============
+=
+= Dial
+=
+=============
+*/
+
+void Dial (void)
+{
+       char    cmd[80];
+       int             p;
+
+       ModemCommand(startup);
+       ModemResponse ("OK");
+
+       printf ("\n"STR_DIALING"\n\n");
+       p = CheckParm ("-dial");
+       sprintf (cmd,"ATDT%s",myargv[p+1]);
+
+       ModemCommand(cmd);
+       ModemResponse (STR_CONNECT);
+       doomcom.consoleplayer = 1;
+}
+
+
+/*
+=============
+=
+= Answer
+=
+=============
+*/
+
+void Answer (void)
+{
+       ModemCommand(startup);
+       ModemResponse ("OK");
+       printf ("\n"STR_WAITRING"\n\n");
+
+       ModemResponse (STR_RING);
+       ModemCommand ("ATA");
+       ModemResponse (STR_CONNECT);
+
+       doomcom.consoleplayer = 0;
+}
+
+//========================================================
+//
+//     Find a Response File
+//
+//========================================================
+void FindResponseFile (void)
+{
+       int             i;
+       #define MAXARGVS        100
+
+       for (i = 1;i < myargc;i++)
+               if (myargv[i][0] == '@')
+               {
+                       FILE *          handle;
+                       int             size;
+                       int             k;
+                       int             index;
+                       int             indexinfile;
+                       char    *infile;
+                       char    *file;
+                       char    *moreargs[20];
+                       char    *firstargv;
+
+                       // READ THE RESPONSE FILE INTO MEMORY
+                       handle = fopen (&myargv[i][1],"rb");
+                       if (!handle)
+                               I_Error (STR_NORESP);
+                       printf("Found response file \"%s\"!\n",strupr(&myargv[i][1]));
+                       fseek (handle,0,SEEK_END);
+                       size = ftell(handle);
+                       fseek (handle,0,SEEK_SET);
+                       file = malloc (size);
+                       fread (file,size,1,handle);
+                       fclose (handle);
+
+                       // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
+                       for (index = 0,k = i+1; k < myargc; k++)
+                               moreargs[index++] = myargv[k];
+
+                       firstargv = myargv[0];
+                       myargv = malloc(sizeof(char *)*MAXARGVS);
+                       memset(myargv,0,sizeof(char *)*MAXARGVS);
+                       myargv[0] = firstargv;
+
+                       infile = file;
+                       indexinfile = k = 0;
+                       indexinfile++;  // SKIP PAST ARGV[0] (KEEP IT)
+                       do
+                       {
+                               myargv[indexinfile++] = infile+k;
+                               while(k < size &&
+                                       ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
+                                       k++;
+                               *(infile+k) = 0;
+                               while(k < size &&
+                                       ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
+                                       k++;
+                       } while(k < size);
+
+                       for (k = 0;k < index;k++)
+                               myargv[indexinfile++] = moreargs[k];
+                       myargc = indexinfile;
+
+                       // DISPLAY ARGS
+//                     printf("%d command-line args:\n",myargc);
+//                     for (k=1;k<myargc;k++)
+//                             printf("%s\n",myargv[k]);
+
+                       break;
+               }
+}
+
+
+
+/*
+=================
+=
+= main
+=
+=================
+*/
+
+void main(void)
+{
+       int                             p;
+
+//
+// set network characteristics
+//
+       doomcom.ticdup = 1;
+       doomcom.extratics = 0;
+       doomcom.numnodes = 2;
+       doomcom.numplayers = 2;
+       doomcom.drone = 0;
+
+       printf("\n"
+                  "---------------------------------\n"
+                  #ifdef DOOM2
+                  STR_DOOMSERIAL"\n"
+                  #else
+                  "DOOM SERIAL DEVICE DRIVER v1.4\n"
+                  #endif
+                  "---------------------------------\n");
+       myargc = _argc;
+       myargv = _argv;
+       FindResponseFile();
+
+//
+// allow override of automatic player ordering to allow a slower computer
+// to be set as player 1 allways
+//
+
+//
+// establish communications
+//
+
+       baudbits = 0x08;                // default to 9600 if not specified on cmd line
+                                                       // or in modem.cfg
+
+       if (CheckParm ("-dial") || CheckParm ("-answer") )
+               ReadModemCfg ();                // may set baudbits
+
+//
+// allow command-line override of modem.cfg baud rate
+//
+       if (CheckParm ("-9600")) baudbits = 0x0c;
+       else if (CheckParm ("-14400")) baudbits = 0x08;
+       else if (CheckParm ("-19200")) baudbits = 0x06;
+       else if (CheckParm ("-38400")) baudbits = 0x03;
+       else if (CheckParm ("-57600")) baudbits = 0x02;
+       else if (CheckParm ("-115200")) baudbits = 0x01;
+
+       InitPort ();
+
+       if (CheckParm ("-dial"))
+               Dial ();
+       else if (CheckParm ("-answer"))
+               Answer ();
+
+       Connect ();
+
+//
+// launch DOOM
+//
+       LaunchDOOM ();
+
+       Error (NULL);
+}
+
diff --git a/sersrc/SERSETUP.H b/sersrc/SERSETUP.H
new file mode 100644 (file)
index 0000000..7bb8f5e
--- /dev/null
@@ -0,0 +1,102 @@
+#include <conio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <conio.h>
+#include <ctype.h>
+#include <dos.h>
+#include <process.h>
+#include <stdarg.h>
+#include <bios.h>
+#include <ctype.h>
+
+
+#define INPUT(port)            inportb(port)
+#define OUTPUT(port,data)      outportb(port,data)
+#define CLI()               disable()
+#define STI()               enable()
+
+
+typedef enum {false, true} boolean;
+typedef unsigned char byte;
+
+
+#define TRANSMIT_HOLDING_REGISTER            0x00
+#define RECEIVE_BUFFER_REGISTER              0x00
+#define INTERRUPT_ENABLE_REGISTER            0x01
+#define   IER_RX_DATA_READY                  0x01
+#define   IER_TX_HOLDING_REGISTER_EMPTY      0x02
+#define   IER_LINE_STATUS                    0x04
+#define   IER_MODEM_STATUS                   0x08
+#define INTERRUPT_ID_REGISTER                0x02
+#define   IIR_MODEM_STATUS_INTERRUPT         0x00
+#define   IIR_TX_HOLDING_REGISTER_INTERRUPT  0x02
+#define   IIR_RX_DATA_READY_INTERRUPT        0x04
+#define   IIR_LINE_STATUS_INTERRUPT          0x06
+#define FIFO_CONTROL_REGISTER                0x02
+#define   FCR_FIFO_ENABLE                    0x01
+#define   FCR_RCVR_FIFO_RESET                0x02
+#define   FCR_XMIT_FIFO_RESET                0x04
+#define   FCR_RCVR_TRIGGER_LSB               0x40
+#define   FCR_RCVR_TRIGGER_MSB               0x80
+#define   FCR_TRIGGER_01                     0x00
+#define   FCR_TRIGGER_04                     0x40
+#define   FCR_TRIGGER_08                     0x80
+#define   FCR_TRIGGER_14                     0xc0
+#define LINE_CONTROL_REGISTER                0x03
+#define   LCR_WORD_LENGTH_MASK               0x03
+#define   LCR_WORD_LENGTH_SELECT_0           0x01
+#define   LCR_WORD_LENGTH_SELECT_1           0x02
+#define   LCR_STOP_BITS                      0x04
+#define   LCR_PARITY_MASK                    0x38
+#define   LCR_PARITY_ENABLE                  0x08
+#define   LCR_EVEN_PARITY_SELECT             0x10
+#define   LCR_STICK_PARITY                   0x20
+#define   LCR_SET_BREAK                      0x40
+#define   LCR_DLAB                           0x80
+#define MODEM_CONTROL_REGISTER               0x04
+#define   MCR_DTR                            0x01
+#define   MCR_RTS                            0x02
+#define   MCR_OUT1                           0x04
+#define   MCR_OUT2                           0x08
+#define   MCR_LOOPBACK                       0x10
+#define LINE_STATUS_REGISTER                 0x05
+#define   LSR_DATA_READY                     0x01
+#define   LSR_OVERRUN_ERROR                  0x02
+#define   LSR_PARITY_ERROR                   0x04
+#define   LSR_FRAMING_ERROR                  0x08
+#define   LSR_BREAK_DETECT                   0x10
+#define   LSR_THRE                           0x20
+#define MODEM_STATUS_REGISTER                0x06
+#define   MSR_DELTA_CTS                      0x01
+#define   MSR_DELTA_DSR                      0x02
+#define   MSR_TERI                           0x04
+#define   MSR_DELTA_CD                       0x08
+#define   MSR_CTS                            0x10
+#define   MSR_DSR                            0x20
+#define   MSR_RI                             0x40
+#define   MSR_CD                             0x80
+#define DIVISOR_LATCH_LOW                    0x00
+#define DIVISOR_LATCH_HIGH                   0x01
+
+
+
+#define        QUESIZE 2048
+
+typedef struct
+{
+       long    head, tail;             // bytes are put on head and pulled from tail
+       unsigned char   data[QUESIZE];
+} que_t;
+
+void InitPort (void);
+void ShutdownPort (void);
+
+int read_byte( void );
+void write_byte( int c );
+
+
+void Error (char *error, ...);
+
+extern int             argc;
+extern char    **argv;
diff --git a/sersrc/SERSTR.H b/sersrc/SERSTR.H
new file mode 100644 (file)
index 0000000..39ce5dc
--- /dev/null
@@ -0,0 +1,21 @@
+#define STR_DROPDTR            "Dropping DTR"
+#define STR_CLEANEXIT  "Clean exit from SERSETUP"
+#define STR_ATTEMPT            "Attempting to connect across serial link, press escape to abort."
+#define STR_NETABORT   "Network game synchronization aborted."
+#define STR_DUPLICATE  "Duplicate id string, try again or check modem init string."
+#define STR_MODEMCMD   "Modem command : "
+#define STR_MODEMRESP  "Modem response: "
+#define STR_RESPABORT  "Modem response aborted."
+#define STR_CANTREAD   "Couldn't read MODEM.CFG"
+#define STR_DIALING            "Dialing..."
+#define STR_CONNECT            "CONNECT"
+#define STR_WAITRING   "Waiting for ring..."
+#define STR_RING               "RING"
+#define STR_NORESP             "No such response file!"
+#define STR_DOOMSERIAL "DOOM II SERIAL DEVICE DRIVER v1.4"
+#define STR_WARNING \
+"Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n"\
+"range.  You can specify a vector with the -vector 0x<num> parameter.\n"
+#define STR_COMM               "Communicating with interrupt vector 0x%x"
+#define STR_RETURNED   "Returned from DOOM II"
+#define STR_PORTSET            "Setting port to %lu baud"
diff --git a/sersrc/SER_FRCH.H b/sersrc/SER_FRCH.H
new file mode 100644 (file)
index 0000000..f265058
--- /dev/null
@@ -0,0 +1,25 @@
+#define STR_DROPDTR            "Abandon de DTR"
+#define STR_CLEANEXIT  "Sortie normale de SERSETUP"
+#define STR_ATTEMPT            "Tentative de connexion en s\82rie, appuyez sur ESC pour annuler."
+#define STR_NETABORT   "Synchronisation de jeu sur r\82seau annul\82e."
+#define STR_DUPLICATE  "Cha\8cne id en double. R\82essayez ou v\82rifiez la cha\8cne d'initialistion du modem."
+#define STR_MODEMCMD   "Commande du modem: "
+#define STR_MODEMRESP  "R\82ponse du modem: "
+#define STR_RESPABORT  "R\82ponse du modem annul\82e."
+#define STR_CANTREAD   "Lecture de MODEM.CFG impossible"
+#define STR_DIALING            "Composition du num\82ro..."
+#define STR_CONNECT            "CONNECTION"
+#define STR_WAITRING   "Attente d'appel..."
+#define STR_RING               "APPEL"
+#define STR_NORESP             "Ce fichier de r\82ponse n'existe pas!"
+#define STR_DOOMSERIAL "GESTIONNAIRE DE LIAISON SERIE DOOM II v1.4"
+#define STR_WARNING \
+"Attention: pas de vecteurs d'interruption NULL ou iret trouv\82s entre 0x60 et 0x66.\n"\
+"Vous pouvez sp\82cifier un vecteur avec le param\8atre -vector 0x<num\82ro>."
+#define STR_COMM               "Communication avec le vecteur d'interruption 0x%x"
+#define STR_RETURNED   "Retour de DOOM II"
+#define STR_PORTLOOK   "Recherche de l'UART sur le port"
+#define STR_UART8250   "UART = 8250"
+#define STR_UART16550  "UART = 16550"
+#define STR_CLEARPEND  "Riinitilisation des interruptions en attente.\n"
+#define STR_PORTSET            "Réglage du port à %lu baud"