*/
Know a good article or link that we're missing? Submit it!
*/

View \ascii_utilities.c

Fast and Compact ASCII-binary Utilities - Keil Shell V1.0

Submitted By: Graham Cole
Rating: (Not rated) (Rate It)


#include "reg51.h"

//
//  Fast Binary To Uppercase ASCII Hexadcimal.
//
//  Author: Graham Cole
//
//  This function converts a value (in LS nibble of R7) in the range 0...15 to
//  the equivalent ASCII hexadacimal character in the range:
//
//      '0'-'9' or 'A'-'F'
//
//  The returned hexadecimal character is returned in the accumulator and, for
//  Keil compatibility, in the register R7.
//
//  An alternative entry point is provided for calls with the value in the LS
//  nibble of the accumulator.
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to an unused RET instruction.
//
//  The table look-up method used to effect the conversion is the most obvious
//  and quickest method. For some applications, the small price of extra code
//  space required for the table of characters is worth paying. However,
//  overwriting the DPTR is a significant disadvantage.
//

#pragma ASM

    $REGUSE _fast_binary_to_uppercase_ascii_hexadcimal( A, PSW, R7 )

#pragma ENDASM

char fast_binary_to_uppercase_ascii_hexadcimal( char value )
{
    value = value;                          // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R7                        ;
                                            ;
fast_binary_to_uppercase_ascii_hexadcimal:  ;
                                            ;
        ANL     A,#0x0F                     ;
                                           
        ADD     A,#( ?fbtuah_table_address - ?fbtuah_table_read ) - 1
                                           
?fbtuah_table_read:                         ;
                                            ;
        MOVC    A,@A+PC                     ;
        MOV     R7,A                        ;
        RET                                 ;
                                            ;
?fbtuah_table_address:                      ;
                                           
        DB      '0','1','2','3','4','5','6','7'
        DB      '8','9','A','B','C','D','E','F'

    #pragma ENDASM

    return( value );                        // Dummy return.
}

//
//  Fast Binary To Eithercase ASCII Hexadcimal.
//
//  Author: Graham Cole
//
//  This function converts a value (in LS nibble of R7) in the range 0...15 to
//  the equivalent ASCII hexadacimal character in the range:
//
//      '0'-'9' or 'A'-'F' or 'a'-'f'
//
//  The flag indicating that lowercase characters are required is passed in
//  register R5. Any non-zero vale will cause a lowercase character to be
//  returned. The returned hexadecimal character is returned in the accumulator
//  and, for Keil compatibility, in the register R7.
//
//  An alternative entry point is provided for calls with the value in the LS
//  nibble of the accumulator and the lowercase flag in F0 (i.e. PSW.5).
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to an unused RET instruction.
//
//  The table look-up method used to effect the conversion is the most obvious
//  and quickest method. For some applications, the small price of extra code
//  space required for the table of characters is worth paying. However,
//  overwriting the DPTR is a significant disadvantage.
//

#pragma ASM

    $REGUSE _fast_binary_to_eithercase_ascii_hexadcimal( A, PSW, R7 )

#pragma ENDASM

char fast_binary_to_eithercase_ascii_hexadcimal( char value, char lowercase )
{
    value = value;                          // Supress UNUSED warning.
    lowercase = lowercase;                  // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R5                        ;
        ADD     A,#0xFF                     ;
        MOV     F0,C                        ;
        MOV     A,R7                        ;
                                            ;
fast_binary_to_eithercase_ascii_hexadcimal: ;
                                            ;
        ANL     A,#0x0F                     ;
                                           
        ADD     A,#( ?fbteah_table_address - ?fbteah_table_read ) - 1
                                           
?fbteah_table_read:                         ;
                                            ;
        MOVC    A,@A+PC                     ;
        JNB     F0,?fbteah_skip             ;
        SETB    Acc.5                       ;
                                            ;
?fbteah_skip:                               ;
                                            ;
        MOV     R7,A                        ;
        RET                                 ;
                                            ;
?fbteah_table_address:                      ;
                                           
        DB      '0','1','2','3','4','5','6','7'
        DB      '8','9','A','B','C','D','E','F'

    #pragma ENDASM

    return( value );                        // Dummy return
}

//
//  Compact Binary To Uppercase ASCII Hexadcimal.
//
//  Author: Graham Cole
//
//  This function converts a value (in LS nibble of R7) in the range 0...15 to
//  the equivalent ASCII hexadacimal character in the range:
//
//      '0'-'9' or 'A'-'F'
//
//  The returned hexadecimal character is returned in the accumulator and, for
//  Keil compatibility, in the register R7.
//
//  An alternative entry point is provided for calls with the value in the LS
//  nibble of the accumulator.
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to the RET instruction.
//
//  The trick of using a combination of ADD and DA instructions to perform this
//  conversion is an old one that I belive predates the 8051 and, as far as I
//  know, the original author is lost to history. The technique is compact and
//  only slightly slower than the table look-up method.
//

#pragma ASM

    $REGUSE _compact_binary_to_uppercase_ascii_hexadcimal( A, PSW, R7 )

#pragma ENDASM

char compact_binary_to_uppercase_ascii_hexadcimal( char value )
{
    value = value;                          // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R7                        ;
                                           
compact_binary_to_uppercase_ascii_hexadcimal:
                                           
        ANL     A,#0x0F                     ;
        ADD     A,#0x90                     ;
        DA      A                           ;
        ADDC    A,#0x40                     ;
        DA      A                           ;
        MOV     R7,A                        ;

    #pragma ENDASM

    return( value );
}

//
//  Compact Binary To Lowercase ASCII Hexadcimal.
//
//  Author: Graham Cole
//
//  This function converts a value (in LS nibble of R7) in the range 0...15 to
//  the equivalent ASCII hexadacimal character in the range:
//
//      '0'-'9' or 'a'-'f'
//
//  The returned hexadecimal character is returned in the accumulator and, for
//  Keil compatibility, in the register R7.
//
//  An alternative entry point is provided for calls with the value in the LS
//  nibble of the accumulator.
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to the RET instruction.
//
//  The trick of using a combination of ADD and DA instructions to perform this
//  conversion is an old one that I belive predates the 8051 and, as far as I
//  know, the original author is lost to history. The technique is compact and
//  only slightly slower than the table look-up method.
//

#pragma ASM

    $REGUSE _compact_binary_to_lowercase_ascii_hexadcimal( A, PSW, R7 )

#pragma ENDASM

char compact_binary_to_lowercase_ascii_hexadcimal( char value )
{
    value = value;                          // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R7                        ;
                                           
compact_binary_to_lowercase_ascii_hexadcimal:
                                           
        ANL     A,#0x0F                     ;
        ADD     A,#0x90                     ;
        DA      A                           ;
        ADDC    A,#0x40                     ;
        DA      A                           ;
        SETB    Acc.5                       ;
        MOV     R7,A                        ;

    #pragma ENDASM

    return( value );
}


//
//  Compact Binary To Eithercase ASCII Hexadcimal.
//
//  Author: Graham Cole
//
//  This function converts a value (in LS nibble of R7) in the range 0...15 to
//  the equivalent ASCII hexadacimal character in the range:
//
//      '0'-'9' or 'A'-'F' or 'a'-'f'
//
//  The flag indicating that lowercase characters are required is passed in
//  register R5. Any non-zero vale will cause a lowercase character to be
//  returned. The returned hexadecimal character is returned in the accumulator
//  and, for Keil compatibility, in the register R7.
//
//  An alternative entry point is provided for calls with the value in the LS
//  nibble of the accumulator and the lowercase flag in F0 (i.e. PSW.5).
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to the RET instruction.
//
//  The trick of using a combination of ADD and DA instructions to perform this
//  conversion is an old one that I belive predates the 8051 and, as far as I
//  know, the original author is lost to history. The technique is compact and
//  only slightly slower than the table look-up method.
//

#pragma ASM

    $REGUSE _compact_binary_to_eithercase_ascii_hexadcimal( A, PSW, R7 )

#pragma ENDASM

char compact_binary_to_eithercase_ascii_hexadcimal( char value, char lowercase )
{
    value = value;                          // Supress UNUSED warning.
    lowercase = lowercase;                  // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R5                        ;
        ADD     A,#0xFF                     ;
        MOV     F0,C                        ;Copy lowercase flag to F0 (in PSW)
                                            ;
        MOV     A,R7                        ;Copy value to accumulator.
                                           
compact_binary_to_eithercase_ascii_hexadcimal:
                                           
        ANL     A,#0x0F                     ;
        ADD     A,#0x90                     ;
        DA      A                           ;
        ADDC    A,#0x40                     ;
        DA      A                           ;
        JNB     F0,?cbteah_skip             ;
        SETB    Acc.5                       ;
                                            ;
?cbteah_skip:                               ;
                                            ;
        MOV     R7,A                        ;

    #pragma ENDASM

    return( value );
}

//
//  Fast ASCII Hexadcimal to binary
//
//  Author: Graham Cole
//
//  This function converts a hexadecimal character in the range below to the
//  equivalent binary value in the range 0...15:
//
//      '0'-'9' or 'A'-'F' or 'a'-'f'
//
//  The value is returned in in LS nibble of R7 (for Keil compatibility).
//
//  An alternative entry point is provided for calls with the hexadecimal
//  character in the accumulator.
//
//  The first line of C code will suppress the UNUSED variable warning and the
//  Keil C51 compiler will optimise this code out. The return() statement is
//  compiled to the RET instruction.
//

#pragma ASM

    $REGUSE _fast_ascii_hexadecimal_to_binary( A, PSW, R7 )

#pragma ENDASM

char fast_ascii_hexadecimal_to_binary( char character )
{
    character = character;                  // Supress UNUSED warning.

    #pragma ASM

        MOV     A,R7                        ;
                                            ;
fast_ascii_hexadecimal_to_binary:           ;
                                            ;
        MOV     C,Acc.6                     ;C set for 'A'-'F' or 'a'-'f'
        ANL     A,#0x0F                     ;
        JNC     ?fahtb_skip                 ;
        ADD     A,#0x09                     ;
                                            ;
?fahtb_skip:                                ;
                                            ;
        MOV     R7,A                        ;
                                            ;
    #pragma ENDASM

    return( character );
}

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.