Skip to content
MegaMech edited this page Feb 26, 2023 · 41 revisions

Segments can be very confusing especially for those with poor memory retention. As such, this page hopes to explain this in an easily refreshable manner.

  • Data - Geometry, object models, animations, course paths, textures, audio, etc.
  • Displaylist- A list of commands sent to the N64 graphics processor (rsp and rdp). Synonymous to a function or block of code.

All of these elements need to be loaded from the cartridge and placed into ram. The confusing part is how the game magically knows where to find this data on cartridge. In essence, it's very simple.

mk64 creates sixteen segments labelled 0x0 to 0xF.

During compile, the linker gathers all the pieces of the program and puts them together. While doing so, it generates symbols, each containing a rom address. The games memory code calculates the size of the data by subtracting the rom end address from the rom start address. This value gets aligned to the next sixteen bytes. One symbol always points to the next free memory location. This pointers current address is saved prior to adding the data[s size to it so that it points to the next free location (for next time the game loads data from the rom).

Finally the meat and potatoes, set_segment_base_addr is passed a hard-coded segment value between 0-16 along with the location of memory free for writing. This address is saved to the segment table array after having its segment removed: 0x08. Only saving the actual offset of the address allows some fancy tricks. The get_segment_base_addr adds the 0x08 back.

Example: Inspecting the following rom address in a hex editor displays MIO0 in the text panel. This compressed data contains course geography vertex data.

_mario_raceway_vertexSegmentRomStart = 0x88FA10
_mario_raceway_vertexSegmentRomEnd = 0x89B510
size   = end      - start
0xBB00 = 0x89B510 - 0x88FA10
align16(0xBB00)
0xBB00 = (0xBB00 + 0xF) AND NOT F (NOT F is FFFFFFFFFFFFFFF0)

Examples of align16 at work:
align16(0xBB01) = 0xBB10, align16(0xBB0F) = 0xBB10, align16(0xBB10) = 0xBB10, align16(0xBB11) = 0xBB20

Aligning ensures that the next chunk of data is placed on a 0x00 boundary and not an oddball number such as 0x03.

Data is copied to ram and its segment base addr is set:
gSegmentTable[segment] addr & 0x1FFFFFFF;
gSegmentTable[0xF] 802887A8 & 0x1FFFFFFF; // Address saved as 002887A8

Now, if the game has a texture saved at a known offset, ex: 0x210. We can take the value in the segment table and add 0x210. If you add the segment number of 0x08, you now have the textures location in memory.

The goal here is to eventually describe what's in each segment and where to find it in the code-base.

Seg Desc
0 General Purpose; contains the game code addressed as 0x80000000 ex 0x8029E158
1 ?
2 Unknown data
3 Common and Course Specific Textures loaded by func_8029E158. Sets data to segment F for extraction.
4 Course meshes for collision and graphics
5 Course Textures
6 Course data overlay consisting of displaylists, textures, models, actor spawn locations, and path data.
7 Unpacked displaylists which reference course mesh data.
8 ?
9 Course offsets for texture lists and a jump table consisting of segment 06 display list.
A ?
B ?
C ?
D ?
E ?
F Temporary buffer for course mesh MIO0 and packed dlists / Course collisions table (44 byte entries)
Clone this wiki locally