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