An SI device is a peripheral device, which is connected to the N64 SI (serial interface). SI devices include the Standard Controller, Controller Pak, etc. This section provides an introduction to SI devices.
SI devices for N64 are discussed here. 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 *1 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 Socket 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 *2.
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.
*1 PIF is the name of the IC chip which plays an intermediary role when the CPU accesses an SI device.
*2 Controllers inserted into ports 0,1,2,3 are designated as Controllers 1,2,3,4.
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 and that are scheduled to become available from Nintendo.
(1) Direct-Type SI Devices
Standard Controller
The Standard Controller is the Controller normally used with N64. This device is used by connecting it to the Controller Socket on the front side of the N64 Control Deck.
EEPROM
EEPROM is attached to the board inside the Game Pak and is used to save data during game play.
Voice Recognition System
The Voice Recognition System is a peripheral device which can recognize words spoken by the game player during an N64 game. To use this device, connect the plug of the voice recognition unit into a Controller Socket, then connect the dedicated microphone into the unit.
Mouse
An N64 mouse connected to the Controller Socket is scheduled to be put on the market in the near future.
(2) Pak-Type SI Devices
Controller Pak
The Controller Pak is a supplemental memory device that is connected to the Controller's joyport connector. By connecting a Controller Pak to the Controller, the player can save their progress in a game and record their high scores.
Rumble Pak
The Rumble Pak is a peripheral device which when connected to the Controller's joyport connector, will vibrate and create tactile sensations for the player during a game.
N64 Transfer Pak
The N64 Transfer Pak is a peripheral device that enables data from a Game Boy Game Pak to be loaded into the N64. To use the N64 Transfer Pak, connect the device to the Controller's joyport connector, then insert a Game Boy Game Pak into the device.
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 that include device initialization, executing various actions, and obtaining device status.
Each of these activities is explained in detail below.
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 (see Section 26.1.6.1 "Initial Setting for SI Device Use"). When this function is called, the system checks the connection status of the SI device. If the PIF 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. It is impossible to access to the SI devices without calling this function. 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.
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. Currently, 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.
Please note the following precautions. When initializing SI devices, if more than one kind of Pak-type SI device is going to be switched and used, make sure to initialize each device each time. This is because the SI device hardware must be initialized whenever it is newly inserted *3.
If you initialize and use a Pak-type SI device such as the Rumble Pak, and then substitute it for another kind of device, such as a Controller Pak, then you need to initialize this second SI device before it is used. Also, if you remove the second device (the Controller Pak) then insert the first device (the Rumble Pak), you need to initialize the Rumble Pak again using its own initialization process. You also need to do this when SI devices are switched among the four Controllers.
Pak-type SI devices use the OSPfs structure as a common file handle. This structure is initialized in the most appropriate form for a given SI device when the initialization function is executed for that particular SI device. Thus, in order to handle a different type of SI device, the OSPfs structure must be initialized again so it will take on the most appropriate form for that new SI device. You might think that you could prepare an OSPfs structure for each SI device and initialize them all at once. However, even if you prepared several OSPfs structures, you would still need to execute the initialization function every time in order to initialize the SI device hardware. So to keep the program from getting too complicated, please use an OSPfs structure that is shared by all Pak-type SI devices.
*3 Both Direct-type SI (Standard Controller and mouse not included) devices and Pak-type SI devices need to be initialized with their own particular initialization process when newly inserted, because the device hardware needs to be initialized.
Below is an example of the flow when switching between Pak-type SI devices.
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 Transfer Pak, and start voice recognition processes and get results with the Voice Recognition System.
Check to see what types of SI devices are connected to the Controller Sockets and joyports, and get the current status of an SI device.
Below are the library functions for each SI device. The functions have been grouped into four categories such as <initialization functions>, <action functions>, <obtain status functions>, and <old-version functions>.
<Initialization functions>, <action functions>,and <obtain status functions> pertain to the explanation of commands 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.
1. SI Device Functions
<Initialization Function>
<Various Action Functions>
<Get Status Functions>
2. Standard Controller Functions
<Various Action Functions>
3. Controller Pak Functions
<Initialization Function>
<Various Action Functions>
<Get Status Function>
<Old Version Functions>
4. Rumble Pak Functions
<Initialization Function>
<Various Action Functions>
5. EEPROM
<Initialization Function>
<Various Action Functions>
6. N64 Transfer Pak Functions
<Initialization Functions>
<Various Action Functions>
<Get Status Function>
7. Voice Recognition System Functions
<Initialization Functions>
<Various Action Functions>
When using SI device functions described in 1.4, 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 including <errors resulting from the fact that no SI device is inserted>, <errors resulting from the fact that a different SI device is inserted>, <errors due to a data transfer failure>, <errors specific to an SI device>, and <fatal errors>.
A <no SI device is inserted> error occurs when nothing is inserted in the specified Controller Socket 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 Socket 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 happen 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.
1. Standard Controller Errors
<No SI Device inserted>
<Data transfer failure>
2. Controller Pak Errors
<No SI device inserted>
<Different SI device inserted>
<Data transfer failure>
<Errors specific to this particular SI device>
<Fatal error>
3. Rumble Pak Errors
<No SI device inserted>
<Different SI Device is inserted>
<Data transfer failure>
4. EEPROM
<No SI device is inserted>
<Fatal error>
*4 This error is not defined by #define.
5. N64 Transfer Pak
<No SI device inserted>
<Different SI Device is inserted>
<Data transfer failure>
<Errors specific to this particular SI device>
<Fatal error>
6. 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>
The following library functions are commonly used for all SI devices. Each function is explained in detail below.
Function
osContInit
Initial Setting for SI Device Use
Syntax
#include <ultra64.h> s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *status);
Description
The osContInit function initializes the SI settings and checks the status and type of the SI device.
This function must be called before you call any functions to be used for initialization that are unique to each SI device. By doing this, the system checks the connection status of the SI device. If the PIF is busy, the timer waits until it is available for use by the SI device. This is because PIF is used to establish a connection between the Game Pak right after N64 starts up. While it is in use, PIF cannot be used.
The osContInit must be called before all the SI device functions are called. After the program starts up or a reset is performed, it should be called only once . It is not necessary to call this function more than once. This function does nothing from the second call on. Therefore, if the status and type of SI device needs to be checked after the first osContInit call, please use the osContStartQuery() function and osContGetQuery().
If the osContInit function is executed it returns, the Controller Socket to which the direct SI device is connected, to bitpattern. Bit 0, 1, 2, 3 of a bitpattern correspond to Controller Socket 0, 1, 2, 3, respectively. Direct SI device is inserted to the Controller Socket 0 if the bit 0 of a bitpattern is set to 1. Also, the osContInit function examines the status of joyport and returns the result to status when the Controller is connected. The area specified by status must be large enough to hold the number of OSContStatus structures specified by MAXCONTROLLERS which store the status for each device inserted to the Controller Socket. OSContStatus structure is shown below.
typedef struct { u16 type; /* SI device type inserted to the Controller Socket */ u8 status; /* Joy port status */ u8 errno; /* 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. Since mq is used inside the function to wait for messages, the application does not need to use mq to wait for an end-of-function message.
0 is returned if initialization is successful, and -1 is returned if it fails to transfer data while SI is in use. It is rarely seen that -1 is returned.
One of the following bits is set to 1 to the value for status->type, depending on which kind of direct- SI device is inserted to the Controller Socket. 0 is returned when no device is inserted to the Controller Socket.
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. Currently, 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 Socket. 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 Socket 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 Socket 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 Socket 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 after reset.
An Error value is set to status errno when the function fails to read the status value of SI device. 0 is returned if the function was successful. One of the following values is returned should an error occur.
CONT_NO_RESPONSE_ERROR
There is no response from the Controller. The Controller is not inserted.
CONT_OVERRUN_ERROR
A communication error has occurred between the N64 Controller Deck and the SI devices. Ignore the data when this error is detected.
When it is recognized that the Controller socket was not connected, or communication error occurs in a Controller Socket (bitpattern's bit is zero, or status errno is not zero), the Controller's status type and status value become invalid. You need to make sure the Controller is connected properly by looking at the bit pattern and status errno first before examining the Controller type and status.
Although it used to be performed in this function with OS 2.0e or previous versions, resetting a Controller cannot be accomplished in this function with OS 2.0f or later. Normally it is not necessary to reset a Controller, however it can be accomplished by using osContReset()
The following sample shows how to use the osContInit function within a program. The function checks each Controller Socket to report which type of direct SI device is inserted.
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\n"); } else if((sdata[I].type & CONT_TYPE_MASK) == CONT_TYPE_MOUSE){ osSyncPrintf("Mouse\n"); } else if((sdata[I].type & CONT_TYPE_MASK) == CONT_TYPE_VOICE){ osSyncPrintf("Voiced Recognition System\n"); } else{ osSyncPrintf("Other Devices\n"); } }else{ osSyncPrintf("Nothing is inserted in this port\n"); } } }
Function
osContStartQuery, osContGetQuery
Get Status and Type of SI Device
Syntax
#include <ultra64.h> s32 osContStartQuery(OSMesgQueue *mq); void osContGetQuery(OSContStatus *status);
Description
The osContStartQuery function starts to read the values for SI device status and type which is connected to the Controller Socket and the joyport connector. The osContGetQuery function returns those values to status. By calling these two functions, such status can be obtained whether a standard Controller is connected to the Controller Socket or that a Controller Pak is inserted to the joyport connector. These two functions must be paired for use.
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.
The osContStartQuery function is called only to issue read command, and the message for completed data reading is returned to the message queue mq. Therefore, the osContGetQuery function should be called to obtain data after the osContStartQuery function is called, and osRecvMesg receives a message indicating data reading is completed. The osContStartQuery function takes around 2 milliseconds to complete its data reading and for osRecvMesg to receive a final message. Other process such as re-drawing the screen can be performed while you are waiting.
You must supply a memory block large enough for MAXCONTROLLERS structures of type OSContStatus. *5 OSContStatus structure is shown below.
typedef struct { u16 type; /* SI device type inserted to the Controller Socket */ u8 status; /* Joyport Status */ u8 errno; /* error from device */ }OSContStatus;
One of the following bit is set to 1 to the value for status->type, depending on which kind of direct- SI device is inserted to the Controller Socket. 0 is returned when no device is inserted to the Controller Socket.
*5 Regarding the osContSetCh() function (see Section 26.1.6.4 "Set the Number of SI Devices to be Accessed"), 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. Currently, 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 Socket. 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 Socket 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. 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 Socket 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 Socket 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 after reset.
An Error value is set to status errno when the function fails to read the status value of SI device. 0 is returned if the function was successful. One of the following values is returned should an error occur.
CONT_NO_RESPONSE_ERROR
There is no response from the Controller. The Controller is not inserted.
CONT_OVERRUN_ERROR
A communication error has occurred between the N64 Controller Deck and the SI devices. Ignore the data when this error is detected.
When it is recognized that the Controller socket was not connected, or a communication error occurs in a Controller Socket(bitpattern's bit is zero, or status errno is not zero), the Controller's status type and status value become invalid. You need to make sure the Controller is connected properly by looking at the bit pattern and status errno first before examining the Controller type and status.
void mainproc(void) { OSMesgQueue intMesgQueue; OSMesg intMesgBuf[1]; OSContStatus sdata[MAXCONTROLLERS]; u8 pattern; osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1); osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL); /* Initialize SI device */ osContInit(&intMesgQueue, &pattern, &sdata[0]); /* start reading SI device status and type */ osContStartQuery(&intMesgQueue); . . /* Confirm the end of reading */ osRecvMesg(&intMesgQueue, NULL, OS_MESG_BLOCK); /* Obtain SI device status and type */ osContGetQuery(&sdata[0]); }
Function
osContReset
Reset all SI Devices
Syntax
#include <ultra64.h> s32 osContReset(OSMesgQueue *mq, OSContStatus *status);
Description
osContReset resets all the direct SI devices that are connected to the Controller Sockets. Specifically, it sets the current position of a 3D stick of a standard Controller back to the neutral position. If it's a voice recognition system, osContReset resets the parameters set by the initialization functions back to the default values.
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.
SI device type and status are returned to status.You must supply a memory block large enough for MAXCONTROLLERS structures of type OSContStatus.*6. OSContStatus structure *7 is shown below.
typedef struct { u16 type; /* The type of SI device inserted in the Controller Socket */ 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.
*6 Regarding the osContSetCh() function (see Section 26.1.6.4 "Set the Number of SI Devices to be Accessed"), 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.
*7 For details on OSContStatus structure, see the section on osContInit().
Function Name
osContSetCh
Set the Number of SI Devices to be Accessed
Syntax
#include <ultra64.h> s32 osContSetCh(u8 ch);
Description
The osContSetCh() function specifies the number of devices for the functions to access when those functions access multiple direct SI devices. Specifically, those functions are osContStartReadData(), osContGetReadData(), osContStartQuery(), osContGetQuery(), and osPfsIsPlug(). By default, it is set up for the system to read device data of the number specified in MAXCONTROLLERS.
Direct SI devices that the system reads range from port 0 to port (ch-1). Note that it cannot be used to obtain the data only from the devices connected to Port 2 and Port 3 out of the number specified in MAXCONTROLLERS. It must start with the first port which is Port 0 in this case. Also ch cannot be greater than the number of MAXCONTROLLERS.
By setting ch to a number smaller than MAXCONTROLLERS, you can save time in reading for Controller data. For instance, it can take as much as 2 milliseconds for the the osContStartReadData function to issue a read command and receive a message for completed data reading and for the osContGetReadData function to obtain data from Controller when ch is set to MAXCONTROLLERS. However, you can save around 0.3 milliseconds for every MAXCONTROLLERS you reduce.
Notes
The function osContInit() must be called before the osContSetCh function is called. If the osContSetCh function is called before the osContInit function, the value specified for ch will be returned to MAXCONTROLLERS.
This section discusses the precautions related to exchanging Pak-type SI devices such as the Controller Pak, Rumble Pak, and the N64 Transfer Pak, in a single application. Please note the following three points when creating programs that assume switching between Pak-type SI devices.
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.