Listing 6 Data copy routine

/***********************************************************************
Internal routine to copy data to Flash Memory. It is assumed that the
destination area has been erased, and that bytes is an even number.
Returns non-zero on success; zero is returned on error and fm_err contains
failure data. FMInfo and pBase are assumed initialized.
  * * * NOTE: This routine has been hand optimized for performance. * * *
***********************************************************************/

#define W_FS_ITER 350 /* number of fail-safe loop iterations per msec */
       /** Re-measure this constant if the fail-safe loop is changed! **/

static fm_cpy(pDst, pSrc, bytes)
register volatile unsigned short *pDst; /* where in Flash to copy data to */
register unsigned short *pSrc;          /* where to copy data from */
register size_t bytes;                  /* # bytes to copy -- must be even */
{
       register volatile unsigned short *ptr1; /* fast FM_ADDR1 ptr */
       register volatile unsigned short *ptr2; /* fast FM_ADDR2 ptr */
       register unsigned short fmd1, fmd2;     /* fast FM_DATA values */
       register unsigned short val;            /* value read in verify loop */
       register unsigned short fail_safe;      /* safety counter */

       /* put these in registers for speed: */
       ptr1 = pBase + FM_ADDR1;
       ptr2 = pBase + FM_ADDR2;
       fmd1 = FM_DATA1;
       fmd2 = FM_DATA2;

       /* loop writing and verifying a word at a time: */
       while (bytes)
       {
              /* this duplicates a call to fm_cmd(), for speed: */
              *ptr1 = fmd1;
              *ptr2 = fmd2;
              *ptr1 = FMCMD_WRITE;

              /* write two bytes: */
              *pDst = *pSrc;
              /* do this here - a bit of parallel processing: */
              bytes -= 2;
              val = *pSrc;

              /* loop checking for write completion: */
              for (fail_safe = FMInfo.MaxWrite_ * W_FS_ITER;  --fail_safe; )
                     if (*pDst == val)
                            break; /* done! */

              /* if loop was exhausted, go handle the error: */
              if (fail_safe == 0)
              {       fm_tofs_error(pDst, val, *pDst, 4);
                     return 0;
              }

              /* move to the next location and loop back: */
              ++pSrc;
              ++pDst;
       }

       /* return happy: */
       return 1;
}
/* End of File */