sm64

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

osAiSetNextBuffer.c (1348B)


      1 #include "libultra_internal.h"
      2 #include "PR/rcp.h"
      3 
      4 /**
      5  * It is worth noting that a previous hardware bug has been fixed by a software
      6  * patch in osAiSetNextBuffer. This bug occurred when the address of the end of the
      7  * buffer specified by osAiSetNextBuffer was at a specific value. This value
      8  * occurred when the following was true:
      9  *
     10  *     (vaddr + nbytes) & 0x00003FFF == 0x00002000
     11  *
     12  * (when the buffer ends with address of lower 14 bits 0x2000) In this case, the
     13  * DMA transfer does not complete successfully. This can cause clicks and pops in
     14  * the audio output. This bug no longer requires special handling by the application
     15  * because it is now patched by osAiSetNextBuffer.
     16  */
     17 
     18 s32 osAiSetNextBuffer(void *buff, u32 len) {
     19     static u8 hdwrBugFlag = 0;
     20     char *bptr;
     21 
     22 #ifdef VERSION_CN
     23     if (__osAiDeviceBusy()) {
     24         return -1;
     25     }
     26 #endif
     27 
     28     bptr = buff;
     29 
     30     if (hdwrBugFlag != 0) {
     31         bptr -= 0x2000;
     32     }
     33 
     34 #ifdef VERSION_CN
     35     if ((((uintptr_t) buff + len) & 0x1fff) == 0) {
     36 #else
     37     if ((((uintptr_t) buff + len) & 0x3fff) == 0x2000) {
     38 #endif
     39         hdwrBugFlag = 1;
     40     } else {
     41         hdwrBugFlag = 0;
     42     }
     43 
     44 #ifndef VERSION_CN
     45     if (__osAiDeviceBusy()) {
     46         return -1;
     47     }
     48 #endif
     49 
     50     IO_WRITE(AI_DRAM_ADDR_REG, osVirtualToPhysical(bptr));
     51     IO_WRITE(AI_LEN_REG, len);
     52     return 0;
     53 }