sm64

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

contramwrite.c (2614B)


      1 #include "libultra_internal.h"
      2 #include "PR/rcp.h"
      3 #include "controller.h"
      4 #include "macros.h"
      5 
      6 extern s32 __osPfsGetStatus(OSMesgQueue *, s32);
      7 void __osPackRamWriteData(s32 channel, u16 address, u8 *buffer);
      8 
      9 s32 __osContRamWrite(OSMesgQueue *mq, s32 channel, u16 address, u8 *buffer, s32 force) {
     10     s32 ret;
     11     s32 i;
     12     u8 *ptr;
     13     __OSContRamReadFormat ramreadformat;
     14     s32 retry;
     15 
     16     ret = 0;
     17     ptr = (u8 *)&__osPfsPifRam;
     18     retry = 2;
     19     if (force != 1 && address < 7 && address != 0) {
     20         return 0;
     21     }
     22     __osSiGetAccess();
     23     __osContLastCmd = CONT_CMD_WRITE_MEMPACK;
     24     __osPackRamWriteData(channel, address, buffer);
     25     ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
     26     osRecvMesg(mq, NULL, OS_MESG_BLOCK);
     27     do {
     28         ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
     29         osRecvMesg(mq, NULL, OS_MESG_BLOCK);
     30         ptr = (u8 *)&__osPfsPifRam;
     31         if (channel != 0) {
     32             for (i = 0; i < channel; i++) {
     33                 ptr++;
     34             }
     35         }
     36 
     37         ramreadformat = *(__OSContRamReadFormat *)ptr;
     38 
     39         ret = CHNL_ERR(ramreadformat);
     40         if (ret == 0) {
     41             if (__osContDataCrc(buffer) != ramreadformat.datacrc) {
     42                 ret = __osPfsGetStatus(mq, channel);
     43                 if (ret != 0) {
     44                     __osSiRelAccess();
     45                     return ret;
     46                 }
     47                 ret = PFS_ERR_CONTRFAIL;
     48             }
     49         } else {
     50             ret = PFS_ERR_NOPACK;
     51         }
     52         if (ret != PFS_ERR_CONTRFAIL) {
     53             break;
     54         }
     55     } while ((retry-- >= 0));
     56     __osSiRelAccess();
     57     return ret;
     58 }
     59 
     60 void __osPackRamWriteData(int channel, u16 address, u8 *buffer) {
     61     u8 *ptr;
     62     __OSContRamReadFormat ramreadformat;
     63     int i;
     64 
     65     ptr = (u8 *)__osPfsPifRam.ramarray;
     66 
     67     for (i = 0; i < ARRAY_COUNT(__osPfsPifRam.ramarray) + 1; i++) {
     68         __osPfsPifRam.ramarray[i] = 0;
     69     }
     70 
     71     __osPfsPifRam.pifstatus = CONT_CMD_EXE;
     72     ramreadformat.dummy = CONT_CMD_NOP;
     73     ramreadformat.txsize = CONT_CMD_WRITE_MEMPACK_TX;
     74     ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX;
     75     ramreadformat.cmd = CONT_CMD_WRITE_MEMPACK;
     76     ramreadformat.address = (address << 0x5) | __osContAddressCrc(address);
     77     ramreadformat.datacrc = CONT_CMD_NOP;
     78     for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) {
     79         ramreadformat.data[i] = *buffer++;
     80     }
     81     if (channel != 0) {
     82         for (i = 0; i < channel; i++) {
     83             *ptr++ = 0;
     84         }
     85     }
     86     *(__OSContRamReadFormat *)ptr = ramreadformat;
     87     ptr += sizeof(__OSContRamReadFormat);
     88     ptr[0] = CONT_CMD_END;
     89 }