interleaved array swap (PASM)
ManAtWork
Posts: 2,262
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:
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.
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.
