Shop OBEX P1 Docs P2 Docs Learn Events
Help with PASM indirect indexing — Parallax Forums

Help with PASM indirect indexing

Agent420Agent420 Posts: 439
edited 2009-09-09 13:26 in Propeller 1
As the Prop does not provide offset indexed register accessing, I am trying to determine the best way to modify random elements of an array when I provide the index (or offset) to the desired element...

I have an array of 32 registers (lpix) that may be modified.

I have two 4 register arrays containing the offset (xoff) and the manipulating data (mpix) that needs to be OR'd with the main array (lpix) if a qualifying value is true (y1-y4).·

This is what I have come up with...· It just seems like a lot of work compared to what I'm used to with processors offerring indexed addressing modes.· Is there a better method?
                        andn    y1,missile_ht   wz, nr  '+4 check if y1 in range
        if_z            mov     lpix_,#lpix             '+4 set line pixel base address
        if_z            add     lpix_,xoff              '+4 add x1 offset
        if_z            movd    :y1,lpix_               '+4 set lpix dest
                        nop                             '+4 movd requires buffer instr
:y1     if_z            or      lpix,mpix               '+4 set pixel
                                                        '* 24 (-166)
                        andn    y2,missile_ht   wz, nr  '+4
        if_z            mov     lpix_,#lpix             '+4
        if_z            add     lpix_,xoff+1            '+4
        if_z            movd    :y2,lpix_               '+4
                        nop                             '+4 movd requires buffer instr
:y2     if_z            or      lpix,mpix+1             '+4                                 
                                                        ' *24 (-142)
                        andn    y3,missile_ht   wz, nr  '+4
        if_z            mov     lpix_,#lpix             '+4
        if_z            add     lpix_,xoff+2            '+4
        if_z            movd    :y3,lpix_               '+4
                        nop                             '+4 movd requires buffer instr
:y3     if_z            or      lpix,mpix+2             '+4                                 
                                                        ' *24 (-118)
                        andn    y4,missile_ht   wz, nr  '+4
        if_z            mov     lpix_,#lpix             '+4
        if_z            add     lpix_,xoff+3            '+4
        if_z            movd    :y4,lpix_               '+4
                        nop                             '+4 movd requires buffer instr
:y4     if_z            or      lpix,mpix+3             '+4                                  
                                                        ' *24 (-94)
 
' Undefined cursor data
x_base                  res     1
y_base                  res     1
idx                     res     1
idy                     res     1
regs                    res     1
mpix                    res     4
mpix_                   res     1
xoff                    res     4
xoff_                   res     1
tpix                    res     1
temp                    res     1
lpix                    res     32
lpix_                   res     1
frame                   res     1
y1                      res     1
y2                      res     1
y3                      res     1
y4                      res     1

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2009-09-09 11:40
    With some little tricks it will be much shorter. For example y1 ... y4 are in a row, xoff values are in a row. The trick is to have a constant that allows to increment the destination part of an instruction by one and one which allows to increment both, destination and source by one. Then you can run the whole thing in a loop that repeats 4 times.
    setup                   ' if you run that code once you don't need setup, as the instructions already have the right values
                            movd    :yaccess, #y1
                            mov     lpix_, #lpix
                            add     lpix_, xoff
                            movd    :y1, lpix_
                            movs    :y1, #mpix
    setup_done
     
                            mov     lp_counter, #3
     
    :yaccess                andn    y1,missile_ht   wz, nr  '
                            add     :y1, inc_dest_n_src     ' this is for not wasting the memory with a NOP - note: this will take effect for the next loop
    :y1     if_z            or      lpix,mpix               '
                            add     :yaccess, inc_dest
                            djnz    :yaccess, lp_counter    ' maybe this one is wrong order?? First lp_counter then :yaccess ... (long time not coded in PASM ;o)
                                                       
    inc_dest_n_src          long    %000000001_000000001
    inc_dest                long    %000000001_000000000
     
    ' here comes your res part
    ......
    
    

    Something like that. You have to debug it by yourself ;o) .. unless til I'm back home.



    Post Edited (MagIO2) : 9/9/2009 11:53:02 AM GMT
  • Agent420Agent420 Posts: 439
    edited 2009-09-09 12:21
    I have used that destination / source addition before, it is a clever trick.

    My problem is that while the y1..y4 and xoff are sequential, the resulting lpix destination will not be (because it is the result of xoff+#lpix and the offset will be different for every value... ie xoff = 1,5,3,2), so I cannot simply incrementally update the lpix destination in your y1: line.

    But you did get me thinking that perhaps I can add the #lpix base address in the area where I am calculating the offset, so I would be storing the lpix addresses I need to reference rather than just the offset (and subsequently needing to calculate the destination address in my example).

    Thanks for your input.

    ·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Agent420Agent420 Posts: 439
    edited 2009-09-09 12:51
    So now I have stored the calculated base addresses that I may need to modify in my xoff array...
                            movd    :y1,#y1                 'init y1 base
                            movd    :y2,#xoff               'init xoff base
                            movs    :y2,#mpix               'init mpix base
     
                            mov     idx,#4                  'start loop
    y1:                     andn    y1,missile_ht   wz, nr  'test cond                          
    y2:     if_z            or      xoff,mpix               'process
                            add     :y1,d1                  'incr y1 dest +1
                            add     :y2,d1s1                'incr y2 dest,source
                            djnz    idx,#:y1                'loop
     
    d1s1                    long    1 << 9 + 1              'd+1, s+1
    d1                      long    1 << 9                  'd+1
    

    But in regards to my original question, if you do need to randomly reference addresses, I guess you would accomplish it by doing the math and then self modifying the code as I did?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-09-09 13:01
    Yep .. self-modifying code is the propellers replacement of indirect adressing. Advantage is that is's much easier to implement in hardware than the indirect adressing mode ... making the die smaller. Otherwise we'd propably only have 4 COGs on one die.
  • Agent420Agent420 Posts: 439
    edited 2009-09-09 13:26
    Bah... sometimes these things make my head spin turn.gif

    I think I have to revert to my original example...· In the revised code, incrementing the destination at :y2 will only result in incrementing the existing address, rather than going to address at xoff+1.

    ie #lpix = $080

    xoff = $080, 083, 090, 087

    ··············· movd··· :y2,xoff·············· 'init xoff base
    ··············· movs··· :y2,#mpix·············'init mpix base

    y2:···· if_z··or········xoff,mpix·············· 'process
    ··············· add···· :y2,d1s1··············· 'incr y2 dest,source

    First time through, :y2 is ok (or $080,mpix).· But then it just gets incremented to $081 rather than $083 where I need it to be.





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Post Edited (Agent420) : 9/9/2009 1:33:41 PM GMT
Sign In or Register to comment.