FormatULONGHex

Purpose: Generate a character string that is the hexadecimal representation of the UNSIGNED LONG INTEGER value passed.
Optionally print and/or copy the string generated.
Assumes: There is sufficient buffer space if copying is enabled (maximum 12 BYTEs, e.g., "0x12345678 ", NULL.)
Passed: R25:R24:R23:R22  ULONG ulValue value to be formatted
R21:R20 BYTE *   bPtrBuffer starting SRAM address at which to generate output; NULL omits copying
R18 BYTE bFlags option BITs BIT_FMT_PRE_0x, BIT_FMT_POST_Sp, and BIT_FMT_PRINT.
R16 BYTE bDigitCount   desired number of hex digits (1 to 8); if any other value, set by this routine.
Be sure the save and restore R16, a System Variable.
Returns:   Nothing.
Alters: SREG (the FLAGs) and possibly the caller's buffer and/or the print buffer; all other Registers are preserved.
Example:  
.ORG  0x1000

   ADIW    R26, 0               ; If 'X' is zero, the command line has nothing
   BREQ    ALocal_Ret           ;  to be checked, so just exit immediately
   MOVW    R24, R26
   CALL    AParseValue
   SBRS    R21, BIT_PV_VALID    ; If a string was passed but there was no value
Local_Ret:                      ;  that could be parsed from it, also exit
   RET

   PUSH    R16                  ; Must preserve R16, a System Variable
   LDI     R16, 0               ; Setting R16 = 0 means suppress leading zeros
   ADIW    R26, 0               ; If no additional parameters, we're ready
   BREQ    ASetSRAMPointer      ;  to call the FormatULONGHex() function

   PUSH    R25                  ; Save the high order BYTEs on the stack during
   PUSH    R24                  ;  the second value parsing call
   MOVW    R30, R22             ; Save the low order BYTEs in the R31:R30 pair,
   MOVW    R24, R26             ;  which is preserved by ParseValue()
   CALL    AParseValue
   MOV     R16, R22             ; Transfer the desired hex digit count to R16
   MOVW    R22, R30
   POP     R24                  ; Restore the ULONG value to R25:R24:R23:R22 
   POP     R25

SetSRAMPointer:
   LDI     R21, 7               ; Set the copy pointer to SRAM address 0x0708
   LDI     R20, 8
   LDI     R18, (1 << BIT_FMT_PRINT) | (1 << BIT_FMT_PRE_0x)
   CALL    AFormatULONGHex      ; Select both copy and print with "0x" prefix
   POP     R16                  ; Restore the System Variable that was needed
   JMP     APrintNewLine
Test it:
m>DS+ 0x700 32         ; The copy buffer area is initally all zeros
SRAM contents:
0700:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0710:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>@ 0x1000 1234        ; Command with no hex digit count parameter
0x4D2
m>ds+ 0x700 32         ; The string was also copied to the buffer:
SRAM contents:
0700:  00 00 00 00 00 00 00 00-30 78 34 44 32 00 00 00  ........0x4D2...
0710:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>@ 0x1000 1234 0      ; Less than 1 hex digit reverts to default
0x4D2
m>@ 0x1000 1234 1      ; 1 hex digit discards any digit 2 through 8
0x2
m>@ 4096 1234 2        ; 2 hex digits again, clips off higher ones
0xD2
m>@ 4096 1234 3
0x4D2
m>@ 0x1000 1234 4
0x04D2
m>@ 0x1000 1234 5
0x004D2
m>@ 0x1000 1234 6
0x0004D2
m>DS+ 0x700 32         ; Display the SRAM buffer again this time
SRAM contents:
0700:  00 00 00 00 00 00 00 00-30 78 30 30 30 34 44 32  ........0x0004D2
0710:  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
m>@ 4096     1234 7
0x00004D2
m>@ 4096    1234   8   ; The maximum number of hex digits is 8
0x000004D2
m>@ 4096   1234  9     ; Greater than 8 reverts to the default as well
0x4D2
m>                                                                              
Notes: This routine creates a local buffer using StackAlloc50, into which the string is generated.
From that local buffer, it is then copied, or printed, or both (or neither.)
Using a bDigitCount value less than 0 or greater than 8 causes the "leading zeroes suppressed" format to be used.
The BIT_FMT_PRE_0x bit causes the "0x" string to be printed before the first digit.
The BIT_FMT_POST_Sp bit pads a space character after the last numeric digit.
The BIT_FMT_PRINT causes the string to be transferred into the COM1 serial port buffer.
Dropin: 
(setup
code)
;   Setup for the FormatULONGHex() call:
; Passed:  R25:R24:R23:R22 ULONG  ulValue to be formatted
;                  R21:R20 BYTE * bPtrBuffer pointer to the SRAM buffer or NULL            
;                      R18 BYTE   bFlags (BIT_FMT_... PRE_0x, POST_Sp & PRINT)
;                      R16 BYTE   bDigitCount desired hex digit count (1 to 8)
; Returns: Nothing.
; Alters:  Only the FLAGs and the copy and/or print buffer(s) selected
; Note:    The value of R16 must be preserved (e.g., PUSH and POP)
Also see:  The FormatULONG, FormatWORD, and FormatCopyAndPrint System Functions.