Introduction to N64 SI Devices

Introduction
This chapter explains the following basic topics related to SI devices.

What is an SI Device?
An SI device is the name for any type of peripheral device that is connected to the joybus, external joybus or joyport, and accessed by the PIf via the serial interface (SI).

The joybus is a signal line that directly connects the SI device to the *PIf. Examples of SI devices that connect via the joybus are the Standard Controller and the Voice Recognition System. These devices are used by inserting them into the controller port on the front face of the N64 Control Deck. The ports are designated starting from the left as **Port 0, Port 1, Port 2 and Port 3.

The external joybus is the name for the joybus signal line exiting from the game pak. An example of an SI device connected via this line is the EEPROM inside the game pak.

The joyport is the signal line located inside the Controller at the insertion site for other SI devices, such as the Controller Pak and the Rumble Pak. These SI devices are attached using the joyport connector which is located on the back of the Controller.

* PIf is the name of the IC chip which plays an intermediary role when the CPU accesses an SI device.

** Controllers inserted into ports 0,1,2,3 are designated as Controllers 1,2,3,4.

Types of SI Devices
There are two types of SI devices. A "direct-type" SI device connects to the joybus or the external joybus and communicates directly with the PIf. A "pak-type" SI device is used via a connection to the Controller's joyport. Below is a list of the SI devices currently available from Nintendo.

Note: The N64 mouse is not currently available from Nintendo, but is scheduled to be developed in the near future. The N64 mouse will connect to the N64 Controller port.

Direct-Type SI Devices

Pak-Type SI Devices

SI Device Commands
A variety of commands can be executed for SI devices by calling library functions. Some library functions are common to all SI devices, while others are unique to a specific SI device. SI device commands can be broadly classified into the following three types of activities:

Each of these activities is explained in detail below.

SI Device Initialization
SI device initialization entails both making the initial settings in order to use the serial interface, and initializing the SI device itself.

The first thing which must be done in order to use an SI device, is to make the initial settings. This process is performed with the osContInit() function. When this function is called, the system checks the connection status of the SI device. If the Plf is busy, the timer waits until it is available for use by the SI device. This is done because, immediately after starting the N64 the PIf is used to communicate with the game pak, and therefore, cannot be used by the SI device until that process ends.

Be sure to execute the osContInit() function to access the SI device. This function need only be called once after starting, or resetting the program. Calling this function a second time will have no effect.

After the initial settings are made to use an SI device, you must perform the steps necessary to initialize the device. This process does the following things:

These steps are performed by calling and executing the initialization function for each SI device. Please check the value returned by the function on the application side and confirm that initialization was successful.

Note: Some SI devices do not have their own initialization process. When this is the case, the initial settings common to all SI devices are sufficient. As of December 1998, the only SI devices which do not need their own initialization process are the Standard Controller and the mouse.

The following flow chart shows the initialization procedure for each SI device.

Figure 26.1.1  Initialization Procedure for SI Devices

Please note the following precautions:

Please note the following exception:

Below is an example of the flow when switching between pak-type SI devices.

Figure 26.1.2  Switching and Using Pak-Type Devices

Executing Various Actions
Various actions can be executed with SI devices. For example, you can obtain data with the control stick and buttons on the Standard Controller, transfer data with the Controller Pak and the N64 Game Boy Pak, and start voice recognition processes and get results with the Voice Recognition System.

Obtaining the Status
Check to see what types of SI devices are connected to the Controller ports and joyports, and get the current status of an SI device.

SI Device Library Functions
Below are the library functions for each SI device. The functions have been grouped into four categories:

The first three groups pertain to the explanation of commands in described above. Old-version functions refer to functions that are no longer in use.

The osContInit() function should be called before you call the initialization function for a particular SI device. You should execute both the osContInit() function and the SI device's own initialization function before executing any of the other functions.

SI Device Functions

Initialization Function

Various Action Functions

Get Status Functions


Standard Controller Functions

Various Action Functions


Controller Pak Functions

Initialization Function

Various Action Functions

Get Status Function

Old Version Functions


Rumble Pak Functions

Initialization Function

Various Action Functions


EEPROM Functions

Initialization Function

Various Action Functions


N64 Game Boy Pak Functions

Initialization Functions

Various Action Functions

Get Status Function


Voice Recognition System Functions

Initialization Functions

Various Action Functions


Errors Related to the Use of SI Devices
When using ]SI device functions, errors can arise if the SI device is handled improperly or the program is put together poorly. The error values are always returned as the return value of the function, with the exception of when a function acts on a number of direct-type SI devices. In that case, errors are returned as member variables of the structures that return values read from the various SI devices.

For example, for the osContInit(), osContGetQuery() and osContReset() functions, errors are returned in the "errno" member variable of the OSContStatus structure, while for the osContGetReadData() function, errors are returned in the "errno" member variable of the OSContPad structure.

There are five major types of errors:

  1. errors resulting from the fact that no SI device is inserted
  2. errors resulting from the fact that a different SI device is inserted
  3. errors due to a data transfer failure
  4. errors specific to an SI device
  5. fatal errors

A "no SI device is inserted" error occurs when nothing is inserted in the specified controller port or joyport connector.

A "different SI device is inserted" error occurs when some device other than the expected SI device is inserted in the specified controller port or joyport connector.

A "data transfer failure" error occurs when data is not transferred successfully between the SI device and the N64. The problem can in the connection or in the hardware itself.

An "error specific to an SI device" is an error that only occurs in that particular SI device.

A "fatal error" can occur due to errors in the program, problems with the use of the hardware, or a problem with the hardware itself.

Below is a list of errors that can arise for each SI device.

Standard Controller Errors

No SI Device inserted

Data transfer failure


Controller Pak Errors

No SI device inserted

Different SI device inserted

Data transfer failure

Errors specific to this particular SI device

Fatal error


Rumble Pak Errors

No SI device inserted

Different SI Device is inserted

Data transfer failure


EEPROM Errors

No SI device is inserted

Fatal error


N64 Game Boy Pak Errors

No SI device inserted

Different SI Device is inserted

Data transfer failure

Errors specific to this particular SI device


Voice Recognition System Errors

No SI device inserted

Different SI Device is inserted

Data transfer failure

Errors specific to this particular SI device

Fatal error


SI Device Function Specifications
The following library functions are commonly used for all SI devices. Each function is explained in detail, below.


Initial Setting for SI Device Use

Function Name - osContInit

Syntax


#include <ultra64.h>

s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *status);

Description
This function initializes the game Controller. It initializes the internal variables to be used for the Controller and returns the bit pattern of the connected Controller to the location pointed to by the bitpattern argument. This function also checks and returns the status of the connected Controller and the Controller Pak to the location pointed to by the status argument.

Before a Controller, Controller Pak, or EEPROM can be used, this function must be called. However, it is meaningless to call this function more than once. This function does nothing if it is called again, after the first call. Therefore, you cannot check the Controller's status.

If you want to check the status of the Controller or the Controller Pak after the first call, use the osContStartQuery and osContGetQuery functions.

The area specified by the status argument must be large enough to store the number of OSContstatus structures specified by MAXCONTROLLERS. The message queue (pointed to by the mg argument) must be the initialized message queue, linked to OS_EVENT_SI. To learn how to make the link, please refer to the osSetEventMesg function in the N64 Online Function Reference Manual..

When the osContInit blocks on the message queue, do not share the queue. 0 is returned if the call is successful, otherwise -1 is returned. Following is the definition for the structure:

typedef struct {
    u16type;  /*Controller type*/
    u8status; /*Controller Pak status*/
    u8errno;  /*Error from SI device
}OSContStatus;

The message queue, mq, is the initialized message queue linked to OS_EVENT_SI. See the osSetEventMesg function to learn how to create this link.

If the initial setting was successful, a 0 is returned. If data transfer fails when an SI device is in use, a -1 is returned.

The bit is set to 1 for status--->type according to the type of device that is inserted into the Controller port. A 0 is returned when nothing is inserted into the port.

CONT_ABSOLUTE
This bit is set to 1 when a Standard Controller is connected to the N64 Control Deck. The connected device is judged to be a Controller if the device has a built-in absolute value counter for counting the amount of movement of the control stick as an absolute value from the origin. As of December 1998, this bit is only set when the Controller is attached.

CONT_RELATIVE
This bit is set to 1 when the mouse is attached. The connected device is judged to be a mouse if the device has a built-in relative counter for counting the amount of movement of the mouse from the current coordinates. As of December 1998, this bit is only set when the mouse is attached.

CONT_JOYPORT
This bit is set to 1 when a joyport is attached to the direct-type SI device that is connected to the Controller Port. As of December 1998, the only SI device with a joyport is the Standard Controller.

Confirm which kind of direct-type SI device is connected to the Controller Port in the following way:

If the direct-type SI device connected to the Controller Port is a Standard Controller, then the status of that joyport can be checked with status->status. The lower bit in status->status is set to 1. If nothing is inserted in either the Controller Port or the joyport connector, or if a direct-type SI device that is not a Controller is inserted, then 0 is returned.

CONT_CARD_ON
This bit is set when a device has been inserted.

CONT_CARD_PULL
This bit is set when the device has been removed.

CONT_NO_RESPONSE_ERROR
There is no response from the Controller. The Controller is not inserted.

CONT_OVERRUN_ERROR
The controller sends data at a higher data transfer rate than the hardware can handle. In this case, you should ignore the data.

Sample

void
mainproc(void)
{
        OSMesgQueue     intMesgQueue;
        OSMesg          intMesgBuf[1];
        OSContStatus    sdata[MAXCONTROLLERS];
        u8              pattern;
        int             i;

        osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1);
        osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
        osContInit(&intMesgQueue, &pattern,   &sdata[0]);

        for(i = 0; i < MAXCONTROLLERS; i++){
                if(((pattern >> i) & 1) && (sdata[i].errno == 0)){
                        if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL){
osSyncPrintf(Standard Controller);
                        }
                        else if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_MOUSE){
                                osSyncPrintf(Mouse);
                        }
                        else if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_VOICE){
                                osSyncPrintf(Voiced Recognition System);
                        }
                        else{
                                osSyncPrintf(Other Devices);
                        }
                }else{
                        osSyncPrintf(Nothing is inserted in this port);
                }
        }
}


Get Status and Type of SI Device

Function Name - osContStartQuery, osContGetQuery

Syntax

#include <ultra64.h>

s32 osContStartQuery(OSMesgqueue *mq);

void osContGetQuery(OSContStatus *status);

Description
The osContStartQuery and osContGetQuery functions obtain the game Controller's status and type. When you call the osContStartQuery function, the query command is issued to the Controller to obtain the Controller's status and type. As the result of the osContGetQuery call, the Controller's status and type are returned to the location pointed to by the status argument.

Notes
You must supply a memory block large enough for MAXCONTROLLER structures of type osContStatus.

The message queue, mq, must be the initialized message queue linked to OS_EVENT_SI. See the osSetEventMesg function in the N64 Online Function Reference Manual to learn how to create this link.

It takes approximately two milliseconds for the query command to retrieve the return value from the Controller. Therefore, the purpose of the osRecvMesg call at the message queue in the example shown below is to wait for this event.

Following is the definition for the structure:

typedef struct {
          u16type;  /* Controller Type */
          u8status; /* Joyport Status */
          u8errno;  /* error from device
   }OSContStatus;

Regarding the osContSetCh function, it is fine to set the number of direct-type SI devices to be used, to a value less than the value set for MAXCONTROLLERS, if the number of direct-type devices used will not be changed in the future.

CONT_ABSOLUTE
This bit is set to 1 when a Standard Controller is connected to the N64 Control Deck. The connected device is judged to be a Controller if the device has a built-in absolute value counter for counting the amount of movement of the control stick as an absolute value from the origin. As of December 1998, this bit is only set when the Controller is attached.

CONT_RELATIVE
This bit is set to 1 when the mouse is attached. The connected device is judged to be a mouse if the device has a built-in relative counter for counting the amount of movement of the mouse from the current coordinates. As of December 1998, this bit is only set when the mouse is attached.

CONT_JOYPORT
This bit is set to 1 when a joyport is attached to the direct-type SI device that is connected to the Controller Port. As of December 1998, the only SI device with a joyport is the Standard Controller.

Confirm which kind of direct-type SI device is connected to the Controller Port in the following way:

  • If the status->type value masked with CONT_TYPE_MASK is equal to CONT_TYPE_NORMAL, then a Standard Controller is connected. (When a Standard Controller is connected, the bits are set to 1 for both CONT_ABSOLUTE and CONT_JOYPORT in status->type. CONT_TYPE_NORMAL includes the bits for both CONT_ABSOLUTE and CONT_JOYPORT.)

  • If the masked value is equal to CONT_TYPE_MOUSE, that means a mouse is connected.

  • And if it is equal to CONT_TYPE_VOICE it means the Voice Recognition System is connected.

If the direct-type SI device connected to the Controller Port is a Standard Controller, then the status of that joyport can be checked with status->status. The lower bit in status->status is set to 1. If nothing is inserted in either the Controller Port or the joyport connector, or if a direct-type SI device that is not a Controller is inserted, then 0 is returned.

CONT_CARD_ON
This bit is set when a device has been inserted.

CONT_CARD_PULL
This bit is set when the device has been removed.

CONT_NO_RESPONSE_ERROR
There is no response from the Controller. The Controller is not inserted.

CONT_OVERRUN_ERROR
The controller sends data at a higher data transfer rate than the hardware can handle. In this case, you should ignore the data.

Sample

void
mainproc(void)
{
        OSMesgQueue     intMesgQueue;
        OSMesg          intMesgBuf[1];
        OSContStatus    sdata[MAXCONTROLLERS];
        u8              pattern;
        int             i;

        osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1);
        osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
        osContInit(&intMesgQueue, &pattern, &sdata[0]);

        for(i = 0; i < MAXCONTROLLERS; i++){
                if(((pattern >> i) & 1) && (sdata[i].errno == 0)){
                        if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL){
                                osSyncPrintf(Standard Controller);
                        }
                        else if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_MOUSE){
                                osSyncPrintf (Mouse);
                        }
                        else if((sdata[i].type & CONT_TYPE_MASK) == CONT_TYPE_VOICE){
                                osSyncPrintf(Voice Recognition System);
                        }
                        else{
                                osSyncPrintf(Other devices);
                        }
                }else{
                        osSyncPrintf(Nothing is inserted into this port);
                }
        }
}


Reset an SI Device

Function Name - osContReset

Syntax

#include <ultra64.h>

s32 osContReset(OSMesgQueue *mq, OSContStatus *status);

Description
The osContReset function resets all game Controllers and returns all control stick setting (A, B, X, Y, Z, L, R, Start buttons) back to their neutral positions. It also returns the game Controller's status back to the location pointed to by the status argument. You must supply a block of memory large enough for MAXCONTROLLERS structures of type OsContStatus.

"mq" is the message queue for initialized messages associated with OS_EVENT_SI events. Please see osSetEventMesg() in the "N64 Online Function Reference Manual," to learn how to make this association.

"status" returns the SI device type and its status. The area secured for "status" must be just large enough to hold the MAXCONTROLLERS number of OSContStatus structures (i.e., 4). The OSContStatus structure is shown below.

typedef struct {
     u16     type;   /* The type of SI device inserted in the controller port */
     u8      status; /* The status of the joyport */
     u8      errno;  /* Error from the SI device */
}OSContStatus;

Notes
This function is utilized at the time of SI device development, and is not normally required when creating applications.

If the osContSetCh() function sets the number of direct-type SI devices accessed at a value less than the MAXCONTROLLERS number, then the area secured can be smaller than the MAXCONTROLLERS number, provided more devices are not added later.

For details about the OSContStatus structure, please see Section 26.1.6.1, where the osContInit() function is discussed.


Set the Number of SI Devices to be Accessed

Function Name - osContSetCh

Syntax

#include <ultra64.h>

s32 osContSetCh(u8 ch);

Description
The osContSetCh() function specifies the number of Controllers (ch) for the system to read. By default, the system polls all MAXCONTROLLERS Controllers to read data. By setting ch to a number smaller than MAXCONTROLLERS, you can save time in polling for Controller data. Note that the ch number cannot be greater than MAXCONTROLLERS.


Exchanging Pak-Type SI Devices
This section discusses the precautions related to exchanging pak-type SI devices such as the Controller Pak, Rumble Pak, and the N64 Game Boy Pak, in a single application. Please note the following three points when creating programs that assume switching between pak-type SI devices.

  1. When exchanging and using more than one type of pak-type SI device, always initialize each specific device each time. For example, if you initialize and use a Controller Pak and then replace that device with an N64 Game Boy Pak, you must initialize the N64 Game Boy Pak to use it. If you then reinsert the Controller Pak, you must initialize the Controller Pak once again. This is because the SI device hardware must be initialized whenever it is newly inserted.

    The OSPf structure is used as a common file handle for pak-type SI devices. However, whenever the initialization process is executed for an SI device, this structure is initialized in the form best suited to that particular device. As a result, in order to handle a different SI device, the OSPf structure must be re-initialized so that it can take on the appropriate form for the new device.

  2. When a pak-type SI device is removed while it is being accessed, you run the risk of a latch-up occurring. (A latch-up is a dangerous state in which electric current continues to flow.) The hardware and the OS specifications are designed to avoid such an event. However, it is important that you also take measures on the application side. Please display a message that warns the user to be careful not to accidently pull the device out during game play. Clearly display messages prompting the user to remove the device in scenes where devices are to be switched. Also, in scenes where devices are not to be removed or inserted, let the player know they need to be careful about removing the device by displaying a message asking them to wait for the OK sign before removing the device.

  3. If the removal and insertion of pak-type SI devices is to be detected automatically, please do so by checking the appropriate flags. Do not use the initialization functions to recognize the removal and insertion of particular devices. Rather, use the values of "status" returned by the osContStartQuery() and osContGetQuery() functions. If the CONT_CARD_PULL flag is up in "status" you know that a device has been removed. And if the CONT_CARD_ON flag is up, you know that some device is inserted.

    For example, if a Controller Pak is inserted and you want to confirm automatically when it has been replaced by a Rumble Pak, do check this status by continually calling the osMotorInit() function. Instead, call the osContStartQuery()and osContGetQuery() functions and look at the values in "status." Confirm that the Controller Pak was removed and a Rumble Pak was inserted, and then call the osMotorInit() function to initialize the Rumble Pak.

The following flow diagrams show what happens when switching SI devices such as Controller Pak and the Rumble Pak. Please refer to these flow diagrams when creating your application.

Note: The diagrams below provide only one example of the possible flow, and do not need to be followed exactly as written. Please feel free to design the process and display messages which fit the needs of your specific application.

Figure 26.1.3  Switching Between the Controller Pak and the Rumble Pak - Flow Chart #1


Figure 26.1.4  Switching Between the Controller Pak and the Rumble Pak - Flow Chart #2

Figure 26.1.5  Switching Between the Controller Pak and the Rumble Pak - Flow Chart #3

Copyright © 1999
Nintendo of America Inc. All Rights Reserved
Nintendo and N64 are registered trademarks of Nintendo
Last Updated January, 1999