Shop OBEX P1 Docs P2 Docs Learn Events
Aliased variables — Parallax Forums

Aliased variables

TwimTwim Posts: 10
edited 2007-07-06 13:56 in Propeller 1
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

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-05 00:32
    Spin does not allow aliases, but it does have provisions for pointers. The best you could do would be to declare a word or long and assign it the address of your array like:
    var word myPtr
          byte myList[noparse][[/noparse]32]
    pub hereWeGo
          myPtr := @myList
          byte[noparse][[/noparse]myPtr] := aValue
          byte[noparse][[/noparse]myPtr][noparse][[/noparse]index] := moreValue
    
    
  • cgraceycgracey Posts: 14,133
    edited 2007-07-05 01:23
    We have accidentally left some info out of the documentation that makes this possible, in a limited sort of way.

    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.
  • TwimTwim Posts: 10
    edited 2007-07-05 13:21
    Thanks, Mike and Chip.
    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
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-07-05 13:57
    Hi Twim,

    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.
  • deSilvadeSilva Posts: 2,967
    edited 2007-07-05 15:00
    Twim said...
    Hello, I am new to the propeller chip..
    It is quite important to understand the memory allocation scheme of SPIN as early as possible - so you can deduce those tricks given to you here for yourself smile.gif

    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 smile.gif
    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 smile.gif ). 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
  • deSilvadeSilva Posts: 2,967
    edited 2007-07-05 15:23
    I should like to add this:
    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 smile.gif )

    Post Edited (deSilva) : 7/5/2007 3:29:33 PM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-07-05 15:39
    Hi deSilva,

    A good description of what's going on. There's just one clarification to be made.
    deSilva said...

    (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 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
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-05 15:44
    deSilva,
    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.
  • KaioKaio Posts: 253
    edited 2007-07-05 17:19
    deSilva,
    deSilva said...

    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 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
  • deSilvadeSilva Posts: 2,967
    edited 2007-07-05 17:53
    :-( I did not check thoroughly. Alas, I am not using the ORG 0 any longer since I recognized its limited value. But this situation is exactly where it will help! And also in cases of extensive use of global space for non-COG matters; but ORGX would be more appropriate for that situation then...

    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 smile.gif 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
  • ericballericball Posts: 774
    edited 2007-07-05 19:13
    deSilva said...
    (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!
    Also remember COGNEW requires ~8000 cycles to load COG-RAM from HUB-RAM, so there's a window of time after COGNEW where any changes to the HUB-RAM variables will be copied into COG-RAM.· Once the HUB-RAM variable is copied to COG-RAM any changes to the HUB-RAM variable won't affect the COG-RAM copy.

    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.
    ·
  • cgraceycgracey Posts: 14,133
    edited 2007-07-05 19:19
    You can have DAT sections fill almost all the 32K. The 496-long limit is only for contiguous assembly instructions. BYTE, WORD,·LONG, and FILE·declarations are not subject to this limitation.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • deSilvadeSilva Posts: 2,967
    edited 2007-07-06 08:21
    Lots of exceptions ... it gets more and more tricky.
    DAT
        ORG 0
                 MOV 0, 0
                 LONG 0, 0, 0,.............
    the_very_end JMP #0
    
    


    is indeed accepted, a problem is reported only for this situation:
    DAT
        ORG 0
                 MOV 0, #the_very_end
                 LONG 0, 0, 0,.............
    the_very_end JMP #0
    


    Thus a good practice would be to always use FIT at the end of every COG definition
    DAT
        ORG 0
                 MOV 0,0
                 LONG 0,0,0,.............
    the_very_end JMP #0
        FIT 496
    
  • deSilvadeSilva Posts: 2,967
    edited 2007-07-06 08:37
    ericball said...
    ... so there's a window of time after COGNEW where any changes to the HUB-RAM variables will be copied into COG-RAM.
    This is not just pure theory! It happened to me when I tried to install 4 nearly identical COGs, distinguished just by I/O ports and other "constants" All turned out to be fully identical - to the last one smile.gif

    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 wink.gif

    Post Edited (deSilva) : 7/6/2007 8:42:47 AM GMT
  • ericballericball Posts: 774
    edited 2007-07-06 13:56
    deSilva said...
    ericball said...
    ... so there's a window of time after COGNEW where any changes to the HUB-RAM variables will be copied into COG-RAM.
    This is not just pure theory! It happened to me when I tried to install 4 nearly identical COGs, distinguished just by I/O ports and other "constants" All turned out to be fully identical - to the last one smile.gif

    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 wink.gif
    Oh yes, it's a little annoying PAR isn't 32 bits.· For my code I have multiple cogs with identical configuration data but I needed to pass in an index which is used to interleave execution (so while cog[noparse][[/noparse]0] is generating output, cog[noparse][[/noparse]1]...cog[noparse][[/noparse]n] are calculating the next sets of output).· What I did is stick a small 8 long table at the end of the cog code which the SPIN code populates with the index by cogid.· (I was using PAR as a HUB-RAM address register for speed reasons, so it wasn't available.)

    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.)
    ·
Sign In or Register to comment.