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