ParseValue  and  ParseValueAfter

Purpose: Convert character string text to the numeric value it represents. Update the string pointer to be able to move through a sequence of numeric values in the same buffered string, typically separated by spaces or commas. Allow the two special strings beginning with either 'M' or 'S' (e.g., "m", "M", "mSec", "mS", "S", "s", "Seconds", etc.) to return the ULONG values of system values millis and SystemSeconds.
Assumes: The string may or may not contain a text representation of a number. If it does not, return "no more strings" so parsing ends there. Each substring may contain text in either Decimal or Hexadecimal format. Accept either.
Passed: R25:R24  CHAR *   cPtrBuffer   pointer to buffer to examine
R22 CHAR cDelimiter character, after which a string or strings to parse may follow (only for ParseValueAfter)
Returns:   R25:R24:R23:R22 LONG lValue 4-byte data value read (or BYTE in R22, or WORD in R23:R22)
R27:R26 CHAR * szPtrNext pointer to the next byte to parse (or NULL if there are no more)
R21 BYTE bFlags bits which indicate the status, specifically these 5:
  BIT_PV_VALID - TRUE if R25:R24:R23:R22 contains a parsed value
  BIT_PV_HEX - TRUE if the value was in hexadecimal format
  BIT_PV_NONZERO - TRUE if the value was NOT zero
  BIT_PV_OVERFLOW - TRUE if larger than 0xFFFFFFFF
  BIT_PV_NEGATIVE - TRUE if the value was negative
Uses: R8 (bFlags_OS) BIT_OS_PARSE_HEX (= BIT 3 = B00001000) to parse as a hexadecimal value without needing the "0x" prefix
Alters: R18 through R20, in addition to R21 through R27 returned (R28 to R31 are preserved)
Example: 
ParsingTest:                    ; Assume R25:R24 points to the buffer
   LDI     R22, ' '             ; To skip past the byte count and command byte,
   CALL    AParseValueAfter     ;  look for the first space and parse the value
   RJMP    APT_Merge            ;  after the space, jumping into the loop

PT_Loop:
   MOVW    R24, R26             ; Point to the next buffer to be examined
   CALL    AParseValue          ; Extract one numeric value from the string

PT_Merge:
   CALL    ADumpRegs_Begin      ; Display the results in the Registers
   SBRS    R21, BIT_PV_VALID    ; If no value was parsed, just exit after
   RJMP    APT_Exit             ;  displaying the results
   ADIW    R26, 0               ; See if a NULL pointer was returned; loop
   BRNE    APT_Loop             ;  back if not to parse the next substring

PT_Exit:
   RET
Notes: Any character except these: +-0123456789ABCDEFabcdefMmSsXx, (e.g., space, equal sign, colon) are either ignored (discarded) if they lead the data field or end parsing if they trail the field. A NULL byte, a semicolon, or error always ends parsing whenever it they occur. A semicolon begins a comment (unless it is inside a quoted string), so anything after it on a line being parsed is discarded.
Dropin: 
(setup
code)
;   Setup for the ParseValueAfter() call:
; Passed:          R25:R24 CHAR * szPtrBuffer pointer to buffer to examine
;                      R22 CHAR   cDelimiter character; the data string follows it
; Returns: R25:R24:R23:R22 LONG   lData   4-byte data value read
;   (also)         R27:R26 CHAR * szPtrNext pointer to next byte to parse (or NULL)
;                      R21 BYTE   bFlags  indicating status; only these 5 bits:
;                           BIT_PV_VALID     = BIT 0 = B00000001 =   1
;                           BIT_PV_HEX       = BIT 2 = B00000100 =   4
;                           BIT_PV_NONZERO   = BIT 3 = B00001000 =   8
;                           BIT_PV_OVERFLOW  = BIT 4 = B00010000 =  16
;                           BIT_PV_NEGATIVE  = BIT 7 = B10000000 = 128
; Alters:  R18, R19, and R20 (in addition to R21 through R27 above) are changed
; Uses:    R8 (bFlags_OS), BIT_OS_PARSE_HEX (= BIT 3 = B00001000) to parse as hex


;   Setup for the ParseValue() call:
; Same as ParseValueAfter() above, except any character passed in R22 is ignored
Also see:  File CommonDefs.Def contains the BIT_PV_* definitions.
Examine the parsing test command output, invoked using '9', e.g., "9 2 42 0 Sec -1 0x2 mSec 0x123".