doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

commit 77735c3ff0772609e9c8d29e3ce2ab42ff54d20b
parent 73424b6129f1c3ca9fc22aedcfe1f5330db137a9
Author: Travis Bradshaw <travis.bradshaw@idsoftware.com>
Date:   Tue, 31 Jan 2012 15:57:38 -0600

The source for the DOOM serial / model driver.

Diffstat:
Asersrc/DOOMNET.C | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asersrc/DOOMNET.H | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asersrc/PORT.C | 428+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asersrc/README.TXT | 1+
Asersrc/SERSETUP.C | 680+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asersrc/SERSETUP.H | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asersrc/SERSTR.H | 21+++++++++++++++++++++
Asersrc/SER_FRCH.H | 25+++++++++++++++++++++++++
8 files changed, 1443 insertions(+), 0 deletions(-)

diff --git a/sersrc/DOOMNET.C b/sersrc/DOOMNET.C @@ -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 @@ -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 @@ -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 @@ -0,0 +1 @@ +This is the source for the DOOM serial / modem driver. diff --git a/sersrc/SERSETUP.C b/sersrc/SERSETUP.C @@ -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 @@ -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 @@ -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 @@ -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‚rie, appuyez sur ESC pour annuler." +#define STR_NETABORT "Synchronisation de jeu sur r‚seau annul‚e." +#define STR_DUPLICATE "ChaŒne id en double. R‚essayez ou v‚rifiez la chaŒne d'initialistion du modem." +#define STR_MODEMCMD "Commande du modem: " +#define STR_MODEMRESP "R‚ponse du modem: " +#define STR_RESPABORT "R‚ponse du modem annul‚e." +#define STR_CANTREAD "Lecture de MODEM.CFG impossible" +#define STR_DIALING "Composition du num‚ro..." +#define STR_CONNECT "CONNECTION" +#define STR_WAITRING "Attente d'appel..." +#define STR_RING "APPEL" +#define STR_NORESP "Ce fichier de r‚ponse 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‚s entre 0x60 et 0x66.\n"\ +"Vous pouvez sp‚cifier un vecteur avec le paramŠtre -vector 0x<num‚ro>." +#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"