/* 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 #include #include #include #include #include #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(); }