Shop OBEX P1 Docs P2 Docs Learn Events
Technique(s) for converting integer to ascii bit pattern in pasm? — Parallax Forums

Technique(s) for converting integer to ascii bit pattern in pasm?

grahamreitzgrahamreitz Posts: 56
edited 2009-08-21 23:59 in Propeller 1
This has probably been answered before. Although, I didn't see anything with a quick forum search.

What techniques are used to convert an integer, stored in a cog register, into an ascii bit pattern, for the purpose of sending it to a terminal, such as the Parallax Serial Terminal?

Thanks,
graham

Comments

  • localrogerlocalroger Posts: 3,452
    edited 2009-08-21 20:14
    You need to be able to divide by 10 and get both the remainder and result. You need a buffer for the results because they will come out in reverse order. You divide by 10, sticking the remainder in your buffer and the result back in your source register, repeat until the result is zero. You now have your digits. Working backward, you add "0" to each digit and spit it out of the port. I use the division routine in the interpreter source for this sort of thing. I'd give some example code but that's on a different computer :-(
  • grahamreitzgrahamreitz Posts: 56
    edited 2009-08-21 21:09
    Thanks localroger.

    If you don't mind me parroting the algorithm:

    1) Number in a cog register #1 is 123
    2) 123/10 = 12r3, store 3 in register #2, 12 in register #1
    3) 12/10 = 1r2, store 2 in register #3, 1 in register #1
    4) 1/10 = 0r1, store 1 in register #4, 0 in register #1
    5) End.

    I see that there is a modulus operator in pasm, '//'. Although, does it only work on constants and not registers?

    From manual:
    "NOTE: All operators shown are constant expression operators."

    I was looking for example syntax of the binary operators in pasm, but only saw spin examples.

    Would this work?

    mov result, number // 10
    

    Post Edited (greitz) : 8/21/2009 9:35:47 PM GMT
  • SRLMSRLM Posts: 5,045
    edited 2009-08-21 21:52
    You don't need to divide (although that is one way to do it), but I subtract (in a loop, which is almost equivalent to dividing). Here is my (partially tested) dec_to_ASCII code:

    dec_to_ASCII            'Converts a number in a register to an ASCII value
                            't1 - The decimal number
                            't2 - The current count of the digits (ie, how many 100's are in 843)
                            't3 - The decimal number address
                            't4 - (parameter) the number to convert
                            't5 - (parameter) the number of digits in the number (modified)
                            '       ---too few will result in tuncation of lower digits
                            'ASCII_num - (result) will contain the number, optional negative (-, counts as digit)
    
                            'note: currently, if the number is too large for the specified number of digits, a nonsense answer will be generated in the highest digit.
    
                            'Negative not implemented right now
                            mov     t3, #decimal
                            add     t3, #10         'go to end of decimal list
                            sub     t3, t5          'step back the number of digits
                            movs    :d_t_a_loop, t3
                             
                            mov     t2, #0
                            movd    :d_t_a_loop_s, #ASCII_num
                            
    :d_t_a_loop             mov     t1, 0-0
                            cmp     t4, t1          wc
                  if_nc     add     t2, #1
                  if_nc     sub     t4, t1
                  if_nc     jmp     #:d_t_a_loop
    
                            add     t2, #48
    :d_t_a_loop_s           mov     0-0, t2
                            add     :d_t_a_loop, #1
                            mov     t2, #0
                            add     :d_t_a_loop_s, destination_mask
                            djnz    t5, #:d_t_a_loop
                             
    
    dec_to_ASCII_ret        ret
    
    



    It's not really all that clear, but from what I've seen so far it works on positive numbers.

    BTW, your code snippet above won't work, since operators in PASM are constant (compile time) only.
  • localrogerlocalroger Posts: 3,452
    edited 2009-08-21 23:59
    @SRLM, that also works though it takes a few more loops; if the extra time isn't an issue it might even be better than the "standard" solution because of code compactness.

    The proper division routine is a bit quicker but takes 30 or 40 longs of COG RAM. It's a lot easier in x86 where the processor does division for you; that's in the PASM instruction set but it's not implemented in the Prop I.
Sign In or Register to comment.