memcpyPGM  or  memcpyFLASH

Purpose: Copy a block of data from PROGRAM memory, or FLASH, to a buffer in SRAM.
Assumes:  bPtrTo and bPtrFrom are valid.
Passed:     R25:R24  BYTE *   bPtrTo the SRAM destination address
R23:R22  BYTE *   bPtrFrom the 328P FLASH source address   OR
R26:R23:R22  BYTE *   bPtrFrom the 1284P or 2560 FLASH source address
R21:R20  WORD wCount number of BYTEs to copy
Returns: R25:R24  BYTE *   bPtrStart the caller's bPtrTo value (unmodified)
R23  BYTE bLast the data value of the last BYTE copied
Alters: R25, R26, R27, the FLAGs, and the SRAM block referenced.
Example: 
.ORG 0x1000

FLASHtoSRAMTest:
   MOVW    R24, R26             ; Copy the pointer to the address passed to us
   CALL    AParseValue          ; Always returns a ULONG in R25:R24:R23:R22
   SBRS    R21, BIT_PV_VALID
   RET                          ; Exit if destination address not found

   MOVW    R30, R22             ; Save only the 16-bit bPtrToSRAM
   MOVW    R24, R26             ; The address of the "next" string to parse was
   CALL    AParseValue          ;  returned in R27:R26, so parse parameter #2
   SBRS    R21, BIT_PV_VALID
   RET                          ; Exit if no source address was found

   PUSH    R23                  ; Save the 16-bit bPtrFromPGM on the stack
   PUSH    R22
   MOVW    R24, R26             ; Load the pointer to the third substring
   CALL    AParseValue          ; Transfer source FLASH address to R25:R24
   POP     R24                  ; Must POP before checking validity; put source
   POP     R25                  ;  into R25:R24 for a moment, since MSWord of
   SBRS    R21, BIT_PV_VALID    ;  the value returned is not needed
   RET

   MOVW    R20, R22             ; Set the last parsed value: the BYTE count
   MOVW    R22, R24             ; This is the FLASH source address
   MOVW    R24, R30             ; This is the SRAM destination address
   JMP     AmemcpyPGM           ; All that to do this one thing
Test it:
m>DP+ 0x3A00 64
FLASH (program memory) contents:
3A00:  4A 65 73 75 73 20 69 73-20 4C 4F 52 44 21 00 43  Jesus is LORD!.C
3A10:  61 75 73 65 20 6F 66 20-74 68 65 20 6C 61 73 74  ause of the last
3A20:  20 72 65 73 65 74 3A 20-00 69 6E 69 74 69 61 6C   reset: .initial
3A30:  20 70 6F 77 65 72 2D 75-70 00 65 78 74 65 72 6E   power-up.extern
m>DS+ 0x5F0 48
SRAM contents:
05F0:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0600:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0610:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>@ 0x1000 0x600 0x3A00 15  ; Syntax: To SRAM, from FLASH, BYTE count
m>DR+ 0x5F0 48
SRAM contents:
05F0:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0600:  4A 65 73 75 73 20 69 73-20 4C 4F 52 44 21 00 00  Jesus is LORD!..
0610:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>                                                                              
Notes: The bPtrTo and bPtrFrom values are not checked for validity.
The wCount is not limited but is initally checked for zero, and if it is zero, the System Function exits immediately without copying anything.
Dropin: 
(setup
code)
;   Setup for the memcpyPGM() or mcmcpyFLASH() call:
; Passed:      R25:R24 BYTE * bPtrTo   pointer to the SRAM destination buffer
;              R23:R22 BYTE * bPtrFrom pointer to the 328P FLASH data source  OR
;          R26:R23:R22 BYTE * bPtrFrom pointer to the 1284P or 2560 FLASH data source
;              R21:R20 WORD   wCount   number of BYTEs to copy
; Returns:     R25:R24 BYTE * bPtrTo   the caller's bPtrTo value (unmodified)
;  (Also):         R23 BYTE   bLast    the data value of the last BYTE copied
; Alters:  R25, R26, R27, the FLAGs, and the SRAM block referenced
Also see:  The memcpy, memcpyEEPROM, memcpySRAMtoEEPROM, and memcpyEEPROMtoEEPROM, System Functions and the EIF or EIP (in Edit) System Command.