Looking for some PASM code to convert a LONG to ASCII
Bean
Posts: 8,129
I'm trying to convert the STR command from SX/B for the PropBASIC compiler.
In SX/B I basically did this:
subtract 10,000 until overflow
subtract 1,000 until overflow
subtract 100 until overflow
subtract 10 until overflow
But the Propeller has LONGs which would require 10 loops, which is going to use up alot of code space. Or I could just divide the value by 10 each time, but that's not very easy either (dividing by 10).
I'm wondering if anyone has any better ideas about how to convert a LONG into ascii character without using too much code space ?
Any ideas are welcome too...
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...
·
In SX/B I basically did this:
subtract 10,000 until overflow
subtract 1,000 until overflow
subtract 100 until overflow
subtract 10 until overflow
But the Propeller has LONGs which would require 10 loops, which is going to use up alot of code space. Or I could just divide the value by 10 each time, but that's not very easy either (dividing by 10).
I'm wondering if anyone has any better ideas about how to convert a LONG into ascii character without using too much code space ?
Any ideas are welcome too...
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...
·

Comments
One "cheap" way to do this would be to initialize a "divisor" to 10^10 and do a conditional subtract (CMPSUB) until the subtract fails, each time incrementing your ASCII digit, then multiple the "divisor" by 10 using shifts and adds ((4*x+x)*2) and repeat until done. You'd need to include zero suppression in the logic.
temp := 10000000000
repeat 10
... digit := "0"
... repeat while value >= temp
...... value -= temp
...... digit ++
... ' output digit
... value := (value << 2 + value) << 1
Post Edited (Mike Green) : 11/5/2009 3:29:14 PM GMT
· Good idea. You mean to multiply the dividend (well really the remainder)·by 10 right ?
· I've never seen it done that way. But you're right, that will use a lot less instructions. Thanks.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...
Post Edited (Bean (Hitt Consulting)) : 11/5/2009 4:17:59 PM GMT
The reason for doing it this way is that you don't need to divide by 10 and multiplying by 10 by shifting and adding is very cheap. You could use a table of powers of ten, and the cost on the Prop of indexing through a table of constants is relatively low, but this would work and I think would take less memory.
· Here is how I implemented it into PropBASIC.
'' *** COMPILED WITH PropBasic VERSION 0.00.23 11/05/2009 *** CON 'DEVICE P8X32A, XTAL1, PLL16X _ClkMode = XTAL1 + PLL16X _XInFreq = 5000000 'FREQ 80_000_000 ' digits VAR LONG (8) 'digits VAR LONG (8) ' value VAR LONG 'value VAR LONG PUB __Program 'PROGRAM Start CogNew(@__Init, @__DATASTART) DAT org 0 __Init mov dira,__InitDirA mov outa,__InitOutA jmp #Start Start 'Start: mov value,_123456 ' value = 123456 mov __temp1,#digits ' STR digits, value, 6 mov __temp2,value mov __temp3,_100000 mov __temp4,#6 __L0001 mov __temp5,#"0"-1 __L0002 adds __temp5,#1 cmpsub __temp2,__temp3 WC, WR IF_C jmp #__L0002 movd $+2,__temp1 add __temp1,#1 mov 0-0,__temp5 mov __temp5,__temp2 shl __temp2,#2 add __temp2,__temp5 shl __temp2,#1 djnz __temp4,#__L0001 __DO_1 ' DO mov __temp1,cnt ' PAUSE 2000 adds __temp1,_1mSec mov __temp2,_2000 __L0003 waitcnt __temp1,_1mSec djnz __temp2,#__L0003 mov value,#0 ' FOR value = 0 TO 5 __FOR_value_1 mov __temp1,#1 ' SEROUT 30, T115200, digits(value) shl __temp1,#30 add value,#digits movs $+2,value sub value,#digits mov __temp2,0-0 or __temp2,#256 shl __temp2,#1 or dira,__temp1 mov __temp3,#10 mov __temp4,_bitDelay add __temp4,cnt __L0004 shr __temp2,#1 WC muxc outa,__temp1 waitcnt __temp4,_bitDelay djnz __temp3,#__L0004 adds value,#1 ' NEXT cmps value,#5 WZ, WC IF_BE jmp #__FOR_value_1 jmp #__DO_1 ' LOOP __LOOP_1 jmp #$ 'END '********************************************************************** __InitDirA LONG %00000000_00000000_00000000_00000000 __InitOutA LONG %00000000_00000000_00000000_00000000 _bitDelay LONG 694 _2000 LONG 2000 _1mSec LONG 80000 _100000 LONG 100000 _123456 LONG 123456 __REMAINDER __TEMP1 RES 1 __TEMP2 RES 1 __TEMP3 RES 1 __TEMP4 RES 1 __TEMP5 RES 1 __PARAM1 RES 1 __PARAM2 RES 1 __PARAM3 RES 1 __PARAM4 RES 1 __PARAMCNT RES 1 digits RES 8 value RES 1 FIT 492 CON LSBFIRST = 0 MSBFIRST = 1 MSBPRE = 0 LSBPRE = 1 MSBPOST = 2 LSBPOST = 3 DAT __DATASTARTBean
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...
·