The idea is, before you start rendering the level, you load any textures you need into your global cache (which can be any size you want, not just 4096 bytes). Then, when the data isn't needed anymore, you mark that part of the buffer as "empty" and you can overwrite it with new data.
You're probably wondering: "Hold on, this global buffer variable is part of the code... Won't it be subject to the exact same 1MB restriction we had before?". The answer is yesno, howeverbecause thisinitialized methodglobal ensuresvariables thatare onlynot theloaded datafrom youROM need(as they're dynamically "created" when your code loads). The downside to this method is loadedthat atyou amight timenot inalways thehave 1MBfull codecontrol segmentover (aswhere opposedthe todata everythingis beinginitialized there)to in memory. The alternative would be:
== Having a buffer somewhere in RAM ==
All we have to do is create a new C file, and in it we place a global buffer just like we did in the previous section. Except this time, we're not going to link this data to our codesegment, rather we'll tell the N64 to reserve this part of RAM for our buffer. We'll need to modify the makefile somewhat, as we'll need to compile our C file into an object file. Lets assume our buffer is in a C file called <code>texbuf.c</code>.
Your makefile should already have a dedicated <code>CODEFILES</code> targetvariable where you put all your C files, and then it gets compiled into one big <code>codesegment.o</code> object file via <code>CODEOBJECTS = $(CODEFILES:.c=.o)</code> and then <code>gcc -o $(CODESEGMENT) -r $(CODEOBJECTS)</code>. The idea now is that you create a new targetvariable, such as <code>DATAFILES</code>, and you place your buffer files here.
<syntaxhighlight lang="makefile">
DATAFILES = buffertexbuf.c
DATAOBJECTS = $(DATAFILES:.c=.o)
</syntaxhighlight>
Now, you'll want to place the <code>DATAOBJECTS</code> in your makefile where it will compile the .o's, '''but not link them to the codesegment'''. Typically, this will be in the target section (such as <code>$(TARGETS):</code> or <code>default:</code>). Example:
<syntaxhighlight lang="makefile">
OBJECTS = $(CODESEGMENT) $(DATAFILES:.c=.o)
$(TARGETS): $(OBJECTS)
$(MAKEROM) spec $(MAKEROMFLAGS) -I$(NUSYSINC) -r $(TARGETS) -e $(APP)
makemask $(TARGETS)
</syntaxhighlight>
Since we're not linking the object file in our makefile, we'll need to do that manually afterwards:
<tabber>
Spec file =
In your spec file, all you need to do is add a new segment, but give it the <code>OBJECT</code> flag instead:
TODO
<syntaxhighlight lang="c">
beginseg
name "texbuf"
flags OBJECT
after "code" // You can use 'address' if you want to specify an exact RAM address to put the buffer at
include "texbuf.o"
endseg
</syntaxhighlight>
You can use <code>#include</code> in your spec file to include a header file with a list of address macros if you want to, and use that macro value in place of raw address numbers or the <code>after</code> keyword.
|-|
Linker script =
TODO
</tabber>
Once it's linked, you're all set! You just need to ensure your array is <code>extern</code>'d somewhere and you can use it without any other changes to your code.
A useful trick, you can <code>extern</code> the codesegment as well:
</syntaxhighlight>
You can use this, for instance, to load your assets right after the code segment by loading them into the address at <code>_codeSegmentRomEnd</code>. You don't ''need'' to create an object file with your buffer as you can just write to any RAM address you seem fit (for instance, you can just define <code>u8* buffer = 0x80000400</code> globally, and then treat it as a array/buffer) but it sure helps as the compiler/linker can potentially catch buffer overflows and/or segment overlapping.
You can see an implementation of thisthe buffer method described in this section [https://github.com/n64brew/N64-Codesplit-Tutorial/tree/main/splitdata-binram here].
== FinalizingManaging thelarge codeprojects ==
After going through all of this code, you probably still have a few wiggling doubts: "How do I manage the loading of data in large projects? How can I tell what assets I have loaded, and what needs to be loaded? How do I tell if my caches are full, thus unable to read more data from the cart?". These questions are answered in the next chapter of the [[Code segmentation guide]], which covers file systems.
TODO
[[Category:Code segmentation guide]]
|