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