strcpyPGM  or  strcpyFLASH

Purpose: Copy an ASCIIz string from FLASH to an SRAM buffer.
The source string in FLASH can be a zero length string, in which case only a single BYTE is copied.
The system function strlenPGM is used to determine the string length, then limited to 254 BYTEs.
Assumes:  szPtrToSRAM and szPtrFromFLASH contain valid addresses.
The string to copy from FLASH is less than 255 characters in length.
The string ends in 0x00, 0xFE, or 0xFF BYTE values.
Any other BYTE value (1 to 253 = 0xFD) is considered to be part of the string.
There destination buffer has room for the string, which cannot exceed 255 bytes.
Passed:     R25:R24  CHAR *   szPtrToSRAM the SRAM destination address
R23:R22  CHAR *   szPtrFromFLASH   the 328P FLASH source address OR
R26:R23:R22  CHAR *   szPtrFromFLASH   the 1284P or 2560 FLASH source address
Returns: R25:R24  CHAR *   szPtrTo the caller's szPtrToSRAM value (unmodified)
Alters: R22, R23, R26, R27, R30, R31, the FLAGs and the SRAM buffer
Example: 
.ORG  0x1000

CopyFromFLASH:
   ADIW    R26, 0                 ; If 'X' is zero, the command line has nothing
   BREQ    ACopyFromFLASH_Ret     ;  to be checked, so just exit immediately
   MOVW    R24, R26               ; Transfer the buffer pointer to R25:R24 and
   LDI     R22, ' '               ;  set the search character in R22, then try
   CALL    AParseValueAfter       ;  to parse a value after the first space
   SBRS    R21, BIT_PV_VALID      ; Exit if the parser says "nothing there"

CopyFromFLASH_Ret:
   RET

   MOVW    R30, R22               ; The first value parsed is the SRAM address
   MOVW    R24, R26               ; Point to the BYTE after the parsed string
   CALL    AParseValue            ;  to parse a value after the first space
   SBRS    R21, BIT_PV_VALID
   RET                            ; If valid, R23:R22 has the FLASH data source

   MOVW    R24, R30               ; Set the destination SRAM address from 'Z'
   JMP     AstrcpyPGM             ; Copy the string from FLASH to SRAM and exit
Test it:
>DS+ 0x600 80
SRAM contents:
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  ................
0620:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0630:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0640:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
>DP+ 0x3F70 80
FLASH (program memory) contents:
3F70:  20 50 72 6F 20 4D 69 6E-69 0D 0A 56 65 72 73 69   Pro Mini..Versi
3F80:  6F 6E 20 33 2E 30 31 20-2D 20 4D 6F 6E 64 61 79  on 3.01 - Monday
3F90:  2C 20 4D 61 72 63 68 20-32 38 2C 20 32 30 32 32  , March 28, 2022
3FA0:  0D 0A 00 00 00 00 00 00-00 00 00 00 00 00 CA 9A  ................
3FB0:  3B 00 E1 F5 05 80 96 98-00 40 42 0F 00 A0 86 01  ;........@B.....
> ; Login to use the indirect subroutine call (the '@' command)
m>EIF 0x610 0x3F7B 40  ; Syntax: edit, SRAM dest, FLASH memory source, count
m>DS+ 0x600 80
SRAM contents:
0600:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0610:  56 65 72 73 69 6F 6E 20-33 2E 30 31 20 2D 20 4D  Version 3.01 - M
0620:  6F 6E 64 61 79 2C 20 4D-61 72 63 68 20 32 38 2C  onday, March 28,
0630:  20 32 30 32 32 0D 0A 00-00 00 00 00 00 00 00 00   2022...........
0640:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>                                                                              
Notes: An ASCIIz string is a series of printable characters, terminated with a NULL (= 0) BYTE.
The szPtrToSRAM and szPtrFromFLASH values are not checked for validity.
Dropin: 
(setup
code)
;   Setup for the strcpyPGM() or strcpyFLASH() call:
; Passed:      R25:R24 CHAR * szPtrToSRAM    pointer to the SRAM buffer
;              R23:R22 CHAR * szPtrFromFLASH pointer to the 328P FLASH source string  OR
;          R26:R23:R22 CHAR * szPtrFromFLASH pointer to string in 1284P or 2560 FLASH
; Returns:     R25:R24 CHAR * the caller's szPtrTo value (unmodified)
; Assumes: The desination SRAM buffer has room for the string
; Alters:  R22, R23, R26, R27, R30, R31, the FLAGs and the SRAM buffer
Also see:  The memcpyPGM, strcmpPGM, strlenPGM, memcpy, strcpy, strlen, and memcpyEEPROM System Functions as well as the EIF (in Edit) System Command.