CC65 pragma for arbitrary segment, equiv to: #pragma zpsym?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
CC65 pragma for arbitrary segment, equiv to: #pragma zpsym?
by on (#158113)
I want to conveniently point to page $0200 of RAM using a C structure for manipulating sprites. In my nes.cfg file, I've explicitly created a segment for this page. In my sprite.s file I have

Code:
.segment "SPRITE"
_sprite_ram: .res 256


Assume I have an include file for exporting the symbol.

In my sprite.h file I have:

Code:
typedef struct {
    char y;
    char tile;
    char attribute;
    char x;
} sprite;

#define SPRITE_RAM ((sprite*) 0x0200)


However, I would much prefer it look like the following. Does CC65 offer a similar pragma to zpsym for saying a symbol exists in a specific segment? I have been reading the docs, but haven't spotted anything. I've only seen additional pragmas for changing what segment code is written to, but not for symbols in ram.
Code:
extern sprite* sprite_ram;
#pragma symseg ("sprite_ram", "SPRITE")  //I made this up, is there anything like this?


I searched for previous threads on this topic---only found a post by thefox concerning the understood usage of zpsym for using a zp variable in C code.
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158115)
Try this:
Code:
extern sprite sprite_ram[64];

If accessing elements of sprite_ram in this way doesn't produce the result you expect, I'd like to see the assembly language that cc65 generates.
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158116)
What tepples said should work. Another option is to define the array in C code. You can place it in the correct segment with #pragma bss-name, or #pragma data-name if you need to initialize its values.

(NOTE: The compiler is not interested in what segments imported symbols come from, so there is no #pragma for specifying that.)
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158155)
I tried this:

Code:
typedef struct {
    char y;
    char tile;
    char attribute;
    char x;
} sprite;

extern sprite[64] sprite_ram;  //line 11

//#define SPRITE_RAM ((sprite*) 0x0200)


And the compiler output now says this:

Code:
inc/sprite.h(11): Error: Identifier expected


I'm able to get the above to compile with just extern sprite* sprite_ram; but then something else must be wrong as the same code which currently works using my previous define now does not (no sprite on screen).
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158157)
Maybe I'm just really rusty at C. With absolutely everything else commented out except a successfully compiling empty main function, then adding the following:

Code:
typedef struct {
    int x;
} my_struct;

my_struct[1] an_array;


I get:
Code:
src\gglib.c(23): Error: Identifier expected
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158159)
In C, you have to define your arrays like this:
Code:
extern sprite sprite_ram[64];

Or this:
Code:
my_struct an_array[1];
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158161)
Good lord, I think I'm dyslexic. :oops: Thanks. Probably due to spending a disproportionate amount of time with Java over the past 5 years.

*edit* Yup, tepple's original suggestion worked once I realized my brain was putting the [64] in a different place than where it actually was on the screen.
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158163)
GradualGames wrote:
I tried this:
Code:
extern sprite[64] sprite_ram;  //line 11


And the compiler output now says this:
Code:
inc/sprite.h(11): Error: Identifier expected


This is your problem. Java allows the number of elements to be placed before or after the array's name. C allows it only after. You have it before. Try the exact syntax I mentioned before:
Code:
extern sprite sprite_ram[64];
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158164)
Yeah. That did it. Thanks tepples and joe! Kinda embarassing on my part, but I appreciate it. :)
Re: CC65 pragma for arbitrary segment, equiv to: #pragma zps
by on (#158237)
GradualGames wrote:
I'm able to get the above to compile with just extern sprite* sprite_ram; but then something else must be wrong as the same code which currently works using my previous define now does not (no sprite on screen).

Yeah extern sprite* sprite_ram and extern sprite sprite_ram[] are not equivalent, even though C can often make it seem like it. In the first case the pointer (2 bytes) would be literally stored in memory. In the second case the sprite struct contents are stored in memory (but the array can implicitly be casted into a pointer if you do sprite *foo = sprite_ram;).