Shop OBEX P1 Docs P2 Docs Learn Events
Double Precision Binary-to-BCD: ALTS/D thoughts — Parallax Forums

Double Precision Binary-to-BCD: ALTS/D thoughts

I adapted a DP Bin2BCD routine for Prop2. The routine repeatedly subtracts double precision powers of 10, beginning with 10E19.

The change from the Prop1 method is that it uses Register Indirection. Here it is.
Bin2BCD  mov   x, #0             'clear index regs (goes by 1)
         mov   y, #0             'goes by 2  
         mov   temp, #20         'will do 20 digits
B2BL1    mov   count, #0         'used to count subtracts
B2BL2    alts  y, #E19+1         'index into DP 10**X table 
         sub   BinLo, 0 wc       'subtract lo order
         alts  y, #E19      
         subx  BinHi, 0 wc       'subtract hi order
  if_NC  djnz  count, #B2BL2     'still positive, adjust count
         altd  x, #tens
         abs   0, count          'save result
         alts  y, #E19+1
         add   BinLo, 0  wc      'restoring add
         alts  y, #E19
         addx  BinHi, 0
         add   x, #1              'adjust indexes
         add   y, #2
         djnz  temp, #B2BL1       'do next power of temp                         
Bin2BCD_ret  ret                 'all done

The prop1 method used self-modifying code to directly point into the table of powers of ten; this uses register indirection.
The nice news is no more self-modifying code; the not-so-nice news is that the inside loop goes from three instructions to five (beginning at B2BL2).
You pays your money, you takes your choice.

I was gonna get all philosophical here about whether avoiding self-modifying code is A Good Thing, but won't.

Comments

  • good that you are @tomcrawford again, and why not going all philosophical about self-modifying code.

    Basically alts, altd, alti are self-modifying code like we used on the P1, just without the hassle of counting instructions in between modifying and using.

    I am slowly diving into PASM2 and like it a lot, already...

    Mike
  • Mark_TMark_T Posts: 1,981
    edited 2019-01-30 11:07
    ALTS et al don't modify code, SETS et al do that. Self-modifying code is non-reentrant and can't be used from multiple cogs executing from hub ram, but ALTS/D/R are fine for that - or for running from ROM indeed.
  • Here's another technique that allows large size patterns to be converted.
    Code is quite compact too.
    con
    
    'isize = input size in longs
    'rsize = result size in longs
    
    '	isize = 1,rsize = 2	'32 buts
    	isize = 2,rsize = 3	'64 buts
    '	isize = 3,rsize = 4	'96 buts
    '	isize = 4,rsize = 5	'128 buts
    
    'e.g. for 64 bits i0+1:i0 converts to q0+2:q0+1:q0
    
    dat
    
    bin2bcd		mov	regx,#q0	'init result
    		rep	#2,#rsize		
    		altd	regx,increg
    		mov	0-0,#0
    
    		mov	numbits,#isize * 32
    convert		mov	countx,#rsize
    		mov	regx,#q0
    .loop		rep	@.length,#8
    		alts	regx
    		getnib	temp,0-0,#7
    		cmp	temp,#4	wcz
    	if_a	add	temp,#3
    		altd	regx
    		setnib	0-0,temp,#7
    		altd	regx
    		rol	0-0,#4
    .length		add	regx,#1
    		djnz	countx,#.loop
    
    		mov	regx,#i0		'rotate bits
    		rep	#2,#isize+rsize
    		altd	regx,increg
    		rcl	0-0,#1	wc
    
    		djnz	numbits,#convert
    		ret
    
    
    increg		long	1 << 9		'+1 increment for ALTD/ALTS
    countx		long	0
    regx		long	0
    numbits		long	0
    temp		long	0
    i0		long	-1[isize]
    q0		long	-1[rsize] 
    


Sign In or Register to comment.