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