Since actual local variables on the stack require more ROM space and more CPU time, I'm trying to come up with an efficient and comfortable way of reusing some global zeropage variables and use them like local variables.
Since my game requires quite a bit of variables, it wouldn't be enough to declare distinct global variables for each function that I only use inside this function. (Or in case of C: Declaring local static variables.)
So, if I neither want to use local variables on the stack, nor global non-zeropage variables, I have to find a way to reuse some zeropage variables.
My currently planned attempt is this:
I declare a bunch of general-purpose variables, but in several "layers" or "levels": A, B, C etc.:
AByte1
AByte2
AByte3
AByte4
AInt1
...
BByte1
BByte2
...
CByte1
CByte2
...
If a function needs local variables and it either doesn't call any other function or it only calls other functions that don't need local variables, this function would use the A variables. Also, the name of the function would get a postfix:
ProcessHero_vA
--> uses A variables
If a function calls another function that already has the A postfix, then this new function uses the B variables and gets a B postfix:
ProcessAllCharacters_vB
--> uses B variables
--> calls ProcessHero_vA
If a function doesn't use local variables itself, but calls other functions that do, then this function of course always gets the highest postfix as well, because those temporary variables are used inside this function via the other functions:
ProcessGameLoop_vB
--> uses no variables
--> calls ProcessAllCharacters_vB
--> Therefore, ProcessGameLoop needs to get the _vB postfix because the B variables are in use while ProcessGameLoop is running (via ProcessAllCharacters), so the function that calls ProcessGameLoop couldn't use the B variables itself, but would have to use the C variables.
In the actual code, I would of course rename the variables. I wouldn't work with AByte1 etc. directly:
#define currentDirection_ AByte1
(The name gets an underscore as a postfix, so that there cannot be any name clash or compiler issue if you happen to have an actual local static variable named currentDirection in your code. Since #define would replace any instance of its name without regard for context.
In Assembly itself, the underscore wouldn't be necessary because this:
currentDirection: .res 1
currentDirection = AByte1
would be a compiler error anyway.)
The layer system is done, so that functions who call each other cannot accidentally overwrite each others' values:
If you have a function DoSomething_vA and you suddenly find out that this function needs to call another function that also has the _vA postfix, then you have to rename DoSomething_vA to DoSomething_vB and use the B values instead of the A values:
Rename
#define currentDirection_ AByte1
to
#define currentDirection_ BByte1
Then you can let the compiler find all instances of the old name DoSomething_vA, so that you can rename these as well as and any other function that calls DoSomething to reflect the new layer of variables.
So, that's my attempt to use zeropage variables as reusable local variables.
Do you know of any alternate way that might be better?
Since my game requires quite a bit of variables, it wouldn't be enough to declare distinct global variables for each function that I only use inside this function. (Or in case of C: Declaring local static variables.)
So, if I neither want to use local variables on the stack, nor global non-zeropage variables, I have to find a way to reuse some zeropage variables.
My currently planned attempt is this:
I declare a bunch of general-purpose variables, but in several "layers" or "levels": A, B, C etc.:
AByte1
AByte2
AByte3
AByte4
AInt1
...
BByte1
BByte2
...
CByte1
CByte2
...
If a function needs local variables and it either doesn't call any other function or it only calls other functions that don't need local variables, this function would use the A variables. Also, the name of the function would get a postfix:
ProcessHero_vA
--> uses A variables
If a function calls another function that already has the A postfix, then this new function uses the B variables and gets a B postfix:
ProcessAllCharacters_vB
--> uses B variables
--> calls ProcessHero_vA
If a function doesn't use local variables itself, but calls other functions that do, then this function of course always gets the highest postfix as well, because those temporary variables are used inside this function via the other functions:
ProcessGameLoop_vB
--> uses no variables
--> calls ProcessAllCharacters_vB
--> Therefore, ProcessGameLoop needs to get the _vB postfix because the B variables are in use while ProcessGameLoop is running (via ProcessAllCharacters), so the function that calls ProcessGameLoop couldn't use the B variables itself, but would have to use the C variables.
In the actual code, I would of course rename the variables. I wouldn't work with AByte1 etc. directly:
#define currentDirection_ AByte1
(The name gets an underscore as a postfix, so that there cannot be any name clash or compiler issue if you happen to have an actual local static variable named currentDirection in your code. Since #define would replace any instance of its name without regard for context.
In Assembly itself, the underscore wouldn't be necessary because this:
currentDirection: .res 1
currentDirection = AByte1
would be a compiler error anyway.)
The layer system is done, so that functions who call each other cannot accidentally overwrite each others' values:
If you have a function DoSomething_vA and you suddenly find out that this function needs to call another function that also has the _vA postfix, then you have to rename DoSomething_vA to DoSomething_vB and use the B values instead of the A values:
Rename
#define currentDirection_ AByte1
to
#define currentDirection_ BByte1
Then you can let the compiler find all instances of the old name DoSomething_vA, so that you can rename these as well as and any other function that calls DoSomething to reflect the new layer of variables.
So, that's my attempt to use zeropage variables as reusable local variables.
Do you know of any alternate way that might be better?