26.3 Controller Pak

UP


26.3.1 What is the Controller Pak?

The Nintendo 64 Controller Pak 256K (Controller Pak) is a removable memory device used with the Nintendo 64 Controller (Controller). The Controller Pak is inserted into the Controller Joy Port and can be used for purposes such as storing game progress and high scores.

It is assumed that the Controller Pak will be shared by multiple applications. Consequently, it uses slightly different interfaces from that of the backup memory used in previous Nintendo products. This interface is now included in the Controller Pak Library. For example, if Controller Pak memory is used by the application, data areas must first be obtained through the library.

As a general rule, always access the Controller Pak via the Controller Pak Library. To allow multiple applications to share the Controller Pak, avoid reserving unnecessary data space.

UP


26.3.2 Controller Pak Configuration

In this section we explain the configuration of the Controller Pak. Please make sure you understand this section, because the specifications are very different from the specifications for Nintendo's backup memory products. Also, note that there are many names such as "page" and "note" which are used only for the Controller Pak.

UP


26.3.2.1 Page

For easy management of the Controller Pak , memory is delimited by 256-byte boundaries and managed in 256-byte units. Each 256 bytes is termed a Page and, beginning with memory area 0x0000 ~ 0x00ff, the pages are named Page 0, Page 1, Page 2, . . . Page 127.

For a 256 Kbit Controller Pak (256 Kbit capacity = 32 Kbytes = 128 pages), 5 pages (Pages 0-4) are reserved by the system for game note management. This reserved area totals 1,280 bytes. Consequently, the number of pages that can actually be used by the game is reduced by 5 pages. The role of each page used by the system is as follows:

Page 0 : serial number, label area
1, 2 : I-NODE area
3, 4 : Game Note (described below) information area
5 ~ : First page of actual game data area

Therefore, the effective number of pages available is 123 pages.

UP


26.3.2.2 Game Note

To allow the Controller Pak to be shared among different applications, the Controller Pak Library creates a file system which it uses for managing the memory areas. Intuitively, this system can be regarded as a greatly simplified version of the file system used in PC operating systems. In the Controller Pak, files are named Game Notes or simply Notes. Up to 16 game notes can be created in one Controller Pak.

The application reserves a game note for data storage. As a general rule, the application program must verify that a game note has been reserved by the application or that there is adequate space remaining before the player begins a game. If no usable note is available, a message must be displayed before the game is started, such as the game can not be saved. Do you still wish to start the game? Please make every effort to avoid problems such as displaying a Cannot Save message, after a player registers a top score in a game.

The size of the game note can be set individually for each game, provided a new note does not exceed the number of pages remaining. When the note size is set with the library, the size is rounded up to the nearest 256 bytes regardless of the actual number input. Therefore it is recommended that the size be specified in multiples of 256 bytes. An area can be re-sized after it is reserved, but this operation should be performed in such a way that it does not cause problems for a player.

In general, one application should only use one game note. The Controller Pak Library does support multiple notes per application, because it is conceivable that the memory space in the Controller Pak can be used more efficiently, or that the game developer can take advantage of multiple notes. Do not misuse this function by reserving multiple notes without good reason.

Game notes contain the following information:

Company code 2 bytes From 0x0001 to 0xffff
Game code 4 bytes From 0x00000001 to 0xffffffff
The Game code is replaced with the initial code.
Note name 16 bytes Use Nintendo's proprietary character code (N64 font code) *9. The note name is the same as the game name or at least similar to it. If the name is less than 16 bytes long, fill the remaining area with 0x00.
Note extension [0] 1 byte This extension is used for multiple notes. Normally the extension is 0x00. If additional notes are used, substitute this with 0x10 - 0x33 (N64 font codes '0' - '9' and 'A' - 'Z').
Note extension[1,2,3] 3 bytes Reserved (always 0x00)

The company code and game code issued by Nintendo are expressed as ASCII code. Note names and note extensions are expressed as N64 font codes.

Accessing game notes produced by other companies is generally prohibited, except when deleting game notes in the Controller Pak menu. Access only game notes with your company code issued by Nintendo. Those wishing to access game notes produced by other companies are asked to inquire with Nintendo.

*9 Please refer to the manual on nosLoadFont() (Section 26.3.5.2 "Loading the Font Data") for the Nintendo font code table.

UP


26.3.2.3 Serial Number

To allow insertion and removal of the Controller Pak to be detected during a game, the serial number is stored in the Controller Pak. In general, each Controller Pak has been assigned a unique number. When the Controller Pak is initialized, this number is read and stored in memory by the Controller Pak Library. Subsequently, each time a Controller Pak is accessed, its number is compared with that in the Controller Pak Library to determine when a different Controller Pak has been substituted.

Because the current specifications do not provide for switching between different Controller Pak(s) during a game, when a different serial number is detected it should be processed as an error. Contact Nintendo if you wish to enable switching between Pak(s) during a game.

Because this serial number is read automatically within each function, the application programmer does not need to be particularly concerned with the serial number.

UP


26.3.2.4 Label

The Controller Pak contains a 32-byte label area. This area is currently undefined. Although there are functions in the Controller Pak Library that read and write to this area, please do not use these functions.

UP


26.3.2.5 Multinote

When reserving multiple notes for an application, create all of these notes using the same company code, game code, and note name. Use the note extension to distinguish between notes.

Note extension[0] uses 0x00 or a character of the alphabet, and is defined as shown below.

Note Extension [0]
First note (main note) 0x00
Second note (additional note 1) 0x1a (N64 font code 'A')
Third note (additional note 2) 0x1b (N64 font code 'B')
:

When Multinote is used, the main note is not always necessary. It may be possible to design so that only new notes can have multiple notes.

Please ensure that notes are not interdependent. This is to prevent situations where the user deletes a note and the game cannot proceed using the remaining notes.

UP


26.3.2.6 Controller Pak Menu

Because the Controller Pak is shared by a number of applications, available space becomes scarce as the Controller Pak is utilized. This necessitates a simple, consistent means by which the user can free up space in the Controller Pak by deleting unnecessary game notes. To prevent confusion at the user level, a uniform start-up method is required.

The specifications listed below are suggested to maintain this uniformity. In creating a Controller Pak menu, please ensure that it meets these specifications.

* Calling Up the Menu

(1) Insert the Controller Pak into Controller 1.

(2) Turn the power ON while pressing the START button, or reset while pressing the START button.

(3) The Controller Pak menu boots up.

* Menu Functions

(1) The menu should display the note name, note extension[0], list of page used, and the number of unused pages

(2) The user can select and delete unwanted game notes.

(3) Before actual deletion, the software must ask the user, "Do you want to delete this game note?".

The nosPakMenu() function is provided as one example of the Controller Pak menu. This function has been made very simple to keep the program size to a minimum. The function can also be included in the application to limit program size and, because the source code is included, it can be used for creating custom menus.

Several functional limitations have been placed on nosPakMenu() to limit program size. The menu cannot be executed with a Control Stick and only game notes for the Controller Pak inserted into Controller #1 can be deleted. Needless to say, eliminating such restrictions is desirable if program size permits.

In addition, access to game notes produced by other companies should be limited to the game note deletion function of this menu. For example, please avoid implementations that provide such access by means other than the Controller Pak menu or provide a menu option of copying the game notes of other companies.

UP


26.3.3 Controller Pak Function Specifications

The following library functions used to handle the Controller Pak in an N64 program. Each of these functions is described in detail below.

UP


26.3.3.1 Initializes the Controller Pak

Function

osPfsInitPak

Initializes the Controller Pak file handle

Syntax

#include <ultra64.h>
s32 osPfsInitPak (OSMesgQueue *mq, OSPfs *pfs, int controller_no);

Description

It initializes the OSPfs structure pfs, which is the file handle used to operate the Controller Pak. This function should be called first when a Controller Pak is used for the first time, a new Controller Pak is inserted, or to access different Controller Paks inserted in multiple controllers. However, because configuration must be performed to use SI, osContInit should be called once at the start, before osPfsInitPak is called.

When controlling a file system, a Controller Pak function uses the OSPfs structure pointed to by the pfs argument as a file handle to gain access. This function, osPfsInitPak, initializes that OSPfs structure.

The controller_no argument specifies the Controller number (0~3) into which the Controller Pak is inserted. A Controller Pak inserted in the controller port which is specified by the controller_no would be the target Controller Pak.

The mq argument is the initialized message queue linked to OS_EVENT_SI. Please refer to osSetEventMesg() for creation of this link. Because mq is used by the function as an internal message queue, it is not necessary for the application to use mq for purposes such as queuing function-termination messages.

The osPfsInitPak performs the following kinds of processing internally. First it checks the disk ID area. If it recognizes the ID, it calls the function osPfsChecker. This enables recovery to be performed automatically if the file management area (FAT area) is destroyed.

Although the previous Pfs initialization function, osPfsInit, performed automatic recovery if the ID area *10 was completely destroyed, osPfsInitPak does not perform automatic restoration. ID recover requires a separate call to function osPfsRepairId. Normally when initializing the Controller Pak, the function osPfsInitPak should be used rather than osPfsInit. In addition, be sure to integrate osPfsRepairId into the program so that it can be called.

This is necessary because certain addresses could become indeterminate due to a poor connection at the connector or for other reasons. If you use osPfsInit to check the ID area, the function could reach the wrong address somehow because of the inappropriate address, although it was supposed to check the ID. Also, the function could determine that it is not a valid ID, looking at the data at the wrong address. In this case, the old osPfsInit function assigns a new ID automatically and it could write the new ID to the wrong address. As a result, the content of the Controller Pak may be destroyed.

Therefore, always use the following procedure when initializing a Controller Pak.

To initialize a Controller Pak, always call osPfsInitPak. If 0 is returned, the call is successful.

If PFS_ERR_ID_FATAL is returned as the error code, one of the following problems may exist: The Controller Pak's ID area is destroyed, the Controller Pak is not connected properly, the Controller Pak ID cannot be read due to a dirty connector, or the Controller's joy bus or Controller Pak is damaged. In this case, you must display the message, "The Controller or Controller Pak may not be inserted properly, the content may have been destroyed, or it may be damaged." Then prompt the user to choose between "connect again" or "repair it - the content of the Controller Pak may be destroyed.". If the user chooses "connect again," call the osPfsInitPak function again. If the user chooses "repair," call the osPfsRepairId function, and then call osPfsInitPak again.

*10 osPfsInitPak confirms ID integrity internally by checksum comparison. If the checksums do not agree, the ID is evaluated as corrupted.

If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted *11. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_ID_FATAL

An attempt was made to initialize the file system, but the ID area was corrupted. Either the Controller Pak data were corrupted or the controller itself is malfunctioning or not properly connected. When this error is returned, the user should first be asked whether the Controller Pak should be initialized (assign a new ID) or to check the Controller Pak connection. If the user responds that the Controller Pak should be initialized, the function osPfsRepairId should be called.

PFS_ERR_DEVICE

A peripheral device other than a Controller Pak (eg, Rumble Pak, 64GB Pak) has been inserted in the controller. Whether a Controller Pak has been inserted is determined by whether the device has RAM. This error is issued if there is no RAM present.

*11 Internally specified Controller Pak is recognized by comparing ID each Controller Pak has.

The following is a sample program for this function.

Example

void
mainproc(void) {
  int i;
  OSMesgQueue     intMesgQueue;
  OSMesg          intMesgBuf[1];
  OSContStatus    contstat[MAXCONTROLLERS];
  OSPfs           pfs[MAXCONTROLLERS];
  u8              contpat;
  s32             ret;
  
  osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1);
  osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
  osContInit(&intMessageQ, &contpat, contstat);

  for (i = 0 ; i < MAXCONTROLLERS ; i ++) {
    if ((contpat >> i) & 1) {
      if ((contstat[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL) {
        do {
          ret = osPfsInitPak(&intMessageQ, &pfs[i], i);
          switch(ret) {
          case 0:
            osSyncPrintf("Controller Pak is inserted into PORT %d\n", i);
            break;
          case PFS_ERR_NOPACK:
            osSyncPrintf("Controller Pak is not inserted into PORT %d\n", i);
            osSyncPrintf("Insert Controller Pak\n");
            break;
          case PFS_ERR_NEW_PACK:
            osSyncPrintf("Controller Pak for PORT %d was replaced\n", i);
            osSyncPrintf("This Controller Pak will be used\n");
            break;
          case PFS_ERR_CONTRFAIL:
            osSyncPrintf("Abnormality is found in connection of Controller Pak for PORT %d\n", i);
            osSyncPrintf("Check if Controller is inserted properly\n");
            break;
          case PFS_ERR_DEVICE:
            osSyncPrintf("It cannot be saved in Controller Pak for PORT %d\n", i);
            osSyncPrintf("Check if Controller Pak is inserted properly\n");
            break;
          case PFS_ERR_ID_FATAL:
            osSyncPrintf("Abnormality is found in Controller Pak for PORT %d\n", i);
            osSyncPrintf("A button..try to recover\n");
            osSyncPrintf("Other buttons, re-insert\n");
            if (AskQuestion(i) == A_BUTTON) {
              osPfsRepairId(&pfs[i]);
            }
            break;
          }
          WaitForPushingAnyButton(i);
        } while (ret != 0) ;
      } else {
        osSyncPrintf("PORT %d is not a normal Controller\n", i);
      }
    } else {
       osSyncPrintf("Controller is not inserted into PORT %d\n", i);
    }
}

UP


26.3.3.2 Creates a new game note

Function

osPfsAllocateFile

Creates a new game note

Syntax

#include <ultra64.h>
s32 osPfsAllocateFile(OSPfs *pfs, u16 company_code, u32 game_code, u8 *game_name,
u8 *ext_name, int length, s32 *file_no);

Description

osPfsAllocateFile creates a new game note (file) in a Controller Pak. The company_code (company code), game_code (game code), game_name (note name), ext_name (note extension), and length (size) arguments must be specified as the information for the game note.

The company_code and game_code are specified as ASCII character strings. The game_name and ext_name are specified by N64 font code.

The size of game_name is PFS_FILE_NAME_LEN(16) bytes. If the size is less than 16 bytes, fill the rest with 0x00. Be sure to make the length 16 bytes.

The size of ext_name is PFS_FILE_EXT_LEN(4) bytes. However, only the first byte is actually used. For this code, use '0' - '9', 'A' ~ 'Z' (0x10~0x33) of N64 font code. The second through fourth bytes are reserved, so use 0x00.

The size is specified by length, in bytes. Because the smallest internal unit is a page (256 bytes), if length is not specified in multiples of 256, the length will be rounded up to the nearest multiple of 256.

The newly created game note's note number (file descriptor) will be returned to file_no. Up to 16 game notes can be created. Therefore, file_no ranges from 0 to 15.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsAllocateFile is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

PFS_DATA_FULL

Although the creation of a new game note was attempted, one could not be created because there was not enough space in the Controller Pak.

PFS_DIR_FULL

Although the creation of a new game note was attempted, it could not be done because the maximum (16) number of game notes have been stored in the Controller Pak.

PFS_ERR_EXIST

Although the creation of a new game note was attempted, it could not be done because the same game note already exists in the Controller Pak.

UP


26.3.3.3 Checks and repairs the Controller Pak file system

Function

osPfsChecker

Checks and repairs the Controller Pak file system

Syntax

#include <ultra64.h>
s32 osPfsChecker(OSPfs *pfs);

Description

osPfsChecker inspects the file management area *12 of the Controller Pak. If it finds a damaged area, it attempts a repair operation. If a repair operation is performed, the status bit of the OSPfs structure pointed to by pfs is set to PFS_CORRUPTED. When this is done, data will be lost in most cases.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

Because osPfsInitPak calls osPfsChecker internally, the application programmer will not usually need to use the osPfsChecker function.

*12 where it manages the file notes address.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

UP


26.3.3.4 Deletes a game note

Function

osPfsDeleteFile

Deletes a game note

Syntax

#include <ultra64.h>
s32 osPfsDeleteFile(OSPfs *pfs, u16 company_code, u32 game_code, u8 *game_name,
u8 *ext_name);

Description

osPfsDeleteFile deletes a game note from the Controller Pak. The game note is specified by the company_code (company code), game_code (game code), game_name (note name), and ext_name (note extension) arguments.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsDeleteFile is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.5 Gets game note information

Function

osPfsFileState

Gets game note information

Syntax

#include <ultra64.h>
s32 osPfsFileState(OSPfs *pfs, s32 file_no, OSPfsState *state);

Description

The osPfsFileState obtains the specified game note information. To specify a game note, use the note number file_no (file descriptor) argument. To retrieve specific game note information, it is necessary to obtain the note number by calling osPfsFindFile, before calling this function. Also, to retrieve all game note information in a Controller Pak, assign 0 to 15 to the file number (file_no) and call osPfsFileState 16 times.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

The game note information is stored in the OSPfsState structure specified by the pointer state argument. The following is the definition of that structure:

typedef struct {
        u32 file_size;          /* Note Size (number of bytes) */
        u32 game_code;          /* Game Code */
        u16 company_code;       /* Company Code */
        char ext_name[4];       /* Note Extension */
        char game_name[16];     /* Note Name */
}

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsFileState is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.6 Searches for a specified game note

Function

osPfsFindFile

Searches for a specified game note

Syntax

#include <ultra64.h>
s32 osPfsFindFile(OSPfs *pfs, u16 company_code, u32 game_code, u8 *game_name,
u8 *ext_name, s32 *file_no);

Description

The osPfsFindFile searches for a specific game note in the Controller Pak. The company code (company_code), game code (game_code), note name (game_name), and note extension (ext_name) arguments are required to specify the game note.

If the specified game note is found in the Controller Pak, the note number (file descriptor) is returned to the file_no argument. If the game note cannot be found, PFS_ERR_INVALID is returned as the error code.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsFindFile is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.7 Gets the free byte size of the Controller Pak

Function

osPfsFreeBlocks

Gets the free byte size of the Controller Pak

Syntax

#include <ultra64.h>
s32 osPfsFreeBlocks(OSPfs *pfs, s32 *bytes_not_used);

Description

osPfsFreeBlocks finds the available number of bytes in a Controller Pak. The available number of bytes is returned to the location pointed to by bytes_not_used.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsFreeBlocks is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.8 Reads a label

Function

osPfsGetLabel

Reads a label

Syntax

#include <ultra64.h>
s32 osPfsGetLabel(OSPfs *pfs, u8 *label, int *length);

Description

A BLOCKSIZE (32 bytes) label area exists in the Controller Pak. osPfsGetLabel reads the label of a Controller Pak. The specification for this label area has not yet been defined. Therefore, DO NOT USE THIS FUNCTION.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

The area specified by the label needs to have the size BLOCKSIZE to store label data.

If this function is called successfully, 0 is retruned, and the length of the label is returned to the location pointed to by the length argument. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

UP


26.3.3.9 Checks whether a pak-type SI device is inserted

Function

osPfsIsPlug

Checks whether a pak-type SI device is inserted

Syntax

#include <ultra64.h>
s32 osPfsIsPlug(OSMesgQueue *mq, u8 *bitpattern);

Description

The osPfsIsPlug detects which Controller contains a SI-Controller Pak, and it returns the results as a bit pattern to the location pointed to by the bitpattern argument. Bits 0, 1, 2, and 3 of the bit pattern correspond to Controllers 1, 2, 3, and 4, respectively. An SI device has been inserted if a bit for each controller is on. If a bit is off that means 0, no device has been inserted for that controller.

The mq argument is the initialized message queue linked to OS_EVENT_SI. Please refer to osSetEventMesg() for creation of this link. Because mq is used by the function as an internal message queue, it is not necessary for the application to use mq for purposes such as queuing function-termination messages.

If this function is called successfully, 0 is retruned. If an error occurs, -1 is returned:

Example

main()
{
        OSMesgQueue     intMesgQueue;
        OSMesg          intMesgBuf[1];
        OSContStatus    sdata[MAXCONTROLLERS];
        u8              cont_pattern;
        u8              pak_pattern;

        osCreateMesgQueue(&intMesgQueue, intMesgBuf, 1);
        osSetEventMesg(OS_EVENT_SI, &intMesgQueue, NULL);
        osContInit(&intMesgQueue, &cont_pattern, &sdata[0]);
        osPfsIsPlug(&intMesgQueue, &pak_pattern);
}

Reference

In addition to osPfsIsPlug, some functions can be used to check if the Controller Pak SI devices are inserted, which inculde osPfsInitPak, osContStartQuery, and osContGetQuery. There are, however, differences described below.

The osPfsIsPlug function issues a request command that checks the status of the Controller and Controller Pak. It checks all Controller sockets, converts the results to a bit pattern, and returns them.

In contrast, osPfsInitPak performs processing for only a single Controller. In addition to performing the Controller and Controller Pak status check that osPfsIsPlug performs, it also performs processing such as initializing the OSPfs structure, acquiring the Controller Pak ID and label areas, and calling the osPfsChecker function. As a result, it is very time consuming to call osPfsInitPak, compared to osPfsIsPlug, to determine whether the Controller Pak is inserted.

For simple status checking, the fastest approach is to use osContStartQuery and osContGetQuery. These functions perform the same processing as the osPfsIsPlug function does and they simplify the error checking process. Also they are a general-purpose function for all SI devices and can therefore also take parameters other than those used to detect whether a Pak-type SI device has been inserted. osPfsIsPlug should not be overused; osContStartQuery and osContGetQuery should be used instead whenever possible.

UP


26.3.3.10 Gets the maximum number of notes and the number of notes in use

Function

osPfsNumFiles

Gets the maximum number of notes and the number of notes in use

Syntax

#include <ultra64.h>
s32 osPfsNumFiles(OSPfs *pfs, s32 *max_files, s32 *files_used);

Description

osPfsNumFiles acquires the maximum note number and the number of notes used in the Controller Pak. When called, this function returns the number of notes used to the location pointed to by the files_used argument, and it returns the total number of notes to the location pointed to by the max_files argument, which is 16.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsNumFiles is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.11 Reads/writes data to a game note

Function

osPfsReadWriteFile

Reads/writes data to a game note

Syntax

#include <ultra64.h>
s32 osPfsReadWriteFile(OSPfs *pfs, s32 file_no, u8 flag, int offset, int
nbytes, u8 * data_buffer);

Description

The osPfsReadWriteFile reads from and writes to game notes. If PFS_READ is specified for the flag argument, data is read from the game note; if PFS_WRITE is specified data is written to the game note.

When data is read, the amount of data specified by the nbytes argument is read, beginning from the offset byte of the game data area specified by the offset argument, and stored in the area pointed to by the data_buffer argument. When data is written, nbytes of data in the area specified by data_buffer is written to the game data area beginning from the offset byte. Both the offset and nbytes arguments must be set to a multiple of BLOCKSIZE (32 bytes) and must be smaller than the file size. The arguments cannot, of course, be set so that data is read from or written to areas outside of those that have been assigned.

The file_no argument specifies the note number (file descriptor). To obtain its value, call the osPfsAllocateFile or osPfsFindFile function.

The OSPfs structure pointed to by the pfs argument is a file handle initialized by the osPfsInitPak function. For information on creating this handle, please see osPfsInitPak().

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_INCONSISTENT

There is a problem in the file system's management area. Usually this error does not occur because osPfsChecker is called internally when you initialize the file system by calling osPfsInitPak. If this error is returned, either the Controller Pak is not connected properly, or the Controller Pak itself is damaged.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsReadWriteFile is executed after the initialization function for Rumble Pak, osMotorInit, is used to initialize OSPfs structure, then this error occurs.

PFS_ERR_BAD_DATA

This is returned when the function (osPfsReadWriteFile) attempts to read data even though the data has not yet been written. If data is written, the PFS_WRITE bit is set to indicate the status of the file information area. When data is read, this bit is checked; if it is not set, this error is returned.

UP


26.3.3.12 Repairs the file system

Function

osPfsRepairId

Repairs the file system

Syntax

#include <ultra64.h>
s32 osPfsRepairId (OSPfs *pfs);

Description

It checks the Controller Pak ID area, assigns a new ID if this area is damaged, and repairs the Controller Pak file system.

Usually this function can be used if a PFS_ERROR_ID_FATAL error code is returned by the ofPfsInitPak fuction. For details, please see osPfsInitPak().

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

PFS_ERR_ID_FATAL

Recovery failed. Possible causes are an abnormality in the controller Joyport or Controller Pak.

PFS_ERR_DEVICE

A peripheral device other than a Controller Pak (eg, Rumble Pak, 64GB Pak) has been inserted in the controller. Whether a Controller Pak has been inserted is determined by whether the device has RAM. This error is issued if there is no RAM present.

PFS_ERR_INVALID

If this error is returned, an incorrect argument was specified when this function was called, the specified game note does not exist, or the Pfs function has been called without being initialized using osPfsInitPak. Also, if the functions for the Controller were executed after the file handle structure pfs was initialized by other than osPfsInitPak, this error occurs.For instance, if osPfsRepairId is executed after the initialization function for Rumble Pak osMotorInit is used to initialize OSPfs structure, then this error occurs.

UP


26.3.3.13 Writes a label

Function

osPfsSetLabel

Writes a label

Syntax

#include <ultra64.h>
s32 osPfsSetLabel(OSPfs *pfs, u8 *label);

Description

A 32-byte label area is provided in the Controller Pak. The function osPfsSetLabel writes this label. Currently, the specifications for the label have not been defined. Thus, this function should not yet be used.

The osPfsSetLabel writes data specified by label to the label area.

The OSPfs structure pointed to by pfs is the file handle to be initialized by the function osPfsInitPak(). Please refer to osPfsInitPak to determine how to create this handle.

If this function is called successfully, 0 is retruned. If an error occurs, one of the following error codes is returned:

PFS_ERR_NOPACK

Either the Controller Pak is not inserted into the specified Controller or the Controller is not properly connected. To determine which is the case, use osContStartQuery or osContGetQuery.

PFS_ERR_NEW_PACK

A different Controller Pak has been inserted. To use the inserted Controller Pak, initialize it by calling osPfsInitPak.

PFS_ERR_CONTRFAIL

Data transfer to or from the Controller has failed. If a transfer error occurs, up to three tries will be done internally. Therefore, it is rather rare to see this error. If this error has returned, it is possible that either the Controller is not connected properly, or the Controller Pak or Controller Socket is damaged.

UP


26.3.4 Using the Controller Pak Functions

The following charts show an example of the user interface when the Controller Pak is being used. Please use them as a reference for developing custom applications.

The charts do not, however, cover processing for cases such as removal of the Controller Pak by the user during game play. These possibilities should also be considered. In such cases, responses such as the display of the following message should be implemented, "No Controller Pak. Unable to Save".

Figure 26-1 Controller Pak Initialization Flow Chart

Figure 26-2 Example 1 - Using the Controller Pak Functions
(Setting Controller Pak to use at the Game Start)

Figure 26-3 Example 2 - Using the Controller Pak Functions
(Controller Pak is Changed During a Game)

UP


26.3.5 Controller Pak Menu Functions

A utility function library and sample program for the Controller Pak menu are available in /usr/src/PR/demos/nosPak. The English-language version of the library is named libnos.a. and libnos_jpn.a for the Japanese-language version.

When linking, use the -lnos or -lnos_jpn option before -lultra (-lultra_d). For details, refer to the Nintendo 64 Function Reference Manual under libnos.a or libnos_jpn.a. The two functions that can be used with this library are as follows.

nosPakMenu() a simple Controller Pak menu
nosLoadFont() expands the font data for English-language characters and Katakana in memory

A sample that incorporates nosPakMenu in the sample program, onetri, is also available.

In addition, if you wish to use a font which is used in this module, nosLoadFont can be used by an application. This function can be used without linking to nosPakMenu.

The N64 font codes are defined in the file ncode.h, included in the Nintendo 64 Software Library.

UP


26.3.5.1 Simple Controller Pak Menu

Function

nosPakMenu

Simple Controller Pak Menu

Syntax

#include <libnos.h>
int nosPakMenu (OSMesgQueue *siMessageQ, OSMesgQueue *retraceMessageQ);

Description

The nosPakMenu() function is a simple Controller Pak menu application. The game player can use this menu to view a list of game notes stored in the Controller Pak, to check the number of pages used and the number of pages remaining, and to delete unnecessary game notes.

siMessageQ is the initialized message queue associated with OS_EVENT_SI events, while retraceMessageQ is the initialized message queue associated with vertical retraces. To learn how to create these associations, see the osSetEventMesg(),and osSetEvent() functions, in the N64 Online Function Reference Manual.

To open the menu, the user must press the START button on the Controller while the program is booting up or being Reset. The menu does not open up if the START button is not pressed and the Controller Pak is not inserted in the Controller.

The following values are returned as error codes:

Condition Return Value
When the Controller Pak is not ready 0
When an error occurs in the Controller Pak menu 1
When the Controller Pak is OK but the START button is not pressed 2
When EXIT is selected in the Controller Pak menu 3

UP


26.3.5.2 Loading the Font Data

Function

nosLoadFont

Loading the Font Data onto memory

Syntax

#include <libnos.h>
void nosLoadFont (u16 *font_buf);

Description

The nosLoadFont() function expands the compressed character font data in RAM in the order of the N64 font codes so the fonts can be used by the application. The start address of the buffer where the data will be expanded is specified as an argument. The necessary size of the buffer is shown below:

English 2112 bytes (0x840) Defined in libnos.h as FONTSIZE_E.
English + Japanese 4768 bytes (0x12a0) Defined in libnos.h as FONTSIZE_J.

The character font size is 16 dots (horizontal) x 16 dots (vertical). One horizontal line of 16 dots corresponds to 16 bits of data. The Hi side is the left side of the font, while the Lo side is the right side.

The N64 font codes for the character fonts is shown in order below:

UP


26.3.5.3 Internal Functions (Reference)

The following flowcharts show how errors occur within Controller Pak functions. Please use these flow charts as a reference.

Figure 26-4 Processing Flow and Error Generation Inside a General Pfs Function

UP