Shop OBEX P1 Docs P2 Docs Learn Events
P2 PASM syntax — Parallax Forums

P2 PASM syntax

pic18f2550pic18f2550 Posts: 392
edited 2021-12-16 13:48 in PASM2/Spin2 (P2)

EEEE 1101100 RAA AAAAAAA AAAAAAAAA
JMP #A Jump to A. If R = 1, PC += A, else PC = A.

EEEE 1101101 RAA AAAAAAA AAAAAAAAA
CALL #A Call to A by pushing {C, Z, 10'b0, PC[19:0]} onto stack. If R = 1, PC += A, else PC = A.

How must JMP and CALL be used to exploit the full address range of 20 bits in PASM.

Comments

  • evanhevanh Posts: 15,126
    edited 2021-11-21 00:21

    As the syntax indicates, these are immediate only encodings. The assembler encodes the address for you. All need do is write call #label

    PS: Wherever "label" is located it'll be reachable since the full 20 bits gets encoded.

  •               orgh      $1000
    ''+------[ Load new COG code ]-------------------------------------------------+
    reload_cog      setq    #512-16-1                       '\ re-load COG 
                    rdlong  #0, ##@cog_code                 '/          
    

    The propeller tool bumps into the last line on the #0.
    What is wrong with it?

  • evanhevanh Posts: 15,126

    The correct syntax is rdlong 0, ##@cog_code

  • Isn't the memory content of address 0 of the COG-Ram taken as target?
    The # should be a direct value.

    FlexProp says >> error: Bad use of immediate for first operand of rdlong

    Propeller Tool says >> Expected a constant, unary operator, or "(".

    How could the original have been translated so that it worked?

    The many tools for translating are not very helpful for learning. :(

    I have taken over the first time so to test I'm not ready anyway there must still be thrown out some.

  • AribaAriba Posts: 2,682
    edited 2021-11-24 11:37

    @pic18f2550 said:
    Isn't the memory content of address 0 of the COG-Ram taken as target?
    The # should be a direct value.

    # is immediate, without # it's direct addressing.
    RDLONG reads into a register, you can't read into an immedate value.

    FlexProp says >> error: Bad use of immediate for first operand of rdlong

    Propeller Tool says >> Expected a constant, unary operator, or "(".

    FlexProp detects the error correct.

    How could the original have been translated so that it worked?

    >
    See evanh's post.

    The many tools for translating are not very helpful for learning. :(

    Then use only one.

    I have taken over the first time so to test I'm not ready anyway there must still be thrown out some.

    The real problem is that you don't get the absolute address with ##@cogcode in a Spin DAT section, but that got discussed many many times.

  • evanhevanh Posts: 15,126
    edited 2021-11-24 11:44

    Possibly the biggest reason for the syntax being as is, is so WRLONG can use both addressing modes:

    • wrlong 0, hubaddr - This copies the content of register 0 to hubaddr in hubRAM.
    • wrlong #0, hubaddr - Whereas this writes a 0 to hubaddr in hubRAM.
  • pic18f2550pic18f2550 Posts: 392
    edited 2021-11-24 15:55

    So with the Propeller Tool I better load a register with 0 to get this right.
    nope does not work either

  • Consider this code:

        org 0
    reg0
        nop
        rdlong reg0, hubaddr
        rdlong 0, hubaddr
    hubaddr
        long $FF00  ' put any hub address here
    

    The two "rdlong" instructions will compile to exactly the same binary instruction; they are the same thing, because the symbol "reg0" is located at address 0. Both of them will take the 4 bytes in HUB starting at hubaddr and put them into COG memory location 0, which initially contains a "nop" instruction (which is represented by all 0's).

  • evanhevanh Posts: 15,126

    @pic18f2550 said:
    nope does not work either

    I suspect the not working part is elsewhere.

  • Ok if the correct CODE comes out that is OK. Thank you.

    I didn't find the "alignl" in the PASM exeltable. What is this for?

  • evanhevanh Posts: 15,126
    edited 2021-11-25 11:53

    ALIGNL is a "directive". It's tells the assembler you want the next data aligned, in the binary file it is assembling, on a longword boundary relative to the file start. The presumption is that it'll then align the same when loaded in memory too.

    EDIT: Or it could be relative to the previous ORG/ORGH. That could technically have a different outcome. Not sure, I've not actually read the definition.

    At any rate, the effect is it can add anything from 0 to 3 padding bytes at that point in the binary file (Assuming bytes is the base addressing size of course).

  • i always do this with a long statement without value. thanks

  • @pic18f2550 said:
    i always do this with a long statement without value. thanks

    That does not work on P2, because the P2 allows LONG values to be placed on any boundary. That's why Chip added ALIGNL.

  • pic18f2550pic18f2550 Posts: 392
    edited 2021-12-09 21:47

    Have a little thinking problem with CALL/JMP/RET.

    :M000
        CALL #:UP1
        CALL #:UP2
        JMP #:M000
    
    :UP1
        RET
    
    :UP2
        JMP #:M000
    

    The call of UP1 is clear to me

    The call of UP2 seems to me to be faulty because no RET is used here.
    What problems could there be with this? (Return address

  • pik33pik33 Posts: 2,347

    P2 has a hardware stack, so you will not overwrite your program using this, but where you got this code from?

  • evanhevanh Posts: 15,126

    @pic18f2550 said:
    What problems could there be with this? (Return address

    The test won't show the actual problem because the hardware stack doesn't use RAM. It's built from a special register set of 8 x 32-bit.

    After several calls to UP2, the oldest return address is lost. And they keep vanishing as more calls pile up. But since the test code is infinite recursion it never needs the lost return addresses. No harm done.

  • Cluso99Cluso99 Posts: 18,066

    Aren't you missing the # from the call and jmp operands?
    ie jmp #:M000

  • It consists of a special register set of 8 x 32 bits.
    I assume per COG?
    Can I manipulate this?
    This results in a maximum nesting depth of 8.

    '' +--------------------------------------------------------------------------+
    '' | Cluso's Z80 emulation for P2                                       v0.xx |
    '' +--------------------------------------------------------------------------+
    '' |  Author(s):     (c)2019-2020 "Cluso99" (Ray Rodrick)    (rewrite for P2) |
    '' |                 (c)2010 "pullmoll" (Juergen)            (original code)  |
    '' |  License: Juergen has gratiously given me permission to modify his code  |
    '' +--------------------------------------------------------------------------+
    ...
    fetch_1                 rdlong  vector3, alu
              cmp     debug_flag, #0          WZ
      if_ne   call    #_debug_opc
                            mov     vector, vector3                 '\ extract first vector (12-bits)
                            and     vector, maskFFF                 '/   and mask to 12-bits
                     1 ->   call    vector                          ' dispatch
    ' ----------------------------------------------------------------------------------------------
                            mov     vector, vector3                 ' 
                            shr     vector, #12                     '\ shift to 2nd vector (10-bits)
                            and     vector, mask3FF                 '/   and mask to 10-bits
                     1 ->   call    vector                          ' dispatch
    ' ----------------------------------------------------------------------------------------------
                            shr     vector3, #22                    ' shift to 3rd vector (10-bits)
                     1 ->   call    vector3                         ' dispatch
    ' ----------------------------------------------------------------------------------------------
    

    I noticed this while rewriting the vectors.
    Because the 3rd value (Vector3) is times vector or a flac mask.

    The 1st branch is always a CALL and exited with JMP.

    In summary you can say that this is not a big problem if you call this code with CALL.

    This means for me that I have to change this.

  • @Cluso99 said:
    Aren't you missing the # from the call and jmp operands?
    ie jmp #:M000

    I have corrected it in #15.

  • Cluso99Cluso99 Posts: 18,066

    @pic18f2550 said:
    It consists of a special register set of 8 x 32 bits.
    I assume per COG?
    Can I manipulate this?
    This results in a maximum nesting depth of 8.

    '' +--------------------------------------------------------------------------+
    '' | Cluso's Z80 emulation for P2                                       v0.xx |
    '' +--------------------------------------------------------------------------+
    '' |  Author(s):     (c)2019-2020 "Cluso99" (Ray Rodrick)    (rewrite for P2) |
    '' |                 (c)2010 "pullmoll" (Juergen)            (original code)  |
    '' |  License: Juergen has gratiously given me permission to modify his code  |
    '' +--------------------------------------------------------------------------+
    ...
    fetch_1                 rdlong  vector3, alu
              cmp     debug_flag, #0          WZ
      if_ne   call    #_debug_opc
                            mov     vector, vector3                 '\ extract first vector (12-bits)
                            and     vector, maskFFF                 '/   and mask to 12-bits
                     1 ->   call    vector                          ' dispatch
    ' ----------------------------------------------------------------------------------------------
                            mov     vector, vector3                 ' 
                            shr     vector, #12                     '\ shift to 2nd vector (10-bits)
                            and     vector, mask3FF                 '/   and mask to 10-bits
                     1 ->   call    vector                          ' dispatch
    ' ----------------------------------------------------------------------------------------------
                            shr     vector3, #22                    ' shift to 3rd vector (10-bits)
                     1 ->   call    vector3                         ' dispatch
    ' ----------------------------------------------------------------------------------------------
    

    I noticed this while rewriting the vectors.
    Because the 3rd value (Vector3) is times vector or a flac mask.

    The 1st branch is always a CALL and exited with JMP.

    In summary you can say that this is not a big problem if you call this code with CALL.

    This means for me that I have to change this.

    You can manipulate the internal 8*32b stack (per COG) by using the PUSH and POP instructions, as well as the CALL and RET instructions.

  • @ersmith
    In my code snippet here, the "RDLONG Interpolator,xtraptr" will work,
    but the "RDLONG tvd,xtraptr" does not load the LUT properly...
    It looks to me like RDLONG destination is the address of the label, not it's value...

    @evanh
    RDLONG #0,xtraptr gives a "Expected a constant, unary operator, or "(" " error message.

    DAT           ORG     0
    Interpolator  long    0
                  nop
    Tvd           long    0             
    ''''''''''''''LUT load routine'''''''''''''''''''''''''''''''''''''''''''''''''''''
                  RDLONG xtraptr,ptra          'read in XposM(pointed to by ptra), which has hub address of lutcall in it
                  SETQ2  #$1FE
                  'RDLONG tvd,xtraptr
                  RDLONG Interpolator,xtraptr  'Interpolator is address zero, but use it for LUT address zero also, not sure how else to do this?
                                               'using setQ2 makes these RDLONG's go into LUT area
    ''''''''''''''LUT load routine end'''''''''''''''''''''''''''''''''''''''''''''''''
    
  • @mwroberts said:
    @ersmith
    In my code snippet here, the "RDLONG Interpolator,xtraptr" will work,
    but the "RDLONG tvd,xtraptr" does not load the LUT properly...
    It looks to me like RDLONG destination is the address of the label, not it's value...

    @evanh
    RDLONG #0,xtraptr gives a "Expected a constant, unary operator, or "(" " error message.

    Yes. rdlong x, y is just like mov x, y or add x, y or any other instruction: it modifies the exact location x that you specify.

    If you're loading LUT, it probably makes sense to hard-code the address to 0 (or whatever other portion of the LUT you want to load), like:

        setq2 #$1ff
        rdlong 0, lutptr  ' load starting at LUT address 0
    
  • @ersmith Thanks... I think I misunderstood an earlier example you posted with a reg0 label on a nop line...
    @evanh Oops, your example was a wrlong #0 not a rdlong #0...

Sign In or Register to comment.