It is currently Sun Oct 22, 2017 3:11 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Fri Nov 11, 2016 11:23 am 
Offline
User avatar

Joined: Sun Sep 26, 2010 10:29 pm
Posts: 35
Hello,
In some documentation if found the possibility to put some data into zero page. This should be done using the following macros before the definition of the variable:
Code:
#pragma bss-name (push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")


My problem is, that I did not find any example for this. Is this the right way to do it?
Code:
#pragma bss-name (push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
static unsigned char my_tiny_variable;


Am I correct that the next definition will be put into common (non-zeropage) RAM? Like this:
Code:
#pragma bss-name (push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
static unsigned char my_variable_in_zero_page;

static unsigned char my_variable_in_common_ram;


And how is the behavior, if I define more than one variable at once? Like this:
Code:
#pragma bss-name (push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
static unsigned char x, y;


Regards
Sebastian


Last edited by -Basti- on Fri Nov 11, 2016 12:01 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Nov 11, 2016 11:43 am 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 558
All variables between the "push" and the "pop" go to ZP. They don't need to be static, it makes no difference even if you only access them in that file.

Code:
#pragma bss-name (push,"ZEROPAGE")
#pragma data-name(push,"ZEROPAGE")
static unsigned char x, y;
unsigned int foo;
#pragma bss-name (pop)
#pragma data-name(pop)

unsigned char not_in_zp;


Top
 Profile  
 
PostPosted: Fri Nov 11, 2016 12:29 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
Also note that bss-name controls uninitialized variables, while data-name controls initialized variables:
Code:
#pragma bss-name (push,"ZEROPAGE")
unsigned int foo; // goes into ZEROPAGE
unsigned int bar = 123; // does NOT go into ZEROPAGE
#pragma bss-name (pop)

#pragma data-name(push,"ZEROPAGE")
unsigned int xyzzy; // does NOT go into ZEROPAGE
unsigned int zaz = 111; // goes into ZEROPAGE
#pragma data-name(pop)

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Fri Nov 11, 2016 1:22 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5730
Location: Canada
You should never change the DATA segment to ZEROPAGE. The DATA segment is a region of ROM that is going to be copied to RAM by the CRT startup before it calls main.

Trying to do this should give a linker warning like: Segment "ZEROPAGE" with type 'bss' contains initialized data. (This should really be a linker error.)

Secondly, for the same reason, you should not use the ZEROPAGE segment for any initialized variables, because the only segment that the CRT is going to initialize is the DATA segment. See copydata.s to see how these things get initialized.

If you did want to use initialized variables on the zeropage, they would need their own segment (which has a load in ROM and run in RAM, like the DATA segment), and at runtime that segment will have to be manually initialized with something like that copydata function. Unfortunately, since that segment wouldn't be called "ZEROPAGE" anymore, the assembler isn't going to know that the variable is on the zeropage anyway, and will emit absolute addresses for it instead, which kind of defeats the purpose of putting it on the zeropage. (The C compiler does not have any mechanism I know of to emit the trailing ": zeropage" necessary for a .segment directive.)


TLDR: don't use #pragma data-name, and don't attempt to put initialized variables on the zeropage.


The other way to create zeropage variables is to define them externally (e.g. in assembly, or even just a separate C module) and then use #pragma zpsym to mark them as a zeropage extern. (This is important for any zeropage variables you are importing with extern, failing to do so demotes them to absolute address instructions.)

So, technically you could have an initialized zeropage variable if you used #pragma data-name with a special segment in an external module, then manually copy that segment's load to run, and then imported them with pragma zpsym, but this is a bit convoluted. Probably way easier just to use an uninitialized zeropage variable, then initialize it explicitly at the beginning of main or somewhere convenient.


Top
 Profile  
 
PostPosted: Sat Nov 12, 2016 2:45 am 
Offline
User avatar

Joined: Sun Sep 26, 2010 10:29 pm
Posts: 35
Thank you all for your explanations :)


Top
 Profile  
 
PostPosted: Sun Nov 13, 2016 9:04 am 
Offline
User avatar

Joined: Sun Sep 26, 2010 10:29 pm
Posts: 35
calima wrote:
All variables between the "push" and the "pop" go to ZP. They don't need to be static, it makes no difference even if you only access them in that file.


Is it also possible, to have multiple zero page section? Like this:

Code:
#pragma bss-name (push,"ZEROPAGE")
static unsigned char x, y;

#pragma bss-name (pop)
...
unsigned char not_in_zp;
...
#pragma bss-name (push,"ZEROPAGE")
static unsigned char z;
#pragma bss-name (pop)


Top
 Profile  
 
PostPosted: Sun Nov 13, 2016 11:07 am 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 558
Yes, you can have multiple sections like that. It's still the same zeropage.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group