ACNews
#68
30 августа 2017 |
|
Handling global variables in Evo SDK - we shall expand Evo SDK possibilities again
Handling global variables in Evo SDK by Hippiman So, guys, we shall expand Evo SDK possibilities again. Initially SDK had very limited possibilities and was close by functionality to popular ZX Spectrum native editors. There was no disk access and high memory addressing, and the terrible code limitation to 32KB. I described means of overcoming that in my previous publications. However, growing code by dividing it in modules was uncomfortable because of no access to global variables from modules. We needed monstrous manager functions to pass needed parameters in module or write them in high memory. In fact, we could live with that, but the need for extra effort slowed down module calls and their uses. Here I'll tell how to make friends with global (and static) variables of main program from a module. * * * First we go to_temp_ subdirectory in our project (if you don't have it, read ACNews #59 ) and open fileout.map. Scroll to the middle of the file, searching for lines like this: Area Addr Size Decimal Bytes (Attributes) --------------------------------------------------------------- _DATA 00005322 000007C9 = 1993. bytes (REL,CON) Where 00005322 is a beginning of data area. (Of course, it varies for different projects.) Let's closeout.map, we don't need it any more. Open out.asm. It starts with function list, skip it. Find the following: ;-------------------------------------------------------- ; ram data ;-------------------------------------------------------- .area _DATA After that, a list of global and static variables follows like this: _curtime: .ds 2 _nexttime: .ds 2 _nextid: .ds 2 _nextglobid: .ds 2 _bullet1: .ds 1 _roadpos: .ds 1 As we see, there are no addresses, and that's confusing. Although we have this:.ds 2. These are nothing but byte sizes of variables. Using simple computations, we produce the addresses: _curtime 0x00005322 (beginning of data area) _nexttime 0x00005322+0x2 = 0x00005324 _nextid 0x00005324+0x2 = 0x00005326 _nextglobid 0x00005326+0x2 = 0x00005328 _bullet1 0x00005328+0x2 = 0x0000532A _roadpos 0x0000532A+0x1 = 0x0000532B etc. So we know all the addresses of global variables. We just need adding then in a module. For example, this way: static u8 *maxhealth; maxhealth=(u8*)_plmaxhealth; *maxhealth=15; Make sure that addresses can change after every change and recompilation of main module. So hand counting all links is bad idea, we better write a script for this. Here is the listing of perl script that processes main module sources and generates two headers: pointers.h - with function pointers; variables.h - with variable pointers. ┌──────────────────────────────────────────────────────────────┐ #!/usr/bin/perl use strict; my $flag; my $str; my @arr; my $databegin; my $tmp; open FIL,"_temp_\out.map"; open OUT,">pointers.h"; open VAR,">variables.h"; $databegin=0; while($str=<FIL>) { chomp $str; $str=~s/s*//; if(length($str)>0) { @arr=split(/ /,$str); if(substr($arr[2],0,1) eq "_") { print "#define " .$arr[2]." 0x". $arr[0]."n"; print OUT "#define " .$arr[2]." 0x". $arr[0]."n"; } if($arr[0]eq"_DATA" && $databegin==0) { $databegin= hex($arr[31]);#we obtained data area address #and convert it in decimal. } } } close FIL; open FIL,"_temp_\out.asm"; #open main source. $flag=0; while($flag==0) #scroll to beginning of variable descriptions { if(!($str=<FIL>)) { $flag=1; } chomp $str; #print $str."n"; if($str eq "; ram data") { $flag=1; } } $str=<FIL>; $str=<FIL>; $flag=0; while($flag==0)#process variable area { if(!($str=<FIL>)) { $flag=1; } chomp $str; if($str eq ";--------------------------------------------------------") #end of area, we don't need anything after it. { $flag=1; } else { $str=~s/t//g;#remove various trash $str=~s/://g; $tmp="#define ".$str." ".sprintf ("0x%x",$databegin)."n"; $str=<FIL>;#read one more line containing shift chomp $str; $str=~s/t//g; @arr=split(/ /,$str); $databegin+=$arr[1];#we obtained new shift print $tmp; print VAR $tmp; #output the result in header } } └──────────────────────────────────────────────────────────────┘ That's all. Now we can call this script from .bat file that compiles the main module, and we shall always have fresh data about addresses of functions and variables.
Другие статьи номера:
Похожие статьи:
В этот день... 15 октября