Aliased variables
Twim
Posts: 10
Hello,
··· I am new to the propeller chip, and wondered if someone would be kind enough to help with a problem:
I have declared an array of bytes (byte· mylist[noparse][[/noparse]32]·) which i would like to reference in my spin program using
different names such that..
myalias[noparse][[/noparse]0] would reference the value at mylist[noparse][[/noparse]0]
Does the spin language allow the same memory location to be referenced using· different names/ labels
if so how would i declare it?
byte··mylist[noparse][[/noparse]32]
byte·myalias = @mylist
<Subject added by moderator>
Post Edited By Moderator (Paul Baker (Parallax)) : 7/5/2007 5:00:32 PM GMT
··· I am new to the propeller chip, and wondered if someone would be kind enough to help with a problem:
I have declared an array of bytes (byte· mylist[noparse][[/noparse]32]·) which i would like to reference in my spin program using
different names such that..
myalias[noparse][[/noparse]0] would reference the value at mylist[noparse][[/noparse]0]
Does the spin language allow the same memory location to be referenced using· different names/ labels
if so how would i declare it?
byte··mylist[noparse][[/noparse]32]
byte·myalias = @mylist
<Subject added by moderator>
Post Edited By Moderator (Paul Baker (Parallax)) : 7/5/2007 5:00:32 PM GMT
Comments
When you declare VAR's, you can specify a·count-size using 'varname[noparse][[/noparse]size]'. If you put 0 (zero) inside the brackets, it will make a zero-sized variable which will have the same address as the next-declared variable of the same type (byte/word/long).
For example, in the case of:
VAR byte b1[noparse][[/noparse]0], b2[noparse][[/noparse]0], b3[noparse][[/noparse]0], b4, b5
Byte variables b1, b2, b3, and b4 all have the same address, or are the same byte variable. B5 is the next byte in RAM, and is therefore unique.
Sorry about this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.
I presume that access to each element in the array using an alias would be possible
using the following declaration: alias1[noparse][[/noparse]0] , alias2[noparse][[/noparse]0], myList[noparse][[/noparse]32]
Thanks again
Yes. You can use [noparse]/noparse to index from any variable, there is no range checking and not even a check to see that the variable was declared as an array. Using Chip's trick, you can access the aliases exactly the same as the real arrays.
There are three areas where memory is "addressed" so to speak:
(1) Procedure Variables (parameters and the names at the right of the "|" ); those are general purpose simple LONGs kept in a stack, which means their address can change depending on the calling sequence of procedures. It is not wise (though there are safe situations!) to use the address ( "@") of such elements at all.
(2) Global Data Variables (defined in a DAT section) have two absolutely different purposes
(a) They can be copied into a COG in connection with a COGNEW instruction, when situated less than 2 k away from the load point. Assembly instructions will use an apropriate addressing scheme to find them, but as they are allocated in the HUB-Ram they of course can be addressed from SPIN as well. This fact can be utilized for parametrizing COGs; but be aware that after the COG has been loaded there is no longer any connection!
(b) As this is the only place where to preset memory statically, Global Data Variables are also used extensively by many programmers to do that. You can use LONG, WORD or BYTE in that place but no vectors, or by extensive presetting only i.e. ("0,0,0,0,0,0..."). Shun the RES directive until you have formed a clear understanding of what it does do
There is a nice feature allowing you even to statically preset addresses of Global Data within Global Data, though there is catch: Thoroughly read the chapter about the SPIN @@ operator before using it!
You can neither use addreses of local Procedure Variables here (or course!) nor an address of a static variable (which seems not logical at the first glance, but becomes clear when you imagine that there can be many instances of an object's static variables!)
(3) Static Variables are - though for unclear reasons - the most commonly used variables; they are defined in the VAR section (maybe this is why..). Here you can define vectors of any size, but you can make no presets, neither with simple variables nor with vectors. But there is an default preset of zero. The memory is simply layed out as you write the names down. Check this by F8-key and study the nice memory map displayed there. Static area is yellow.
The most tricky thing - and the diffrerence to the really Global Data (2) which behaves like Code - is that Static Variables are "Object Space", each time you "reference" this Object in an OBJ Section an additional copy of this data is allocated (this is done statically at compile time of course, as there is no such thing as dynamic object instantiation in SPIN ). You see this happen by
OBJ
xxx [noparse][[/noparse] 3 ] : "myObject"
e.g. By "seeing" I mean you you really can see it in the left upper window of the Propeller Tool.
Hope this cleared the picture a little bit!
Post Edited (deSilva) : 7/5/2007 3:26:38 PM GMT
It seems that ALL fractions of DAT sections within one Object are collected together and checked that they do not exceed 496 LONGs; RES is correctly included in this calculation.
So what to do when you want to start two or more COGs the accumulated size of which exceed 496 ?
There is no way! You have to write different Objects! (But you can group them again afterwards by a third one )
Post Edited (deSilva) : 7/5/2007 3:29:33 PM GMT
A good description of what's going on. There's just one clarification to be made.
The variables are not quite laid out in memory the order they are in the source. They are laid out with all the LONGs first, then the WORDS, then the BYTES. But within those groups in the order they are in the source. This has the advantage that you don't need to lay out the variables so as to pack them into memory in the optimal way. But the disadvantage that if you are passing a variable block in a COGINIT, you must always use variables of the same length.
Also a tip. The first 32 LONGS use less bytecode and are faster to access than the other variables. So it makes sense to use these for the most critical, commonly used variables. And as a rule of thumb always define arrays after non-array variables.
Post Edited (CardboardGuru) : 7/5/2007 3:46:29 PM GMT
I don't think that's correct. You need to use an "ORG 0" statement at the beginning of each cog's code. The Propeller Tool checks this location counter to make sure its value doesn't exceed 496, but you should be able to have several sections of code in one DAT section, each up to 496 longs in size and each with the "ORG 0" at the beginning.
you can use the undocumented ORGX statement to put more data in the DAT section.
This statement was introduced by Chip to allow compilation of large memory model code.
http://forums.parallax.com/showthread.php?p=615404
Thomas
And CardboardGuru's remark is of great value! Funny, I did not run into problems earlier! It is of course NOT checkable by simply typing F8, as you will see nothing but zeroes but it is exacctly as CardboardGuru explained. Saves you a lot of padding, but makes "Overlay-Techniques" (This is the thread, isn't ist?) much more risky.
Thank you all for your valuable information!!!
Edit:
Forgot to mention: Of course such tricky things cannot be allowed in the DAT area! Padding happens if bytes WORDs or LONGs would not allign. THis is something you can really "see", and I erroniously assumed the same would happen with VAR data...
Post Edited (deSilva) : 7/5/2007 6:10:58 PM GMT
And if the PASM code wants to access the HUB-RAM copy, then it will need to use WRLONG/RDLONG and the address of the HUB-RAM variable will need to be supplied somehow - either via the PAR variable from COGNEW, or via another variable copied in.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.
is indeed accepted, a problem is reported only for this situation:
Thus a good practice would be to always use FIT at the end of every COG definition
There were 3 solutions:
- Wait until each COG was installed (simple and straight forward; waiting for their "real" feed back even gives an additional layer of reliability!)
- using PAR with different parameter blocks (nice and memory waste)
- setting those "constants" into PAR (You are all aware of the 14-bit trickery, aren't you?)
Needless to say I chose option #3
Post Edited (deSilva) : 7/6/2007 8:42:47 AM GMT
In your case, putting your constant block at the top of the cog code (i.e. right after a JMP #start2) and populating it before each COGNEW should work.· (Since the SPIN code can't update the HUB-RAM faster than the cog would read the data.)
·