PrintEEPROMString,  PrintFLASHString,  and  PrintSRAMString

Purpose: Transmit a series of BYTEs out the COM1 console serial port.
Assumes:  Since these system calls can "block", interrupts will be enabled if they are disabled when called.
Passed: R25:R24  CHAR *   szPtrBuffer address of the EEPROM or SRAM or 328P FLASH buffer to output OR
R26:R25:R24  CHAR *   szPtrBuffer address of the 1284P or 2560 FLASH buffer to output
R22 BYTE bPrintCount number of BYTEs to be enbuffered, from 1 to 255 (zero is a special case; see the note below)
Returns:   R25:R24 CHAR * szPtrBuffer the same address passed, unchanged
R22 BYTE bPrintCount   the number of BYTEs that were enbuffered to be output
Alters: R20 and the FLAGs, in addition to R22, R24, and R25 returned
Example:  
BLength = ACopyToSRAM - AMultiLine
   .ORG  0x1000

   LDI     R25, 0               ; Point to the beginning of the customary Boot
   LDI     R24, 0xB0            ;   Initialiation strings in EEPROM (@ 0x00B0)
   LDI     R22, 27              ; Set the BYTE count
   RCALL   ALocalDumpRegs
   CALL    APrintEEPROMString   ; Output the text then, since that string has
   CALL    APrintNewLine        ;  no Carriage Return or Line Feed, print them
   RCALL   ALocalDumpRegs

   LDI     R25, 0               ; Point to the Copyright O.S. string in system
   LDI     R24, 4               ;  area of FLASH memory (@ 0x0004)
   LDI     R22, 165
   CALL    APrintFLASHString
   RCALL   ALocalDumpRegs

   RCALL   ACopyToSRAM          ; Call the local subroutine (below)
   LDI     R25, 7
   LDI     R24, 0
   LDI     R22, BLength         ; Use the calculated BYTE count
   RCALL   ALocalDumpRegs
   CALL    APrintSRAMString

LocalDumpRegs:
   JMP     ADumpRegs_Begin      ; A single, local, FAR jump used by all above

MultiLine: .STRING "Line #1\r\n"       ; Three strings, all NULL terminated,
           .STRING "Line #2\r\n"       ;  and having their own CR, LF endings
           .STRING "Line #3\r\n"

CopyToSRAM:
   LDI     R25, 7               ; The SRAM location: 0x700 - arbitrary, but
   LDI     R24, 0               ;  at the high end of the HEAP
   LDI     R23, AMultiLine >> 8 ; Pointer to the string above in FLASH
   LDI     R22, AMultiLine & 0xFF
   LDI     R21, 0               ; MSByte of the BYTE count WORD to copy
   LDI     R20, BLength         ; The BYTE count is a calculated value
   JMP     AmemcpyFLASH 
Test it:
m>@ 0x1000  ; One call does it all!

 10   32   54   76   98  1110 1312 1514 1716 1918 2120 2322 2524 2726 2928 3130  SP  RetAdd   SREG
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ------ --------
0000 0446 0975 FF28-0004 0000 0000 6000-0021 0000 0D10 081B-00B0 0000 0280 0800 08F5  1008  IthsvnZc
; Bootup Init: E 1 ~= 0xC0
0000 0446 0975 FF28-0004 0000 0000 6000-0021 0000 0DFE 081B-00B0 0000 0280 0800 08F5  1012  ItHSvNzC
Copyright, 2013-2021, SCADA Support Group, Inc.
Sonoma, CA 95476  ###.###.####
MIRTOS for 16 MHz Arduino Pro Mini
Version 3.01 - Monday, March 28, 2022
0000 0446 0975 FF28-0004 0000 0000 6000-0021 0000 0DFF 08A5-0004 0000 0280 0800 08F5  101E  IthsvnZc
0000 0446 0975 FF28-0004 0000 0000 6000-0021 0000 001E 001E-0700 001E 0280 0800 08F5  1028  IthsvnZc
Line #1
Line #2
Line #3
0000 0446 0975 FF28-0004 0000 0000 6000-0021 0000 0000 001E-0700 001E 0280 0800 08F7  6252  IthsvnZc
m>                                                                                                   
Notes: These routines are simply placing characters into the COM1 (or terminal) transmit buffer, a FIFO queue. They will only block if there is not room in the queue to enbuffer all of the characters. Any delay is due to waiting until enough characters are transmitted (i.e., removed from the queue) to make room for all of the new ones. These routines return as soon as all characters are enbuffered, leaving the actual output to be handled by the interrupt-driven print spooler.
If zero BYTEs are specified in R22, these routines become like the corresponding Print####ASCIIz routine, which calculate the string length (which could be zero.)
BYTEs with values of 0 through 6 or 0xFF are skipped.
The term "block" means that the subroutine does not return until its function is complete.
These routines internally call the COM1_Write System Function after determining the string length with the appropriate strlen function and specifying the string source.
The function name PrintPGMString is the same as PrintFLASHString.
The function name PrintRAMString is the same as PrintSRAMString.
Dropin: 
(setup
code)
;   Setup for the Print####String() call:
; Passed:  R25:R24 CHAR * szPtrBuffer 2-BYTE pointer to the string to print
;              R22 BYTE   bPrintCount number of BYTEs to be enbuffered
; Returns: R25:R24 CHAR * szPtrBuffer pointer to the string, unmodified
;              R22 BYTE   bPrintCount number of BYTEs placed in the print queue
; Alters:  R20 and the FLAGs

;   Setup for the 1284P or 2560 PrintFLASHString() call:
; Passed:  R26:R25:R24 CHAR * szPtrBuffer 3-BYTE pointer to the string to print
;                  R22 BYTE   bPrintCount number of BYTEs to be enbuffered
; Returns:     R25:R24 CHAR * szPtrBuffer pointer to the string, unmodified
;                  R22 BYTE   bPrintCount number of BYTEs placed in the print queue
; Alters:  R20 and the FLAGs
Also see:  The strlen, strlenEEPROM, and strlenPGM family, as well as the Print####ASCIIz family and the COM1 receive status, transmit status, read, write, and wait family of System Functions.