mr_sleepy
Member
I have spent a couple of weeks now hunting around for information to step7 indirect addressing. There are many, many discussions relating to this subject but none of them quite answer my question specifically so here goes.
I am programming up a recipe function for a new project which involves doing a dynamic lookup of db address areas and then using a block move function to copy recipe params to a working area. I did a sample of 2 or 3 recipes to prove my basic concept was sound so now i want to roll it out to 30 or more. My first option is to copy the 5 or 6 lines of code generated for 2 or 3 recipes and hand modify them to add the extra lines of code but i wanted it to look neater and more graceful than that. This led me once again to indirect addressing for s7. By using the block move function i have cornered myself a little in the restriction of using the any pointer. What i have been looking at is any pointer maths so i can modify the index of the lookup on the fly to find the block of data relevant to the recipe being called.
For reference my any pointer on the block move looks like this p#db351.dbx500.0 word 500. My first job was too find out what the elements of the pointer were so after a bit of googling i found how to export the pointer elements like so
L P##pntrin (i just pass the initial pointer as an input to the fc)
LAR1
L W [AR1,P#0.0]
T MW 1500
L W [AR1,P#2.0]
T MW 1502
L W [AR1,P#4.0]
T MW 1504
L D [AR1,P#6.0]
T MD 1506
then with my element data safely contained in 'real' memory locations i studied its contents to work out the indexes and got this
mw1500 = address type/pointer header
mw1502 = no of data to transfer
mw1504 = datablock number to look up
mw1506 = 0x84 + 000000 where 000000 = address offset * 8 + bit no (0 in my application).
So to get the dynamic pointer i thought it should be easy to do some basic math on these values, load them back into the pointer and then call it on my block move. My code so far is
L P##pntrin (same here, passed the pointer as a parameter)
LAR1
L DW#16#84000000
T #Temp
L "Menu_Display_Data".Menu_Current_Selection
L 1
-I
L L#500
*D
L L#8
*D
L #Temp
OD
T #Temp
T D [AR1,P#6.0]
TAR1
So for clarity what im doing is leaving all the other elements of the pointer as is and modifying only the double word pointer that references my address in the chosen datablock. The hex header of 0x84 stays the same hence the 2 double words getting or'd together.
The first problem is im not really understanding what happens to begin with, ar1 & ar2 are both 32 bit registers, or so im led to believe, but right at the start my instruction l##pntrin loads the any pointer into accu1 which i then transfer into ar1. If my understanding is correct the temp variable pntrin of type any takes up 10 bytes which is 2 bytes longer than ar1 + ar2 when i do the instruction L D [AR1,P#6.0] to get the elements where is the address that im actually looking at? It works because the correct data goes into accu1 and then onwards to my md1506 but i dont know why.
The second problem is that once i modify the double word to contain the value i want to use i can load it back into ar1 as in T D [AR1,P#6.0] but then the subsequent tar1 instruction puts the pointer back to accu1 (i think) but then i try to do T P##pntrin or any other 'any' variable and the compiler doesnt like it. So now im stuck, im either trying to assign the modified pointer to an 'any' variable and using that for the blkmov(sfc20), or im using the ar1 as an input for the blkmov in stl. At least i think thats what im trying to do.
Edit** After reading this post again the other thing i thought about doing was declaring the any pointer as a variable, passing it an external value (which im already doing) and then using the ar1/ar2 to load a local indirect pointer (l#0.0?) and modifying the local data stack this way. Is that possible?
Many many thanks in advance to anyone who feels clever enough to tackle this perplexing problem on a monday morning.
I am programming up a recipe function for a new project which involves doing a dynamic lookup of db address areas and then using a block move function to copy recipe params to a working area. I did a sample of 2 or 3 recipes to prove my basic concept was sound so now i want to roll it out to 30 or more. My first option is to copy the 5 or 6 lines of code generated for 2 or 3 recipes and hand modify them to add the extra lines of code but i wanted it to look neater and more graceful than that. This led me once again to indirect addressing for s7. By using the block move function i have cornered myself a little in the restriction of using the any pointer. What i have been looking at is any pointer maths so i can modify the index of the lookup on the fly to find the block of data relevant to the recipe being called.
For reference my any pointer on the block move looks like this p#db351.dbx500.0 word 500. My first job was too find out what the elements of the pointer were so after a bit of googling i found how to export the pointer elements like so
L P##pntrin (i just pass the initial pointer as an input to the fc)
LAR1
L W [AR1,P#0.0]
T MW 1500
L W [AR1,P#2.0]
T MW 1502
L W [AR1,P#4.0]
T MW 1504
L D [AR1,P#6.0]
T MD 1506
then with my element data safely contained in 'real' memory locations i studied its contents to work out the indexes and got this
mw1500 = address type/pointer header
mw1502 = no of data to transfer
mw1504 = datablock number to look up
mw1506 = 0x84 + 000000 where 000000 = address offset * 8 + bit no (0 in my application).
So to get the dynamic pointer i thought it should be easy to do some basic math on these values, load them back into the pointer and then call it on my block move. My code so far is
L P##pntrin (same here, passed the pointer as a parameter)
LAR1
L DW#16#84000000
T #Temp
L "Menu_Display_Data".Menu_Current_Selection
L 1
-I
L L#500
*D
L L#8
*D
L #Temp
OD
T #Temp
T D [AR1,P#6.0]
TAR1
So for clarity what im doing is leaving all the other elements of the pointer as is and modifying only the double word pointer that references my address in the chosen datablock. The hex header of 0x84 stays the same hence the 2 double words getting or'd together.
The first problem is im not really understanding what happens to begin with, ar1 & ar2 are both 32 bit registers, or so im led to believe, but right at the start my instruction l##pntrin loads the any pointer into accu1 which i then transfer into ar1. If my understanding is correct the temp variable pntrin of type any takes up 10 bytes which is 2 bytes longer than ar1 + ar2 when i do the instruction L D [AR1,P#6.0] to get the elements where is the address that im actually looking at? It works because the correct data goes into accu1 and then onwards to my md1506 but i dont know why.
The second problem is that once i modify the double word to contain the value i want to use i can load it back into ar1 as in T D [AR1,P#6.0] but then the subsequent tar1 instruction puts the pointer back to accu1 (i think) but then i try to do T P##pntrin or any other 'any' variable and the compiler doesnt like it. So now im stuck, im either trying to assign the modified pointer to an 'any' variable and using that for the blkmov(sfc20), or im using the ar1 as an input for the blkmov in stl. At least i think thats what im trying to do.
Edit** After reading this post again the other thing i thought about doing was declaring the any pointer as a variable, passing it an external value (which im already doing) and then using the ar1/ar2 to load a local indirect pointer (l#0.0?) and modifying the local data stack this way. Is that possible?
Many many thanks in advance to anyone who feels clever enough to tackle this perplexing problem on a monday morning.