Exemple #1
0
/**
 * \brief       int16_t main() 
 *
 * \param[in]	pFileName - something like "dump_01.txt"
 * 
 * \param[out]	Description
 * 
 * \return		test framework main() routine 
 *              
 * 
 */
int
main (int argc, char *argv[])
{
	//  arg0 is the actual command line that invoked this program!
char *fileName = argv[1];
static char returnBuffer[BUFFER_LEN] = {'\0','\0','\0','\0','\0','\0','\0' };  
int16_t result;
int16_t fd = 0; 
int16_t autoIncrement = 0;
    // size of Front Panel Display - must be int variables for scanf() function
int frontPanelRows = 0;       
int frontPanelCols = 0;
// char *portName = "/dev/tty";  // use keyboard tty input for serial I/O
char *portName = NULL;

	printf("\n\n  Test Framework for vt100 emulator library ");
	printf("\n        (command syntax:  './vt filename')\n");
	
	  // get the working port name and fd 
	fd = vt100_getPortFd(portName);
	// portName = "/dev/ttyS3";
	
	   // Initial setup of arrays in memory 
	if( strcmp(fileName, "") == 0)  
			fileName = "disp_dumpVD.txt";
	
	printf("\n main: fileName is %s, portName is %s, port fd is %d \n", 
			fileName, portName, fd);
	 
	//  Due to Dynamic Memory Allocation - can not call any routines until vt100_start() is called 
	// result = vt100_dumpVD(fileName, 0, "Initial State");   // show original data array - with no number extenison
	// printf("\n\n Result of vt100_dumpVT = %d \n", result);
	// vt100_showVD(stdout, "Initial State");
	// do compare on intial state 
	// result = vt100_compareVD("display.8.40.start");
	// printf("\n Default compareVD: display.8.40.start = %d \n", result);
	
	printf("\n\n Number of rows in the Front Panel Display: ");
	scanf("%d", &frontPanelRows );
	printf("\n Number of columns in the Front Panel Display: ");
	scanf("%d", &frontPanelCols );
		
	  //  vt100_start() 

	printf("\n\n=================  vt100_start() =============\n");
	
	printf("\n - calling vt100_start() for port %s: with %d rows and %d columns\n", portName,
			     frontPanelRows, frontPanelCols);
	
    //	result = vt100_start(portName);   // modify array 
	result = vt100_start(NULL , frontPanelRows, frontPanelCols);   // modify array 
	if( result != 0 ) printf("\n  ... returned error code = %d ", result);
	printf("\n Initial states of errorCode: %d and errorText  %s ", 
			     vt100_get_errorCode(), vt100_get_errorText() );
	
	vt100_dumpVD("dump.vt100_start", ++autoIncrement, "after vt100_start()"); 
	vt100_showVD(stdout, "after vt100_start()");
	
	
	vt100_clearVD();     // initialize or clear the display rows & columns from malloc garbage
	printf("\n\n=========  vt100_clear - compare clear with display.clear =============\n");
	vt100_dumpVD("dump.after_1st_clear", ++autoIncrement, "after 1st clear"); 
	vt100_showVD(stdout, "after 1st vt100_clear(0 after the start()");
	result = vt100_compareVD("display.clear");
	printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, 
			"display.clear");
	if( result != 0 )
		printf("\n  errorText = %s", vt100_get_errorText() );

	printf("\n\n=================  vt100_set_auxSwitch() ON ===========================\n");
	
	result = vt100_set_auxSwitch( 1 );	
	vt100_dumpVD("auxSwitch.out", ++autoIncrement, "set_auxSwitch ON");     
	printf("\n\n Result vt100_set_auxSwitch = %d \n", result);
	vt100_showVD(stdout, "fileToVD");
	sleep(1);

	printf("\n\n=================  vt100_set_auxSwitch() OFF ==========================\n");
	
	result = vt100_set_auxSwitch( 0 );	
	vt100_dumpVD("auxSwitch.out", ++autoIncrement, "set_auxSwitch OFF");     
	printf("\n\n Result vt100_set_auxSwitch = %d \n", result);
	vt100_showVD(stdout, "fileToVD");
	sleep(1);
	
	printf("\n\n=================  vt100_fileToVD - short file '1234.in'  =============\n");
	
	result = vt100_fileToVD("1234.in");
	
	vt100_dumpVD("1234.out", ++autoIncrement, "fileToVD");     
	printf("\n\n Result vt100_fileToVD = %d \n", result);
	vt100_showVD(stdout, "fileToVD");
	sleep(1);
	printf("\n ------------- return buffer: ------------");
	vt100_vtInputBuffer(returnBuffer, sizeof (returnBuffer));
	printf("\n returnBuffer starts on next line: \n%s\n-------------------\n", returnBuffer);
	sleep(2);

	printf("\n\n=================  Command/Response sequences  ========\n");
	
	result = vt100_fileToVD("commands.in");
	sleep(1);
	vt100_dumpVD("cmdResponses.out", ++autoIncrement, "CMD Responses");     
	printf("\n\n Result of cmdResponses using vt100_fileToVD = %d \n", result);
	vt100_showVD(stdout, "CMD_Repsonses ");
	sleep(1);
	
	printf("\n\n=================  vt100_stringToVD  # 1 - very short =============\n");
	
	vt100_stringToVD("1234");
	
	result = vt100_dumpVD("displayString.txt", ++autoIncrement, "short stringToVD");     
	printf("\n\n Result of vt100_dumpVD = %d \n", result);
	vt100_showVD(stdout, "short vt100_stringToVD");

	
	printf("\n\n=================  vt100_stringToVD  # 2 - long multi-line  ========\n");
	
	vt100_stringToVD("This is a test \n#9999: of the emergency broadcasting system 0123456789ABC\n\n\n\tTAKE 2 \n\n\tThe END\t17abc\t25def\t33ghi\n\t\t\t7777");
	
	result = vt100_dumpVD("displayString.txt", ++autoIncrement, "long stringToVD");     
	printf("\n\n Result of vt100_dumpVD = %d \n", result);
	vt100_showVD(stdout, "long vt100_stringToVD");
    sleep(2);

	
	printf("\n\n============  Special Chars create (vt100_fileToVD) =============\n");
	
	vt100_clearVD();     // initialize or clear the display rows & columns 
	vt100_resetParms();  // restore all PARMs etc before doing Special Chars testing
	
	result = vt100_fileToVD("specialChars.in");
	
	vt100_dumpVD("specialChars.out", ++autoIncrement, "Special Chars");     
	printf("\n\n Result of Special Chars vt100_fileToVD = %d \n", result);
	vt100_showVD(stdout, "Special Chars Compose ");
	sleep(1);
	
	printf("\n\n=========== Special Chars compare  - display.special OK ============\n");

	result = vt100_compareVD("display.special");
	printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, 
			"display.special");

	if( result != 0 )
		printf("\n  errorText = %s ", vt100_get_errorText() );

	printf("\n\n======= Special Chars compare  - display.special.bad - FAIL ========\n");

	result = vt100_compareVD("display.special.bad");
	printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, 
			"display.special.bad");

	if( result != 0 )
		printf("\n  errorText = %s ", vt100_get_errorText() );

	printf("\n\n=============  vt100_fileToVD - junk screen =============\n");
	
	result = vt100_fileToVD("testFileToVD.in");
	
	vt100_dumpVD("testFileToVD.out", ++autoIncrement, "fileToVD");     
	printf("\n\n Result vt100_fileToVD = %d \n", result);
	vt100_showVD(stdout, "fileToVD");
	printf("\n - compare the testFileToVD.in with the display.testIput ");
	result = vt100_compareVD("display.testInput");
	printf("\n\n Result  = %d, for file: %s \n", result, "display.testIput");
	sleep(1);
	printf("\n ------------- return buffer: ------------");
	vt100_vtInputBuffer(returnBuffer, sizeof (returnBuffer));
	printf("\n returnBuffer starts on next line: \n%s\n-------------------\n", returnBuffer);
	sleep(1);

	printf("\n\n=============  Command/Response sequences  # 2    =======\n");
	
	result = vt100_fileToVD("commands.in");
	sleep(1);
	vt100_dumpVD("cmdResponses.out", ++autoIncrement, "CMD Responses");     
	printf("\n\n Result of cmdResponses using vt100_fileToVD = %d \n", result);
	vt100_showVD(stdout, "CMD_Repsonses ");
	sleep(1);

	
	printf("\n\n=================  vt100_fromDumptoVD - display.fpm =============\n");
	
	vt100_resetParms();      // restore to power up condition
	result = vt100_fromDumpToVD("display.fpm");
	
	vt100_dumpVD("test_fromDumpToVD.out", ++autoIncrement, "fromDumpToVD");     
	printf("\n\n Result vt100_fromDumpToVD = %d \n", result);
	vt100_showVD(stdout, "fromDumpToVD");
	
	printf("\n\n=================  vt100_compareVD - display.fpm =============\n");

	result = vt100_compareVD("display.fpm");
	printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, 
			"display.fpm");

	if( result != 0 )
		printf("\n  errorText = %s ", vt100_get_errorText() );

/*************************	don't need to test this any more .....	
	printf("\n\n=================  vt100_fromDumptoVD - bad file =======\n");
	
	result = vt100_fromDumpToVD("display.fail");
	
	vt100_dumpVD("test_fromDumpToVD.out", ++autoIncrement, "fromDumpToVD_FAIL");     
	printf("\n\n Result vt100_fromDumpToVD = %d \n", result);
	vt100_showVD(stdout, "fromDumpToVD_FAIL");
****************************************************/

	printf("\n\n=================  vt100_fromDumptoVD - display.config =============\n");
	
	// vt100_resetParms();      // restore to power up condition
	result = vt100_fromDumpToVD("display.config");

	vt100_dumpVD("disp_dumpVD.tst", ++autoIncrement, "fromDumpToVD - config");     
	printf("\n\n Result vt100_fromDumpToVD = %d \n", result);
	// printf("\n errorCode: %d, errorText: %s ", vt100_get_errorCode(),vt100_get_errorText() );
	vt100_showVD(stdout, "fromDumpToVD - config");

	
	printf("\n\n=================  vt100_compareVD - display.config =============\n");

	result = vt100_compareVD("display.config");
	printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, 
			"display.config");

	if( result != 0 )
		printf("\n  errorText = %s ", vt100_get_errorText() );


	printf("\n\n=================  vt100_scrollVD - UP  =======\n");
	
	vt100_scrollVD(1); 
	
	vt100_dumpVD("test_scrollVD_UP.out", ++autoIncrement, "scrollVD-UP!");     
	vt100_showVD(stdout, "scrollVD-UP!");

	printf("\n\n=================  vt100_scrollVD - DOWN  =======\n");
	
	vt100_scrollVD(-1); 
	
	vt100_dumpVD("test_scrollVD_DOWN.out", ++autoIncrement, "scrollVD-DOWN!");     
	vt100_showVD(stdout, "scrollVD-DOWN!");
		
	/* ****************** don't need this test anymore ************
	printf("\n\n=================  vt100_scrollVD - Bad arg =======\n");
	
	vt100_scrollVD(5); 
	
	vt100_dumpVD("test_scrollVD_badArg.out", ++autoIncrement, "scrollVD-badArg!");     
	vt100_showVD(stdout, "scrollVD-badArg!");
	*********************************************/
		
	/*************************
	 usleep(3);  // 300 msecs ?

	printf("\n\n\n\n  SYSTEM CALL to show process ID:");
	system( "ps -e | grep vt");
	printf("\n--------------------------------\n\n");
	***********************************/	
	
	vt100_end();
	
	
	sleep (1);      // give time for last calls to output to screen?

	
	exit(0);
	
	
}  // end - main () 
Exemple #2
0
int16_t						// no return value - provided by vt100_getError()
vt100_thread(THREAD_ARGS *args )
{
// char nextChar;					// input character from Serial port
// int16_t fd = 0;						// file descriptor for Serial Port open, read, write
const char *portName;
VIRTUAL_DISPLAY *pVDisplay;		    // pointer to virtual Display
char *pTextBuffer = NULL;			//  malloc'd text area
char *pAttribsBuffer = NULL; 		//  malloc'd attribs area
char **pTextPtrsBuffer = NULL;      //  malloc'd text pointers (rows) area
char **pAttribsPtrsBuffer = NULL;   //  malloc'd attribs pointers (rows) area 
int16_t rows         = 0;
int16_t cols         = 0;
int16_t bumpUpCols   = 0;
int16_t numBytes     = 0;
int16_t numPtrBytes  = 0;
int16_t rowLength    = 0;
int16_t i            = 0;           // array loop variable 

	//   unpack the two most crucial parameters - rows & cols - from args 
	rows = args[0].thr_DisplayRows;
	cols = args[0].thr_DisplayCols;
	//  have to allocate space on even pointer boundaries for rows 
	bumpUpCols = cols % sizeof( char *);    // see if number of columns is on a pointer boundary
	if( bumpUpCols) 
		cols += ( sizeof(char *) - bumpUpCols);  // if not (non-zero remainder), force to next boundary

	numBytes = rows * cols;
	rowLength = cols * (sizeof(char));

#if DEBUG_ON
	printf("\n\nvt100_THREAD %d is STARTING", args[0].thr_threadId);
	printf("\n  - on port %s with display rows %d and cols %d, pointer size is %d bytes", 
			  args[0].thr_portName, rows, cols, sizeof( char *) ); 
	printf("\n malloc() %d bytes each for Virtual Display text & data arrays",
			     numBytes );
#endif
	
    // 
	//   Concept - since screen size can vary in number of row or columns,
	//      we have dynamic arrays for the text display and the attributes display
	//      The Virtual Display for text is a list of pointers - 1 per line, and 
	//       a similar list of pointers for the attributes - 1 pointer per line 
	// 
	
	
	/*    
	 *   First - malloc() all Virtual Display data area and set up pointer arrays   
	 *   
	 */
	pTextBuffer    = (char *) malloc(numBytes); 
	pAttribsBuffer = (char *) malloc(numBytes); 

	numPtrBytes    = numRows * (sizeof (char *));
	pTextPtrsBuffer = (char **) malloc(numPtrBytes );
	pAttribsPtrsBuffer = (char **) malloc(numPtrBytes );
	if( (pTextBuffer == NULL)  || (pAttribsBuffer == NULL) || (pTextPtrsBuffer == NULL) 
			|| (pAttribsPtrsBuffer == NULL) ) 
	{
#if DEBUG_ON & DEBUG_MALLOC
		printf("\n\nvt100_thread: malloc probs: numBytes %d,  numPtrBytes %d ", numBytes,
				   numPtrBytes );
		printf("\n Ptrs are: %0x, %0x, %0x, %0x", (unsigned int) pTextBuffer, 
				   (unsigned int) pAttribsBuffer, (unsigned int) pTextPtrsBuffer,
				   (unsigned int) pAttribsPtrsBuffer );
#endif
		return( vt100_set_errorCode(ERR_09_MEM_ALLOC) );
	}
	
#if DEBUG_ON & DEBUG_THREAD
	printf("\n\nvt100_thread: malloc results: numBytes %d,  numPtrBytes %d ", numBytes,
			   numPtrBytes );
#endif
	
	//  init the Virtual Display with the buffer addresses & row pointer arrays
	//   buffer & array addresses used for later free() calls 
	vDisplay.pText        = pTextPtrsBuffer;
	vDisplay.pAttribs     = pAttribsPtrsBuffer;
	vDisplay.pTextBuf     = pTextBuffer;
	vDisplay.pAttribsBuf  = pAttribsBuffer;
	vDisplay.ptrsBufSize  = numPtrBytes;
	vDisplay.charsBufSize = numBytes;
	
	//  set up the pointer arrays from malloc'd memory 
	for( i = 0; i < rows ; i++ )   // distribute the memory into pointer arrays 
	{    
		pTextPtrsBuffer[i] = pTextBuffer;
		pTextBuffer += rowLength;
		pAttribsPtrsBuffer[i] = pAttribsBuffer;
		pAttribsBuffer += rowLength;
#if DEBUG_ON & DEBUG_MALLOC 
		printf("\n row %d: TextPtr: %0x, Attribs Ptr: %0x,", i+1, (unsigned int) pTextPtrsBuffer[i], 
				(unsigned int)  pAttribsPtrsBuffer[i] );
#endif
		
	}
	
	
#if DEBUG_ON & DEBUG_MALLOC
		printf("\n vDisplay struct: TextPtrBuffer: %0x, AttribsPtrBuffer: %0x,", 
				(unsigned int) pTextPtrsBuffer, (unsigned int) pAttribsPtrsBuffer );
		printf("\n==========================================================");
		for( i = 0; i < rows; i++ ) 
		{
			printf("\n %d: text %0x,  attrib %0x ", i, (unsigned int) vDisplay.pText[i], 
					(unsigned int) vDisplay.pAttribs[i]);
		}
#endif
	
	
	// check if fpui port is present and can be opened 
	
	
	portName  = args[0].thr_portName; 
	pVDisplay = args[0].thr_DisplayPtr;
	
	if( portName == NULL )   // no fpui present - can't read any chars
	{
		while(!vt100_allDone)
		{
#if DEBUG_ON & DEBUG_THREAD
			printf("T%d, ", ++counter); 
			if( counter % 10) printf("\n");
#endif 
			sleep(1);    // wait 1secs - allow asynch call to process file input 
		}
	}
	else     
	{        
		// we are given port to open like "/dev/fpi" 
		// we will open the port and process characters received to the VT 
		
#if DEBUG_ON
    //  clear the display and show the results 
	// do compare on the display that was just cleared with the local dump file 
	//  this must be removed for delivery - should not be accessed from the library routines
int16_t result = 0;
		vt100_clearVD();        // start clean & clear before text input 
		result = vt100_compareVD("display.clear");
		printf("\nvt100_thread: compareVD: display.clear = %d \n", result);
		vt100_showVD(stdout, "After call to vt100_clearVD");
#endif
	
	
		if( (fdSerialPort = openSerialPort(portName) ) <= 0 ){   // Error on open
#if DEBUG_ON
			printf("\n ERR_05_PORT_OPEN; received %d trying to open %s \n", fdSerialPort, portName);
#endif
			vt100_set_errorCode(ERR_05_PORT_OPEN); 
			threadErrorCode = ERR_05_PORT_OPEN;
			vt100_allDone = TRUE;
		}
	
#if DEBUG_ON
		printf("\nTHREAD %d ready to read input from %s ... ", 
					args[0].thr_threadId, portName);
		printf("\n Please start entering input:\n  (terminate with a 'z' on a new line}\n");
#endif
	
		while(!vt100_allDone ) 
		{
			vt100_processInput( fdSerialPort, NULL, pVDisplay );     //  read Serial Port and process forever - no line buffer here
		}  // end forever while loop 
		
		// all done - close the serial port and exit
		
		closeSerialPort(fdSerialPort);
	
		// vt100_dumpVD("dump.thread.after", "thread after key inputs");
	
	}  // end - good serial port 
	
	
#if DEBUG_ON
	printf("\n\n vt100 - exiting thread # %d", args[0].thr_threadId );
#endif
	
	sleep(1);
	
	//  free the malloc'd memory in reverse order
	free( vDisplay.pAttribs );
	free( vDisplay.pText );
	free( vDisplay.pAttribsBuf );	
	free( vDisplay.pTextBuf  );
	
	pthread_exit(&threadErrorCode);   // return error code to the original start function
	
	
	//   return (errorCode);
	
	
}  // end vt100_thread()
void 
process_ESC_Seq(int16_t fd, VIRTUAL_DISPLAY *VD_ptr, char **pBuffPtr)
{
char ESC_sequence[MAX_ESC_SEQ_LEN];         // holds the <ESC> sequence chars 
char outputSeqBuffer[MAX_ESC_SEQ_LEN];      // output buffer to make string for serial port write
int16_t outBufLen = 0;                      // length of the output string 
int16_t numBytesWritten = 0;                // bytes written to the Serial Port 
char nextChar = 0;
int     tempIntValue = 0;
int16_t seqCode = 0;
int seqValue = 0;
int16_t initCol = 0;                        // starting column (from cursorPos) in a line
int16_t i=0, j=0;
static int ESC_line = 0, ESC_col = 0;       // for Py;Px conversions
char *pESC = ESC_sequence;                  // ptr for parsing through ESC sequence 
char **pTextArray = VD_ptr->pText;          // set up the malloc'd data area pointers 
char **pAttribsArray = VD_ptr->pAttribs;
char *pRowText = NULL;
char *pRowAttribs = NULL;
//static int seq = 0;

	ESC_sequence[0] = ESC_CHAR;    //  init the start of the sequence
	ESC_sequence[1] = 0; 
	ESC_sequence[2] = 0;
	ESC_sequence[3] = 0;

	pRowText        = pTextArray[cursorPos.cp_row];
	pRowAttribs     = pAttribsArray[cursorPos.cp_row];

	  
	     //read the ESC sequence 
	nextChar = getNextChar(fd, pBuffPtr);
	switch (nextChar) {
	
	case 'D':
		// scroll window up one line
		vt100_scrollVD( 1 );
		break;
	case 'E':
		// move to next line  ? start of line or just next row below?
		//   if ( (cursorPos.cp_row += 1) >  numRows - 1 )
		if( cursorPos.cp_row < (numRows - 1) )
				cursorPos.cp_row++ ;   // rows start with 0 
		// cursorPos.cp_col = 0;       // comment out for now - just move down 1 row
		break;
				
	case 'H':
		// set tab at current column 
		tabCol = cursorPos.cp_col;
		tabStops[tabCol] = 'T';    // show an ASCII 'T' instead of ' '
		seqCode = 0;
		break; 
		
	case 'M':    // scroll window down one line
		vt100_scrollVD( -1 ); 
		break;
			
	case 'P':     // Compose Special Character
        // sequence is <ESC> P P1 [ Pn ; Pn ; Pn ; .... f
		ESC_sequence[1] = 'P';
		
		seqCode = get_ESC_Seq(fd, ESC_sequence, pBuffPtr);
		
		if( seqCode == CURSOR_POSITION )  // should have found an 'f' terminator
			seqCode = COMPOSE_SPECIAL;    // this should occur

#if DEBUG_ON & DEBUG_SPECIAL
		else
			printf("\n process_ESC_seq(): Compose SPECIAL CHAR # %d: seqCode was %d, should be %d ",
					    ESC_sequence[2], seqCode, CURSOR_POSITION );
#endif
		
		break;
			
	case '[':      //  <ESC> [  sequence 
		// get rest of sequence and process
		ESC_sequence[1] = '[';
		seqCode = get_ESC_Seq(fd, ESC_sequence, pBuffPtr);
//printf("get_ESC_Seq:ESC[0x%02x,0x%02x seqCode=%d\n", ESC_sequence[2], ESC_sequence[3], seqCode);
		break;
		
	case '6':      //  <ESC> 6 n  sequence - CURSOR_POSITION request 
		//  this is an older VT-100 original query 
		//    CursorPos,  Parameters/Attributes,  auxSwitch status 
		if( (nextChar = getNextChar(fd, pBuffPtr)) == 'n' ) {
			// dummy this in to be the same as the new STATUS QUERY COMMANDS for RESPONSES
			ESC_sequence[1] = '[';
			ESC_sequence[2] = '6';
			ESC_sequence[3] = 'n';
			seqCode = STATUS_QUERY;
		}
		else
		{
			ESC_sequence[1] = '6';
			ESC_sequence[2] = nextChar;
			//  don't know really what to do here - this is not defined 
			//  no further processing will happen without the 'seqCode' being set 
		}
		break;
		
	case '7':      //  <ESC> 7 sequence - SAVE_CURSOR_POS
		ESC_sequence[1] = '7';
		seqCode = SAVE_CURSOR_POS;
		
		break;
		
	case '8':      //  <ESC> 8 sequence - REST_CURSOR_POS
		ESC_sequence[1] = '8';
		seqCode = REST_CURSOR_POS;
		
		break;
	
	case 'G':        // <ESC> G sequence - Graphics Mode Commands
		ESC_sequence[1] = 'G';

		nextChar = getNextChar(fd, pBuffPtr);
		ESC_sequence[2] = nextChar;
		switch (nextChar) {
			case 'U':
				nextChar = getNextChar(fd, pBuffPtr);
				if (nextChar == '0')
					graphicModeFlags &= ~(GRAPHIC_UNDERLAY_1 | GRAPHIC_UNDERLAY_2);
				else if (nextChar == '1')
					graphicModeFlags |= GRAPHIC_UNDERLAY_1;
				else if (nextChar == '2')
					graphicModeFlags |= GRAPHIC_UNDERLAY_2;
				ESC_sequence[3] = nextChar;
				break;
			case 'O':
				nextChar = getNextChar(fd, pBuffPtr);
				if (nextChar == '0')
					graphicModeFlags &= ~(GRAPHIC_OVERLAY_1 | GRAPHIC_OVERLAY_2);
				else if (nextChar == '1')
					graphicModeFlags |= GRAPHIC_OVERLAY_1;
				else if (nextChar == '2')
					graphicModeFlags |= GRAPHIC_OVERLAY_2;
				ESC_sequence[3] = nextChar;
				break;
			case 'C':
				nextChar = getNextChar(fd, pBuffPtr);
				if (nextChar == '0')
					graphicModeFlags &= ~(GRAPHIC_CURSOR_U | GRAPHIC_CURSOR_O);
				else if (nextChar == 'U')
					graphicModeFlags |= GRAPHIC_CURSOR_U;
				else if (nextChar == 'O')
					graphicModeFlags |= GRAPHIC_CURSOR_O;
				ESC_sequence[3] = nextChar;
				break;
			default:
				break;
		}
		break;
		
	default:
		//  unknown or not-handled ESC sequence 
		break;
			
	}
		

	if( seqCode > 0 )   // valid ESC Sequence that needs processing?
	{
		seqValue = 0;
		if( isdigit ( ESC_sequence[2]))
		{
			if( sscanf( &ESC_sequence[2], "%d", &seqValue) != 1 )
			{
				printf("sscanf error for seqCode %d\n", seqCode);
				seqValue = 0;
			}
		}
		else if( isdigit ( ESC_sequence[3]))    // is this <ESC>[?NN or something similar 
		{
			if( sscanf( &ESC_sequence[3], "%d", &seqValue) != 1 )
			{
				printf("sscanf error for seqCode %d\n", seqCode);
				seqValue = 0;
			}
		}
	
		//  now have valid sequence code and numeric value if present
				
		
#if DEBUG_ON & DEBUG_ESC_SEQ
		printf("process_ESC_sequence for <ESC> [ 0x%02x, seqCode=%d\n", seqValue, seqCode);
#endif
				
		switch( seqCode) {
		case CURSOR_UP:
			if ( (cursorPos.cp_row -= seqValue) < 0 )
				cursorPos.cp_row = 0;
			break;
			
		case CURSOR_DOWN:
			if ( (cursorPos.cp_row += seqValue) >=  (numRows - 1) )  // cursorPos values start with 0
				cursorPos.cp_row = numRows - 1;   // rows start with 0 
			break;
			
		case CURSOR_RIGHT:
			if ( (cursorPos.cp_col += seqValue) >= (numCols - 1) )    // cursorPos values start with 0
				cursorPos.cp_col = numCols - 1;     // force to last position 
			break;
			
		case CURSOR_LEFT:
			if ( (cursorPos.cp_col -= seqValue) < 0 )
				cursorPos.cp_col = 0;              // force to start of line position 
			break;
		case HOME_CURSOR:
			cursorPos.cp_row = 0;
			cursorPos.cp_col = 0;
			break;
		case CURSOR_POSITION:
			cursorPos.cp_row = 0;
			cursorPos.cp_col = 0;
			// check for row;column position as opposed to top left 
			if( isdigit( ESC_sequence[2]) )  // if no number - then home to top left
			{ 
				if( sscanf(&ESC_sequence[2], "%d;%d", &ESC_line, &ESC_col) >= 2 )
				{	// ESC sequence starts row and cols with a 1 to 8 row # and 1 to 40 col #
					//  first - confirm within boundaries and set to boundaries if be
					if( ESC_line < 1 ) ESC_line = 1; 
					if( ESC_col < 1 )  ESC_col  = 1;
					if( ESC_line > numRows) ESC_line = numRows;
					if( ESC_col  > numCols) ESC_col  = numCols;
					  // internally we use cols from 0 to numCols and
					  //   row numbers from 0 to numRows 
					  // so we will subtract 1 from ESC_line & ESC_col 
					cursorPos.cp_row = ESC_line - 1;
					cursorPos.cp_col = ESC_col  - 1;
				}
			}
			break;
			
			
		case SET_AUTO_MODES:
//printf("\nprocess_ESC_Seq() - [?%d h - SET_AUTO_MODES\n", seqValue);
			switch (seqValue)
			{
			case 5:    
				if( ESC_sequence[2] == '?') // set Reverse Video 				
					vt100_set_reverseVideo((int16_t) ON );
				else if( ESC_sequence[2] == '<')
					vt100_set_backLight( (int16_t) ON );
				else
#if DEBUG_ON
					printf("\n process_ESC_Seq() - [ ??? 5 h - SET_AUTO_MODES ");
#else

					;   // do nothing - maybe non-implemented <ESC> sequence 
#endif
				break;
			case 7: 
				vt100_set_autoWrap((int16_t) TEXT_WRAP_NL);
				break;
			case 8:
				vt100_set_autoRepeat( (int16_t) ON );
				break;
			case 24:       // UNDERLINE MODE ON 
				currentAttribs |= ATTRIB_UNDER;   // bit flags "OR"
				break;
			case 25:       // could be 25 or 025 in <ESC>[ sequence - 2 different actions 
				if(ESC_sequence[2] == '0')
					vt100_set_cursorState(ON);
				else					
					currentAttribs |= ATTRIB_BLINK;   // bit flags "OR"
				break;
			case 27:     // set Reverse Video 
				vt100_set_reverseVideo((int16_t) ON );
				currentAttribs |= ATTRIB_REVERSE;
				break;
			case 33:       // Cursor Blink ON 
				vt100_set_cursorBlink(ON);
				break;
			case 47:       // AutoScroll ON 
				vt100_set_autoScroll( (int16_t) ON );
				break;
			default:
				break;
			}
			break;
			
		case CLEAR_AUTO_MODES:
			switch (seqValue)
			{
			case 5:     
				if( ESC_sequence[2] == '?') // turn off Reverse Video 				
					vt100_set_reverseVideo((int16_t) OFF );
				else if( ESC_sequence[2] == '<')
					vt100_set_backLight( (int16_t) OFF );
				else
#if DEBUG_ON
					printf("\n process_ESC_Seq() - [ ??? 5 l - CLEAR_AUTO_MODES ");
#else

					;   // do nothing - maybe non-implemented <ESC> sequence 
#endif
				break;
			case 7: 
				vt100_set_autoWrap((int16_t) TEXT_WRAP_OFF);
				break;
			case 8:
				vt100_set_autoRepeat( (int16_t) OFF );
				break;
			case 24:       // UNDERLINE MODE OFF 
				currentAttribs &= ~ATTRIB_UNDER;
				break;
			case 25:      // could be 25 or 025 in <ESC>[ sequence - 2 different actions   
				if(ESC_sequence[2] == '0')
					vt100_set_cursorState(OFF);
				else					   
					currentAttribs &= ~ATTRIB_BLINK;  // clear the Blink bit 
				break;
			case 27:     // Turn Off Reverse Video 
				vt100_set_reverseVideo((int16_t) OFF );
				currentAttribs &= ~ATTRIB_REVERSE;
				break;
			case 33:       // Cursor Blink OFF 
				vt100_set_cursorBlink(OFF);
				break;
			case 47:       // AutoScroll OFF 
				vt100_set_autoScroll( (int16_t) OFF );
				break;
			default:
				break;
			}
			break;
			
		case CLEAR_DISPLAY:      //  have to do the rest of the codes - clear is only 
			switch (seqValue) 
			{
			case 0:      // Clear screen from cursor down 
				i = cursorPos.cp_row;
				initCol = cursorPos.cp_col;
				for(i = cursorPos.cp_row; i < numRows ; i++ ){
					pRowText = pTextArray[i];
					pRowAttribs = pAttribsArray[i];
					for(j = initCol; j < numCols; j++ ) {
						*pRowText++    = ' ';     // set to blanks for Text and 
						*pRowAttribs++ = '0';	  //  ASCII Zeroes for the attributes 	
						// VD_ptr->text[i][j] = ' ';   // blanks for cleared text 
						// VD_ptr->attribs[i][j] = '0'; // zero for cleared attributes 
					}
					initCol = 0;     // clear all the rest of the rows going down 
				}
				break;
				
			case 1:    // Clear screen from cursor up
				i = cursorPos.cp_row;
				initCol = cursorPos.cp_col;
				for(i = cursorPos.cp_row; i >= 0 ; i-- ){
					pRowText = pTextArray[i];
					pRowAttribs = pAttribsArray[i];
					for(j = initCol; j >= 0; j-- ) {
						*pRowText++    = ' ';     // set to blanks for Text and 
						*pRowAttribs++ = '0';	  //  ASCII Zeroes for the attributes 	
						// VD_ptr->text[i][j] = ' ';   // blanks for cleared text 
						// VD_ptr->attribs[i][j] = '0'; // zero for cleared attributes 
					}
					initCol = numCols - 1;     // clear rest of rows going up, starting from last column
				}
				break;
				
			case 2:    // Clear entire screen 
				vt100_clearVD();
				break;
				
			default:
				break;
			}
			
			break;
			
		case CLEAR_LINE:
			// cursorPos has line number 
			switch (seqValue) 
			{
			case 0:  // Clear from cursor to the right 
				
 				for(j = cursorPos.cp_col; j < numCols; j++ ) 
				    {
 					pRowText[j]    = ' ';   // blanks for cleared text 
 					pRowAttribs[j] = '0';   // zero for cleared attributes 
				    }
				break;
				
			case 1:  // Clear line from cursor to the left 
 				for(j = cursorPos.cp_col; j >= 0; j-- ) 
				    {
 					pRowText[j]    = ' ';   // blanks for cleared text 
 					pRowAttribs[j] = '0';   // zero for cleared attributes 
				    }
				break;
				
			case 2:  // Clear entire line  
 				for(j = 0; j < numCols; j++ ) 
				    {
 					pRowText[j]    = ' ';   // blanks for cleared text 
 					pRowAttribs[j] = '0';   // zero for cleared attributes 
				    }
				break;
			default:
				break;
			}
			break;
			
		case CLEAR_TABS:
			switch (seqValue) 
			{
			case 0:    // Clear a tab at the current column 
				tabStops[cursorPos.cp_col] = '0';
				break;
			case 3:    // Clear all tab stops 
				for(j = 0; j < numCols; j++ ) 
				{
					tabStops[j] = '0';
				}
				break;
			default:
				// unknown tabstop seqValue 
				break;
			}
			break;
			
		case CHAR_ATTRIBUTES:
			switch (seqValue)
			{
			case RESET_ATTRIBUTES:  // clear all attributes
				// what about the bit 8 for the Special Character???
				// it can't be kept in currentAttribs because it only applies to one character at a time
				currentAttribs = '0';
				break;
			case BLINK_ON:
				currentAttribs |= ATTRIB_BLINK;   // bit flags "OR"
				break;
			case REVERSE_ON:
				currentAttribs |= ATTRIB_REVERSE;   // bit flags "OR"
				break;
			case UNDER_ON:
				currentAttribs |= ATTRIB_UNDER;   // bit flags "OR"
				break;
			default:
				break;
				
			}
			break;
			
		case BACKLIGHT_TIMEOUT:
			vt100_set_backLightTimeout(seqValue);   // sequence value sets timeout in seconds
			                    // NOTE:  These routines currently have no implementation of  
			                    //        this timeout countdown between key strokes by user 
			                    //        at the Front Panel.
			break;
			
		case COMPOSE_SPECIAL:      // Compose a Special bit-mapped character - seqValue has which one
			                       // sequence is <ESC> P P1 [ Pn ; Pn ; Pn ; .... f
			pESC = &ESC_sequence[4];   // should be the first 8-bit # 
			
			seqValue = ESC_sequence[2] - '0';
			if ((seqValue < 1) || (seqValue > 8)) {
				printf("\nvt100_processInput error: invalid special char %d", seqValue);
				break;
			}
#if DEBUG_ON & DEBUG_SPECIAL
            printf("\n Composing SpecChar # %d [%c] : %s ", seqValue, ESC_sequence[2], &ESC_sequence[1] );
#endif
			for(i=0; i < BYTES_PER_SPEC_CHAR; i++)   // up to 8 elements before the 'f' delimiter
			{
				sscanf(pESC, "%d", &tempIntValue);
				specialChars[seqValue-1][i] = (uint8_t) tempIntValue;
				while( isdigit( *pESC) )    // bypass the number just converted 
					pESC++;
				
				if( *pESC == ';' ) {
					pESC++;   // skip the ';' delimiter to get to the next bit-map byte 
				}
				
				if( *pESC == 'f' ){  // this will allow a ";f"  sequence even though it might be wrong
					i++;      // account for this Pn Value before breaking the loop
					break;    // special chars can be 5 - 8 columns long; Pn = P1 - P8
				}
			}
#if DEBUG_ON & DEBUG_SPECIAL
			if( *pESC != 'f' ) {
				printf("\n vt100_processInput error: loading Special Char # %d: terminator '%c' should be 'f'",
							 seqValue, *pESC);
			// NOTE:  This could be caused it there are more than 8 Pn values, which would make a very wide 
			//         Special Character, which would be invalid and cleared out 
			}
#endif

			if( (i >= MIN_SPEC_CHAR_COLS )  && (i <= MAX_SPEC_CHAR_COLS ) )
			{
				specialCharColumns[seqValue-1] = i;    // should be a number in range 5 - 8 
			}
			else
			{    // should clear out this invalid attempt 
#if DEBUG_ON & DEBUG_SPECIAL
				printf("\n vt100_processInput:  Invalid attempt to set up Special Character # %d - only %d columns",
						           seqValue, i);
#endif 
				
				for(i=0; i < BYTES_PER_SPEC_CHAR; i++)   // up to 8 elements before the 'f' delimiter
				{
					specialChars[seqValue-1][i] = 0;
				}
	
			}
			
			break;
				
		case SPECIAL_CHAR:    // display one of 8 Special Characters as a ASCII Digit '1' thru '8' 
			// and put the Atrribute Bit On for Speciall Char for that character only
			// The special character number is in the "seqValue" variable 
			processInputChar((char) ((uint8_t) ( (0x30 + seqValue) | 0x80) ), pVD);  // ASCII '0' + seq + bit 7

			break;

		case STATUS_QUERY: 
			// one of three possible queries - cursorPos, attribs/parameters, auxSwitch state 
			// all need to have responses generated and written to the serial port fd if open 
			//  have to send (transmit) cursor pos message onto Serial Port (fd)
			//  sequence is:  <ESC>[<row>;<col>R or similar 
			// clear and load an output buffer for response 
#if DEBUG_ON & DEBUG_SERIAL
			printf("\n vt100_process_ESC_Seq:  STATUS QUERY # %c\n", ESC_sequence[2]);
#endif
			
			for(i = 0; i < MAX_ESC_SEQ_LEN; i++ ){
				outputSeqBuffer[i] = '\0';
			}
			outputSeqBuffer[0] = ESC_CHAR;
			outputSeqBuffer[1] = '[';
			
			switch ( ESC_sequence[2] ) {
			
			case '6':    // return Cursor Position 
				sprintf(&outputSeqBuffer[2], "%d;%dR", cursorPos.cp_row + 1, cursorPos.cp_col + 1);
				break;
				
			case 'A':    // return Auxillary Switch Status
				sprintf(&outputSeqBuffer[2], "%cR", vt100_get_auxSwitch()?'h':'l' );
				break;
				
			case 'B':    // return status of various attributes and parameters 
				sprintf(&outputSeqBuffer[2], "%c;%c;%c;%c;%d;%cR", 
					vt100_get_autoWrap()?'h':'l', vt100_get_autoScroll()?'h':'l',
					vt100_get_autoRepeat()?'h':'l', vt100_get_backLight()?'h':'l',
					vt100_get_backLightTimeout(), vt100_get_auxSwitch()?'h':'l');
				break;
				
			default:
				break;
			}
			
			outBufLen = strlen(outputSeqBuffer);

			if( fdSerialPort > 0 )
			{
				numBytesWritten = writeSerialPort(fdSerialPort, outputSeqBuffer, outBufLen ); 
				if( numBytesWritten == outBufLen )
				{
					;  // good command written out 
				}
				else
				{
					;      // null statement - placeholder
#if DEBUG_ON & DEBUG_SERIAL
					//     ERR_07_PORT_WRITE  if there was a return value 
					printf("\n vt100_process_ESC_Seq:  Only wrote %d of %d bytes to Serial port for CMD/RESP",
							    numBytesWritten, outBufLen); 
#endif
				}
			}
			else 
			{
#if DEBUG_ON & DEBUG_SERIAL
				printf("\n vt100_process_ESC_Seq: write out to serial port %d chars:\n  %s ", 
						     outBufLen, outputSeqBuffer);
#endif 
			}

			break;

		case SAVE_CURSOR_POS:
			vt100_save_cursorPos();
			break;
			
		case REST_CURSOR_POS:
			vt100_rest_cursorPos();
			break;
			
		default:
			break;
						
		}   // end switch
	
	}   // end if 
//printf("ESC%d|%d[%d;%d]", seqCode, seqValue, cursorPos.cp_row, cursorPos.cp_col);
//vt100_dumpVD("process_ESC", seq++,"after ESC sequence");	
}  // end process_ESC_Seq