| Purpose: |
Convert two (2) ASCII BYTEs into their hexadecimal equivalent value. |
| Assumes: |
The byte order is R25:R24, but they are two (2) ASCII BYTEs,
not a WORD. |
| Passed: |
R25 |
BYTE |
bHigh |
ASCII digit representing the MSByte (e.g., '1', 'a') |
| R24 |
BYTE |
bLow |
ASCII digit representing the LSByte (e.g., 'F', '9') |
| Returns: |
R24 |
BYTE |
bASCII |
Hexadecimal value corresponding to the 2 ASCII digits |
| T |
FLAG |
BIT_T |
CLEAR (0 or FALSE) if no error, SET (1 or TRUE) on error
An error is any digit NOT '0' to '9', 'A' to 'F', or 'a' to 'f' |
| Alters: |
Only R24, R25, and the FLAGs (SREG) |
| Notes: |
"Error" above means any unconvertable ASCII BYTE pair, i.e.,
not in the "00" to "FF" range.
An ASCIIz terminating NULL is a good example of using 'T' to signal
the end of convertable data. |
| Purpose: |
Convert the Low-Order NYBBLE of R24 to its UPPERCASE ASCII
character. |
| Assumes: |
Uppercase "A" through "F" are used rather than lowercase
AND The caller has saved the High-Order NYBBLE. |
| Passed: |
R24 |
BYTE |
bDigit |
the Low Nybble to be converted, i.e., to '0' to '9', 'A' to 'F' (none invalid) |
| Returns: |
R24 |
BYTE |
bASCII |
the ASCII character representing the LSNybble digit, 0x30 to 0x39, 0x41 to 0x46 |
| Alters: |
Only R24 and the FLAGs (SREG) |
| Notes: |
Only the LOW 4 bits of R24 are used so the caller must save
R24, swap, and call again to get both digits.
The bits in the MSNybble (Most Significant Nybble) of R24 are lost. |
Example Part 1: |
.ORG 0x1000
AResultBuffer = 0x0700
ASCIItoHex_Demo:
ADIW R26, 0 ; If 'X' is zero, the command line tail is
BRNE AASCIItoHex_Begin ; empty, so just exit
RET
ASCIItoHex_Begin:
ADIW R26, 1 ; Move 'X' past the initial space character
LDI R31, AResultBuffer >> 8 ; Point 'Z' at an aribitrary buffer in SRAM
LDI R30, AResultBuffer & 0xFF
ASCIItoHex_Loop:
LD R25, X+ ; R25 is the MSNybble, R24 is the LSNybble,
LD R24, X+ ; so this is reading the 2 ASCII digits
CALL AASCIIToHex ; Call the System Function to convert it
BRTC AASCIItoHex_Store ; Any unrecognized digit terminates the
LDI R24, 0 ; string; replace it with an ASCIIz NULL
ASCIItoHex_Store:
ST Z+, R24 ; Store the new BYTE, either converted or
BRTC AASCIItoHex_Loop ; or NULL terminator, and loop if former
; Fall through into UpperCase_Init |
Example Part 2: |
UpperCase_Init:
ADIW R30, 16 ; Align 'Z' so the last digit is 0 (e.g.,
ANDI R30, B11110000 ; 0x0720, called a "sentence" boundary)
MOVW R20, R30 ; Save it for the HexToASCII step below
LDI R27, AResultBuffer >> 8 ; Point to the BYTEs saved above
LDI R26, AResultBuffer & 0xFF
UpperCase_Loop:
LD R24, X+ ; Retrieve the next BYTE and convert it
CALL AUpperCase ; to its UPPERCASE equivalent
ST Z+, R24 ; Store it then see if it was the NULL
OR R24, R24 ; ASCIIs string terminator (assumes that
BRNE AUpperCase_Loop ; it was text); loop back if not a NULL
; Fall through into HexToASCII_Init |
Example Part 3: |
HexToASCII_Init:
ADIW R30, 16 ; Align 'Z' again to the next "sentence"
ANDI R30, B11110000
MOVW R26, R20 ; Initialize 'X' to the prior 'Z' start
HexToASCII_Loop:
LD R24, X+ ; Retrieve the next hex BYTE to convert
CPI R24, 0 ; If is it a NULL terminator (set by the
BREQ AHexToASCII_Ret ; Uppercase code above), exit the loop
MOV R25, R24 ; Save the BYTE just retrieved to R25
SWAP R24 ; Swap the MSNybble to the LSNybble and
CALL AHexToASCII ; convert it (MSNybble) to its ASCII
ST Z+, R24 ; equivalent and store it, advancing 'Z'
MOV R24, R25 ; Convert the Least Significant Nybble to
CALL AHexToASCII ; to its uppercase ASCII character and
ST Z+, R24 ; store it, again advancing 'Z' pointer
RJMP AHexToASCII_Loop ; Always loop back; exit check done above
HexToASCII_Ret:
ST Z, R24 ; Since R24 = 0 caused the loop to exit,
RET ; NULL terminate the string and return |
| Test all 3: |
m>EFS 0x700 0x7E 112 ; Fill the buffer with nonzero BYTEs
m>DS+ 0x700 112 ; The initial destination buffer contents:
SRAM contents:
0700: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0710: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0720: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0730: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0740: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0750: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
0760: 7E 7E 7E 7E 7E 7E 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ~~~~~~~~~~~~~~~~
m>@ 0x1000 44656d6f20737472696E67202D2031322c3334352e ; Note mixed case
m>DS+ 0x700 112 ; The results of all three (3) examples above:
SRAM contents:
0700: 44 65 6D 6F 20 73 74 72-69 6E 67 20 2D 20 31 32 Demo string - 12
0710: 2C 33 34 35 2E 00 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ,345..~~~~~~~~~~
0720: 44 45 4D 4F 20 53 54 52-49 4E 47 20 2D 20 31 32 DEMO STRING - 12
0730: 2C 33 34 35 2E 00 7E 7E-7E 7E 7E 7E 7E 7E 7E 7E ,345..~~~~~~~~~~
0740: 34 34 34 35 34 44 34 46-32 30 35 33 35 34 35 32 44454D4F20535452
0750: 34 39 34 45 34 37 32 30-32 44 32 30 33 31 33 32 494E47202D203132
0760: 32 43 33 33 33 34 33 35-32 45 00 7E 7E 7E 7E 7E 2C3334352E.~~~~~
m>
|
| Notes: |
Example Parts 1 through 3 above were all assembled from one file, at one
time, as a complete sequence, to generate the output shown above. |
|
Dropin: (setup code) |
; Setup for the ASCIIToHex() call:
; Passed: R25 BYTE bHigh ASCII digit representing the High Byte
; R24 BYTE bLow ASCII digit representing the Low Byte
; Returns: R24 BYTE bASCII Hexadecimal value for the R25:R24 ASCII digits
; 'T' FLAG BIT_T CLEAR if accepted, FALSE if either digit not hex
; Alters: R24, R25, and the FLAGs
; Setup for the HexToASCII() call:
; Passed: R24 BYTE bDigit Low Nybble to be converted to its ASCII equivalent
; Returns: R24 BYTE bASCII ASCII character representing LSNybble digit as hex
; Alters: R24 and the FLAGs
; Setup for the UpperCase() call:
; Passed: R25 BYTE bChar ASCII CHARacter to be examined and converted
; Returns: R24 BYTE bCHAR ASCII CHARacter, changed if 'a' (0x61) to 'z' (0x7A)
; Alters: R24 and the FLAGs |
| Also see: | - |