2.4 Boot Portion of a Typical N64 Program

Thus far, we have tried to paint a picture of how a multi-thread program operates. Starting with this section, we will get into more detailed explanations using a program actually written for the N64.

In an N64 program, first you prepare a thread called the "idle thread." As the name implies, the idle thread is executed when the CPU is free, and it is given the lowest priority. Although the term "idle thread" may not sound familiar, this thread is absolutely essential for an N64 program. The reason is that the N64 program always needs at least one active thread at all times. The idle thread must exist at all times so it can be executed when all higher priority threads become inactive.

You create the idle thread as well as all other threads by calling the osCreateThread function.

List 2-1

void boot(void)
{
  /* Initialize hardware and software */
  osInitialize();

  /* Create and activate the idle thread  */
  osCreateThread(&idleThread, IDLE_THREAD_ID, idle, (void *)0,
    (idleThreadStack + STACKSIZE / sizeof(u64)), OS_PRIORITY_IDLE);
  osStartThread(&idleThread);
}

Usually the idle thread is constructed such that it lowers its own priority and continues to exist after calling several initialization functions and activating the "main thread," which as the name implies is the main thread of the program.

In a simple program, the idle thread basically goes into a loop after it has done its job and no longer needs to execute, as in the idle function (which is the idle thread itself) shown below.

List 2-2

static void idle(void *argument)
{
  /* Initialize VI */
  osCreateViManager(OS_PRIORITY_VIMGR);
  osViSetMode(&osViModeTable[OS_VI_NTSC_LAN1]);

  /* Create and activate the PI Manager thread  */
  osCreatePiManager((OSPri)OS_PRIORITY_PIMGR,
    &PiMessageQ, PiMessages, NUM_PI_MSGS);

  (Parts have been omitted)

  /* Activate the main thread */
  osCreateThread(&mainThread, MAIN_THREAD_ID, mainproc, arg,
    (mainThreadStack + STACKSIZE / sizeof(u64)),
    MAIN_THREAD_PRI);
  osStartThread(&mainThread);

  /* Make itself the lowest priority thread */
  osSetThreadPri(0, 0);

  /* Repeat loop without doing anything */
  for(;;);
}

Typically, the idle thread lowers its own priority and then kills time in an infinite loop after the main thread has been activated.

In contrast to this, the main thread performs a wide variety of operations that vary, depending on the program. In this tutorial, we will take a stepwise approach in our explanation of the main thread, using by way of example of an advanced main thread that we will introduce one part at a time.