Initializes the Controller Pak's file handle
#include <ultra64.h> /* os.h */
s32 osPfsInitPak(OSMesgQueue *mq, OSPfs *pfs, int controller_no);
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 managment area (FAT area) is destroyed.
Although the previous Pfs initialization function, osPfsInit, performed automatic recovery if the ID area was completely destroyed, osPfsInitPak does not perform automatic restoration. (osPfsInitPak confirms ID integrity internally by checksum comparison. If the checksums do not agree, the ID is evaluated as corrupted.) 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. And 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.
If an error occurs, one of the following error codes is returned:
The programming example with this function is shown below.
void
mainproc(void) {
int i;
OSMesgQueue intMesgQueue;
OSMesg intMesgBuf[1];
OSContStatus contstat[MAXCONTROLLERS];
OSPfs pfs[MAXCONTROLLERS];
u8 contpat;
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);
}
}
}
osPfsRepairId, osPfsAllocateFile, osPfsChecker, osPfsFileState, osPfsFreeBlocks, osPfsIsPlug, osPfsReadWriteFile, osPfsSetLabel, and osSetEventMesg
1999/02/01 Completely revised
1999/04/30 Changed format