dynamic linking on Saturn


Established Member
There is a possibility documented to load & execute binaries(modules, non-resident programs) from CD, which access functions like SGL or GFS located in a resident program(and vice versa).

Since that requires to recompile/relink the resident or non-resident program when one of both changes,

is there a possibilitie to use dynamic linking on Saturn?

I've read about the compile and link option -fpic. But the dynamic link support and Global Offset Table are said to be delivered by the OS....



1-5 Creating Resident/Non-Resident Programs

When the amount of data becomes too large and cannot be stored completely

within Saturn's memory, it is possible to preload only the portion of data that

is used. In the case of code, it is possible to use overlays.

However, since an overlay feature is not provided on the Saturn, it is

necessary to structure your application for this purpose as well as to use

linker functions.

Use the following example as a starting point:

1. Creating Resident Programs

A resident program contains minimal file I/O functions as well as shared-use

libraries. There are two ways of executing a non-resident program (module)

that is loaded in from the CD-ROM to a specified address.

a. Call Program from a Specified Address

After the non-resident module is loaded, it is executed from a preset address.

Coding Example:

   fid = GFS_NameToId((Sint8 *)fname); /* fname is the non-resident module */

   GFS_Load(fid, 0, 0x6080000, GFS_BUFSIZ_INF);

  /* The starting address is read from the non-resident module's map file. */

  ((volatile void (*)())(0x6081000))();

 <Declaration of the program at link-time>

   GCC -m2 -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....

In this example, it will be necessary to recompile this program if the address

of the non-resident module's execution start function changes.

b. Define a function with an external declaration and set an address at link-

time for the function with the -defsym option. The function is executed after

the non-resident module is read into memory.

Coding Example:

    extern void SUB_main1( void );

    #define SUB_ADDR  0x06080000

    void main( void )



    /* Example of loading a non-resident module */

      buf[0].type = CDBUF_COPY;

      buf[0].trans.copy.addr = (Uint32)SUB_ADDR;



    /* Executing the non-resident module */




  <Declaration of the program at link-time.>

     GCC -m2 -Xlinker -defsym -Xlinker _SUB_main1=0x06081000 *

      -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....

Since the address of the non-resident module's execution start function is

undefined, set a dummy address first and then set the real address later from

the completed non-resident program's map. It is necessary to link the program

after resetting the address.

2. Creating Non-Resident Programs (Modules)

A non-resident module is a program that is not used constantly within the

application. For example, the program can be only used on a per-game stage

basis. Although multiple non-resident modules may exist, the following

precautions must be taken when they are coded:

a. Caution During Programming

Name the object files so that they are not created with the same function name

contained in the resident program (e.g. the main function may conflict).

b. Caution When Loading the Non-Resident Module

Set the start address of the non-resident module to the same address as the

load address of the resident program.

c. Passing the Resident Program's Map Data

When creating the non-resident module, use the linker's -R option to specify

the resident program's execution file (Kernal.COF in our example)

   GCC -m2 -Xlinker -R -Xlinker kernal.cof.....

With this setting, the resident program's symbols are extracted and included

in the non-resident program. If the same functions exist when libraries that

are being used are linked in the same manner as the resident program, the

information contained in the COFF file specified by the -R option overrides


3. Resetting the Non-Resident Program's Execution Start Address Called by the

Resident Program.

After creating the non-resident program, check the function address called by

the resident program from the map file. Use that address to reset the

execution start function address with the -defsym option at link-time. This

does not need to be done if the address is already the same as the resident

Overlays are statically linked, one way of doing them is to create many linker sections at the same address and then assign each resident set to a distinct section. GameBoy Advance Dev'rs has a working setup for the GBA which you can adapt.
bump for more details, i may use "dynamic" libraries
any way to use DLLib on saturn ?
You'll need a loader to resolve relocations and find symbol addresses. Overlays (with function tables) would be easier to use, as they're linked to absolute addresses.
antime said:
You'll need a loader to resolve relocations and find symbol addresses. Overlays (with function tables) would be easier to use, as they're linked to absolute addresses.
thanks but i don't know how to do that, the only "good" link i've found is this one :


I didn't find the GBA setup for overlays :(
I've found this for PSY-Q / Saturn :)

and this on another source code :

gcc @tdd.gcc -c -o stg_06.obj stg_06.c

ld -o stage6.out -T stageovl.ld stg_06.obj gym.obj -T stageovl.ln -L\gnu\lib\sh2 -lgcc -lc -lgcc -M >stage6.map

coff2bin stage6.out bin\stage6.ovl /b0x6060000


    4.6 KB · Views: 124
The GBA link script can be found here. The basic idea is you have a bunch of sections that will be linked to the same address in memory. You use GCC's attributes to assign code and data to the appropriate section, and create separate binary images for each one, which you can then load into memory as needed.

The same method can be used for linking code to run in locked CPU cache.