268 lines
5.5 KiB
C
268 lines
5.5 KiB
C
|
/*
|
||
|
Copyright (C) 1994-1995 Apogee Software, Ltd.
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
||
|
See the GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
|
||
|
*/
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <process.h>
|
||
|
#include <dos.h>
|
||
|
#include <conio.h>
|
||
|
#include "c:\merge\rottnet.h"
|
||
|
#include "global.h"
|
||
|
#if ROTTSER
|
||
|
#include "port.h"
|
||
|
#endif
|
||
|
|
||
|
rottcom_t rottcom;
|
||
|
int vectorishooked=0;
|
||
|
boolean pause;
|
||
|
void interrupt (*oldrottvect) (void);
|
||
|
static char * rottnet_stack;
|
||
|
static unsigned short rottnet_stacksegment;
|
||
|
static unsigned short rottnet_stackpointer;
|
||
|
static unsigned short old_stacksegment;
|
||
|
static unsigned short old_stackpointer;
|
||
|
|
||
|
#define ROTTNET_STACKSIZE (2048)
|
||
|
#define ROTTNET_SAFETYMARGIN (8)
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
=
|
||
|
= SetupROTTCOM
|
||
|
=
|
||
|
=============
|
||
|
*/
|
||
|
|
||
|
void SetupROTTCOM ( void )
|
||
|
{
|
||
|
unsigned char far *vectorptr;
|
||
|
long vector;
|
||
|
char * topofstack;
|
||
|
|
||
|
|
||
|
vector=GetVector();
|
||
|
|
||
|
/* Get an interrupt vector if not already set */
|
||
|
if (vector == -1)
|
||
|
{
|
||
|
for (vector = 0x60 ; vector <= 0x66 ; vector++)
|
||
|
{
|
||
|
vectorptr = *(unsigned char far * far *)(vector*4);
|
||
|
if ( !vectorptr || *vectorptr == 0xcf )
|
||
|
break;
|
||
|
}
|
||
|
if (vector == 0x67)
|
||
|
{
|
||
|
printf ("Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n"
|
||
|
"range. You can specify a vector with the -vector parameter\n"
|
||
|
"Press a key to continue...\n");
|
||
|
getch ();
|
||
|
printf ("Using default vector 0x66\n");
|
||
|
vector = 0x66;
|
||
|
}
|
||
|
}
|
||
|
rottcom.intnum = (short)vector;
|
||
|
|
||
|
// allocate the rottnet stack
|
||
|
|
||
|
rottnet_stack = malloc(ROTTNET_STACKSIZE);
|
||
|
if (!rottnet_stack)
|
||
|
Error("Could not allocate stack");
|
||
|
|
||
|
// Calculate top of stack
|
||
|
|
||
|
topofstack = rottnet_stack + ROTTNET_STACKSIZE - ROTTNET_SAFETYMARGIN;
|
||
|
|
||
|
// Determine stack segment and pointer
|
||
|
|
||
|
rottnet_stacksegment = FP_SEG( (char huge *)topofstack );
|
||
|
rottnet_stackpointer = FP_OFF( (char huge *)topofstack );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
=
|
||
|
= ShutdownROTTCOM
|
||
|
=
|
||
|
=============
|
||
|
*/
|
||
|
|
||
|
void ShutdownROTTCOM ( void )
|
||
|
{
|
||
|
if (vectorishooked)
|
||
|
setvect (rottcom.intnum,oldrottvect);
|
||
|
vectorishooked=0;
|
||
|
free ( rottnet_stack );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
=
|
||
|
= GetVector
|
||
|
=
|
||
|
=============
|
||
|
*/
|
||
|
|
||
|
long GetVector (void)
|
||
|
{
|
||
|
unsigned char far * vector;
|
||
|
long intnum;
|
||
|
|
||
|
|
||
|
if (CheckParm ("-vector"))
|
||
|
{
|
||
|
intnum = sscanf ("0x%x",_argv[CheckParm("-vector")+1]);
|
||
|
vector = *(unsigned char far * far *)(intnum*4);
|
||
|
if (vector != NULL && *vector != 0xcf)
|
||
|
Error("The specified vector (0x%02x) was already hooked.\n", intnum);
|
||
|
return intnum;
|
||
|
}
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
=
|
||
|
= ROTTNET_ISR
|
||
|
=
|
||
|
=============
|
||
|
*/
|
||
|
|
||
|
#define GetStack(a,b) \
|
||
|
{ \
|
||
|
*a = _SS; \
|
||
|
*b = _SP; \
|
||
|
}
|
||
|
#define SetStack(a,b) \
|
||
|
{ \
|
||
|
_SS=a; \
|
||
|
_SP=b; \
|
||
|
}
|
||
|
|
||
|
void interrupt ROTTNET_ISR (void)
|
||
|
{
|
||
|
//
|
||
|
// Get current stack
|
||
|
//
|
||
|
|
||
|
GetStack( &old_stacksegment, &old_stackpointer );
|
||
|
|
||
|
//
|
||
|
// Set the local stack
|
||
|
//
|
||
|
|
||
|
SetStack( rottnet_stacksegment, rottnet_stackpointer );
|
||
|
|
||
|
//
|
||
|
// call the interrupt service routine
|
||
|
//
|
||
|
|
||
|
NetISR();
|
||
|
|
||
|
//
|
||
|
// Restore the old stack
|
||
|
//
|
||
|
|
||
|
SetStack( old_stacksegment, old_stackpointer );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
=
|
||
|
= LaunchROTT
|
||
|
=
|
||
|
=============
|
||
|
*/
|
||
|
|
||
|
void LaunchROTT (void)
|
||
|
{
|
||
|
char *newargs[99];
|
||
|
char adrstring[10];
|
||
|
long flatadr;
|
||
|
int argnum = 1;
|
||
|
int i;
|
||
|
|
||
|
SetupROTTCOM ();
|
||
|
|
||
|
// prepare for ROTT
|
||
|
|
||
|
oldrottvect = getvect (rottcom.intnum);
|
||
|
setvect (rottcom.intnum,ROTTNET_ISR);
|
||
|
vectorishooked = 1;
|
||
|
|
||
|
// set ticstep
|
||
|
|
||
|
if (rottcom.gametype == 0) // modem game
|
||
|
{
|
||
|
rottcom.ticstep = 2; // skip every other tic
|
||
|
}
|
||
|
else // must be a network game
|
||
|
{
|
||
|
rottcom.ticstep = 1; // use every tic
|
||
|
}
|
||
|
|
||
|
// build the argument list for ROTT, adding "-net" and the address of rottcom.
|
||
|
|
||
|
for (i=1;i<_argc;i++)
|
||
|
newargs [argnum++] = _argv[i];
|
||
|
|
||
|
newargs [argnum++] = "now";
|
||
|
|
||
|
#if ROTTSER
|
||
|
if (Is8250())
|
||
|
newargs [argnum++] = "IS8250";
|
||
|
#endif
|
||
|
newargs [argnum++] = "-net";
|
||
|
|
||
|
/* Add address of rottcom structure */
|
||
|
|
||
|
flatadr = (long)_DS*16 + (unsigned)&rottcom;
|
||
|
sprintf (adrstring,"%lu",flatadr);
|
||
|
newargs [argnum++] = adrstring;
|
||
|
|
||
|
newargs [argnum] = NULL;
|
||
|
|
||
|
newargs [0] = ROTTLAUNCHER;
|
||
|
|
||
|
if (pause==true)
|
||
|
{
|
||
|
printf ("About to launch %s -- Passing these arguments:\n",ROTTLAUNCHER);
|
||
|
for (i = 0; i < argnum; i++)
|
||
|
printf (" arg %d = %s\n", i, newargs [i]);
|
||
|
printf (" player = %d\n", rottcom.consoleplayer);
|
||
|
|
||
|
printf ("\nPress ESC to abort, or any other key to continue...");
|
||
|
if (getch () == ESC)
|
||
|
{
|
||
|
printf ("\n\n");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
spawnv (P_WAIT, ROTTLAUNCHER, newargs);
|
||
|
printf ("\nReturned from ROTT\n\n");
|
||
|
|
||
|
ShutdownROTTCOM();
|
||
|
}
|