Pnut arrays?
in Propeller 2
I'm trying to re-write a program to take advantage of the P2 block moves instead of just moving individual values into and out of Hub ram.
However... I can't figure out how to manipulate values indexed from a start location with Pnut.
I can reserve blocks of cog memory with RES for instance:
VALSX res 8 ( which I THINK reserves 8 longs in memory)
but I've tried various combinations of VALSX[1], VALSX+1, @VALS etc and haven't managed to make it work. Is there an example of how to access a value indexed from a starting cog memory location?

Comments
you have code in a cog needing indexed access into a HUB array or indexed access into a COGram array or indexed access into the LUTram
because all work different
more input,
Mike
alts index, #valsx ' replace next instruction's S field with valsx+index add x, $-$ ' turns into add x, {substituted valsx+index from previous instruction}The $-$ (or 0-0) is a conspicuous placeholder value that's often used to denote fields that get replaced by alt[sdr] or by self-modifying code.I need to move data in blocks, first from Hub memory to CogA's ram memory ( blocks of about 25 variables. Let's say they are going from hub ram locations 5000 - 5024 to CogA ram locations 475-499 )
I'm currently doing this with individual RDLONG instructions into individual variables but I know I'm wasting a lot of program space.
I do calculations on that data then move the "Answers" into 20 variables in the shared LUT and set a LUT "flag" that triggers CogB into action.
CogB loads those 20 variables from the shared LUT into it's RAM using individual RDLUT instructions then uses those variables to do its operation. When done, CogB puts the resulting data back into another location in the LUT which CogA uses for feedback on it's next setup for CogB.
This is what I'm doing now: setting up pointers, moving the data individually, then using those values in my control routine. What I'd LIKE to do is have my variables moved into memory in a block, then only change a base pointer to the data for the next operation. This would let me "Hot Swap" data eliminating the several microsecond delays I have now from one operation to the next.
' first set up pointers to all the input data MOV spd_ptr, ##3010 ' spd_ptr points to the current speed value variable. Hub data > Speed mov maxspd_ptr, ##3014 mov minspd_ptr, ##3018 mov ramp1steps_ptr, ##3022 mov ramp1rate_ptr, ##3026 mov ramp2steps_ptr, ##3022 mov ramp2rate_ptr, ##3026 . . . mov ramp5steps_ptr, ##3054 mov ramp5rate_ptr, ##3058 mov ramp6steps_ptr, ##3062 mov ramp6rate_ptr, ##3066 ' now load the data pointed to by the pointers rdlong speed, spd_ptr rdlong maxspeed, maxspd_ptr . . (Etc)Doing this same thing in a block move should save time and memory
To USE that data, In spin, it would just be something like:
I'm not sure how to index from the start of the block (VALS[0] +1, +5, etc. ) in P2 assembly to use the values in the other variables.
I just saw your info Electrodude, I'll see if I can decipher how to use it to do what I need. Thanks!
( but if you know of any sample code that does some of the things I mentioned, I'd love to see some working examples)
KenB
mov PTRA, ##3010 ' spd_ptr points to the current speed value variable. Hub data > Speed rdlong speed, PTRA++ rdlong maxspeed, PTRA++ ...there is also another way I havn't tested yet, but it is from @Cluso99 so it will probably work
mov PTRA, ##3010 ' spd_ptr points to the current speed value variable. Hub data > Speed setq #numbers of longs -1 rdlong speed, PTRAIt looks like you are wasting a lot of code space...
Enjoy!
Mike
MOV PTRA,##$3010 (missing $)
use
LOC PTRA,#$3010
as it saves an instruction, and that's what LOC is for.
thanks,
Mike
I managed to get a program indexing to data in an array using the alts instruction. I thought I was good to go when I tried to comment out some unused code at the end of the program. When I did this, the program stopped working correctly. ( unusual delays got added to the operation ) Also, if I comment out the unused MOV loopcnt, #0 in line 76, the operation changes also.
I have tried this same program compiled with Pnut AND the spin2 compiler. I have tried it running in cog 0 and
( as here ) running it from an initializing cog. All work the same. I suspect the problem is my understanding of the ALTS instruction, but for the life of me, I don't understand why commenting out unused code would change the functionality of the "Running" code. Can anyone spot what I'm missing? I'd like to post (correctly working ) code as an example of how to use ALTS Base + index but it's obvious I'm missing something. Any clues what?
( the program blinks LEDs on the P2-EV board according to a group of variables with the LED port addresses in them )
{ This is a sample program using the "alts" instruction to index to data in an array or a variable indexed in a sequential group of variables. A pointer called "PBASE" points to the start of the memory where you want to pull variables from PBASE is initialized by moving the address of the first value into it using: " MOV PBASE, #V " (V being a variable name at the start of the block of data to be indexed into. an index value called "INDX" is added to the PBASE location to let you pull values There is an oddity that I haven't been able to fix or understand: When you comment out the (unused) movedatain function, the overall operation changes. Ken B } CON _XTALFREQ = 20_000_000 ' crystal frequency _XDIV = 4 '\ '\ crystal divider to give 5.0MHz _XMUL = 72 '| 180MHz '| crystal / div * mul to give 360MHz _XDIVP = 2 '/ '/ crystal / div * mul /divp to give 180MHz _XOSC = %01 'OSC ' %00=OFF, %01=OSC, %10=15pF, %11=30pF _XSEL = %11 'XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms) _XPPPP = ((_XDIVP>>1) + 15) & $F ' 1->15, 2->0, 4->1, 6->2...30->14 _CLOCKFREQ = _XTALFREQ / _XDIV * _XMUL / _XDIVP ' internal clock frequency _SETFREQ = 1<<24 + (_XDIV-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSC<<2 ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00 ' setup oscillator _ENAFREQ = _SETFREQ + _XSEL DAT org 0 '+-------[ Set Xtal ]----------------------------------------------------------+ entry hubset #0 ' set 20MHz+ mode hubset ##_SETFREQ ' setup oscillator waitx ##20_000_000/100 ' ~10ms hubset ##_ENAFREQ ' enable oscillator '+-----------------------------------------------------------------------------+ waitx ##_clockfreq*5 ' just a delay to get pc terminal running coginit cognum1, #@blinkrun ' init cog1 for the movement function cogstop #0 ' terminate the startup cog. cognum1 long 2 ORG 0 Blinkrun drvh #60 drvh #61 ' TURN OFF THE TWO LED'S THAT TEND TO STAY HIGH FOR A WHILE ' NOW PUT THE LED PORT ADDRESSES INTO THE MEMORY LOCATIONS THAT WILL BE USED IN THE INDEXED LOOKUP MOV P1, #56 MOV P2, #57 MOV P3, #58 MOV P4, #59 MOV P5, #60 MOV P6, #61 MOV P7, #62 MOV P8, #63 '*** note, these above variables must be defined sequentially ( AT THE END OF THE CODE ) for the lookup to work correctly blinkitstart ' Set up your memory pointers: MOV INDX, #0 MOV PBASE, #p1 ' this sets the base address to the address of p1 ' Set up your counters : MOV blinkcount, #3 ' do the main loop 3 times MOV loopcnt, #0 ' used to index the data to another position. blinkitloop ' drvnot #63 ' TOGGLE THE P63 LED (just to show the loop is working) MOV INDX, #0 ' set the base +pointer to zero each time through the loop ' blink the first LED pointed to: alts PBASE, INDX ' replace next instruction S field with PBASE+index mov pt, $ ' $ is replaced with the value pointed to by PBASE + index in this case p1 which is set to #57 drvl pt ' turn the LED on. waitx waitime ' pause for a while drvh pt ' now turn the LED off waitx waitime ' and wait again. ' now point to the next port location and do the same thing ' blink the second LED pointed to: add INDX, #1 ' incriment the index pointer to point to the value in p2 alts PBASE, INDX ' replace next instruction source field with valsx+index mov pt, $ drvl pt ' LED on waitx waitime drvh pt ' LED off waitx waitime ' point to the next port location and do the same thing ' blink the third LED pointed to: add INDX, #1 ' incriment the index pointer to point to the value in p3 alts PBASE, INDX ' replace next instructions S field with valsx+index mov pt, $ drvl pt ' LED on waitx waitime drvh pt ' LED off waitx waitime sub blinkcount, #1 ' subtract 1 from the blinkcount counter cmp blinkcount, #0 wcz ' see if you're at zero yet IF_NE jmp #blinkitloop ' if you ARE NOT at zero, jump back to the start of the 3 led blink function again. ' otherwise pause a moment ane reset the blinkcount counter ' waitx ## 50000000 mov blinkcount, #4 ' this dertermines how many times the inner 3 led blink function loops add pbase, #1 cmp pbase, #61 wcz if_a jmp #blinkitstart ' if you're above port 61 restart everything again jmp #blinkitloop ' otherwise do the loop again cogstop #2 ' terminate the cog if you get this far . ' none of the following code SHOULD make any difference to the program operation, but it does. ' { ' if you remove the ' to comment out this line and the one in front of the pairing bracket, the program works oddly . movedatain add loopcnt, #1 cmp loopcnt, #8 wcz IF_b jmp #setnext ' if the loopcnt is < 4, index to the next value group ' otherwise, jmp #blinkitstart ' to reset everything setnext mov pbase, #p2 ' drvnot #62 mov loopcnt, #9 add pbase, #1 ' otherwise, incriment the base of the pointer and do the loop again. jmp #blinkitloop ' } ' other bracket to remove waitime long 10000000 pt long 0 PBASE long 0 INDX long 0 p1 long 0 p2 long 0 p3 long 0 p4 long 0 p5 long 0 p6 long 0 p7 long 0 p8 long 0 p9 long 0 p10 long 0 p11 long 0 blinkcount long 0 loopcnt long 0It's been years (decades) since I've done pointers in Assembly. I'm trying to get the hang of the P2's instruction set before I start working with the P2 in Spin or C++.
With minimal documentation ( that I know is being diligently worked on ) and new tools, some of this doesn't click the first time through my brain.