sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

osEPiRawStartDma.c (3195B)


      1 #include "libultra_internal.h"
      2 #include "PR/rcp.h"
      3 #include "PR/ique.h"
      4 #include "new_func.h"
      5 #include "PR/R4300.h"
      6 #include "piint.h"
      7 
      8 // TODO: This define is from os.h, but including that causes problems...
      9 #define PI_DOMAIN1 0
     10 
     11 #if defined(VERSION_SH) || defined(VERSION_CN)
     12 extern OSPiHandle *__osCurrentHandle[2];
     13 #endif
     14 
     15 s32 osEPiRawStartDma(OSPiHandle *pihandle, s32 dir, u32 devAddr, void *dram_addr, u32 size) {
     16 #ifdef VERSION_CN
     17     u64 dummyBuf[2];
     18     u32 status;
     19     u32 domain;
     20     u32 buf;
     21     u32 mask;
     22     u16 *tmp;
     23     u32 i;
     24     u32 end;
     25 #elif defined(VERSION_SH)
     26     u32 status;
     27     u32 domain;
     28 #else
     29     register u32 status;
     30 #endif
     31 
     32 #if defined(VERSION_SH) || defined(VERSION_CN)
     33     EPI_SYNC(pihandle, status, domain);
     34 #else
     35     WAIT_ON_IO_BUSY(status);
     36 #endif
     37 
     38 #ifdef VERSION_CN
     39     if (dir == OS_READ) {
     40         mask = 1;
     41 
     42         for (i = 1; i <= pihandle->pageSize + 2; i++) {
     43             mask *= 2;
     44         }
     45 
     46         if ((devAddr & (mask - 1)) == mask - 2) {
     47             osEPiRawReadIo(pihandle, devAddr - 2, &buf);
     48 
     49             tmp = (u16 *) PHYS_TO_K1(dram_addr);
     50             *(tmp++) = (u16) buf;
     51 
     52             devAddr += 2;
     53             dram_addr = tmp;
     54             size -= 2;
     55 
     56             if (size >= 4) {
     57                 osEPiRawReadIo(pihandle, devAddr, &buf);
     58 
     59                 tmp = (u16 *) dram_addr;
     60                 *(tmp++) = buf >> 16;
     61                 *(tmp++) = (u16) buf;
     62 
     63                 devAddr += 4;
     64                 dram_addr = tmp;
     65                 size -= 4;
     66 
     67                 if (size != 0) {
     68                     osEPiRawReadIo(pihandle, devAddr, &buf);
     69 
     70                     tmp = (u16 *) PHYS_TO_K1(dram_addr);
     71                     *(tmp++) = buf >> 16;
     72 
     73                     devAddr += 2;
     74                     dram_addr = tmp;
     75                     size -= 2;
     76                 }
     77             }
     78         }
     79 
     80         end = devAddr + size;
     81 
     82         if (((end & (mask - 1)) == 2) | (size == 2)) {
     83             if (end & 2) {
     84                 osEPiRawReadIo(pihandle, end - 2, &buf);
     85                 tmp = (u16 *) PHYS_TO_K1(dram_addr) + (size - 2) / 2;
     86                 *tmp = buf >> 16;
     87             } else {
     88                 osEPiRawReadIo(pihandle, end - 4, &buf);
     89                 tmp = (u16 *) PHYS_TO_K1(dram_addr) + (size - 2) / 2;
     90                 *tmp = (u16) buf;
     91             }
     92 
     93             size -= 2;
     94         }
     95 
     96         if (size == 0) {
     97             size = 8;
     98             dram_addr = dummyBuf;
     99             devAddr = 0;
    100         }
    101     }
    102 #endif
    103 
    104     IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dram_addr));
    105     IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(pihandle->baseAddress | devAddr));
    106 
    107 #ifdef VERSION_CN
    108     if ((u32) dir >= 2U) {
    109         return -1;
    110     }
    111 
    112     if ((pihandle->baseAddress | devAddr) <= 0x400) {
    113         IO_WRITE(dir == OS_READ ? PI_EX_WR_LEN_REG : PI_EX_RD_LEN_REG, size - 1);
    114     } else {
    115         IO_WRITE(dir == OS_READ ? PI_WR_LEN_REG : PI_RD_LEN_REG, size - 1);
    116     }
    117 #else
    118     switch (dir) {
    119         case OS_READ:
    120             IO_WRITE(PI_WR_LEN_REG, size - 1);
    121             break;
    122         case OS_WRITE:
    123             IO_WRITE(PI_RD_LEN_REG, size - 1);
    124             break;
    125         default:
    126             return -1;
    127     }
    128 #endif
    129     return 0;
    130 }
    131