CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

NULLMGR.CPP (96616B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /counterstrike/NULLMGR.CPP 2     3/07/97 6:40p Steve_tall $ */
     17 /***************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***************************************************************************
     20  *                                                                         *
     21  *                 Project Name : Command & Conquer                        *
     22  *                                                                         *
     23  *                    File Name : NULLMGR.CPP                              *
     24  *                                                                         *
     25  *                   Programmer : Bill Randolph                            *
     26  *                                                                         *
     27  *                   Start Date : April 5, 1995       	 						*
     28  *                                                                         *
     29  *                  Last Update : May 1, 1995 [BRR]                        *
     30  *                                                                         *
     31  *-------------------------------------------------------------------------*
     32  * Functions:    			                                                   *
     33  *   NullModemClass::NullModemClass -- class constructor                   *
     34  *   NullModemClass::~NullModemClass -- class destructor                   *
     35  *   NullModemClass::Init -- initialization											*
     36  *   NullModemClass::Send_Message -- sends a message								*
     37  *   NullModemClass::Get_Message -- polls the Queue for a message				*
     38  *   NullModemClass::Service -- main polling routine								*
     39  *   NullModemClass::Num_Send -- Returns # of unACK'd send entries			*
     40  *   NullModemClass::Num_Receive -- Returns # entries in the receive queue *
     41  *   NullModemClass::Response_Time -- Returns Queue's avg response time    *
     42  *   NullModemClass::Reset_Response_Time -- Resets response time computatio*
     43  *   NullModemClass::Oldest_Send -- Returns ptr to oldest unACK'd send buf *
     44  *   NullModemClass::Detect_Modem -- Detects and initializes the modem     *
     45  *   NullModemClass::Dial_Modem -- dials a number passed                   *
     46  *   NullModemClass::Answer_Modem -- waits for call and answers            *
     47  *   NullModemClass::Hangup_Modem -- hangs up the modem                    *
     48  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     49 #if (0)//PG
     50 #include "function.h"
     51 #ifdef WIN32
     52 #include "wincomm.h"
     53 #include "modemreg.h"
     54 extern ModemRegistryEntryClass *ModemRegistry;
     55 #endif	//WIN32
     56 #include "i86.h"
     57 
     58 
     59 // Turn off "expression is not meaningful".
     60 #pragma warning 628 9
     61 
     62 
     63 // the following line was taken from Greenleaf's <ibmkeys.h> <asciidef.h>
     64 // because of other define conflicts
     65 
     66 #define ESC		         27
     67 #define NOKEY           0xffff
     68 #define INIT_COMMAND_RETRIES	2
     69 
     70 // this time is in milliseconds
     71 
     72 #define DEFAULT_TIMEOUT			1500
     73 
     74 //
     75 // the following is for a fix around a greenleaf bug
     76 // where they do not check for the value of abortkey
     77 // to determine whether or not they call the abort modem function.
     78 //
     79 extern "C" {
     80 	extern void (*_AbortModemFunctionPtr)(int);
     81 }
     82 
     83 static void (*NullModemClass::OrigAbortModemFunc)(int);
     84 
     85 static KeyNumType NullModemClass::Input;
     86 static GadgetClass *NullModemClass::Commands;		// button list
     87 
     88 /*
     89 ** Ugly hack: this string stores the string received from the modem
     90 */
     91 char ModemRXString[80];
     92 
     93 
     94 /***************************************************************************
     95  * NullModemClass::NullModemClass -- class constructor                     *
     96  *                                                                         *
     97  * INPUT:                                                                  *
     98  *		numsend			# desired entries for the send queue						*
     99  *		numreceive		# desired entries for the receive queue					*
    100  *		maxlen			application's max packet length								*
    101  *		magicnum			application-specific magic # (so we don't 				*
    102  *							accidentally end up talking to another one of our own	*
    103  *							products using the same protocol)							*
    104  *                                                                         *
    105  * OUTPUT:                                                                 *
    106  *		none.																						*
    107  *                                                                         *
    108  * WARNINGS:                                                               *
    109  *		none.																						*
    110  *                                                                         *
    111  * HISTORY:                                                                *
    112  *   12/20/1994 BR : Created.                                              *
    113  *=========================================================================*/
    114 NullModemClass::NullModemClass (int numsend, int numreceive, int maxlen,
    115 	unsigned short magicnum) : ConnManClass()
    116 {
    117 	/*------------------------------------------------------------------------
    118 	Init Port to NULL; we haven't opened Greenleaf yet.
    119 	------------------------------------------------------------------------*/
    120 #ifdef WIN32
    121 	PortHandle = NULL;
    122 #else	//WIN32
    123 	Port = NULL;
    124 #endif	//WIN32
    125 
    126 	Connection = NULL;
    127 
    128 	NumSend = numsend;
    129 	NumReceive = numreceive;
    130 	MaxLen = maxlen;
    131 	MagicNum = magicnum;
    132 
    133 	RXBuf = 0;
    134 	BuildBuf = 0;
    135 
    136 	EchoSize = 500;
    137 	EchoBuf = 0;
    138 
    139 	OldIRQPri = -1;
    140 
    141 	ModemVerboseOn = false;					// default true
    142 	ModemEchoOn = false;						// default true
    143 	ModemWaitCarrier = 50000;				// default 50 * 1000ms = 50 secs
    144 	ModemCarrierDetect = 600;				// default 6  * 100ms  = .6 secs
    145 	ModemCarrierLoss = 1400;				// default 14 * 100ms  = 1.4 secs
    146 	ModemHangupDelay = 20000;				// default 20 * 1000ms = 20 secs
    147 	ModemGuardTime = 1000;					// default 50 * 20ms   = 1 sec
    148 	ModemEscapeCode = '+';					// default ASCII 43
    149 
    150 	SendOverflows = 0;
    151 	ReceiveOverflows = 0;
    152 	CRCErrors = 0;
    153 
    154 	NumConnections = 0;
    155 
    156 	/*------------------------------------------------------------------------
    157 	Init timing parameters
    158 	------------------------------------------------------------------------*/
    159 	RetryDelta = 60;		// 60 ticks between retries
    160 	MaxRetries = -1;		// disregard # retries
    161 	Timeout = 1200;		// report bad connection after 20 seconds
    162 
    163 }	/* end of NullModemClass */
    164 
    165 
    166 /***************************************************************************
    167  * NullModemClass::~NullModemClass -- class destructor                     *
    168  *                                                                         *
    169  * INPUT:                                                                  *
    170  *		none.																						*
    171  *                                                                         *
    172  * OUTPUT:                                                                 *
    173  *		none.																						*
    174  *                                                                         *
    175  * WARNINGS:                                                               *
    176  *		none.																						*
    177  *                                                                         *
    178  * HISTORY:                                                                *
    179  *   12/20/1994 BR : Created.                                              *
    180  *=========================================================================*/
    181 NullModemClass::~NullModemClass ()
    182 {
    183 	Delete_Connection();
    184 
    185 }	/* end of ~NullModemClass */
    186 
    187 
    188 /***************************************************************************
    189  * NullModemClass::Init -- initialization											  *
    190  *                                                                         *
    191  * INPUT:                                                                  *
    192  *		port				address  														  *
    193  *		irq				2-15     														  *
    194  *     dev_name			name of communications device (win32 only)           *
    195  *		baud				300, 1200, 9600, etc											  *
    196  *		parity			'O' (odd), 'E' (even), 'N' (none), 'S' (space),		  *
    197  *							'M' (mark)														  *
    198  *		wordlength		5, 6, 7, or 8													  *
    199  *		stopbits			1 or 2															  *
    200  *                                                                         *
    201  * OUTPUT:                                                                 *
    202  *		1 = OK, 0 = error																	  *
    203  *                                                                         *
    204  * WARNINGS:                                                               *
    205  *		none.																					  *
    206  *                                                                         *
    207  * HISTORY:                                                                *
    208  *   12/20/1994 BR : Created.                                              *
    209  *   10/9/1996  ST : Modified to take device name in win32                 *
    210  *=========================================================================*/
    211 int NullModemClass::Init (int port, int irq, char *dev_name, int baud, char parity, int wordlen, int stopbits, int flowcontrol)
    212 {
    213 	int com;
    214 
    215 #ifdef WIN32
    216 
    217 	/*
    218 	** Get rid of the 'no reference to' warning
    219 	*/
    220 	irq = irq;
    221 
    222 	/*
    223 	** Make sure the port is closed before we start
    224 	*/
    225 	if (PortHandle) {
    226 		CloseHandle (PortHandle);
    227 		PortHandle = NULL;
    228 	}
    229 
    230 	if (!Connection) {
    231 
    232 #else	//WIN32
    233 
    234 	int irqnum;
    235 	int address;
    236 	int status;
    237 
    238 	/*
    239 	** Get rid of the 'no reference to' warning
    240 	*/
    241 	dev_name = dev_name;
    242 
    243 	if (Port) {
    244 		PortClose(Port);
    245 		Port = NULL;
    246 	}else {
    247 
    248 #endif	//WIN32
    249 
    250 	/*------------------------------------------------------------------------
    251 	Init our Connection
    252 	------------------------------------------------------------------------*/
    253 		Connection = new NullModemConnClass (NumSend, NumReceive, MaxLen,
    254 			MagicNum);
    255 
    256 		Connection->Set_Retry_Delta (RetryDelta);
    257 		Connection->Set_Max_Retries (MaxRetries);
    258 		Connection->Set_TimeOut (Timeout);
    259 
    260 		/*---------------------------------------------------------------------
    261 		Allocate our packet parsing buffer; make it the same # of packets as the
    262 		# of receive queue entries the application has requested.  Use the
    263 		"Actual" maximum packet size, given from the connection; this allows for
    264 		both headers that get added to the packet.
    265 		---------------------------------------------------------------------*/
    266 		RXSize = Connection->Actual_Max_Packet() * NumReceive;
    267 		RXBuf = new char [RXSize];
    268 
    269 		BuildBuf = new char [MaxLen];
    270 
    271 		EchoBuf = new char [ EchoSize ];
    272 	}
    273 
    274 	RXCount = 0;
    275 	EchoCount = 0;
    276 
    277 
    278 	/*------------------------------------------------------------------------
    279 	This call allocates all necessary queue buffers
    280 	------------------------------------------------------------------------*/
    281 	switch (port) {
    282 		case 0x3f8:
    283 			com = COM1;
    284 			break;
    285 
    286 		case 0x2f8:
    287 			com = COM2;
    288 			break;
    289 
    290 		case 0x3e8:
    291 			com = COM3;
    292 			break;
    293 
    294 		case 0x2e8:
    295 			com = COM4;
    296 			break;
    297 
    298 		default:
    299 			com = COM5;
    300 			break;
    301 	}
    302 
    303 #ifdef WIN32
    304 	int	i;
    305 
    306 	/*
    307 	** Create a new modem class for our com port
    308 	*/
    309 	if (!SerialPort) {
    310 		SerialPort = new WinModemClass;
    311 	}
    312 
    313 	/*
    314 	** Shift up the baud rate to sensible values
    315 	*/
    316 //	if (baud == 14400) baud = 19200;
    317 //	if (baud == 28800) baud = 38400;
    318 
    319 	static char com_ids[9][5]={
    320 		"COM1",
    321 		"COM2",
    322 		"COM3",
    323 		"COM4",
    324 		"COM5",
    325 		"COM6",
    326 		"COM7",
    327 		"COM8",
    328 		"COM9"
    329 	};
    330 
    331 	char *device;
    332 
    333 	switch ( port ) {
    334 
    335 		case 0x3f8:
    336 			device = com_ids[0];
    337 			break;
    338 
    339 		case 0x2f8:
    340 			device = com_ids[1];
    341 			break;
    342 
    343 		case 0x3e8:
    344 			device = com_ids[2];
    345 			break;
    346 
    347 		case 0x2e8:
    348 			device = com_ids[3];
    349 			break;
    350 
    351 		case 1:
    352 			/*
    353 			** 1 is a special value. It means use the device name not the port address.
    354 			*/
    355 			device = dev_name;
    356 
    357 			/*
    358 			** If we can match a registry entry with the device name then use that, otherwise use
    359 			** the device name directly to open the port with.
    360 			*/
    361 			if (ModemRegistry){
    362 				delete ModemRegistry;
    363 				ModemRegistry = NULL;
    364 			}
    365 			for ( i=0 ; i<10 ; i++ ){
    366 				ModemRegistry = new ModemRegistryEntryClass (i);
    367 				if (ModemRegistry->Get_Modem_Name()){
    368 					if (!strcmp (dev_name, ModemRegistry->Get_Modem_Name() )){
    369 						device = ModemRegistry->Get_Modem_Device_Name();
    370 						break;
    371 					}
    372 				}
    373 				delete ModemRegistry;
    374 				ModemRegistry = NULL;
    375 			}
    376 			break;
    377 
    378 		default:
    379 			device = NULL;
    380 	}
    381 
    382 
    383 
    384 	/*
    385 	** Open the com port
    386 	*/
    387 	PortHandle = SerialPort->Serial_Port_Open (device, baud, parity, wordlen, stopbits, flowcontrol);
    388 	if (PortHandle == INVALID_HANDLE_VALUE) {
    389 		Shutdown();
    390 		return(false);
    391 	}
    392 
    393 	Connection->Init (PortHandle);
    394 
    395 #else	//WIN32
    396 
    397 	status = FastGetPortHardware( com, &irqnum, &address );
    398 	if (status == ASSUCCESS) {
    399 		if (port != address || irq != irqnum) {
    400 
    401 			status = FastSetPortHardware( com, irq, port );
    402 
    403 			if (status < ASSUCCESS) {
    404 				Mono_Printf( "Unable to set Com port status %d\n", status );
    405 				Mono_Printf( "Com port number %d with address %x, irq %d\n",
    406 					com + 1, port, irq );
    407 			} else {
    408 				Mono_Printf( "Changed Com port number %d to address %x, irq %d\n",
    409 					com + 1, port, irq );
    410 			}
    411 		} else {
    412 			Mono_Printf( "No changes to Com port number %d with address %x, irq %d\n",
    413 				com + 1, port, irq );
    414 		}
    415 	} else {
    416 		Mono_Printf( "Com port number %d\n", com + 1 );
    417 	}
    418 
    419 	if (status != ASSUCCESS) {
    420 		Delete_Connection();
    421 		return(false);
    422 	}
    423 
    424 	/*------------------------------------------------------------------------
    425 	Open the Greenleaf port
    426 	------------------------------------------------------------------------*/
    427 	Port = PortOpenGreenleafFast (com, baud, parity, wordlen, stopbits);
    428 
    429 	if (Port->status != ASSUCCESS) {
    430 		Shutdown();
    431 		return(false);
    432 	}
    433 
    434 //	UseRtsCts( Port, 1 );			// use RTS CTS hardware flow control
    435 
    436 	/*------------------------------------------------------------------------
    437 	Init the Connection
    438 	------------------------------------------------------------------------*/
    439 	Connection->Init(Port);
    440 	//because Watcom is so stupid
    441 	flowcontrol = flowcontrol;
    442 
    443 #endif	//WIN32
    444 
    445 	NumConnections = 1;
    446 
    447 	return(true);
    448 }
    449 
    450 
    451 /***********************************************************************************************
    452  * NMC::Num_Connections -- returns NumConnections member                                       *
    453  *                                                                                             *
    454  *                                                                                             *
    455  *                                                                                             *
    456  * INPUT:    Nothing                                                                           *
    457  *                                                                                             *
    458  * OUTPUT:   NumConnections                                                                    *
    459  *                                                                                             *
    460  * WARNINGS: None                                                                              *
    461  *                                                                                             *
    462  * HISTORY:                                                                                    *
    463  *    8/2/96 11:44AM ST : Documented / Win32 support                                           *
    464  *=============================================================================================*/
    465 int NullModemClass::Num_Connections( void )
    466 {
    467 	return(NumConnections);
    468 }
    469 
    470 
    471 /***********************************************************************************************
    472  * NMC::Delete_Connection -- removes the connection                                            *
    473  *                                                                                             *
    474  *                                                                                             *
    475  *                                                                                             *
    476  * INPUT:    Nothing                                                                           *
    477  *                                                                                             *
    478  * OUTPUT:   true                                                                              *
    479  *                                                                                             *
    480  * WARNINGS: None                                                                              *
    481  *                                                                                             *
    482  * HISTORY:                                                                                    *
    483  *    8/2/96 11:44AM ST : Documented / Win32 support                                           *
    484  *=============================================================================================*/
    485 int NullModemClass::Delete_Connection( void )
    486 {
    487 	if (Connection) {
    488 		delete Connection;
    489 		Connection = NULL;
    490 	}
    491 
    492 	if (RXBuf) {
    493 		delete [] RXBuf;
    494 		RXBuf = NULL;
    495 	}
    496 
    497 	if (BuildBuf) {
    498 		delete [] BuildBuf;
    499 		BuildBuf = NULL;
    500 	}
    501 
    502 	if (EchoBuf) {
    503 		delete [] EchoBuf;
    504 		EchoBuf = NULL;
    505 	}
    506 
    507 	NumConnections = 0;
    508 
    509 	return( true );
    510 }	/* end of Delete_Connection */
    511 
    512 
    513 
    514 /***********************************************************************************************
    515  * NMC::Init_Send_Queue -- Initialises the connections send queue                              *
    516  *                                                                                             *
    517  *                                                                                             *
    518  *                                                                                             *
    519  * INPUT:    Nothing                                                                           *
    520  *                                                                                             *
    521  * OUTPUT:   true                                                                              *
    522  *                                                                                             *
    523  * WARNINGS: None                                                                              *
    524  *                                                                                             *
    525  * HISTORY:                                                                                    *
    526  *    8/2/96 11:46AM ST : Documented / Win32 support                                           *
    527  *=============================================================================================*/
    528 int NullModemClass::Init_Send_Queue( void )
    529 {
    530 
    531 	/*------------------------------------------------------------------------
    532 	Init the send queue
    533 	------------------------------------------------------------------------*/
    534 	if ( Connection ) {
    535 		Connection->Queue->Init_Send_Queue();
    536 	}
    537 
    538 	return(true);
    539 }
    540 
    541 
    542 
    543 /***********************************************************************************************
    544  * NMC::Detect_Port -- Checks that the specified com port exists                               *
    545  *                                                                                             *
    546  *                                                                                             *
    547  *                                                                                             *
    548  * INPUT:    ptr to SerialSettingsType                                                         *
    549  *                                                                                             *
    550  * OUTPUT:   true if port is valid                                                             *
    551  *                                                                                             *
    552  * WARNINGS: Win32 version always returns true as win95 shouldnt allow us to open the          *
    553  *           port if it doesnt exist or is in use by the mouse                                 *
    554  *                                                                                             *
    555  * HISTORY:                                                                                    *
    556  *    8/2/96 11:47AM ST : Documented / Win32 support                                           *
    557  *=============================================================================================*/
    558 DetectPortType NullModemClass::Detect_Port( SerialSettingsType *settings )
    559 {
    560 
    561 #ifdef WIN32
    562 
    563 	static char com_ids[9][5]={
    564 		"COM1",
    565 		"COM2",
    566 		"COM3",
    567 		"COM4",
    568 		"COM5",
    569 		"COM6",
    570 		"COM7",
    571 		"COM8",
    572 		"COM9"
    573 	};
    574 
    575 	int	i;
    576 
    577 	/*
    578 	** Create a new modem class for our com port
    579 	*/
    580 	if (!SerialPort) {
    581 		SerialPort = new WinModemClass;
    582 	}else{
    583 		SerialPort->Serial_Port_Close();
    584 	}
    585 
    586 	/*
    587 	** Shift up the baud rate to sensible values
    588 	*/
    589 	int baud = settings->Baud;
    590 //	if (baud == 14400) baud = 19200;
    591 //	if (baud == 28800) baud = 38400;
    592 
    593 
    594 	/*
    595 	** Translate the port address into a usable device name
    596 	*/
    597 	char *device;
    598 
    599 	switch ( settings->Port ) {
    600 
    601 		case 0x3f8:
    602 			device = com_ids[0];
    603 			break;
    604 
    605 		case 0x2f8:
    606 			device = com_ids[1];
    607 			break;
    608 
    609 		case 0x3e8:
    610 			device = com_ids[2];
    611 			break;
    612 
    613 		case 0x2e8:
    614 			device = com_ids[3];
    615 			break;
    616 
    617 		case 1:
    618 			/*
    619 			** 1 is a special value. It means use the device name not the port address.
    620 			*/
    621 			device = settings->ModemName;
    622 
    623 			/*
    624 			** If we can match a registry entry with the device name then use that, otherwise use
    625 			** the device name directly to open the port with.
    626 			*/
    627 			if (ModemRegistry){
    628 				delete ModemRegistry;
    629 				ModemRegistry = NULL;
    630 			}
    631 			for ( i=0 ; i<10 ; i++){
    632 				ModemRegistry = new ModemRegistryEntryClass (i);
    633 				if (ModemRegistry->Get_Modem_Name()){
    634 					if (!strcmp (device, ModemRegistry->Get_Modem_Name() )){
    635 						/*
    636 						** Got a match. Break out leaving the registry info intact.
    637 						*/
    638 						device = ModemRegistry->Get_Modem_Device_Name();
    639 						break;
    640 					}
    641 				}
    642 				delete ModemRegistry;
    643 				ModemRegistry = NULL;
    644 			}
    645 			break;
    646 
    647 		default:
    648 			return (PORT_INVALID);
    649 	}
    650 
    651 	/*
    652 	** Open the com port
    653 	*/
    654 	HANDLE porthandle = SerialPort->Serial_Port_Open (device, baud, 0, 8, 1, settings->HardwareFlowControl);
    655 
    656 	if (porthandle == INVALID_HANDLE_VALUE){
    657 		return (PORT_INVALID);
    658 	}
    659 
    660 	SerialPort->Serial_Port_Close();
    661 	return (PORT_VALID);
    662 
    663 
    664 
    665 #else	//WIN32
    666 
    667 	union REGS		regs ;
    668 	int com;
    669 	int irqnum;
    670 	int address;
    671 	int status;
    672 
    673 
    674 	// shutdown previous port
    675 
    676 	Shutdown();
    677 
    678 	if (settings->IRQ > 0xf) {
    679 		return( PORT_INVALID );
    680 	}
    681 
    682 	//
    683 	// check if the IRQ is the same as the mouse
    684 	// call mouse func to get mouse IRQ number
    685 	//
    686 
    687 	regs.x.eax = 0x0024;
    688 	int386( 0x33, &regs, &regs );
    689 
    690 	//
    691 	// check for error
    692 	//
    693 	if (regs.w.ax != 0xffff) {
    694 		//
    695 		// is the mouse IRQ the same as that they selected
    696 		//
    697 		if (regs.h.cl == 0) {	// PS/2 IRQ 0xc
    698 			if (settings->IRQ == 0xc) {
    699 				return( PORT_IRQ_INUSE );
    700 			}
    701 		} else if (regs.h.cl == (unsigned char)(settings->IRQ)) {
    702 			return( PORT_IRQ_INUSE );
    703 		}
    704 	}
    705 
    706 	if (settings->IRQ < 2					// 0 timer, 1 keyboard
    707 		|| settings->IRQ == 6				// floppy disk
    708 		|| settings->IRQ == 8				// CMOS real-time clock
    709 		|| settings->IRQ == 0xd				// math coprocessor error
    710 		|| settings->IRQ == 0xe) {			// hard disk
    711 		return( PORT_IRQ_INUSE );
    712 	}
    713 
    714 	/*------------------------------------------------------------------------
    715 	This call allocates all necessary queue buffers
    716 	------------------------------------------------------------------------*/
    717 	switch ( settings->Port ) {
    718 		case 0x3f8:
    719 			com = COM1;
    720 			break;
    721 
    722 		case 0x2f8:
    723 			com = COM2;
    724 			break;
    725 
    726 		case 0x3e8:
    727 			com = COM3;
    728 			break;
    729 
    730 		case 0x2e8:
    731 			com = COM4;
    732 			break;
    733 
    734 		default:
    735 			com = COM5;
    736 			break;
    737 	}
    738 
    739 	status = FastGetPortHardware( com, &irqnum, &address );
    740 	if (status == ASSUCCESS) {
    741 		if (settings->Port != address || settings->IRQ != irqnum) {
    742 			status = FastSetPortHardware( com, settings->IRQ, settings->Port );
    743 		}
    744 	}
    745 
    746 	if (status != ASSUCCESS) {
    747 		return( PORT_INVALID );
    748 	}
    749 
    750 	/*------------------------------------------------------------------------
    751 	Open the Greenleaf port
    752 	------------------------------------------------------------------------*/
    753 	Port = PortOpenGreenleafFast (com, settings->Baud, 'N', 8, 1);
    754 
    755 	status = Port->status;
    756 
    757 	PortClose(Port);
    758 	Port = NULL;
    759 
    760 	if (status == ASIRQINUSE) {
    761 		return( PORT_IRQ_INUSE );
    762 	} else if (status != ASSUCCESS) {
    763 		return( PORT_INVALID );
    764 	}
    765 
    766 	return( PORT_VALID );
    767 #endif	//WIN32
    768 }
    769 
    770 
    771 /***********************************************************************************************
    772  * NullModemClass::ShutDown -- Closes serial port and removes the connection                   *
    773  *                                                                                             *
    774  *                                                                                             *
    775  *                                                                                             *
    776  * INPUT:    Nothing                                                                           *
    777  *                                                                                             *
    778  * OUTPUT:   Nothing                                                                           *
    779  *                                                                                             *
    780  * WARNINGS: None                                                                              *
    781  *                                                                                             *
    782  * HISTORY:                                                                                    *
    783  *    8/2/96 11:43AM ST : Documented / Win32 support                                           *
    784  *=============================================================================================*/
    785 void NullModemClass::Shutdown ( void )
    786 {
    787 
    788 #ifdef WIN32
    789 
    790 	if (PortHandle && SerialPort) {
    791 		SerialPort->Serial_Port_Close();
    792 		delete SerialPort;
    793 		SerialPort = NULL;
    794 		PortHandle = NULL;
    795 		Delete_Connection();
    796 	}
    797 
    798 #else	//WIN32
    799 	if (Port) {
    800 		PortClose(Port);
    801 		Port = NULL;
    802 		Delete_Connection();
    803 	}
    804 
    805 #endif	//WIN32
    806 
    807 }	/* end of Shutdown */
    808 
    809 
    810 /***************************************************************************
    811  * NullModemClass::Set_Timing -- sets timing for all connections				*
    812  *                                                                         *
    813  * This will set the timing parameters.  This allows an application to		*
    814  * measure the Response_Time while running, and adjust timing accordingly.	*
    815  *                                                                         *
    816  * INPUT:                                                                  *
    817  *		retrydelta	value to set for retry delta 										*
    818  *		maxretries	value to set for max # retries									*
    819  *		timeout		value to set for connection timeout								*
    820  *                                                                         *
    821  * OUTPUT:                                                                 *
    822  *		none.																						*
    823  *                                                                         *
    824  * WARNINGS:                                                               *
    825  *		none.																						*
    826  *                                                                         *
    827  * HISTORY:                                                                *
    828  *   08/07/1995 DRD : Created.                                             *
    829  *=========================================================================*/
    830 void NullModemClass::Set_Timing (unsigned long retrydelta,
    831 	unsigned long maxretries, unsigned long timeout)
    832 {
    833 	RetryDelta = retrydelta;
    834 	MaxRetries = maxretries;
    835 	Timeout = timeout;
    836 
    837 	Connection->Set_Retry_Delta (RetryDelta);
    838 	Connection->Set_Max_Retries (MaxRetries);
    839 	Connection->Set_TimeOut (Timeout);
    840 
    841 }	/* end of Set_Timing */
    842 
    843 
    844 /***************************************************************************
    845  * NullModemClass::Send_Message -- sends a message									*
    846  *                                                                         *
    847  * For clarity's sake, here's what happens to the buffer passed in:			*
    848  * - It gets passed to the Connection's Send_Packet() routine					*
    849  * - The CommHeaderType header gets tacked onto it									*
    850  * - The resulting buffer gets added to the Connection's Send Queue			*
    851  * - When Service() determines that it needs to send the data, it				*
    852  *   copies the entire packet (CommHeaderType and all) into its local 		*
    853  *   SendBuf, adds the packet start ID, length, and CRC, then sends it out.*
    854  *                                                                         *
    855  * The ack_req argument will almost always be '1' (the default).  The only	*
    856  * reason to use 0 is if you don't know whether the other system is			*
    857  * ready or not, so you have to periodically send out a query packet,		*
    858  * and wait for a response.  (Using the connection's built-in retry			*
    859  * system would just blast out useless data if the other system isn't		*
    860  * even there.)																				*
    861  *                                                                         *
    862  * INPUT:                                                                  *
    863  *		buf			buffer to send															*
    864  *		buflen		length of buffer														*
    865  *		ack_req		1 = ACK is required; 0 = not										*
    866  *                                                                         *
    867  * OUTPUT:                                                                 *
    868  *		1 = OK; 0 = error																		*
    869  *                                                                         *
    870  * WARNINGS:                                                               *
    871  *		none.																						*
    872  *                                                                         *
    873  * HISTORY:                                                                *
    874  *   12/20/1994 BR : Created.                                              *
    875  *=========================================================================*/
    876 int NullModemClass::Send_Message (void *buf, int buflen, int ack_req)
    877 {
    878 	int rc;
    879 
    880 	if (NumConnections == 0) {
    881 		return( false );
    882 	}
    883 
    884 	rc = Connection->Send_Packet(buf,buflen,ack_req);
    885 	if (!rc)
    886 		SendOverflows++;
    887 
    888 	return(rc);
    889 
    890 }	/* end of Send_Message */
    891 
    892 
    893 /***************************************************************************
    894  * NullModemClass::Get_Message -- polls the Queue for a message				*
    895  *                                                                         *
    896  * INPUT:                                                                  *
    897  *		buf			buffer to store message in											*
    898  *		buflen		ptr filled in with length of message							*
    899  *                                                                         *
    900  * OUTPUT:                                                                 *
    901  *		1 = message was received; 0 = wasn't											*
    902  *                                                                         *
    903  * WARNINGS:                                                               *
    904  *		none.																						*
    905  *                                                                         *
    906  * HISTORY:                                                                *
    907  *   12/20/1994 BR : Created.                                              *
    908  *=========================================================================*/
    909 int NullModemClass::Get_Message (void *buf, int *buflen)
    910 {
    911 	if (NumConnections == 0) {
    912 		return( false );
    913 	}
    914 	return( Connection->Get_Packet( buf, buflen ) );
    915 }
    916 
    917 
    918 /***************************************************************************
    919  * NullModemClass::Service -- main polling routine								  *
    920  *                                                                         *
    921  * INPUT:                                                                  *
    922  *		none.																					  *
    923  *                                                                         *
    924  * OUTPUT:                                                                 *
    925  *		1 = OK, 0 = connection has gone bad											  *
    926  *                                                                         *
    927  * WARNINGS:                                                               *
    928  *		none.																					  *
    929  *                                                                         *
    930  * HISTORY:                                                                *
    931  *   12/20/1994 BR : Created.                                              *
    932  *   8/2/96     ST : Win32 support                                         *
    933  *=========================================================================*/
    934 int NullModemClass::Service (void)
    935 {
    936 	int pos;				// current position in RXBuf
    937 	int i;				// loop counter
    938 	unsigned short length;
    939 	SerialHeaderType *header;	// decoded packet start, length
    940 	SerialCRCType *crc;			// decoded packet CRC
    941 	char moredata = 0;
    942 
    943 	if (NumConnections == 0) {
    944 		return( false );
    945 	}
    946 
    947 #ifdef WIN32
    948 
    949 	RXCount += SerialPort->Read_From_Serial_Port((unsigned char*)(RXBuf + RXCount), int(RXSize - RXCount) );
    950 
    951 #else	//WIN32
    952 
    953 	int status;
    954 	static unsigned long last_time = 0;
    955 
    956 	/*------------------------------------------------------------------------
    957 	First, copy all the bytes we can from the Greenleaf RX buffer to our
    958 	own buffer.
    959 	(For Win95, only call GetLineStatus() 60 times a second at most.
    960 	Otherwise, we don't receive any packets!)
    961 	------------------------------------------------------------------------*/
    962 	if ( (TickCount - last_time) > 0) {
    963 		if ( GetLineStatus( Port ) ) {
    964 			Mono_Set_Cursor(0,0);
    965 			ClearLineStatus( Port );
    966 		}
    967 		last_time = TickCount;
    968 	}
    969 
    970 	status = SpaceUsedInRXBuffer( Port );
    971 
    972 	if ( status < ASSUCCESS) {
    973 //		Smart_Printf( "SpaceUsedInRXBuffer status = %d, port status = %d \n", status, Port->status );
    974 
    975 		if ( Port->status < ASSUCCESS ) {
    976 			ClearError( Port );
    977 		}
    978 
    979 	} else if (status > 0) {
    980 		status = ReadBuffer( Port, RXBuf + RXCount, RXSize - RXCount );
    981 
    982 #if (CONN_DEBUG)
    983 		printf( "ReadBuffer status = %d, port status = %d, count = %d \n", status, Port->status, Port->count );
    984 #endif
    985 //			Smart_Printf( "ReadBuffer status = %d, port status = %d, count = %d \n", status, Port->status, Port->count );
    986 		if (status < ASSUCCESS && status != ASBUFREMPTY) {
    987 //				Smart_Printf( "ReadBuffer ERRRRRRORRRRRR! \n" );
    988 		} else {
    989 			moredata = 1;
    990 		}
    991 
    992 		if ( Port->status < ASSUCCESS ) {
    993 			ClearError( Port );
    994 		}
    995 
    996 		RXCount += Port->count;
    997 	}
    998 
    999 
   1000 #endif	//WIN32
   1001 
   1002 	// minimum packet size
   1003 
   1004 	if ( RXCount < (PACKET_SERIAL_OVERHEAD_SIZE + 1) ) {
   1005 		return( Connection->Service() );
   1006 	}
   1007 
   1008 	/*------------------------------------------------------------------------
   1009 	Now scan the buffer for the start of a packet.
   1010 	------------------------------------------------------------------------*/
   1011 	pos = -1;
   1012 	for (i = 0; i <= RXCount - sizeof( short ); i++) {
   1013 		if ( *((unsigned short *)(RXBuf + i)) == PACKET_SERIAL_START ) {
   1014 			pos = i;
   1015 			break;
   1016 		}
   1017 	}
   1018 
   1019 	/*------------------------------------------------------------------------
   1020 	No start code was found; throw away all bytes except the last few, and
   1021 	return.
   1022 	------------------------------------------------------------------------*/
   1023 	if (pos==-1) {
   1024 // Smart_Printf( "No magic number found \n" );
   1025 		/*.....................................................................
   1026 		move the remaining, un-checked bytes to the start of the buffer
   1027 		.....................................................................*/
   1028 		memmove (RXBuf, RXBuf + i, sizeof( short ) - 1);
   1029 		RXCount = sizeof( short ) - 1;
   1030 		return( Connection->Service() );
   1031 	}
   1032 
   1033 	/*------------------------------------------------------------------------
   1034 	Check to see if there are enough bytes for the header to be decoded
   1035 	------------------------------------------------------------------------*/
   1036 	if ( (RXCount - pos) < sizeof( SerialHeaderType ) ) {
   1037 		memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1038 		RXCount -= pos;
   1039 		return(Connection->Service());
   1040 	}
   1041 
   1042 	/*------------------------------------------------------------------------
   1043 	A start code was found; check the packet's length & CRC
   1044 	------------------------------------------------------------------------*/
   1045 	header = (SerialHeaderType *)(RXBuf + pos);
   1046 
   1047 	/*------------------------------------------------------------------------
   1048 	If we lost a byte in the length, we may end up waiting a very long time
   1049 	for the buffer to get to the right length; check the verify value to
   1050 	make sure this didn't happen.
   1051 	------------------------------------------------------------------------*/
   1052 	if ( header->MagicNumber2 != PACKET_SERIAL_VERIFY ) {
   1053 // Smart_Printf( "Verify failed\n");
   1054 //		Hex_Dump_Data( (RXBuf + pos), PACKET_SERIAL_OVERHEAD_SIZE );
   1055 
   1056 		pos += sizeof ( short );		// throw away the bogus start code
   1057 		memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1058 		RXCount -= pos;
   1059 		return(Connection->Service());
   1060 	}
   1061 
   1062 	length = header->Length;
   1063 
   1064 	/*------------------------------------------------------------------------
   1065 	Special case: if the length comes out too long for us to process:
   1066 	- Assume the packet is bad
   1067 	- Throw away the bogus packet-start code
   1068 	- Return;  we'll search for another packet-start code next time.
   1069 	------------------------------------------------------------------------*/
   1070 	if (length > MaxLen) {
   1071 #if (CONN_DEBUG)
   1072 		printf( "length too lonnng\n" );
   1073 #endif
   1074 // Smart_Printf( "length too lonnng %d, max %d \n", length, MaxLen );
   1075 
   1076 		pos += sizeof ( short );		// throw away the bogus start code
   1077 		memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1078 		RXCount -= pos;
   1079 		return(Connection->Service());
   1080 	}
   1081 
   1082 	/*------------------------------------------------------------------------
   1083 	If the entire packet isn't stored in our buffer, copy the remaining bytes
   1084 	to the front of the buffer & return.
   1085 	------------------------------------------------------------------------*/
   1086 	if ( (pos + length + PACKET_SERIAL_OVERHEAD_SIZE) > RXCount) {
   1087 
   1088 		if ( moredata ) {
   1089 // Smart_Printf( "waiting for more data %d, pos = %d \n", ((length + PACKET_SERIAL_OVERHEAD_SIZE) - (RXCount - pos)), pos );
   1090 		}
   1091 
   1092 		if (pos) {
   1093 			memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1094 			RXCount -= pos;
   1095 		}
   1096 		return(Connection->Service());
   1097 	}
   1098 
   1099 	/*------------------------------------------------------------------------
   1100 	Now grab the CRC value in the packet, & compare it to the CRC value
   1101 	computed from the actual data.  If they don't match, throw away the bogus
   1102 	start-code, move the rest to the front of the buffer, & return.
   1103 	We'll continue parsing this data when we're called next time.
   1104 	------------------------------------------------------------------------*/
   1105 	crc = (SerialCRCType *)(RXBuf + pos + sizeof( SerialHeaderType ) + length);
   1106 	if (NullModemConnClass::Compute_CRC(RXBuf + pos +
   1107 		sizeof( SerialHeaderType ), length) != crc->SerialCRC) {
   1108 
   1109 		CRCErrors++;
   1110 
   1111 #if (CONN_DEBUG)
   1112 		printf( "CRC check failed\n" );
   1113 #endif
   1114 // Smart_Printf( "CRC check failed for packet of length %d \n", length );
   1115 
   1116 //		if (length < 100) {
   1117 //			Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) );
   1118 //		}
   1119 
   1120 		pos += sizeof ( short );		// throw away the bogus start code
   1121 		memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1122 		RXCount -= pos;
   1123 		return(Connection->Service());
   1124 	}
   1125 
   1126 #if(0)
   1127 // Mono_Printf( "received %d bytes \n", sendlen );
   1128  Debug_Modem_Dump = true;
   1129  Smart_Printf( "Received tick=%d, Protocol=%d \n",  TickCount, Session.CommProtocol );
   1130  Hex_Dump_Data( (RXBuf + pos), (sizeof( SerialHeaderType) + length) );
   1131  Debug_Modem_Dump = false;
   1132 #endif
   1133 
   1134 	/*------------------------------------------------------------------------
   1135 	Give the new packet to the Connection to process.
   1136 	------------------------------------------------------------------------*/
   1137 	if (!Connection->Receive_Packet(RXBuf + pos + sizeof( SerialHeaderType ), length)) {
   1138 		ReceiveOverflows++;
   1139 // Smart_Printf( "Received overflows %d \n", ReceiveOverflows );
   1140 	}
   1141 
   1142 #if(0)
   1143 	else {
   1144 // Mono_Printf( "added packet \n", sendlen );
   1145  Debug_Modem_Dump = true;
   1146  Smart_Printf( "Received Packet \n" );
   1147  Debug_Modem_Dump = false;
   1148 	}
   1149 #endif
   1150 
   1151 #if (0)
   1152 	Hex_Dump_Data( (RXBuf + pos), (PACKET_SERIAL_OVERHEAD_SIZE + length) );
   1153 #endif
   1154 
   1155 	/*------------------------------------------------------------------------
   1156 	Move all data past this packet to the front of the buffer.
   1157 	------------------------------------------------------------------------*/
   1158 	pos += (PACKET_SERIAL_OVERHEAD_SIZE + length);
   1159 	memmove (RXBuf, RXBuf + pos, RXCount - pos);
   1160 	RXCount -= pos;
   1161 
   1162 	/*------------------------------------------------------------------------
   1163 	Now, service the connection's Queue's; this will handle ACK & Retries.
   1164 	------------------------------------------------------------------------*/
   1165 	return(Connection->Service());
   1166 
   1167 }	/* end of Service */
   1168 
   1169 
   1170 /***************************************************************************
   1171  * NullModemClass::Num_Send -- Returns # of unACK'd send entries				*
   1172  *                                                                         *
   1173  * INPUT:                                                                  *
   1174  *                                                                         *
   1175  * OUTPUT:                                                                 *
   1176  *                                                                         *
   1177  * WARNINGS:                                                               *
   1178  *                                                                         *
   1179  * HISTORY:                                                                *
   1180  *   05/01/1995 BRR : Created.                                             *
   1181  *=========================================================================*/
   1182 int NullModemClass::Num_Send(void)
   1183 {
   1184 	if (Connection)
   1185 		return( Connection->Queue->Num_Send() );
   1186 	else
   1187 		return (0);
   1188 
   1189 }	/* end of Num_Send */
   1190 
   1191 
   1192 /***************************************************************************
   1193  * NullModemClass::Num_Receive -- Returns # entries in the receive queue   *
   1194  *                                                                         *
   1195  * INPUT:                                                                  *
   1196  *                                                                         *
   1197  * OUTPUT:                                                                 *
   1198  *                                                                         *
   1199  * WARNINGS:                                                               *
   1200  *                                                                         *
   1201  * HISTORY:                                                                *
   1202  *   05/01/1995 BRR : Created.                                             *
   1203  *=========================================================================*/
   1204 int NullModemClass::Num_Receive(void)
   1205 {
   1206 	if (Connection)
   1207 		return( Connection->Queue->Num_Receive() );
   1208 	else
   1209 		return (0);
   1210 
   1211 }	/* end of Num_Receive */
   1212 
   1213 
   1214 /***************************************************************************
   1215  * NullModemClass::Response_Time -- Returns Queue's avg response time      *
   1216  *                                                                         *
   1217  * INPUT:                                                                  *
   1218  *                                                                         *
   1219  * OUTPUT:                                                                 *
   1220  *                                                                         *
   1221  * WARNINGS:                                                               *
   1222  *                                                                         *
   1223  * HISTORY:                                                                *
   1224  *   05/01/1995 BRR : Created.                                             *
   1225  *=========================================================================*/
   1226 unsigned long NullModemClass::Response_Time(void)
   1227 {
   1228 	if (Connection)
   1229 		return( Connection->Queue->Avg_Response_Time() );
   1230 	else
   1231 		return (0);
   1232 
   1233 }	/* end of Response_Time */
   1234 
   1235 
   1236 /***************************************************************************
   1237  * NullModemClass::Reset_Response_Time -- Resets response time computation *
   1238  *                                                                         *
   1239  * INPUT:                                                                  *
   1240  *                                                                         *
   1241  * OUTPUT:                                                                 *
   1242  *                                                                         *
   1243  * WARNINGS:                                                               *
   1244  *                                                                         *
   1245  * HISTORY:                                                                *
   1246  *   05/01/1995 BRR : Created.                                             *
   1247  *=========================================================================*/
   1248 void NullModemClass::Reset_Response_Time(void)
   1249 {
   1250 	if (Connection)
   1251 		Connection->Queue->Reset_Response_Time();
   1252 
   1253 }	/* end of Reset_Response_Time */
   1254 
   1255 
   1256 /***************************************************************************
   1257  * Oldest_Send -- Returns ptr to oldest unACK'd send buffer                *
   1258  *                                                                         *
   1259  * INPUT:                                                                  *
   1260  *                                                                         *
   1261  * OUTPUT:                                                                 *
   1262  *                                                                         *
   1263  * WARNINGS:                                                               *
   1264  *                                                                         *
   1265  * HISTORY:                                                                *
   1266  *   05/01/1995 BRR : Created.                                             *
   1267  *=========================================================================*/
   1268 void * NullModemClass::Oldest_Send(void)
   1269 {
   1270 	int i;
   1271 	SendQueueType *send_entry;				// ptr to send entry header
   1272 	CommHeaderType *packet;
   1273 	void *buf = NULL;
   1274 
   1275 	for (i = 0; i < Connection->Queue->Num_Send(); i++) {
   1276 		send_entry = Connection->Queue->Get_Send(i);
   1277 		if (send_entry) {
   1278 			packet = (CommHeaderType *)send_entry->Buffer;
   1279 			if (packet->Code == ConnectionClass::PACKET_DATA_ACK && send_entry->IsACK == 0) {
   1280 				buf = send_entry->Buffer;
   1281 				break;
   1282 			}
   1283 		}
   1284 	}
   1285 
   1286 	return(buf);
   1287 
   1288 }	/* end of Oldest_Send */
   1289 
   1290 
   1291 /***************************************************************************
   1292  * NullModemClass::Configure_Debug -- sets up special debug values         *
   1293  *                                                                         *
   1294  * Mono_Debug_Print2() can look into a packet to pull out a particular		*
   1295  * ID, and can print both that ID and a string corresponding to				*
   1296  * that ID.  This routine configures these values so it can find				*
   1297  * and decode the ID.  This ID is used in addition to the normal				*
   1298  * CommHeaderType values.																	*
   1299  *                                                                         *
   1300  * INPUT:                                                                  *
   1301  *		index			(not used)																*
   1302  *		type_offset		ID's byte offset into packet									*
   1303  *		type_size		size of ID, in bytes; 0 if none								*
   1304  *		names				ptr to array of names; use ID as an index into this	*
   1305  *		namestart		numerical start of the 1st name value						*
   1306  *		namecount		# in the names array; 0 if none.								*
   1307  *                                                                         *
   1308  * OUTPUT:                                                                 *
   1309  *		none.																						*
   1310  *                                                                         *
   1311  * WARNINGS:                                                               *
   1312  *		Names shouldn't be longer than 12 characters.								*
   1313  *                                                                         *
   1314  * HISTORY:                                                                *
   1315  *   05/31/1995 BRR : Created.                                             *
   1316  *=========================================================================*/
   1317 void NullModemClass::Configure_Debug(int, int type_offset, int type_size,
   1318 	char **names, int namestart, int namecount)
   1319 {
   1320 	if (Connection)
   1321 		Connection->Queue->Configure_Debug (type_offset, type_size, names,
   1322 			namestart, namecount);
   1323 }
   1324 
   1325 #ifdef CHEAT_KEYS
   1326 /***************************************************************************
   1327  * Mono_Debug_Print -- Debug output routine                                *
   1328  *                                                                         *
   1329  * INPUT:                                                                  *
   1330  *		index			(not used)																*
   1331  *		refresh		1 = clear screen & completely refresh							*
   1332  *                                                                         *
   1333  * OUTPUT:                                                                 *
   1334  *		none.																						*
   1335  *                                                                         *
   1336  * WARNINGS:                                                               *
   1337  *		none.																						*
   1338  *                                                                         *
   1339  * HISTORY:                                                                *
   1340  *   05/02/1995 BRR : Created.                                             *
   1341  *=========================================================================*/
   1342 void NullModemClass::Mono_Debug_Print(int,int refresh)
   1343 {
   1344 	if (!Connection)
   1345 		return;
   1346 
   1347 	Connection->Queue->Mono_Debug_Print (refresh);
   1348 
   1349 	if (refresh) {
   1350 		Mono_Set_Cursor (31,1);
   1351 		Mono_Printf ("Serial Port Queues");
   1352 
   1353 		Mono_Set_Cursor (9,2);
   1354 		Mono_Printf ("Average Response Time:");
   1355 
   1356 		Mono_Set_Cursor (20,3);
   1357 		Mono_Printf ("CRC Errors:");
   1358 
   1359 		Mono_Set_Cursor (43,2);
   1360 		Mono_Printf ("Send Overflows:");
   1361 
   1362 		Mono_Set_Cursor (40,3);
   1363 		Mono_Printf ("Receive Overflows:");
   1364 	}
   1365 
   1366 	Mono_Set_Cursor (32,2);
   1367 	Mono_Printf ("%d  ", Connection->Queue->Avg_Response_Time());
   1368 
   1369 	Mono_Set_Cursor (32,3);
   1370 	Mono_Printf ("%d  ", CRCErrors);
   1371 
   1372 	Mono_Set_Cursor (59,2);
   1373 	Mono_Printf ("%d  ", SendOverflows);
   1374 
   1375 	Mono_Set_Cursor (59,3);
   1376 	Mono_Printf ("%d  ", ReceiveOverflows);
   1377 
   1378 	Mono_Set_Cursor (2,5);
   1379 	Mono_Printf ("%d  ", Num_Send());
   1380 
   1381 	Mono_Set_Cursor (41,5);
   1382 	Mono_Printf ("%d  ", Num_Receive());
   1383 
   1384 }	/* end of Mono_Debug_Print */
   1385 #endif
   1386 
   1387 
   1388 /***************************************************************************
   1389  * NullModemClass::Detect_Modem -- Detects and initializes the modem       *
   1390  *                                                                         *
   1391  * INPUT:                                                                  *
   1392  *		settings		ptr to SerialSettings structure     						  *
   1393  *                                                                         *
   1394  * OUTPUT:                                                                 *
   1395  *		-1				init string invalid												  *
   1396  *		0				no modem found														  *
   1397  *		1				modem found			  												  *
   1398  *                                                                         *
   1399  * WARNINGS:                                                               *
   1400  *		none.																					  *
   1401  *                                                                         *
   1402  * HISTORY:                                                                *
   1403  *   06/02/1995 DRD : Created.                                             *
   1404  *   8/2/96      ST : Added Win32 support                                  *
   1405  *=========================================================================*/
   1406 int NullModemClass::Detect_Modem( SerialSettingsType *settings, bool reconnect )
   1407 {
   1408 	/*------------------------------------------------------------------------
   1409 	Button Enumerations
   1410 	------------------------------------------------------------------------*/
   1411 	int status;
   1412 	int error_count = 0;
   1413 
   1414 	int x,y,width,height;					// dialog dimensions
   1415 	char buffer[80*3];
   1416 
   1417 	/*
   1418 	** Get resolution factor
   1419 	*/
   1420 //	int	factor = SeenBuff.Get_Width()/320;
   1421 
   1422 	/*------------------------------------------------------------------------
   1423 	Determine the dimensions of the text to be used for the dialog box.
   1424 	These dimensions will control how the dialog box looks.
   1425 	------------------------------------------------------------------------*/
   1426 	strcpy( buffer, Text_String( TXT_INITIALIZING_MODEM ) );
   1427 
   1428 	Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TEXT);
   1429 	int lines = Format_Window_String(buffer, SeenBuff.Get_Height(), width, height);
   1430 
   1431 	width = max(width, 90 * RESFACTOR);
   1432 	width += 40 * RESFACTOR;
   1433 	height += 40 * RESFACTOR;
   1434 
   1435 	x = (SeenBuff.Get_Width() - width) / 2;
   1436 	y = (SeenBuff.Get_Height() - height) / 2;
   1437 
   1438 	/*------------------------------------------------------------------------
   1439 	Initialize
   1440 	------------------------------------------------------------------------*/
   1441 	Set_Logic_Page(SeenBuff);
   1442 
   1443 	/*------------------------------------------------------------------------
   1444 	Draw the dialog
   1445 	------------------------------------------------------------------------*/
   1446 	Hide_Mouse();
   1447 	if ( !reconnect ) {
   1448 		Load_Title_Page(true);
   1449 	}
   1450 
   1451 	Dialog_Box(x, y, width, height);
   1452 	Draw_Caption(TXT_NONE, x, y, width);
   1453 
   1454 	if (lines == 1) {
   1455 		Fancy_Text_Print(buffer, x + width/2, y + 25, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT|TPF_CENTER);
   1456 	} else {
   1457 		Fancy_Text_Print(buffer, x + 20*RESFACTOR, y + 25, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT);
   1458 	}
   1459 
   1460 	Show_Mouse();
   1461 
   1462 
   1463 	HMWaitForOK( 0, NULL );
   1464 
   1465 
   1466 	/*
   1467 	** OK, lets not mess about any more. Just turn on echo, verbose, and result codes
   1468 	** before we even begin. At least this way when we get an error later on we have already
   1469 	** removed all the steps we use to try and recover.
   1470 	** The timeouts need to be quite small in case the modem is turned off.
   1471 	*/
   1472 
   1473 	/*
   1474 	** Turn on result codes.
   1475 	*/
   1476 	Send_Modem_Command ( "ATQ0", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
   1477 
   1478 	/*
   1479 	** Make result codes verbose.
   1480 	*/
   1481 	Send_Modem_Command ( "ATV1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
   1482 
   1483 	/*
   1484 	** Turn on echo.
   1485 	*/
   1486 	Send_Modem_Command ( "ATE1", '\r', buffer, 81, DEFAULT_TIMEOUT / 2, 2);
   1487 
   1488 	ModemVerboseOn = true;
   1489 	ModemEchoOn = true;
   1490 
   1491 
   1492 
   1493 
   1494 
   1495 	/*
   1496 	** Try sending a plain old AT command to the modem. Now that we have theoretically
   1497 	** turned on verbose result codes we should get an 'OK' back.
   1498 	**
   1499 	*/
   1500 	status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 2 );
   1501 
   1502 	if (status < ASSUCCESS) {
   1503 #ifdef FIXIT_MULTI_SAVE
   1504 		return(false);
   1505 #else
   1506 		if (WWMessageBox().Process(TXT_ERROR_NO_RESP, TXT_IGNORE, TXT_CANCEL)) return( false );
   1507 		error_count++;
   1508 #endif
   1509 	}
   1510 
   1511 	/*
   1512 	** Send the user supplied modem init string
   1513 	*/
   1514 	if (settings->InitStringIndex == -1) {
   1515 		status = Send_Modem_Command( "", '\r', buffer, 81, 300, 1 );
   1516 	} else {
   1517 		/*
   1518 		** Split up the init string into seperate strings if it contains one or more '|' characters.
   1519 		** This character acts as a carriage return/pause.
   1520 		*/
   1521 		char *istr = new char [2 + strlen( Session.InitStrings [settings->InitStringIndex] )];
   1522 		char *tokenptr;
   1523 		strcpy (istr, Session.InitStrings [settings->InitStringIndex] );
   1524 
   1525 		/*
   1526 		** Tokenise the string and send it in chunks
   1527 		*/
   1528 		tokenptr = strtok ( istr, "|" );
   1529 		while ( tokenptr ) {
   1530 
   1531 			status = Send_Modem_Command( tokenptr, '\r', buffer, 81, 3000, 1 );
   1532 			/*
   1533 			** Handle error case.
   1534 			*/
   1535 			if (status < ASSUCCESS) {
   1536 				if (WWMessageBox().Process(TXT_ERROR_NO_INIT, TXT_IGNORE, TXT_CANCEL)) {
   1537 					delete istr;
   1538 					return( false );
   1539 				}
   1540 #ifdef WIN32
   1541 				error_count++;
   1542 #endif	//WIN32
   1543 				break;
   1544 			}
   1545 
   1546 			tokenptr = strtok ( NULL, "|");
   1547 
   1548 		}
   1549 	}
   1550 
   1551 #ifdef WIN32
   1552 
   1553 	if (settings->Port == 1 && ModemRegistry) {
   1554 		/*
   1555 		** Send the init strings from the registry if available
   1556 		*/
   1557 		char send_string[256] = {"AT"};
   1558 
   1559 		/*
   1560 		** Send the init string for hardware flow control
   1561 		*/
   1562 		if (settings->HardwareFlowControl){
   1563 			if (ModemRegistry->Get_Modem_Hardware_Flow_Control()) {
   1564 				strcpy (&send_string[2], ModemRegistry->Get_Modem_Hardware_Flow_Control());
   1565 				status = Send_Modem_Command (send_string, '\r', buffer, 81, 300, 1);
   1566 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1567 					if (WWMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1568 				}
   1569 			}
   1570 		}else{
   1571 			/*
   1572 			** Send the init string for no flow control
   1573 			*/
   1574 			if (ModemRegistry->Get_Modem_No_Flow_Control()) {
   1575 				strcpy (&send_string[2], ModemRegistry->Get_Modem_No_Flow_Control());
   1576 				status = Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
   1577 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1578 					if (WWMessageBox().Process(TXT_NO_FLOW_CONTROL_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1579 				}
   1580 			}
   1581 		}
   1582 
   1583 
   1584 		/*
   1585 		** Send the string for data compresseion
   1586 		*/
   1587 		if (settings->Compression){
   1588 
   1589 			if (ModemRegistry->Get_Modem_Compression_Enable()) {
   1590 				strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Enable());
   1591 				Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
   1592 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1593 					if (WWMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1594 				}
   1595 			}
   1596 		}else{
   1597 
   1598 			if (ModemRegistry->Get_Modem_Compression_Disable()) {
   1599 				strcpy (&send_string[2], ModemRegistry->Get_Modem_Compression_Disable());
   1600 				Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
   1601 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1602 					if (WWMessageBox().Process(TXT_NO_COMPRESSION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1603 				}
   1604 			}
   1605 		}
   1606 
   1607 
   1608 		/*
   1609 		** Send the string for error correction
   1610 		*/
   1611 		if (settings->ErrorCorrection){
   1612 
   1613 			if (ModemRegistry->Get_Modem_Error_Correction_Enable()) {
   1614 				strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Enable());
   1615 				Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
   1616 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1617 					if (WWMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1618 				}
   1619 			}
   1620 		}else{
   1621 			if (ModemRegistry->Get_Modem_Error_Correction_Disable()) {
   1622 				strcpy (&send_string[2], ModemRegistry->Get_Modem_Error_Correction_Disable());
   1623 				Send_Modem_Command (send_string, '\r', buffer, 81, DEFAULT_TIMEOUT, 1);
   1624 				if (status != MODEM_CMD_OK && status != MODEM_CMD_0) {
   1625 					if (WWMessageBox().Process(TXT_NO_ERROR_CORRECTION_RESPONSE, TXT_IGNORE, TXT_CANCEL)) return (false);
   1626 				}
   1627 			}
   1628 		}
   1629 	}
   1630 
   1631 #endif	//WIN32
   1632 
   1633 
   1634 	/*
   1635 	** We require that auto-answer be disabled so turn it off now.
   1636 	*/
   1637 	status = Send_Modem_Command( "ATS0=0", '\r', buffer, 81, DEFAULT_TIMEOUT, INIT_COMMAND_RETRIES );
   1638 	if (status != MODEM_CMD_OK) {
   1639 		if (WWMessageBox().Process(TXT_ERROR_NO_DISABLE, TXT_IGNORE, TXT_CANCEL)) return( false );
   1640 		error_count++;
   1641 	}
   1642 
   1643 	/*
   1644 	** If we had an unreasonable number of ignored errors then return failure
   1645 	*/
   1646 	if (error_count >= 3) {
   1647 		WWMessageBox().Process(TXT_ERROR_TOO_MANY, TXT_OK);
   1648 		return (false);
   1649 	}
   1650 
   1651 	return( true );
   1652 }
   1653 
   1654 
   1655 /***************************************************************************
   1656  * NullModemClass::Dial_Modem -- dials a number passed                     *
   1657  *                                                                         *
   1658  * INPUT:                                                                  *
   1659  *		settings		ptr to SerialSettings structure     						  *
   1660  *                                                                         *
   1661  * OUTPUT:                                                                 *
   1662  *		status		DialStatus															  *
   1663  *                                                                         *
   1664  * WARNINGS:                                                               *
   1665  *		none.																					  *
   1666  *                                                                         *
   1667  * HISTORY:                                                                *
   1668  *   06/02/1995 DRD : Created.                                             *
   1669  *   8/2/96      ST : Win32 support                                        *
   1670  *=========================================================================*/
   1671 DialStatusType NullModemClass::Dial_Modem( char *string, DialMethodType method, bool reconnect )
   1672 {
   1673 	/*
   1674 	** Get the resolution factor
   1675 	*/
   1676 //	int factor = SeenBuff.Get_Width()/320;
   1677 
   1678 	/*------------------------------------------------------------------------
   1679 	Button Enumerations
   1680 	------------------------------------------------------------------------*/
   1681 	enum {
   1682 		BUTTON_CANCEL = 100,
   1683 	};
   1684 
   1685 	/*------------------------------------------------------------------------
   1686 	Dialog variables
   1687 	------------------------------------------------------------------------*/
   1688 	bool process = true;						// process while true
   1689 #ifndef WIN32
   1690 	int status;
   1691 #endif	//WIN32
   1692 	int delay;
   1693 	DialStatusType dialstatus;
   1694 
   1695 	int x,y,width,height;					// dialog dimensions
   1696 	char buffer[80*3];
   1697 
   1698 
   1699 	/*------------------------------------------------------------------------
   1700 	Determine the dimensions of the text to be used for the dialog box.
   1701 	These dimensions will control how the dialog box looks.
   1702 	------------------------------------------------------------------------*/
   1703 	if (reconnect) {
   1704 		strcpy( buffer, Text_String( TXT_MODEM_CONNERR_REDIALING ) );
   1705 	} else {
   1706 		strcpy( buffer, Text_String( TXT_DIALING ) );
   1707 	}
   1708 
   1709 	Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_TEXT);
   1710 	Format_Window_String(buffer, SeenBuff.Get_Height(), width, height);
   1711 
   1712 	int text_width = width;
   1713 	width = max(width, 90 * RESFACTOR);
   1714 	width += 40 * RESFACTOR;
   1715 	height += 60 * RESFACTOR;
   1716 
   1717 	x = (SeenBuff.Get_Width() - width) / 2;
   1718 	y = (SeenBuff.Get_Height() - height) / 2;
   1719 
   1720 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
   1721 		x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8 * RESFACTOR)) >> 1),
   1722 		y + height - (FontHeight + FontYSpacing + 2 * RESFACTOR) - 10 * RESFACTOR);
   1723 
   1724 	/*------------------------------------------------------------------------
   1725 	Initialize
   1726 	------------------------------------------------------------------------*/
   1727 	Set_Logic_Page(SeenBuff);
   1728 
   1729 	/*------------------------------------------------------------------------
   1730 	Create the list
   1731 	------------------------------------------------------------------------*/
   1732 	Commands = &cancelbtn;
   1733 
   1734 	Commands->Flag_List_To_Redraw();
   1735 
   1736 	/*------------------------------------------------------------------------
   1737 	Draw the dialog
   1738 	------------------------------------------------------------------------*/
   1739 	Hide_Mouse();
   1740 	if ( !reconnect ) {
   1741 		Load_Title_Page(true);
   1742 	}
   1743 
   1744 	Dialog_Box(x, y, width, height);
   1745 	Draw_Caption(TXT_NONE, x, y, width);
   1746 
   1747 	Fancy_Text_Print(buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25 *RESFACTOR, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT);
   1748 
   1749 	Commands->Draw_All();
   1750 	Show_Mouse();
   1751 
   1752 	/*
   1753 	** Start waiting for connection response
   1754 	*/
   1755 #ifdef WIN32
   1756 	SerialPort->Set_Modem_Dial_Type((WinCommDialMethodType) method);
   1757 	/*
   1758 	** Clear out any old modem results that might be hanging around
   1759 	*/
   1760 	SerialPort->Get_Modem_Result(60, buffer, 81);
   1761 	/*
   1762 	** Dial that sucker
   1763 	*/
   1764 	SerialPort->Dial_Modem(string);
   1765 
   1766 #else	//WIN32
   1767 	HMSetDialingMethod( Port, (int)method );
   1768 	status = HMDial( Port, string );
   1769 
   1770 #endif	//WIN32
   1771 
   1772 
   1773 	/*
   1774 	** Sets up the ability to abort modem commands when any input is in the
   1775 	** Keyboard buffer.  This also calls the game CallBack().
   1776 	*/
   1777 	Setup_Abort_Modem();
   1778 
   1779 	/*------------------------------------------------------------------------
   1780 	Main Processing Loop
   1781 	------------------------------------------------------------------------*/
   1782 	process = true;
   1783 	delay = ModemWaitCarrier;
   1784 	while (process) {
   1785 #ifdef WIN32
   1786 		/*
   1787 		** If we have just received input focus again after running in the background then
   1788 		** we need to redraw.
   1789 		*/
   1790 		if (AllSurfaces.SurfacesRestored) {
   1791 			AllSurfaces.SurfacesRestored=FALSE;
   1792 			Commands->Draw_All();
   1793 		}
   1794 
   1795 		delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
   1796 #else	//WIN32
   1797 		delay = HMInputLine( Port, delay, buffer, 81 );
   1798 #endif	//WIN32
   1799 
   1800 		/*.....................................................................
   1801 		Process input
   1802 		.....................................................................*/
   1803 		switch (Input) {
   1804 			case (KN_ESC):
   1805 			case (BUTTON_CANCEL | KN_BUTTON):
   1806 				dialstatus = DIAL_CANCELED;
   1807 				process = false;
   1808 				break;
   1809 
   1810 			default:
   1811 				break;
   1812 		}
   1813 
   1814 		if (process) {
   1815 			if ( strncmp( buffer, "CON", 3 ) == 0 ) {
   1816 				memset (ModemRXString, 0, 80);
   1817 				strncpy (ModemRXString, buffer, 79);
   1818 				dialstatus = DIAL_CONNECTED;
   1819 				process = false;
   1820 			} else if ( strncmp( buffer, "BUSY", 4 ) == 0 ) {
   1821 				dialstatus = DIAL_BUSY;
   1822 				process = false;
   1823 			} else if ( strncmp( buffer, "NO C", 4 ) == 0 ) {
   1824 				dialstatus = DIAL_NO_CARRIER;
   1825 				process = false;
   1826 			} else if ( strncmp( buffer, "NO D", 4 ) == 0 ) {
   1827 				dialstatus = DIAL_NO_DIAL_TONE;
   1828 				process = false;
   1829 			} else if ( strncmp( buffer, "ERRO", 4 ) == 0 ) {
   1830 				dialstatus = DIAL_ERROR;
   1831 				process = false;
   1832 			}
   1833 		}
   1834 
   1835 		if (delay <= 0) {
   1836 			process = false;
   1837 		}
   1838 	}
   1839 
   1840 	Remove_Abort_Modem();
   1841 
   1842 	return( dialstatus );
   1843 
   1844 }	/* end of Dial_Modem */
   1845 
   1846 
   1847 /***************************************************************************
   1848  * NullModemClass::Answer_Modem -- waits for call and answers              *
   1849  *                                                                         *
   1850  * INPUT:                                                                  *
   1851  *		reconnect	whether this is to reconnect		     						  *
   1852  *                                                                         *
   1853  * OUTPUT:                                                                 *
   1854  *		status		DialStatus															  *
   1855  *                                                                         *
   1856  * WARNINGS:                                                               *
   1857  *		none.																					  *
   1858  *                                                                         *
   1859  * HISTORY:                                                                *
   1860  *   06/02/1995 DRD : Created.                                             *
   1861  *   8/2/96      ST : Added Win32 support                                  *
   1862  *=========================================================================*/
   1863 DialStatusType NullModemClass::Answer_Modem( bool reconnect )
   1864 {
   1865 	/*
   1866 	** Get the resolution factor
   1867 	*/
   1868 //	int factor 		= (SeenBuff.Get_Width() == 320) ? 1 : 2;
   1869 
   1870 	/*------------------------------------------------------------------------
   1871 	Button Enumerations
   1872 	------------------------------------------------------------------------*/
   1873 	enum {
   1874 		BUTTON_CANCEL = 100,
   1875 	};
   1876 
   1877 	/*------------------------------------------------------------------------
   1878 	Redraw values: in order from "top" to "bottom" layer of the dialog
   1879 	------------------------------------------------------------------------*/
   1880 	typedef enum {
   1881 		REDRAW_NONE = 0,
   1882 		REDRAW_BUTTONS,
   1883 		REDRAW_BACKGROUND,
   1884 		REDRAW_ALL = REDRAW_BACKGROUND
   1885 	} RedrawType;
   1886 
   1887 	/*------------------------------------------------------------------------
   1888 	Dialog variables
   1889 	------------------------------------------------------------------------*/
   1890 	RedrawType display = REDRAW_ALL;		// redraw level
   1891 	bool process = true;						// process while true
   1892 #ifndef WIN32
   1893 	int status;
   1894 #endif	//WIN32
   1895 	int delay;
   1896 	DialStatusType dialstatus;
   1897 	bool ring = false;
   1898 
   1899 	int x,y,width,height;					// dialog dimensions
   1900 	int text_width;
   1901 	char text_buffer[80*3];
   1902 	char comm_buffer[80*3];
   1903 
   1904 	/*------------------------------------------------------------------------
   1905 	Determine the dimensions of the text to be used for the dialog box.
   1906 	These dimensions will control how the dialog box looks.
   1907 	------------------------------------------------------------------------*/
   1908 	if (reconnect) {
   1909 		strcpy( text_buffer, Text_String( TXT_MODEM_CONNERR_WAITING ) );
   1910 	} else {
   1911 		strcpy( text_buffer, Text_String( TXT_WAITING_FOR_CALL ) );
   1912 	}
   1913 
   1914 	Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TEXT);
   1915 	Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height);
   1916 
   1917 	text_width = width;
   1918 	width = max(width, 90 * RESFACTOR);
   1919 	width += 40 * RESFACTOR;
   1920 	height += 60 * RESFACTOR;
   1921 
   1922 	x = (SeenBuff.Get_Width() - width) / 2;
   1923 	y = (SeenBuff.Get_Height() - height) / 2;
   1924 
   1925 	TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON,
   1926 		x + ((width - (String_Pixel_Width( Text_String( TXT_CANCEL ) ) + 8 * RESFACTOR)) >> 1),
   1927 		y + height - (FontHeight + FontYSpacing + 2 * RESFACTOR) - 10 * RESFACTOR);
   1928 
   1929 	/*------------------------------------------------------------------------
   1930 	Initialize
   1931 	------------------------------------------------------------------------*/
   1932 	Set_Logic_Page(SeenBuff);
   1933 	Load_Title_Page(true);
   1934 
   1935 	Input = KN_NONE;
   1936 
   1937 	/*------------------------------------------------------------------------
   1938 	Create the list
   1939 	------------------------------------------------------------------------*/
   1940 	Commands = &cancelbtn;
   1941 
   1942 	Commands->Flag_List_To_Redraw();
   1943 
   1944 	/*
   1945 	** Sets up the ability to abort modem commands when any input is in the
   1946 	** Keyboard buffer.  This also calls the game CallBack() and Input().
   1947 	*/
   1948 	Setup_Abort_Modem();
   1949 
   1950 	/*------------------------------------------------------------------------
   1951 	Main Processing Loop
   1952 	------------------------------------------------------------------------*/
   1953 	process = true;
   1954 	delay = 60000;
   1955 	while (process) {
   1956 #ifdef WIN32
   1957 		/*
   1958 		** If we have just received input focus again after running in the background then
   1959 		** we need to redraw.
   1960 		*/
   1961 		if (AllSurfaces.SurfacesRestored) {
   1962 			AllSurfaces.SurfacesRestored=FALSE;
   1963 			display=REDRAW_ALL;
   1964 		}
   1965 #endif	//WIN32
   1966 
   1967 		/*.....................................................................
   1968 		Refresh display if needed
   1969 		.....................................................................*/
   1970 		if (display) {
   1971 			Hide_Mouse();
   1972 			if (display >= REDRAW_BACKGROUND) {
   1973 				/*...............................................................
   1974 				Refresh the backdrop
   1975 				...............................................................*/
   1976 				if ( !reconnect ) {
   1977 					Load_Title_Page(true);
   1978 				}
   1979 
   1980 				/*...............................................................
   1981 				Draw the background
   1982 				...............................................................*/
   1983 				Dialog_Box(x, y, width, height);
   1984 
   1985 				/*...............................................................
   1986 				Draw the labels
   1987 				...............................................................*/
   1988 				Draw_Caption(TXT_NONE, x, y, width);
   1989 
   1990 				Fancy_Text_Print(text_buffer, SeenBuff.Get_Width()/2 - text_width/2, y + 25 * RESFACTOR,
   1991 					GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT);
   1992 
   1993 				Commands->Draw_All();
   1994 			}
   1995 			Show_Mouse();
   1996 			display = REDRAW_NONE;
   1997 		}
   1998 
   1999 #ifdef WIN32
   2000 		delay = SerialPort->Get_Modem_Result(delay, comm_buffer, 81);
   2001 #else	//WIN32
   2002 		delay = HMInputLine( Port, delay, comm_buffer, 81 );
   2003 #endif	//WIN32
   2004 
   2005 
   2006 		/*.....................................................................
   2007 		Process input
   2008 		.....................................................................*/
   2009 		if (!Input) Input = Commands->Input();
   2010 		switch (Input) {
   2011 			case (KN_ESC):
   2012 			case (BUTTON_CANCEL | KN_BUTTON):
   2013 				dialstatus = DIAL_CANCELED;
   2014 				process = false;
   2015 				break;
   2016 
   2017 			default:
   2018 				break;
   2019 		}
   2020 
   2021 		if (process) {
   2022 			if ( strncmp( comm_buffer, "RING", 4 ) == 0 ) {
   2023 
   2024 				strcpy( text_buffer, Text_String( TXT_ANSWERING ) );
   2025 
   2026 				Fancy_Text_Print(TXT_NONE,0,0,TBLACK,TBLACK,TPF_TEXT);
   2027 				Format_Window_String(text_buffer, SeenBuff.Get_Height(), width, height);
   2028 
   2029 				text_width = width;
   2030 				width = max(width, 90 * RESFACTOR);
   2031 				width += 40 * RESFACTOR;
   2032 				height += 60 * RESFACTOR;
   2033 
   2034 				x = (SeenBuff.Get_Width() - width) / 2;
   2035 				y = (SeenBuff.Get_Height() - height) / 2;
   2036 
   2037 #ifdef WIN32
   2038 				SerialPort->Write_To_Serial_Port ((unsigned char*)"ATA\r", strlen("ATA\r"));
   2039 #else	//WIN32
   2040 				PortKillTime( Port, 100 );
   2041 				HMWaitForOK( 0, NULL );
   2042 				status = HMAnswer( Port );
   2043 #endif	//WIN32
   2044 
   2045 				ring = true;
   2046 				delay = ModemWaitCarrier;
   2047 				display = REDRAW_ALL;
   2048 			} else if ( strncmp( comm_buffer, "CON", 3 ) == 0 ) {
   2049 				memset (ModemRXString, 0, 80);
   2050 				strncpy (ModemRXString, comm_buffer, 79);
   2051 				dialstatus = DIAL_CONNECTED;
   2052 				process = false;
   2053 			} else if ( strncmp( comm_buffer, "BUSY", 4 ) == 0 ) {
   2054 				dialstatus = DIAL_BUSY;
   2055 				process = false;
   2056 			} else if ( strncmp( comm_buffer, "NO C", 4 ) == 0 ) {
   2057 				dialstatus = DIAL_NO_CARRIER;
   2058 				process = false;
   2059 			} else if ( strncmp( comm_buffer, "ERRO", 4 ) == 0 ) {
   2060 				dialstatus = DIAL_ERROR;
   2061 				WWMessageBox().Process(TXT_ERROR_ERROR, TXT_OK);
   2062 				process = false;
   2063 			}
   2064 		}
   2065 
   2066 #ifdef WIN32
   2067 
   2068 		if (delay <= 0) {
   2069 			if (ring) {
   2070 				if (SerialPort->Get_Modem_Status() & CD_SET) {
   2071 					sprintf(ModemRXString, "%s", "Connected");
   2072 					dialstatus = DIAL_CONNECTED;
   2073 				} else {
   2074 					dialstatus = DIAL_ERROR;
   2075 					WWMessageBox().Process(TXT_ERROR_TIMEOUT, TXT_OK);
   2076 				}
   2077 				process = false;
   2078 			} else {
   2079 				delay = 60000;
   2080 			}
   2081 		}
   2082 #else	//WIN32
   2083 
   2084 		if (delay <= 0) {
   2085 			if (ring) {
   2086 				process = false;
   2087 			} else {
   2088 				delay = 60000;
   2089 			}
   2090 		}
   2091 #endif	//WIN32
   2092 
   2093 	}
   2094 
   2095 	Remove_Abort_Modem();
   2096 
   2097 	return( dialstatus );
   2098 
   2099 }	/* end of Answer_Modem */
   2100 
   2101 
   2102 /***************************************************************************
   2103  * NullModemClass::Hangup_Modem -- hangs up the modem                      *
   2104  *                                                                         *
   2105  * INPUT:                                                                  *
   2106  *		none																					  *
   2107  *                                                                         *
   2108  * OUTPUT:                                                                 *
   2109  *		status		successful or not													  *
   2110  *                                                                         *
   2111  * WARNINGS:                                                               *
   2112  *		none.																					  *
   2113  *                                                                         *
   2114  * HISTORY:                                                                *
   2115  *   06/02/1995 DRD : Created.                                             *
   2116  *   8/2/96         : Added Win32 support                                  *
   2117  *=========================================================================*/
   2118 bool NullModemClass::Hangup_Modem( void )
   2119 {
   2120 	int status;
   2121 	int delay;
   2122 	char buffer[81];
   2123 	char escape[4];
   2124 
   2125 	/*
   2126 	**	Turn modem servicing off in the callback routine.
   2127 	*/
   2128 	Session.ModemService = false;
   2129 
   2130 	status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
   2131 
   2132 	if (status == MODEM_CMD_OK) {
   2133 		Session.ModemService = true;
   2134 		return( true );
   2135 	}
   2136 
   2137 	/*
   2138 	** Toggle DTR low then high
   2139 	*/
   2140 #ifdef WIN32
   2141 	SerialPort->Set_Serial_DTR(FALSE);
   2142 	Delay(3200/60);
   2143 	SerialPort->Set_Serial_DTR(TRUE);
   2144 #else	//WIN32
   2145 
   2146 	SetDtr( Port, 0 );
   2147 	PortKillTime( Port, 3200 );
   2148 	SetDtr( Port, 1 );
   2149 #endif	//WIN32
   2150 
   2151 	status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
   2152 
   2153 	if (status == MODEM_CMD_OK) {
   2154 		Session.ModemService = true;
   2155 		return( true );
   2156 	}
   2157 
   2158 	delay = ModemGuardTime;
   2159 	while ( delay > 0 ) {
   2160 #ifdef WIN32
   2161 		delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
   2162 #else	//WIN32
   2163 		delay = HMInputLine( Port, delay, buffer, 81 );
   2164 #endif	//WIN32
   2165 	}
   2166 
   2167 	/*
   2168 	** Send modem break commmand
   2169 	*/
   2170 	escape[0] = ModemEscapeCode;
   2171 	escape[1] = ModemEscapeCode;
   2172 	escape[2] = ModemEscapeCode;
   2173 	escape[3] = 0;
   2174 
   2175 #ifdef WIN32
   2176 	SerialPort->Write_To_Serial_Port((unsigned char*)escape, 3);
   2177 #else	//WIN32
   2178 	status = HMSendStringNoWait( Port, escape, -1 );
   2179 #endif	//WIN32
   2180 
   2181 
   2182 	delay = ModemGuardTime;
   2183 	while ( delay > 0 ) {
   2184 #ifdef WIN32
   2185 		delay = SerialPort->Get_Modem_Result(delay, buffer, 81);
   2186 #else	//WIN32
   2187 		delay = HMInputLine( Port, delay, buffer, 81 );
   2188 #endif	//WIN32
   2189 
   2190 		if ( strncmp( buffer, "OK", 2 ) == 0 ) {
   2191 			break;
   2192 		}
   2193 	}
   2194 
   2195 	/*
   2196 	** Send the hangup command
   2197 	*/
   2198 	status = Send_Modem_Command( "ATH", '\r', buffer, 81, ModemHangupDelay, 1 );
   2199 
   2200 	if (status == MODEM_CMD_OK) {
   2201 	} else {
   2202 		Session.ModemService = true;
   2203 		return( false );
   2204 	}
   2205 
   2206 	/*
   2207 	** Send spurious ATZ command for no apparent reason
   2208 	*/
   2209 	status = Send_Modem_Command( "ATZ", '\r', buffer, 81, 5000, 1 );
   2210 
   2211 	if (status != MODEM_CMD_OK) {
   2212 		Session.ModemService = true;
   2213 		return( false );
   2214 	}
   2215 
   2216 	Session.ModemService = true;
   2217 	return( true );
   2218 
   2219 }	/* end of Hangup_Modem */
   2220 
   2221 
   2222 /***********************************************************************************************
   2223  * NMC::Setup_Modem_Echo -- Sets the echo callback function pointer                            *
   2224  *                                                                                             *
   2225  *                                                                                             *
   2226  *                                                                                             *
   2227  * INPUT:    Ptr to callback function                                                          *
   2228  *                                                                                             *
   2229  * OUTPUT:   Nothing                                                                           *
   2230  *                                                                                             *
   2231  * WARNINGS: None                                                                              *
   2232  *                                                                                             *
   2233  * HISTORY:                                                                                    *
   2234  *    8/2/96 12:48PM ST : Documented and added WIn32 support                                   *
   2235  *=============================================================================================*/
   2236 void NullModemClass::Setup_Modem_Echo( void ( *func )( char c) )
   2237 {
   2238 #ifdef WIN32
   2239 	SerialPort->Set_Echo_Function(func);
   2240 #else	//WIN32
   2241 	HMSetUpEchoRoutine( func );
   2242 #endif	//WIN32
   2243 
   2244 }	/* end of Setup_Modem_Echo */
   2245 
   2246 
   2247 /***********************************************************************************************
   2248  * NMC::Remove_Modem_Echo -- Set the echo function callback pointer to null                    *
   2249  *                                                                                             *
   2250  *                                                                                             *
   2251  *                                                                                             *
   2252  * INPUT:    Nothing                                                                           *
   2253  *                                                                                             *
   2254  * OUTPUT:   Nothing                                                                           *
   2255  *                                                                                             *
   2256  * WARNINGS: None                                                                              *
   2257  *                                                                                             *
   2258  * HISTORY:                                                                                    *
   2259  *    8/2/96 12:50PM ST : Documented / Win32 support added                                     *
   2260  *=============================================================================================*/
   2261 void NullModemClass::Remove_Modem_Echo( void )
   2262 {
   2263 //	Smart_Printf( "Remove Echo modem code\n" );
   2264 	HMSetUpEchoRoutine( NULL );
   2265 
   2266 }	/* end of Remove_Modem_Echo */
   2267 
   2268 
   2269 
   2270 /***********************************************************************************************
   2271  * NMC::Print_EchoBuf -- Print out the contents of the echo buffer                             *
   2272  *                                                                                             *
   2273  *                                                                                             *
   2274  *                                                                                             *
   2275  * INPUT:    Nothing                                                                           *
   2276  *                                                                                             *
   2277  * OUTPUT:   Nothing                                                                           *
   2278  *                                                                                             *
   2279  * WARNINGS: None                                                                              *
   2280  *                                                                                             *
   2281  * HISTORY:                                                                                    *
   2282  *    8/2/96 12:51PM ST : Documented                                                           *
   2283  *=============================================================================================*/
   2284 void NullModemClass::Print_EchoBuf( void )
   2285 {
   2286 	for (int i = 0; i < strlen(NullModem.EchoBuf); i++) {
   2287 		if (NullModem.EchoBuf[i] == '\r') {
   2288 			NullModem.EchoBuf[i] = 1;
   2289 		} else {
   2290 			if (NullModem.EchoBuf[i] == '\n') {
   2291 				NullModem.EchoBuf[i] = 2;
   2292 			}
   2293 		}
   2294 	}
   2295 //	Smart_Printf( "Echo buffer length %d (%s)\n", NullModem.EchoCount, NullModem.EchoBuf );
   2296 }
   2297 
   2298 
   2299 
   2300 /***********************************************************************************************
   2301  * NMC::Reset_EchoBuf -- Empties the echo buffer                                               *
   2302  *                                                                                             *
   2303  *                                                                                             *
   2304  *                                                                                             *
   2305  * INPUT:    Nothing                                                                           *
   2306  *                                                                                             *
   2307  * OUTPUT:   Nothing                                                                           *
   2308  *                                                                                             *
   2309  * WARNINGS: None                                                                              *
   2310  *                                                                                             *
   2311  * HISTORY:                                                                                    *
   2312  *    8/2/96 12:51PM ST : Documented                                                           *
   2313  *=============================================================================================*/
   2314 void NullModemClass::Reset_EchoBuf( void )
   2315 {
   2316 	*EchoBuf = 0;
   2317 	EchoCount = 0;
   2318 }
   2319 
   2320 
   2321 /***********************************************************************************************
   2322  * NMC::Abort_Modem -- Checks for user input so that modem operations can be aborted           *
   2323  *                                                                                             *
   2324  *                                                                                             *
   2325  *                                                                                             *
   2326  * INPUT:    Nothing                                                                           *
   2327  *                                                                                             *
   2328  * OUTPUT:   ASUSERABORT if abort key pressed. ASSUCESS otherwise.                             *
   2329  *                                                                                             *
   2330  * WARNINGS: None                                                                              *
   2331  *                                                                                             *
   2332  * HISTORY:                                                                                    *
   2333  *    8/2/96 12:52PM ST : Documented                                                           *
   2334  *=============================================================================================*/
   2335 int NullModemClass::Abort_Modem( PORT * )
   2336 {
   2337 	/*
   2338 	** Button Enumerations
   2339 	*/
   2340 	enum {
   2341 		BUTTON_CANCEL = 100,
   2342 	};
   2343 
   2344 	/*
   2345 	** Invoke game callback
   2346 	*/
   2347 	Call_Back();
   2348 
   2349 	/*
   2350 	** Get user input
   2351 	*/
   2352 	Input = Commands->Input();
   2353 
   2354 	switch ( Input ) {
   2355 		case (KN_ESC):
   2356 		case (BUTTON_CANCEL | KN_BUTTON):
   2357 			return( ASUSERABORT );
   2358 	}
   2359 
   2360 	return( ASSUCCESS );
   2361 
   2362 }	/* end of Abort_Modem */
   2363 
   2364 
   2365 /***********************************************************************************************
   2366  * NMC::Setup_Abort_Modem -- sets the modem abort function pointer                             *
   2367  *                                                                                             *
   2368  *                                                                                             *
   2369  *                                                                                             *
   2370  * INPUT:    Nothing                                                                           *
   2371  *                                                                                             *
   2372  * OUTPUT:   Nothing                                                                           *
   2373  *                                                                                             *
   2374  * WARNINGS: None                                                                              *
   2375  *                                                                                             *
   2376  * HISTORY:                                                                                    *
   2377  *    8/2/96 2:59PM ST : Documented / Win32 support added                                      *
   2378  *=============================================================================================*/
   2379 void NullModemClass::Setup_Abort_Modem( void )
   2380 {
   2381 
   2382 #ifdef WIN32
   2383 
   2384 	SerialPort->Set_Abort_Function((int(*)(void))Abort_Modem);
   2385 
   2386 #else	//WIN32
   2387 	/*
   2388 	** save off original abort modem function to later restore
   2389 	*/
   2390 	OrigAbortModemFunc = _AbortModemFunctionPtr;
   2391 	HMSetUpAbortKey( ESC );
   2392 	SetAbortModemFunctionPtr( Abort_Modem );
   2393 #endif	//WIN32
   2394 
   2395 }	/* end of Setup_Abort_Modem */
   2396 
   2397 
   2398 /***********************************************************************************************
   2399  * NMC::Remove_Abort_Modem -- Removes the modem abort function pointer                         *
   2400  *                                                                                             *
   2401  *                                                                                             *
   2402  *                                                                                             *
   2403  * INPUT:    Nothing                                                                           *
   2404  *                                                                                             *
   2405  * OUTPUT:   Nothing                                                                           *
   2406  *                                                                                             *
   2407  * WARNINGS: None                                                                              *
   2408  *                                                                                             *
   2409  * HISTORY:                                                                                    *
   2410  *    8/2/96 3:01PM ST : Documented / Win32 support added                                      *
   2411  *=============================================================================================*/
   2412 void NullModemClass::Remove_Abort_Modem( void )
   2413 {
   2414 
   2415 #ifdef WIN32
   2416 	SerialPort->Set_Abort_Function(NULL);
   2417 
   2418 #else	//WIN32
   2419 
   2420 	HMSetUpAbortKey( NOKEY );
   2421 
   2422 	/*
   2423 	** Restore the original abort modem function
   2424 	*/
   2425 	_AbortModemFunctionPtr = OrigAbortModemFunc;
   2426 #endif	//WIN32
   2427 
   2428 }	/* end of Remove_Abort_Modem */
   2429 
   2430 
   2431 
   2432 /***********************************************************************************************
   2433  * NMC::Change_IRQ_Priority -- Increases the priority of the serial interrupt                  *
   2434  *                                                                                             *
   2435  *                                                                                             *
   2436  *                                                                                             *
   2437  * INPUT:    Interrupt request number                                                          *
   2438  *                                                                                             *
   2439  * OUTPUT:   ASSUCCESS if changed                                                              *
   2440  *                                                                                             *
   2441  * WARNINGS: The Win32 version of this function does nothing.                                  *
   2442  *           Priorities are controlled by windoze                                              *
   2443  *                                                                                             *
   2444  * HISTORY:                                                                                    *
   2445  *    8/2/96 3:03PM ST : Documented / Win32 support added                                      *
   2446  *=============================================================================================*/
   2447 int NullModemClass::Change_IRQ_Priority( int irq )
   2448 {
   2449 #ifdef WIN32
   2450 
   2451 	irq = irq;
   2452 	return ( ASSUCCESS );
   2453 
   2454 #else	//WIN32
   2455 
   2456 	if (irq != OldIRQPri) {
   2457 		OldIRQPri = irq;
   2458 		return( Change8259Priority( irq ) );
   2459 	} else {
   2460 		return( ASSUCCESS );
   2461 	}
   2462 
   2463 #endif	//WIN32
   2464 
   2465 }	/* end of Change_IRQ_Priority */
   2466 
   2467 
   2468 
   2469 /***********************************************************************************************
   2470  * NMC::Get_Modem_Status -- returns status of modem control bits                               *
   2471  *                                                                                             *
   2472  *                                                                                             *
   2473  *                                                                                             *
   2474  * INPUT:    Nothing                                                                           *
   2475  *                                                                                             *
   2476  * OUTPUT:   Modem status                                                                      *
   2477  *                                                                                             *
   2478  * WARNINGS: None                                                                              *
   2479  *                                                                                             *
   2480  * HISTORY:                                                                                    *
   2481  *    8/2/96 3:06PM ST : Documented / Win32 support added                                      *
   2482  *=============================================================================================*/
   2483 int NullModemClass::Get_Modem_Status( void )
   2484 {
   2485 	int modemstatus;
   2486 	int status;
   2487 	char buffer[81];
   2488 
   2489 #ifdef WIN32
   2490 	modemstatus = SerialPort->Get_Modem_Status();
   2491 #else	//WIN32
   2492 	modemstatus = GetModemStatus( Port );
   2493 #endif	//WIN32
   2494 
   2495 	status = Send_Modem_Command( "AT", '\r', buffer, 81, DEFAULT_TIMEOUT, 1 );
   2496 
   2497 	if (status == MODEM_CMD_OK) {
   2498 		modemstatus &= (~CD_SET);
   2499 	}
   2500 
   2501 	return( modemstatus );
   2502 
   2503 }	/* end of Get_Modem_Status */
   2504 
   2505 
   2506 /***********************************************************************************************
   2507  * NMC::Send_Modem_Command -- Sends an 'AT' command to the modem and gets the response         *
   2508  *                                                                                             *
   2509  *                                                                                             *
   2510  *                                                                                             *
   2511  * INPUT:    command to send to modem. e.g. 'ATZ'                                              *
   2512  *           terminator byte for command string                                                *
   2513  *           buffer to put modem response into                                                 *
   2514  *           length of above buffer                                                            *
   2515  *           delay to wait for response                                                        *
   2516  *           number of times to retry when modem doesnt respond                                *
   2517  *                                                                                             *
   2518  * OUTPUT:   input delay less the time it took the modem to respond                            *
   2519  *                                                                                             *
   2520  * WARNINGS: None                                                                              *
   2521  *                                                                                             *
   2522  * HISTORY:                                                                                    *
   2523  *    8/2/96 3:09PM ST : Documented / Win32 support added                                      *
   2524  *=============================================================================================*/
   2525 int NullModemClass::Send_Modem_Command( char *command, char terminator, char *buffer, int buflen, int delay, int retries )
   2526 {
   2527 
   2528 #ifdef WIN32
   2529 	return (SerialPort->Send_Command_To_Modem(command, terminator, buffer, buflen, delay, retries));
   2530 #else	//WIN32
   2531 
   2532 	int status, tmpdelay, retry;
   2533 	char tempbuf[81];
   2534 
   2535 
   2536 	*buffer = 0;
   2537 
   2538 	for ( retry = 0; retry < retries; retry++ ) {
   2539 
   2540 		PortKillTime( Port, 100 );
   2541 
   2542 		status = HMSendStringNoWait( Port, command, terminator );
   2543 
   2544 
   2545 		if (status < ASSUCCESS) {
   2546 			return( status );
   2547 		}
   2548 
   2549 		tmpdelay = delay;
   2550 		while ( tmpdelay > 0 ) {
   2551 
   2552 			tmpdelay = HMInputLine( Port, tmpdelay, tempbuf, 81 );
   2553 
   2554 			if ( strcmp( tempbuf, "OK" ) == 0 ) {
   2555 				return( MODEM_CMD_OK );
   2556 			} else if ( strcmp( tempbuf, "0" ) == 0 ) {
   2557 				return( MODEM_CMD_0 );
   2558 			} else if ( strcmp( tempbuf, "ERROR" ) == 0 ) {
   2559 				return( MODEM_CMD_ERROR );
   2560 			} else if ( tempbuf[0] != 0 ) {
   2561 				strncpy( buffer, tempbuf, buflen );
   2562 			}
   2563 		}
   2564 
   2565 		PortKillTime( Port, 100 );
   2566 
   2567 		/*
   2568 		**	Send and extra return to help clear out any problems with the modem (if any).
   2569 		*/
   2570 		HMWaitForOK( 300, NULL );
   2571 		status = HMSendString( Port, "" );
   2572 		HMWaitForOK( 0, NULL );
   2573 	}
   2574 
   2575 	return( tmpdelay );
   2576 
   2577 #endif	//WIN32
   2578 }
   2579 
   2580 
   2581 /***********************************************************************************************
   2582  * NMC::Verify_And_Convert_To_Int -- converts a text string of numbers to an int               *
   2583  *                                                                                             *
   2584  *                                                                                             *
   2585  *                                                                                             *
   2586  * INPUT:    ptr to buffer                                                                     *
   2587  *                                                                                             *
   2588  * OUTPUT:   value of text number in buffer                                                    *
   2589  *                                                                                             *
   2590  * WARNINGS: None                                                                              *
   2591  *                                                                                             *
   2592  * HISTORY:                                                                                    *
   2593  *    8/2/96 3:13PM ST : Documented                                                            *
   2594  *=============================================================================================*/
   2595 int NullModemClass::Verify_And_Convert_To_Int( char *buffer )
   2596 {
   2597 	int value = 0;
   2598 	int len = strlen(buffer);
   2599 
   2600 
   2601 	for (int i = 0; i < len; i++) {
   2602 		if ( !isdigit( *(buffer + i) ) ) {
   2603 			value = -1;
   2604 			break;
   2605 		}
   2606 	}
   2607 
   2608 	if (value == 0) {
   2609 		value = atoi( buffer );
   2610 	}
   2611 
   2612 	return( value );
   2613 
   2614 }	/* end of Verify_And_Convert_To_Int */
   2615 
   2616 /*************************** end of nullmgr.cpp ****************************/
   2617 
   2618 #endif