osEPiRawStartDma, osEPiRawWriteIo, osEPiRawReadIo, osEPiGetDeviceType

Gains access to EPI without PI manager (Not supported under os2.01/patch5 or later)


#include <ultra64.h>
s32 osEPiRawStartDma(OSPiHandle *pihandle, s32 direction,
u32 devAddr, void *vAddr, u32 nbytes);
s32 osEPiRawWriteIo(OSPiHandle *pihandle, u32 devAddr, u32 data);
s32 osEPiRawReadIo(OSPiHandle *pihandle, u32 devAddr, u32 *data);
s32 osEPiGetDeviceType(OSPiHandle *pihandle, OSPiInfo *info);


The expanded peripheral interface (EPI) transfers data between RDRAM and a bulk storage device (BSD) such as ROM, Drive ROM, and the N64 Disk Drive. EPI supports many devices sharing the PI domain, and it can switch among these devices dynamically.

The osEPiRawStartDma, osEPiRawWriteIo, osEPiRawReadIo, and osEPiGetDeviceType functions gain access to the expanded peripheral interface (EPI) without using the PI manager.However, these functions should be used only when other services including debug, print, logging, and profiling are not using the PI bus. Nintendo strongly recommends that the PI manager be used when using the EPI. Please see osEPiStartDma for more information.

The OSPiHandle data structure acts as a handler for the EPI routine when referencing each PI device without using the PI manager. The OSPiHandle structure is allocated and initialized by each device's initialization routine. It is also used for saving each PI device attributes.

The osEPiRawStartDma function sets up the DMA transfer condition between RDRAM (using the virtual address pointed to by the vAddr argument) and the EPI device (using the address specified by the devAddr argument) based on the value of the direction argument (OS_READ or OS_WRITE). The counter specified by the nbytes argument is the transfer size of DMA (16 megabytes is the maximum); it must be a multiple of two. Two-byte alignment must be done for the PI's device address (devAddr). Although eight-byte alignment is required for the RDRAM's virtual address (vAddr), 16-byte alignment is recommended if you are performing an RDRAM operation with OS_READ. Please refer to OS_DCACHE_ROUNDUP_ADDR concerning problems that may occur when address and transfer volume is not a multiple of the cache line (16 bytes).The osEPiRawStartDma routine performs a polling operation to determine whether or not the interface is available before setting the DMA register.

The osEPiRawWriteIo routine performs a 32-bit IO Write operation from devAddr. This routine performs a polling operation to determine whether or not the interface is available before the operation. Similarly, the osEPiRawReadIo routine performs a 32-bit IO Read operation from devAddr and stores the value to data. This routine also performs a polling operation to determine whether or not the interface is available before the operation. Note that four-byte alignment is necessary for devAddr.

The osEPiGetDeviceType routine gets the PI information recognized by the PI handler. The device information is represented by the OSPiInfo structure as shown here:

typedef struct {
        u8 type;
        u32 address;
} OSPiInfo;

The device type is either DEVICE_TYPE_CART (usual game Pak), DEVICE_TYPE_BULK (bulk storage device), or DEVICE_TYPE_64DD (disk drive). The specified device's base IO address is returned to the address field.


osEPiRawStartDma, osEPiRawWriteIo, and osEPiRawReadIo reset the PI bus if there is a discrepancy between the given PI bus setting specified by pihandle and the actual PI bus setting when the function is called. It is not necessary to call osCartRomInit each time.

See Also

osPiRawStartDma, osPiStartDma, osEPiStartDma , osCartRomInit, osEPiRawWriteIo, osEPiGetDeviceType, osPiRawStartDma, and osCartRomInit