With previous osPi functions, the programmer only needed to access the Game Pak. To do this the programmer would provide the virtual address of Game Pak ROM, (not a physical address but an offset from the start of the cartridge), to a function and switch the offset to a physical address within the osPi function. (For example, the first address of the Game Pak can be accessed if 0 is given to osPi*, but the actual first physical address of Game Pak is 0x1000_0000.)
Using the previous osPi functions, the programmer could access the address space of Game Pak ROM, however, an Extension device located in another address space like SRAM or the ROM in the N64 Disk Drive could not be used.
The new osEPi function (Enhanced PI) allows the programmer to indicate which device is to be accessed using a handler (OSPiHandle structure). A handler is set up depending upon the characteristics of the hardware to be used. Standard handler acquisition functions are listed below.
Device Name | Handler Acquisition Function |
---|---|
Game Pak ROM | osCartRomInit() |
N64 Disk Drive ROM | osDriveRomInit() |
N64 Disk Drive Registers | osLeoDiskInit() |
The return values of the above handler acquisition functions will be the handler for each device. For example, in the case of ROM software, the programmer can use functions such as OSPiHandle *carthandle and proceed to,
carthandle = osCartRomInit()
"carthandle", a handler for ROM software will be returned. With the use of the new function, driveromhandle, the following steps can be performed.
(Using osLeoDiskInit(), the N64 Disk Drive registers can be accessed, but in general, a user does not need to use this function. These settings are done automatically in the N64 Disk Drive device manager.)
The handler contains the following information.
typedef struct OSPiHandle_s { struct OSPiHandle_s *next; /* point to next handle on the table */ u8 type; /* DEVICE_TYPE_BULK for disk */ u8 latency; /* domain latency */ u8 pageSize; /* domain page size */ u8 relDuration; /* domain release duration */ u8 pulse; /* domain pulse width */ u8 domain; /* which domain */ u32 baseAddress; /* Domain address */ u32 speed; /* for roms only */ /* The following are "private" elements" */ __OSTranxInfo transferInfo; /* for disk only */ } OSPiHandle; (from os.h)
Here, latency, pageSize, relDuration, and pulse are parameters that determine the access speed of the PI bus.
The user needs to set up an appropriate value for the device being used.
Domain means domain names. There are two domains (domain 1 and domain 2). Domain is an area where each speed parameter can be set. Addresses for each domain are divided into several areas and defined in rcp.h, as listed below.
#define PI_DOM1_ADDR1 0x06000000 /* to 0x07FFFFFF */ #define PI_DOM1_ADDR2 0x10000000 /* to 0x1FBFFFFF */ #define PI_DOM1_ADDR3 0x1FD00000 /* to 0x7FFFFFFF */ #define PI_DOM2_ADDR1 0x05000000 /* to 0x05FFFFFF */ #define PI_DOM2_ADDR2 0x08000000 /* to 0x0FFFFFFF */
Even if a device exists whose speed is different within the same domain, it is possible to change the speed parameter using the EPI.
Device Type is used internally to distinguish the type of media used. The current N64 environment supports values 0 through 2. Values 0 through 3 or greater will be supported in the future as new devices come available.
/************************************************************************* * External device info */ #define DEVICE_TYPE_CART 0 /* ROM cartridge */ #define DEVICE_TYPE_BULK 1 /* ROM bulk */ #define DEVICE_TYPE_64DD 2 /* 64 Disk Drive */ #define DEVICE_TYPE_SRAM 3 /* SRAM */ (from rcp.h)
baseAddress is a start address for the device. If a programmer simply provides the offset from the first address to osEPi without the starting address, the osEPi function will OR the offset and baseAddress, and the device will be accessed with the resulting value.
speed is a parameter reserved for the future. For the time being, there is no need to set this parameter.
transferInfo is a parameter that can be used only for the N64 Disk Drive. There is no need to set this parameter for any device other than the N64 Disk Drive.
As it is cumbersome to set each value, the Handler acquisition function described above was produced. As these functions provide an appropriate setting for each device, an application programmer can acquire a handler by simply calling these functions. To access the device after calling the handler acquisition function, the programmer can use the handler which was already acquired.
The function osEPi remembers the device setting of the current Pi bus. When it is next called, it will set the Pi bus if the specified device is different. If the specified device is the same, it will process DMA.
The EPI Manager can be used like the old PI Manager using the handler that is set. For usage of each EPI function, please refer to the N64 Function Reference Manual.