Shop OBEX P1 Docs P2 Docs Learn Events
Printing strings using getbyte — Parallax Forums

Printing strings using getbyte

proppyproppy Posts: 7
edited 2024-03-14 21:27 in PASM2/Spin2 (P2)

Hi,

I have been slowly learning and inching my way through the propeller p2asm manual. I tried to print a string but noticed that if i use getbyte i can only get the first four characters. I'm not sure if getbyte is what I should use or if I need to use another instruction to advance the string past the first four characters. My example code is below:
con

dat
org

' Set the clock mode
asmclk  

' configure rx smart pin
fltl      #63
wrpin     #P_ASYNC_RX, #63
wxpin     ##655367, #62
drvl      #63

' configure tx smart pin
fltl      #62
wrpin     ##(P_ASYNC_TX | P_OE), #62
wxpin     ##655367, #62
drvl      #62


    getbyte tempbyte, msg, #0
    wypin tempbyte, #62
    'flush the tx pin
    nop
    .waittx     testp     #62  wc
            if_nc  jmp       #.waittx
             akpin     #62

    msg byte "Hello,world!", 10
    tempbyte res 1

I am able to print H, e, l or l using #0 thru #3 but can't seem to figure out how to print the rest. I want to eventually put the whole thing in a loop, which i understand a little more now.

Comments

  • JonnyMacJonnyMac Posts: 8,929

    ...the properller p2asm manual.

    Where is this?

    This is a small section from an S.BUS receiver program I wrote a while ago. What I have that you're missing is a loop, and an adjustment to the offset into the array (in your case, the message).

    .build_ch       altgb     icog, #sbusraw                        ' get s.bus byte from cog array
                    getbyte   t1                                    ' get new byte
                    add       icog, #1                              ' bump byte array index
                    shl       t1, bc                                ' prep new byte
                    or        chwork, t1                            ' add into work
                    add       bc, #8                                ' update bit count
                    cmpsub    bc, #11                       wc      ' enough bits for channel value?
        if_nc       jmp       #.build_ch
    
  • JonnyMacJonnyMac Posts: 8,929
    edited 2024-03-14 21:28

    I just noticed that you have a 62 where you want 63 in your setup of the RX pin. This is why "magic numbers" are considered less than optimal (use named constants).

    I am able to print H, e, l or l using #0 thru #3 but can't seem to figure out how to print the rest.

    You need to use the alternative version of getbyte that is prefaced with altgb -- this allows a variable index.

    I did a version using inline PASM. Maybe this will be helpful.

    pub main()
    
      org
                            fltl      #PGM_RX
                            wrpin     #P_ASYNC_RX, #PGM_RX
                            wxpin     ##BAUDMODE, #PGM_RX
                            drvl      #PGM_RX
    
                            fltl      #PGM_TX
                            wrpin     ##(P_ASYNC_TX | P_OE), #PGM_TX
                            wxpin     ##BAUDMODE, #PGM_TX
                            drvl      #PGM_TX
    
                            mov       pr0, #0                       ' index into message
    
    .print                  altgb     pr0, #msg                     ' point to msg[pr0]
                            getbyte   pr1                           ' get char
                            tjz       pr1, #.done                   ' done if at end
                            add       pr0, #1
    
                            wypin     pr1, #PGM_TX
                            nop
    .flush                  rdpin     pr2, #PGM_TX          wc      ' check busy flag
            if_c            jmp       #.flush                       ' hold until done
    
                            jmp       #.print
    
    .done                   ret
    
    msg                     byte      "Hello, JonnyMac!", 13
                            byte      "How's your day going?", 13
                            byte      0
      end
    

    That said, PASM is not my strength; I resort to it when I need it.

  • Hi JonnyMac,

    Thank you for the response. I will look it over. So far I think i understand. It didn't occur to me that i needed to set the index at the start. I had read in the manual how altgb works but didn't realize i needed to move the index at the start. Thanks so much for this, gonna pick away at it and see what i come away with.

    I also corrected the misspelling of propeller as well. :smile:

  • @JonnyMac said:
    I just noticed that you have a 62 where you want 63 in your setup of the RX pin. This is why "magic numbers" are considered less than optimal (use named constants).

    I am able to print H, e, l or l using #0 thru #3 but can't seem to figure out how to print the rest.

    You need to use the alternative version of getbyte that is prefaced with altgb -- this allows a variable index.

    I did a version using inline PASM. Maybe this will be helpful.

    pub main()
    
      org
                            fltl      #PGM_RX
                            wrpin     #P_ASYNC_RX, #PGM_RX
                            wxpin     ##BAUDMODE, #PGM_RX
                            drvl      #PGM_RX
    
                            fltl      #PGM_TX
                            wrpin     ##(P_ASYNC_TX | P_OE), #PGM_TX
                            wxpin     ##BAUDMODE, #PGM_TX
                            drvl      #PGM_TX
    
                            mov       pr0, #0                       ' index into message
    
    .print                  altgb     pr0, #msg                     ' point to msg[pr0]
                            getbyte   pr1                           ' get char
                            tjz       pr1, #.done                   ' done if at end
                            add       pr0, #1
    
                            wypin     pr1, #PGM_TX
                            nop
    .flush                  rdpin     pr2, #PGM_TX          wc      ' check busy flag
            if_c            jmp       #.flush                       ' hold until done
    
                            jmp       #.print
    
    .done                   ret
    
    msg                     byte      "Hello, JonnyMac!", 13
                            byte      "How's your day going?", 13
                            byte      0
      end
    

    That said, PASM is not my strength; I resort to it when I need it.

    I must say, that this is one of the riddles of P2 and it's documentation. Why not just:

    ....
    mov pr0,#msg
    .print rdbyte pr1,pr0
    ....

    You would not want a string constant in precious cog ram registers, I think?
    Christof

  • JonnyMacJonnyMac Posts: 8,929

    The OP is just learning PASM2, and I was following his structure. In an application I would pass a pointer to the start of a string that is stored in the hub.

  • Yes, that is correct. I am currently just going through the manual and learning what the instructions and registers do. Some concepts are pretty easy to understand such a looping and add/sub/mul. Others have a little more fine print to them, like getbyte. It did not click with me that i could do getbyte with one dest but altgb has a different dest. Also, learning how to push an address pointer forward was a key point because the manual does not clearly mention how to perform this.

    Here is what I ended up:
    con

    dat
    org

    ' Set the clock mode
    asmclk  
    
    ' configure rx smart pin
    fltl      #63
    wrpin     #P_ASYNC_RX, #63
    wxpin     ##655367, #63
    drvl      #63
    
    ' configure tx smart pin
    fltl      #62
    wrpin     ##(P_ASYNC_TX | P_OE), #62
    wxpin     ##655367, #62
    drvl      #62
    
    
    mov pr0, #0
    
    .print                  altgb     pr0, #msg                     ' point to msg[pr0]
                            getbyte   pr1                           ' get char
                            tjz       pr1, #.done                   ' done if at end
                            add       pr0, #1
                wypin     pr1, #62
                            nop
    
    .flush                  rdpin     pr2, #62         wc      ' check busy flag
            if_c            jmp       #.flush                       ' hold until done
                            jmp       #.print
    
    .done                   ret
    
    msg byte "Hello,world!", 0
    

    This works perfectly as far as I can tell. I have a ton of C/spin examples to convert to pasm2 which will help me learn more. I will also get rid of the magic numbers. :blush: Thank you all and I will try the mov pr0,#msg and .print rdbyte pr1,pr0. As stated before something like that is definitely not in the manual, but learning what the instructions do comes first for now. :smiley:

  • JonnyMacJonnyMac Posts: 8,929

    I will also get rid of the magic numbers.

    Good. Especially in code that you share publicly. For example

    fltl      #62
    wrpin     ##(P_ASYNC_TX | P_OE), #62
    wxpin     ##655367, #62
    drvl      #62
    

    I know this sets pin 62 to be a TX UART, but I have no idea what baud to set into my terminal so that I can see the output.

    "Quick and dirty" is only ever dirty -- and easy way to create confusion, bugs, and burdensome editing.

  • @JonnyMac said:
    "Quick and dirty" is only ever dirty -- and easy way to create confusion, bugs, and burdensome editing.

    If anything, calculating the "magic number" separately and then pasting it into the code is more work than just writing the calculation into the code.

  • JonnyMacJonnyMac Posts: 8,929

    If anything, calculating the "magic number" separately and then pasting it into the code is more work than just writing the calculation into the code.

    Agreed. I did this in my example:

      BAUDMODE =  ((CLK_FREQ / 230_400) << 16) | (8-1) 
    
Sign In or Register to comment.