home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Doom I/II Collection
/
DM12.ISO
/
serial
/
serial28
/
source.exe
/
SERSETUP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-08
|
12KB
|
676 lines
// sersetup.c
#include "sersetup.h"
#include "DoomNet.h"
extern que_t inque, outque;
void jump_start( void );
extern int uart;
int usemodem;
char startup[256], shutdown[256], baudrate[256], hardhand[256], extirq[256], extport[256],extractics[256];
unsigned char bauddivl, usehardhand;
int useextirq, useextport, useextractics;
extern int accessMCR;
extern int accessLSR;
extern long intRX;
extern long intTX;
void ModemCommand (char *str);
/*
================
=
= 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--)
{
outque.data[outque.head&(QUESIZE-1)]=*buffer++;
outque.head++;
}
if ( INPUT(accessLSR) & 0x40)
jump_start();
}
/*
=================
=
= Error
=
= For abnormal program terminations
=
=================
*/
void Error (char *error, ...)
{
va_list argptr;
if (usemodem)
{
printf ("\n");
printf ("\nDropping DTR\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 );
delay (250);
ModemCommand("+++");
delay (1250);
ModemCommand("AT");
delay (250);
ModemCommand("AT");
delay (250);
ModemCommand(shutdown);
delay (1250);
}
ShutdownPort ();
if (vectorishooked)
{
printf("Vector is hooked\n");
setvect (doomcom.intnum,olddoomvect);
}
printf("Diagnostic Data:\n");
printf("TX Interrupts: %ld\n",intTX);
printf("TX Characters: %ld\n",outque.tail);
printf("TX FIFO utilization: %ld%%\n",intTX*100/(outque.tail+1));
printf("RX Interrupts: %ld\n",intRX);
printf("RX Characters: %ld\n",inque.tail);
printf("RX FIFO utilization: %ld%%\n",intRX*100/(inque.head+1));
if (error)
{
va_start (argptr,error);
vprintf (error,argptr);
va_end (argptr);
printf ("\n");
exit (1);
}
printf ("Clean exit from SERSETUP\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
{
if(inque.tail>=inque.head) return false;
c=inque.data[inque.tail&(QUESIZE-1)];
inque.tail++;
if ((inque.head-inque.tail)<(QUESIZE/2))
OUTPUT( accessMCR,INPUT(accessMCR) | MCR_RTS);
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)
{
if (len > MAXPACKET)
return;
if (outque.head-outque.tail+len+len>QUESIZE)
outque.tail=outque.head;
while (len--)
{
if (*buffer == FRAMECHAR)
{
outque.data[outque.head&(QUESIZE-1)]=FRAMECHAR;
outque.head++;
}
outque.data[outque.head&(QUESIZE-1)]=*buffer++;
outque.head++;
}
outque.data[outque.head&(QUESIZE-1)]=FRAMECHAR;
outque.head++;
outque.data[outque.head&(QUESIZE-1)]=0;
outque.head++;
if ( INPUT( accessLSR ) & 0x40)
jump_start();
}
/*
=============
=
= NetISR
=
=============
*/
void interrupt NetISR (void)
{
if (doomcom.command == CMD_SEND)
{
WritePacket ((char *)&doomcom.data, doomcom.datalength);
}
else if (doomcom.command == CMD_GET)
{
if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
{
doomcom.remotenode = 1;
doomcom.datalength = packetlen;
memcpy (&doomcom.data, &packet, packetlen);
}
else
doomcom.remotenode = -1;
}
}
/*
=================
=
= Connect
=
= Figures out who is player 0 and 1
=================
*/
void Connect (void)
{
struct time time;
int oldsec;
int localstage, remotestage;
char str[20];
//
// wait for a good packet
//
printf ("Attempting to connect across serial link, press escape to abort.\n");
oldsec = -1;
localstage = remotestage = 0;
do
{
while ( bioskey(1) )
{
if ( (bioskey (0) & 0xff) == 27)
Error ("\n\nNetwork game synchronization aborted.");
}
while (ReadPacket ())
{
packet[packetlen] = 0;
// printf ("read: %s\n",packet);
if (packetlen != 7)
goto badpacket;
if (strncmp(packet,"PLAY",4) )
goto badpacket;
remotestage = packet[6] - '0';
localstage = remotestage+1;
if (packet[4] == '0'+doomcom.consoleplayer)
{
doomcom.consoleplayer ^= 1;
localstage = remotestage = 0;
}
oldsec = -1;
}
badpacket:
gettime (&time);
if (time.ti_sec != oldsec)
{
oldsec = time.ti_sec;
sprintf (str,"PLAY%i_%i",doomcom.consoleplayer,localstage);
WritePacket (str,strlen(str));
// printf ("wrote: %s\n",str);
}
} while (remotestage < 1);
//
// flush out any extras
//
while (ReadPacket ())
;
}
/*
==============
=
= ModemCommand
=
==============
*/
void ModemCommand (char *str)
{
int len;
printf ("Modem command : %s\n",str);
for(len=0;len<strlen(str); len++)
{
delay(20);
write_buffer(str+len,1);
}
delay(20);
write_buffer ("\r",1);
}
/*
==============
=
= ModemResponse
=
= Waits for OK, RING, CONNECT, etc
==============
*/
char response[80];
void ModemResponse (char *resp)
{
int c;
int respptr;
do
{
printf ("Modem response: ");
respptr=0;
do
{
while ( bioskey(1) )
{
if ( (bioskey (0) & 0xff) == 27)
Error ("\nModem response aborted.");
}
c = read_byte ();
if (c==-1)
continue;
// printf("<%c>",c);
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)
Error ("EOF in modem.cfg");
if (c == '\r' || c == '\n')
break;
*dest++ = c;
} while (1);
*dest = 0;
}
/*
=============
=
= SnagBaud
=
=============
*/
void SnagBaud (void)
{
int mcr;
FILE *f;
unsigned long baudtouse;
unsigned long bauddiv;
f = fopen ("modem.cfg","r");
if (!f)
Error ("Couldn't read MODEM.CFG");
ReadLine (f, startup);
ReadLine (f, shutdown);
ReadLine (f, baudrate);
ReadLine (f, hardhand);
ReadLine (f, extirq);
ReadLine (f, extport);
ReadLine (f, extractics);
fclose (f);
sscanf(baudrate,"%ld",&baudtouse);
if (hardhand[0]=='0') usehardhand=0; else usehardhand=1;
if ((baudtouse!=9600)&&
(baudtouse!=19200)&&
(baudtouse!=38400)&&
(baudtouse!=57600)&&
(baudtouse!=115200)) baudtouse=9600;
bauddiv=1843200/(16*baudtouse);
bauddivl=(unsigned char)(bauddiv%0x0F);
printf("Using %ld baud to modem. BaudDivisorL=%u\n",baudtouse,bauddivl);
if (usehardhand)
printf("Using hardware handshaking.\n");
else
printf("Not using hardware handshaking.\n");
sscanf(extirq,"%d",&useextirq);
if (!((useextirq>=2)&&(useextirq<=15)))
useextirq=0;
if (useextirq)
printf("Using irq: %x from modem.cfg file.\n");
sscanf(extport,"%x",&useextport);
if (useextport==0) sscanf(extport,"%X",&useextport);
if (useextport)
printf("Using port: 0x%x from modem.cfg file.\n");
sscanf(extractics,"%d",&useextractics);
if ((useextractics>1)||(useextractics<0)) useextractics=0;
printf("Using extractics: %d\n",useextractics);
}
void DTR_Flash(void)
{
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 );
delay (250);
}
/*
=============
=
= InitModem
=
=============
*/
void InitModem (void)
{
int mcr;
FILE *f;
int temp;
f = fopen ("modem.cfg","r");
if (!f)
Error ("Couldn't read MODEM.CFG");
ReadLine (f, startup);
ReadLine (f, shutdown);
fclose (f);
do
temp=read_byte(); //clear any junk in the buffer.
while (temp!=-1);
DTR_Flash();
ModemCommand("AT");
delay(250);
ModemCommand("AT");
delay(250);
ModemCommand(startup);
ModemResponse ("OK");
delay(500);
ModemCommand("AT");
delay(250);
ModemCommand("AT");
delay(450);
}
/*
=============
=
= Dial
=
=============
*/
void Dial (void)
{
char cmd[80];
int p;
usemodem = true;
InitModem ();
printf ("\nDialing...\n\n");
p = CheckParm ("-dial");
sprintf (cmd,"ATDT%s",_argv[p+1]);
ModemCommand(cmd);
ModemResponse ("CONNECT");
//if (strncmp (response+8,"9600",4) )
// Error ("The connection MUST be made at 9600 baud, no error correction, no compression!\n"
// "Check your modem initialization string!");
doomcom.consoleplayer = 1;
}
/*
=============
=
= Answer
=
=============
*/
void Answer (void)
{
usemodem = true;
InitModem ();
printf ("\nWaiting for ring...\n\n");
ModemResponse ("RING");
ModemCommand ("ATA");
ModemResponse ("CONNECT");
doomcom.consoleplayer = 0;
}
/*
=================
=
= main
=
=================
*/
void main(void)
{
int p;
//
// set network characteristics
//
doomcom.ticdup = 1;
doomcom.extratics = (short) useextractics; //changed from 0
doomcom.numnodes = 2;
doomcom.numplayers = 2;
doomcom.drone = 0;
printf("\n"
"---------------------------------\n"
"WORKING DOOM SERIAL DEVICE DRIVER\n"
"---------------------------------\n"
"\n"
"Mods by: Tony da Costa, U.B.C. Electrical Engineers\n"
"Mods: Arbitrary baud, hardware handshaking, arbitrary irq\n"
"Mods date: March 7, 1994\n"
"Mods rev: 2.8\n\n"
"Baudrate must be third parameter in modem.cfg\n"
"Hardware handshaking must be fourth parameter in modem.cfg,1=on, 0=off\n"
"Irq must be fifth parameter in modem.cfg (0=use default)\n"
"Port address must be sixth parameter in modem.cfg (0=use doom defaults)\n\n"
"This has been tested to 57600 on a USR Sportster 14,400 FAX MODEM,\n"
"using a 16550.\n\n"
);
//
// allow override of automatic player ordering to allow a slower computer
// to be set as player 1 allways
//
if (CheckParm ("-player1"))
doomcom.consoleplayer = 1;
else
doomcom.consoleplayer = 0;
//
// establish communications
//
SnagBaud ();
InitPort ();
if (CheckParm ("-dial"))
Dial ();
else if (CheckParm ("-answer"))
Answer ();
Connect ();
//
// launch DOOM
//
LaunchDOOM ();
#if 0
{
union REGS regs;
delay (1000);
doomcom.command = CMD_SEND;
doomcom.datalength = 12;
memcpy (doomcom.data,"abcdefghijklmnop",12);
int86 (doomcom.intnum, ®s, ®s);
delay (1000);
doomcom.command = CMD_GET;
doomcom.datalength = 0;
int86 (doomcom.intnum, ®s, ®s);
printf ("datalength: %i\n",doomcom.datalength);
delay (1000);
doomcom.command = CMD_SEND;
doomcom.datalength = 12;
memcpy (doomcom.data,"abcdefghijklmnop",12);
int86 (doomcom.intnum, ®s, ®s);
delay (1000);
doomcom.command = CMD_GET;
doomcom.datalength = 0;
int86 (doomcom.intnum, ®s, ®s);
printf ("datalength: %i\n",doomcom.datalength);
}
#endif
Error (NULL);
}