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