16-Bit value to single Digits
16-Bit value to single Digits
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
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
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: 16-Bit value to single Digits
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.
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.
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)
;
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: 16-Bit value to single Digits
Hey, thanks a lot!
But: STZ-OP-Code is only for 65C02, I guess!
Best
Erik
But: STZ-OP-Code is only for 65C02, I guess!
Best
Erik
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: 16-Bit value to single Digits
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)
Mike B. (about me) (learning how to github)
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: 16-Bit value to single Digits
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
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!
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: 16-Bit value to single Digits
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.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: 16-Bit value to single Digits
Welcome, Erik!
Re: 16-Bit value to single Digits
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.
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.
Re: 16-Bit value to single Digits
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
rtsRe: 16-Bit value to single Digits
BigEd wrote:
Welcome, Erik!
Erik
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: 16-Bit value to single Digits
Erik wrote:
BigEd wrote:
Welcome, Erik!
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!
- electricdream
- Posts: 6
- Joined: 12 Nov 2022
- Location: Maine, USA
Re: 16-Bit value to single Digits
Erik wrote:
Hey, thanks a lot!
But: STZ-OP-Code is only for 65C02, I guess!
Best
Erik
But: STZ-OP-Code is only for 65C02, I guess!
Best
Erik
Re: 16-Bit value to single Digits
electricdream wrote:
I think an "LDA #$00" followed by a "STA location" achieves what "STZ location" does.
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
https://laughtonelectronics.com/Arcana/ ... mmary.html