SX/B Compiler Variables Limits
pjv
Posts: 1,903
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
·
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
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.
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
·
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.
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
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
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.
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
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
Bean.
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
·
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
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)
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
·
Cheers,
Paul