1.5

Bug information and programming guides for the N64 will be periodically released. All information that will become unnecessary with software (library, etc.) and hardware upgrades used in development will be noted together. Please utilize this information after confirming that the information concerns your specific upgrade.

Contents:
  1. Reset Processing
  2. Processing Flow During Reset
  3. Precautions
  4. About pre-NMI Processing
  5. Sample of pre-NMI Processing

1. Reset Processing

There are two types of reset used in the Nintendo 64. Cold Reset is accomplished by cycling the power OFF and ON, while NMI (non-maskable interrupt) Reset is generated by pressing the RESET button. This document describes the processing methods for resetting the system using NMI.

There are actually 3 reset methods which can be used with the R4000 Series: cold reset, soft reset and NMI, but soft reset is not supported by the Nintendo 64.


2. Processing Flow During Reset

The processing flow when the user presses the RESET button is as follows.

  1. Press RESET button
  2. pre-NMI is generated
  3. pre-NMI processing
  4. NMI is generated
  5. CPU goes to reset vector
  6. CPU executes boot program

The time from Pre-NMI generation to NMI generation is 0.5 seconds or more.

That is, if the finger is removed from the RESET button within 0.5 seconds, this time duration will be 0.5 seconds. However, if the button is continuously pressed for more than 0.5 seconds, the reset time will continue until immediately after the finger is removed (i.e., if the button is continuously pressed for 1 second, reset time will be 1 second).

There is no RESET switch on the current emulation boards, but a pseudo-NMI can be generated by executing a RESET program.

On the other hand, PARTNER-N64 has a switch to reset, however, it is not possible for the software to issue NMI.

It is expected to be improved near future.


3. Precautions

NMI's are generated by the PIf. The PIf's job is primarily to perform the processing for mechanisms which use a serial interface, such as the Controller.

Consequently, in cases where the CPU is constantly monitoring the Controller, there are instances in which the PIF will be BUSY and RESET generation will be delayed.

This creates no problems as long as Controller data are read one time per frame.

In addition, the NMI wait time on current emulation boards is 0.5 seconds or more (around several seconds).


4. About pre-NMI Processing

If the PIf load is at a normal level, a pre-NMI is generated at the time the RESET switch is pressed. The minimum processing that must be performed at the time of the pre-NMI is comprised of the following 4 items:

  1. Stop GFX task
  2. Stop audio task
  3. Don't issue a new PI DMA
  4. Return YScale value to 1(osViSetYScale(1)), if it has been modified.

In other words, all RCP processing is stopped. When 64DD is used, it must also be reset.

Next, why these per-NMI processing is necessary will be explained.

An NMI signal is generated in the Nintendo 64 only for the CPU. No RESET signal is input to the RCP. This is because it is difficult to forcibly terminate graphic and sound tasks which are currently being executed without giving the user an uneasy feeling.

Therefore, if processing in the RCP is not terminated after the pre-NMI is generated, processing in the RCP will continue to be executed even after a RESET. In the worst case, this will have a detrimental effect on the CPU's boot sequence, inevitably causing the CPU to hang up.

In order to avoid this situation, it is necessary to terminate any processing being executed in the RCP after a pre-NMI has been generated.


5. Sample of pre-NMI Processing

In the following example, a sample source code "simple" has been partially modified.

Each thread senses the generation of a pre-NMI by means of an OS_EVENT_PRENMI message, and the necessary processing is performed.

  1. Stopping GFX task


static void gameproc(void *argv)
{
    ...

    while (1)
    {
        ...

        switch (msg->gen.type)
        {
            ...

            if (pendingGFX gen.type)
            {

            ...

            case (OS_SC_PRE_NMI_MSG):
              /* what should we really do here? quit? ramp down volume? */
              alSeqpStop(seqp);
              alSeqpDelete(seqp);
              done = 1;
              break;

              ...

	    }
        }
    }

    alClose(&__am.g);
}

It is possible to stop sound in the same way as graphics by not performing any new processing after generating a pre-NMI. In the above case, the procedure


alSeqpStop -> alSeqpDelete

was used because a standard MIDI sequence player is being used, but if a compact MIDI player is being used, sound would be stopped using the procedure


alCSPStop -> alCSPDelete

while if synthesizer voice is being used by a sound effect, the sound effect would be stopped using the procedure


alSynStopVoice -> alSynDelete 

(however, alSynDelete cannot be implementedat the current time.)

Caution is required when using alSeqpDelete and alCSPDelete, since there is a system anomaly in the N64 OS up to revision 2.0e which makes it possible that the interrupt would continue to be masked.

Because of this, either use patch 1.01, or use OS 2.0g or later, when using these functions.

Processing is also possible which gradually diminishes the sound in the same way as the screen by decreasing the volume in a stepwise fashion. However, stop the execution of new audio tasks when the volume reaches 0.