Home | History | Annotate | Download | only in fpga
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Porting to u-boot:
      4  *
      5  * (C) Copyright 2010
      6  * Stefano Babic, DENX Software Engineering, sbabic (at) denx.de.
      7  *
      8  * Lattice ispVME Embedded code to load Lattice's FPGA:
      9  *
     10  * Copyright 2009 Lattice Semiconductor Corp.
     11  *
     12  * ispVME Embedded allows programming of Lattice's suite of FPGA
     13  * devices on embedded systems through the JTAG port.  The software
     14  * is distributed in source code form and is open to re - distribution
     15  * and modification where applicable.
     16  *
     17  * Revision History of ivm_core.c module:
     18  * 4/25/06 ht   Change some variables from unsigned short or int
     19  *              to long int to make the code compiler independent.
     20  * 5/24/06 ht   Support using RESET (TRST) pin as a special purpose
     21  *              control pin such as triggering the loading of known
     22  *              state exit.
     23  * 3/6/07 ht added functions to support output to terminals
     24  *
     25  * 09/11/07 NN Type cast mismatch variables
     26  *		   Moved the sclock() function to hardware.c
     27  * 08/28/08 NN Added Calculate checksum support.
     28  * 4/1/09 Nguyen replaced the recursive function call codes on
     29  *        the ispVMLCOUNT function
     30  */
     31 
     32 #include <common.h>
     33 #include <linux/string.h>
     34 #include <malloc.h>
     35 #include <lattice.h>
     36 
     37 #define vme_out_char(c)	printf("%c", c)
     38 #define vme_out_hex(c)	printf("%x", c)
     39 #define vme_out_string(s) printf("%s", s)
     40 
     41 /*
     42  *
     43  * Global variables used to specify the flow control and data type.
     44  *
     45  *	g_usFlowControl:	flow control register. Each bit in the
     46  *                               register can potentially change the
     47  *                               personality of the embedded engine.
     48  *	g_usDataType:		holds the data type of the current row.
     49  *
     50  */
     51 
     52 static unsigned short g_usFlowControl;
     53 unsigned short g_usDataType;
     54 
     55 /*
     56  *
     57  * Global variables used to specify the ENDDR and ENDIR.
     58  *
     59  *	g_ucEndDR:		the state that the device goes to after SDR.
     60  *	g_ucEndIR:		the state that the device goes to after SIR.
     61  *
     62  */
     63 
     64 unsigned char g_ucEndDR = DRPAUSE;
     65 unsigned char g_ucEndIR = IRPAUSE;
     66 
     67 /*
     68  *
     69  * Global variables used to support header/trailer.
     70  *
     71  *	g_usHeadDR:		the number of lead devices in bypass.
     72  *	g_usHeadIR:		the sum of IR length of lead devices.
     73  *	g_usTailDR:		the number of tail devices in bypass.
     74  *	g_usTailIR:		the sum of IR length of tail devices.
     75  *
     76  */
     77 
     78 static unsigned short g_usHeadDR;
     79 static unsigned short g_usHeadIR;
     80 static unsigned short g_usTailDR;
     81 static unsigned short g_usTailIR;
     82 
     83 /*
     84  *
     85  * Global variable to store the number of bits of data or instruction
     86  * to be shifted into or out from the device.
     87  *
     88  */
     89 
     90 static unsigned short g_usiDataSize;
     91 
     92 /*
     93  *
     94  * Stores the frequency. Default to 1 MHz.
     95  *
     96  */
     97 
     98 static int g_iFrequency = 1000;
     99 
    100 /*
    101  *
    102  * Stores the maximum amount of ram needed to hold a row of data.
    103  *
    104  */
    105 
    106 static unsigned short g_usMaxSize;
    107 
    108 /*
    109  *
    110  * Stores the LSH or RSH value.
    111  *
    112  */
    113 
    114 static unsigned short g_usShiftValue;
    115 
    116 /*
    117  *
    118  * Stores the current repeat loop value.
    119  *
    120  */
    121 
    122 static unsigned short g_usRepeatLoops;
    123 
    124 /*
    125  *
    126  * Stores the current vendor.
    127  *
    128  */
    129 
    130 static signed char g_cVendor = LATTICE;
    131 
    132 /*
    133  *
    134  * Stores the VME file CRC.
    135  *
    136  */
    137 
    138 unsigned short g_usCalculatedCRC;
    139 
    140 /*
    141  *
    142  * Stores the Device Checksum.
    143  *
    144  */
    145 /* 08/28/08 NN Added Calculate checksum support. */
    146 unsigned long g_usChecksum;
    147 static unsigned int g_uiChecksumIndex;
    148 
    149 /*
    150  *
    151  * Stores the current state of the JTAG state machine.
    152  *
    153  */
    154 
    155 static signed char g_cCurrentJTAGState;
    156 
    157 /*
    158  *
    159  * Global variables used to support looping.
    160  *
    161  *	g_pucHeapMemory:	holds the entire repeat loop.
    162  *	g_iHeapCounter:		points to the current byte in the repeat loop.
    163  *	g_iHEAPSize:		the current size of the repeat in bytes.
    164  *
    165  */
    166 
    167 unsigned char *g_pucHeapMemory;
    168 unsigned short g_iHeapCounter;
    169 unsigned short g_iHEAPSize;
    170 static unsigned short previous_size;
    171 
    172 /*
    173  *
    174  * Global variables used to support intelligent programming.
    175  *
    176  *	g_usIntelDataIndex:     points to the current byte of the
    177  *                               intelligent buffer.
    178  *	g_usIntelBufferSize:	holds the size of the intelligent
    179  *                               buffer.
    180  *
    181  */
    182 
    183 unsigned short g_usIntelDataIndex;
    184 unsigned short g_usIntelBufferSize;
    185 
    186 /*
    187  *
    188  * Supported VME versions.
    189  *
    190  */
    191 
    192 const char *const g_szSupportedVersions[] = {
    193 	"__VME2.0", "__VME3.0", "____12.0", "____12.1", 0};
    194 
    195 /*
    196  *
    197  * Holds the maximum size of each respective buffer. These variables are used
    198  * to write the HEX files when converting VME to HEX.
    199  *
    200 */
    201 
    202 static unsigned short g_usTDOSize;
    203 static unsigned short g_usMASKSize;
    204 static unsigned short g_usTDISize;
    205 static unsigned short g_usDMASKSize;
    206 static unsigned short g_usLCOUNTSize;
    207 static unsigned short g_usHDRSize;
    208 static unsigned short g_usTDRSize;
    209 static unsigned short g_usHIRSize;
    210 static unsigned short g_usTIRSize;
    211 static unsigned short g_usHeapSize;
    212 
    213 /*
    214  *
    215  * Global variables used to store data.
    216  *
    217  *	g_pucOutMaskData:	local RAM to hold one row of MASK data.
    218  *	g_pucInData:		local RAM to hold one row of TDI data.
    219  *	g_pucOutData:		local RAM to hold one row of TDO data.
    220  *	g_pucHIRData:		local RAM to hold the current SIR header.
    221  *	g_pucTIRData:		local RAM to hold the current SIR trailer.
    222  *	g_pucHDRData:		local RAM to hold the current SDR header.
    223  *	g_pucTDRData:		local RAM to hold the current SDR trailer.
    224  *	g_pucIntelBuffer:	local RAM to hold the current intelligent buffer
    225  *	g_pucOutDMaskData:	local RAM to hold one row of DMASK data.
    226  *
    227  */
    228 
    229 unsigned char	*g_pucOutMaskData	= NULL,
    230 		*g_pucInData		= NULL,
    231 		*g_pucOutData		= NULL,
    232 		*g_pucHIRData		= NULL,
    233 		*g_pucTIRData		= NULL,
    234 		*g_pucHDRData		= NULL,
    235 		*g_pucTDRData		= NULL,
    236 		*g_pucIntelBuffer	= NULL,
    237 		*g_pucOutDMaskData	= NULL;
    238 
    239 /*
    240  *
    241  * JTAG state machine transition table.
    242  *
    243  */
    244 
    245 struct {
    246 	 unsigned char  CurState;  /* From this state */
    247 	 unsigned char  NextState; /* Step to this state */
    248 	 unsigned char  Pattern;   /* The tragetory of TMS */
    249 	 unsigned char  Pulses;    /* The number of steps */
    250 } g_JTAGTransistions[25] = {
    251 { RESET,	RESET,		0xFC, 6 },	/* Transitions from RESET */
    252 { RESET,	IDLE,		0x00, 1 },
    253 { RESET,	DRPAUSE,	0x50, 5 },
    254 { RESET,	IRPAUSE,	0x68, 6 },
    255 { IDLE,		RESET,		0xE0, 3 },	/* Transitions from IDLE */
    256 { IDLE,		DRPAUSE,	0xA0, 4 },
    257 { IDLE,		IRPAUSE,	0xD0, 5 },
    258 { DRPAUSE,	RESET,		0xF8, 5 },	/* Transitions from DRPAUSE */
    259 { DRPAUSE,	IDLE,		0xC0, 3 },
    260 { DRPAUSE,	IRPAUSE,	0xF4, 7 },
    261 { DRPAUSE,	DRPAUSE,	0xE8, 6 },/* 06/14/06 Support POLL STATUS LOOP*/
    262 { IRPAUSE,	RESET,		0xF8, 5 },	/* Transitions from IRPAUSE */
    263 { IRPAUSE,	IDLE,		0xC0, 3 },
    264 { IRPAUSE,	DRPAUSE,	0xE8, 6 },
    265 { DRPAUSE,	SHIFTDR,	0x80, 2 }, /* Extra transitions using SHIFTDR */
    266 { IRPAUSE,	SHIFTDR,	0xE0, 5 },
    267 { SHIFTDR,	DRPAUSE,	0x80, 2 },
    268 { SHIFTDR,	IDLE,		0xC0, 3 },
    269 { IRPAUSE,	SHIFTIR,	0x80, 2 },/* Extra transitions using SHIFTIR */
    270 { SHIFTIR,	IRPAUSE,	0x80, 2 },
    271 { SHIFTIR,	IDLE,		0xC0, 3 },
    272 { DRPAUSE,	DRCAPTURE,	0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/
    273 { DRCAPTURE, DRPAUSE,	0x80, 2 },
    274 { IDLE,     DRCAPTURE,	0x80, 2 },
    275 { IRPAUSE,  DRCAPTURE,  0xE0, 4 }
    276 };
    277 
    278 /*
    279  *
    280  * List to hold all LVDS pairs.
    281  *
    282  */
    283 
    284 LVDSPair *g_pLVDSList;
    285 unsigned short g_usLVDSPairCount;
    286 
    287 /*
    288  *
    289  * Function prototypes.
    290  *
    291  */
    292 
    293 static signed char ispVMDataCode(void);
    294 static long int ispVMDataSize(void);
    295 static void ispVMData(unsigned char *Data);
    296 static signed char ispVMShift(signed char Code);
    297 static signed char ispVMAmble(signed char Code);
    298 static signed char ispVMLoop(unsigned short a_usLoopCount);
    299 static signed char ispVMBitShift(signed char mode, unsigned short bits);
    300 static void ispVMComment(unsigned short a_usCommentSize);
    301 static void ispVMHeader(unsigned short a_usHeaderSize);
    302 static signed char ispVMLCOUNT(unsigned short a_usCountSize);
    303 static void ispVMClocks(unsigned short Clocks);
    304 static void ispVMBypass(signed char ScanType, unsigned short Bits);
    305 static void ispVMStateMachine(signed char NextState);
    306 static signed char ispVMSend(unsigned short int);
    307 static signed char ispVMRead(unsigned short int);
    308 static signed char ispVMReadandSave(unsigned short int);
    309 static signed char ispVMProcessLVDS(unsigned short a_usLVDSCount);
    310 static void ispVMMemManager(signed char types, unsigned short size);
    311 
    312 /*
    313  *
    314  * External variables and functions in hardware.c module
    315  *
    316  */
    317 static signed char g_cCurrentJTAGState;
    318 
    319 #ifdef DEBUG
    320 
    321 /*
    322  *
    323  * GetState
    324  *
    325  * Returns the state as a string based on the opcode. Only used
    326  * for debugging purposes.
    327  *
    328  */
    329 
    330 const char *GetState(unsigned char a_ucState)
    331 {
    332 	switch (a_ucState) {
    333 	case RESET:
    334 		return "RESET";
    335 	case IDLE:
    336 		return "IDLE";
    337 	case IRPAUSE:
    338 		return "IRPAUSE";
    339 	case DRPAUSE:
    340 		return "DRPAUSE";
    341 	case SHIFTIR:
    342 		return "SHIFTIR";
    343 	case SHIFTDR:
    344 		return "SHIFTDR";
    345 	case DRCAPTURE:/* 11/15/05 support DRCAPTURE*/
    346 		return "DRCAPTURE";
    347 	default:
    348 		break;
    349 	}
    350 
    351 	return 0;
    352 }
    353 
    354 /*
    355  *
    356  * PrintData
    357  *
    358  * Prints the data. Only used for debugging purposes.
    359  *
    360  */
    361 
    362 void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData)
    363 {
    364 	/* 09/11/07 NN added local variables initialization */
    365 	unsigned short usByteSize  = 0;
    366 	unsigned short usBitIndex  = 0;
    367 	signed short usByteIndex   = 0;
    368 	unsigned char ucByte       = 0;
    369 	unsigned char ucFlipByte   = 0;
    370 
    371 	if (a_iDataSize % 8) {
    372 		/* 09/11/07 NN Type cast mismatch variables */
    373 		usByteSize = (unsigned short)(a_iDataSize / 8 + 1);
    374 	} else {
    375 		/* 09/11/07 NN Type cast mismatch variables */
    376 		usByteSize = (unsigned short)(a_iDataSize / 8);
    377 	}
    378 	puts("(");
    379 	/* 09/11/07 NN Type cast mismatch variables */
    380 	for (usByteIndex = (signed short)(usByteSize - 1);
    381 		usByteIndex >= 0; usByteIndex--) {
    382 		ucByte = a_pucData[usByteIndex];
    383 		ucFlipByte = 0x00;
    384 
    385 		/*
    386 		*
    387 		* Flip each byte.
    388 		*
    389 		*/
    390 
    391 		for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) {
    392 			ucFlipByte <<= 1;
    393 			if (ucByte & 0x1) {
    394 				ucFlipByte |= 0x1;
    395 			}
    396 
    397 			ucByte >>= 1;
    398 		}
    399 
    400 		/*
    401 		*
    402 		* Print the flipped byte.
    403 		*
    404 		*/
    405 
    406 		printf("%.02X", ucFlipByte);
    407 		if ((usByteSize - usByteIndex) % 40 == 39) {
    408 			puts("\n\t\t");
    409 		}
    410 		if (usByteIndex < 0)
    411 			break;
    412 	}
    413 	puts(")");
    414 }
    415 #endif /* DEBUG */
    416 
    417 void ispVMMemManager(signed char cTarget, unsigned short usSize)
    418 {
    419 	switch (cTarget) {
    420 	case XTDI:
    421 	case TDI:
    422 		if (g_pucInData != NULL) {
    423 			if (previous_size == usSize) {/*memory exist*/
    424 				break;
    425 			} else {
    426 				free(g_pucInData);
    427 				g_pucInData = NULL;
    428 			}
    429 		}
    430 		g_pucInData = (unsigned char *) malloc(usSize / 8 + 2);
    431 		previous_size = usSize;
    432 	case XTDO:
    433 	case TDO:
    434 		if (g_pucOutData != NULL) {
    435 			if (previous_size == usSize) { /*already exist*/
    436 				break;
    437 			} else {
    438 				free(g_pucOutData);
    439 				g_pucOutData = NULL;
    440 			}
    441 		}
    442 		g_pucOutData = (unsigned char *) malloc(usSize / 8 + 2);
    443 		previous_size = usSize;
    444 		break;
    445 	case MASK:
    446 		if (g_pucOutMaskData != NULL) {
    447 			if (previous_size == usSize) {/*already allocated*/
    448 				break;
    449 			} else {
    450 				free(g_pucOutMaskData);
    451 				g_pucOutMaskData = NULL;
    452 			}
    453 		}
    454 		g_pucOutMaskData = (unsigned char *) malloc(usSize / 8 + 2);
    455 		previous_size = usSize;
    456 		break;
    457 	case HIR:
    458 		if (g_pucHIRData != NULL) {
    459 			free(g_pucHIRData);
    460 			g_pucHIRData = NULL;
    461 		}
    462 		g_pucHIRData = (unsigned char *) malloc(usSize / 8 + 2);
    463 		break;
    464 	case TIR:
    465 		if (g_pucTIRData != NULL) {
    466 			free(g_pucTIRData);
    467 			g_pucTIRData = NULL;
    468 		}
    469 		g_pucTIRData = (unsigned char *) malloc(usSize / 8 + 2);
    470 		break;
    471 	case HDR:
    472 		if (g_pucHDRData != NULL) {
    473 			free(g_pucHDRData);
    474 			g_pucHDRData = NULL;
    475 		}
    476 		g_pucHDRData = (unsigned char *) malloc(usSize / 8 + 2);
    477 		break;
    478 	case TDR:
    479 		if (g_pucTDRData != NULL) {
    480 			free(g_pucTDRData);
    481 			g_pucTDRData = NULL;
    482 		}
    483 		g_pucTDRData = (unsigned char *) malloc(usSize / 8 + 2);
    484 		break;
    485 	case HEAP:
    486 		if (g_pucHeapMemory != NULL) {
    487 			free(g_pucHeapMemory);
    488 			g_pucHeapMemory = NULL;
    489 		}
    490 		g_pucHeapMemory = (unsigned char *) malloc(usSize + 2);
    491 		break;
    492 	case DMASK:
    493 		if (g_pucOutDMaskData != NULL) {
    494 			if (previous_size == usSize) { /*already allocated*/
    495 				break;
    496 			} else {
    497 				free(g_pucOutDMaskData);
    498 				g_pucOutDMaskData = NULL;
    499 			}
    500 		}
    501 		g_pucOutDMaskData = (unsigned char *) malloc(usSize / 8 + 2);
    502 		previous_size = usSize;
    503 		break;
    504 	case LHEAP:
    505 		if (g_pucIntelBuffer != NULL) {
    506 			free(g_pucIntelBuffer);
    507 			g_pucIntelBuffer = NULL;
    508 		}
    509 		g_pucIntelBuffer = (unsigned char *) malloc(usSize + 2);
    510 		break;
    511 	case LVDS:
    512 		if (g_pLVDSList != NULL) {
    513 			free(g_pLVDSList);
    514 			g_pLVDSList = NULL;
    515 		}
    516 		g_pLVDSList = (LVDSPair *) malloc(usSize * sizeof(LVDSPair));
    517 		if (g_pLVDSList)
    518 			memset(g_pLVDSList, 0, usSize * sizeof(LVDSPair));
    519 		break;
    520 	default:
    521 		return;
    522     }
    523 }
    524 
    525 void ispVMFreeMem(void)
    526 {
    527 	if (g_pucHeapMemory != NULL) {
    528 		free(g_pucHeapMemory);
    529 		g_pucHeapMemory = NULL;
    530 	}
    531 
    532 	if (g_pucOutMaskData != NULL) {
    533 		free(g_pucOutMaskData);
    534 		g_pucOutMaskData = NULL;
    535 	}
    536 
    537 	if (g_pucInData != NULL) {
    538 		free(g_pucInData);
    539 		g_pucInData = NULL;
    540 	}
    541 
    542 	if (g_pucOutData != NULL) {
    543 		free(g_pucOutData);
    544 		g_pucOutData = NULL;
    545 	}
    546 
    547 	if (g_pucHIRData != NULL) {
    548 		free(g_pucHIRData);
    549 		g_pucHIRData = NULL;
    550 	}
    551 
    552 	if (g_pucTIRData != NULL) {
    553 		free(g_pucTIRData);
    554 		g_pucTIRData = NULL;
    555 	}
    556 
    557 	if (g_pucHDRData != NULL) {
    558 		free(g_pucHDRData);
    559 		g_pucHDRData = NULL;
    560 	}
    561 
    562 	if (g_pucTDRData != NULL) {
    563 		free(g_pucTDRData);
    564 		g_pucTDRData = NULL;
    565 	}
    566 
    567 	if (g_pucOutDMaskData != NULL) {
    568 		free(g_pucOutDMaskData);
    569 		g_pucOutDMaskData = NULL;
    570 	}
    571 
    572 	if (g_pucIntelBuffer != NULL) {
    573 		free(g_pucIntelBuffer);
    574 		g_pucIntelBuffer = NULL;
    575 	}
    576 
    577 	if (g_pLVDSList != NULL) {
    578 		free(g_pLVDSList);
    579 		g_pLVDSList = NULL;
    580 	}
    581 }
    582 
    583 
    584 /*
    585  *
    586  * ispVMDataSize
    587  *
    588  * Returns a VME-encoded number, usually used to indicate the
    589  * bit length of an SIR/SDR command.
    590  *
    591  */
    592 
    593 long int ispVMDataSize()
    594 {
    595 	/* 09/11/07 NN added local variables initialization */
    596 	long int iSize           = 0;
    597 	signed char cCurrentByte = 0;
    598 	signed char cIndex       = 0;
    599 	cIndex = 0;
    600 	while ((cCurrentByte = GetByte()) & 0x80) {
    601 		iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex;
    602 		cIndex += 7;
    603 	}
    604 	iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex;
    605 	return iSize;
    606 }
    607 
    608 /*
    609  *
    610  * ispVMCode
    611  *
    612  * This is the heart of the embedded engine. All the high-level opcodes
    613  * are extracted here. Once they have been identified, then it
    614  * will call other functions to handle the processing.
    615  *
    616  */
    617 
    618 signed char ispVMCode()
    619 {
    620 	/* 09/11/07 NN added local variables initialization */
    621 	unsigned short iRepeatSize = 0;
    622 	signed char cOpcode	   = 0;
    623 	signed char cRetCode       = 0;
    624 	unsigned char ucState      = 0;
    625 	unsigned short usDelay     = 0;
    626 	unsigned short usToggle    = 0;
    627 	unsigned char usByte       = 0;
    628 
    629 	/*
    630 	*
    631 	* Check the compression flag only if this is the first time
    632 	* this function is entered. Do not check the compression flag if
    633 	* it is being called recursively from other functions within
    634 	* the embedded engine.
    635 	*
    636 	*/
    637 
    638 	if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) {
    639 		usByte = GetByte();
    640 		if (usByte == 0xf1) {
    641 			g_usDataType |= COMPRESS;
    642 		} else if (usByte == 0xf2) {
    643 			g_usDataType &= ~COMPRESS;
    644 		} else {
    645 			return VME_INVALID_FILE;
    646 		}
    647 	}
    648 
    649 	/*
    650 	*
    651 	* Begin looping through all the VME opcodes.
    652 	*
    653 	*/
    654 
    655 	while ((cOpcode = GetByte()) >= 0) {
    656 
    657 		switch (cOpcode) {
    658 		case STATE:
    659 
    660 			/*
    661 			 * Step the JTAG state machine.
    662 			 */
    663 
    664 			ucState = GetByte();
    665 
    666 			/*
    667 			 * Step the JTAG state machine to DRCAPTURE
    668 			 * to support Looping.
    669 			 */
    670 
    671 			if ((g_usDataType & LHEAP_IN) &&
    672 				 (ucState == DRPAUSE) &&
    673 				 (g_cCurrentJTAGState == ucState)) {
    674 				ispVMStateMachine(DRCAPTURE);
    675 			}
    676 
    677 			ispVMStateMachine(ucState);
    678 
    679 #ifdef DEBUG
    680 			if (g_usDataType & LHEAP_IN) {
    681 				debug("LDELAY %s ", GetState(ucState));
    682 			} else {
    683 				debug("STATE %s;\n", GetState(ucState));
    684 			}
    685 #endif /* DEBUG */
    686 			break;
    687 		case SIR:
    688 		case SDR:
    689 		case XSDR:
    690 
    691 #ifdef DEBUG
    692 			switch (cOpcode) {
    693 			case SIR:
    694 				puts("SIR ");
    695 				break;
    696 			case SDR:
    697 			case XSDR:
    698 				if (g_usDataType & LHEAP_IN) {
    699 					puts("LSDR ");
    700 				} else {
    701 					puts("SDR ");
    702 				}
    703 				break;
    704 			}
    705 #endif /* DEBUG */
    706 			/*
    707 			*
    708 			* Shift in data into the device.
    709 			*
    710 			*/
    711 
    712 			cRetCode = ispVMShift(cOpcode);
    713 			if (cRetCode != 0) {
    714 				return cRetCode;
    715 			}
    716 			break;
    717 		case WAIT:
    718 
    719 			/*
    720 			*
    721 			* Observe delay.
    722 			*
    723 			*/
    724 
    725 			/* 09/11/07 NN Type cast mismatch variables */
    726 			usDelay = (unsigned short) ispVMDataSize();
    727 			ispVMDelay(usDelay);
    728 
    729 #ifdef DEBUG
    730 			if (usDelay & 0x8000) {
    731 
    732 				/*
    733 				 * Since MSB is set, the delay time must be
    734 				 * decoded to millisecond. The SVF2VME encodes
    735 				 * the MSB to represent millisecond.
    736 				 */
    737 
    738 				usDelay &= ~0x8000;
    739 				if (g_usDataType & LHEAP_IN) {
    740 					printf("%.2E SEC;\n",
    741 						(float) usDelay / 1000);
    742 				} else {
    743 					printf("RUNTEST %.2E SEC;\n",
    744 						(float) usDelay / 1000);
    745 				}
    746 			} else {
    747 				/*
    748 				 * Since MSB is not set, the delay time
    749 				 * is given as microseconds.
    750 				 */
    751 
    752 				if (g_usDataType & LHEAP_IN) {
    753 					printf("%.2E SEC;\n",
    754 						(float) usDelay / 1000000);
    755 				} else {
    756 					printf("RUNTEST %.2E SEC;\n",
    757 						(float) usDelay / 1000000);
    758 				}
    759 			}
    760 #endif /* DEBUG */
    761 			break;
    762 		case TCK:
    763 
    764 			/*
    765 			 * Issue clock toggles.
    766 			*/
    767 
    768 			/* 09/11/07 NN Type cast mismatch variables */
    769 			usToggle = (unsigned short) ispVMDataSize();
    770 			ispVMClocks(usToggle);
    771 
    772 #ifdef DEBUG
    773 			printf("RUNTEST %d TCK;\n", usToggle);
    774 #endif /* DEBUG */
    775 			break;
    776 		case ENDDR:
    777 
    778 			/*
    779 			*
    780 			* Set the ENDDR.
    781 			*
    782 			*/
    783 
    784 			g_ucEndDR = GetByte();
    785 
    786 #ifdef DEBUG
    787 			printf("ENDDR %s;\n", GetState(g_ucEndDR));
    788 #endif /* DEBUG */
    789 			break;
    790 		case ENDIR:
    791 
    792 			/*
    793 			*
    794 			* Set the ENDIR.
    795 			*
    796 			*/
    797 
    798 			g_ucEndIR = GetByte();
    799 
    800 #ifdef DEBUG
    801 			printf("ENDIR %s;\n", GetState(g_ucEndIR));
    802 #endif /* DEBUG */
    803 			break;
    804 		case HIR:
    805 		case TIR:
    806 		case HDR:
    807 		case TDR:
    808 
    809 #ifdef DEBUG
    810 			switch (cOpcode) {
    811 			case HIR:
    812 				puts("HIR ");
    813 				break;
    814 			case TIR:
    815 				puts("TIR ");
    816 				break;
    817 			case HDR:
    818 				puts("HDR ");
    819 				break;
    820 			case TDR:
    821 				puts("TDR ");
    822 				break;
    823 			}
    824 #endif /* DEBUG */
    825 			/*
    826 			 * Set the header/trailer of the device in order
    827 			 * to bypass
    828 			 * successfully.
    829 			 */
    830 
    831 			cRetCode = ispVMAmble(cOpcode);
    832 			if (cRetCode != 0) {
    833 				return cRetCode;
    834 			}
    835 
    836 #ifdef DEBUG
    837 			puts(";\n");
    838 #endif /* DEBUG */
    839 			break;
    840 		case MEM:
    841 
    842 			/*
    843 			 * The maximum RAM required to support
    844 			 * processing one row of the VME file.
    845 			 */
    846 
    847 			/* 09/11/07 NN Type cast mismatch variables */
    848 			g_usMaxSize = (unsigned short) ispVMDataSize();
    849 
    850 #ifdef DEBUG
    851 			printf("// MEMSIZE %d\n", g_usMaxSize);
    852 #endif /* DEBUG */
    853 			break;
    854 		case VENDOR:
    855 
    856 			/*
    857 			*
    858 			* Set the VENDOR type.
    859 			*
    860 			*/
    861 
    862 			cOpcode = GetByte();
    863 			switch (cOpcode) {
    864 			case LATTICE:
    865 #ifdef DEBUG
    866 				puts("// VENDOR LATTICE\n");
    867 #endif /* DEBUG */
    868 				g_cVendor = LATTICE;
    869 				break;
    870 			case ALTERA:
    871 #ifdef DEBUG
    872 				puts("// VENDOR ALTERA\n");
    873 #endif /* DEBUG */
    874 				g_cVendor = ALTERA;
    875 				break;
    876 			case XILINX:
    877 #ifdef DEBUG
    878 				puts("// VENDOR XILINX\n");
    879 #endif /* DEBUG */
    880 				g_cVendor = XILINX;
    881 				break;
    882 			default:
    883 				break;
    884 			}
    885 			break;
    886 		case SETFLOW:
    887 
    888 			/*
    889 			 * Set the flow control. Flow control determines
    890 			 * the personality of the embedded engine.
    891 			 */
    892 
    893 			/* 09/11/07 NN Type cast mismatch variables */
    894 			g_usFlowControl |= (unsigned short) ispVMDataSize();
    895 			break;
    896 		case RESETFLOW:
    897 
    898 			/*
    899 			*
    900 			* Unset the flow control.
    901 			*
    902 			*/
    903 
    904 			/* 09/11/07 NN Type cast mismatch variables */
    905 			g_usFlowControl &= (unsigned short) ~(ispVMDataSize());
    906 			break;
    907 		case HEAP:
    908 
    909 			/*
    910 			*
    911 			* Allocate heap size to store loops.
    912 			*
    913 			*/
    914 
    915 			cRetCode = GetByte();
    916 			if (cRetCode != SECUREHEAP) {
    917 				return VME_INVALID_FILE;
    918 			}
    919 			/* 09/11/07 NN Type cast mismatch variables */
    920 			g_iHEAPSize = (unsigned short) ispVMDataSize();
    921 
    922 			/*
    923 			 * Store the maximum size of the HEAP buffer.
    924 			 * Used to convert VME to HEX.
    925 			 */
    926 
    927 			if (g_iHEAPSize > g_usHeapSize) {
    928 				g_usHeapSize = g_iHEAPSize;
    929 			}
    930 
    931 			ispVMMemManager(HEAP, (unsigned short) g_iHEAPSize);
    932 			break;
    933 		case REPEAT:
    934 
    935 			/*
    936 			*
    937 			* Execute loops.
    938 			*
    939 			*/
    940 
    941 			g_usRepeatLoops = 0;
    942 
    943 			/* 09/11/07 NN Type cast mismatch variables */
    944 			iRepeatSize = (unsigned short) ispVMDataSize();
    945 
    946 			cRetCode = ispVMLoop((unsigned short) iRepeatSize);
    947 			if (cRetCode != 0) {
    948 				return cRetCode;
    949 			}
    950 			break;
    951 		case ENDLOOP:
    952 
    953 			/*
    954 			*
    955 			* Exit point from processing loops.
    956 			*
    957 			*/
    958 
    959 			return cRetCode;
    960 		case ENDVME:
    961 
    962 			/*
    963 			 * The only valid exit point that indicates
    964 			 * end of programming.
    965 			 */
    966 
    967 			return cRetCode;
    968 		case SHR:
    969 
    970 			/*
    971 			*
    972 			* Right-shift address.
    973 			*
    974 			*/
    975 
    976 			g_usFlowControl |= SHIFTRIGHT;
    977 
    978 			/* 09/11/07 NN Type cast mismatch variables */
    979 			g_usShiftValue = (unsigned short) (g_usRepeatLoops *
    980 				(unsigned short)GetByte());
    981 			break;
    982 		case SHL:
    983 
    984 			/*
    985 			 * Left-shift address.
    986 			 */
    987 
    988 			g_usFlowControl |= SHIFTLEFT;
    989 
    990 			/* 09/11/07 NN Type cast mismatch variables */
    991 			g_usShiftValue = (unsigned short) (g_usRepeatLoops *
    992 				(unsigned short)GetByte());
    993 			break;
    994 		case FREQUENCY:
    995 
    996 			/*
    997 			*
    998 			* Set the frequency.
    999 			*
   1000 			*/
   1001 
   1002 			/* 09/11/07 NN Type cast mismatch variables */
   1003 			g_iFrequency = (int) (ispVMDataSize() / 1000);
   1004 			if (g_iFrequency == 1)
   1005 				g_iFrequency = 1000;
   1006 
   1007 #ifdef DEBUG
   1008 			printf("FREQUENCY %.2E HZ;\n",
   1009 				(float) g_iFrequency * 1000);
   1010 #endif /* DEBUG */
   1011 			break;
   1012 		case LCOUNT:
   1013 
   1014 			/*
   1015 			*
   1016 			* Process LCOUNT command.
   1017 			*
   1018 			*/
   1019 
   1020 			cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize());
   1021 			if (cRetCode != 0) {
   1022 				return cRetCode;
   1023 			}
   1024 			break;
   1025 		case VUES:
   1026 
   1027 			/*
   1028 			*
   1029 			* Set the flow control to verify USERCODE.
   1030 			*
   1031 			*/
   1032 
   1033 			g_usFlowControl |= VERIFYUES;
   1034 			break;
   1035 		case COMMENT:
   1036 
   1037 			/*
   1038 			*
   1039 			* Display comment.
   1040 			*
   1041 			*/
   1042 
   1043 			ispVMComment((unsigned short) ispVMDataSize());
   1044 			break;
   1045 		case LVDS:
   1046 
   1047 			/*
   1048 			*
   1049 			* Process LVDS command.
   1050 			*
   1051 			*/
   1052 
   1053 			ispVMProcessLVDS((unsigned short) ispVMDataSize());
   1054 			break;
   1055 		case HEADER:
   1056 
   1057 			/*
   1058 			*
   1059 			* Discard header.
   1060 			*
   1061 			*/
   1062 
   1063 			ispVMHeader((unsigned short) ispVMDataSize());
   1064 			break;
   1065 		/* 03/14/06 Support Toggle ispENABLE signal*/
   1066 		case ispEN:
   1067 			ucState = GetByte();
   1068 			if ((ucState == ON) || (ucState == 0x01))
   1069 				writePort(g_ucPinENABLE, 0x01);
   1070 			else
   1071 				writePort(g_ucPinENABLE, 0x00);
   1072 			ispVMDelay(1);
   1073 			break;
   1074 		/* 05/24/06 support Toggle TRST pin*/
   1075 		case TRST:
   1076 			ucState = GetByte();
   1077 			if (ucState == 0x01)
   1078 				writePort(g_ucPinTRST, 0x01);
   1079 			else
   1080 				writePort(g_ucPinTRST, 0x00);
   1081 			ispVMDelay(1);
   1082 			break;
   1083 		default:
   1084 
   1085 			/*
   1086 			*
   1087 			* Invalid opcode encountered.
   1088 			*
   1089 			*/
   1090 
   1091 #ifdef DEBUG
   1092 			printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode);
   1093 #endif /* DEBUG */
   1094 
   1095 			return VME_INVALID_FILE;
   1096 		}
   1097 	}
   1098 
   1099 	/*
   1100 	*
   1101 	* Invalid exit point. Processing the token 'ENDVME' is the only
   1102 	* valid way to exit the embedded engine.
   1103 	*
   1104 	*/
   1105 
   1106 	return VME_INVALID_FILE;
   1107 }
   1108 
   1109 /*
   1110  *
   1111  * ispVMDataCode
   1112  *
   1113  * Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command.
   1114  *
   1115  */
   1116 
   1117 signed char ispVMDataCode()
   1118 {
   1119 	/* 09/11/07 NN added local variables initialization */
   1120 	signed char cDataByte    = 0;
   1121 	signed char siDataSource = 0;  /*source of data from file by default*/
   1122 
   1123 	if (g_usDataType & HEAP_IN) {
   1124 		siDataSource = 1;  /*the source of data from memory*/
   1125 	}
   1126 
   1127 	/*
   1128 	*
   1129 	* Clear the data type register.
   1130 	*
   1131 	**/
   1132 
   1133 	g_usDataType &= ~(MASK_DATA + TDI_DATA +
   1134 		TDO_DATA + DMASK_DATA + CMASK_DATA);
   1135 
   1136 	/*
   1137 	 * Iterate through SIR/SDR command and look for TDI,
   1138 	 * TDO, MASK, etc.
   1139 	 */
   1140 
   1141 	while ((cDataByte = GetByte()) >= 0) {
   1142 			ispVMMemManager(cDataByte, g_usMaxSize);
   1143 			switch (cDataByte) {
   1144 			case TDI:
   1145 
   1146 				/*
   1147 				 * Store the maximum size of the TDI buffer.
   1148 				 * Used to convert VME to HEX.
   1149 				 */
   1150 
   1151 				if (g_usiDataSize > g_usTDISize) {
   1152 					g_usTDISize = g_usiDataSize;
   1153 				}
   1154 				/*
   1155 				 * Updated data type register to indicate that
   1156 				 * TDI data is currently being used. Process the
   1157 				 * data in the VME file into the TDI buffer.
   1158 				 */
   1159 
   1160 				g_usDataType |= TDI_DATA;
   1161 				ispVMData(g_pucInData);
   1162 				break;
   1163 			case XTDO:
   1164 
   1165 				/*
   1166 				 * Store the maximum size of the TDO buffer.
   1167 				 * Used to convert VME to HEX.
   1168 				 */
   1169 
   1170 				if (g_usiDataSize > g_usTDOSize) {
   1171 					g_usTDOSize = g_usiDataSize;
   1172 				}
   1173 
   1174 				/*
   1175 				 * Updated data type register to indicate that
   1176 				 * TDO data is currently being used.
   1177 				 */
   1178 
   1179 				g_usDataType |= TDO_DATA;
   1180 				break;
   1181 			case TDO:
   1182 
   1183 				/*
   1184 				 * Store the maximum size of the TDO buffer.
   1185 				 * Used to convert VME to HEX.
   1186 				 */
   1187 
   1188 				if (g_usiDataSize > g_usTDOSize) {
   1189 					g_usTDOSize = g_usiDataSize;
   1190 				}
   1191 
   1192 				/*
   1193 				 * Updated data type register to indicate
   1194 				 * that TDO data is currently being used.
   1195 				 * Process the data in the VME file into the
   1196 				 * TDO buffer.
   1197 				 */
   1198 
   1199 				g_usDataType |= TDO_DATA;
   1200 				ispVMData(g_pucOutData);
   1201 				break;
   1202 			case MASK:
   1203 
   1204 				/*
   1205 				 * Store the maximum size of the MASK buffer.
   1206 				 * Used to convert VME to HEX.
   1207 				 */
   1208 
   1209 				if (g_usiDataSize > g_usMASKSize) {
   1210 					g_usMASKSize = g_usiDataSize;
   1211 				}
   1212 
   1213 				/*
   1214 				 * Updated data type register to indicate that
   1215 				 * MASK data is currently being used. Process
   1216 				 * the data in the VME file into the MASK buffer
   1217 				 */
   1218 
   1219 				g_usDataType |= MASK_DATA;
   1220 				ispVMData(g_pucOutMaskData);
   1221 				break;
   1222 			case DMASK:
   1223 
   1224 				/*
   1225 				 * Store the maximum size of the DMASK buffer.
   1226 				 * Used to convert VME to HEX.
   1227 				 */
   1228 
   1229 				if (g_usiDataSize > g_usDMASKSize) {
   1230 					g_usDMASKSize = g_usiDataSize;
   1231 				}
   1232 
   1233 				/*
   1234 				 * Updated data type register to indicate that
   1235 				 * DMASK data is currently being used. Process
   1236 				 * the data in the VME file into the DMASK
   1237 				 * buffer.
   1238 				 */
   1239 
   1240 				g_usDataType |= DMASK_DATA;
   1241 				ispVMData(g_pucOutDMaskData);
   1242 				break;
   1243 			case CMASK:
   1244 
   1245 				/*
   1246 				 * Updated data type register to indicate that
   1247 				 * MASK data is currently being used. Process
   1248 				 * the data in the VME file into the MASK buffer
   1249 				 */
   1250 
   1251 				g_usDataType |= CMASK_DATA;
   1252 				ispVMData(g_pucOutMaskData);
   1253 				break;
   1254 			case CONTINUE:
   1255 				return 0;
   1256 			default:
   1257 				/*
   1258 				 * Encountered invalid opcode.
   1259 				 */
   1260 				return VME_INVALID_FILE;
   1261 			}
   1262 
   1263 			switch (cDataByte) {
   1264 			case TDI:
   1265 
   1266 				/*
   1267 				 * Left bit shift. Used when performing
   1268 				 * algorithm looping.
   1269 				 */
   1270 
   1271 				if (g_usFlowControl & SHIFTLEFT) {
   1272 					ispVMBitShift(SHL, g_usShiftValue);
   1273 					g_usFlowControl &= ~SHIFTLEFT;
   1274 				}
   1275 
   1276 				/*
   1277 				 * Right bit shift. Used when performing
   1278 				 * algorithm looping.
   1279 				 */
   1280 
   1281 				if (g_usFlowControl & SHIFTRIGHT) {
   1282 					ispVMBitShift(SHR, g_usShiftValue);
   1283 					g_usFlowControl &= ~SHIFTRIGHT;
   1284 				}
   1285 			default:
   1286 				break;
   1287 			}
   1288 
   1289 			if (siDataSource) {
   1290 				g_usDataType |= HEAP_IN; /*restore from memory*/
   1291 			}
   1292 	}
   1293 
   1294 	if (siDataSource) {  /*fetch data from heap memory upon return*/
   1295 		g_usDataType |= HEAP_IN;
   1296 	}
   1297 
   1298 	if (cDataByte < 0) {
   1299 
   1300 		/*
   1301 		 * Encountered invalid opcode.
   1302 		 */
   1303 
   1304 		return VME_INVALID_FILE;
   1305 	} else {
   1306 		return 0;
   1307 	}
   1308 }
   1309 
   1310 /*
   1311  *
   1312  * ispVMData
   1313  * Extract one row of data operand from the current data type opcode. Perform
   1314  * the decompression if necessary. Extra RAM is not required for the
   1315  * decompression process. The decompression scheme employed in this module
   1316  * is on row by row basis. The format of the data stream:
   1317  * [compression code][compressed data stream]
   1318  * 0x00    --No compression
   1319  * 0x01    --Compress by 0x00.
   1320  *           Example:
   1321  *           Original stream:   0x000000000000000000000001
   1322  *           Compressed stream: 0x01000901
   1323  *           Detail:            0x01 is the code, 0x00 is the key,
   1324  *                              0x09 is the count of 0x00 bytes,
   1325  *                              0x01 is the uncompressed byte.
   1326  * 0x02    --Compress by 0xFF.
   1327  *           Example:
   1328  *           Original stream:   0xFFFFFFFFFFFFFFFFFFFFFF01
   1329  *           Compressed stream: 0x02FF0901
   1330  *           Detail:            0x02 is the code, 0xFF is the key,
   1331  *                              0x09 is the count of 0xFF bytes,
   1332  *                              0x01 is the uncompressed byte.
   1333  * 0x03
   1334  * : :
   1335  * 0xFE   -- Compress by nibble blocks.
   1336  *           Example:
   1337  *           Original stream:   0x84210842108421084210
   1338  *           Compressed stream: 0x0584210
   1339  *           Detail:            0x05 is the code, means 5 nibbles block.
   1340  *                              0x84210 is the 5 nibble blocks.
   1341  *                              The whole row is 80 bits given by g_usiDataSize.
   1342  *                              The number of times the block repeat itself
   1343  *                              is found by g_usiDataSize/(4*0x05) which is 4.
   1344  * 0xFF   -- Compress by the most frequently happen byte.
   1345  *           Example:
   1346  *           Original stream:   0x04020401030904040404
   1347  *           Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0)
   1348  *                          or: 0xFF044090181C240
   1349  *           Detail:            0xFF is the code, 0x04 is the key.
   1350  *                              a bit of 0 represent the key shall be put into
   1351  *                              the current bit position and a bit of 1
   1352  *                              represent copying the next of 8 bits of data
   1353  *                              in.
   1354  *
   1355  */
   1356 
   1357 void ispVMData(unsigned char *ByteData)
   1358 {
   1359 	/* 09/11/07 NN added local variables initialization */
   1360 	unsigned short size               = 0;
   1361 	unsigned short i, j, m, getData   = 0;
   1362 	unsigned char cDataByte           = 0;
   1363 	unsigned char compress            = 0;
   1364 	unsigned short FFcount            = 0;
   1365 	unsigned char compr_char          = 0xFF;
   1366 	unsigned short index              = 0;
   1367 	signed char compression           = 0;
   1368 
   1369 	/*convert number in bits to bytes*/
   1370 	if (g_usiDataSize % 8 > 0) {
   1371 		/* 09/11/07 NN Type cast mismatch variables */
   1372 		size = (unsigned short)(g_usiDataSize / 8 + 1);
   1373 	} else {
   1374 		/* 09/11/07 NN Type cast mismatch variables */
   1375 		size = (unsigned short)(g_usiDataSize / 8);
   1376 	}
   1377 
   1378 	/*
   1379 	 * If there is compression, then check if compress by key
   1380 	 * of 0x00 or 0xFF or by other keys or by nibble blocks
   1381 	 */
   1382 
   1383 	if (g_usDataType & COMPRESS) {
   1384 		compression = 1;
   1385 		compress = GetByte();
   1386 		if ((compress  == VAR) && (g_usDataType & HEAP_IN)) {
   1387 			getData = 1;
   1388 			g_usDataType &= ~(HEAP_IN);
   1389 			compress = GetByte();
   1390 		}
   1391 
   1392 		switch (compress) {
   1393 		case 0x00:
   1394 			/* No compression */
   1395 			compression = 0;
   1396 			break;
   1397 		case 0x01:
   1398 			/* Compress by byte 0x00 */
   1399 			compr_char = 0x00;
   1400 			break;
   1401 		case 0x02:
   1402 			/* Compress by byte 0xFF */
   1403 			compr_char = 0xFF;
   1404 			break;
   1405 		case 0xFF:
   1406 			/* Huffman encoding */
   1407 			compr_char = GetByte();
   1408 			i = 8;
   1409 			for (index = 0; index < size; index++) {
   1410 				ByteData[index] = 0x00;
   1411 				if (i > 7) {
   1412 					cDataByte = GetByte();
   1413 					i = 0;
   1414 				}
   1415 				if ((cDataByte << i++) & 0x80)
   1416 					m = 8;
   1417 				else {
   1418 					ByteData[index] = compr_char;
   1419 					m = 0;
   1420 				}
   1421 
   1422 				for (j = 0; j < m; j++) {
   1423 					if (i > 7) {
   1424 						cDataByte = GetByte();
   1425 						i = 0;
   1426 					}
   1427 					ByteData[index] |=
   1428 					((cDataByte << i++) & 0x80) >> j;
   1429 				}
   1430 			}
   1431 			size = 0;
   1432 			break;
   1433 		default:
   1434 			for (index = 0; index < size; index++)
   1435 				ByteData[index] = 0x00;
   1436 			for (index = 0; index < compress; index++) {
   1437 				if (index % 2 == 0)
   1438 					cDataByte = GetByte();
   1439 				for (i = 0; i < size * 2 / compress; i++) {
   1440 					j = (unsigned short)(index +
   1441 						(i * (unsigned short)compress));
   1442 					/*clear the nibble to zero first*/
   1443 					if (j%2) {
   1444 						if (index % 2)
   1445 							ByteData[j/2] |=
   1446 								cDataByte & 0xF;
   1447 						else
   1448 							ByteData[j/2] |=
   1449 								cDataByte >> 4;
   1450 					} else {
   1451 						if (index % 2)
   1452 							ByteData[j/2] |=
   1453 								cDataByte << 4;
   1454 						else
   1455 							ByteData[j/2] |=
   1456 							cDataByte & 0xF0;
   1457 					}
   1458 				}
   1459 			}
   1460 			size = 0;
   1461 			break;
   1462 		}
   1463 	}
   1464 
   1465 	FFcount = 0;
   1466 
   1467 	/* Decompress by byte 0x00 or 0xFF */
   1468 	for (index = 0; index < size; index++) {
   1469 		if (FFcount <= 0) {
   1470 			cDataByte = GetByte();
   1471 			if ((cDataByte == VAR) && (g_usDataType&HEAP_IN) &&
   1472 				!getData && !(g_usDataType&COMPRESS)) {
   1473 				getData = 1;
   1474 				g_usDataType &= ~(HEAP_IN);
   1475 				cDataByte = GetByte();
   1476 			}
   1477 			ByteData[index] = cDataByte;
   1478 			if ((compression) && (cDataByte == compr_char))
   1479 				/* 09/11/07 NN Type cast mismatch variables */
   1480 				FFcount = (unsigned short) ispVMDataSize();
   1481 				/*The number of 0xFF or 0x00 bytes*/
   1482 		} else {
   1483 			FFcount--; /*Use up the 0xFF chain first*/
   1484 			ByteData[index] = compr_char;
   1485 		}
   1486 	}
   1487 
   1488 	if (getData) {
   1489 		g_usDataType |= HEAP_IN;
   1490 		getData = 0;
   1491 	}
   1492 }
   1493 
   1494 /*
   1495  *
   1496  * ispVMShift
   1497  *
   1498  * Processes the SDR/XSDR/SIR commands.
   1499  *
   1500  */
   1501 
   1502 signed char ispVMShift(signed char a_cCode)
   1503 {
   1504 	/* 09/11/07 NN added local variables initialization */
   1505 	unsigned short iDataIndex  = 0;
   1506 	unsigned short iReadLoop   = 0;
   1507 	signed char cRetCode       = 0;
   1508 
   1509 	cRetCode = 0;
   1510 	/* 09/11/07 NN Type cast mismatch variables */
   1511 	g_usiDataSize = (unsigned short) ispVMDataSize();
   1512 
   1513 	/*clear the flags first*/
   1514 	g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA);
   1515 	switch (a_cCode) {
   1516 	case SIR:
   1517 		g_usDataType |= SIR_DATA;
   1518 		/*
   1519 		 * 1/15/04 If performing cascading, then go directly to SHIFTIR.
   1520 		 *  Else, go to IRPAUSE before going to SHIFTIR
   1521 		 */
   1522 		if (g_usFlowControl & CASCADE) {
   1523 			ispVMStateMachine(SHIFTIR);
   1524 		} else {
   1525 			ispVMStateMachine(IRPAUSE);
   1526 			ispVMStateMachine(SHIFTIR);
   1527 			if (g_usHeadIR > 0) {
   1528 				ispVMBypass(HIR, g_usHeadIR);
   1529 				sclock();
   1530 			}
   1531 		}
   1532 		break;
   1533 	case XSDR:
   1534 		g_usDataType |= EXPRESS; /*mark simultaneous in and out*/
   1535 	case SDR:
   1536 		g_usDataType |= SDR_DATA;
   1537 		/*
   1538 		 * 1/15/04 If already in SHIFTDR, then do not move state or
   1539 		 * shift in header.  This would imply that the previously
   1540 		 * shifted frame was a cascaded frame.
   1541 		 */
   1542 		if (g_cCurrentJTAGState != SHIFTDR) {
   1543 			/*
   1544 			 * 1/15/04 If performing cascading, then go directly
   1545 			 * to SHIFTDR.  Else, go to DRPAUSE before going
   1546 			 * to SHIFTDR
   1547 			 */
   1548 			if (g_usFlowControl & CASCADE) {
   1549 				if (g_cCurrentJTAGState == DRPAUSE) {
   1550 					ispVMStateMachine(SHIFTDR);
   1551 					/*
   1552 					 * 1/15/04 If cascade flag has been seat
   1553 					 * and the current state is DRPAUSE,
   1554 					 * this implies that the first cascaded
   1555 					 * frame is about to be shifted in.  The
   1556 					 * header must be shifted prior to
   1557 					 * shifting the first cascaded frame.
   1558 					 */
   1559 					if (g_usHeadDR > 0) {
   1560 						ispVMBypass(HDR, g_usHeadDR);
   1561 						sclock();
   1562 					}
   1563 				} else {
   1564 					ispVMStateMachine(SHIFTDR);
   1565 				}
   1566 			} else {
   1567 				ispVMStateMachine(DRPAUSE);
   1568 				ispVMStateMachine(SHIFTDR);
   1569 				if (g_usHeadDR > 0) {
   1570 					ispVMBypass(HDR, g_usHeadDR);
   1571 					sclock();
   1572 				}
   1573 			}
   1574 		}
   1575 		break;
   1576 	default:
   1577 		return VME_INVALID_FILE;
   1578 	}
   1579 
   1580 	cRetCode = ispVMDataCode();
   1581 
   1582 	if (cRetCode != 0) {
   1583 		return VME_INVALID_FILE;
   1584 	}
   1585 
   1586 #ifdef DEBUG
   1587 	printf("%d ", g_usiDataSize);
   1588 
   1589 	if (g_usDataType & TDI_DATA) {
   1590 		puts("TDI ");
   1591 		PrintData(g_usiDataSize, g_pucInData);
   1592 	}
   1593 
   1594 	if (g_usDataType & TDO_DATA) {
   1595 		puts("\n\t\tTDO ");
   1596 		PrintData(g_usiDataSize, g_pucOutData);
   1597 	}
   1598 
   1599 	if (g_usDataType & MASK_DATA) {
   1600 		puts("\n\t\tMASK ");
   1601 		PrintData(g_usiDataSize, g_pucOutMaskData);
   1602 	}
   1603 
   1604 	if (g_usDataType & DMASK_DATA) {
   1605 		puts("\n\t\tDMASK ");
   1606 		PrintData(g_usiDataSize, g_pucOutDMaskData);
   1607 	}
   1608 
   1609 	puts(";\n");
   1610 #endif /* DEBUG */
   1611 
   1612 	if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) {
   1613 		if (g_usDataType & DMASK_DATA) {
   1614 			cRetCode = ispVMReadandSave(g_usiDataSize);
   1615 			if (!cRetCode) {
   1616 				if (g_usTailDR > 0) {
   1617 					sclock();
   1618 					ispVMBypass(TDR, g_usTailDR);
   1619 				}
   1620 				ispVMStateMachine(DRPAUSE);
   1621 				ispVMStateMachine(SHIFTDR);
   1622 				if (g_usHeadDR > 0) {
   1623 					ispVMBypass(HDR, g_usHeadDR);
   1624 					sclock();
   1625 				}
   1626 				for (iDataIndex = 0;
   1627 					iDataIndex < g_usiDataSize / 8 + 1;
   1628 					iDataIndex++)
   1629 					g_pucInData[iDataIndex] =
   1630 						g_pucOutData[iDataIndex];
   1631 				g_usDataType &= ~(TDO_DATA + DMASK_DATA);
   1632 				cRetCode = ispVMSend(g_usiDataSize);
   1633 			}
   1634 		} else {
   1635 			cRetCode = ispVMRead(g_usiDataSize);
   1636 			if (cRetCode == -1 && g_cVendor == XILINX) {
   1637 				for (iReadLoop = 0; iReadLoop < 30;
   1638 					iReadLoop++) {
   1639 					cRetCode = ispVMRead(g_usiDataSize);
   1640 					if (!cRetCode) {
   1641 						break;
   1642 					} else {
   1643 						/* Always DRPAUSE */
   1644 						ispVMStateMachine(DRPAUSE);
   1645 						/*
   1646 						 * Bypass other devices
   1647 						 * when appropriate
   1648 						 */
   1649 						ispVMBypass(TDR, g_usTailDR);
   1650 						ispVMStateMachine(g_ucEndDR);
   1651 						ispVMStateMachine(IDLE);
   1652 						ispVMDelay(1000);
   1653 					}
   1654 				}
   1655 			}
   1656 		}
   1657 	} else { /*TDI only*/
   1658 		cRetCode = ispVMSend(g_usiDataSize);
   1659 	}
   1660 
   1661 	/*transfer the input data to the output buffer for the next verify*/
   1662 	if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) {
   1663 		if (g_pucOutData) {
   1664 			for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1;
   1665 				iDataIndex++)
   1666 				g_pucOutData[iDataIndex] =
   1667 					g_pucInData[iDataIndex];
   1668 		}
   1669 	}
   1670 
   1671 	switch (a_cCode) {
   1672 	case SIR:
   1673 		/* 1/15/04 If not performing cascading, then shift ENDIR */
   1674 		if (!(g_usFlowControl & CASCADE)) {
   1675 			if (g_usTailIR > 0) {
   1676 				sclock();
   1677 				ispVMBypass(TIR, g_usTailIR);
   1678 			}
   1679 			ispVMStateMachine(g_ucEndIR);
   1680 		}
   1681 		break;
   1682 	case XSDR:
   1683 	case SDR:
   1684 		/* 1/15/04 If not performing cascading, then shift ENDDR */
   1685 		if (!(g_usFlowControl & CASCADE)) {
   1686 			if (g_usTailDR > 0) {
   1687 				sclock();
   1688 				ispVMBypass(TDR, g_usTailDR);
   1689 			}
   1690 			ispVMStateMachine(g_ucEndDR);
   1691 		}
   1692 		break;
   1693 	default:
   1694 		break;
   1695 	}
   1696 
   1697 	return cRetCode;
   1698 }
   1699 
   1700 /*
   1701  *
   1702  * ispVMAmble
   1703  *
   1704  * This routine is to extract Header and Trailer parameter for SIR and
   1705  * SDR operations.
   1706  *
   1707  * The Header and Trailer parameter are the pre-amble and post-amble bit
   1708  * stream need to be shifted into TDI or out of TDO of the devices. Mostly
   1709  * is for the purpose of bypassing the leading or trailing devices. ispVM
   1710  * supports only shifting data into TDI to bypass the devices.
   1711  *
   1712  * For a single device, the header and trailer parameters are all set to 0
   1713  * as default by ispVM. If it is for multiple devices, the header and trailer
   1714  * value will change as specified by the VME file.
   1715  *
   1716  */
   1717 
   1718 signed char ispVMAmble(signed char Code)
   1719 {
   1720 	signed char compress = 0;
   1721 	/* 09/11/07 NN Type cast mismatch variables */
   1722 	g_usiDataSize = (unsigned short)ispVMDataSize();
   1723 
   1724 #ifdef DEBUG
   1725 	printf("%d", g_usiDataSize);
   1726 #endif /* DEBUG */
   1727 
   1728 	if (g_usiDataSize) {
   1729 
   1730 		/*
   1731 		 * Discard the TDI byte and set the compression bit in the data
   1732 		 * type register to false if compression is set because TDI data
   1733 		 * after HIR/HDR/TIR/TDR is not compressed.
   1734 		 */
   1735 
   1736 		GetByte();
   1737 		if (g_usDataType & COMPRESS) {
   1738 			g_usDataType &= ~(COMPRESS);
   1739 			compress = 1;
   1740 		}
   1741 	}
   1742 
   1743 	switch (Code) {
   1744 	case HIR:
   1745 
   1746 		/*
   1747 		 * Store the maximum size of the HIR buffer.
   1748 		 * Used to convert VME to HEX.
   1749 		 */
   1750 
   1751 		if (g_usiDataSize > g_usHIRSize) {
   1752 			g_usHIRSize = g_usiDataSize;
   1753 		}
   1754 
   1755 		/*
   1756 		 * Assign the HIR value and allocate memory.
   1757 		 */
   1758 
   1759 		g_usHeadIR = g_usiDataSize;
   1760 		if (g_usHeadIR) {
   1761 			ispVMMemManager(HIR, g_usHeadIR);
   1762 			ispVMData(g_pucHIRData);
   1763 
   1764 #ifdef DEBUG
   1765 			puts(" TDI ");
   1766 			PrintData(g_usHeadIR, g_pucHIRData);
   1767 #endif /* DEBUG */
   1768 		}
   1769 		break;
   1770 	case TIR:
   1771 
   1772 		/*
   1773 		 * Store the maximum size of the TIR buffer.
   1774 		 * Used to convert VME to HEX.
   1775 		 */
   1776 
   1777 		if (g_usiDataSize > g_usTIRSize) {
   1778 			g_usTIRSize = g_usiDataSize;
   1779 		}
   1780 
   1781 		/*
   1782 		 * Assign the TIR value and allocate memory.
   1783 		 */
   1784 
   1785 		g_usTailIR = g_usiDataSize;
   1786 		if (g_usTailIR) {
   1787 			ispVMMemManager(TIR, g_usTailIR);
   1788 			ispVMData(g_pucTIRData);
   1789 
   1790 #ifdef DEBUG
   1791 			puts(" TDI ");
   1792 			PrintData(g_usTailIR, g_pucTIRData);
   1793 #endif /* DEBUG */
   1794 		}
   1795 		break;
   1796 	case HDR:
   1797 
   1798 		/*
   1799 		 * Store the maximum size of the HDR buffer.
   1800 		 * Used to convert VME to HEX.
   1801 		 */
   1802 
   1803 		if (g_usiDataSize > g_usHDRSize) {
   1804 			g_usHDRSize = g_usiDataSize;
   1805 		}
   1806 
   1807 		/*
   1808 		 * Assign the HDR value and allocate memory.
   1809 		 *
   1810 		 */
   1811 
   1812 		g_usHeadDR = g_usiDataSize;
   1813 		if (g_usHeadDR) {
   1814 			ispVMMemManager(HDR, g_usHeadDR);
   1815 			ispVMData(g_pucHDRData);
   1816 
   1817 #ifdef DEBUG
   1818 			puts(" TDI ");
   1819 			PrintData(g_usHeadDR, g_pucHDRData);
   1820 #endif /* DEBUG */
   1821 		}
   1822 		break;
   1823 	case TDR:
   1824 
   1825 		/*
   1826 		 * Store the maximum size of the TDR buffer.
   1827 		 * Used to convert VME to HEX.
   1828 		 */
   1829 
   1830 		if (g_usiDataSize > g_usTDRSize) {
   1831 			g_usTDRSize = g_usiDataSize;
   1832 		}
   1833 
   1834 		/*
   1835 		 * Assign the TDR value and allocate memory.
   1836 		 *
   1837 		 */
   1838 
   1839 		g_usTailDR = g_usiDataSize;
   1840 		if (g_usTailDR) {
   1841 			ispVMMemManager(TDR, g_usTailDR);
   1842 			ispVMData(g_pucTDRData);
   1843 
   1844 #ifdef DEBUG
   1845 			puts(" TDI ");
   1846 			PrintData(g_usTailDR, g_pucTDRData);
   1847 #endif /* DEBUG */
   1848 		}
   1849 		break;
   1850 	default:
   1851 		break;
   1852 	}
   1853 
   1854 	/*
   1855 	*
   1856 	* Re-enable compression if it was previously set.
   1857 	*
   1858 	**/
   1859 
   1860 	if (compress) {
   1861 		g_usDataType |= COMPRESS;
   1862 	}
   1863 
   1864 	if (g_usiDataSize) {
   1865 		Code = GetByte();
   1866 		if (Code == CONTINUE) {
   1867 			return 0;
   1868 		} else {
   1869 
   1870 			/*
   1871 			 * Encountered invalid opcode.
   1872 			 */
   1873 
   1874 			return VME_INVALID_FILE;
   1875 		}
   1876 	}
   1877 
   1878 	return 0;
   1879 }
   1880 
   1881 /*
   1882  *
   1883  * ispVMLoop
   1884  *
   1885  * Perform the function call upon by the REPEAT opcode.
   1886  * Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP.
   1887  * After the loop is stored then execution begin. The REPEATLOOP flag is set
   1888  * on the g_usFlowControl register to indicate the repeat loop is in session
   1889  * and therefore fetch opcode from the memory instead of from the file.
   1890  *
   1891  */
   1892 
   1893 signed char ispVMLoop(unsigned short a_usLoopCount)
   1894 {
   1895 	/* 09/11/07 NN added local variables initialization */
   1896 	signed char cRetCode      = 0;
   1897 	unsigned short iHeapIndex = 0;
   1898 	unsigned short iLoopIndex = 0;
   1899 
   1900 	g_usShiftValue = 0;
   1901 	for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) {
   1902 		g_pucHeapMemory[iHeapIndex] = GetByte();
   1903 	}
   1904 
   1905 	if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) {
   1906 		return VME_INVALID_FILE;
   1907 	}
   1908 
   1909 	g_usFlowControl |= REPEATLOOP;
   1910 	g_usDataType |= HEAP_IN;
   1911 
   1912 	for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) {
   1913 		g_iHeapCounter = 0;
   1914 		cRetCode = ispVMCode();
   1915 		g_usRepeatLoops++;
   1916 		if (cRetCode < 0) {
   1917 			break;
   1918 		}
   1919 	}
   1920 
   1921 	g_usDataType &= ~(HEAP_IN);
   1922 	g_usFlowControl &= ~(REPEATLOOP);
   1923 	return cRetCode;
   1924 }
   1925 
   1926 /*
   1927  *
   1928  * ispVMBitShift
   1929  *
   1930  * Shift the TDI stream left or right by the number of bits. The data in
   1931  * *g_pucInData is of the VME format, so the actual shifting is the reverse of
   1932  * IEEE 1532 or SVF format.
   1933  *
   1934  */
   1935 
   1936 signed char ispVMBitShift(signed char mode, unsigned short bits)
   1937 {
   1938 	/* 09/11/07 NN added local variables initialization */
   1939 	unsigned short i       = 0;
   1940 	unsigned short size    = 0;
   1941 	unsigned short tmpbits = 0;
   1942 
   1943 	if (g_usiDataSize % 8 > 0) {
   1944 		/* 09/11/07 NN Type cast mismatch variables */
   1945 		size = (unsigned short)(g_usiDataSize / 8 + 1);
   1946 	} else {
   1947 		/* 09/11/07 NN Type cast mismatch variables */
   1948 		size = (unsigned short)(g_usiDataSize / 8);
   1949 	}
   1950 
   1951 	switch (mode) {
   1952 	case SHR:
   1953 		for (i = 0; i < size; i++) {
   1954 			if (g_pucInData[i] != 0) {
   1955 				tmpbits = bits;
   1956 				while (tmpbits > 0) {
   1957 					g_pucInData[i] <<= 1;
   1958 					if (g_pucInData[i] == 0) {
   1959 						i--;
   1960 						g_pucInData[i] = 1;
   1961 					}
   1962 					tmpbits--;
   1963 				}
   1964 			}
   1965 		}
   1966 		break;
   1967 	case SHL:
   1968 		for (i = 0; i < size; i++) {
   1969 			if (g_pucInData[i] != 0) {
   1970 				tmpbits = bits;
   1971 				while (tmpbits > 0) {
   1972 					g_pucInData[i] >>= 1;
   1973 					if (g_pucInData[i] == 0) {
   1974 						i--;
   1975 						g_pucInData[i] = 8;
   1976 					}
   1977 					tmpbits--;
   1978 				}
   1979 			}
   1980 		}
   1981 		break;
   1982 	default:
   1983 		return VME_INVALID_FILE;
   1984 	}
   1985 
   1986 	return 0;
   1987 }
   1988 
   1989 /*
   1990  *
   1991  * ispVMComment
   1992  *
   1993  * Displays the SVF comments.
   1994  *
   1995  */
   1996 
   1997 void ispVMComment(unsigned short a_usCommentSize)
   1998 {
   1999 	char cCurByte = 0;
   2000 	for (; a_usCommentSize > 0; a_usCommentSize--) {
   2001 		/*
   2002 		*
   2003 		* Print character to the terminal.
   2004 		*
   2005 		**/
   2006 		cCurByte = GetByte();
   2007 		vme_out_char(cCurByte);
   2008 	}
   2009 	cCurByte = '\n';
   2010 	vme_out_char(cCurByte);
   2011 }
   2012 
   2013 /*
   2014  *
   2015  * ispVMHeader
   2016  *
   2017  * Iterate the length of the header and discard it.
   2018  *
   2019  */
   2020 
   2021 void ispVMHeader(unsigned short a_usHeaderSize)
   2022 {
   2023 	for (; a_usHeaderSize > 0; a_usHeaderSize--) {
   2024 		GetByte();
   2025 	}
   2026 }
   2027 
   2028 /*
   2029  *
   2030  * ispVMCalculateCRC32
   2031  *
   2032  * Calculate the 32-bit CRC.
   2033  *
   2034  */
   2035 
   2036 void ispVMCalculateCRC32(unsigned char a_ucData)
   2037 {
   2038 	/* 09/11/07 NN added local variables initialization */
   2039 	unsigned char ucIndex          = 0;
   2040 	unsigned char ucFlipData       = 0;
   2041 	unsigned short usCRCTableEntry = 0;
   2042 	unsigned int crc_table[16] = {
   2043 		0x0000, 0xCC01, 0xD801,
   2044 		0x1400, 0xF001, 0x3C00,
   2045 		0x2800, 0xE401, 0xA001,
   2046 		0x6C00, 0x7800, 0xB401,
   2047 		0x5000, 0x9C01, 0x8801,
   2048 		0x4400
   2049 	};
   2050 
   2051 	for (ucIndex = 0; ucIndex < 8; ucIndex++) {
   2052 		ucFlipData <<= 1;
   2053 		if (a_ucData & 0x01) {
   2054 			ucFlipData |= 0x01;
   2055 		}
   2056 		a_ucData >>= 1;
   2057 	}
   2058 
   2059 	/* 09/11/07 NN Type cast mismatch variables */
   2060 	usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]);
   2061 	g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF);
   2062 	g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^
   2063 			usCRCTableEntry ^ crc_table[ucFlipData & 0xF]);
   2064 	usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]);
   2065 	g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF);
   2066 	g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^
   2067 		usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]);
   2068 }
   2069 
   2070 /*
   2071  *
   2072  * ispVMLCOUNT
   2073  *
   2074  * Process the intelligent programming loops.
   2075  *
   2076  */
   2077 
   2078 signed char ispVMLCOUNT(unsigned short a_usCountSize)
   2079 {
   2080 	unsigned short usContinue	  = 1;
   2081 	unsigned short usIntelBufferIndex = 0;
   2082 	unsigned short usCountIndex       = 0;
   2083 	signed char cRetCode              = 0;
   2084 	signed char cRepeatHeap           = 0;
   2085 	signed char cOpcode               = 0;
   2086 	unsigned char ucState             = 0;
   2087 	unsigned short usDelay            = 0;
   2088 	unsigned short usToggle           = 0;
   2089 
   2090 	g_usIntelBufferSize = (unsigned short)ispVMDataSize();
   2091 
   2092 	/*
   2093 	 * Allocate memory for intel buffer.
   2094 	 *
   2095 	 */
   2096 
   2097 	ispVMMemManager(LHEAP, g_usIntelBufferSize);
   2098 
   2099 	/*
   2100 	 * Store the maximum size of the intelligent buffer.
   2101 	 * Used to convert VME to HEX.
   2102 	 */
   2103 
   2104 	if (g_usIntelBufferSize > g_usLCOUNTSize) {
   2105 		g_usLCOUNTSize = g_usIntelBufferSize;
   2106 	}
   2107 
   2108 	/*
   2109 	 * Copy intel data to the buffer.
   2110 	 */
   2111 
   2112 	for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize;
   2113 		usIntelBufferIndex++) {
   2114 		g_pucIntelBuffer[usIntelBufferIndex] = GetByte();
   2115 	}
   2116 
   2117 	/*
   2118 	 * Set the data type register to get data from the intelligent
   2119 	 * data buffer.
   2120 	 */
   2121 
   2122 	g_usDataType |= LHEAP_IN;
   2123 
   2124 	/*
   2125 	*
   2126 	* If the HEAP_IN flag is set, temporarily unset the flag so data will be
   2127 	* retrieved from the status buffer.
   2128 	*
   2129 	**/
   2130 
   2131 	if (g_usDataType & HEAP_IN) {
   2132 		g_usDataType &= ~HEAP_IN;
   2133 		cRepeatHeap = 1;
   2134 	}
   2135 
   2136 #ifdef DEBUG
   2137 	printf("LCOUNT %d;\n", a_usCountSize);
   2138 #endif /* DEBUG */
   2139 
   2140 	/*
   2141 	 * Iterate through the intelligent programming command.
   2142 	*/
   2143 
   2144 	for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) {
   2145 
   2146 		/*
   2147 		*
   2148 		* Initialize the intel data index to 0 before each iteration.
   2149 		*
   2150 		**/
   2151 
   2152 		g_usIntelDataIndex = 0;
   2153 		cOpcode            = 0;
   2154 		ucState            = 0;
   2155 		usDelay            = 0;
   2156 		usToggle           = 0;
   2157 		usContinue		   = 1;
   2158 
   2159 		/*
   2160 		*
   2161 		* Begin looping through all the VME opcodes.
   2162 		*
   2163 		*/
   2164 		/*
   2165 		* 4/1/09 Nguyen replaced the recursive function call codes on
   2166 		*        the ispVMLCOUNT function
   2167 		*
   2168 		*/
   2169 		while (usContinue) {
   2170 			cOpcode = GetByte();
   2171 			switch (cOpcode) {
   2172 			case HIR:
   2173 			case TIR:
   2174 			case HDR:
   2175 			case TDR:
   2176 				/*
   2177 				 * Set the header/trailer of the device in order
   2178 				 * to bypass successfully.
   2179 				 */
   2180 
   2181 				ispVMAmble(cOpcode);
   2182 			break;
   2183 			case STATE:
   2184 
   2185 				/*
   2186 				 * Step the JTAG state machine.
   2187 				 */
   2188 
   2189 				ucState = GetByte();
   2190 				/*
   2191 				 * Step the JTAG state machine to DRCAPTURE
   2192 				 * to support Looping.
   2193 				 */
   2194 
   2195 				if ((g_usDataType & LHEAP_IN) &&
   2196 					 (ucState == DRPAUSE) &&
   2197 					 (g_cCurrentJTAGState == ucState)) {
   2198 					ispVMStateMachine(DRCAPTURE);
   2199 				}
   2200 				ispVMStateMachine(ucState);
   2201 #ifdef DEBUG
   2202 				printf("LDELAY %s ", GetState(ucState));
   2203 #endif /* DEBUG */
   2204 				break;
   2205 			case SIR:
   2206 #ifdef DEBUG
   2207 				printf("SIR ");
   2208 #endif /* DEBUG */
   2209 				/*
   2210 				 * Shift in data into the device.
   2211 				 */
   2212 
   2213 				cRetCode = ispVMShift(cOpcode);
   2214 				break;
   2215 			case SDR:
   2216 
   2217 #ifdef DEBUG
   2218 				printf("LSDR ");
   2219 #endif /* DEBUG */
   2220 				/*
   2221 				 * Shift in data into the device.
   2222 				 */
   2223 
   2224 				cRetCode = ispVMShift(cOpcode);
   2225 				break;
   2226 			case WAIT:
   2227 
   2228 				/*
   2229 				*
   2230 				* Observe delay.
   2231 				*
   2232 				*/
   2233 
   2234 				usDelay = (unsigned short)ispVMDataSize();
   2235 				ispVMDelay(usDelay);
   2236 
   2237 #ifdef DEBUG
   2238 				if (usDelay & 0x8000) {
   2239 
   2240 					/*
   2241 					 * Since MSB is set, the delay time must
   2242 					 * be decoded to millisecond. The
   2243 					 * SVF2VME encodes the MSB to represent
   2244 					 * millisecond.
   2245 					 */
   2246 
   2247 					usDelay &= ~0x8000;
   2248 					printf("%.2E SEC;\n",
   2249 						(float) usDelay / 1000);
   2250 				} else {
   2251 					/*
   2252 					 * Since MSB is not set, the delay time
   2253 					 * is given as microseconds.
   2254 					 */
   2255 
   2256 					printf("%.2E SEC;\n",
   2257 						(float) usDelay / 1000000);
   2258 				}
   2259 #endif /* DEBUG */
   2260 				break;
   2261 			case TCK:
   2262 
   2263 				/*
   2264 				 * Issue clock toggles.
   2265 				 */
   2266 
   2267 				usToggle = (unsigned short)ispVMDataSize();
   2268 				ispVMClocks(usToggle);
   2269 
   2270 #ifdef DEBUG
   2271 				printf("RUNTEST %d TCK;\n", usToggle);
   2272 #endif /* DEBUG */
   2273 				break;
   2274 			case ENDLOOP:
   2275 
   2276 				/*
   2277 				 * Exit point from processing loops.
   2278 				 */
   2279 				usContinue = 0;
   2280 				break;
   2281 
   2282 			case COMMENT:
   2283 
   2284 				/*
   2285 				 * Display comment.
   2286 				 */
   2287 
   2288 				ispVMComment((unsigned short) ispVMDataSize());
   2289 				break;
   2290 			case ispEN:
   2291 				ucState = GetByte();
   2292 				if ((ucState == ON) || (ucState == 0x01))
   2293 					writePort(g_ucPinENABLE, 0x01);
   2294 				else
   2295 					writePort(g_ucPinENABLE, 0x00);
   2296 				ispVMDelay(1);
   2297 				break;
   2298 			case TRST:
   2299 				if (GetByte() == 0x01)
   2300 					writePort(g_ucPinTRST, 0x01);
   2301 				else
   2302 					writePort(g_ucPinTRST, 0x00);
   2303 				ispVMDelay(1);
   2304 				break;
   2305 			default:
   2306 
   2307 				/*
   2308 				 * Invalid opcode encountered.
   2309 				 */
   2310 
   2311 				debug("\nINVALID OPCODE: 0x%.2X\n", cOpcode);
   2312 
   2313 				return VME_INVALID_FILE;
   2314 			}
   2315 		}
   2316 		if (cRetCode >= 0) {
   2317 			/*
   2318 			 * Break if intelligent programming is successful.
   2319 			 */
   2320 
   2321 			break;
   2322 		}
   2323 
   2324 	}
   2325 	/*
   2326 	 * If HEAP_IN flag was temporarily disabled,
   2327 	 * re-enable it before exiting
   2328 	 */
   2329 
   2330 	if (cRepeatHeap) {
   2331 		g_usDataType |= HEAP_IN;
   2332 	}
   2333 
   2334 	/*
   2335 	 * Set the data type register to not get data from the
   2336 	 * intelligent data buffer.
   2337 	 */
   2338 
   2339 	g_usDataType &= ~LHEAP_IN;
   2340 	return cRetCode;
   2341 }
   2342 /*
   2343  *
   2344  * ispVMClocks
   2345  *
   2346  * Applies the specified number of pulses to TCK.
   2347  *
   2348  */
   2349 
   2350 void ispVMClocks(unsigned short Clocks)
   2351 {
   2352 	unsigned short iClockIndex = 0;
   2353 	for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) {
   2354 		sclock();
   2355 	}
   2356 }
   2357 
   2358 /*
   2359  *
   2360  * ispVMBypass
   2361  *
   2362  * This procedure takes care of the HIR, HDR, TIR, TDR for the
   2363  * purpose of putting the other devices into Bypass mode. The
   2364  * current state is checked to find out if it is at DRPAUSE or
   2365  * IRPAUSE. If it is at DRPAUSE, perform bypass register scan.
   2366  * If it is at IRPAUSE, scan into instruction registers the bypass
   2367  * instruction.
   2368  *
   2369  */
   2370 
   2371 void ispVMBypass(signed char ScanType, unsigned short Bits)
   2372 {
   2373 	/* 09/11/07 NN added local variables initialization */
   2374 	unsigned short iIndex       = 0;
   2375 	unsigned short iSourceIndex = 0;
   2376 	unsigned char cBitState     = 0;
   2377 	unsigned char cCurByte      = 0;
   2378 	unsigned char *pcSource    = NULL;
   2379 
   2380 	if (Bits <= 0) {
   2381 		return;
   2382 	}
   2383 
   2384 	switch (ScanType) {
   2385 	case HIR:
   2386 		pcSource = g_pucHIRData;
   2387 		break;
   2388 	case TIR:
   2389 		pcSource = g_pucTIRData;
   2390 		break;
   2391 	case HDR:
   2392 		pcSource = g_pucHDRData;
   2393 		break;
   2394 	case TDR:
   2395 		pcSource = g_pucTDRData;
   2396 		break;
   2397 	default:
   2398 		break;
   2399 	}
   2400 
   2401 	iSourceIndex = 0;
   2402 	cBitState = 0;
   2403 	for (iIndex = 0; iIndex < Bits - 1; iIndex++) {
   2404 		/* Scan instruction or bypass register */
   2405 		if (iIndex % 8 == 0) {
   2406 			cCurByte = pcSource[iSourceIndex++];
   2407 		}
   2408 		cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
   2409 			? 0x01 : 0x00);
   2410 		writePort(g_ucPinTDI, cBitState);
   2411 		sclock();
   2412 	}
   2413 
   2414 	if (iIndex % 8 == 0)  {
   2415 		cCurByte = pcSource[iSourceIndex++];
   2416 	}
   2417 
   2418 	cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
   2419 		? 0x01 : 0x00);
   2420 	writePort(g_ucPinTDI, cBitState);
   2421 }
   2422 
   2423 /*
   2424  *
   2425  * ispVMStateMachine
   2426  *
   2427  * This procedure steps all devices in the daisy chain from a given
   2428  * JTAG state to the next desirable state. If the next state is TLR,
   2429  * the JTAG state machine is brute forced into TLR by driving TMS
   2430  * high and pulse TCK 6 times.
   2431  *
   2432  */
   2433 
   2434 void ispVMStateMachine(signed char cNextJTAGState)
   2435 {
   2436 	/* 09/11/07 NN added local variables initialization */
   2437 	signed char cPathIndex  = 0;
   2438 	signed char cStateIndex = 0;
   2439 
   2440 	if ((g_cCurrentJTAGState == cNextJTAGState) &&
   2441 		(cNextJTAGState != RESET)) {
   2442 		return;
   2443 	}
   2444 
   2445 	for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) {
   2446 		if ((g_cCurrentJTAGState ==
   2447 			 g_JTAGTransistions[cStateIndex].CurState) &&
   2448 			(cNextJTAGState ==
   2449 				 g_JTAGTransistions[cStateIndex].NextState)) {
   2450 			break;
   2451 		}
   2452 	}
   2453 
   2454 	g_cCurrentJTAGState = cNextJTAGState;
   2455 	for (cPathIndex = 0;
   2456 		cPathIndex < g_JTAGTransistions[cStateIndex].Pulses;
   2457 		cPathIndex++) {
   2458 		if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex)
   2459 			& 0x80) {
   2460 			writePort(g_ucPinTMS, (unsigned char) 0x01);
   2461 		} else {
   2462 			writePort(g_ucPinTMS, (unsigned char) 0x00);
   2463 		}
   2464 		sclock();
   2465 	}
   2466 
   2467 	writePort(g_ucPinTDI, 0x00);
   2468 	writePort(g_ucPinTMS, 0x00);
   2469 }
   2470 
   2471 /*
   2472  *
   2473  * ispVMStart
   2474  *
   2475  * Enable the port to the device and set the state to RESET (TLR).
   2476  *
   2477  */
   2478 
   2479 void ispVMStart()
   2480 {
   2481 #ifdef DEBUG
   2482 	printf("// ISPVM EMBEDDED ADDED\n");
   2483 	printf("STATE RESET;\n");
   2484 #endif
   2485 	g_usFlowControl	= 0;
   2486 	g_usDataType = g_uiChecksumIndex = g_cCurrentJTAGState = 0;
   2487 	g_usHeadDR = g_usHeadIR = g_usTailDR = g_usTailIR = 0;
   2488 	g_usMaxSize = g_usShiftValue = g_usRepeatLoops = 0;
   2489 	g_usTDOSize =  g_usMASKSize = g_usTDISize = 0;
   2490 	g_usDMASKSize = g_usLCOUNTSize = g_usHDRSize = 0;
   2491 	g_usTDRSize = g_usHIRSize = g_usTIRSize =  g_usHeapSize	= 0;
   2492 	g_pLVDSList = NULL;
   2493 	g_usLVDSPairCount = 0;
   2494 	previous_size = 0;
   2495 
   2496 	ispVMStateMachine(RESET);    /*step devices to RESET state*/
   2497 }
   2498 
   2499 /*
   2500  *
   2501  * ispVMEnd
   2502  *
   2503  * Set the state of devices to RESET to enable the devices and disable
   2504  * the port.
   2505  *
   2506  */
   2507 
   2508 void ispVMEnd()
   2509 {
   2510 #ifdef DEBUG
   2511 	printf("// ISPVM EMBEDDED ADDED\n");
   2512 	printf("STATE RESET;\n");
   2513 	printf("RUNTEST 1.00E-001 SEC;\n");
   2514 #endif
   2515 
   2516 	ispVMStateMachine(RESET);   /*step devices to RESET state */
   2517 	ispVMDelay(1000);              /*wake up devices*/
   2518 }
   2519 
   2520 /*
   2521  *
   2522  * ispVMSend
   2523  *
   2524  * Send the TDI data stream to devices. The data stream can be
   2525  * instructions or data.
   2526  *
   2527  */
   2528 
   2529 signed char ispVMSend(unsigned short a_usiDataSize)
   2530 {
   2531 	/* 09/11/07 NN added local variables initialization */
   2532 	unsigned short iIndex       = 0;
   2533 	unsigned short iInDataIndex = 0;
   2534 	unsigned char cCurByte      = 0;
   2535 	unsigned char cBitState     = 0;
   2536 
   2537 	for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) {
   2538 		if (iIndex % 8 == 0) {
   2539 			cCurByte = g_pucInData[iInDataIndex++];
   2540 		}
   2541 		cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80)
   2542 			? 0x01 : 0x00);
   2543 		writePort(g_ucPinTDI, cBitState);
   2544 		sclock();
   2545 	}
   2546 
   2547 	if (iIndex % 8 == 0) {
   2548 		/* Take care of the last bit */
   2549 		cCurByte = g_pucInData[iInDataIndex];
   2550 	}
   2551 
   2552 	cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
   2553 		? 0x01 : 0x00);
   2554 
   2555 	writePort(g_ucPinTDI, cBitState);
   2556 	if (g_usFlowControl & CASCADE) {
   2557 		/*1/15/04 Clock in last bit for the first n-1 cascaded frames */
   2558 		sclock();
   2559 	}
   2560 
   2561 	return 0;
   2562 }
   2563 
   2564 /*
   2565  *
   2566  * ispVMRead
   2567  *
   2568  * Read the data stream from devices and verify.
   2569  *
   2570  */
   2571 
   2572 signed char ispVMRead(unsigned short a_usiDataSize)
   2573 {
   2574 	/* 09/11/07 NN added local variables initialization */
   2575 	unsigned short usDataSizeIndex    = 0;
   2576 	unsigned short usErrorCount       = 0;
   2577 	unsigned short usLastBitIndex     = 0;
   2578 	unsigned char cDataByte           = 0;
   2579 	unsigned char cMaskByte           = 0;
   2580 	unsigned char cInDataByte         = 0;
   2581 	unsigned char cCurBit             = 0;
   2582 	unsigned char cByteIndex          = 0;
   2583 	unsigned short usBufferIndex      = 0;
   2584 	unsigned char ucDisplayByte       = 0x00;
   2585 	unsigned char ucDisplayFlag       = 0x01;
   2586 	char StrChecksum[256]            = {0};
   2587 	unsigned char g_usCalculateChecksum = 0x00;
   2588 
   2589 	/* 09/11/07 NN Type cast mismatch variables */
   2590 	usLastBitIndex = (unsigned short)(a_usiDataSize - 1);
   2591 
   2592 #ifndef DEBUG
   2593 	/*
   2594 	 * If mask is not all zeros, then set the display flag to 0x00,
   2595 	 * otherwise it shall be set to 0x01 to indicate that data read
   2596 	 * from the device shall be displayed. If DEBUG is defined,
   2597 	 * always display data.
   2598 	 */
   2599 
   2600 	for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8;
   2601 		usDataSizeIndex++) {
   2602 		if (g_usDataType & MASK_DATA) {
   2603 			if (g_pucOutMaskData[usDataSizeIndex] != 0x00) {
   2604 				ucDisplayFlag = 0x00;
   2605 				break;
   2606 			}
   2607 		} else if (g_usDataType & CMASK_DATA) {
   2608 			g_usCalculateChecksum = 0x01;
   2609 			ucDisplayFlag = 0x00;
   2610 			break;
   2611 		} else {
   2612 			ucDisplayFlag = 0x00;
   2613 			break;
   2614 		}
   2615 	}
   2616 #endif /* DEBUG */
   2617 
   2618 	/*
   2619 	*
   2620 	* Begin shifting data in and out of the device.
   2621 	*
   2622 	**/
   2623 
   2624 	for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize;
   2625 		usDataSizeIndex++) {
   2626 		if (cByteIndex == 0) {
   2627 
   2628 			/*
   2629 			 * Grab byte from TDO buffer.
   2630 			 */
   2631 
   2632 			if (g_usDataType & TDO_DATA) {
   2633 				cDataByte = g_pucOutData[usBufferIndex];
   2634 			}
   2635 
   2636 			/*
   2637 			 * Grab byte from MASK buffer.
   2638 			 */
   2639 
   2640 			if (g_usDataType & MASK_DATA) {
   2641 				cMaskByte = g_pucOutMaskData[usBufferIndex];
   2642 			} else {
   2643 				cMaskByte = 0xFF;
   2644 			}
   2645 
   2646 			/*
   2647 			 * Grab byte from CMASK buffer.
   2648 			 */
   2649 
   2650 			if (g_usDataType & CMASK_DATA) {
   2651 				cMaskByte = 0x00;
   2652 				g_usCalculateChecksum = 0x01;
   2653 			}
   2654 
   2655 			/*
   2656 			 * Grab byte from TDI buffer.
   2657 			 */
   2658 
   2659 			if (g_usDataType & TDI_DATA) {
   2660 				cInDataByte = g_pucInData[usBufferIndex];
   2661 			}
   2662 
   2663 			usBufferIndex++;
   2664 		}
   2665 
   2666 		cCurBit = readPort();
   2667 
   2668 		if (ucDisplayFlag) {
   2669 			ucDisplayByte <<= 1;
   2670 			ucDisplayByte |= cCurBit;
   2671 		}
   2672 
   2673 		/*
   2674 		 * Check if data read from port matches with expected TDO.
   2675 		 */
   2676 
   2677 		if (g_usDataType & TDO_DATA) {
   2678 			/* 08/28/08 NN Added Calculate checksum support. */
   2679 			if (g_usCalculateChecksum) {
   2680 				if (cCurBit == 0x01)
   2681 					g_usChecksum +=
   2682 						(1 << (g_uiChecksumIndex % 8));
   2683 				g_uiChecksumIndex++;
   2684 			} else {
   2685 				if ((((cMaskByte << cByteIndex) & 0x80)
   2686 					? 0x01 : 0x00)) {
   2687 					if (cCurBit != (unsigned char)
   2688 					(((cDataByte << cByteIndex) & 0x80)
   2689 						? 0x01 : 0x00)) {
   2690 						usErrorCount++;
   2691 					}
   2692 				}
   2693 			}
   2694 		}
   2695 
   2696 		/*
   2697 		 * Write TDI data to the port.
   2698 		 */
   2699 
   2700 		writePort(g_ucPinTDI,
   2701 			(unsigned char)(((cInDataByte << cByteIndex) & 0x80)
   2702 				? 0x01 : 0x00));
   2703 
   2704 		if (usDataSizeIndex < usLastBitIndex) {
   2705 
   2706 			/*
   2707 			 * Clock data out from the data shift register.
   2708 			 */
   2709 
   2710 			sclock();
   2711 		} else if (g_usFlowControl & CASCADE) {
   2712 
   2713 			/*
   2714 			 * Clock in last bit for the first N - 1 cascaded frames
   2715 			 */
   2716 
   2717 			sclock();
   2718 		}
   2719 
   2720 		/*
   2721 		 * Increment the byte index. If it exceeds 7, then reset it back
   2722 		 * to zero.
   2723 		 */
   2724 
   2725 		cByteIndex++;
   2726 		if (cByteIndex >= 8) {
   2727 			if (ucDisplayFlag) {
   2728 
   2729 			/*
   2730 			 * Store displayed data in the TDO buffer. By reusing
   2731 			 * the TDO buffer to store displayed data, there is no
   2732 			 * need to allocate a buffer simply to hold display
   2733 			 * data. This will not cause any false verification
   2734 			 * errors because the true TDO byte has already
   2735 			 * been consumed.
   2736 			 */
   2737 
   2738 				g_pucOutData[usBufferIndex - 1] = ucDisplayByte;
   2739 				ucDisplayByte = 0;
   2740 			}
   2741 
   2742 			cByteIndex = 0;
   2743 		}
   2744 		/* 09/12/07 Nguyen changed to display the 1 bit expected data */
   2745 		else if (a_usiDataSize == 1) {
   2746 			if (ucDisplayFlag) {
   2747 
   2748 				/*
   2749 				 * Store displayed data in the TDO buffer.
   2750 				 * By reusing the TDO buffer to store displayed
   2751 				 * data, there is no need to allocate
   2752 				 * a buffer simply to hold display data. This
   2753 				 * will not cause any false verification errors
   2754 				 * because the true TDO byte has already
   2755 				 * been consumed.
   2756 				 */
   2757 
   2758 				/*
   2759 				 * Flip ucDisplayByte and store it in cDataByte.
   2760 				 */
   2761 				cDataByte = 0x00;
   2762 				for (usBufferIndex = 0; usBufferIndex < 8;
   2763 					usBufferIndex++) {
   2764 					cDataByte <<= 1;
   2765 					if (ucDisplayByte & 0x01) {
   2766 						cDataByte |= 0x01;
   2767 					}
   2768 					ucDisplayByte >>= 1;
   2769 				}
   2770 				g_pucOutData[0] = cDataByte;
   2771 				ucDisplayByte = 0;
   2772 			}
   2773 
   2774 			cByteIndex = 0;
   2775 		}
   2776 	}
   2777 
   2778 	if (ucDisplayFlag) {
   2779 
   2780 #ifdef DEBUG
   2781 		debug("RECEIVED TDO (");
   2782 #else
   2783 		vme_out_string("Display Data: 0x");
   2784 #endif /* DEBUG */
   2785 
   2786 		/* 09/11/07 NN Type cast mismatch variables */
   2787 		for (usDataSizeIndex = (unsigned short)
   2788 				((a_usiDataSize + 7) / 8);
   2789 			usDataSizeIndex > 0 ; usDataSizeIndex--) {
   2790 			cMaskByte = g_pucOutData[usDataSizeIndex - 1];
   2791 			cDataByte = 0x00;
   2792 
   2793 			/*
   2794 			 * Flip cMaskByte and store it in cDataByte.
   2795 			 */
   2796 
   2797 			for (usBufferIndex = 0; usBufferIndex < 8;
   2798 				usBufferIndex++) {
   2799 				cDataByte <<= 1;
   2800 				if (cMaskByte & 0x01) {
   2801 					cDataByte |= 0x01;
   2802 				}
   2803 				cMaskByte >>= 1;
   2804 			}
   2805 #ifdef DEBUG
   2806 			printf("%.2X", cDataByte);
   2807 			if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex)
   2808 				% 40 == 39) {
   2809 				printf("\n\t\t");
   2810 			}
   2811 #else
   2812 			vme_out_hex(cDataByte);
   2813 #endif /* DEBUG */
   2814 		}
   2815 
   2816 #ifdef DEBUG
   2817 		printf(")\n\n");
   2818 #else
   2819 		vme_out_string("\n\n");
   2820 #endif /* DEBUG */
   2821 		/* 09/02/08 Nguyen changed to display the data Checksum */
   2822 		if (g_usChecksum != 0) {
   2823 			g_usChecksum &= 0xFFFF;
   2824 			sprintf(StrChecksum, "Data Checksum: %.4lX\n\n",
   2825 				g_usChecksum);
   2826 			vme_out_string(StrChecksum);
   2827 			g_usChecksum = 0;
   2828 		}
   2829 	}
   2830 
   2831 	if (usErrorCount > 0) {
   2832 		if (g_usFlowControl & VERIFYUES) {
   2833 			vme_out_string(
   2834 				"USERCODE verification failed.   "
   2835 				"Continue programming......\n\n");
   2836 			g_usFlowControl &= ~(VERIFYUES);
   2837 			return 0;
   2838 		} else {
   2839 
   2840 #ifdef DEBUG
   2841 			printf("TOTAL ERRORS: %d\n", usErrorCount);
   2842 #endif /* DEBUG */
   2843 
   2844 			return VME_VERIFICATION_FAILURE;
   2845 		}
   2846 	} else {
   2847 		if (g_usFlowControl & VERIFYUES) {
   2848 			vme_out_string("USERCODE verification passed.    "
   2849 				"Programming aborted.\n\n");
   2850 			g_usFlowControl &= ~(VERIFYUES);
   2851 			return 1;
   2852 		} else {
   2853 			return 0;
   2854 		}
   2855 	}
   2856 }
   2857 
   2858 /*
   2859  *
   2860  * ispVMReadandSave
   2861  *
   2862  * Support dynamic I/O.
   2863  *
   2864  */
   2865 
   2866 signed char ispVMReadandSave(unsigned short int a_usiDataSize)
   2867 {
   2868 	/* 09/11/07 NN added local variables initialization */
   2869 	unsigned short int usDataSizeIndex = 0;
   2870 	unsigned short int usLastBitIndex  = 0;
   2871 	unsigned short int usBufferIndex   = 0;
   2872 	unsigned short int usOutBitIndex   = 0;
   2873 	unsigned short int usLVDSIndex     = 0;
   2874 	unsigned char cDataByte            = 0;
   2875 	unsigned char cDMASKByte           = 0;
   2876 	unsigned char cInDataByte          = 0;
   2877 	unsigned char cCurBit              = 0;
   2878 	unsigned char cByteIndex           = 0;
   2879 	signed char cLVDSByteIndex         = 0;
   2880 
   2881 	/* 09/11/07 NN Type cast mismatch variables */
   2882 	usLastBitIndex = (unsigned short) (a_usiDataSize - 1);
   2883 
   2884 	/*
   2885 	*
   2886 	* Iterate through the data bits.
   2887 	*
   2888 	*/
   2889 
   2890 	for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize;
   2891 		usDataSizeIndex++) {
   2892 		if (cByteIndex == 0) {
   2893 
   2894 			/*
   2895 			 * Grab byte from DMASK buffer.
   2896 			 */
   2897 
   2898 			if (g_usDataType & DMASK_DATA) {
   2899 				cDMASKByte = g_pucOutDMaskData[usBufferIndex];
   2900 			} else {
   2901 				cDMASKByte = 0x00;
   2902 			}
   2903 
   2904 			/*
   2905 			 * Grab byte from TDI buffer.
   2906 			 */
   2907 
   2908 			if (g_usDataType & TDI_DATA) {
   2909 				cInDataByte = g_pucInData[usBufferIndex];
   2910 			}
   2911 
   2912 			usBufferIndex++;
   2913 		}
   2914 
   2915 		cCurBit = readPort();
   2916 		cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80)
   2917 			? 0x01 : 0x00);
   2918 
   2919 		/*
   2920 		 * Initialize the byte to be zero.
   2921 		 */
   2922 
   2923 		if (usOutBitIndex % 8 == 0) {
   2924 			g_pucOutData[usOutBitIndex / 8] = 0x00;
   2925 		}
   2926 
   2927 		/*
   2928 		 * Use TDI, DMASK, and device TDO to create new TDI (actually
   2929 		 * stored in g_pucOutData).
   2930 		 */
   2931 
   2932 		if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) {
   2933 
   2934 			if (g_pLVDSList) {
   2935 				for (usLVDSIndex = 0;
   2936 					 usLVDSIndex < g_usLVDSPairCount;
   2937 					usLVDSIndex++) {
   2938 					if (g_pLVDSList[usLVDSIndex].
   2939 						usNegativeIndex ==
   2940 						usDataSizeIndex) {
   2941 						g_pLVDSList[usLVDSIndex].
   2942 							ucUpdate = 0x01;
   2943 						break;
   2944 					}
   2945 				}
   2946 			}
   2947 
   2948 			/*
   2949 			 * DMASK bit is 1, use TDI.
   2950 			 */
   2951 
   2952 			g_pucOutData[usOutBitIndex / 8] |= (unsigned char)
   2953 				(((cDataByte & 0x1) ? 0x01 : 0x00) <<
   2954 				(7 - usOutBitIndex % 8));
   2955 		} else {
   2956 
   2957 			/*
   2958 			 * DMASK bit is 0, use device TDO.
   2959 			 */
   2960 
   2961 			g_pucOutData[usOutBitIndex / 8] |= (unsigned char)
   2962 				(((cCurBit & 0x1) ? 0x01 : 0x00) <<
   2963 				(7 - usOutBitIndex % 8));
   2964 		}
   2965 
   2966 		/*
   2967 		 * Shift in TDI in order to get TDO out.
   2968 		 */
   2969 
   2970 		usOutBitIndex++;
   2971 		writePort(g_ucPinTDI, cDataByte);
   2972 		if (usDataSizeIndex < usLastBitIndex) {
   2973 			sclock();
   2974 		}
   2975 
   2976 		/*
   2977 		 * Increment the byte index. If it exceeds 7, then reset it back
   2978 		 * to zero.
   2979 		 */
   2980 
   2981 		cByteIndex++;
   2982 		if (cByteIndex >= 8) {
   2983 			cByteIndex = 0;
   2984 		}
   2985 	}
   2986 
   2987 	/*
   2988 	 * If g_pLVDSList exists and pairs need updating, then update
   2989 	 * the negative-pair to receive the flipped positive-pair value.
   2990 	 */
   2991 
   2992 	if (g_pLVDSList) {
   2993 		for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount;
   2994 			usLVDSIndex++) {
   2995 			if (g_pLVDSList[usLVDSIndex].ucUpdate) {
   2996 
   2997 				/*
   2998 				 * Read the positive value and flip it.
   2999 				 */
   3000 
   3001 				cDataByte = (unsigned char)
   3002 				 (((g_pucOutData[g_pLVDSList[usLVDSIndex].
   3003 					usPositiveIndex / 8]
   3004 					<< (g_pLVDSList[usLVDSIndex].
   3005 					usPositiveIndex % 8)) & 0x80) ?
   3006 					0x01 : 0x00);
   3007 				/* 09/11/07 NN Type cast mismatch variables */
   3008 				cDataByte = (unsigned char) (!cDataByte);
   3009 
   3010 				/*
   3011 				 * Get the byte that needs modification.
   3012 				 */
   3013 
   3014 				cInDataByte =
   3015 				g_pucOutData[g_pLVDSList[usLVDSIndex].
   3016 					usNegativeIndex / 8];
   3017 
   3018 				if (cDataByte) {
   3019 
   3020 					/*
   3021 					 * Copy over the current byte and
   3022 					 * set the negative bit to 1.
   3023 					 */
   3024 
   3025 					cDataByte = 0x00;
   3026 					for (cLVDSByteIndex = 7;
   3027 						cLVDSByteIndex >= 0;
   3028 						cLVDSByteIndex--) {
   3029 						cDataByte <<= 1;
   3030 						if (7 -
   3031 						(g_pLVDSList[usLVDSIndex].
   3032 							usNegativeIndex % 8) ==
   3033 							cLVDSByteIndex) {
   3034 
   3035 							/*
   3036 							 * Set negative bit to 1
   3037 							 */
   3038 
   3039 							cDataByte |= 0x01;
   3040 						} else if (cInDataByte & 0x80) {
   3041 							cDataByte |= 0x01;
   3042 						}
   3043 
   3044 						cInDataByte <<= 1;
   3045 					}
   3046 
   3047 					/*
   3048 					 * Store the modified byte.
   3049 					 */
   3050 
   3051 					g_pucOutData[g_pLVDSList[usLVDSIndex].
   3052 					usNegativeIndex / 8] = cDataByte;
   3053 				} else {
   3054 
   3055 					/*
   3056 					 * Copy over the current byte and set
   3057 					 * the negative bit to 0.
   3058 					 */
   3059 
   3060 					cDataByte = 0x00;
   3061 					for (cLVDSByteIndex = 7;
   3062 						cLVDSByteIndex >= 0;
   3063 						cLVDSByteIndex--) {
   3064 						cDataByte <<= 1;
   3065 						if (7 -
   3066 						(g_pLVDSList[usLVDSIndex].
   3067 						usNegativeIndex % 8) ==
   3068 						cLVDSByteIndex) {
   3069 
   3070 							/*
   3071 							 * Set negative bit to 0
   3072 							 */
   3073 
   3074 							cDataByte |= 0x00;
   3075 						} else if (cInDataByte & 0x80) {
   3076 							cDataByte |= 0x01;
   3077 						}
   3078 
   3079 						cInDataByte <<= 1;
   3080 					}
   3081 
   3082 					/*
   3083 					 * Store the modified byte.
   3084 					 */
   3085 
   3086 					g_pucOutData[g_pLVDSList[usLVDSIndex].
   3087 					usNegativeIndex / 8] = cDataByte;
   3088 				}
   3089 
   3090 				break;
   3091 			}
   3092 		}
   3093 	}
   3094 
   3095 	return 0;
   3096 }
   3097 
   3098 signed char ispVMProcessLVDS(unsigned short a_usLVDSCount)
   3099 {
   3100 	unsigned short usLVDSIndex = 0;
   3101 
   3102 	/*
   3103 	 * Allocate memory to hold LVDS pairs.
   3104 	 */
   3105 
   3106 	ispVMMemManager(LVDS, a_usLVDSCount);
   3107 	g_usLVDSPairCount = a_usLVDSCount;
   3108 
   3109 #ifdef DEBUG
   3110 	printf("LVDS %d (", a_usLVDSCount);
   3111 #endif /* DEBUG */
   3112 
   3113 	/*
   3114 	 * Iterate through each given LVDS pair.
   3115 	 */
   3116 
   3117 	for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) {
   3118 
   3119 		/*
   3120 		 * Assign the positive and negative indices of the LVDS pair.
   3121 		 */
   3122 
   3123 		/* 09/11/07 NN Type cast mismatch variables */
   3124 		g_pLVDSList[usLVDSIndex].usPositiveIndex =
   3125 			(unsigned short) ispVMDataSize();
   3126 		/* 09/11/07 NN Type cast mismatch variables */
   3127 		g_pLVDSList[usLVDSIndex].usNegativeIndex =
   3128 			(unsigned short)ispVMDataSize();
   3129 
   3130 #ifdef DEBUG
   3131 		if (usLVDSIndex < g_usLVDSPairCount - 1) {
   3132 			printf("%d:%d, ",
   3133 				g_pLVDSList[usLVDSIndex].usPositiveIndex,
   3134 				g_pLVDSList[usLVDSIndex].usNegativeIndex);
   3135 		} else {
   3136 			printf("%d:%d",
   3137 				g_pLVDSList[usLVDSIndex].usPositiveIndex,
   3138 				g_pLVDSList[usLVDSIndex].usNegativeIndex);
   3139 		}
   3140 #endif /* DEBUG */
   3141 
   3142 	}
   3143 
   3144 #ifdef DEBUG
   3145 	printf(");\n");
   3146 #endif /* DEBUG */
   3147 
   3148 	return 0;
   3149 }
   3150