Q&A- Other System Questions

QA1 What is the difference between libgultra.a, libgultra_d.a, and libgultra_rom.a?
QA2 Abnormal stop with mild...
QA3 The PRENMI event crashes when booting
QA4 How do I directly reference the data existing in the Static Segment?
QA5 Looking at the CPU fault...
QA6 How many record boundaries are there in the spec file?
QA7 I need more detailed explanation for spec file.
QA8 A lot of WARNINGS and FATAL errors occur when linking with ld.
QA9 makemask core dumps if the file is a read-only file.
QA10 Can't the standard C library functions be used?
QA11 The error "cfe:error Make depend:No record locks available" occurs when I compile...
QA12 The warning "dangerous relocation: GP relative relocation when GP not defined appears when mild is executed...
QA13 The message "undefined reference to 'sins'" appears when linking
QA14 What is the size of the executable files for exeGCC?
QA15 How do I run osAfterPreNMI() with OS2.0H? (199909)

Q1 It says in the manual that there are 3 libraries, "libgultra.a," "libgultra_d.a," and "libgultra_rom.a," used for debugging, non-debugging, and master submission, respectively. What are the actual differences between these 3 libraries?

A1 The differences in the compile options used when building each library are listed below.

  libgultra_d:   -D_DEBUG -g 
  libgultra:     -DNDEBUG -O2 
  libgultra_rom: -DNDEBUG -D_FINALROM -O2

The _DEBUG option adds processing such as checking the argument range, etc. (osERROR is called when there is a problem in the argument). Array overflow checks, etc. are used by assert, but assert is disabled when the NDEBUG option is used. _FINALROM deletes segments which are not necessary in the final ROM, such as communication with the host computer, etc. osSyncPrintf, and the like become null functions.


Q2 When mild is executed, the messages

 bfd assertion fail elf.c:1638 
 mild: ld execute fail 

appear, and the message

[This program has performed an illegal operation and has been forcibly terminated.]
[Notify the manufacturer if you are unable to resolve the problem.]

is displayed. When I then open [Details],


is displayed.

The object file that configures the ROM image exceeds 400, 70% of which is mapped to the same address in RAM.

A2 An error will occur if the section which can be managed by the linker (ld) exceeds a maximum value of 512.

KMC kindly distributes ld.out, in which the maximum number of sections is 1024, through Nintendo (Bundled in the OS2.0j CD released March, 1999). Those of you who use more than 512 sections should switch to ld.out.


Q3 I am doing PAL development, but when I do a series of resets, PRENMI events are dropped and PRENMI processing is not performed. As a result the task is stopped and/or the Y scale is not initialized, causing the program to crash.

A3 This problem is a bug in the N64 OS, and is corrected in OS2.0i, Patch 5. However, there is still a possibility that the PRENMI will still be dropped as a result of how the scheduler was created.

The NuSystem 1.2 scheduler had this problem, but it was corrected in NuSystem 2.0 and later.

When the scheduler received a PRENMI message and performed processing to send the message to multiple other threads, if a PRENMI message was generated before the PRENMI message handler was registered in the scheduler, the scheduler would go into standby mode waiting for the next message without sending the current PRENMI message anywhere, ultimately not processing the PRENMI message.

If a PRENMI event occurred between the time that a reset was started and the PRENMI message handler was set in the scheduler, the PRENMI would be dropped.

In this kind of situation, prevent the PRENMI from being dropped by performing processing such as registering a flag that a PRENMI message has been received, then sending the PRENMI message when the PRENMI message handler has been registered. Or register the PRENMI message handler at as early a stage as possible.


Q4 How do I directly reference the data existing in the Static Segment?

Example In static.c,

        Tri triData[]={

is declared, and, currently, if I want to read data in the code onetri.c as


I get all zeroes.

A4 The STATIC_SEGMENT declared in samples such as onetri, etc. is declared in the spec file declarations as


The number declaration segment exists only in ROM in its initial state.

This is transferred from ROM to DRAM in this portion of onetri.c around line 225

*Stick the static segment right after the code/data segment
                (u32)_staticSegmentRomEnd - (u32)_staticSegmentRomStart,
*Wait for DMA to finish
(void) osRecvMesg(&dmaMessageQ,NULL,OS_MESG_BLOCK);

Up until that point, it existed as address information, but it contained no data. The reason for this is to enable the static data for the RSP to be (relocatably) read in as needed. See the section of RSP addressing in the manual. In this figure, SegID is STATIC_SEGMENT (=1, See onetri.h) in the above case, while Segment Offset is offset from the head of the name "static" segment in spec. (When there are multiple number STATIC_SEGMENT segments in spec, the symbol in each one is the offset from the head of the respective segment.) The Segment Base Address defined by SegID is


in the vicinity of line 258 of onetri.c, and the DRAM head address previously read from ROM (the contents of the staticSegment variable) is specified by segID=1(STATIC_SEGMENT). As shown in these materials, the RSP is SegID(Segment Base)+offset(=physical address), and the CPU is KOSEG (the virtual address from 0x80000000). In order to access the segment defined by number from the CPU, it is necessary to perform similar calculations and change the KOSEG virtual address from the RSP virtual address. However, there is no such macro or routine (there is KOSEG, etc., but...) That is because the ability to set Segment Base is internal to the RSP (using (gSPSegment).

Try putting this at the head of the file,


and check the address allotted to the symbol triData which can be seen from the CPU.


Q5 I am using IRIX 5.3, but how should I view CPU faults?

The message displayed on the console when an exception error occurs is as follows.

Fault in thread 6:

epc 0x8002f98c
cause 0x0000005c <Watchpoint exception>
sr 0x0000ff03 <IM8,IM7,IM6,IM5,IM4,IM3,IM2,IM1,KER,EXL,IE>
badvaddr 0x0004dc10

A5 The message displayed on the console when an exception error occurs is as follows.

>Fault in thread 6:
>epc 0x8002f98c <---- Pay attention to this address
>cause 0x0000005c <Watchpoint exception>
>sr 0x0000ff03 <IM8,IM7,IM6,IM5,IM4,IM3,IM2,IM1,KER,EXL,IE>
>badvaddr 0x0004dc10
  1. When a fault is output, pay attention to the "epc" address.

    Note: epc is the Exception Program Count register, and holds the virtual address at which execution of a command is restarted after an error has occurred. This address corresponds to one of the following.

    In other words, by paying attention to this address, you can pinpoint the command that caused the trouble.

  2. In the INDY IRIX 5.3 environment, the following commands are valuable in finding the addresses of commands.

    List of Powerful Debugging Functions

    %gdis -S codesegment.o /* Outputs reverse-assembly data for the sourced
                              program to the console.*/
    %gnm -Bvx simple /* Use this when you can't produce it with nm.  Outputs
                        the command and the virtual address to the console.*/

    Note: Neither gdis nor gnm is displayed on the console in the "man" manual, but try finding them among the optional functions using dis and nm.


Q6 What is the limit on the number of segments which can be registered in the spec file?

A6 There are no limits on either makerom or mild from a programming standpoint.

However, since there is a limit to the number of sections that can be linked by the linker (ld), which internally calls mild, that limit becomes a limit on the number of segments.

The maximum number of sections that can be handled by the linker (ld) in exeGCC ver1.2 is 512. KMC kindly distributes ld.out (in which the maximum number of sections is 1024) through Nintendo (Bundled in the OS2.0j CD released March, 1999). If you are using more than 512 sections, you should switch to ld.out.


Q7 I would like a detailed explanation of the RAM specified by the flags in the spec file.

A7 See Writing the Spec File.


Q8 I am doing development in the IRIX 6.2 environment, but when I create codesegment.o, the following errors are generated by the ld (link editor), and I am unable to create ROM.

ld: WARNING 86: section .rel.text of input file *****.o 
not included as output. 
ld: WARNING 86: section .rel.text of input file *****.o 
not included as output.

After spitting out many WARNINGS, the following messages are displayed:

ld: Giving up after printing 50 warnings.
Use -wall to print all warnings. 
ld: FATAL 87: input sections have not been specified
for inclusion in a.out.
This is typically due to omissions in the -elspec file.
See error messages above.
*** Error code 4

and the operation is terminated. What should I do?

A8 It seems that there is a restriction in the argument of ld.

It seems that you should be able to use ld in two stages, without creating codesegment.o all at once from all of the objects, but by dividing them in half. There is also the technique of using the general purpose segments as a library using ar.


Q9 When makemask is encountered in a read-only file, makemask causes a core dump (Segmentation fault). I have version 2.02. The same symptom occurs in the PC version.

A9 makemask overwrites the actual ROM image file specified in the argument. Since an error must be generated if a read-only file has been specified, a core dump is executed since an error check is not being performed. If there is an upgrade for makemask in the future, we will correct this accordingly.


Q10 Can I use standard C library functions, such as memset and memcpy, etc.?

A10 The standard C libraries are bundled in the "Nintendo 64 Developers Kit" CD-ROM released October 9, 1997.

There is also a standard library in "CodeWarrior for N64," included in the Monegi SmartPak.

Incidentally, bcmp, bcopy, bzero, and sprintf, etc. are included in some N64 OS's. If they are included, they generally are faster.


Q11 When I mount a different file system and run a compile, I get the following error

cfe:error Make depend:No record locks available 

and when I link, I get the error

Make depend: No record locks available***
Error codel(bu21)

How should I handle this?

A11 Since this is probably a problem with UNIX and with your communications settings, contact the manufacturer from whom you bought your equipment.


Q12 When mild is executed, the following warning message appears:

dangerous relocation: GP relative relocation when GP not defined

A12 This message will appear if the compile option -G 0 is not specified. Normally, this option must be included.


Q13 I'm trying to use the N64 OS functions sins() and coss(), but the messages

undefined reference to 'sins' 
undefined reference to 'coss'

appear and I can't get a ROM image. Is something required to use these?

A13 You should be able to use sins() and coss() just like any other functions.

When the program segment is divided into several objects and processing is performed so that the ROM image is created last with makerom(mild), the functions used by all of the other programs must be linked to the objects which are linked to the OS library.

If this is not done, the above kind of undefined errors will occur.

When you use the ld option -u, undefined symbols can be additionally linked to objects. For instance, sins can be forcibly added to the linked objects by linking them using the following option.

-u sins -L$(LIB) -lgmus -lgultra_d -L$(GCCDIR)/mipse/lib -lkmc 


Q14 I am using exeGCC, but I'd like to know how large the executable file is.

A14 If you enter size XXX.out, you will get the following output.

text data bss dec hex filename 
149040 24 1103056 1252120 131b18 game.out

text data bss   Size of each section (bytes)
dec             Total number of sections
hex             Hexadecimal expression thereof


Q15 I am localizing software for sale in the US that was originally developed for use in Japan and when running it on the MPAL 64, pressing the reset button causes a hang up about 30% of the time.
When I looked at the Programming Cautions, it said that you need to execute an osAfterPreNMI() after receiving a pre-NMI message, but because I am using the 2.0H library, there is no osAfterPreNMI().
What should I do about this?

A15 Include the following source code.

#include <ultra64.h>
extern s32 __osSpSetPc(u32); 
s32 osAfterPreNMI(void)