Indirect Addressing in Spin
Jamesx
Posts: 132
Could someone direct me to a clear explanation of how indirect addressing works in Spin? The explanation in the manual associated with the "@" symbol starts, but I cannot seem to find a complete working example.
What I'm trying to do is have one method (or object) change a variable that can then be read by another method. Not passed like a result, but changing continuously in one cog, to be read by another cog.
Thanks
What I'm trying to do is have one method (or object) change a variable that can then be read by another method. Not passed like a result, but changing continuously in one cog, to be read by another cog.
Thanks
Comments
var_ptr := @variable ' var_ptr must be long but variable can be any type.
Then pass it to the other object, which would access the variable as follows:
LONG[noparse]/noparse]var_ptr] := long_value[color=white]·[/color] '[color=white]·[/color] WORD[noparse][[/noparse and BYTE[noparse]/noparse can also be used where appropriate
-or-
long_value := LONG[noparse][[/noparse]var_ptr]
You would only need to pass the pointer once, i.e., during an initialization routine because once a variable·is defined it will always be at the same address.· Subsequently you can access the variable with the LONG[noparse]/noparse, WORD[noparse]/noparse, and BYTE[noparse]/noparse functions.
If you have two methods within the same object, then you can access the variable from both methods by name and do not need to use the pointer.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Ken Peterson) : 6/24/2008 7:27:47 PM GMT
Thanks for the direction. This is confusing stuff, and it will take a bit to test your suggestions. In the meantime, I'm looking at a the Propeller Manual and it describes the use of @. Using this little program, the output is 0. But it seems to me it should be 5.
Any ideas would be welcome.
J
Post Edited (Timmoore) : 6/25/2008 12:44:50 AM GMT
The following makes sense, and works! The trick was figuring out the special commands (Byte, Word and Long) that are needed to put data into a variable's location, after it's address is passed.
I've got the passing between methods. Next is to figure out how indirect passing works between objects...
J
GetString(@Str)
Oled.PutText (0,2,2, 255,255,255, snum.dec(str))
PUB GetString(Str1)
Byte [noparse][[/noparse]Str1]:=5
To be a pedant with Ken's "var_ptr must be long", as the Prop I memory is only 64K ( 32K RAM, 32K ROM ), any pointer can be held in a word but that won't be the case with the Prop II so it's a good habit to get into using longs for all pointers.
Just to make sure I've got it;
The method modify_d will increment testdata, and when I call the method Display, the new value of testdata will be passed. So, anytime I want to modify a VAR within a single object (on the same cog), I don't need to use the Symbol address operator (@).
Using a new cog, If I do;
Will start a new cog to run the method modify_d. But that new cog won't know where the variable 'testdata' came from, and will likely Smile out. To do this the right way;
The new cog will take a long, starting at addr, and increment. When the first cog reads testdata, it will get the newly written value. It works the same way if you're calling a new object.
In the second example the separately launched Cog will know where testdata is in memory so that will work, but only because it's in the same object ( objects aren't the same as cogs ), but the last example would be necessary if the modify_d() were in another object, and it works even when it isn't. The advantage is that you could change "modify_d(@testdata)" to "modify_d(@somethingElse)" if you needed to and the modify_d() doesn't need to change.
You can also use @Stack rather than @Stack[noparse][[/noparse]0]; means the same and is less typing.
I've just settled on thinking of the long/word/byte qualifiers as something of a type cast.
Using that, I interpret a string in the same way as a C pointer.
So accessing characters in a string like sp := string("Hello") can be done as byte[noparse][[/noparse]sp+index]
(or byte[noparse][[/noparse]sp][noparse][[/noparse]index] as defined by spin). If sp (a pointer) is the address of something it works.
The sp pointer is an address where Hello is stored as "H","e","l","l","o",0 . To get "e" it can
be written as somevar := byte[noparse][[/noparse]sp+1]. I suppose the same statement can be written as
somevar := byte[noparse][[/noparse]sp] which means something entirely different for most languages
(not bad, just different).
The problem I often have with this thinking is with word and long. Expression word[noparse][[/noparse]sp+1]
still points to "e", but it also delivers "el" in some form rather than the more natural,
to me at least, "lo"; to get "lo" one must use word[noparse][[/noparse]sp+2]. It seems word[noparse][[/noparse]sp] would
deliver the same value as word[noparse][[/noparse]sp+2]. The same can be extended to long.
Somebody yell if this is wrong [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔