Hi-Tech memcpy
This routine is a substitution for the one in the Hi-Tech PICC compiler library.
The original has some limitations that I wanted to overcome:
1 - The data destination must always be in bank 0 or bank 1.
2 - If the data source is in program memory (retlw table) it must be 256 entries long or less, and it must not cross a 256 instruction address boundary.My version can copy data to any RAM bank, from any RAM bank or a retlw table, without any size or alignment restriction. Besides, it is over twice as fast as the original.
There are draw-backs tough:
1 - The parameter 'Dst' is declared 'const void *', when it should be declared 'void *', but a non-const pointer can point only to banks 0 and 1 or to banks 2 and 3, never to all banks. It's no problem if the programmer is a bit careful.
2 - the function returns 'void', where it should return 'void *'. I did this to save some RAM and execution time (I personally never used the return from memcpy, as it is the same destination pointer I already have). If one needs it the right way, it is easy to fix.Note:
If a pointer to program memory is passed to 'Dst', the function returns without doing nothing.
;============================================================================== ; Copyright (c) 2008, Isaac Marino Bavaresco ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: ; * Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; * Neither the name of the author nor the ; names of its contributors may be used to endorse or promote products ; derived from this software without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;============================================================================== ; isaacbavaresco@yahoo.com.br ;============================================================================== INDF equ 0 PCL equ 2 STATUS equ 3 FSR equ 4 PCLATH equ 10 ;=============================================================================== _memcpy$Dst set ?_memcpy+0 _memcpy$DstBnk set ?_memcpy+1 _memcpy$Src set ?_memcpy+2 _memcpy$SrcBnk set ?_memcpy+3 _memcpy$Len set ?_memcpy+4 ;=============================================================================== ; void memcpy( const void *Dst, const void *Src, unsigned char Len ) psect text0,local,class=CODE,delta=2 global _memcpy signat _memcpy,0x3078 fnsize _memcpy,0,5 global ?_memcpy _memcpy: clrf STATUS ;--------------------------------------------------------------- btfss _memcpy$DstBnk,7 ; if( !( Dst & 0x8000 )) DstInROM: return ; return; incf _memcpy$Len,f ;--------------------------------------------------------------- DstInRAM: btfsc _memcpy$SrcBnk,7 ; if( Src & 0x8000 ) goto SrcInRAMTest ;--------------------------------------------------------------- SrcInROM: btfsc _memcpy$DstBnk,0 bsf STATUS,7 movf _memcpy$Dst,w movwf FSR goto SrcInROMTest ;--------------------------------------------------------------- SrcInROMLoop: call LookUp movwf INDF pagesel $ incfsz _memcpy$Src,f goto $+2 incf _memcpy$SrcBnk,f incf FSR,f SrcInROMTest: decfsz _memcpy$Len,f goto SrcInROMLoop return ;--------------------------------------------------------------- LookUp: movf _memcpy$SrcBnk,w movwf PCLATH movf _memcpy$Src,w movwf PCL ;--------------------------------------------------------------- SrcInRAM: bcf STATUS,7 btfsc _memcpy$SrcBnk,0 bsf STATUS,7 movf _memcpy$Src,w movwf FSR movf INDF,w movwf btemp+0 bcf STATUS,7 btfsc _memcpy$DstBnk,0 bsf STATUS,7 movf _memcpy$Dst,w movwf FSR movf btemp+0,w movwf INDF incf _memcpy$Src,f incf _memcpy$Dst,f SrcInRAMTest: decfsz _memcpy$Len,f goto SrcInRAM return ;=============================================================================== psect temp,ovrld,class=BANK0,space=1 btemp ds 1 ;===============================================================================