SLAU131V October 2004 – February 2020
/* cpy_tbl.c v##### */
/* */
/* General purpose copy routine. Given the address of a linker-generated */
/* COPY_TABLE data structure, copy all object components designated for copy */
/* via the corresponding LCF table() operator. */
/*****************************************************************************/
#include <cpy_tbl.h>
#include <string.h>
#ifdef __TI_EABI__
/*************************************************************************/
/* MSP copy tables can handle moving functions even in small data model */
/* + large code model, where data pointers are not big enough to */
/* represent function pointers. This requires the EABI decompression */
/* functions (SHARED/copy_*.c) to be changed to accept "far" pointers. */
/* For this memory model combination, the decompression functions are */
/* changed to use "unsigned long" to represent function pointers, so */
/* function pointers through which we call these functions also needs to */
/* have a prototype accepting "unsigned long" instead of pointer types. */
/* All other memory model combinations use the same prototype that all */
/* the other targets use: two data pointer arguments. Ultimately we use */
/* MSP peek/poke intrinsics to read/write the "far" memory. */
/*************************************************************************/
#if __LARGE_CODE_MODEL__ && !__LARGE_DATA_MODEL__
typedef void (*handler_fptr)(unsigned long in, unsigned long out);
#else
typedef void (*handler_fptr)(const unsigned char *in, unsigned char *out);
#endif
#define HANDLER_TABLE __TI_Handler_Table_Base
#pragma WEAK(HANDLER_TABLE)
extern unsigned int HANDLER_TABLE;
#endif
#if __LARGE_CODE_MODEL__ && !__LARGE_DATA_MODEL__ void __memcpy_far(unsigned long dst,
unsigned long src, unsigned long sz);
#endif
void copy_in(COPY_TABLE *tp)
{
unsigned short i;
for (i = 0; i < tp->num_recs; i++)
{
COPY_RECORD crp = tp->recs[i];
#if __LARGE_CODE_MODEL__ & __LARGE_DATA_MODEL__
unsigned long ld_addr = crp.load_addr;
unsigned long rn_addr = crp.run_addr;
#else
unsigned char *ld_addr = crp.load_addr;
unsigned char *rn_addr = crp.run_addr;
#endif
if (crp.size) {
/*------------------------------------------------------------------*/
/* Copy record has non-zero size so data is not compressed. */
/*------------------------------------------------------------------*/
#if __LARGE_CODE_MODEL__ && !__LARGE_DATA_MODEL__
if (ld_addr >> 16 || rn_addr >> 16)
__memcpy_far(rn_addr, ld_addr, crp.size);
else
memcpy((void*)(unsigned int)rn_addr,
(void*)(unsigned int)ld_addr, crp.size);
#else
memcpy(rn_addr, ld_addr, crp.size);
#endif
}
#ifdef __TI_EABI__
else if (HANDLER_TABLE)
{
/*------------------------------------------------------------------*/
/* Copy record has size zero so the data is compressed. The first */
/* byte of the load data has the handler index. Use this index with */
/* the handler table to get the handler for this data. Then call */
/* the handler by passing the load and run address. */
/*------------------------------------------------------------------*/
#if __LARGE_CODE_MODEL__ && !__LARGE_DATA_MODEL__
unsigned char index = __data20_read_char(ld_addr++);
#else
unsigned char index = *((unsigned char *)ld_addr++);
#endif
handler_fptr hndl = (handler_fptr)(&HANDLER_TABLE)[index];
#if __LARGE_CODE_MODEL__ && !__LARGE_DATA_MODEL__
(*hndl)(ld_addr, rn_addr);
#else
(*hndl)((const unsigned char *)ld_addr, (unsigned char *)rn_addr);
#endif
}
#endif
}
}