Shop OBEX P1 Docs P2 Docs Learn Events
interleaved array swap (PASM) — Parallax Forums

interleaved array swap (PASM)

ManAtWorkManAtWork Posts: 2,176
edited 2013-12-05 04:52 in Propeller 1
Hi,

in my latest project I'm trying to generate two step/dir signal pairs from one cog. To calculate the timer frequencies and dir bit patterns I have to do relatively complex math operations. The code to execute is the same for both chanels but the data is different. To save cog memory I'd like to use a subroutine call for the two calculations but since there is no stack and no indexed adressing mode this is not easy in PASM. There are many parameters to be passed and the two "state machines" must have an internal memory to remember the state between calls (or in C terminology static local variables).

So I came up with the idea to store parameters and state memory in an interleaved array. Say, all variables for axis no 1 are stored at even adresses and all variables for axis 2 at even adresses. Between the two calls I swap the contents of all even against all odd adresses of the array. So I can write the subroutine without self-modifying code and without long mov-op lists and a third set of variables.

So my code looks something like this:
mainLoop
              call   #CalcStepDir
              call   #SwapArray
              call   #CalcStepDir
              call   #SwapArray
              ...
SwapArray
              movs   :getTmp,#ArrayStart
              movs   :move,#ArrayStart+1
              movd   :move,#ArrayStart
              movd   :putTmp,#ArrayStart+1
              mov    count,#(ArrayEnd-ArrayStart)/2
:getTmp       mov    temp,ArrayStart
:move         mov    ArrayStart,ArrayStart+1
:putTmp       mov    ArrayStart+1,temp
              add    :getTmp,#2
              add    :move,incSrcDst2
              add    :putTmp,incDst2
              djnz   count,#:getTmp
SwapArray_ret ret

incDst2       long      2<<9
incSrcDst2    long      2<<9+2
Of course, the two subroutines could be combined to one, I just let it that way for better readability.

Is this a good idea? How would you do it? Does anybody see a trick to make it more (code space) efficient? Execution time is not that critical. The calculation takes aprox. 200µs for one axis and I have ~1ms cycle time. However, spin is not fast enough.
Sign In or Register to comment.