Convert 32-bit Binary to ASCII Number String by BigDumbDinosaur
[Up to Source Code Repository]


Convert ASCII Number String to 32-bit Binary

This program converts 32-bit binary back to an ASCII string. It is a companion to Convert ASCII Number String to 32-bit Binary.

A subroutine in this program makes use of the MPU's decimal mode. Since decimal mode is not cleared following an interrupt on an NMOS processor, there are notes in the code warning about it. Please see them below.

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;*                                                                             *
;*                CONVERT 32-BIT BINARY TO ASCII NUMBER STRING                 *
;*                                                                             *
;*                             by BigDumbDinosaur                              *
;*                                                                             *
;* This 6502 assembly language program converts a 32-bit unsigned binary value *
;* into a null-terminated ASCII string whose format may be in  binary,  octal, *
;* decimal or hexadecimal.                                                     *
;*                                                                             *
;* --------------------------------------------------------------------------- *
;*                                                                             *
;* Copyright (C)1985 by BCS Technology Limited.  All rights reserved.          *
;*                                                                             *
;* Permission is hereby granted to copy and redistribute this software,  prov- *
;* ided this copyright notice remains in the source code & proper  attribution *
;* is given.  Any redistribution, regardless of form, must be at no charge  to *
;* the end user.  This code MAY NOT be incorporated into any package  intended *
;* for sale unless written permission has been given by the copyright holder.  *
;*                                                                             *
;* THERE IS NO WARRANTY OF ANY KIND WITH THIS SOFTWARE.  It's free, so no mat- *
;* ter what, you're getting a great deal.                                      *
;*                                                                             *
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
;	CALLING SYNTAX:
;
;	        LDA #RADIX         ;radix character, see below
;	        LDX #<OPERAND      ;binary value address LSB
;	        LDY #>OPERAND      ;binary value address MSB
;	        (ORA #%10000000)   ;radix suppression, see below
;	        JSR BINSTR         ;perform conversion
;	        STX ZPPTR          ;save string address LSB
;	        STY ZPPTR+1        ;save string address MSB
;	        TAY                ;string length
;	LOOP    LDA (ZPPTR),Y      ;copy string to...
;	        STA MYSPACE,Y      ;safe storage, will include...
;	        DEY                ;the terminator
;	        BPL LOOP
;
;	CALLING PARAMETERS:
;
;	.A      Conversion radix, which may be any of the following:
;
;	        '%'  Binary.
;	        '@'  Octal.
;	        '$'  Hexadecimal.
;
;	        If the radix is not one of the above characters decimal will be
;	        assumed.  Binary, octal & hex conversion will prepend the radix
;	        character to the string.  To suppress this feature set bit 7 of
;	        the radix.
;
;	.X/.Y   The address of the 32-bit binary value (operand) that is to be
;	        converted.  The operand must be in little-endian format.
;
;	REGISTER RETURNS:
;
;	.A      The printable string length.  The exact length will depend on
;	        the radix that has been selected, whether the radix is to be
;	        prepended to the string & the number of significant digits.
;	        Maximum possible printable string lengths for each radix type
;	        are as follows:
;
;	        %  Binary   33
;	        @  Octal    12
;	           Decimal  11
;	        $  Hex       9
;
;	.X/.Y   The LSB/MSB address at which the null-terminated conversion
;	        string will be located.  The string will be assembled into a
;	        statically allocated buffer and should be promptly copied to
;	        user-defined safe storage.
;
;	.C      The carry flag will always be clear.
;
;	APPROXIMATE EXECUTION TIMES in CLOCK CYCLES:
;
;	        Binary    5757
;	        Octal     4533
;	        Decimal  13390
;	        Hex       4373
;
;	The above execution times assume the operand is $FFFFFFFF, the radix
;	is to be prepended to the conversion string & all workspace other than
;	the string buffer is on zero page.  Relocating ZP workspace to absolute
;	memory will increase execution time approximately 8 percent.
;
;================================================================================
;
;ATOMIC CONSTANTS
;
_origin_ =$02000               ;assembly address
_zpage_  =$00                  ;start of ZP storage
;
;	------------------------------------------
;	Modify the above to suit your application.
;	------------------------------------------
;
a_hexdec ='A'-'9'-2            ;hex to decimal difference
m_bits   =32                   ;operand bit size
m_cbits  =48                   ;workspace bit size
m_strlen =m_bits+1             ;maximum printable string length
n_radix  =4                    ;number of supported radices
s_pfac   =m_bits/8             ;primary accumulator size
s_ptr    =2                    ;pointer size
s_wrkspc =m_cbits/8            ;conversion workspace size
;
;================================================================================
;
;ZERO PAGE ASSIGNMENTS
;
ptr01    =_zpage_              ;string storage pointer
;
;	---------------------------------
;	The following may be relocated to
;	absolute storage if desired.
;	---------------------------------
;
pfac     =ptr01+s_ptr          ;primary accumulator
wrkspc01 =pfac+s_pfac          ;conversion...
wrkspc02 =wrkspc01+s_wrkspc    ;workspace
formflag =wrkspc02+s_wrkspc    ;string format flag
radix    =formflag+1           ;radix index
stridx   =radix+1              ;string buffer index
;
;================================================================================
;
;CONVERT 32-BIT BINARY TO NULL-TERMINATED ASCII NUMBER STRING
;
;	----------------------------------------------------------------
;	WARNING! If this code is run on an NMOS MPU it will be necessary
;	         to disable IRQs during binary to BCD conversion unless
;	         the target system's IRQ handler clears decimal mode.
;	         Refer to the FACBCD subroutine.
;	----------------------------------------------------------------
;
         *=_origin_
;
binstr   stx ptr01             ;operand pointer LSB
         sty ptr01+1           ;operand pointer MSB
         tax                   ;protect radix
         ldy #s_pfac-1         ;operand size
;
binstr01 lda (ptr01),y         ;copy operand to...
         sta pfac,y            ;workspace
         dey
         bpl binstr01
;
         iny
         sty stridx            ;initialize string index
;
;	--------------
;	evaluate radix
;	--------------
;
         txa                   ;radix character
         asl                   ;extract format flag &...
         ror formflag          ;save it
         lsr                   ;extract radix character
         ldx #n_radix-1        ;total radices
;
binstr03 cmp radxtab,x         ;recognized radix?
         beq binstr04          ;yes
;
         dex
         bne binstr03          ;try next
;
;	------------------------------------
;	radix not recognized, assume decimal
;	------------------------------------
;
binstr04 stx radix             ;save radix index for later
         txa                   ;converting to decimal?
         bne binstr05          ;no
;
;	------------------------------
;	prepare for decimal conversion
;	------------------------------
;
         jsr facbcd            ;convert operand to BCD
         lda #0
         beq binstr09          ;skip binary stuff
;
;	-------------------------------------------
;	prepare for binary, octal or hex conversion
;	-------------------------------------------
;
binstr05 bit formflag
         bmi binstr06          ;no radix symbol wanted
;
         lda radxtab,x         ;radix table
         sta strbuf            ;prepend to string
         inc stridx            ;bump string index
;
binstr06 ldx #0                ;operand index
         ldy #s_wrkspc-1       ;workspace index
;
binstr07 lda pfac,x            ;copy operand to...
         sta wrkspc01,y        ;workspace in...
         dey                   ;big-endian order
         inx
         cpx #s_pfac
         bne binstr07
;
         lda #0
;
binstr08 sta wrkspc01,y        ;pad workspace
         dey
         bpl binstr08
;
;	----------------------------
;	set up conversion parameters
;	----------------------------
;
binstr09 sta wrkspc02          ;initialize byte counter
         ldy radix             ;radix index
         lda numstab,y         ;numerals in string
         sta wrkspc02+1        ;set remaining numeral count
         lda bitstab,y         ;bits per numeral
         sta wrkspc02+2        ;set
         lda lzsttab,y         ;leading zero threshold
         sta wrkspc02+3        ;set
;
;	--------------------------
;	generate conversion string
;	--------------------------
;
binstr10 lda #0
         ldy wrkspc02+2        ;bits per numeral
;
binstr11 ldx #s_wrkspc-1       ;workspace size
         clc                   ;avoid starting carry
;
binstr12 rol wrkspc01,x        ;shift out a bit...
         dex                   ;from the operand or...
         bpl binstr12          ;BCD conversion result
;
         rol                   ;bit to .A
         dey
         bne binstr11          ;more bits to grab
;
         tay                   ;if numeral isn't zero...
         bne binstr13          ;skip leading zero tests
;
         ldx wrkspc02+1        ;remaining numerals
         cpx wrkspc02+3        ;leading zero threshold
         bcc binstr13          ;below it, must convert
;
         ldx wrkspc02          ;processed byte count
         beq binstr15          ;discard leading zero
;
binstr13 cmp #10               ;check range
         bcc binstr14          ;is 0-9
;
         adc #a_hexdec         ;apply hex adjust
;
binstr14 adc #'0'              ;change to ASCII
         ldy stridx            ;string index
         sta strbuf,y          ;save numeral in buffer
         inc stridx            ;next buffer position
         inc wrkspc02          ;bytes=bytes+1
;
binstr15 dec wrkspc02+1        ;numerals=numerals-1
         bne binstr10          ;not done
;
;	-----------------------
;	terminate string & exit
;	-----------------------
;
         lda #0
         ldx stridx            ;printable string length
         sta strbuf,x          ;terminate string
         txa
         ldx #<strbuf          ;converted string LSB
         ldy #>strbuf          ;converted string MSB
         clc                   ;all okay
         rts
;
;================================================================================
;
;CONVERT PFAC INTO BCD
;
;	---------------------------------------------------------------
;	Uncomment noted instructions if this code is to be used  on  an
;	NMOS system whose interrupt handlers do not clear decimal mode.
;	---------------------------------------------------------------
;
facbcd   ldx #s_pfac-1         ;primary accumulator size -1
;
facbcd01 lda pfac,x            ;value to be converted
         pha                   ;protect
         dex
         bpl facbcd01          ;next
;
         lda #0
         ldx #s_wrkspc-1       ;workspace size
;
facbcd02 sta wrkspc01,x        ;clear final result
         sta wrkspc02,x        ;clear scratchpad
         dex
         bpl facbcd02
;
         inc wrkspc02+s_wrkspc-1
         ;php                   ;!!! uncomment for NMOS MPU !!!
         ;sei                   ;!!! uncomment for NMOS MPU !!!
         sed                   ;select decimal mode
         ldy #m_bits-1         ;bits to convert -1
;
facbcd03 ldx #s_pfac-1         ;operand size
         clc                   ;no carry at start
;
facbcd04 ror pfac,x            ;grab LS bit in operand
         dex
         bpl facbcd04
;
         bcc facbcd06          ;LS bit clear
;
         clc
         ldx #s_wrkspc-1
;
facbcd05 lda wrkspc01,x        ;partial result
         adc wrkspc02,x        ;scratchpad
         sta wrkspc01,x        ;new partial result
         dex
         bpl facbcd05
;
         clc
;
facbcd06 ldx #s_wrkspc-1
;
facbcd07 lda wrkspc02,x        ;scratchpad
         adc wrkspc02,x        ;double &...
         sta wrkspc02,x        ;save
         dex
         bpl facbcd07
;
         dey
         bpl facbcd03          ;next operand bit
;
         ;plp                   ;!!! uncomment for NMOS MPU !!!
         ldx #0
;
facbcd08 pla                   ;operand
         sta pfac,x            ;restore
         inx
         cpx #s_pfac
         bne facbcd08          ;next
;
         rts
;
;================================================================================
;
;PER RADIX CONVERSION TABLES
;
bitstab  .byte 4,1,3,4         ;bits per numeral
lzsttab  .byte 2,9,2,3         ;leading zero suppression thresholds
numstab  .byte 12,48,16,12     ;maximum numerals
radxtab  .byte 0,"%@$"         ;recognized symbols
;
;================================================================================
;
;STATIC STORAGE
;
strbuf   *=*+m_strlen+1        ;conversion string buffer
;
;================================================================================
	.end

Last page update: March 28, 2010.