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