Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
monpjc
Date:
Sat Jun 30 13:17:05 2012 +0000
Commit message:
removed returns for debug and corrected usages of fp in main()

Changed in this revision

lenval.c Show annotated file Show diff for this revision Revisions of this file
lenval.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
micro.c Show annotated file Show diff for this revision Revisions of this file
micro.h Show annotated file Show diff for this revision Revisions of this file
ports.c Show annotated file Show diff for this revision Revisions of this file
ports.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lenval.c	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,190 @@
+/*******************************************************/
+/* file: lenval.c                                      */
+/* abstract:  This file contains routines for using    */
+/*            the lenVal data structure.               */
+/*******************************************************/
+#include "lenval.h"
+#include "ports.h"
+
+/*****************************************************************************
+* Function:     value
+* Description:  Extract the long value from the lenval array.
+* Parameters:   plvValue    - ptr to lenval.
+* Returns:      long        - the extracted value.
+*****************************************************************************/
+long value( lenVal*     plvValue )
+{
+	long    lValue;         /* result to hold the accumulated result */
+	short   sIndex;
+
+    lValue  = 0;
+	for ( sIndex = 0; sIndex < plvValue->len ; ++sIndex )
+	{
+		lValue <<= 8;                       /* shift the accumulated result */
+		lValue |= plvValue->val[ sIndex];   /* get the last byte first */
+	}
+
+	return( lValue );
+}
+
+/*****************************************************************************
+* Function:     initLenVal
+* Description:  Initialize the lenval array with the given value.
+*               Assumes lValue is less than 256.
+* Parameters:   plv         - ptr to lenval.
+*               lValue      - the value to set.
+* Returns:      void.
+*****************************************************************************/
+void initLenVal( lenVal*    plv,
+                 long       lValue )
+{
+	plv->len    = 1;
+	plv->val[0] = (unsigned char)lValue;
+}
+
+/*****************************************************************************
+* Function:     EqualLenVal
+* Description:  Compare two lenval arrays with an optional mask.
+* Parameters:   plvTdoExpected  - ptr to lenval #1.
+*               plvTdoCaptured  - ptr to lenval #2.
+*               plvTdoMask      - optional ptr to mask (=0 if no mask).
+* Returns:      short   - 0 = mismatch; 1 = equal.
+*****************************************************************************/
+short EqualLenVal( lenVal*  plvTdoExpected,
+                   lenVal*  plvTdoCaptured,
+                   lenVal*  plvTdoMask )
+{
+    short           sEqual;
+	short           sIndex;
+    unsigned char   ucByteVal1;
+    unsigned char   ucByteVal2;
+    unsigned char   ucByteMask;
+
+    sEqual  = 1;
+    sIndex  = plvTdoExpected->len;
+
+    while ( sEqual && sIndex-- )
+    {
+        ucByteVal1  = plvTdoExpected->val[ sIndex ];
+        ucByteVal2  = plvTdoCaptured->val[ sIndex ];
+        if ( plvTdoMask )
+        {
+            ucByteMask  = plvTdoMask->val[ sIndex ];
+            ucByteVal1  &= ucByteMask;
+            ucByteVal2  &= ucByteMask;
+        }
+        if ( ucByteVal1 != ucByteVal2 )
+        {
+            sEqual  = 0;
+        }
+    }
+
+	return( sEqual );
+}
+
+
+/*****************************************************************************
+* Function:     RetBit
+* Description:  return the (byte, bit) of lv (reading from left to right).
+* Parameters:   plv     - ptr to lenval.
+*               iByte   - the byte to get the bit from.
+*               iBit    - the bit number (0=msb)
+* Returns:      short   - the bit value.
+*****************************************************************************/
+short RetBit( lenVal*   plv,
+              int       iByte,
+              int       iBit )
+{
+    /* assert( ( iByte >= 0 ) && ( iByte < plv->len ) ); */
+    /* assert( ( iBit >= 0 ) && ( iBit < 8 ) ); */
+    return( (short)( ( plv->val[ iByte ] >> ( 7 - iBit ) ) & 0x1 ) );
+}
+
+/*****************************************************************************
+* Function:     SetBit
+* Description:  set the (byte, bit) of lv equal to val
+* Example:      SetBit("00000000",byte, 1) equals "01000000".
+* Parameters:   plv     - ptr to lenval.
+*               iByte   - the byte to get the bit from.
+*               iBit    - the bit number (0=msb).
+*               sVal    - the bit value to set.
+* Returns:      void.
+*****************************************************************************/
+void SetBit( lenVal*    plv,
+             int        iByte,
+             int        iBit,
+             short      sVal )
+{
+    unsigned char   ucByteVal;
+    unsigned char   ucBitMask;
+
+    ucBitMask   = (unsigned char)(1 << ( 7 - iBit ));
+    ucByteVal   = (unsigned char)(plv->val[ iByte ] & (~ucBitMask));
+
+    if ( sVal )
+    {
+        ucByteVal   |= ucBitMask;
+    }
+    plv->val[ iByte ]   = ucByteVal;
+}
+
+/*****************************************************************************
+* Function:     AddVal
+* Description:  add val1 to val2 and store in resVal;
+*               assumes val1 and val2  are of equal length.
+* Parameters:   plvResVal   - ptr to result.
+*               plvVal1     - ptr of addendum.
+*               plvVal2     - ptr of addendum.
+* Returns:      void.
+*****************************************************************************/
+void addVal( lenVal*    plvResVal,
+             lenVal*    plvVal1,
+             lenVal*    plvVal2 )
+{
+	unsigned char   ucCarry;
+    unsigned short  usSum;
+    unsigned short  usVal1;
+    unsigned short  usVal2;
+	short           sIndex;
+	
+	plvResVal->len  = plvVal1->len;         /* set up length of result */
+	
+	/* start at least significant bit and add bytes    */
+    ucCarry = 0;
+    sIndex  = plvVal1->len;
+    while ( sIndex-- )
+    {
+		usVal1  = plvVal1->val[ sIndex ];   /* i'th byte of val1 */
+		usVal2  = plvVal2->val[ sIndex ];   /* i'th byte of val2 */
+		
+		/* add the two bytes plus carry from previous addition */
+		usSum   = (unsigned short)( usVal1 + usVal2 + ucCarry );
+		
+		/* set up carry for next byte */
+		ucCarry = (unsigned char)( ( usSum > 255 ) ? 1 : 0 );
+		
+        /* set the i'th byte of the result */
+		plvResVal->val[ sIndex ]    = (unsigned char)usSum;
+    }
+}
+
+/*****************************************************************************
+* Function:     readVal
+* Description:  read from XSVF numBytes bytes of data into x.
+* Parameters:   plv         - ptr to lenval in which to put the bytes read.
+*               sNumBytes   - the number of bytes to read.
+* Returns:      void.
+*****************************************************************************/
+void readVal( lenVal*   plv,
+              short     sNumBytes )
+{
+    unsigned char*  pucVal;
+	
+    plv->len    = sNumBytes;        /* set the length of the lenVal        */
+    for ( pucVal = plv->val; sNumBytes; --sNumBytes, ++pucVal )
+    {
+        /* read a byte of data into the lenVal */
+		readByte( pucVal );
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lenval.h	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,93 @@
+/*******************************************************/
+/* file: lenval.h                                      */
+/* abstract:  This file contains a description of the  */
+/*            data structure "lenval".                 */
+/*******************************************************/
+
+#ifndef lenval_dot_h
+#define lenval_dot_h
+
+/* the lenVal structure is a byte oriented type used to store an */
+/* arbitrary length binary value. As an example, the hex value   */
+/* 0x0e3d is represented as a lenVal with len=2 (since 2 bytes   */
+/* and val[0]=0e and val[1]=3d.  val[2-MAX_LEN] are undefined    */
+
+/* maximum length (in bytes) of value to read in        */
+/* this needs to be at least 4, and longer than the     */
+/* length of the longest SDR instruction.  If there is, */
+/* only 1 device in the chain, MAX_LEN must be at least */
+/* ceil(27/8) == 4.  For 6 devices in a chain, MAX_LEN  */
+/* must be 5, for 14 devices MAX_LEN must be 6, for 20  */
+/* devices MAX_LEN must be 7, etc..                     */
+/* You can safely set MAX_LEN to a smaller number if you*/
+/* know how many devices will be in your chain.         */
+/*  #define MAX_LEN (Actual #define is below this comment block)
+      This #define defines the maximum length (in bytes) of predefined
+      buffers in which the XSVF player stores the current shift data.
+      This length must be greater than the longest shift length (in bytes)
+      in the XSVF files that will be processed.  7000 is a very conservative
+      number.  The buffers are stored on the stack and if you have limited
+      stack space, you may decrease the MAX_LEN value.
+
+      How to find the "shift length" in bits?
+      Look at the ASCII version of the XSVF (generated with the -a option
+      for the SVF2XSVF translator) and search for the XSDRSIZE command
+      with the biggest parameter.  XSDRSIZE is equivalent to the SVF's
+      SDR length plus the lengths of applicable HDR and TDR commands.
+      Remember that the MAX_LEN is defined in bytes.  Therefore, the
+      minimum MAX_LEN = ceil( max( XSDRSIZE ) / 8 );
+
+      The following MAX_LEN values have been tested and provide relatively
+      good margin for the corresponding devices:
+
+        DEVICE       MAX_LEN   Resulting Shift Length Max (in bits)
+        ---------    -------   ----------------------------------------------
+        XC9500/XL/XV 32        256
+
+        CoolRunner/II 256      2048   - actual max 1 device = 1035 bits
+
+        FPGA         128       1024    - svf2xsvf -rlen 1024
+
+        XC18V00/XCF00
+                     1100      8800   - no blank check performed (default)
+                                      - actual max 1 device = 8192 bits verify
+                                      - max 1 device = 4096 bits program-only
+
+        XC18V00/XCF00 when using the optional Blank Check operation
+                     2500      20000  - required for blank check
+                                      - blank check max 1 device = 16384 bits
+*/
+#define MAX_LEN 7000
+
+
+typedef struct var_len_byte
+{
+    short len;   /* number of chars in this value */
+    unsigned char val[MAX_LEN+1];  /* bytes of data */
+} lenVal;
+
+
+/* return the long representation of a lenVal */
+extern long value(lenVal *x);
+
+/* set lenVal equal to value */
+extern void initLenVal(lenVal *x, long value);
+
+/* check if expected equals actual (taking the mask into account) */
+extern short EqualLenVal(lenVal *expected, lenVal *actual, lenVal *mask);
+
+/* add val1+val2 and put the result in resVal */
+extern void addVal(lenVal *resVal, lenVal *val1, lenVal *val2);
+
+/* return the (byte, bit) of lv (reading from left to right) */
+extern short RetBit(lenVal *lv, int byte, int bit);
+
+/* set the (byte, bit) of lv equal to val (e.g. SetBit("00000000",byte, 1)
+   equals "01000000" */
+extern void SetBit(lenVal *lv, int byte, int bit, short val);
+
+/* read from XSVF numBytes bytes of data into x */
+extern void  readVal(lenVal *x, short numBytes);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,54 @@
+#include "mbed.h"
+#include "micro.h"
+
+DigitalOut led_1(LED1);
+DigitalOut led_2(LED2);
+DigitalOut led_3(LED3);
+DigitalOut led_4(LED4);
+
+LocalFileSystem local("local");
+Serial pc(USBTX, USBRX);
+
+FILE *fp;
+
+int main() {
+    led_1 = 1;
+    led_2 = 1;
+    led_3 = 1;
+    led_4 = 1;
+    wait(1);
+    pc.printf("\nJTAG Programmer\nLooking for /local/XSVF.bit\n");
+    led_1 = 0;
+    led_2 = 0;
+    led_3 = 0;
+    led_4 = 0;
+    wait(1);
+    led_1 = 1; //Program Started
+
+    fp = fopen("/local/XSVF.bit", "rb");
+
+    if (fp == NULL) {
+        pc.printf("Failed to open file\n");
+        while(1) //blink LED2 as a error
+        {
+            led_2 = 1;
+            wait(1);
+            led_2 = 0;
+            wait(0.2);
+        }
+    } else {
+        pc.printf("Binary file opened successfully\n");
+        led_2 = 1; // file open, starting programming progress
+        xsvfExecute();
+        fclose(fp);
+    }
+
+    pc.printf("Programming complted\n");
+    while(1)
+    {
+        led_4 = 1;
+        wait(1);
+        led_4 = 0;
+        wait(0.2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/micro.c	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,1741 @@
+/*****************************************************************************
+* file:         micro.c
+* abstract:     This file contains the function, xsvfExecute(),
+*               call for interpreting the XSVF commands.
+* Usage:        Call xsvfExecute() to process XSVF data.
+*               The XSVF data is retrieved by readByte() in ports.c
+*               Remove the main function if you already have one.
+* Options:      XSVF_SUPPORT_COMPRESSION
+*                   This define supports the XC9500/XL compression scheme.
+*                   This define adds support for XSDRINC and XSETSDRMASKS.
+*               XSVF_SUPPORT_ERRORCODES
+*                   This define causes the xsvfExecute function to return
+*                   an error code for specific errors.  See error codes below.
+*                   If this is not defined, the return value defaults to the
+*                   legacy values for backward compatibility:
+*                   1 = success;  0 = failure.
+* Debugging:    DEBUG_MODE (Legacy name)
+*               Define DEBUG_MODE to compile with debugging features.
+*               Both micro.c and ports.c must be compiled with the DEBUG_MODE
+*               defined to enable the standalone main implementation in
+*               micro.c that reads XSVF from a file.
+* History:      v2.00   - Original XSVF implementation.
+*               v4.04   - Added delay at end of XSIR for XC18v00 support.
+*                         Added new commands for CoolRunner support:
+*                         XSTATE, XENDIR, XENDDR
+*               v4.05   - Cleanup micro.c but leave ports.c intact.
+*               v4.06   - Fix xsvfGotoTapState for retry transition.
+*               v4.07   - Update example waitTime implementations for
+*                         compatibility with Virtex-II.
+*               v4.10   - Add new XSIR2 command that supports a 2-byte
+*                         IR-length parameter for IR shifts > 255 bits.
+*               v4.11   - No change.  Update version to match SVF2XSVF xlator.
+*               v4.14   - Added XCOMMENT.
+*               v5.00   - Improve XSTATE support.
+*                         Added XWAIT.
+*               v5.01   - make sure that TCK is low during RUNTEST wait for
+*                         XC18V00/XCF00 support.  Only change is in PORTS.C
+*                         waitTime() function for implementations that do NOT
+*                         pulse TCK during the waitTime.
+*****************************************************************************/
+
+/*============================================================================
+* #pragmas
+============================================================================*/
+#ifdef  _MSC_VER
+    #pragma warning( disable : 4100 )
+#endif  /* _MSC_VER */
+
+/*============================================================================
+* #include files
+============================================================================*/
+#define DEBUG_MODE
+//#define DEBUG_MODE
+/*#ifdef  DEBUG_MODE
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <string.h>
+    #include <time.h>
+#endif*/  /* DEBUG_MODE */
+
+#include "micro.h"
+#include "lenval.h"
+#include "ports.h"
+#include "mbed.h"
+extern Serial pc;
+
+/*============================================================================
+* XSVF #define
+============================================================================*/
+
+#define XSVF_VERSION    "5.01"
+
+/*****************************************************************************
+* Define:       XSVF_SUPPORT_COMPRESSION
+* Description:  Define this to support the XC9500/XL XSVF data compression
+*               scheme.
+*               Code size can be reduced by NOT supporting this feature.
+*               However, you must use the -nc (no compress) option when
+*               translating SVF to XSVF using the SVF2XSVF translator.
+*               Corresponding, uncompressed XSVF may be larger.
+*****************************************************************************/
+#ifndef XSVF_SUPPORT_COMPRESSION
+    #define XSVF_SUPPORT_COMPRESSION    1
+#endif
+
+/*****************************************************************************
+* Define:       XSVF_SUPPORT_ERRORCODES
+* Description:  Define this to support the new XSVF error codes.
+*               (The original XSVF player just returned 1 for success and
+*               0 for an unspecified failure.)
+*****************************************************************************/
+#ifndef XSVF_SUPPORT_ERRORCODES
+    #define XSVF_SUPPORT_ERRORCODES     1
+#endif
+
+#ifdef  XSVF_SUPPORT_ERRORCODES
+    #define XSVF_ERRORCODE(errorCode)   errorCode
+#else   /* Use legacy error code */
+    #define XSVF_ERRORCODE(errorCode)   ((errorCode==XSVF_ERROR_NONE)?1:0)
+#endif  /* XSVF_SUPPORT_ERRORCODES */
+
+
+/*****************************************************************************
+* Define:       XSVF_MAIN
+* Description:  Define this to compile with a main function for standalone
+*               debugging.
+*****************************************************************************/
+#ifndef XSVF_MAIN
+    #ifdef DEBUG_MODE
+//        #define XSVF_MAIN   1
+    #endif  /* DEBUG_MODE */
+#endif  /* XSVF_MAIN */
+
+
+/*============================================================================
+* DEBUG_MODE #define
+============================================================================*/
+
+#ifdef  DEBUG_MODE
+    #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) pc.printf( pzFormat )
+    #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) pc.printf( pzFormat, arg1 )
+    #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) pc.printf( pzFormat, arg1, arg2 )
+    #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) pc.printf( pzFormat, arg1, arg2, arg3 )
+    #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal)
+#else   /* !DEBUG_MODE */
+    #define XSVFDBG_PRINTF(iDebugLevel,pzFormat)
+    #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1)
+    #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2)
+    #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3)
+    #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal)
+#endif  /* DEBUG_MODE */
+
+
+/*============================================================================
+* XSVF Type Declarations
+============================================================================*/
+
+/*****************************************************************************
+* Struct:       SXsvfInfo
+* Description:  This structure contains all of the data used during the
+*               execution of the XSVF.  Some data is persistent, predefined
+*               information (e.g. lRunTestTime).  The bulk of this struct's
+*               size is due to the lenVal structs (defined in lenval.h)
+*               which contain buffers for the active shift data.  The MAX_LEN
+*               #define in lenval.h defines the size of these buffers.
+*               These buffers must be large enough to store the longest
+*               shift data in your XSVF file.  For example:
+*                   MAX_LEN >= ( longest_shift_data_in_bits / 8 )
+*               Because the lenVal struct dominates the space usage of this
+*               struct, the rough size of this struct is:
+*                   sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals)
+*               xsvfInitialize() contains initialization code for the data
+*               in this struct.
+*               xsvfCleanup() contains cleanup code for the data in this
+*               struct.
+*****************************************************************************/
+typedef struct tagSXsvfInfo
+{
+    /* XSVF status information */
+    unsigned char   ucComplete;         /* 0 = running; 1 = complete */
+    unsigned char   ucCommand;          /* Current XSVF command byte */
+    long            lCommandCount;      /* Number of commands processed */
+    int             iErrorCode;         /* An error code. 0 = no error. */
+
+    /* TAP state/sequencing information */
+    unsigned char   ucTapState;         /* Current TAP state */
+    unsigned char   ucEndIR;            /* ENDIR TAP state (See SVF) */
+    unsigned char   ucEndDR;            /* ENDDR TAP state (See SVF) */
+
+    /* RUNTEST information */
+    unsigned char   ucMaxRepeat;        /* Max repeat loops (for xc9500/xl) */
+    long            lRunTestTime;       /* Pre-specified RUNTEST time (usec) */
+
+    /* Shift Data Info and Buffers */
+    long            lShiftLengthBits;   /* Len. current shift data in bits */
+    short           sShiftLengthBytes;  /* Len. current shift data in bytes */
+
+    lenVal          lvTdi;              /* Current TDI shift data */
+    lenVal          lvTdoExpected;      /* Expected TDO shift data */
+    lenVal          lvTdoCaptured;      /* Captured TDO shift data */
+    lenVal          lvTdoMask;          /* TDO mask: 0=dontcare; 1=compare */
+
+#ifdef  XSVF_SUPPORT_COMPRESSION
+    /* XSDRINC Data Buffers */
+    lenVal          lvAddressMask;      /* Address mask for XSDRINC */
+    lenVal          lvDataMask;         /* Data mask for XSDRINC */
+    lenVal          lvNextData;         /* Next data for XSDRINC */
+#endif  /* XSVF_SUPPORT_COMPRESSION */
+} SXsvfInfo;
+
+/* Declare pointer to functions that perform XSVF commands */
+typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
+
+
+/*============================================================================
+* XSVF Command Bytes
+============================================================================*/
+
+/* encodings of xsvf instructions */
+#define XCOMPLETE        0
+#define XTDOMASK         1
+#define XSIR             2
+#define XSDR             3
+#define XRUNTEST         4
+/* Reserved              5 */
+/* Reserved              6 */
+#define XREPEAT          7
+#define XSDRSIZE         8
+#define XSDRTDO          9
+#define XSETSDRMASKS     10
+#define XSDRINC          11
+#define XSDRB            12
+#define XSDRC            13
+#define XSDRE            14
+#define XSDRTDOB         15
+#define XSDRTDOC         16
+#define XSDRTDOE         17
+#define XSTATE           18         /* 4.00 */
+#define XENDIR           19         /* 4.04 */
+#define XENDDR           20         /* 4.04 */
+#define XSIR2            21         /* 4.10 */
+#define XCOMMENT         22         /* 4.14 */
+#define XWAIT            23         /* 5.00 */
+/* Insert new commands here */
+/* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */
+#define XLASTCMD         24         /* Last command marker */
+
+
+/*============================================================================
+* XSVF Command Parameter Values
+============================================================================*/
+
+#define XSTATE_RESET     0          /* 4.00 parameter for XSTATE */
+#define XSTATE_RUNTEST   1          /* 4.00 parameter for XSTATE */
+
+#define XENDXR_RUNTEST   0          /* 4.04 parameter for XENDIR/DR */
+#define XENDXR_PAUSE     1          /* 4.04 parameter for XENDIR/DR */
+
+/* TAP states */
+#define XTAPSTATE_RESET     0x00
+#define XTAPSTATE_RUNTEST   0x01    /* a.k.a. IDLE */
+#define XTAPSTATE_SELECTDR  0x02
+#define XTAPSTATE_CAPTUREDR 0x03
+#define XTAPSTATE_SHIFTDR   0x04
+#define XTAPSTATE_EXIT1DR   0x05
+#define XTAPSTATE_PAUSEDR   0x06
+#define XTAPSTATE_EXIT2DR   0x07
+#define XTAPSTATE_UPDATEDR  0x08
+#define XTAPSTATE_IRSTATES  0x09    /* All IR states begin here */
+#define XTAPSTATE_SELECTIR  0x09
+#define XTAPSTATE_CAPTUREIR 0x0A
+#define XTAPSTATE_SHIFTIR   0x0B
+#define XTAPSTATE_EXIT1IR   0x0C
+#define XTAPSTATE_PAUSEIR   0x0D
+#define XTAPSTATE_EXIT2IR   0x0E
+#define XTAPSTATE_UPDATEIR  0x0F
+
+/*============================================================================
+* XSVF Function Prototypes
+============================================================================*/
+
+int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo );   /* Illegal command function */
+int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo );
+int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSIR( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDR( SXsvfInfo* pXsvfInfo );
+int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo );
+int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo );
+int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo );
+int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo );
+int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo );
+int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo );
+/* Insert new command functions here */
+
+/*============================================================================
+* XSVF Global Variables
+============================================================================*/
+
+/* Array of XSVF command functions.  Must follow command byte value order! */
+/* If your compiler cannot take this form, then convert to a switch statement*/
+TXsvfDoCmdFuncPtr   xsvf_pfDoCmd[]  =
+{
+    xsvfDoXCOMPLETE,        /*  0 */
+    xsvfDoXTDOMASK,         /*  1 */
+    xsvfDoXSIR,             /*  2 */
+    xsvfDoXSDR,             /*  3 */
+    xsvfDoXRUNTEST,         /*  4 */
+    xsvfDoIllegalCmd,       /*  5 */
+    xsvfDoIllegalCmd,       /*  6 */
+    xsvfDoXREPEAT,          /*  7 */
+    xsvfDoXSDRSIZE,         /*  8 */
+    xsvfDoXSDRTDO,          /*  9 */
+#ifdef  XSVF_SUPPORT_COMPRESSION
+    xsvfDoXSETSDRMASKS,     /* 10 */
+    xsvfDoXSDRINC,          /* 11 */
+#else
+    xsvfDoIllegalCmd,       /* 10 */
+    xsvfDoIllegalCmd,       /* 11 */
+#endif  /* XSVF_SUPPORT_COMPRESSION */
+    xsvfDoXSDRBCE,          /* 12 */
+    xsvfDoXSDRBCE,          /* 13 */
+    xsvfDoXSDRBCE,          /* 14 */
+    xsvfDoXSDRTDOBCE,       /* 15 */
+    xsvfDoXSDRTDOBCE,       /* 16 */
+    xsvfDoXSDRTDOBCE,       /* 17 */
+    xsvfDoXSTATE,           /* 18 */
+    xsvfDoXENDXR,           /* 19 */
+    xsvfDoXENDXR,           /* 20 */
+    xsvfDoXSIR2,            /* 21 */
+    xsvfDoXCOMMENT,         /* 22 */
+    xsvfDoXWAIT             /* 23 */
+/* Insert new command functions here */
+};
+
+#ifdef  DEBUG_MODE
+    char* xsvf_pzCommandName[]  =
+    {
+        "XCOMPLETE",
+        "XTDOMASK",
+        "XSIR",
+        "XSDR",
+        "XRUNTEST",
+        "Reserved5",
+        "Reserved6",
+        "XREPEAT",
+        "XSDRSIZE",
+        "XSDRTDO",
+        "XSETSDRMASKS",
+        "XSDRINC",
+        "XSDRB",
+        "XSDRC",
+        "XSDRE",
+        "XSDRTDOB",
+        "XSDRTDOC",
+        "XSDRTDOE",
+        "XSTATE",
+        "XENDIR",
+        "XENDDR",
+        "XSIR2",
+        "XCOMMENT",
+        "XWAIT"
+    };
+
+    char*   xsvf_pzErrorName[]  =
+    {
+        "No error",
+        "ERROR:  Unknown",
+        "ERROR:  TDO mismatch",
+        "ERROR:  TDO mismatch and exceeded max retries",
+        "ERROR:  Unsupported XSVF command",
+        "ERROR:  Illegal state specification",
+        "ERROR:  Data overflows allocated MAX_LEN buffer size"
+    };
+
+    char*   xsvf_pzTapState[] =
+    {
+        "RESET",        /* 0x00 */
+        "RUNTEST/IDLE", /* 0x01 */
+        "DRSELECT",     /* 0x02 */
+        "DRCAPTURE",    /* 0x03 */
+        "DRSHIFT",      /* 0x04 */
+        "DREXIT1",      /* 0x05 */
+        "DRPAUSE",      /* 0x06 */
+        "DREXIT2",      /* 0x07 */
+        "DRUPDATE",     /* 0x08 */
+        "IRSELECT",     /* 0x09 */
+        "IRCAPTURE",    /* 0x0A */
+        "IRSHIFT",      /* 0x0B */
+        "IREXIT1",      /* 0x0C */
+        "IRPAUSE",      /* 0x0D */
+        "IREXIT2",      /* 0x0E */
+        "IRUPDATE"      /* 0x0F */
+    };
+#endif  /* DEBUG_MODE */
+
+#ifdef DEBUG_MODE
+    //FILE* in;   /* Legacy DEBUG_MODE file pointer */
+    int xsvf_iDebugLevel;
+#endif /* DEBUG_MODE */
+
+/*============================================================================
+* Utility Functions
+============================================================================*/
+
+/*****************************************************************************
+* Function:     xsvfPrintLenVal
+* Description:  Print the lenval value in hex.
+* Parameters:   plv     - ptr to lenval.
+* Returns:      void.
+*****************************************************************************/
+#ifdef  DEBUG_MODE
+void xsvfPrintLenVal( lenVal *plv )
+{
+    int i;
+
+    if ( plv )
+    {
+        printf( "0x" );
+        for ( i = 0; i < plv->len; ++i )
+        {
+            printf( "%02x", ((unsigned int)(plv->val[ i ])) );
+        }
+    }
+}
+#endif  /* DEBUG_MODE */
+
+
+/*****************************************************************************
+* Function:     xsvfInfoInit
+* Description:  Initialize the xsvfInfo data.
+* Parameters:   pXsvfInfo   - ptr to the XSVF info structure.
+* Returns:      int         - 0 = success; otherwise error.
+*****************************************************************************/
+int xsvfInfoInit( SXsvfInfo* pXsvfInfo )
+{
+    //XSVFDBG_PRINTF1( 4, "    sizeof( SXsvfInfo ) = %d bytes\n",
+    //                 sizeof( SXsvfInfo ) );
+
+    pXsvfInfo->ucComplete       = 0;
+    pXsvfInfo->ucCommand        = XCOMPLETE;
+    pXsvfInfo->lCommandCount    = 0;
+    pXsvfInfo->iErrorCode       = XSVF_ERROR_NONE;
+    pXsvfInfo->ucMaxRepeat      = 0;
+    pXsvfInfo->ucTapState       = XTAPSTATE_RESET;
+    pXsvfInfo->ucEndIR          = XTAPSTATE_RUNTEST;
+    pXsvfInfo->ucEndDR          = XTAPSTATE_RUNTEST;
+    pXsvfInfo->lShiftLengthBits = 0L;
+    pXsvfInfo->sShiftLengthBytes= 0;
+    pXsvfInfo->lRunTestTime     = 0L;
+
+    return( 0 );
+}
+
+/*****************************************************************************
+* Function:     xsvfInfoCleanup
+* Description:  Cleanup the xsvfInfo data.
+* Parameters:   pXsvfInfo   - ptr to the XSVF info structure.
+* Returns:      void.
+*****************************************************************************/
+void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo )
+{
+}
+
+/*****************************************************************************
+* Function:     xsvfGetAsNumBytes
+* Description:  Calculate the number of bytes the given number of bits
+*               consumes.
+* Parameters:   lNumBits    - the number of bits.
+* Returns:      short       - the number of bytes to store the number of bits.
+*****************************************************************************/
+short xsvfGetAsNumBytes( long lNumBits )
+{
+    return( (short)( ( lNumBits + 7L ) / 8L ) );
+}
+
+/*****************************************************************************
+* Function:     xsvfTmsTransition
+* Description:  Apply TMS and transition TAP controller by applying one TCK
+*               cycle.
+* Parameters:   sTms    - new TMS value.
+* Returns:      void.
+*****************************************************************************/
+void xsvfTmsTransition( short sTms )
+{
+    setPort( TMS, sTms );
+    setPort( TCK, 0 );
+    setPort( TCK, 1 );
+}
+
+/*****************************************************************************
+* Function:     xsvfGotoTapState
+* Description:  From the current TAP state, go to the named TAP state.
+*               A target state of RESET ALWAYS causes TMS reset sequence.
+*               All SVF standard stable state paths are supported.
+*               All state transitions are supported except for the following
+*               which cause an XSVF_ERROR_ILLEGALSTATE:
+*                   - Target==DREXIT2;  Start!=DRPAUSE
+*                   - Target==IREXIT2;  Start!=IRPAUSE
+* Parameters:   pucTapState     - Current TAP state; returns final TAP state.
+*               ucTargetState   - New target TAP state.
+* Returns:      int             - 0 = success; otherwise error.
+*****************************************************************************/
+int xsvfGotoTapState( unsigned char*   pucTapState,
+                      unsigned char    ucTargetState )
+{
+    int i;
+    int iErrorCode;
+
+    iErrorCode  = XSVF_ERROR_NONE;
+    if ( ucTargetState == XTAPSTATE_RESET )
+    {
+        /* If RESET, always perform TMS reset sequence to reset/sync TAPs */
+        xsvfTmsTransition( 1 );
+        for ( i = 0; i < 5; ++i )
+        {
+            setPort( TCK, 0 );
+            setPort( TCK, 1 );
+        }
+        *pucTapState    = XTAPSTATE_RESET;
+        XSVFDBG_PRINTF( 3, "   TMS Reset Sequence -> Test-Logic-Reset\n" );
+        XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
+                         xsvf_pzTapState[ *pucTapState ] );
+    }
+    else if ( ( ucTargetState != *pucTapState ) &&
+              ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) ||
+                ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) )
+    {
+        /* Trap illegal TAP state path specification */
+        iErrorCode      = XSVF_ERROR_ILLEGALSTATE;
+    }
+    else
+    {
+        if ( ucTargetState == *pucTapState )
+        {
+            /* Already in target state.  Do nothing except when in DRPAUSE
+               or in IRPAUSE to comply with SVF standard */
+            if ( ucTargetState == XTAPSTATE_PAUSEDR )
+            {
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT2DR;
+                XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
+                                 xsvf_pzTapState[ *pucTapState ] );
+            }
+            else if ( ucTargetState == XTAPSTATE_PAUSEIR )
+            {
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT2IR;
+                XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
+                                 xsvf_pzTapState[ *pucTapState ] );
+            }
+        }
+
+        /* Perform TAP state transitions to get to the target state */
+        while ( ucTargetState != *pucTapState )
+        {
+            switch ( *pucTapState )
+            {
+            case XTAPSTATE_RESET:
+                xsvfTmsTransition( 0 );
+                *pucTapState    = XTAPSTATE_RUNTEST;
+                break;
+            case XTAPSTATE_RUNTEST:
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_SELECTDR;
+                break;
+            case XTAPSTATE_SELECTDR:
+                if ( ucTargetState >= XTAPSTATE_IRSTATES )
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_SELECTIR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_CAPTUREDR;
+                }
+                break;
+            case XTAPSTATE_CAPTUREDR:
+                if ( ucTargetState == XTAPSTATE_SHIFTDR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_SHIFTDR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_EXIT1DR;
+                }
+                break;
+            case XTAPSTATE_SHIFTDR:
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT1DR;
+                break;
+            case XTAPSTATE_EXIT1DR:
+                if ( ucTargetState == XTAPSTATE_PAUSEDR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_PAUSEDR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_UPDATEDR;
+                }
+                break;
+            case XTAPSTATE_PAUSEDR:
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT2DR;
+                break;
+            case XTAPSTATE_EXIT2DR:
+                if ( ucTargetState == XTAPSTATE_SHIFTDR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_SHIFTDR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_UPDATEDR;
+                }
+                break;
+            case XTAPSTATE_UPDATEDR:
+                if ( ucTargetState == XTAPSTATE_RUNTEST )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_RUNTEST;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_SELECTDR;
+                }
+                break;
+            case XTAPSTATE_SELECTIR:
+                xsvfTmsTransition( 0 );
+                *pucTapState    = XTAPSTATE_CAPTUREIR;
+                break;
+            case XTAPSTATE_CAPTUREIR:
+                if ( ucTargetState == XTAPSTATE_SHIFTIR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_SHIFTIR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_EXIT1IR;
+                }
+                break;
+            case XTAPSTATE_SHIFTIR:
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT1IR;
+                break;
+            case XTAPSTATE_EXIT1IR:
+                if ( ucTargetState == XTAPSTATE_PAUSEIR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_PAUSEIR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_UPDATEIR;
+                }
+                break;
+            case XTAPSTATE_PAUSEIR:
+                xsvfTmsTransition( 1 );
+                *pucTapState    = XTAPSTATE_EXIT2IR;
+                break;
+            case XTAPSTATE_EXIT2IR:
+                if ( ucTargetState == XTAPSTATE_SHIFTIR )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_SHIFTIR;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_UPDATEIR;
+                }
+                break;
+            case XTAPSTATE_UPDATEIR:
+                if ( ucTargetState == XTAPSTATE_RUNTEST )
+                {
+                    xsvfTmsTransition( 0 );
+                    *pucTapState    = XTAPSTATE_RUNTEST;
+                }
+                else
+                {
+                    xsvfTmsTransition( 1 );
+                    *pucTapState    = XTAPSTATE_SELECTDR;
+                }
+                break;
+            default:
+                iErrorCode      = XSVF_ERROR_ILLEGALSTATE;
+                *pucTapState    = ucTargetState;    /* Exit while loop */
+                break;
+            }
+            XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
+                             xsvf_pzTapState[ *pucTapState ] );
+        }
+    }
+
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfShiftOnly
+* Description:  Assumes that starting TAP state is SHIFT-DR or SHIFT-IR.
+*               Shift the given TDI data into the JTAG scan chain.
+*               Optionally, save the TDO data shifted out of the scan chain.
+*               Last shift cycle is special:  capture last TDO, set last TDI,
+*               but does not pulse TCK.  Caller must pulse TCK and optionally
+*               set TMS=1 to exit shift state.
+* Parameters:   lNumBits        - number of bits to shift.
+*               plvTdi          - ptr to lenval for TDI data.
+*               plvTdoCaptured  - ptr to lenval for storing captured TDO data.
+*               iExitShift      - 1=exit at end of shift; 0=stay in Shift-DR.
+* Returns:      void.
+*****************************************************************************/
+void xsvfShiftOnly( long    lNumBits,
+                    lenVal* plvTdi,
+                    lenVal* plvTdoCaptured,
+                    int     iExitShift )
+{
+    unsigned char*  pucTdi;
+    unsigned char*  pucTdo;
+    unsigned char   ucTdiByte;
+    unsigned char   ucTdoByte;
+    unsigned char   ucTdoBit;
+    int             i;
+
+    /* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */
+
+    /* Initialize TDO storage len == TDI len */
+    pucTdo  = 0;
+    if ( plvTdoCaptured )
+    {
+        plvTdoCaptured->len = plvTdi->len;
+        pucTdo              = plvTdoCaptured->val + plvTdi->len;
+    }
+
+    /* Shift LSB first.  val[N-1] == LSB.  val[0] == MSB. */
+    pucTdi  = plvTdi->val + plvTdi->len;
+    while ( lNumBits )
+    {
+        /* Process on a byte-basis */
+        ucTdiByte   = (*(--pucTdi));
+        ucTdoByte   = 0;
+        for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i )
+        {
+            --lNumBits;
+            if ( iExitShift && !lNumBits )
+            {
+                /* Exit Shift-DR state */
+                setPort( TMS, 1 );
+            }
+
+            /* Set the new TDI value */
+            setPort( TDI, (short)(ucTdiByte & 1) );
+            ucTdiByte   >>= 1;
+
+            /* Set TCK low */
+            setPort( TCK, 0 );
+
+            if ( pucTdo )
+            {
+                /* Save the TDO value */
+                ucTdoBit    = readTDOBit();
+                ucTdoByte   |= ( ucTdoBit << i );
+            }
+
+            /* Set TCK high */
+            setPort( TCK, 1 );
+        }
+
+        /* Save the TDO byte value */
+        if ( pucTdo )
+        {
+            (*(--pucTdo))   = ucTdoByte;
+        }
+    }
+}
+
+/*****************************************************************************
+* Function:     xsvfShift
+* Description:  Goes to the given starting TAP state.
+*               Calls xsvfShiftOnly to shift in the given TDI data and
+*               optionally capture the TDO data.
+*               Compares the TDO captured data against the TDO expected
+*               data.
+*               If a data mismatch occurs, then executes the exception
+*               handling loop upto ucMaxRepeat times.
+* Parameters:   pucTapState     - Ptr to current TAP state.
+*               ucStartState    - Starting shift state: Shift-DR or Shift-IR.
+*               lNumBits        - number of bits to shift.
+*               plvTdi          - ptr to lenval for TDI data.
+*               plvTdoCaptured  - ptr to lenval for storing TDO data.
+*               plvTdoExpected  - ptr to expected TDO data.
+*               plvTdoMask      - ptr to TDO mask.
+*               ucEndState      - state in which to end the shift.
+*               lRunTestTime    - amount of time to wait after the shift.
+*               ucMaxRepeat     - Maximum number of retries on TDO mismatch.
+* Returns:      int             - 0 = success; otherwise TDO mismatch.
+* Notes:        XC9500XL-only Optimization:
+*               Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1]
+*               is NOT all zeros and sMatch==1.
+*****************************************************************************/
+int xsvfShift( unsigned char*   pucTapState,
+               unsigned char    ucStartState,
+               long             lNumBits,
+               lenVal*          plvTdi,
+               lenVal*          plvTdoCaptured,
+               lenVal*          plvTdoExpected,
+               lenVal*          plvTdoMask,
+               unsigned char    ucEndState,
+               long             lRunTestTime,
+               unsigned char    ucMaxRepeat )
+{
+    int             iErrorCode;
+    int             iMismatch;
+    unsigned char   ucRepeat;
+    int             iExitShift;
+
+    iErrorCode  = XSVF_ERROR_NONE;
+    iMismatch   = 0;
+    ucRepeat    = 0;
+    iExitShift  = ( ucStartState != ucEndState );
+
+    XSVFDBG_PRINTF1( 3, "   Shift Length = %ld\n", lNumBits );
+    XSVFDBG_PRINTF( 4, "    TDI          = ");
+    XSVFDBG_PRINTLENVAL( 4, plvTdi );
+    XSVFDBG_PRINTF( 4, "\n");
+    XSVFDBG_PRINTF( 4, "    TDO Expected = ");
+    XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
+    XSVFDBG_PRINTF( 4, "\n");
+
+    if ( !lNumBits )
+    {
+        /* Compatibility with XSVF2.00:  XSDR 0 = no shift, but wait in RTI */
+        if ( lRunTestTime )
+        {
+            /* Wait for prespecified XRUNTEST time */
+            xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
+            XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime );
+            waitTime( lRunTestTime );
+        }
+    }
+    else
+    {
+        do
+        {
+            /* Goto Shift-DR or Shift-IR */
+            xsvfGotoTapState( pucTapState, ucStartState );
+
+            /* Shift TDI and capture TDO */
+            xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift );
+
+            if ( plvTdoExpected )
+            {
+                /* Compare TDO data to expected TDO data */
+                iMismatch   = !EqualLenVal( plvTdoExpected,
+                                            plvTdoCaptured,
+                                            plvTdoMask );
+            }
+
+            if ( iExitShift )
+            {
+                /* Update TAP state:  Shift->Exit */
+                ++(*pucTapState);
+                XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
+                                 xsvf_pzTapState[ *pucTapState ] );
+
+                if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) )
+                {
+                    XSVFDBG_PRINTF( 4, "    TDO Expected = ");
+                    XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
+                    XSVFDBG_PRINTF( 4, "\n");
+                    XSVFDBG_PRINTF( 4, "    TDO Captured = ");
+                    XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured );
+                    XSVFDBG_PRINTF( 4, "\n");
+                    XSVFDBG_PRINTF( 4, "    TDO Mask     = ");
+                    XSVFDBG_PRINTLENVAL( 4, plvTdoMask );
+                    XSVFDBG_PRINTF( 4, "\n");
+                    XSVFDBG_PRINTF1( 3, "   Retry #%d\n", ( ucRepeat + 1 ) );
+                    /* Do exception handling retry - ShiftDR only */
+                    xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR );
+                    /* Shift 1 extra bit */
+                    xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR );
+                    /* Increment RUNTEST time by an additional 25% */
+                    lRunTestTime    += ( lRunTestTime >> 2 );
+                }
+                else
+                {
+                    /* Do normal exit from Shift-XR */
+                    xsvfGotoTapState( pucTapState, ucEndState );
+                }
+
+                if ( lRunTestTime )
+                {
+                    /* Wait for prespecified XRUNTEST time */
+                    xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
+                    XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime );
+                    waitTime( lRunTestTime );
+                }
+            }
+        } while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) );
+    }
+
+    if ( iMismatch )
+    {
+        XSVFDBG_PRINTF( 1, " TDO Expected = ");
+        XSVFDBG_PRINTLENVAL( 1, plvTdoExpected );
+        XSVFDBG_PRINTF( 1, "\n");
+        XSVFDBG_PRINTF( 1, " TDO Captured = ");
+        XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured );
+        XSVFDBG_PRINTF( 1, "\n");
+        XSVFDBG_PRINTF( 1, " TDO Mask     = ");
+        XSVFDBG_PRINTLENVAL( 1, plvTdoMask );
+        XSVFDBG_PRINTF( 1, "\n");
+        if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) )
+        {
+            iErrorCode  = XSVF_ERROR_MAXRETRIES;
+        }
+        else
+        {
+            iErrorCode  = XSVF_ERROR_TDOMISMATCH;
+        }
+    }
+
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfBasicXSDRTDO
+* Description:  Get the XSDRTDO parameters and execute the XSDRTDO command.
+*               This is the common function for all XSDRTDO commands.
+* Parameters:   pucTapState         - Current TAP state.
+*               lShiftLengthBits    - number of bits to shift.
+*               sShiftLengthBytes   - number of bytes to read.
+*               plvTdi              - ptr to lenval for TDI data.
+*               lvTdoCaptured       - ptr to lenval for storing TDO data.
+*               iEndState           - state in which to end the shift.
+*               lRunTestTime        - amount of time to wait after the shift.
+*               ucMaxRepeat         - maximum xc9500/xl retries.
+* Returns:      int                 - 0 = success; otherwise TDO mismatch.
+*****************************************************************************/
+int xsvfBasicXSDRTDO( unsigned char*    pucTapState,
+                      long              lShiftLengthBits,
+                      short             sShiftLengthBytes,
+                      lenVal*           plvTdi,
+                      lenVal*           plvTdoCaptured,
+                      lenVal*           plvTdoExpected,
+                      lenVal*           plvTdoMask,
+                      unsigned char     ucEndState,
+                      long              lRunTestTime,
+                      unsigned char     ucMaxRepeat )
+{
+    readVal( plvTdi, sShiftLengthBytes );
+    if ( plvTdoExpected )
+    {
+        readVal( plvTdoExpected, sShiftLengthBytes );
+    }
+    return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
+                       plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask,
+                       ucEndState, lRunTestTime, ucMaxRepeat ) );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoSDRMasking
+* Description:  Update the data value with the next XSDRINC data and address.
+* Example:      dataVal=0x01ff, nextData=0xab, addressMask=0x0100,
+*               dataMask=0x00ff, should set dataVal to 0x02ab
+* Parameters:   plvTdi          - The current TDI value.
+*               plvNextData     - the next data value.
+*               plvAddressMask  - the address mask.
+*               plvDataMask     - the data mask.
+* Returns:      void.
+*****************************************************************************/
+#ifdef  XSVF_SUPPORT_COMPRESSION
+void xsvfDoSDRMasking( lenVal*  plvTdi,
+                       lenVal*  plvNextData,
+                       lenVal*  plvAddressMask,
+                       lenVal*  plvDataMask )
+{
+    int             i;
+    unsigned char   ucTdi;
+    unsigned char   ucTdiMask;
+    unsigned char   ucDataMask;
+    unsigned char   ucNextData;
+    unsigned char   ucNextMask;
+    short           sNextData;
+
+    /* add the address Mask to dataVal and return as a new dataVal */
+    addVal( plvTdi, plvTdi, plvAddressMask );
+
+    ucNextData  = 0;
+    ucNextMask  = 0;
+    sNextData   = plvNextData->len;
+    for ( i = plvDataMask->len - 1; i >= 0; --i )
+    {
+        /* Go through data mask in reverse order looking for mask (1) bits */
+        ucDataMask  = plvDataMask->val[ i ];
+        if ( ucDataMask )
+        {
+            /* Retrieve the corresponding TDI byte value */
+            ucTdi       = plvTdi->val[ i ];
+
+            /* For each bit in the data mask byte, look for 1's */
+            ucTdiMask   = 1;
+            while ( ucDataMask )
+            {
+                if ( ucDataMask & 1 )
+                {
+                    if ( !ucNextMask )
+                    {
+                        /* Get the next data byte */
+                        ucNextData  = plvNextData->val[ --sNextData ];
+                        ucNextMask  = 1;
+                    }
+
+                    /* Set or clear the data bit according to the next data */
+                    if ( ucNextData & ucNextMask )
+                    {
+                        ucTdi   |= ucTdiMask;       /* Set bit */
+                    }
+                    else
+                    {
+                        ucTdi   &= ( ~ucTdiMask );  /* Clear bit */
+                    }
+
+                    /* Update the next data */
+                    ucNextMask  <<= 1;
+                }
+                ucTdiMask   <<= 1;
+                ucDataMask  >>= 1;
+            }
+
+            /* Update the TDI value */
+            plvTdi->val[ i ]    = ucTdi;
+        }
+    }
+}
+#endif  /* XSVF_SUPPORT_COMPRESSION */
+
+/*============================================================================
+* XSVF Command Functions (type = TXsvfDoCmdFuncPtr)
+* These functions update pXsvfInfo->iErrorCode only on an error.
+* Otherwise, the error code is left alone.
+* The function returns the error code from the function.
+============================================================================*/
+
+/*****************************************************************************
+* Function:     xsvfDoIllegalCmd
+* Description:  Function place holder for illegal/unsupported commands.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
+{
+    XSVFDBG_PRINTF2( 0, "ERROR:  Encountered unsupported command #%d (%s)\n",
+                     ((unsigned int)(pXsvfInfo->ucCommand)),
+                     ((pXsvfInfo->ucCommand < XLASTCMD)
+                      ? (xsvf_pzCommandName[pXsvfInfo->ucCommand])
+                      : "Unknown") );
+    pXsvfInfo->iErrorCode   = XSVF_ERROR_ILLEGALCMD;
+    return( pXsvfInfo->iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXCOMPLETE
+* Description:  XCOMPLETE (no parameters)
+*               Update complete status for XSVF player.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
+{
+    pXsvfInfo->ucComplete   = 1;
+    return( XSVF_ERROR_NONE );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXTDOMASK
+* Description:  XTDOMASK <lenVal.TdoMask[XSDRSIZE]>
+*               Prespecify the TDO compare mask.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
+{
+    readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes );
+    XSVFDBG_PRINTF( 4, "    TDO Mask     = ");
+    XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) );
+    XSVFDBG_PRINTF( 4, "\n");
+    return( XSVF_ERROR_NONE );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSIR
+* Description:  XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]>
+*               Get the instruction and shift the instruction into the TAP.
+*               If prespecified XRUNTEST!=0, goto RUNTEST and wait after
+*               the shift for XRUNTEST usec.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
+{
+    unsigned char   ucShiftIrBits;
+    short           sShiftIrBytes;
+    int             iErrorCode;
+
+    /* Get the shift length and store */
+    readByte( &ucShiftIrBits );
+    sShiftIrBytes   = xsvfGetAsNumBytes( ucShiftIrBits );
+    XSVFDBG_PRINTF1( 3, "   XSIR length = %d\n",
+                     ((unsigned int)ucShiftIrBits) );
+
+    if ( sShiftIrBytes > MAX_LEN )
+    {
+        iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
+    }
+    else
+    {
+        /* Get and store instruction to shift in */
+        readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) );
+
+        /* Shift the data */
+        iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
+                                 ucShiftIrBits, &(pXsvfInfo->lvTdi),
+                                 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
+                                 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
+                                 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
+    }
+
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSIR2
+* Description:  XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]>
+*               Get the instruction and shift the instruction into the TAP.
+*               If prespecified XRUNTEST!=0, goto RUNTEST and wait after
+*               the shift for XRUNTEST usec.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
+{
+    long            lShiftIrBits;
+    short           sShiftIrBytes;
+    int             iErrorCode;
+
+    /* Get the shift length and store */
+    readVal( &(pXsvfInfo->lvTdi), 2 );
+    lShiftIrBits    = value( &(pXsvfInfo->lvTdi) );
+    sShiftIrBytes   = xsvfGetAsNumBytes( lShiftIrBits );
+    XSVFDBG_PRINTF1( 3, "   XSIR2 length = %d\n", lShiftIrBits);
+
+    if ( sShiftIrBytes > MAX_LEN )
+    {
+        iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
+    }
+    else
+    {
+        /* Get and store instruction to shift in */
+        readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) );
+
+        /* Shift the data */
+        iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
+                                 lShiftIrBits, &(pXsvfInfo->lvTdi),
+                                 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
+                                 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
+                                 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
+    }
+
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSDR
+* Description:  XSDR <lenVal.TDI[XSDRSIZE]>
+*               Shift the given TDI data into the JTAG scan chain.
+*               Compare the captured TDO with the expected TDO from the
+*               previous XSDRTDO command using the previously specified
+*               XTDOMASK.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
+{
+    int iErrorCode;
+    readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
+    /* use TDOExpected from last XSDRTDO instruction */
+    iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
+                             pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi),
+                             &(pXsvfInfo->lvTdoCaptured),
+                             &(pXsvfInfo->lvTdoExpected),
+                             &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
+                             pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXRUNTEST
+* Description:  XRUNTEST <uint32>
+*               Prespecify the XRUNTEST wait time for shift operations.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
+{
+    readVal( &(pXsvfInfo->lvTdi), 4 );
+    pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) );
+    XSVFDBG_PRINTF1( 3, "   XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime );
+    return( XSVF_ERROR_NONE );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXREPEAT
+* Description:  XREPEAT <byte>
+*               Prespecify the maximum number of XC9500/XL retries.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
+{
+    readByte( &(pXsvfInfo->ucMaxRepeat) );
+    XSVFDBG_PRINTF1( 3, "   XREPEAT = %d\n",
+                     ((unsigned int)(pXsvfInfo->ucMaxRepeat)) );
+    return( XSVF_ERROR_NONE );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSDRSIZE
+* Description:  XSDRSIZE <uint32>
+*               Prespecify the XRUNTEST wait time for shift operations.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
+{
+    int iErrorCode;
+    iErrorCode  = XSVF_ERROR_NONE;
+    readVal( &(pXsvfInfo->lvTdi), 4 );
+    pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) );
+    pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits );
+    XSVFDBG_PRINTF1( 3, "   XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits );
+    if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN )
+    {
+        iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSDRTDO
+* Description:  XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
+*               Get the TDI and expected TDO values.  Then, shift.
+*               Compare the expected TDO with the captured TDO using the
+*               prespecified XTDOMASK.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
+{
+    int iErrorCode;
+    iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
+                                    pXsvfInfo->lShiftLengthBits,
+                                    pXsvfInfo->sShiftLengthBytes,
+                                    &(pXsvfInfo->lvTdi),
+                                    &(pXsvfInfo->lvTdoCaptured),
+                                    &(pXsvfInfo->lvTdoExpected),
+                                    &(pXsvfInfo->lvTdoMask),
+                                    pXsvfInfo->ucEndDR,
+                                    pXsvfInfo->lRunTestTime,
+                                    pXsvfInfo->ucMaxRepeat );
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSETSDRMASKS
+* Description:  XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]>
+*                            <lenVal.DataMask[XSDRSIZE]>
+*               Get the prespecified address and data mask for the XSDRINC
+*               command.
+*               Used for xc9500/xl compressed XSVF data.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+#ifdef  XSVF_SUPPORT_COMPRESSION
+int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
+{
+    /* read the addressMask */
+    readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes );
+    /* read the dataMask    */
+    readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes );
+
+    XSVFDBG_PRINTF( 4, "    Address Mask = " );
+    XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) );
+    XSVFDBG_PRINTF( 4, "\n" );
+    XSVFDBG_PRINTF( 4, "    Data Mask    = " );
+    XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) );
+    XSVFDBG_PRINTF( 4, "\n" );
+
+    return( XSVF_ERROR_NONE );
+}
+#endif  /* XSVF_SUPPORT_COMPRESSION */
+
+/*****************************************************************************
+* Function:     xsvfDoXSDRINC
+* Description:  XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)>
+*                       <lenVal.data[XSETSDRMASKS.dataMask.len]> ...
+*               Get the XSDRINC parameters and execute the XSDRINC command.
+*               XSDRINC starts by loading the first TDI shift value.
+*               Then, for numTimes, XSDRINC gets the next piece of data,
+*               replaces the bits from the starting TDI as defined by the
+*               XSETSDRMASKS.dataMask, adds the address mask from
+*               XSETSDRMASKS.addressMask, shifts the new TDI value,
+*               and compares the TDO to the expected TDO from the previous
+*               XSDRTDO command using the XTDOMASK.
+*               Used for xc9500/xl compressed XSVF data.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+#ifdef  XSVF_SUPPORT_COMPRESSION
+int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
+{
+    int             iErrorCode;
+    int             iDataMaskLen;
+    unsigned char   ucDataMask;
+    unsigned char   ucNumTimes;
+    unsigned char   i;
+
+    readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
+    iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
+                             pXsvfInfo->lShiftLengthBits,
+                             &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured),
+                             &(pXsvfInfo->lvTdoExpected),
+                             &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
+                             pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
+    if ( !iErrorCode )
+    {
+        /* Calculate number of data mask bits */
+        iDataMaskLen    = 0;
+        for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i )
+        {
+            ucDataMask  = pXsvfInfo->lvDataMask.val[ i ];
+            while ( ucDataMask )
+            {
+                iDataMaskLen    += ( ucDataMask & 1 );
+                ucDataMask      >>= 1;
+            }
+        }
+
+        /* Get the number of data pieces, i.e. number of times to shift */
+        readByte( &ucNumTimes );
+
+        /* For numTimes, get data, fix TDI, and shift */
+        for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i )
+        {
+            readVal( &(pXsvfInfo->lvNextData),
+                     xsvfGetAsNumBytes( iDataMaskLen ) );
+            xsvfDoSDRMasking( &(pXsvfInfo->lvTdi),
+                              &(pXsvfInfo->lvNextData),
+                              &(pXsvfInfo->lvAddressMask),
+                              &(pXsvfInfo->lvDataMask) );
+            iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState),
+                                     XTAPSTATE_SHIFTDR,
+                                     pXsvfInfo->lShiftLengthBits,
+                                     &(pXsvfInfo->lvTdi),
+                                     &(pXsvfInfo->lvTdoCaptured),
+                                     &(pXsvfInfo->lvTdoExpected),
+                                     &(pXsvfInfo->lvTdoMask),
+                                     pXsvfInfo->ucEndDR,
+                                     pXsvfInfo->lRunTestTime,
+                                     pXsvfInfo->ucMaxRepeat );
+        }
+    }
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+#endif  /* XSVF_SUPPORT_COMPRESSION */
+
+/*****************************************************************************
+* Function:     xsvfDoXSDRBCE
+* Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]>
+*               If not already in SHIFTDR, goto SHIFTDR.
+*               Shift the given TDI data into the JTAG scan chain.
+*               Ignore TDO.
+*               If cmd==XSDRE, then goto ENDDR.  Otherwise, stay in ShiftDR.
+*               XSDRB, XSDRC, and XSDRE are the same implementation.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
+{
+    unsigned char   ucEndDR;
+    int             iErrorCode;
+    ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ?
+                                pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
+    iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
+                                    pXsvfInfo->lShiftLengthBits,
+                                    pXsvfInfo->sShiftLengthBytes,
+                                    &(pXsvfInfo->lvTdi),
+                                    /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
+                                    /*plvTdoMask*/0, ucEndDR,
+                                    /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSDRTDOBCE
+* Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
+*               If not already in SHIFTDR, goto SHIFTDR.
+*               Shift the given TDI data into the JTAG scan chain.
+*               Compare TDO, but do NOT use XTDOMASK.
+*               If cmd==XSDRTDOE, then goto ENDDR.  Otherwise, stay in ShiftDR.
+*               XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
+{
+    unsigned char   ucEndDR;
+    int             iErrorCode;
+    ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ?
+                                pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
+    iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
+                                    pXsvfInfo->lShiftLengthBits,
+                                    pXsvfInfo->sShiftLengthBytes,
+                                    &(pXsvfInfo->lvTdi),
+                                    &(pXsvfInfo->lvTdoCaptured),
+                                    &(pXsvfInfo->lvTdoExpected),
+                                    /*plvTdoMask*/0, ucEndDR,
+                                    /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXSTATE
+* Description:  XSTATE <byte>
+*               <byte> == XTAPSTATE;
+*               Get the state parameter and transition the TAP to that state.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
+{
+    unsigned char   ucNextState;
+    int             iErrorCode;
+    readByte( &ucNextState );
+    iErrorCode  = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState );
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXENDXR
+* Description:  XENDIR/XENDDR <byte>
+*               <byte>:  0 = RUNTEST;  1 = PAUSE.
+*               Get the prespecified XENDIR or XENDDR.
+*               Both XENDIR and XENDDR use the same implementation.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
+{
+    int             iErrorCode;
+    unsigned char   ucEndState;
+
+    iErrorCode  = XSVF_ERROR_NONE;
+    readByte( &ucEndState );
+    if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) )
+    {
+        iErrorCode  = XSVF_ERROR_ILLEGALSTATE;
+    }
+    else
+    {
+
+    if ( pXsvfInfo->ucCommand == XENDIR )
+    {
+            if ( ucEndState == XENDXR_RUNTEST )
+            {
+                pXsvfInfo->ucEndIR  = XTAPSTATE_RUNTEST;
+            }
+            else
+            {
+                pXsvfInfo->ucEndIR  = XTAPSTATE_PAUSEIR;
+            }
+            XSVFDBG_PRINTF1( 3, "   ENDIR State = %s\n",
+                             xsvf_pzTapState[ pXsvfInfo->ucEndIR ] );
+        }
+    else    /* XENDDR */
+    {
+            if ( ucEndState == XENDXR_RUNTEST )
+            {
+                pXsvfInfo->ucEndDR  = XTAPSTATE_RUNTEST;
+            }
+    else
+    {
+                pXsvfInfo->ucEndDR  = XTAPSTATE_PAUSEDR;
+            }
+            XSVFDBG_PRINTF1( 3, "   ENDDR State = %s\n",
+                             xsvf_pzTapState[ pXsvfInfo->ucEndDR ] );
+        }
+    }
+
+    if ( iErrorCode != XSVF_ERROR_NONE )
+    {
+        pXsvfInfo->iErrorCode   = iErrorCode;
+    }
+    return( iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXCOMMENT
+* Description:  XCOMMENT <text string ending in \0>
+*               <text string ending in \0> == text comment;
+*               Arbitrary comment embedded in the XSVF.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
+{
+    /* Use the comment for debugging */
+    /* Otherwise, read through the comment to the end '\0' and ignore */
+    //unsigned char   ucText;
+/*
+    if ( xsvf_iDebugLevel > 0 )
+    {
+        putchar( ' ' );
+    }
+
+    do
+    {
+        readByte( &ucText );
+        if ( xsvf_iDebugLevel > 0 )
+        {
+            putchar( ucText ? ucText : '\n' );
+        }
+    } while ( ucText );
+*/
+    pXsvfInfo->iErrorCode   = XSVF_ERROR_NONE;
+
+    return( pXsvfInfo->iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfDoXWAIT
+* Description:  XWAIT <wait_state> <end_state> <wait_time>
+*               If not already in <wait_state>, then go to <wait_state>.
+*               Wait in <wait_state> for <wait_time> microseconds.
+*               Finally, if not already in <end_state>, then goto <end_state>.
+* Parameters:   pXsvfInfo   - XSVF information pointer.
+* Returns:      int         - 0 = success;  non-zero = error.
+*****************************************************************************/
+int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
+{
+    unsigned char   ucWaitState;
+    unsigned char   ucEndState;
+    long            lWaitTime;
+
+    /* Get Parameters */
+    /* <wait_state> */
+    readVal( &(pXsvfInfo->lvTdi), 1 );
+    ucWaitState = pXsvfInfo->lvTdi.val[0];
+
+    /* <end_state> */
+    readVal( &(pXsvfInfo->lvTdi), 1 );
+    ucEndState = pXsvfInfo->lvTdi.val[0];
+
+    /* <wait_time> */
+    readVal( &(pXsvfInfo->lvTdi), 4 );
+    lWaitTime = value( &(pXsvfInfo->lvTdi) );
+    XSVFDBG_PRINTF2( 3, "   XWAIT:  state = %s; time = %ld\n",
+                     xsvf_pzTapState[ ucWaitState ], lWaitTime );
+
+    /* If not already in <wait_state>, go to <wait_state> */
+    if ( pXsvfInfo->ucTapState != ucWaitState )
+    {
+        xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState );
+    }
+
+    /* Wait for <wait_time> microseconds */
+    waitTime( lWaitTime );
+
+    /* If not already in <end_state>, go to <end_state> */
+    if ( pXsvfInfo->ucTapState != ucEndState )
+    {
+        xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState );
+    }
+
+    return( XSVF_ERROR_NONE );
+}
+
+
+/*============================================================================
+* Execution Control Functions
+============================================================================*/
+
+/*****************************************************************************
+* Function:     xsvfInitialize
+* Description:  Initialize the xsvf player.
+*               Call this before running the player to initialize the data
+*               in the SXsvfInfo struct.
+*               xsvfCleanup is called to clean up the data in SXsvfInfo
+*               after the XSVF is played.
+* Parameters:   pXsvfInfo   - ptr to the XSVF information.
+* Returns:      int - 0 = success; otherwise error.
+*****************************************************************************/
+int xsvfInitialize( SXsvfInfo* pXsvfInfo )
+{
+    /* Initialize values */
+    pXsvfInfo->iErrorCode   = xsvfInfoInit( pXsvfInfo );
+
+    if ( !pXsvfInfo->iErrorCode )
+    {
+        /* Initialize the TAPs */
+        pXsvfInfo->iErrorCode   = xsvfGotoTapState( &(pXsvfInfo->ucTapState),
+                                                    XTAPSTATE_RESET );
+    }
+
+    return( pXsvfInfo->iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfRun
+* Description:  Run the xsvf player for a single command and return.
+*               First, call xsvfInitialize.
+*               Then, repeatedly call this function until an error is detected
+*               or until the pXsvfInfo->ucComplete variable is non-zero.
+*               Finally, call xsvfCleanup to cleanup any remnants.
+* Parameters:   pXsvfInfo   - ptr to the XSVF information.
+* Returns:      int         - 0 = success; otherwise error.
+*****************************************************************************/
+int xsvfRun( SXsvfInfo* pXsvfInfo )
+{
+    /* Process the XSVF commands */
+    if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) )
+    {
+        /* read 1 byte for the instruction */
+        readByte( &(pXsvfInfo->ucCommand) );
+        ++(pXsvfInfo->lCommandCount);
+
+        if ( pXsvfInfo->ucCommand < XLASTCMD )
+        {
+            /* Execute the command.  Func sets error code. */
+            XSVFDBG_PRINTF1( 2, "  %s\n",
+                             xsvf_pzCommandName[pXsvfInfo->ucCommand] );
+            /* If your compiler cannot take this form,
+               then convert to a switch statement */
+            xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo );
+        }
+        else
+        {
+            /* Illegal command value.  Func sets error code. */
+            xsvfDoIllegalCmd( pXsvfInfo );
+        }
+    }
+
+    return( pXsvfInfo->iErrorCode );
+}
+
+/*****************************************************************************
+* Function:     xsvfCleanup
+* Description:  cleanup remnants of the xsvf player.
+* Parameters:   pXsvfInfo   - ptr to the XSVF information.
+* Returns:      void.
+*****************************************************************************/
+void xsvfCleanup( SXsvfInfo* pXsvfInfo )
+{
+    xsvfInfoCleanup( pXsvfInfo );
+}
+
+
+/*============================================================================
+* xsvfExecute() - The primary entry point to the XSVF player
+============================================================================*/
+
+/*****************************************************************************
+* Function:     xsvfExecute
+* Description:  Process, interpret, and apply the XSVF commands.
+*               See port.c:readByte for source of XSVF data.
+* Parameters:   none.
+* Returns:      int - Legacy result values:  1 == success;  0 == failed.
+*****************************************************************************/
+int xsvfExecute()
+{
+    SXsvfInfo   xsvfInfo;
+
+    pc.printf("=========================\n");
+    
+    xsvfInitialize( &xsvfInfo );
+
+    pc.printf("init complete\n");
+
+    while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) )
+    {
+        xsvfRun( &xsvfInfo );
+        pc.printf("loop>\n");
+    }
+
+    if ( xsvfInfo.iErrorCode )
+    {
+        XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[
+                         ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST )
+                         ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] );
+        XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld.  See line #%ld in the XSVF ASCII file.\n",
+                         xsvfInfo.lCommandCount, xsvfInfo.lCommandCount );
+    }
+    else
+    {
+        XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" );
+    }
+
+    xsvfCleanup( &xsvfInfo );
+
+    return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) );
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/micro.h	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,42 @@
+/*****************************************************************************
+* File:         micro.h
+* Description:  This header file contains the function prototype to the
+*               primary interface function for the XSVF player.
+* Usage:        FIRST - PORTS.C
+*               Customize the ports.c function implementations to establish
+*               the correct protocol for communicating with your JTAG ports
+*               (setPort() and readTDOBit()) and tune the waitTime() delay
+*               function.  Also, establish access to the XSVF data source
+*               in the readByte() function.
+*               FINALLY - Call xsvfExecute().
+*****************************************************************************/
+#ifndef XSVF_MICRO_H
+#define XSVF_MICRO_H
+
+/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */
+#define XSVF_LEGACY_SUCCESS 1
+#define XSVF_LEGACY_ERROR   0
+
+/* 4.04 [NEW] Error codes for xsvfExecute. */
+/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */
+#define XSVF_ERROR_NONE         0
+#define XSVF_ERROR_UNKNOWN      1
+#define XSVF_ERROR_TDOMISMATCH  2
+#define XSVF_ERROR_MAXRETRIES   3   /* TDO mismatch after max retries */
+#define XSVF_ERROR_ILLEGALCMD   4
+#define XSVF_ERROR_ILLEGALSTATE 5
+#define XSVF_ERROR_DATAOVERFLOW 6   /* Data > lenVal MAX_LEN buffer size*/
+/* Insert new errors here */
+#define XSVF_ERROR_LAST         7
+
+/*****************************************************************************
+* Function:     xsvfExecute
+* Description:  Process, interpret, and apply the XSVF commands.
+*               See port.c:readByte for source of XSVF data.
+* Parameters:   none.
+* Returns:      int - For error codes see above.
+*****************************************************************************/
+extern int xsvfExecute();
+
+#endif  /* XSVF_MICRO_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports.c	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,91 @@
+/*******************************************************/
+/* file: ports.c                                       */
+/* abstract:  This file contains the routines to       */
+/*            output values on the JTAG ports, to read */
+/*            the TDO bit, and to read a byte of data  */
+/*            from the prom                            */
+/* Revisions:                                          */
+/* 12/01/2008:  Same code as before (original v5.01).  */
+/*              Updated comments to clarify instructions.*/
+/*              Add print in setPort for xapp058_example.exe.*/
+/*******************************************************/
+#include "ports.h"
+/*#include "prgispx.h"*/
+#include "mbed.h"
+DigitalOut TMS_pin(p5);
+DigitalOut TDI_pin(p6);
+DigitalOut TCK_pin(p7);
+DigitalIn  TDO_pin(p8);
+
+extern FILE *fp;
+static int  g_iTCK = 0; /* For xapp058_example .exe */
+static int  g_iTMS = 0; /* For xapp058_example .exe */
+static int  g_iTDI = 0; /* For xapp058_example .exe */
+
+/*BYTE *xsvf_data=0;*/
+
+
+/* setPort:  Implement to set the named JTAG signal (p) to the new value (v).*/
+/* if in debugging mode, then just set the variables */
+void setPort(short p,short val)
+{
+    /* Printing code for the xapp058_example.exe.  You must set the specified
+       JTAG signal (p) to the new value (v).  See the above, old Win95 code
+       as an implementation example. */
+    if (p==TMS)
+    {
+        g_iTMS = val;
+        TMS_pin = val;
+    }
+    if (p==TDI)
+    {
+        g_iTDI = val;
+        TDI_pin = val;
+    }
+    if (p==TCK)
+    {
+        g_iTCK = val;
+        TCK_pin = val;
+        printf( "TCK = %d;  TMS = %d;  TDI = %d\n", g_iTCK, g_iTMS, g_iTDI );
+    }
+}
+
+
+/* toggle tck LH.  No need to modify this code.  It is output via setPort. */
+void pulseClock()
+{
+    setPort(TCK,0);  /* set the TCK port to low  */
+    setPort(TCK,1);  /* set the TCK port to high */
+}
+
+
+/* readByte:  Implement to source the next byte from your XSVF file location */
+/* read in a byte of data from the prom */
+void readByte(unsigned char *data)
+{
+    /* pretend reading using a file */
+    *data   = (unsigned char)fgetc( fp );
+
+}
+
+/* readTDOBit:  Implement to return the current value of the JTAG TDO signal.*/
+/* read the TDO bit from port */
+unsigned char readTDOBit()
+{
+    /* You must return the current value of the JTAG TDO signal. */
+    return( (unsigned char) TDO_pin );
+}
+
+/* waitTime:  Implement as follows: */
+/* REQUIRED:  This function must consume/wait at least the specified number  */
+/*            of microsec, interpreting microsec as a number of microseconds.*/
+/* REQUIRED FOR SPARTAN/VIRTEX FPGAs and indirect flash programming:         */
+/*            This function must pulse TCK for at least microsec times,      */
+/*            interpreting microsec as an integer value.                     */
+/* RECOMMENDED IMPLEMENTATION:  Pulse TCK at least microsec times AND        */
+/*                              continue pulsing TCK until the microsec wait */
+/*                              requirement is also satisfied.               */
+void waitTime(long microsec)
+{
+    wait(microsec);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports.h	Sat Jun 30 13:17:05 2012 +0000
@@ -0,0 +1,31 @@
+/*******************************************************/
+/* file: ports.h                                       */
+/* abstract:  This file contains extern declarations   */
+/*            for providing stimulus to the JTAG ports.*/
+/*******************************************************/
+
+#ifndef ports_dot_h
+#define ports_dot_h
+
+/* these constants are used to send the appropriate ports to setPort */
+/* they should be enumerated types, but some of the microcontroller  */
+/* compilers don't like enumerated types */
+#define TCK (short) 0
+#define TMS (short) 1
+#define TDI (short) 2
+
+/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */
+extern void setPort(short p, short val);
+
+/* read the TDO bit and store it in val */
+extern unsigned char readTDOBit();
+
+/* make clock go down->up->down*/
+extern void pulseClock();
+
+/* read the next byte of data from the xsvf file */
+extern void readByte(unsigned char *data);
+
+extern void waitTime(long microsec);
+
+#endif