#include	"MemoryDeal.h"


#if 1   // 声明工具级的指针服务函数
unsigned char _gptrget1  (void *gptr);
void _gptrput1  (void *ptr, unsigned char val);
#endif
/*****************************************************************************
函数名称 : Get_Check_Sum
功能描述 : 计算校验和    嵌汇编实现结合到16bit，可根据需要进行返回类型调整
输入参数 : pack:数据源指针
           pack_len:计算校验和长度
返回参数 : 校验和
*****************************************************************************/
unsigned char Get_Check_Sum(unsigned char *pack, unsigned char pack_len)
{
#if 0
  unsigned char i;				// (short)
  unsigned char check_sum = 0; 	// (short)

  for(i = 0; i < pack_len; i ++)
  {
    check_sum += *pack ++;
  }

  return check_sum;
#else   // 约节约2个RAM，和55条
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  ;//  R0(STK04) STK00  STK01       （STK02）charlen    （STK02 STK03）shortlen
  ;//  STK06 STK05 （汇编指令增加不多，计数时加和结果按2字节，根据需要做返回即可）
   BANKSEL STK05
   CLR STK05
   BANKSEL STK06
   CLR STK06

   BANKSEL STK04
   MOV STK04,R0
   ;//#############################################
 condition_execute_get_check_sum:
	   BANKSEL STK02
	   MOV R0,STK02          ;// char型长度参数
	   ORL R0,#0x00
	   JNB PSW,2
	   JMP Return_get_check_sum_Label

//	   BANKSEL STK02
//	   MOV R0,STK02          ;// short型长度参数
//	   BANKSEL STK03
//	   ORL R0,STK03
//	   JNB PSW,2
//	   JMP Return_get_check_sum_Label
	   ;;// get vaule
	   BANKSEL STK04
	   MOV R0,STK04
	   PAGESEL __gptrget1
	   CALL __gptrget1
	   PAGESEL $
	   ;// ++
	   BANKSEL STK05
	   ADD STK05,R0
	   JB PSW,0
	   BANKSEL STK06
	   INC STK06
	   ;;// 如果下次，下次地址更新，仅考虑有效的2字节内容
	   BANKSEL STK01
	   INC STK01
	   JB  PSW,2
	   JMP  Next_Flag_get_check_sum_001
	   BANKSEL STK00
	   INC STK00
	   ;;// 次数--
  Next_Flag_get_check_sum_001:

	  BANKSEL STK02         ;// char型长度参数
	  DECJZ STK02
	  JMP condition_execute_get_check_sum

//	   MOV R0,#0xFF
//	   BANKSEL STK03          ;// short型长度参数
//	   ADD STK03,R0
//	   JNB PSW ,0
//	   JMP condition_execute_get_check_sum
//	   BANKSEL STK02
//	   DEC STK02
//	   JMP condition_execute_get_check_sum
  ;//#############################################
   Return_get_check_sum_Label:
	   BANKSEL STK05
	   MOV R0, STK05
	   ;//BANKSEL STK00
	   ;//MOV STK00,R0
	   ;//BANKSEL STK06
	   ;//MOV R0,STK06       ;// 2字节返回开启屏蔽的4行，有效代码2句，BANKSEL伪指令，默认STK都在一个区，会被优化掉
  __endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : my_strlen
功能描述 : 求字符串长度
输入参数 : src:源地址
返回参数 : len:数据长度
*****************************************************************************/
unsigned short My_Strlen(unsigned char *str)
{
#if 0
  unsigned short len = 0;
  if(str == NULL)
  {
    return 0;
  }

  for(len = 0; *str ++ != '\0'; )
  {
    len ++;
  }

  return len;
#else  // 约节约8RAM ，44条
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  	  ;// 参数  R0（STK02）   STK00 ，STK01 ，R0决定了是常数或RAM，有效地址为低2字节
  	  ;// 指针目标应该传递，有效，执行const或RAM,调用指针获取函数__gptrget1
  	  ;// 结果长度虽然使用了long型，只能为RAM的最大128，或Const的0x0000XXXX(程序空间)
  	  ;// 初始化目标长度0
  	  BANKSEL  STK03
  	  CLR STK03
  	  BANKSEL STK04
  	  CLR STK04
  	  ;// 入口参数的保护
  	  BANKSEL STK02
  	  MOV STK02,R0
  	  ;// 空指针的返回
  	  BANKSEL STK00
  	  ORL R0,STK00
  	  BANKSEL STK01
  	  ORL R0,STK01
  	  JNB PSW,2
  	  JMP END_my_strlen
  	  ;// 循环入口：
  	Check_END_my_strlen:
  	  BANKSEL STK02
  	  MOV R0,STK02
  	  ;// 获取一个内容,指针获取函数，不改变地址信息，即STK00 SK01
  	  PAGESEL  __gptrget1
  	  CALL __gptrget1
  	  XOR R0,#0x00
  	  JNB PSW,2
  	  JMP END_my_strlen
  	  ;//Next Addr
  	  BANKSEL STK04
  	  INC STK04
  	  JB PSW,2
  	  JMP my_strlen_add_addr
  	  BANKSEL STK03
  	  INC STK03
  	my_strlen_add_addr:
	  BANKSEL STK01
	  INC STK01
	  JB PSW,2
	  JMP Check_END_my_strlen
	  BANKSEL STK00
	  INC STK00
  	  JMP Check_END_my_strlen
  	  ;// relust
  	END_my_strlen:
  	  ;//  长度  STK03 STK04，转入返回规则的 R0  STK00
  	  BANKSEL STK04
  	  MOV R0,STK04
  	  BANKSEL STK00
  	  MOV STK00,R0

  	  BANKSEL STK03
  	  MOV R0,STK03

  __endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : my_memset
功能描述 : 把src所指内存区域的前count个字节设置成字符c
输入参数 : src:源地址
           ch:设置字符
           count:设置数据长度   STK03
返回参数 : src:数据处理完后的源地址尾
*****************************************************************************/
void *My_Memset(void *src,unsigned char ch,unsigned char count)
{
	// 设定RAM ,长度只能最大为128，这里保留使用2字节的int
#if 0

  unsigned char *tmp = (unsigned char *)src;

  if(src == NULL)
  {
    return NULL;
  }

  while(count --)
  {
    *tmp ++ = ch;
  }

  return src;
#else  // 约节约11RAM ，86条
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  ;// 参数  R0(SKT05),STK00 STK01 、  STK02  、 STK03
  BANKSEL STK05
  MOV STK05,R0
  ;// 判断目标是否存在
  BANKSEL STK00
  ORL R0,STK00
  BANKSEL STK01
  ORL R0,STK01
  JNB PSW,2
  JMP Return_my_memset ;// 自身都是0的，原封0返回 R0 STK00 STK01
  ;//循环判断
  Condition_SetVaule_my_memset:
  BANKSEL STK03
  MOV R0,STK03
  XOR R0,#0x00
  JNB PSW,2
  JMP EndSet_Return_my_memset
  ;// 赋值，char型不调用赋值函数，直接书写实现,但不同系列的KF的指针赋值存在差异，采用调用函数
  ;// 该函数的参数满足调用函数关系，因此节省传参传递
  BANKSEL STK05
  MOV R0,STK05
  PAGESEL __gptrput1 ;// * :R0 STK00 STK01   V:STK02,函数不会改变STK00和STK01
  CALL __gptrput1
  PAGESEL $
  ;//循环控制,RAM特性，SKT00为RAM区信息，++不用做改变的，因为STK01从0x80到0xFF，不允许回零的
  ;// 故指针执向和长度下不应超过源有效内容
	BANKSEL STK01
	INC STK01
	;//JB PSW,2
	;//JMP　Condition_Flag_my_memset
	;//BANKSEL STK00
	;//INC STK00
  Condition_Flag_my_memset:
    BANKSEL STK03
    DEC STK03
    JMP Condition_SetVaule_my_memset
  ;//返回
  EndSet_Return_my_memset:
   BANKSEL STK05
   MOV R0,STK05
  ;// 函数尾部
  Return_my_memset:
  __endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 :
功能描述 :比较内容是否相等，0相等，其他值为不等的1开始的偏移位置
输入参数 :

返回参数 :
*****************************************************************************/
unsigned int My_strcmp(void *dest, void *src)
{
#if 0
	unsigned int i=0;  // 有限字符串长度，一般不会const对const，RAM限定有效128字节
	unsigned char *pdest = (unsigned char *)dest;
	const unsigned char *psrc  = (const unsigned char *)src;
	while(1)
	{
		if(pdest[i]!=psrc[i])
			return i+1;
		if(  (pdest[i]==0)  &&  (psrc[i]==0) )
			return 0;
		i++;
	}
#else	//约节省15RAM 130地址
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
	__asm
	;//#########################################################
     ;//  R0(STK05)  STK00(STK06)  STK01(STK07)   VS  STK02 STK03 STK04
     ;//              STK08        STK09     STK10
     ;// 现场维护
     BANKSEL STK05
     MOV STK05,R0

     BANKSEL STK00
     MOV R0,STK00
     BANKSEL STK06
     MOV STK06,R0
     BANKSEL STK08
     MOV STK08,R0

     BANKSEL STK01
     MOV R0,STK01
     BANKSEL STK07
     MOV STK07,R0
     BANKSEL STK09
     MOV STK09,R0
     ;// 参数有效判断

 condition_EQU_Check_my_strcmp_Flag:
     ;// 获取目标值1
     ;//  R0(STK05)  STK00(STK06)  STK01(STK07)   VS  STK02 STK03 STK04
     ;//               STK08          STK09     STK10
     BANKSEL STK07
     MOV R0,STK07
     BANKSEL STK01
     MOV STK01,R0

     BANKSEL STK06
     MOV R0,STK06
     BANKSEL STK00
     MOV STK00,R0

     BANKSEL STK05
     MOV R0,STK05

     PAGESEL __gptrget1
     CALL   __gptrget1
     PAGESEL $
     BANKSEL STK10
     MOV STK10,R0
     ;// 获取目标值2
     BANKSEL STK04
     MOV R0,STK04
     BANKSEL STK01
     MOV STK01,R0

     BANKSEL STK03
     MOV R0,STK03
     BANKSEL STK00
     MOV STK00,R0

     BANKSEL STK02
     MOV R0,STK02

     PAGESEL __gptrget1
     CALL   __gptrget1
     PAGESEL $
     ;// 比较结果
     XOR R0,#0x00
     JB PSW ,2
     JMP GetVaule2_my_strcmp_Flag
      ;;//
     BANKSEL STK10
     XOR R0,STK10  ;// R0本是0前提
     JB PSW,2
     JMP NotEqu_my_strcmp_Flag
     ;//====================== V1 V2 ALL  Zero
     BANKSEL STK00
     CLR STK00
     CLR R0
     JMP my_strcmp_End_Flag  ;// 相等的条件
     ;//---------------------
 GetVaule2_my_strcmp_Flag:
 	 MOV R1,R0
 	 CLR R0
 	 BANKSEL STK10
	 XOR R0,STK10
	 JNB PSW,2
	 JMP NotEqu_my_strcmp_Flag
	 ;//=====================V1 V2 ALL NOT Zero
 	 BANKSEL STK10
	 XOR R1,STK10
	 JB PSW,2
	 JMP NotEqu_my_strcmp_Flag
	 ;//======================
     ;//循环处理
     ;//  R0(STK05)  STK00(STK06)  STK01(STK07)   VS  STK02 STK03 STK04
     ;//             STK08          STK09     STK10
     BANKSEL STK07
     INC STK07
     JB PSW,2
     JMP Check_my_strcmp_Flag_001
     BANKSEL STK06
     INC STK06
  Check_my_strcmp_Flag_001:
     BANKSEL STK04
     INC STK04
     JB PSW,2
     JMP condition_EQU_Check_my_strcmp_Flag
     BANKSEL STK03
     INC STK03
     JMP condition_EQU_Check_my_strcmp_Flag
     ;// 不等于的返回
   NotEqu_my_strcmp_Flag:
   	  BANKSEL STK09
   	  MOV R0,STK09
   	  BANKSEL STK07
   	  SUB R0,STK07
   	  BANKSEL STK00
   	  MOV STK00,R0

   	  BANKSEL STK08
   	  MOV R0,STK08
   	  JB PSW,0
   	  INC R0
   	  BANKSEL STK06
   	  SUB R0,STK06

   	  BANKSEL STK00
   	  INC STK00
   	  JNB PSW,2
   	  INC R0  ;// 不等偏移起始为1的处理，即第几个
     my_strcmp_End_Flag:
	;//#########################################################
	__endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : my_strfind
功能描述 :  定位发现数据串，0未找到，其他为找到的起始1开始的偏移位置
输入参数 : dest:目标地址
           src:源地址
           count:数据拷贝数量
返回参数 : src:数据处理完后的源地址
*****************************************************************************/
unsigned char My_strfind(void *dest, void *src,unsigned short offset)
{
#if 0
	unsigned char i=0,j;  // 有限字符串长度
	unsigned char *pdest = (unsigned char *)dest;
	const unsigned char *psrc  = (const unsigned char *)src+offset;


	while(psrc[i]!=0x00)
	{
		//============================
		j=0;
		while(1)
		{
			if(   psrc[i+j]!=pdest[j]  )
				break;
			// next  pre
			j++;
			if(pdest[j]==0x00)
				return i+1;
			// 源
			if(psrc[i+j]==0x00)
				return  0;
		}
		//=========================
		i++;
	}
	return 0;
#else   // 约节省最大14RAM和132地址
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
	__asm
	;//#########################################################
	;// R0(STK07)  STK00(STK08)  STK01(STK09)    STK02 STK03 STK04     （ STK05  STK06
	;///    i STK10   j STK11
	BANKSEL STK07
	MOV STK07,R0

	BANKSEL STK00
	MOV R0,STK00
	BANKSEL STK08
	MOV STK08,R0

	BANKSEL STK01
	MOV R0,STK01
	BANKSEL STK09
	MOV STK09,R0      ;// S7 S8 S9   pdest
	;/// 源起始偏移定位,最高位不会进位的，否则是错误的
	BANKSEL STK06
	MOV R0,STK06
	BANKSEL STK05
	MOV R1,STK05

	BANKSEL STK04
	ADD STK04,R0
	JNB PSW,0
	INC R1
	BANKSEL STK03
	ADD STK03,R1       ;//  S2 S3 S4  psrc

my_strfind_Flag_002:
;// R0(STK07)  STK00(STK08)  STK01(STK09)    STK02 STK03 STK04 （ STK05  STK06）
;///    i STK10   j STK11
	BANKSEL STK10
	CLR STK10     ;// i=0
	;;//#########################################################
	;;//#########################################################
	;;//#########################################################
while_Src_Exist_my_strfind:
	;///GetVaule2Begin
	BANKSEL STK04
	MOV R0,STK04
	BANKSEL STK10
	ADD R0,STK10
	BANKSEL STK01
	MOV STK01,R0

	BANKSEL STK03
	MOV R0,STK03
	JNB PSW,0
	INC R0
	BANKSEL STK00
	MOV STK00,R0

	BANKSEL STK02
	MOV R0,STK02  ;//  R S0 S1= psrc+i(S2 S2 S4)
    ;//get
    PAGESEL __gptrget1
    CALL   __gptrget1
    PAGESEL $
    XOR R0,#0x00
    JNB PSW,2
    JMP ReturnNoFine_my_strfind
    ;// while(psrc[i]!=0x00)
    BANKSEL STK11
    CLR STK11
    ;;//-------------------------------------------------------------------
Find_dest_Equ_my_strfind:
	;// getv2order
	BANKSEL STK04
	MOV R0,STK04
	BANKSEL STK01
	MOV STK01,R0

	BANKSEL STK03
	MOV R0,STK03
	BANKSEL STK00
	MOV STK00,R0

	BANKSEL STK10
	MOV R0,STK10
	BANKSEL STK11
	ADD R0,STK11
	JB PSW,0
	JMP my_strfind_Flag_0003
	BANKSEL STK00
	INC STK00
my_strfind_Flag_0003:
	BANKSEL STK01
	ADD STK01,R0
	JB PSW,0
	JMP my_strfind_Flag_0004
	BANKSEL STK00
	INC STK00
my_strfind_Flag_0004:
	BANKSEL STK02
	MOV R0,STK02		;//  R S0 S1= {S2 S3 S4 + i+j)
    PAGESEL __gptrget1
    CALL   __gptrget1
    PAGESEL $
    BANKSEL STK05
    MOV STK05,R0		;// bak in S5
    ;// getv1order
	BANKSEL STK09
	MOV R0,STK09
	BANKSEL STK01
	MOV STK01,R0

	BANKSEL STK08
	MOV R0,STK08
	BANKSEL STK00
	MOV STK00,R0

	BANKSEL STK11
	MOV R0,STK11

	BANKSEL STK01
	ADD STK01,R0
	JB PSW,0
	JMP my_strfind_Flag_0005
	BANKSEL STK00
	INC STK00
my_strfind_Flag_0005:
	BANKSEL STK07
	MOV R0,STK07	;// R0 S0 S1 = (S7 S8 S9 +j)
    PAGESEL __gptrget1
    CALL   __gptrget1
    PAGESEL $
    ;//if(   psrc[i+j]!=pdest[j]  )
    BANKSEL STK05
    XOR R0,STK05
    JB PSW ,2
    JMP my_strfind_Flag_0010  ;// goto  i++
    ;// R0(STK07)  STK00(STK08)  STK01(STK09)    STK02 STK03 STK04 （ STK05  STK06）
    ;///    i STK10   j STK11
    BANKSEL STK11
    INC STK11			;// j++

    ;// getv1order again  if(pdest[j]==0x00)
	BANKSEL STK09
	MOV R0,STK09
	BANKSEL STK01
	MOV STK01,R0

	BANKSEL STK08
	MOV R0,STK08
	BANKSEL STK00
	MOV STK00,R0

	BANKSEL STK11
	MOV R0,STK11

	BANKSEL STK01
	ADD STK01,R0
	JB PSW,0
	JMP my_strfind_Flag_0006
	BANKSEL STK00
	INC STK00
my_strfind_Flag_0006:
	BANKSEL STK07
	MOV R0,STK07		 ;//  R S0 S1= (S7 S8 S9 +j)
    PAGESEL __gptrget1
    CALL   __gptrget1
    PAGESEL $
    XOR R0,#0x00
    JB PSW,2
    JMP  my_strfind_Flag_0007
    BANKSEL STK10
    INCR STK10
    JMP my_strfind_END_Flag

my_strfind_Flag_0007:  ;//if(psrc[i+j]==0x00)
	;// getv2order
	BANKSEL STK04
	MOV R0,STK04
	BANKSEL STK01
	MOV STK01,R0

	BANKSEL STK03
	MOV R0,STK03
	BANKSEL STK00
	MOV STK00,R0

	BANKSEL STK10
	MOV R0,STK10
	BANKSEL STK11
	ADD R0,STK11
	JB PSW,0
	JMP my_strfind_Flag_0008
	BANKSEL STK00
	INC STK00
	my_strfind_Flag_0008:
	BANKSEL STK01
	ADD STK01,R0
	JB PSW,0
	JMP my_strfind_Flag_0009
	BANKSEL STK00
	INC STK00
	my_strfind_Flag_0009:
	BANKSEL STK02
	MOV R0,STK02		;// R S0 S1=(S2 S3 S4 + i+j)
	PAGESEL __gptrget1
	CALL   __gptrget1
	PAGESEL $
    XOR R0,#0x00
    JNB PSW,2
    JMP ReturnNoFine_my_strfind ;// R0自身是0,逻辑到最后返回
	JMP Find_dest_Equ_my_strfind
  my_strfind_Flag_0010:
    ;// i++
	BANKSEL STK10
	INC STK10
	JMP while_Src_Exist_my_strfind
	;//errfind  return 0
 ReturnNoFine_my_strfind:
	CLR R0
	;//#########################################################
my_strfind_END_Flag:
	__endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : mymemcpy
功能描述 : 内存拷贝
输入参数 : dest:目标地址
           src:源地址
           count:数据拷贝数量
返回参数 : src:数据处理完后的源地址
*****************************************************************************/
void *My_memcpy(void *dest, const void *src, unsigned char count)
{
#if 0
  unsigned char *pdest = (unsigned char *)dest;
  const unsigned char *psrc  = (const unsigned char *)src;
  unsigned char i;

  if(dest == NULL || src == NULL)
  {
    return NULL;
  }

  if((pdest <= psrc) || (pdest > psrc + count))
  {
    for(i = 0; i < count; i ++)
    {
      pdest[i] = psrc[i];
    }
  }
  else
  {
    for(i = count; i > 0; i --)
    {
      pdest[i - 1] = psrc[i - 1];
    }
  }

  return dest;
#else  // 节省约20RAM 200地址
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  ;//  *:R0(STK07)  STK00(STK08) STK01(STK09)   *: STK02(STK10) STK03 STK04   int:STK05

  ;//  因为函数的返回，记录RAM的返回地址(起始)信息到 STK11 ，仅记录地址，区不应该变，标记固定为0
  ;// 识别目标及源是否存在
  BANKSEL STK07
  MOV STK07,R0

  BANKSEL STK00
  ORL R0,STK00
  BANKSEL STK01
  ORL R0,STK01
  JNB PSW,2
  JMP Return0_my_memcpy_out

  BANKSEL STK02
  MOV R0,STK02
  BANKSEL STK03
  ORL R0,STK03
  BANKSEL STK04
  ORL R0,STK04
  JNB PSW,2
  JMP Return0_my_memcpy_out
  ;//标志
  BANKSEL STK06
  CLR STK06
  ;// 因涉及到指针内容的获取，并指针的赋值，需要使用参数R0 STK00 STK01 STK02,故参数转移
  BANKSEL STK00
  MOV R0, STK00
  BANKSEL STK08
  MOV STK08,R0

  BANKSEL STK01
  MOV R0, STK01
  BANKSEL STK09
  MOV STK09,R0
  BANKSEL STK11    ;// 函数返回需要的原始数据，，高2位内容具有指定性，已使用了最大的参数容量STK11，无额外可用
  MOV STK11,R0     ;//  即返回时 STK07 STK08 STK11  【过程仅STK09变化，因为目标只能是RAM，限定在一个区内】

  BANKSEL STK02
  MOV R0, STK02
  BANKSEL STK10
  MOV STK10,R0
  ;// 复制长度有效性判断
  BANKSEL STK05
  MOV R0,STK05
  ORL R0,#0x00
  JNB PSW,2
  JMP Return_my_memcpy_out

  DEC STK05  ;// 计算末尾开始转移的长度叠加量
  ;//
  ;// 识别目标，源的关系，绝对数据转移的起始位置
  ;// 目标比如为RAM ,源也是RAM,并在同一区转移分起始方向，否则
  MOV R0,STK09
  SUB R0,STK04   ;// R0=STK04-STK09
  JNB PSW,0
  JMP  DoGetAndSet_my_memcpy
  ;//  *:R0(STK07)  STK00(STK08) STK01(STK09)   *: STK02(STK10) STK03 STK04   char:STK05
  BANKSEL STK06
  INC STK06  ;// 复制方向更新  0-> 1

  BANKSEL STK05
  MOV R0,STK05

  BANKSEL STK09
  ADD STK09,R0
  JB PSW ,0
  JMP my_memcpy_label001
  BANKSEL STK08
  INC STK08
  my_memcpy_label001:
  BANKSEL STK04
  ADD STK04,R0
  JB PSW ,0
  JMP DoGetAndSet_my_memcpy
  BANKSEL STK03
  INC STK03 ;// 起始赋值指针地址执行末尾
  ;//
  DoGetAndSet_my_memcpy:
    BANKSEL STK05
    INC  STK05  ;// 还原的次数，到0的退出判断条件
  DoGetAndSet_my_memcpy_execute:
    ;//  *:R0(STK07)  STK00(STK08) STK01(STK09)   *: STK02(STK10) STK03 STK04   char:STK05
    BANKSEL STK04
    MOV R0,STK04
    BANKSEL STK01
    MOV STK01,R0

    BANKSEL STK03
    MOV R0,STK03
    BANKSEL STK00
    MOV STK00,R0

    BANKSEL STK10
    MOV R0,STK10
    PAGESEL __gptrget1
    CALL __gptrget1
    BANKSEL STK02
    MOV STK02,R0
    ;//  *:R0(STK07)  STK00(STK08) STK01(STK09)   *: STK02(STK10) STK03 STK04   char:STK05
    BANKSEL STK09
    MOV R0,STK09
    BANKSEL STK01
    MOV STK01,R0

    BANKSEL STK08
    MOV R0,STK08
    BANKSEL STK00
    MOV STK00,R0

    BANKSEL STK07
    MOV R0,STK07
    PAGESEL __gptrput1
    CALL  __gptrput1
    PAGESEL $
  ;// 循环控制
	   BANKSEL STK06
	   JNB STK06,0
	   JMP bigT0samll_my_memcpy
			   ;;// ++
			   BANKSEL STK09
			   INC STK09
			   JB PSW ,2
			   JMP my_memcpy_label002
			   BANKSEL STK08
			   INC STK08
		 my_memcpy_label002:
			   BANKSEL STK04
			   INC STK04
			   JB PSW ,2
			   JMP while_Count_control_my_memcpy
			   BANKSEL STK03
			   INC STK03 ;
	   JMP while_Count_control_my_memcpy
  bigT0samll_my_memcpy:
			   ;// --
			   MOV R0,#0xFF
			   BANKSEL STK09
			   ADD STK09,R0
			   JNB PSW ,0
			   JMP my_memcpy_label003
			   BANKSEL STK08
			   DEC STK08
		 my_memcpy_label003:
			   BANKSEL STK04
			   ADD STK04,R0
			   JNB PSW ,0
			   JMP while_Count_control_my_memcpy
			   BANKSEL STK03
			   DEC STK03 ;
			   JMP while_Count_control_my_memcpy
  while_Count_control_my_memcpy:
	   BANKSEL STK05
	   DECJZ STK05
	   JMP DoGetAndSet_my_memcpy_execute
  ;// 函数结束
  Return_my_memcpy_out:
	  BANKSEL STK08
	  MOV R0,STK08
	  BANKSEL STK00
	  MOV STK00,R0

	  BANKSEL STK11
	  MOV R0,STK11
	  BANKSEL STK01
	  MOV STK01,R0

	  CLR R0
	  JMP Return_my_memcpy_end
  ;// 空目标或源的返回空
  Return0_my_memcpy_out:
	  BANKSEL STK01
	  CLR STK01
	  BANKSEL STK00
	  CLR STK00
	  CLR R0
  Return_my_memcpy_end:
  __endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : Long_To_BigBytebuffer
功能描述 : 将int类型拆分四个字节，需要注意的是大小数据格式的转换  这里大格式转换小格式，
		芯片为小格式，可结构联合体之间用，不需要转换
输入参数 : number:4字节原数据;value:处理完成后4字节数据
返回参数 :无
****************************************************************************/
void Long_To_BigBytebuffer(unsigned long number,unsigned char value[4])
{
#if 0
  value[0] = number >> 24;
  value[1] = number >> 16;
  value[2] = number >> 8;
  value[3] = number & 0xff;
#else // 约节省15RAM 113地址
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  ;// 大数据格式转换
  ;// R0(STK06) STK00(STK07) STK01(STK08) STK02(STK09)  -    STK03  STK04  STK05
  ;// 转存
   BANKSEL STK06
   MOV STK06,R0

   BANKSEL STK00
   MOV R0,STK00
   BANKSEL STK07
   MOV STK07,R0

   BANKSEL STK01
   MOV R0,STK01
   BANKSEL STK08
   MOV STK08,R0

   BANKSEL STK02
   MOV R0,STK02
   BANKSEL STK09
   MOV STK09,R0
   ;// 赋值1
   BANKSEL STK06
   MOV R0,STK06
   BANKSEL STK02
   MOV STK02,R0

   BANKSEL STK05
   MOV R0,STK05
   BANKSEL STK01
   MOV STK01,R0
   BANKSEL STK04
   MOV R0,STK04
   BANKSEL STK00
   MOV STK00,R0
   BANKSEL STK03
   MOV R0,STK03
   PAGESEL __gptrput1
   CALL __gptrput1
   PAGESEL$
   ;// 赋值2
   BANKSEL STK07
   MOV R0,STK07
   BANKSEL STK02
   MOV STK02,R0
   ;// 优化 到RAM的转换，高位必然为0，中位为区信息，低位为地址，地址++不能进位
   BANKSEL STK05
   INC STK05
   MOV R0,STK05
   BANKSEL STK01
   MOV STK01,R0
   BANKSEL STK04
   MOV R0,STK04
   BANKSEL STK00
   MOV STK00,R0
   BANKSEL STK03
   MOV R0,STK03
   PAGESEL __gptrput1
   CALL __gptrput1
   PAGESEL$
   ;// 赋值3
   BANKSEL STK08
   MOV R0,STK08
   BANKSEL STK02
   MOV STK02,R0
   ;// 优化 到RAM的转换，高位必然为0，中位为区信息，低位为地址，地址++不能进位
   BANKSEL STK05
   INC STK05
   MOV R0,STK05
   BANKSEL STK01
   MOV STK01,R0
   BANKSEL STK04
   MOV R0,STK04
   BANKSEL STK00
   MOV STK00,R0
   BANKSEL STK03
   MOV R0,STK03
   PAGESEL __gptrput1
   CALL __gptrput1
   PAGESEL$
   ;// 赋值4
   BANKSEL STK09
   MOV R0,STK09
   BANKSEL STK02
   MOV STK02,R0
   ;// 优化 到RAM的转换，高位必然为0，中位为区信息，低位为地址，地址++不能进位
   BANKSEL STK05
   INC STK05
   MOV R0,STK05
   BANKSEL STK01
   MOV STK01,R0
   BANKSEL STK04
   MOV R0,STK04
   BANKSEL STK00
   MOV STK00,R0
   BANKSEL STK03
   MOV R0,STK03
   PAGESEL __gptrput1
   CALL __gptrput1
   PAGESEL$
  __endasm;
#pragma restore
#endif
}
/*****************************************************************************
函数名称 : BigByte_to_int
功能描述 : 将4字节合并为1个32bit变量   这里小格式转换大格式，
		芯片为小格式，可结构联合体之间用，不需要转换
输入参数 : value:4字节数组
返回参数 : number:合并完成后的32bit变量
****************************************************************************/
unsigned long BigByte_to_int(const unsigned char value[4])
{
#if 0
  unsigned long nubmer = 0;

  nubmer = (unsigned long)value[0];
  nubmer <<= 8;
  nubmer |= (unsigned long)value[1];
  nubmer <<= 8;
  nubmer |= (unsigned long)value[2];
  nubmer <<= 8;
  nubmer |= (unsigned long)value[3];

  return nubmer;
#else  // 约节省12RAM 142地址
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
  __asm
  ;// R0(STK02) STK00 STK01   大数据格式合并为long  STK03 STK04 STK05 STK06
  BANKSEL STK02
  MOV STK02,R0
  ;// 获取
  PAGESEL __gptrget1
  CALL __gptrget1
  PAGESEL$
  BANKSEL STK03
  MOV STK03,R0
  ;;// 优化RAM或Const的有效位数2字节的继续获取
  BANKSEL STK01
  INC STK01
  JB PSW,2
  JMP  ToGetVaule_byte_to_int1
  BANKSEL STK00
  INC STK00
 ToGetVaule_byte_to_int1:
  BANKSEL STK02
  MOV R0,STK02
  PAGESEL __gptrget1
  CALL __gptrget1
  PAGESEL$
  BANKSEL STK04
  MOV STK04,R0
  ;;// 优化RAM或Const的有效位数2字节的继续获取
  BANKSEL STK01
  INC STK01
  JB PSW,2
  JMP  ToGetVaule_byte_to_int2
  BANKSEL STK00
  INC STK00
 ToGetVaule_byte_to_int2:
  BANKSEL STK02
  MOV R0,STK02
  PAGESEL __gptrget1
  CALL __gptrget1
  PAGESEL$
  BANKSEL STK05
  MOV STK05,R0
  ;;// 优化RAM或Const的有效位数2字节的继续获取
  BANKSEL STK01
  INC STK01
  JB PSW,2
  JMP  ToGetVaule_byte_to_int3
  BANKSEL STK00
  INC STK00
 ToGetVaule_byte_to_int3:
  BANKSEL STK02
  MOV R0,STK02
  PAGESEL __gptrget1
  CALL __gptrget1
  PAGESEL$
  BANKSEL STK06
  MOV STK06,R0

  ;;// 函数返回  STK3-STK6 -> R0 STK00 STK01 STK02
  BANKSEL STK06
  MOV R0,STK06
  BANKSEL STK02
  MOV STK02,R0

  BANKSEL STK05
  MOV R0,STK05
  BANKSEL STK01
  MOV STK01,R0

  BANKSEL STK04
  MOV R0,STK04
  BANKSEL STK00
  MOV STK00,R0

  BANKSEL STK03
  MOV R0,STK03
  __endasm;
#pragma restore
#endif
}
