[solved]cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

[solved]cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

I tried four different ways

1. Invalid:
#pragma code-name ("BNK05")

typedef struct {
u16 map_org;
u8 map_alt;
u8 prg_mode;
u8 chr_mode;
u8 wram_en;
u8 xram_en;
u8 prg_bank_a;
u8 map_sub;
} MapDB;

#pragma rodata-name ("BNK05")

static const MapDB map_db[] = {
#include "map_database.h"
};

2. I replaced the compilation control statement with:

#pragma rodata-name (push, "BNK05")

Still invalid



3. Based on 2, I added a line at the end of the global variable:

#pragma rodata-name (pop)

An error was reported and the message "segment name stack is empty" was prompted(how could it be? )


4. I wrote this before the global variable

#pragma code-name ("BNK05")
#pragma rodata-name ("BNK05")

These above two sentences are continuous without any other code before defining global variables.
Wonderfully, the compilation passed, but the generated RODATA may overwrite the RODATA of other subsequent files.


My fault, a simple syntax error. I inserted a compilation control macro, but # pragma was blocked
Last edited by aquasnake on Tue Sep 13, 2022 9:51 pm, edited 2 times in total.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by rainwarrior »

I have used "#pragma rodata-name" successfully in the past... what exactly is the error in the cases that didn't work? Are you allowing it to generate the intermediate assembly file? Usually that gives good diagnostic information about what went wrong.
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

Similar problems have been fed back by many people on GitHub. Previously, the BSS segment also had the same bug. The C compiler will insert the dynamic data into the fixed non-ZP RAM segment by default, whether you specify it or not.

I can realize that at first, the compiler author regarded BSS,HEAP, DATA and RODATA segments as a design concept that can not be bank switched (it is impossible to determine whether this concept is right or wrong, and it can only be tested under certain circumstances to see if it is meaningful)

For BSS, HEAP, and DATA, I really do not need use bank switching. On the NES platform, the console has 2KB of system RAM built in. I do not need to add other RAM to store real-time variables (for other 6502 platforms, it may be necessary to extpand RAM)

But RODATA must support bank feature. For example, I have a 16KB static array,and the compiler stores it in the fixed PRG segment. Then I can't do anything.

The above issue only appears in the C file. Of course, if I write this file in assembly, there is absolutely not an issue
Last edited by aquasnake on Tue Sep 13, 2022 7:53 pm, edited 2 times in total.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by rainwarrior »

Well, could you share an example of exactly what's wrong? From your description I don't understand what the error is enough to be able to diagnose or help... Can you at least post a sample of the malformed assembly .s output vs. the .c that generated it?

This is a feature I use frequently in cc65, and I do use that pragma to switch banks w.r.t. RODATA. If there's a bug with it, I'd like to help report it and maybe get it fixed, so that I don't have to run into it myself eventually.
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

rainwarrior wrote: Tue Sep 13, 2022 7:42 pm Well, could you share an example of exactly what's wrong? From your description I don't understand what the error is enough to be able to diagnose or help... Can you at least post a sample of the malformed assembly .s output vs. the .c that generated it?

This is a feature I use frequently in cc65, and I do use that pragma to switch banks w.r.t. RODATA. If there's a bug with it, I'd like to help report it and maybe get it fixed, so that I don't have to run into it myself eventually.
1. Invalid:
#pragma code-name ("BNK05")

typedef struct {
u16 map_org;
u8 map_alt;
u8 prg_mode;
u8 chr_mode;
u8 wram_en;
u8 xram_en;
u8 prg_bank_a;
u8 map_sub;
} MapDB;

#pragma rodata-name ("BNK05")

static const MapDB map_db[] = {
#include "map_database.h"
};

2. I replaced the compilation control statement with:

#pragma rodata-name (push, "BNK05")

Still invalid



3. Based on 2, I added a line at the end of the global variable:

#pragma rodata-name (pop)

An error was reported and the message "segment name stack is empty" was prompted(how could it be? )
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by rainwarrior »

What is "invalid" about 1 and 2? Was there an error message, or did it produce bad code? What assembly did they generate?

For 3, that looks like the correct syntax for push/pop pragmas, so I can't speculate what went wrong with just that description. (At least, push/pop does work as expected for me with rodata-name pragma, so I haven't been able to write an example that confirms a problem.)

I think I would expect a problem with all 3 in your first post, even 4. I believe there have been errors in the past because the compiler expects different segments for RODATA and CODE, so I didn't think that was valid to do, but it's possible that a solution for that desire eventually was put in?

I have always used different segments for RODATA and CODE, even if they belong to the same bank. I believed this was a requirement, and it might be.
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

rainwarrior wrote: Tue Sep 13, 2022 7:42 pm Well, could you share an example of exactly what's wrong? From your description I don't understand what the error is enough to be able to diagnose or help... Can you at least post a sample of the malformed assembly .s output vs. the .c that generated it?

This is a feature I use frequently in cc65, and I do use that pragma to switch banks w.r.t. RODATA. If there's a bug with it, I'd like to help report it and maybe get it fixed, so that I don't have to run into it myself eventually.

Code: Select all

.segment	"RODATA"

_map_db:
	.word	$0000
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.word	$00DA
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$01
	.word	$008F
	.byte	$00
	.byte	$00

...
...
...

The table is too large to be posted completely. I expect it to be stored in "BNK05", and the compiler actually put it in "RODATA“
As a result, the linking was not successful at all, indicating that the RODATA space exceeded
ERROR.png
ERROR.png (3.93 KiB) Viewed 1826 times
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

By the way, the cc65 executable file I use is the Windows snapshot version released in November 2019
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by rainwarrior »

Well, I tried copy pasting your struct and data table into my own test program to try and duplicate the problem, but I can't seem to. I'm getting it relocated to a different segment like I expect. So, unfortunately I'm not able to create a usable example to diagnose a bug. :(

If it's possible for you to share a complete example that compiles with the error (I guess all that is needed is a C file, if it doesn't have any includes... the linker CFG doesn't matter here), I'd be happy to take a look. I can't seem to make the same problem happen from just these snippets though.

(I have no idea if there are differences in this regard between current snapshot and 2019, though. I'm testing with a much more recent one.)
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

rainwarrior wrote: Tue Sep 13, 2022 8:11 pm
I have always used different segments for RODATA and CODE, even if they belong to the same bank. I believed this was a requirement, and it might be.

Maybe I ignored this, I'll try
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: cc65 cannot output RODATA to a specified bank with pseudo instructions in C language?

Post by aquasnake »

Code: Select all


.segment	"RODATA"

.segment	"BNK05"
_map_db:
	.word	$0000
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.word	$00DA
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$01
	.word	$008F
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$02
	.word	$00AA
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$00
	.byte	$03
It seems OK this time
The problem is in myself. No problem with cc65.
Thanks to rainWarrior.
Post Reply