16-Bit value to single Digits

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
Highli007
Posts: 1
Joined: 31 Aug 2022

16-Bit value to single Digits

Post by Highli007 »

Hello,

I am looking for a program that will allow me to display a stored 16-bit value on my LC display. For example, I have the decimal value: 16768 and need a subroutine that generates the characters 1, 6, 7, 6 and 8 for display.

Maybe someone can help me.

Greetings

Erik
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: 16-Bit value to single Digits

Post by floobydust »

You can try this routine from my C02 Monitor. Initially based on code adapted from "6502 Assembly Language Subroutines" with changes from me and later Mike Barry.

Code: Select all

;HEX2ASC - Accepts 16-bit Hexadecimal value and converts to an ASCII decimal string. Input is
; via the A and Y Registers and output is up to 5 ASCII digits in DATABUFF. The High Byte is in
; the Y Register and Low Byte is in the A Register. Output data is placed in variable DATABUFF
; and terminated with a null character.
; Note: leading zeros are suppressed. PROMPTR routine is used to print the ASCII decimal value.
; Core routine based on Michael Barry's code. Saves many bytes with two updates/changes ;-)
HEX2ASC         STA     BINVALL         ;Save Low byte
                STY     BINVALH         ;Save High byte
                LDX     #5              ;Get ASCII buffer offset
                STZ     DATABUFF,X      ;Zero last buffer byte for null end
;
CNVERT          LDA     #$00            ;Clear remainder
                LDY     #16             ;Set loop count for 16-bits
;
DVLOOP          CMP     #$05            ;Partial remainder >= 10/2
                BCC     DVLOOP2         ;Branch if less
                SBC     #$05            ;Update partial (carry set)
;
DVLOOP2         ROL     BINVALL         ;Shift carry into dividend
                ROL     BINVALH         ;Which will be quotient
                ROL     A               ;Rotate A Reg
                DEY                     ;Decrement count
                BNE     DVLOOP          ;Branch back until done
                ORA     #$30            ;OR in $30 for ASCII
;
                DEX                     ;Decrement buffer offset
                STA     DATABUFF,X      ;Store digit into buffer
;
                LDA     BINVALL         ;Get the Low byte
                ORA     BINVALH         ;OR in the High byte (check for zero)
                BNE     CNVERT          ;Branch back until done
;
;Conversion is complete, get the string address, add offset, then call prompt routine and return
; note DATABUFF is fixed location in Page 0, carry flag need not be cleared as result can never
; set flag after ADC instruction.
                TXA                     ;Get buffer offset
                ADC     #<DATABUFF      ;Add Low byte address
                LDY     #>DATABUFF      ;Get High byte address
                BRA     PROMPTR         ;Branch to PROMPTR to Print numeric string
;
;PROMPT routine: Send indexed text string to terminal. Index is contained in A Reg.
; String buffer address is stored in variable PROMPTL/PROMPTH.
PROMPT          ASL     A               ;Multiply by two for msg table index
                TAX                     ;Xfer to X Reg - index
                LDA     MSG_TABLE,X     ;Get low byte address
                LDY     MSG_TABLE+1,X   ;Get high byte address
;
;PROMPTR routine: takes message address in Y/A and prints via PROMPT2 routine
PROMPTR         STA     PROMPTL         ;Store low byte
                STY     PROMPTH         ;Store high byte
;
;PROMPT2 routine: prints message at address (PROMPTL) till null character found
PROMPT2         LDA     (PROMPTL)       ;Get string data (5)
                BEQ     HINEXIT         ;If null character, exit (borrowed RTS) (2/3)
                JSR     B_CHROUT        ;Send character to terminal (6)
                INC     PROMPTL         ;Increment low byte index (5)
                BNE     PROMPT2         ;Loop back for next character (2/3)
                INC     PROMPTH         ;Increment high byte index (5)
                BRA     PROMPT2         ;Loop back and continue printing (3)
;
Note that the B_CHROUT routine outputs a character to a serial port on my Pocket SBC. You can replace it to send the data to wherever you need it.
Erik
Posts: 7
Joined: 17 May 2022
Contact:

Re: 16-Bit value to single Digits

Post by Erik »

Hey, thanks a lot!

But: STZ-OP-Code is only for 65C02, I guess!

Best

Erik
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 16-Bit value to single Digits

Post by barrym95838 »

Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 16-Bit value to single Digits

Post by BigDumbDinosaur »

Highli007 wrote:
Hello,

I am looking for a program that will allow me to display a stored 16-bit value on my LC display. For example, I have the decimal value: 16768 and need a subroutine that generates the characters 1, 6, 7, 6 and 8 for display.

Maybe someone can help me.

Greetings

Erik

Have you looked in the code section of this site?
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: 16-Bit value to single Digits

Post by floobydust »

That's a good idea to prompt newbies to the site to look at the code section. Granted, I've gone thru it a number of times, but I really don't think about it much. Perhaps a gentle reminder when creating a new post to look at the other sections of the site would be useful.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: 16-Bit value to single Digits

Post by BigEd »

Welcome, Erik!
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: 16-Bit value to single Digits

Post by BillG »

Converting a binary number to decimal or BCD has previously been discussed extensively.

Two recent threads include

viewtopic.php?f=2&t=6579

and

viewtopic.php?f=2&t=4894

I posted my code for doing it on several processors at

viewtopic.php?p=90926#p90926

It was designed to convert quantities up to 64 bits in size using an optimized Double Dabble algorithm. For 16 bit numbers, it is probably overkill.
pjdennis
Posts: 51
Joined: 15 Apr 2022
Location: San Antonio, TX, USA

Re: 16-Bit value to single Digits

Post by pjdennis »

Here's my implementation (vasm assembler,) which is based on code shown in one of Ben Eater's videos:

Code: Select all

; Requires TO_DECIMAL_PARAM (9 bytes)

TO_DECIMAL_VALUE = TO_DECIMAL_PARAM + 0  ; 2 bytes
TO_DECIMAL_MOD10 = TO_DECIMAL_PARAM + 2  ; 1 byte
TO_DECIMAL_RESULT = TO_DECIMAL_MOD10 + 1 ; 6 bytes

; On entry A, X = low, high bytes of value to convert
; On exit A, X point to the result
;         Y is preserved
to_decimal:
  ; Initialize result to empty string
  stz TO_DECIMAL_RESULT
  
  ; Initialize value to be the number to convert
  sta TO_DECIMAL_VALUE
  stx TO_DECIMAL_VALUE + 1

to_decimal_divide:
  ; Initialize the remainder to be zero
  stz TO_DECIMAL_MOD10
  clc

  ldx #16
to_decimal_divloop:
  ; Rotate quotient and remainder
  rol TO_DECIMAL_VALUE
  rol TO_DECIMAL_VALUE + 1
  rol TO_DECIMAL_MOD10

  ; a = dividend - divisor
  sec
  lda TO_DECIMAL_MOD10
  sbc #10
  bcc to_decimal_ignore_result ; Branch if dividend < divisor
  sta TO_DECIMAL_MOD10

to_decimal_ignore_result:
  dex
  bne to_decimal_divloop
  rol TO_DECIMAL_VALUE
  rol TO_DECIMAL_VALUE + 1

  ; Shift result
  ldx #5
to_decimal_shift_loop:
  lda TO_DECIMAL_RESULT-1,X
  sta TO_DECIMAL_RESULT,X
  dex
  bne to_decimal_shift_loop

  ; Save value into result
  lda TO_DECIMAL_MOD10
  clc
  adc #'0'
  sta TO_DECIMAL_RESULT

  ; If value != 0 then continue dividing
  lda TO_DECIMAL_VALUE
  ora TO_DECIMAL_VALUE + 1
  bne to_decimal_divide

  lda #<TO_DECIMAL_RESULT
  ldx #>TO_DECIMAL_RESULT

  rts
Erik
Posts: 7
Joined: 17 May 2022
Contact:

Re: 16-Bit value to single Digits

Post by Erik »

BigEd wrote:
Welcome, Erik!
Thanks a lot!

Erik
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 16-Bit value to single Digits

Post by BigDumbDinosaur »

Erik wrote:
BigEd wrote:
Welcome, Erik!
Thanks a lot!

Erik

P.S. Welcome as well.

See here for a “universal” binary to ASCII conversion function, “universal” meaning it will run on NMOS 6502s, as well as the 65C02 and the 65C816 in either mode. It’s probably overkill for your application, but maybe not.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
electricdream
Posts: 6
Joined: 12 Nov 2022
Location: Maine, USA

Re: 16-Bit value to single Digits

Post by electricdream »

Erik wrote:
Hey, thanks a lot!

But: STZ-OP-Code is only for 65C02, I guess!

Best

Erik
Is it possible to modify that part of the code? I think an "LDA #$00" followed by a "STA location" achieves what "STZ location" does.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: 16-Bit value to single Digits

Post by Dr Jefyll »

electricdream wrote:
I think an "LDA #$00" followed by a "STA location" achieves what "STZ location" does.
Yup -- good thought.

Just be aware that "LDA #$00" followed by a "STA location" achieves more than what STZ does, because the accumulator and the flags get altered by the LDA. But that's acceptable in this case because the accumulator and the flags aren't important -- the immediately following instruction (at CNVERT) overwrites them anyway.

-- Jeff

Code: Select all

HEX2ASC         STA     BINVALL         ;
                STY     BINVALH         ;
                LDX     #5              ;
                STZ     DATABUFF,X      ; <---- replace this with "LDA #$00" followed by a "STA DATABUFF,X" ?
;
CNVERT          LDA     #$00            ;
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Post Reply