diff src/gpf3/ccd/cdc_std.c @ 2:c41a534f33c6

src/gpf3: preened GPF goo from TCS3.2
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 25 Sep 2016 23:52:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpf3/ccd/cdc_std.c	Sun Sep 25 23:52:50 2016 +0000
@@ -0,0 +1,1204 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  
+|  Modul   : cdc_std.c
++----------------------------------------------------------------------------- 
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  Condat Conder Decoder 
+|             Definitions of non protocol specific encoding and decoding 
+|             functions
++----------------------------------------------------------------------------- 
+*/ 
+
+#define CCD_STD_C
+
+#ifdef _MSDOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+/*
+ * standard definitions like UCHAR, ERROR etc.
+ */
+#include "typedefs.h"
+#include "header.h"
+#include <string.h>
+
+/*
+ * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
+ * look at ccdapi.h.
+ */
+#undef USE_DRIVER
+#include "ccdapi.h"
+
+/*
+ * Types and functions for bit access and manipulation
+ */
+#include "ccd_globs.h"
+#include "bitfun.h"
+
+/*
+ * Declaration of coder/decoder tables and/or functions to access them
+ */
+#include "ccdtable.h"
+#include "ccddata.h"
+
+/*
+ * Prototypes of ccd internal functions
+ */
+#include "ccd.h"
+
+/*
+ * Need memory allocation functions for dynamic arrays (pointers)
+ */
+#ifdef DYNAMIC_ARRAYS
+#include "vsi.h"
+#endif
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : cdc_decodeElemvalue   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Performs a standard decoding for a given elem table entry.
+            This means for non structured elements that 1-n bits are
+            read from the bitstream and write to a C-Variable
+            in a machine dependent format. For structured elements
+            an (indirect) recursive call to cc_decodeComposition()
+            is performed. If the element is a bitbuffer with variable
+            size, the repeat value gives the number of bits to read
+            from the bitstream into the buffer. The maxBitpos
+            indicates the maximum valid position for the
+            readpointer of the bitstream while decoding this element.
+            If the readpointer break this boundary, this element will
+            not be decoded.
+*/
+
+void cdc_decodeElemvalue (ULONG e_ref, ULONG *repeat, T_CCD_Globs *globs)
+{
+  UBYTE     *ActStructpos;
+  ULONG      i;
+  UBYTE      spareLen;
+
+  /*
+   * element is a bit field of variable length
+   */
+  if ((melem[e_ref].repType == 'b') || (melem[e_ref].repType == 's'))
+  {
+    if (*repeat > (ULONG) (globs->maxBitpos-globs->bitpos))
+    {
+      ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, 
+                       (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
+      *repeat = MINIMUM (*repeat, (ULONG) (globs->maxBitpos-globs->bitpos));
+    }
+    if (melem[e_ref].repType == 'b')
+    {
+      if (mvar[melem[e_ref].elemRef].cType EQ 'X')
+        bf_readBitChunk (*repeat, globs);
+      else
+        bf_readBits (*repeat, globs); 
+    }
+    else 
+    {
+      U16 finalBP = globs->bitpos + (USHORT) *repeat;
+      /* Store the limit. This comp may contain other comps as bitstring. */
+      globs->maxBitpos = finalBP;
+      ActStructpos = globs->pstruct;
+      globs->pstruct += globs->pstructOffs;
+#ifdef DEBUG_CCD
+#ifdef CCD_SYMBOLS
+      TRACE_CCD (globs, "decoding composition %s as a bit array",
+                       mcomp[melem[e_ref].elemRef].name);
+#else
+      TRACE_CCD (globs, "decoding composition %d", melem[e_ref].elemRef);
+#endif
+#endif
+
+      ccd_decodeComposition ((ULONG) (melem[e_ref].elemRef), globs);
+      if (finalBP < globs->bitpos)
+      {
+        ccd_recordFault (globs, ERR_BITSTR_COMP, CONTINUE, (USHORT) e_ref,
+                         globs->pstruct + globs->pstructOffs);
+      }
+      bf_setBitpos (finalBP, globs);
+      /* Update maxBitpos to avoid an early end of decoding. */
+      globs->maxBitpos = globs->buflen;
+      globs->pstruct = ActStructpos;
+    }
+  }
+  else
+  {
+    /*
+     * For pointer types, globs->pstruct is already set to point to
+     * the new memory area, and these types are not treated differently
+     * from non-pointer types.
+     */
+    i=0;
+    switch (melem[e_ref].elemType)
+    {
+      case 'R': /* Pointer to (possible array of) basetype */
+      case 'F': /* Code-transparent pointer to (possible array of) basetype */
+      case 'V':
+        while (i < *repeat)
+        {
+          if (globs->bitpos < globs->maxBitpos)
+          {
+#ifdef DEBUG_CCD
+#ifdef CCD_SYMBOLS
+            TRACE_CCD (globs, "decoding var %s",
+                       ccddata_get_alias((USHORT) e_ref, 1));
+#else
+            TRACE_CCD (globs, "decoding var %d", melem[e_ref].elemRef);
+#endif
+#endif
+            if (mvar[melem[e_ref].elemRef].cType EQ 'X')
+              bf_readBitChunk (mvar[melem[e_ref].elemRef].bSize, globs);
+            else
+              bf_readBits (mvar[melem[e_ref].elemRef].bSize, globs);
+
+            globs->pstructOffs += mvar[melem[e_ref].elemRef].cSize;
+
+            i++;
+          }
+          else
+          {
+            if (melem[e_ref].repType != 'i')
+            {
+              ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref,
+                               globs->pstruct + globs->pstructOffs);
+            }
+            break;
+          }
+        }
+        break;
+
+      case 'D': /* Pointer to a composition */
+      case 'P': /* Code transparent pointer to a comp */
+      case 'C': /* Element is a composition. */
+      case 'U': /* Element is a union. */
+        /*
+         * Store the actual structure position.
+         */
+        ActStructpos = globs->pstruct;
+
+        globs->pstruct += globs->pstructOffs;
+
+        while (i < *repeat)
+        {
+          if (globs->bitpos < globs->maxBitpos)
+          {
+#ifdef DEBUG_CCD
+#ifdef CCD_SYMBOLS
+            TRACE_CCD (globs, "decoding composition %s",
+                       mcomp[melem[e_ref].elemRef].name);
+#else
+            TRACE_CCD (globs, "decoding composition %d", melem[e_ref].elemRef);
+#endif
+#endif
+		        /*
+		         * recursiv call
+		         */
+            ccd_decodeComposition ((ULONG) (melem[e_ref].elemRef), globs);
+            globs->pstruct += mcomp[melem[e_ref].elemRef].cSize;
+
+            i++;
+          }
+          else
+          {
+            if (melem[e_ref].repType != 'i')
+            {
+              ccd_recordFault (globs, ERR_ELEM_LEN, CONTINUE, (USHORT) e_ref,
+                               globs->pstruct + globs->pstructOffs);
+            }
+            break;
+          }
+        }
+        /*
+         * restore the write pointer
+         */
+        globs->pstruct = ActStructpos;
+        break;
+
+      case 'S': /* Element is a spare. */
+      {
+        spareLen = spare[melem[e_ref].elemRef].bSize;
+        /*
+         * Do not decode padding bits. They are not relevant.
+         * Just adjust the position pointer in the bit stream buffer.
+         */
+        while (i < *repeat)
+        {
+          if (globs->bitpos < globs->maxBitpos)
+          {
+#ifdef DEBUG_CCD
+            TRACE_CCD (globs, "decoding spare");
+#endif
+            bf_incBitpos (spareLen, globs);
+            i++;
+          }
+          else
+            break;
+        }
+        break;
+      }
+    }
+    *repeat = i;
+  }
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : cdc_encodeElemvalue   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Performs a standard encoding for a given elem table entry.
+            This means for non structured elements that 1-n bits are
+            read from the bitstream and write to a C-Variable
+            in a machine dependent format. For structured elements
+            an (indirect) recursive call to cc_decodeComposition()
+            is performed. If the element is a bitbuffer with variable
+            size, the repeat value gives the number of bits to write
+            from the buffer into the bitstream.
+*/
+
+void cdc_encodeElemvalue (ULONG e_ref, ULONG repeat, T_CCD_Globs *globs)
+{
+  UBYTE     *ActStructpos = NULL;
+  ULONG      i;
+  UBYTE      spareLen;
+
+  /*
+   * Element is a bit field of variable length.
+   */
+  if (melem[e_ref].repType == 'b')
+  {
+    if (mvar[melem[e_ref].elemRef].cType EQ 'X')
+      bf_writeBitChunk (repeat, globs);
+    else
+      bf_writeBits (repeat, globs);
+  }
+  /*
+   * Element is a structured IE defined as bit string.
+   */
+  else if (melem[e_ref].repType == 's')
+  {
+    U16 finalBP = (USHORT) (globs->bitpos + repeat);
+    ActStructpos = globs->pstruct;
+    globs->pstruct += globs->pstructOffs;
+#ifdef DEBUG_CCD
+#ifdef CCD_SYMBOLS
+    TRACE_CCD (globs, "encoding composition %s as a bit array",
+                       mcomp[melem[e_ref].elemRef].name);
+#else
+    TRACE_CCD (globs, "encoding composition %d", melem[e_ref].elemRef);
+#endif
+#endif
+
+    ccd_encodeComposition ((ULONG) melem[e_ref].elemRef, globs);
+    if (finalBP < globs->bitpos)
+    {
+      ccd_recordFault (globs, ERR_BITSTR_COMP, CONTINUE, (USHORT) e_ref, 
+                       globs->pstruct + globs->pstructOffs);
+    }
+    bf_setBitpos (finalBP, globs);
+    globs->pstruct = ActStructpos;
+  }
+  else
+  {
+    /*
+     * For pointer types, globs->pstruct is already set to point to
+     * the new memory area, and these types are not treated differently
+     * from non-pointer types.
+     */
+    switch(melem[e_ref].elemType)
+    {
+      case 'R': /* Pointer to (possible array of) basetype */
+      case 'F': /* Code-transparent pointer to (possible array of) basetype */
+      case 'V':
+        for (i=0; i<repeat; i++)
+        {
+  #ifdef DEBUG_CCD
+  #ifdef CCD_SYMBOLS
+          TRACE_CCD (globs, "encoding var %s",
+                     ccddata_get_alias((USHORT) e_ref, 1));
+  #else
+          TRACE_CCD (globs, "encoding var %s", melem[e_ref].elemRef);
+  #endif
+  #endif
+          if (mvar[melem[e_ref].elemRef].cType EQ 'X')
+            bf_writeBitChunk (mvar[melem[e_ref].elemRef].bSize, globs);
+          else
+            bf_writeBits (mvar[melem[e_ref].elemRef].bSize, globs);
+
+          globs->pstructOffs += mvar[melem[e_ref].elemRef].cSize;
+        }
+        break;
+
+      case 'D': /* Pointer to a composition (already dereferenced) */
+      case 'P': /* Code transparent pointer to a comp (already dereferenced) */
+      case 'C': /* Element is a composition. */
+      case 'U': /* Element is a union. */
+        /*
+         * store the actual structure position
+         */
+        ActStructpos = globs->pstruct;
+
+        globs->pstruct += globs->pstructOffs;
+
+        for (i=0; i<repeat; i++)
+        {
+  #ifdef DEBUG_CCD
+  #ifdef CCD_SYMBOLS
+          TRACE_CCD (globs, "encoding composition %s",
+                     mcomp[melem[e_ref].elemRef].name);
+  #else
+          TRACE_CCD (globs, "encoding composition %d", melem[e_ref].elemRef);
+  #endif
+  #endif
+          ccd_encodeComposition ((ULONG) melem[e_ref].elemRef, globs);	/* recursiv call */
+          globs->pstruct += mcomp[melem[e_ref].elemRef].cSize;
+        }
+        /*
+         * restore the write pointer
+         */
+        globs->pstruct = ActStructpos;
+        break;
+
+      case 'S': /* element is a spare          */
+      {
+        spareLen = spare[melem[e_ref].elemRef].bSize;
+
+        /*
+         * encode the spare
+         */
+        for (i=0; i < repeat; i++)
+        {
+  #ifdef DEBUG_CCD
+          TRACE_CCD (globs, "encoding spare");
+  #endif
+          bf_codeLongNumber (spareLen, spare[melem[e_ref].elemRef].value, globs);
+        }
+        break;
+      }
+    }
+  }
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : cdc_STD_decode        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Performs a standard decoding for a given elem table entry.
+            This means for non structured elements that 1-n bits are
+            read from the bitstream and write to a C-Variable
+            in a machine dependent format. For structured elements
+            an (indirect) recursive call to cc_decodeComposition()
+            is performed.
+            The element may be conditional and/or repeatable.
+*/
+
+SHORT cdc_std_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG               repeat, amount, act_offset;
+  BOOL                is_variable;
+  U8                 *old_pstruct = NULL;
+  ULONG               cix_ref, num_prolog_steps, prolog_step_ref;
+
+#ifdef DEBUG_CCD
+  #ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_std_decode()");
+	#else
+	TRACE_CCD (globs, "cdc_std_decode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  cix_ref = melem[e_ref].calcIdxRef;
+  num_prolog_steps = calcidx[cix_ref].numPrologSteps;
+  prolog_step_ref  = calcidx[cix_ref].prologStepRef;
+
+  /*
+   * if this element is conditional, check the condition
+   */
+  if (calcidx[cix_ref].numCondCalcs NEQ 0
+  AND ! ccd_conditionOK (e_ref, globs))
+    return 1;
+
+  /*
+   * if this element has a defined prologue
+   * we have to process it before decoding the bitstream
+   * If there are some epilogue expressions to be processed for this element
+   * (rare cases) the result here will be a reading of 0 to an internal
+   * register. The valid processing of expression takes place after the 
+   * decoding of the element. 
+   */
+  if (num_prolog_steps)
+  {
+    ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
+  }
+  
+  /*
+   * if this element is repeatable, and the number of
+   * repeats depends on another element, calculate the repeater
+   */
+  if (melem[e_ref].repType NEQ ' ')
+  {
+    is_variable = ccd_calculateRep (e_ref, &repeat, &act_offset, globs);
+  }
+  else
+  {
+    repeat = 1;
+    is_variable = FALSE;
+  }
+
+  if (melem[e_ref].elemType NEQ 'S')
+  {
+    /*
+     * Element is not a SPARE.
+     * Setup the offset into the C-structure for this element
+     */
+    globs->pstructOffs = melem[e_ref].structOffs;
+
+    if (melem[e_ref].optional)
+    {
+      /* 20010621 MVJ: Dynamic array addition.
+       * Postpone optional flag setting for non-code transparent
+       * pointer types ('P', 'Q', 'R').
+       * For these types, the optional flag is the pointer itself.
+       * These types cannot be set yet, as the pointer may be
+       * preceeded by a counter octet, a union tag id octet etc.
+       */
+      if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
+	      globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE;
+    }
+
+    if (is_variable)
+    {
+      /*
+       * for variable sized elements store the min-value
+       * as counter into the C-Structure (c_xxx).
+       */
+      if (act_offset > 65535)
+        *(ULONG *) (globs->pstruct + globs->pstructOffs++) = repeat;
+      else if (act_offset > 255)
+        *(USHORT *) (globs->pstruct + globs->pstructOffs++) = (USHORT) repeat;
+      else
+        globs->pstruct[globs->pstructOffs] = (UBYTE) repeat;
+
+      globs->pstructOffs++;
+    }
+  }
+  #ifdef DYNAMIC_ARRAYS
+  /*
+   * MVJ: Dynamic array addition.
+   * Check for pointer types; allocate memory if necessary.
+   */
+  if ( is_pointer_type(e_ref) ) {
+    U32     cSize;
+    U8      *addr;
+
+    /*
+     * Find size to allocate;
+     * - Read from mcomp or mvar according to type
+     */
+    cSize = (ULONG)((melem[e_ref].elemType EQ 'V' OR
+		      melem[e_ref].elemType EQ 'R')
+                     ? mvar[melem[e_ref].elemRef].cSize
+                     : mcomp[melem[e_ref].elemRef].cSize
+		     ) * repeat;
+
+    /*
+     * Allocate additional memory
+     */
+    addr = (U8 *)DP_ALLOC( cSize, globs->alloc_head, DP_NO_FRAME_GUESS);
+
+    /* If no memory, log error and return immediately */
+    if (addr EQ NULL) {
+      ccd_setError (globs, ERR_NO_MEM,
+                    BREAK,
+                    (USHORT) -1);
+      return 1;
+    }
+    else
+      memset (addr, 0, (size_t)cSize);
+
+    /*
+     * Memory allocated;
+     * 1. Save old "globs->pstruct" variables
+     * 2. Store pointer to freshly allocated memory area in structure
+     * 3. Initialize pstruct to point to the freshly allocated memory area.
+     * 4. Initialize pstructOffs to 0 to start decoding at offset 0
+     *    in the new memory area.
+     */
+    old_pstruct        = globs->pstruct;
+    *(U8 **)(globs->pstruct + globs->pstructOffs) = addr;
+    globs->pstruct     = addr;
+    globs->pstructOffs = 0;
+  }
+#endif
+
+  amount = repeat;
+
+  cdc_decodeElemvalue (e_ref, &amount, globs);
+
+  /*
+   * process the epilogue expression for this element if there is any 
+   */
+  if (num_prolog_steps)
+  {
+    if (  (calc[prolog_step_ref+1].operation EQ 'K')
+       || (calc[prolog_step_ref+1].operation EQ 'C')
+       || (calc[prolog_step_ref+1].operation EQ 's'))
+    {
+      ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
+    }
+  }
+
+#ifdef DYNAMIC_ARRAYS
+  /*
+   * Restore globs->pstruct for possible use below
+   */
+  if (old_pstruct NEQ NULL)
+  {
+    globs->pstruct     = old_pstruct;
+  }
+#endif
+  if (amount NEQ repeat AND is_variable)
+  {
+    /*
+     * if the decoded elements are not equal the specified
+     * repeat value, because the bitstream or the IE ended,
+     * store the new c_xxx value.
+     */
+    globs->pstructOffs = melem[e_ref].structOffs;
+
+    if (melem[e_ref].optional)
+      globs->pstructOffs++;
+
+      if (act_offset > 65535)
+        *(ULONG *) (globs->pstruct + globs->pstructOffs) = amount;
+      else if (act_offset > 255)
+        *(USHORT *) (globs->pstruct + globs->pstructOffs) = (USHORT) amount;
+      else
+        globs->pstruct[globs->pstructOffs] = (UBYTE) amount;
+
+    if (melem[e_ref].repType NEQ 'i')
+    {
+      /*
+       * if this element is not of the repeat style 'interval'
+       * ([X..Y] where X and Y are constants) we have to generate
+       * an ccd error because some outstanding repeats are missing.
+       */
+      ccd_setError (globs, ERR_MAND_ELEM_MISS, CONTINUE, (USHORT) -1);
+    }
+  }
+
+  return 1;
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : cdc_std_encode        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Performs a standard encoding for a given elem table entry.
+            This means for non structured elements that m bytes read
+            from the C-Variable, converted to MSB-first format and
+            write 1-n bits at the end of the bitstream.
+            For structured elements an (indirect) recursive call
+            to ccd_encodeComposition() is performed.
+            The element may be conditional and/or repeatable.
+*/
+
+SHORT cdc_std_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
+{
+  ULONG               repeat, max_rep;
+  BOOL                is_variable;
+  ULONG               cix_ref, num_prolog_steps, prolog_step_ref;
+#ifdef DYNAMIC_ARRAYS
+  U8                  *old_pstruct = NULL;
+#endif
+
+#ifdef DEBUG_CCD
+	#ifndef CCD_SYMBOLS
+  TRACE_CCD (globs, "cdc_std_encode()");
+	#else
+	TRACE_CCD (globs, "cdc_std_encode() %s", ccddata_get_alias((USHORT) e_ref, 1));
+	#endif
+#endif
+
+  cix_ref = melem[e_ref].calcIdxRef;
+  num_prolog_steps = calcidx[cix_ref].numPrologSteps;
+  prolog_step_ref  = calcidx[cix_ref].prologStepRef;
+  /*
+   * if this element is conditional, check the condition
+   */
+  if (calcidx[cix_ref].numCondCalcs NEQ 0
+  AND ! ccd_conditionOK (e_ref, globs))
+    return 1;
+
+  /*
+   * if this element have a defined Prolog
+   * we have to process it before decoding the bitstream
+   */
+  if (num_prolog_steps)
+  {
+    ccd_performOperations (num_prolog_steps, prolog_step_ref, globs);
+  }
+  
+  if (melem[e_ref].elemType NEQ 'S')
+  {
+    /*
+     * Element is not a SPARE.
+     * Setup the readpointer into the C-structure for this element
+     * MVJ: In case of pointer types, the pstructOffs must be
+     * the offset into the memory area pointed to. CCDGEN must
+     * ensure this holds true.
+     */
+    globs->pstructOffs = melem[e_ref].structOffs;
+
+    if (melem[e_ref].optional)
+    {
+      /*
+       * for optional elements check the valid-flag in the C-struct.
+       * Spare elements does not have a corresponding valid flag. For
+       * the spare elements we have to calculate and check the
+       * condition to decide if this elements have to be coded.
+       */
+      /* 20010621 MVJ: Dynamic array addition.
+       * Postpone optional check for non-code transparent pointer
+       * types ('P', 'Q', 'R').
+       * For these types, the optional flag is the pointer itself.
+       * These types cannot be checked yet, as the pointer may be
+       * preceeded by a counter octet, a union tag id octet etc.
+       */
+      if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R')
+      { 
+        if (globs->pstruct[globs->pstructOffs++] == FALSE)
+        {
+          return 1;
+        }
+#ifdef DEBUG_CCD
+        else if (globs->pstruct [melem[e_ref].structOffs] != TRUE)
+        {
+          TRACE_CCD (globs, "Ambiguous value for valid flag!\n...assumed 1 for ccdID=%d",
+                     e_ref);
+        }
+#endif
+      }
+    }
+
+    if ((melem[e_ref].repType EQ 'v' OR melem[e_ref].repType EQ 'i'))
+    {
+      /*
+       * for variable sized elements read the amount
+       * of repeats out of the C-Structure (c_xxx).
+       * If the number of repeats given by the C-Structure 
+       * exceeds the allowed value (maxRepeat) CCD gives a warning!
+       */
+      if (melem[e_ref].maxRepeat > 255)
+      {
+        ULONG count = (ULONG) (* (USHORT *)(globs->pstruct + globs->pstructOffs++));
+        repeat = MINIMUM (count, (ULONG) melem[e_ref].maxRepeat);
+        if (repeat < count) 
+          ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, 
+                           (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
+      }
+      else
+      {
+        repeat = (ULONG)MINIMUM (globs->pstruct[globs->pstructOffs], 
+                                  melem[e_ref].maxRepeat);
+        if ( repeat < (ULONG) (globs->pstruct[globs->pstructOffs]) ) 
+          ccd_recordFault (globs, ERR_MAX_REPEAT, CONTINUE, 
+                           (USHORT) e_ref, globs->pstruct + globs->pstructOffs);
+      }
+      globs->pstructOffs++;
+    }
+    else
+      if (melem[e_ref].repType EQ 'c')
+      {
+        repeat = (ULONG) melem[e_ref].maxRepeat;
+      }
+      else
+        if (melem[e_ref].repType == 's' || melem[e_ref].repType == 'b')
+        {
+          switch (melem[e_ref].elemType)
+          {
+            case 'R': /* Pointer to (possible array of) basetype */
+            case 'F': /* Code-transparent pointer to (possible array of) basetype */
+            case 'V':
+              globs->maxBitpos = globs->bitpos + mvar[melem[e_ref].elemRef].bSize;
+              break;
+            case 'D': /* Pointer to a composition */
+            case 'P': /* Code transparent pointer to a comp */
+            case 'C': /* Element is a composition. */
+            case 'E': /* Pointer to a union */
+            case 'Q': /* Code transparent pointer to a union */
+            case 'U': /* Element is a union. */
+              globs->maxBitpos = globs->bitpos + mcomp[melem[e_ref].elemRef].bSize;
+              break;
+          }
+          
+          is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
+        }
+        else
+          repeat = 1;
+
+    /* 20010621 MVJ: Dynamic array addition.
+     * Check for non-code transparent pointer types ('P', 'Q', 'R').
+     * For these types, the optional flag is the pointer itself.
+     * ASSUMPTION: The pointer may be preceeded by a counter octet,
+     * a union tag id octet etc., but it is up to CCDGEN to ensure
+     * word alignment (by inserting alignment bytes). Therefore
+     * we just read from globs->pstruct[globs->pstructOffs].
+    */
+#ifdef DEBUG_CCD
+    /* Check pointer alignment and re-align if necessary (should never happen) */
+    if ( is_pointer_type(e_ref) AND ((globs->pstructOffs & 3) NEQ 0)) {
+      TRACE_CCD (globs, "cdc_STD_encode(): Pointer misaligned! pstruct=0x08x,"
+		 " pstructOffs=0x%08x", globs->pstruct, globs->pstructOffs);
+      globs->pstructOffs = (globs->pstructOffs + 3) & 3;
+    }
+#endif
+#ifdef DYNAMIC_ARRAYS
+    /*
+     * MVJ: Perform pointer dereference for pointer types.
+     * Also, check optionality for these types.
+     */
+    if ( is_pointer_type(e_ref) ) {
+      U8 *deref_pstruct;
+
+      /* Get pointer value */
+      deref_pstruct = *(U8 **)&globs->pstruct[globs->pstructOffs];
+
+      /*
+       * Strictly speaking the 'D' to 'F' types should not need this
+       * check (should have returned after the optionality check above),
+       * but it will catch stray NULL pointers (or uninitialized
+       * valid flags)
+      */
+      if (ccd_check_pointer(deref_pstruct) != ccdOK )
+      {
+        ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref, 
+                         &globs->pstruct[globs->pstructOffs]);
+        return 1;
+      }
+      /*
+       * Pointer not NULL;
+       * 1. Save old globs->pstruct and assign pointer to globs->pstruct
+       *    as new base.
+       * 2. Set pstructOffs to 0 (zero) as the next offset will start
+       *    in the new memory area.
+       */
+      old_pstruct        = globs->pstruct;
+      globs->pstruct     = deref_pstruct;
+      globs->pstructOffs = 0;
+    }
+#endif /* DYNAMIC_ARRAYS */
+  }
+  else
+  {
+    /*
+     * for spare elements we have to calculate the conditions
+     * and the repetitions because there are no valid-flags and
+     * c_xxx variables in the C-structure to read.
+     */
+    if (melem[e_ref].optional)
+    {
+      /*
+       * Spare elements does not have a corresponding valid flag.
+       * For the spare elements we have to calculate and check the
+       * condition to decide if this elements have to be coded.
+       */
+      if (calcidx[cix_ref].numCondCalcs NEQ 0
+      AND ! ccd_conditionOK (e_ref, globs))
+        return 1;
+    }
+    /*
+     * if this spare is repeatable, calculate the amount of
+     * repeats because there is no corresponding c_xxx element
+     * in the C-Structure.
+     */
+    if (melem[e_ref].repType NEQ ' ')
+    {
+      globs->maxBitpos = globs->bitpos + spare[melem[e_ref].elemRef].bSize;
+      is_variable = ccd_calculateRep (e_ref, &repeat, &max_rep, globs);
+    }
+    else
+      repeat = 1;
+  }
+
+  cdc_encodeElemvalue (e_ref, repeat, globs);
+
+#ifdef DYNAMIC_ARRAYS
+  if ( old_pstruct NEQ NULL )
+    globs->pstruct = old_pstruct;
+#endif
+
+  return 1;
+}
+#endif /* !RUN_FLASH */
+
+/*
+ * some elementary bitfunctions
+ */
+
+/* LSB,MSB Definitions for the CPUs */
+
+#ifdef M_INTEL
+#define MSB_POS 1
+#define LSB_POS 0
+#define MSW_POS 2
+#define LSW_POS 0
+#else /* M_INTEL */
+#ifdef M_MOTOROLA
+#define MSB_POS 0
+#define LSB_POS 1
+#define MSW_POS 0
+#define LSW_POS 2
+#endif /* M_MOTOROLA */
+#endif /* M_INTEL */
+
+extern const ULONG ccd_bitfun_mask[];
+
+/*
+ * Table of one-bit values (2^X)
+ * This unused variable is commented now in order to avoid some compiler 
+ * warnings like:  variable "shift" (line xxx) is not used
+
+LOCAL const UBYTE shift[] =
+{
+  128, 64, 32, 16, 8, 4, 2, 1
+};
+ */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : ccd_codeByte          |
++--------------------------------------------------------------------+
+
+ PURPOSE:   encodes the value of (value) into a CPU-dependent
+            bitstring. The length of the bitstring is specified
+            throu (bitlen). The function copies the bitstring into
+            the buffer (bitstream) at bit position (startbit).
+            The bitlen may be between 1 and 8.
+
+*/
+
+BYTE CCDDATA_PREF(ccd_codeByte) (UBYTE * bitstream,
+                                 USHORT startbit,
+              		               USHORT bitlen,
+                                 UBYTE value)
+{
+  union
+  {	/* Conversion structure 2 Byte <-> unsigned short */
+    UBYTE c[2];
+    USHORT s;
+  }
+  conv;
+
+  UBYTE *p, lshift;
+
+  USHORT m;
+
+  p = bitstream + (startbit >> 3);
+
+  lshift = (16 - ((startbit & 7) + bitlen));
+
+  conv.c[MSB_POS] = p[0];
+
+  conv.c[LSB_POS] = p[1];
+
+  m = ((USHORT) ccd_bitfun_mask[bitlen]) << lshift;
+
+  conv.s &= ~m;
+
+  conv.s |= ((value << lshift) & m);
+
+  p[0] = conv.c[MSB_POS];
+
+  p[1] = conv.c[LSB_POS];
+
+  return ccdOK;
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : ccd_decodeByte        |
++--------------------------------------------------------------------+
+
+ PURPOSE:   decodes (bitlen) bits from the (bitstream) at position
+            (startbit) and converts them to a numeric value (value)
+            The bitlen may be between 1 and 8.
+
+*/
+
+BYTE CCDDATA_PREF(ccd_decodeByte) (UBYTE *bitstream,
+                                   USHORT startbit,
+                                   USHORT bitlen,
+                                   UBYTE *value)
+{
+  union
+  {	/* Conversion structure 2 Byte <-> unsigned short */
+    UBYTE c[2];
+    USHORT s;
+  }
+  conv;
+
+  UBYTE *p;
+
+  p = bitstream + (startbit >> 3);
+
+  conv.c[MSB_POS] = *p++;
+
+  conv.c[LSB_POS] = *p;
+
+  conv.s >>= (16 - ((startbit & 7) + bitlen));
+
+  conv.s &= (USHORT) ccd_bitfun_mask[bitlen];
+
+  *value = (UBYTE) conv.s;
+
+  return ccdOK;
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : ccd_codeLong          |
++--------------------------------------------------------------------+
+
+ PURPOSE:   encodes the value of (value) into a CPU-dependent
+            bitstring. The length of the bitstring is specified
+            throu (bitlen). The function copies the bitstring into
+            the buffer (bitstream) at bit position (startbit).
+            The bitlen may be between 1 and 32.
+
+*/
+
+BYTE CCDDATA_PREF(ccd_codeLong) (UBYTE *bitstream,
+                                 USHORT startbit,
+	                               USHORT bitlen,
+                                 ULONG value)
+{
+  UBYTE *p;
+
+  union
+  {	/* Conversion structure 4 Byte <-> unsigned long */
+    UBYTE c[4];
+    ULONG l;
+  }
+  conv;
+
+  p = bitstream + (startbit >> 3);
+  startbit &= 7;
+
+  conv.l = value & ccd_bitfun_mask[bitlen];
+  conv.l <<= (32-bitlen-startbit);
+
+  p[0] &= (UCHAR)~ccd_bitfun_mask[8-startbit];
+
+  switch ((USHORT)(startbit+bitlen-1) >> 3)
+  {
+    case 0:
+      p[0] |= conv.c[MSW_POS+MSB_POS];
+      break;
+    case 1:
+      p[0] |= conv.c[MSW_POS+MSB_POS];
+      p[1]  = conv.c[MSW_POS+LSB_POS];
+      break;
+    case 2:
+      p[0] |= conv.c[MSW_POS+MSB_POS];
+      p[1]  = conv.c[MSW_POS+LSB_POS];
+      p[2]  = conv.c[LSW_POS+MSB_POS];
+      break;
+    case 3:
+      p[0] |= conv.c[MSW_POS+MSB_POS];
+      p[1]  = conv.c[MSW_POS+LSB_POS];
+      p[2]  = conv.c[LSW_POS+MSB_POS];
+      p[3]  = conv.c[LSW_POS+LSB_POS];
+      break;
+    default:
+      p[0] |= conv.c[MSW_POS+MSB_POS];
+      p[1]  = conv.c[MSW_POS+LSB_POS];
+      p[2]  = conv.c[LSW_POS+MSB_POS];
+      p[3]  = conv.c[LSW_POS+LSB_POS];
+      p[4]  = (UBYTE) ((value & 0xff) << (8-startbit));
+      break;
+  }
+  return ccdOK;
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : ccd_decodeLong        |
++--------------------------------------------------------------------+
+
+ PURPOSE:   decodes (bitlen) bits from the (bitstream) at position
+            (startbit) and converts them to a numeric value (value)
+            The bitlen may be between 1 and 32.
+
+*/
+
+BYTE CCDDATA_PREF(ccd_decodeLong) (UBYTE *bitstream,
+                                   USHORT startbit,
+	                                 USHORT bitlen,
+                                   ULONG *value)
+{
+  UBYTE *p;
+
+  union
+  {	/* Conversion structure 4 Byte <-> unsigned long */
+    UBYTE c[4];
+    ULONG l;
+  }
+  conv;
+
+  p = bitstream + (startbit >> 3);
+  startbit &= 7;
+
+  conv.l = 0L;
+  switch ((USHORT)(startbit+bitlen-1) >> 3)
+  {
+    case 0:
+      conv.c[MSW_POS+MSB_POS] = p[0];
+      conv.l <<= startbit;
+      conv.l >>= (32-bitlen);
+      break;
+    case 1:
+      conv.c[MSW_POS+MSB_POS] = p[0];
+      conv.c[MSW_POS+LSB_POS] = p[1];
+      conv.l <<= startbit;
+      conv.l >>= (32-bitlen);
+      break;
+    case 2:
+      conv.c[MSW_POS+MSB_POS] = p[0];
+      conv.c[MSW_POS+LSB_POS] = p[1];
+      conv.c[LSW_POS+MSB_POS] = p[2];
+      conv.l <<= startbit;
+      conv.l >>= (32-bitlen);
+      break;
+    case 3:
+      conv.c[MSW_POS+MSB_POS] = p[0];
+      conv.c[MSW_POS+LSB_POS] = p[1];
+      conv.c[LSW_POS+MSB_POS] = p[2];
+      conv.c[LSW_POS+LSB_POS] = p[3];
+      conv.l <<= startbit;
+      conv.l >>= (32-bitlen);
+      break;
+    default:
+      conv.c[MSW_POS+MSB_POS] = p[0];
+      conv.c[MSW_POS+LSB_POS] = p[1];
+      conv.c[LSW_POS+MSB_POS] = p[2];
+      conv.c[LSW_POS+LSB_POS] = p[3];
+      conv.l <<= startbit;
+      conv.l >>= (32-bitlen);
+      conv.c[LSW_POS+LSB_POS] |= (p[4] >> (8-startbit));
+      break;
+  }
+  *value = conv.l & ccd_bitfun_mask[bitlen];
+  return ccdOK;
+}
+#endif /* !RUN_FLASH */
+
+#ifndef RUN_FLASH
+/*
++--------------------------------------------------------------------+
+| PROJECT : CCD (6144)               MODULE  : CCD                   |
+| STATE   : code                     ROUTINE : ccd_bitcopy           |
++--------------------------------------------------------------------+
+
+ PURPOSE: copys bitlen bits from the source buffer to the destination
+          buffer. offset contains the position of the first bit in
+          the source bitfield. This function may perform a leftshift
+          to adjust the most significant bit on byte boundarys of the
+          first byte in dest.
+
+*/
+
+void CCDDATA_PREF(ccd_bitcopy) (UBYTE     *dest,
+                                UBYTE     *source,
+                                USHORT     bitlen,
+                                USHORT     offset)
+{
+  union
+  {	/* Conversion structure 2 Byte <-> unsigned short */
+    UBYTE  c[2];
+    USHORT s;
+  }
+  conv;
+
+  USHORT l_shift       = offset & 7;
+  USHORT bytes_to_copy = (bitlen >> 3);
+
+  /*
+   * go to the byte that contains the first valid bit.
+   */
+  source += (offset >> 3);
+
+
+  if (l_shift)
+  {
+    /*
+     * shift and copy each byte
+     */
+    while (bytes_to_copy--)
+    {
+      conv.c[MSB_POS] = *source;
+      source++;
+      conv.c[LSB_POS] = *source;
+      conv.s <<= l_shift;
+      *dest = conv.c[MSB_POS];
+      dest++;
+    }
+  }
+  else
+  {
+    /*
+     * no shift operation, do a memcopy;
+     */
+    while (bytes_to_copy--)
+    {
+      *dest = *source;
+      dest++;
+      source++;
+    }
+  }
+  /*
+   * cutoff the garbage at the end of the bitstream
+   */
+ 
+  *(dest-1) &= (UCHAR)(~ccd_bitfun_mask[(8-(bitlen&7))&7]);
+}
+#endif /* !RUN_FLASH */