DRW wrote:I only know constructors from object oriented languages like C++. So, I don't think I will use them in the program.
In this case "constructors" is CC65 specific jargon for a piece of code that runs at startup. More info
here. Destructors are for when the program shuts down, but that's not relevant on the NES, since NES programs don't do that.
I'm not really sure why they added this feature to CC65. Probably for initializing zeropage variables used by the CRT or something? Only a few parts of the CRT use them. In particular, I think the heap allocators (i.e. "malloc" and "free") need them, but you probably wouldn't be using those in an NES game.
If it ever turns out you need them, you can just add
jsr initlib after the other stuff. I think if you don't have an INIT segment in your CFG it will give you an error if you ever accidentally invoke a CRT module that has a constructor, so you should be safe as long as your CFG has no INIT segment.
DRW wrote:Is the call to copydata necessary?
Yes, unless you aren't using the DATA segment at all.
DRW wrote:I know when you declare a non-constant global variable and immediately initialize it, it is put into DATA instead of BSS. I never really understood why. So, I assume you cannot use the variables from the DATA section without calling copydata first?
Yes, exactly that. In C, any variable with an initializer gets its initialization value stored in the DATA segment, which is copied to RAM at startup by the copydata routine.
However, I haven't needed a DATA section until now.
If your CFG file has no DATA segment, then at least you'll get a error if you ever accidentally need it. If you're trying to avoid calling copydata,
don't put a DATA segment in your CFG.
I either declare global variables for general usage or I declare constants. I haven't really found any use for a global variable that can change the value later, but that has to have a definite initialization value. Do you know any?
Like a lot of programming language features, there are always a thousand other ways to get something done; it isn't essential that you be able to initialize variables. It is just one of many convenient features of C. If you want to never use C initializers, that's fine. If you want to use them, CC65 will put them in the DATA segment and it needs to get copied to RAM at startup.
What is cstack in your code?
I must have explicitly allocated an area for the C stack with a .res directive somewhere, rather than just assuming that it goes at the end of the BSS segment or something.