Shop OBEX P1 Docs P2 Docs Learn Events
SX/B Compiler Variables Limits — Parallax Forums

SX/B Compiler Variables Limits

pjvpjv Posts: 1,903
edited 2004-11-16 16:05 in General Discussion
Hi Y'all;

Does the new SX/B compiler have a limit of 20 byte variables, or am I missing something?

When I try to define· more than 20, and hence run into the end of bank 1 memory boundary, I get an "out of memory" type of error message.

I still seem able to declare arrays past this point.

Thanks,

Peter
·

Comments

  • BeanBean Posts: 8,129
    edited 2004-11-12 00:43
    Peter,
    Yes you can have 20 byte variables, but arrays are stored differently.
    If you need more than the 20 byte variables you can alias an array and use it in most cases.

    MyArray VAR BYTE(16)
    MyByte1 VAR MyArray(0)
    MyByte2 VAR MyArray(1)

    Start:
    MyByte1=MyByte2 + 5 ' Same as MyArray(0)=MyArray(1) + 5

    Hope this helps,
    Bean.
  • pjvpjv Posts: 1,903
    edited 2004-11-12 01:05
    Thanks Bean;

    I guess I did not word my question very clearly.

    What I meant was can one have more than twenty single byte variables, and not be forced to have them as an array.

    Also, arrays are limited to 16 bytes each.

    Thanks,

    Peter
    ·
  • BeanBean Posts: 8,129
    edited 2004-11-12 12:10
    The SX28 can only access ram from $08 to $1F (24 bytes) without bank switching, and the compiler need 4 temporary variables to do math and advanced functions (like SERIN).

    All arrays are in the other banks and are accessed using FSR, problem is that the other banks are not contiguous. They are 16 bytes long (hence the 16 element limit on arrays).

    What are you trying to do ? Maybe there is a more effecient way ?

    Bean.
  • pjvpjv Posts: 1,903
    edited 2004-11-12 15:34
    Hello Again, Bean;

    My question about the·20 (4 in bank0 + 16 in bank1)·one byte variabe addressing limit was generic; I can find no reference to such a limit in the documentation.

    Many of my industrial projects are pushing the performance capability envelope of the SX, running as many as·10 simultaneous real-time threads under a 2.5 usec scheduler, and the extra overhead of accessing memory through array based variables is not a help, and hence the question.

    Don't misunderstand me, I think the SX/B compiler looks like a very useful tool,·it would be much better if it permitted single byte variables up to the memory limit, and took care of the bank switching·issues·itself.

    I have been successfully using SX chips since they first appeared, and have been writing embedded software for them for over a hundred· different applications. All of it has been in assembler, although now I'm having a go at a CCS compiler. They are working feverishly at getting the bugs out. In the meantime I'm exploring the SX/B, and seeing how well it fits for bigger applications.·Extension·to the SX48/52 is absolutely essential.

    Peter
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-11-12 16:42
    I know this is off-topic to pjv's real question, but arrays greater than 16 bytes·are capable of being accomplished on the SX, even in SX/B. You just need code to catch "invalid" locations and adjust accordingly. I've discussed the principle in the thread: http://forums.parallax.com/showthread.php?p=468859·. This approach would work for an array up to 32 bytes assuming the array starts at $10, $30, $50 etc (ie always make sure the 5th bit is set, the pseudo-code looks like: if (index >= 16) then index = index + 16) for arrays larger than 32 bytes the code becomes a bit more complicated, basically you preserve the lower 4 bits of the index and you multiply the upper 4 bits by 2 (rl). I leave the task of arrays not aligned to $10, $30, $50, ... to you, just draw the indirect memory map and make sure the lower 16 bytes of any bank are never accessed.

    Of course, once they come out with a SX/B version for the SX48/52, there won't be any limitations on the size of arrays for those chips (besides the total amount of memory on the chip), since the memory map of indirect addressing for the SX48/52·does not suffer the same problem.

    Paul

    BTW when you·create the array you'll have to adjust the size accordingly, ie a 18 byte array would be declared as a 34 byte array.

    PS. I have removed the portion of my original post regarding array index starting at 1 based upon Bean's subsequent post so as not to confuse any newbie SX/B devlopers.

    Post Edited (Paul Baker) : 11/12/2004 9:14:23 PM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-11-12 16:56
    In answer to pjv's true question, my understanding of the SX/B is that there is a little less hand-holding than the basic stamp does (not having programmed for either yet, this is speculation based primarly on John William's article, forgive me if I got the wrong impression from it). More specifically the underlying architecture is not as obfuscated, without examining the internals of how SX/B declares and uses variables, you will need to account for bank switching in SX/B just as you would in assembly. If there is no interprocess communication, and each process needs 16 or fewer variables, you could probably add a line in your task scheduler that would switch the bank before running the next task. Since you have 10 processes running you can also dedicate one or more banks to inter-process communication if you need to do so.

    Paul
  • BeanBean Posts: 8,129
    edited 2004-11-12 17:33
    Just to clarify,
    SX/B Arrays start at index zero.
    SX/B does not use BANK switching. All arrays are accessed by setting FSR and using IND.

    Bean.
  • pjvpjv Posts: 1,903
    edited 2004-11-12 17:36
    Thanks for your comment Paul;

    Back to the basic issue of declaring variables in SX/B;

    Is the limit of declaring single byte variables 20, landing 4 in global bank0 at $0c, $od, $0e, $0f, and 16 in the adjacent space at $10 through $1f. ??

    And one cannot declare single byte variables in any memory space beyond that ??

    Thanks,

    Peter
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-11-15 15:51
    Since I do not have the time to investigate the methodology of variable declaration within SX/B (plus my home computer is sans internet connection at the moment, my usb drive key fob is MIA, and installing SX/B on my home computer via MasterSplitter + 7 floppies is more hassle than I care to deal with at the moment), I can only provide some suggestions to help you determine this on your own. Since you have ASM experience·with the·SXs, try some test programs to see where variables get mapped to, if you find that SX/B is wrapping the 21st variable into the ind register (at location $20) there should be two work-arounds that should get beyond this (well one·should work the other perhaps may not).

    The first (and the one I’m not certain will work) is after the 20th variable, create an array of 16 bytes and label it something like "dummy". You will not use the array; it will just be a placeholder to skip over the memory locations you do not want to use.

    The second is to write a wrapper function for the bank asm opcode, using the bank command would require a different wrapper function for each bank. So before you want to use a variable in a different bank, you would call the wrapper function for the bank the variable you want to access is (don’t forget a wrapper function for the 0th bank). I know this is a hassle but it should work. You can be slightly more clever and make a generic bank by loading one of SX/B's temp variables (or any of the global variables, i.e. $08-$0f) with an address residing in the bank you want to access and the wrapper function would load the fsr with the value of the temp register, the benefit of this is you only need one wrapper function because it takes an argument to switch to the correct bank (the bank instruction requires the bank is known at compile time). A third option for the wrapper function is a sort of fetch operation. Assign a placeholder variable within the first·4 bytes, say "MAPVAR" and say you need 8 bytes beyond the 20 bytes for a total of 28 bytes, and you want the 21st variable (which should reside at $30 in the SX memory map) in basic you would load the index of the variable you want (there are different ways of providing the index:·the absolute address, which can be a hassle from the point of programming in basic since the 16th variable beyond the 20th would be indexed as $3f and the 17th is $50; or the relative address, which is a hassle from the assembly viewpoint, just refer to my prior post for this) your wrapper function would move the contents of the loaded variable, move it to fsr, do an indirect move into MAPVAR, so that when the wrapper returns you have the contents of the variable you want.

    A quick rundown of the three types of wrapper functions:
    ···· using bank opcode, provides the fastest method, only 1 clock cycle per switch but you need a wrapper for each bank you intend to use leading to 16 wrapper functions, or inlining the bank instruction before each access
    ···· using fsr load to bank switch, only one wrapper needed but it takes at least 2 clock cycles, if you are inlining the asm use the bank opcode because this method does not provide any advantage unless it is a function.
    ···· using fsr load and indirect fetch, this is the slowest method, should only be used as·a function but this code would likely be most understandable to a person with little to no asm experience, provided you give the a little explanation of how the asm wrapped function works.

    Now all of this still somewhat skirts the issue of SX/B variable declaration, and it maybe necessary to do both the wrapper and the "bang it into submission" (BIIS or·dummyvar) solution, because if SX/B·does not provide any banking code·in its asm output the BIIS solution will not work, and similarly you need someway of declaring within basic the variable in order to use it. Now lets assume you declare the first 20 variables as VAR0 through VAR19, now VAR0 - VAR3 will reside in the global regs and VAR4-VAR19 occupy the banked variables. Now you could place your inline bank opcode to point to bank 1 (2nd bank) then access VAR4 this would be a different than the bank 0 VAR4. But this is considered extremely poor programming practice and you would absolutely confuse the hell out of anyone trying to understand your code who only knows basic or has no·experience with the SX architecture, but if your code is "for your eyes only" this really·isn't an issue. But if your combine the two (assuming the BIIS solution works as I think it likely will (ie SX/B does not insert appropiate bank instructions)) you could declare your variables as: GVAR0-GVAR3, B0VAR0-B0VARF, B1DUMMY0-B1DUMMYF, B1VAR0-B1VARF, B2DUMMY0-B2DUMMYF, ... (repeat as needed) by prepending the variable names with BX where X is the bank it resides in, and placing an inline bank instruction whenever you·access a variable from·different bank than he one previously accessed, you should be able to provide a clear enough methodology that anyone (including yourself say 5 years from now) should be able to understand what you are doing, an how you are doing it. Of course you may use any actual variable name following BX.

    I hope this finally solves your dilemma,

    Paul

    PS. Of course if the SX/B compiler is so ignorant as to throw its hands up and refuse to compile then none of this may actually work (I call this the "uSoft is god and therefore your a complete idiot for even trying to think" problem·(I battle with MS word every day because of it's unintelligent auto-correct features)). If this is the case·you maybe able to plead with·Parallax to provide a compilation option to ignore "Out of memory" issues since Parallax is responsive to customers. The only problem with this is you'll have to wait until they come out with the next version of SX/B. If you can't wait your likely forced to use arrays, and see my prior post for dealing with those. Actually on second thought,·the fetch (which is a form of an array with a single variable mapped into·a global variable)·and the "Bad programming style" methods·would likely work as well.

    Post Edited (Paul Baker) : 11/15/2004 4:08:46 PM GMT
  • BeanBean Posts: 8,129
    edited 2004-11-15 18:19
    Here is an example of using BANK switching in SX/B.

    Bean.
  • pjvpjv Posts: 1,903
    edited 2004-11-15 19:46
    Thanks Paul;

    In many cases my code needs to be as fast as possible, so mostly I use the bank switch, and·then direct access the memory. The extra overheads of accessing via FSR, although a good technical solution, not always as "sinple and fast" as I would like it.

    Thanks for your interest and your comments.

    Peter
    ·
  • pjvpjv Posts: 1,903
    edited 2004-11-15 19:57
    Hello Bean;

    I·think you nailed it.

    In reading the HELP on variables again, it·certainly states that variables can be aliased, and, perhaps because there was not an exact·example of byte for byte aliasing,·somehow I missed that subtlety. In my test I had simply made a long list (that is, greater than 20) of variables after which the compiler memory error occurred.

    Your answer is the best way to deal with it, although it seems to me the compiler should have been able to handle this aliasing directly. Perhaps they wanted folks to be explicitly aware of the bank switch requirement, and that certainly has been accomplished here.

    Thanks again,



    Peter
  • DWinchellDWinchell Posts: 60
    edited 2004-11-16 02:51
    Hi all;

    Sometimes "Source Code to Assembled Code" Picture is worth a thousand words. The following a layout of variables that could used with the SX/B Compiler. As a matter of fact you could cut and paste the list and use it in your standard SX/B Code Template. Just change the variable names. BE CAREFUL using Aliased (renamed) Variables. I have gotten into trouble as some compiler commands want SIMPLE variables ( one of the first 20 I guess) Seems like you could have an Aliased variable for every array byte but it does not work that way. Mr. Bean will have to explain why :-)

    As you can see the MISTERY is gone the compiler translates the "VAR" defination to an simple "EQU" statment. The SX only has so many registers to use for variables.

    Thank You

    Dave inchell



    ====================· SX/B Source code for declaring Variables ======================

    '===============
    ' Bit Variables
    '===============
    Bit00 Var Bit
    Bit01 Var Bit
    Bit02 Var Bit
    Bit03 Var Bit

    Bit04 Var Bit
    Bit05 Var Bit
    Bit06 Var Bit
    Bit07 Var Bit

    '===============
    ' Byte Variables
    '===============
    Var01 Var Byte
    Var02 Var Byte
    Var03 Var Byte
    Var04 Var Byte
    Var05 Var Byte

    Var06 Var Byte
    Var07 Var Byte
    Var08 Var Byte
    Var09 Var Byte
    Var10 Var Byte

    Var11 Var Byte
    Var12 Var Byte
    Var13 Var Byte
    Var14 Var Byte
    Var15 Var Byte

    Var16 Var Byte
    Var17 Var Byte
    Var18 Var Byte
    Var19 Var Byte

    '=====================
    ' Byte Array Variables
    '=====================
    Array21 Var Byte (16)
    Array22 Var Byte (16)
    Array23 Var Byte (16)
    Array24 Var Byte (16)
    Array25 Var Byte (16)

    Array26 Var Byte (16)
    Array27 Var Byte (9)

    '============================
    ' Aliased (renamed) Variables
    '============================
    Var20 Var Array21(0)
    Var21 Var Array21(1)
    Var22 Var Array21(2)
    Var23 Var Array21(3)

    Var24 Var Array21(4)
    Var25 Var Array21(5)
    Var26 Var Array21(6)
    Var27 Var Array21(7)

    Var28 Var Array21(8)
    Var29 Var Array21(9)
    Var30 Var Array21(10)
    Var31 Var Array21(11)

    Var32 Var Array21(12)
    Var33 Var Array21(13)
    Var34 Var Array21(14)
    Var35 Var Array21(15)

    =============== Assembler or CTRL-L Output ========

    Bit00········ EQU· 0x0C.0······· ;Bit00 Var Bit
    Bit01········ EQU· 0x0C.1······· ;Bit01 Var Bit
    Bit02········ EQU· 0x0C.2······· ;Bit02 Var Bit
    Bit03········ EQU· 0x0C.3······· ;Bit03 Var Bit

    Bit04········ EQU· 0x0C.4······· ;Bit04 Var Bit
    Bit05········ EQU· 0x0C.5······· ;Bit05 Var Bit
    Bit06········ EQU· 0x0C.6······· ;Bit06 Var Bit
    Bit07········ EQU· 0x0C.7······· ;Bit07 Var Bit

    ································ ;'===============
    ································ ;' Byte Variables
    ································ ;'===============
    Var01········ EQU· 0x0D········· ;Var01 Var Byte
    Var02········ EQU· 0x0E········· ;Var02 Var Byte
    Var03········ EQU· 0x0F········· ;Var03 Var Byte
    Var04········ EQU· 0x10········· ;Var04 Var Byte
    Var05········ EQU· 0x11········· ;Var05 Var Byte

    Var06········ EQU· 0x12········· ;Var06 Var Byte
    Var07········ EQU· 0x13········· ;Var07 Var Byte
    Var08········ EQU· 0x14········· ;Var08 Var Byte
    Var09········ EQU· 0x15········· ;Var09 Var Byte
    Var10········ EQU· 0x16········· ;Var10 Var Byte

    Var11········ EQU· 0x17········· ;Var11 Var Byte
    Var12········ EQU· 0x18········· ;Var12 Var Byte
    Var13········ EQU· 0x19········· ;Var13 Var Byte
    Var14········ EQU· 0x1A········· ;Var14 Var Byte
    Var15········ EQU· 0x1B········· ;Var15 Var Byte


    Var16········ EQU· 0x1C········· ;Var16 Var Byte
    Var17········ EQU· 0x1D········· ;Var17 Var Byte
    Var18········ EQU· 0x1E········· ;Var18 Var Byte
    Var19········ EQU· 0x1F········· ;Var19 Var Byte

    ································ ;'=====================
    ································ ;' Byte Array Variables
    ································ ;'=====================
    Array21······ EQU· 0x30········· ;Array21 Var Byte (16)
    Array22······ EQU· 0x50········· ;Array22 Var Byte (16)
    Array23······ EQU· 0x70········· ;Array23 Var Byte (16)
    Array24······ EQU· 0x90········· ;Array24 Var Byte (16)
    Array25······ EQU· 0xB0········· ;Array25 Var Byte (16)


    Array26······ EQU· 0xD0········· ;Array26 Var Byte (16)
    Array27······ EQU· 0xF0········· ;Array27 Var Byte (9)

    ································ ;'============================
    ································ ;' Aliased (renamed) Variables
    ································ ;'============================
    Var20········ EQU· Array21+0···· ;Var20 Var Array21(0)
    Var21········ EQU· Array21+1···· ;Var21 Var Array21(1)
    Var22········ EQU· Array21+2···· ;Var22 Var Array21(2)
    Var23········ EQU· Array21+3···· ;Var23 Var Array21(3)

    Var24········ EQU· Array21+4···· ;Var24 Var Array21(4)
    Var25········ EQU· Array21+5···· ;Var25 Var Array21(5)
    Var26········ EQU· Array21+6···· ;Var26 Var Array21(6)
    Var27········ EQU· Array21+7···· ;Var27 Var Array21(7)


    Var28········ EQU· Array21+8···· ;Var28 Var Array21(8)
    Var29········ EQU· Array21+9···· ;Var29 Var Array21(9)
    Var30········ EQU· Array21+10··· ;Var30 Var Array21(10)
    Var31········ EQU· Array21+11··· ;Var31 Var Array21(11)


    Var32········ EQU· Array21+12··· ;Var32 Var Array21(12)
    Var33········ EQU· Array21+13··· ;Var33 Var Array21(13)
    Var34········ EQU· Array21+14··· ;Var34 Var Array21(14)
    Var35········ EQU· Array21+15··· ;Var35 Var Array21(15)
  • pjvpjv Posts: 1,903
    edited 2004-11-16 04:28
    Hello Dave;

    You are absolutely correct that one can alias single byte variables into elements of an array. In fact,·each array can be as short as one byte, and thereby·has a one-to-one mapping.·The downfall of this with the SX/B is that one can then only access those aliased (array) variables via the indirect FSR approach. Many times we are already pointing somewhere with FSR, and don't want to destroy that previous pointer calculation.

    For my needs it·seems·Bean has the best approach, albeit the programmer needs to deal with the bank switching, which of course was always the case in programming in straight assembler.

    Thanks,

    Peter
    ·
  • Paul BakerPaul Baker Posts: 6,351
    edited 2004-11-16 16:05
    Thanks Bean (and DWinchell) for the clarification, not having direct access to SX/B for testing my theoretical solutions (as explained in a prior post), I was left only to hypothosize potential solutions. I decided to go ahead and stab at possible solutions since an entire weekend had passed and it seemed that pjv's original question was still not definitively answered. It appears in now has been.

    Cheers,
    Paul
Sign In or Register to comment.