sm64

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

osContInit.c (3798B)


      1 #include "libultra_internal.h"
      2 #include "osContInternal.h"
      3 #include "PR/os.h"
      4 #include "controller.h"
      5 #include "PR/ique.h"
      6 
      7 void __osPackRequestData(u8);
      8 void __osContGetInitData(u8 *, OSContStatus *);
      9 
     10 u32 _osContInitialized = 0; // probably initialized
     11 
     12 #ifdef VERSION_CN
     13 #define CLOCK_RATE (62500000ULL * 3 / 4)
     14 #else
     15 #define CLOCK_RATE osClockRate
     16 #endif
     17 
     18 // these probably belong in EEPROMlongread or something
     19 u8 __osContLastCmd;
     20 u8 __osMaxControllers;
     21 OSTimer __osEepromTimer;
     22 OSMesgQueue __osEepromTimerQ;
     23 OSMesg __osEepromTimerMsg[4];
     24 
     25 s32 osContInit(OSMesgQueue *mq, u8 *bitpattern, OSContStatus *status) {
     26     OSMesg mesg;
     27     u32 ret = 0;
     28     OSTime currentTime;
     29     OSTimer timer;
     30     OSMesgQueue timerMesgQueue;
     31 
     32     if (_osContInitialized) {
     33         return 0;
     34     }
     35     _osContInitialized = 1;
     36     currentTime = osGetTime();
     37     if (500000 * CLOCK_RATE / 1000000 > currentTime) {
     38         osCreateMesgQueue(&timerMesgQueue, &mesg, 1);
     39         osSetTimer(&timer, 500000 * CLOCK_RATE / 1000000 - currentTime, 0, &timerMesgQueue, &mesg);
     40         osRecvMesg(&timerMesgQueue, &mesg, OS_MESG_BLOCK);
     41     }
     42     __osMaxControllers = MAXCONTROLLERS;
     43 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN)
     44     __osPackRequestData(0);
     45 #else
     46     __osPackRequestData(255);
     47 #endif
     48     ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray);
     49     osRecvMesg(mq, &mesg, OS_MESG_BLOCK);
     50     ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray);
     51     osRecvMesg(mq, &mesg, OS_MESG_BLOCK);
     52     __osContGetInitData(bitpattern, status);
     53 #if defined(VERSION_EU) || defined(VERSION_SH)
     54     __osContLastCmd = CONT_CMD_REQUEST_STATUS;
     55 #elif defined(VERSION_CN)
     56     __osContLastCmd = 0xfd;
     57 #else
     58     __osContLastCmd = CONT_CMD_RESET;
     59 #endif
     60     __osSiCreateAccessQueue();
     61     osCreateMesgQueue(&__osEepromTimerQ, __osEepromTimerMsg, 1);
     62     return ret;
     63 }
     64 
     65 void __osContGetInitData(u8 *bitpattern, OSContStatus *status) {
     66     u8 *cmdBufPtr;
     67     OSContPackedRequest response;
     68     s32 i;
     69     u8 sp7;
     70 
     71     sp7 = 0;
     72     cmdBufPtr = (u8 *) __osContPifRam.ramarray;
     73     for (i = 0; i < __osMaxControllers; i++, cmdBufPtr += sizeof(OSContPackedRequest), status++) {
     74         response = *(OSContPackedRequest *) cmdBufPtr;
     75         status->errnum = (response.rxLen & 0xc0) >> 4;
     76         if (status->errnum == 0) {
     77             status->type = response.data2 << 8 | response.data1;
     78 #ifdef VERSION_CN
     79             status->status = __osBbPakAddress[i] != NULL ? 1 : 0;
     80 #else
     81             status->status = response.data3;
     82 #endif
     83 
     84             sp7 |= 1 << i;
     85         }
     86     }
     87 #ifdef VERSION_CN
     88     if (__osBbIsBb != 0 && __osBbHackFlags != 0) {
     89         OSContStatus tmp;
     90         status -= __osMaxControllers;
     91         sp7 = (sp7 & ~((1 << __osBbHackFlags) | 1)) |
     92                 ((sp7 & 1) << __osBbHackFlags) |
     93                 ((sp7 & (1 << __osBbHackFlags)) >> __osBbHackFlags);
     94         tmp = *status;
     95         *status = status[__osBbHackFlags];
     96         status[__osBbHackFlags] = tmp;
     97     }
     98 #endif
     99     *bitpattern = sp7;
    100 }
    101 
    102 void __osPackRequestData(u8 command) {
    103     u8 *cmdBufPtr;
    104     OSContPackedRequest request;
    105     s32 i;
    106 
    107 #ifdef VERSION_CN
    108     for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray); i++) {
    109 #else
    110     for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray) + 1; i++) {
    111 #endif
    112         __osContPifRam.ramarray[i] = 0;
    113     }
    114 
    115     __osContPifRam.pifstatus = 1;
    116     cmdBufPtr = (u8 *) __osContPifRam.ramarray;
    117     request.padOrEnd = 255;
    118     request.txLen = 1;
    119     request.rxLen = 3;
    120     request.command = command;
    121     request.data1 = 255;
    122     request.data2 = 255;
    123     request.data3 = 255;
    124     request.data4 = 255;
    125 
    126     for (i = 0; i < __osMaxControllers; i++) {
    127         * (OSContPackedRequest *) cmdBufPtr = request;
    128         cmdBufPtr += sizeof(OSContPackedRequest);
    129     }
    130     *cmdBufPtr = 254;
    131 }