Shop OBEX P1 Docs P2 Docs Learn Events
PASM1 to PASM2 Question — Parallax Forums

PASM1 to PASM2 Question

JonnyMacJonnyMac Posts: 9,412
edited 2025-08-12 15:50 in PASM2/Spin2 (P2)

Is the correct translation of

                        movs      :getins, reg     
                        movd      :setins, reg

this?

                        sets      #.getins, reg
                        setd      #.setins, reg

I used # because ChatGPT says the destination field of sets and setd is an address. Am I being too literal?

Comments

  • RaymanRayman Posts: 15,464
    edited 2025-08-12 16:15

    Don't think you need # on the D field because writing to a register number is only option. Not sure if that will give an error or not. But, should be same with or without.

    The S field could be literal or register though...

  • RaymanRayman Posts: 15,464

    Had to look up the instruction. Seems that self-modifying code is rarely needed with P2...

  • RaymanRayman Posts: 15,464

    Might be that Alts, Altd are usually better because don't have to worry about needing a dummy instruction before use...

  • evanhevanh Posts: 16,637
    edited 2025-08-12 18:32

    I don't know Pasm1 all that well but it does look correct to me. SETS and SETD are the direct translation instructions and using # is the correct way to hit the target register number. If the # is removed then that D register gets loaded to reference another register. to be modified. EDIT: See example from Silicon Manual in post #7 below. EDIT2: In fact it's not possible to use a # in that position. It'll generate a syntax error.

    Rayman is correct that SETS/SETD are used far less often with the Prop2. It has ALTD/ALTS/ALTI instructions which will often do the job better - Via instruction modification in the pipeline instead of modifying the code in memory. This is also known as instruction-prefixing - Which doesn't get the bad rep associated with self-modifying-code.

    PS: Whether calling cogRAM a set of registers or a memory array is something of a terminology preference thing. I've used both. Sometimes It's just clearer described as a memory array, but mostly using register terminology works better since hubRAM easily fills the main memory definition on the proviso that the Propeller is considered a strong load-store architecture. It has no hubRAM addressing modes beyond RDxxxx/WRxxxx instructions.

  • Wuerfel_21Wuerfel_21 Posts: 5,444
    edited 2025-08-12 17:36

    sigh. taps the sign

    We'll leave it at a warning this time 🤠

    The correct answer is to just exchange MOVS/MOVD with SETS/SETD, they do the same operation, no weird nonsense required. (and of course to deal with the different local label syntax in Spin1 vs Spin2, colons vs dots)

    However, due to changed pipelining, if you translate code 1:1, it probably doesn't Work Like That, see also https://p2docs.github.io/errata.html#dual-port-ram-simultaneous-readwrite-hazard

    As noted by posters above, it's generally beneficial to actually read the code (big concept) and semantically replace it with ALTS/ALTD instead, since that's less hassle and you can potentially roll an ADD or similar into it, but that's not always possible.

    I did a port of ye 'olde HEL_GFX_ENGINE_040.spin to P2, but I didn't post it anywhere yet. In that I was often able to save 3 instructions translating patterns such as

                  mov       r0, #sprite_scanline_mask       ' r0 = @sprite_scanline_mask
                  add       r0, sprite_tile_x               ' r0 = @sprite_scanline_mask + sprite_tile_x
                  movd      :Write4, r0                     ' modify destination address of the AND opcode downstream to hold address in r0
                  nop                                       ' wait for pre-fetch, so we don't execute self modifying code too quickly
    :Write4       and       0-0, sprite_mask_buffer    
    

    into

                  altd      sprite_tile_x,#sprite_scanline_mask
    .Write4       and       0-0, sprite_mask_buffer       
    

    in that case the .Write4 label is only retained because it's already there, it is no longer needed.
    Note that the P1 code here was not optimal, either.

  • evanhevanh Posts: 16,637
    edited 2025-08-12 18:25

    @Wuerfel_21 said:
    However, due to changed pipelining, if you translate code 1:1, it probably doesn't Work Like That,

    True, two NOPs are needed on the Prop2. Here's the blurb from Silicon Manual:

    EDIT: Oh, looking at this example it looks like Rayman is correct about not using # as well.

Sign In or Register to comment.