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