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