====== Putting code into the PROGx banks ====== To get more room for code, you can create a number of extra "PROG" banks as declared in [[development:csdk:2.0:configuration|project.json]]. Once you've created those banks, you'll need to mark your functions and variables to indicate when they live in a non-default bank. Functions and const variables have different markers in the form of Compiler Pragmas that should be wrapped around their definitions. See the [[https://cc65.github.io/doc/cc65.html#s7|CC65 documentation]] for full details, but the important parts will be explained here as well. First, an example: #pragma rodata-name (push, "PROG0") const char longWindedDialogueText[] = "According to all known laws of aviation, there is no way a bee shou[...]"; #pragma rodata-name (pop) #pragma code-name (push, "PROG0") void mySprawlingPlayerUpdateFunction() { // absolutely massive switch block // good lord so many if-statements // did you really need to fully implement A-star } #pragma code-name (pop) Here we can see that ''rodata-name'' is used for ''const'' variables, and ''code-name'' is used for actual executable code. These pragmas also take "push" and "pop" parameters so you can have things in the same file assigned to different banks. Now, if you simply call this function or access that data without any preparation you're gonna encounter unexpected behavior or crash. To correctly access this data you'll need to use the [[development:csdk:2.0:headers:banking|Bank Switching API]]. #include "gt/banking.h" //Banking API #include "gen/bank_nums.h" //Generated macros for named bank numbers //no pragmas around this, it should live in the default code bank void mySprawlingPlayerUpdateFunction_wrapper() { push_rom_bank(); change_rom_bank(BANK_PROG0); mySprawlingPlayerUpdateFunction(); pop_rom_bank(); } ===== A warning ===== You really don't want to call ''change_rom_bank'' or ''pop_rom_bank'' directly from code that lives in an alternate bank, since it'll disappear from under you as soon as either of those functions return. You can set up wrapper functions, also know as "trampolines" that live in the default code bank. Or just structure your code so that all your bank changes are called from the default code bank without explicitly setting up wrappers.