snes-sdk, tcc816, and large arrays

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

snes-sdk, tcc816, and large arrays

Post by Shiru »

Just thought this information could be useful to someone who want to use snes-sdk and will have the same problem I had, and solved with help of mic and Chilly Willy.

The tcc816 from the snes-sdk is a nice C compiler, but currently it has few problems that could be a real showstopper for any large project (say, just a full screen picture and music).

First problem, rather obvious, is that one piece of data can't be larger than 32K. So if you have a data array that is larger than 32K, you need to split it to few smaller arrays.

Second problem. Compiler puts data into .data section regardless of const. When this section overflows, linker tell you there is no room in .data. You can fix this with a custom tool that will move all the const data to .rodata section. mic made such a tool (source code only), but you may need to change it a bit if you have different data organization in your program.

Third problem. Even with the tool, when you have total amount of const data >32K, you'll get a linker error that there is no room in .rodata now. The problem is neither the compiler nor linker are allocate data into ROM banks automatically. You have do to it by yourself, creating .rodata1, .rodata2 etc sections and putting no more than 32K of data in every .rodata section. You can do it either by creating a custom tool, or by declaring additional .rodata sections in a separate assembly file, including the data with incbin and referencing to the data from C code through extern.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ »

For big data files, like graphics, music, level data, etc. the best thing is probably to incbin them in assembly files rather than converting the data files to C arrays. You don't need to split the files yourself, since the assembler can do that for you:

Code: Select all

.bank 1
.incbin "big_file.bin" read $8000

.bank 2
.incbin "big_file.bin" skip $8000 read $8000

; and so on...

Some other tips:

* The C compiler generates "superfree" sections for the compiled code. This means that the linker is free to put these sections anywhere it sees fit (i.e. where there's room for it). So if you use HiROM you might want to fill up the even banks (0, 2, 4, ...) with garbage to avoid having the linker placing any code or data in those banks, as they won't be directly addressable (you'd have to access them through one of the mirrors, e.g. $4xyyyy).

* There's no way to tell the compiler to place code in the .data section. The assembler/linker won't even let you do it manually IIRC. So what I did was to write all code I wanted to execute from RAM in assembly and putting them in the ROM bank at $018000 (making sure to use word addressing instead of long addressing when these functions call eachother). At startup I would copy all that code from $018000 to $7E8000 and create function pointers to call the copies in RAM.
OzzyyzzO
Posts: 1
Joined: Sun Jun 23, 2024 10:10 pm

Re: snes-sdk, tcc816, and large arrays

Post by OzzyyzzO »

in 2024 is there any way to fix the problem of 'const data' directed to the .data section ?
Last edited by OzzyyzzO on Mon Jun 24, 2024 1:39 am, edited 1 time in total.
Post Reply