sm64

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

load_sh.c (51421B)


      1 #if defined(VERSION_SH) || defined(VERSION_CN)
      2 #include <ultra64.h>
      3 #include <PR/os.h>
      4 
      5 #include "data.h"
      6 #include "external.h"
      7 #include "heap.h"
      8 #include "load.h"
      9 #include "seqplayer.h"
     10 
     11 #define ALIGN16(val) (((val) + 0xF) & ~0xF)
     12 
     13 struct SharedDma {
     14     /*0x0*/ u8 *buffer;       // target, points to pre-allocated buffer
     15     /*0x4*/ uintptr_t source; // device address
     16     /*0x8*/ u16 sizeUnused;   // set to bufSize, never read
     17     /*0xA*/ u16 bufSize;      // size of buffer
     18     /*0xC*/ u8 unused2;       // set to 0, never read
     19     /*0xD*/ u8 reuseIndex;    // position in sSampleDmaReuseQueue1/2, if ttl == 0
     20     /*0xE*/ u8 ttl;           // duration after which the DMA can be discarded
     21 };                            // size = 0x10
     22 
     23 void port_eu_init(void);
     24 void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo);
     25 void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue);
     26 
     27 struct Note *gNotes;
     28 
     29 UNUSED static u32 pad;
     30 
     31 struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS];
     32 struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS];
     33 struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS];
     34 
     35 struct SequenceChannel gSequenceChannelNone;
     36 struct AudioListItem gLayerFreeList;
     37 struct NotePool gNoteFreeLists;
     38 
     39 struct AudioBankSample *D_SH_8034EA88[0x80];
     40 struct UnkStructSH8034EC88 D_SH_8034EC88[0x80];
     41 s32 D_SH_8034F688; // index into D_SH_8034EA88
     42 s32 D_SH_8034F68C; // index or size for D_SH_8034EC88
     43 
     44 struct PendingDmaAudioBank {
     45     s8 inProgress;
     46     s8 timer;
     47     s8 medium;
     48     struct AudioBank *audioBank;
     49     uintptr_t devAddr;
     50     void *vAddr;
     51     u32 remaining;
     52     u32 transferSize;
     53     u32 encodedInfo;
     54     OSMesgQueue *retQueue;
     55     OSMesgQueue dmaRetQueue;
     56     OSMesg mesgs[1];
     57     OSIoMesg ioMesg;
     58 };
     59 struct PendingDmaAudioBank sPendingDmaAudioBanks[16];
     60 
     61 OSMesgQueue gUnkQueue1;
     62 OSMesg gUnkMesgBufs1[0x10];
     63 OSMesgQueue gUnkQueue2;
     64 OSMesg gUnkMesgBufs2[0x10];
     65 
     66 OSMesgQueue gCurrAudioFrameDmaQueue;
     67 OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
     68 OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
     69 
     70 OSMesgQueue gAudioDmaMesgQueue;
     71 OSMesg gAudioDmaMesg;
     72 OSIoMesg gAudioDmaIoMesg;
     73 
     74 struct SharedDma *sSampleDmas;
     75 u32 gSampleDmaNumListItems;
     76 u32 sSampleDmaListSize1;
     77 u32 sUnused80226B40; // set to 0, never read
     78 
     79 // Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256.
     80 u8 sSampleDmaReuseQueue1[256];
     81 u8 sSampleDmaReuseQueue2[256];
     82 u8 sSampleDmaReuseQueueTail1;
     83 u8 sSampleDmaReuseQueueTail2;
     84 u8 sSampleDmaReuseQueueHead1;
     85 u8 sSampleDmaReuseQueueHead2;
     86 
     87 ALSeqFile *gSeqFileHeader;
     88 ALSeqFile *gAlCtlHeader;
     89 ALSeqFile *gAlTbl;
     90 u8 *gAlBankSets;
     91 u16 gSequenceCount;
     92 
     93 struct CtlEntry *gCtlEntries;
     94 
     95 struct AudioBufferParametersEU gAudioBufferParameters;
     96 u32 sDmaBufSize;
     97 s32 gMaxAudioCmds;
     98 s32 gMaxSimultaneousNotes;
     99 
    100 s16 gTempoInternalToExternal;
    101 
    102 s8 gSoundMode;
    103 
    104 s8 gAudioUpdatesPerFrame;
    105 
    106 extern u64 gAudioGlobalsStartMarker;
    107 extern u64 gAudioGlobalsEndMarker;
    108 
    109 extern u8 gSoundDataADSR[]; // ctl
    110 extern u8 gSoundDataRaw[];  // tbl
    111 extern u8 gMusicData[];     // sequences
    112 
    113 ALSeqFile *get_audio_file_header(s32 arg0);
    114 
    115 void *func_sh_802f3688(s32 bankId);
    116 void *get_bank_or_seq_wrapper(s32 arg0, s32 arg1);
    117 void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
    118 void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium);
    119 s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr,
    120         void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason);
    121 void func_sh_802f4a4c(s32 audioResetStatus);
    122 void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len);
    123 void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
    124 struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size,
    125         s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo);
    126 void func_sh_802f4dcc(s32 audioResetStatus);
    127 void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus);
    128 void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len);
    129 void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
    130 BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3);
    131 s32 func_sh_802f573c(s32 audioResetStatus);
    132 void *func_sh_802f3564(s32 seqId);
    133 s32 func_sh_802f3ec4(s32 arg0, uintptr_t *arg1);
    134 void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes);
    135 
    136 s32 canonicalize_index(s32 poolIdx, s32 idx);
    137 
    138 void decrease_sample_dma_ttls() {
    139     u32 i;
    140 
    141     for (i = 0; i < sSampleDmaListSize1; i++) {
    142         struct SharedDma *temp = &sSampleDmas[i];
    143         if (temp->ttl != 0) {
    144             temp->ttl--;
    145             if (temp->ttl == 0) {
    146                 temp->reuseIndex = sSampleDmaReuseQueueHead1;
    147                 sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i;
    148             }
    149         }
    150     }
    151 
    152     for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
    153         struct SharedDma *temp = &sSampleDmas[i];
    154         if (temp->ttl != 0) {
    155             temp->ttl--;
    156             if (temp->ttl == 0) {
    157                 temp->reuseIndex = sSampleDmaReuseQueueHead2;
    158                 sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i;
    159             }
    160         }
    161     }
    162 
    163     sUnused80226B40 = 0;
    164 }
    165 
    166 extern char shindouDebugPrint62[]; // "SUPERDMA"
    167 void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium) {
    168     UNUSED s32 sp60;
    169     struct SharedDma *dma;
    170     s32 hasDma = FALSE;
    171     uintptr_t dmaDevAddr;
    172     UNUSED u32 pad;
    173     u32 dmaIndex;
    174     u32 transfer;
    175     ssize_t bufferPos;
    176     u32 i;
    177 
    178     if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) {
    179         for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
    180             dma = &sSampleDmas[i];
    181             bufferPos = devAddr - dma->source;
    182             if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
    183                 // We already have a DMA request for this memory range.
    184                 if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) {
    185                     // Move the DMA out of the reuse queue, by swapping it with the
    186                     // tail, and then incrementing the tail.
    187                     if (dma->reuseIndex != sSampleDmaReuseQueueTail2) {
    188                         sSampleDmaReuseQueue2[dma->reuseIndex] =
    189                             sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
    190                         sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex =
    191                             dma->reuseIndex;
    192                     }
    193                     sSampleDmaReuseQueueTail2++;
    194                 }
    195                 dma->ttl = 60;
    196                 *dmaIndexRef = (u8) i;
    197                 return &dma->buffer[(devAddr - dma->source)];
    198             }
    199         }
    200 
    201         if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) {
    202             // Allocate a DMA from reuse queue 2. This queue can be empty, since
    203             // TTL 60 is pretty large.
    204             dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
    205             sSampleDmaReuseQueueTail2++;
    206             dma = sSampleDmas + dmaIndex;
    207             hasDma = TRUE;
    208         }
    209     } else {
    210         dma = sSampleDmas + *dmaIndexRef;
    211         bufferPos = devAddr - dma->source;
    212         if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
    213             // We already have DMA for this memory range.
    214             if (dma->ttl == 0) {
    215                 // Move the DMA out of the reuse queue, by swapping it with the
    216                 // tail, and then incrementing the tail.
    217                 if (dma->reuseIndex != sSampleDmaReuseQueueTail1) {
    218                     sSampleDmaReuseQueue1[dma->reuseIndex] =
    219                         sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1];
    220                     sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex =
    221                         dma->reuseIndex;
    222                 }
    223                 sSampleDmaReuseQueueTail1++;
    224             }
    225             dma->ttl = 2;
    226             return dma->buffer + (devAddr - dma->source);
    227         }
    228     }
    229 
    230     if (!hasDma) {
    231         if (1) {}
    232         // Allocate a DMA from reuse queue 1. This queue will hopefully never
    233         // be empty, since TTL 2 is so small.
    234         dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++];
    235         dma = sSampleDmas + dmaIndex;
    236         hasDma = TRUE;
    237     }
    238 
    239     transfer = dma->bufSize;
    240     dmaDevAddr = devAddr & ~0xF;
    241     dma->ttl = 2;
    242     dma->source = dmaDevAddr;
    243     dma->sizeUnused = transfer;
    244     func_sh_802f3dd0(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ,
    245          dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue, medium, shindouDebugPrint62);
    246     *dmaIndexRef = dmaIndex;
    247     return (devAddr - dmaDevAddr) + dma->buffer;
    248 }
    249 
    250 void init_sample_dma_buffers(UNUSED s32 arg0) {
    251     s32 i;
    252 
    253     sDmaBufSize = 0x2D0;
    254     sSampleDmas = sound_alloc_uninitialized(&gNotesAndBuffersPool,
    255             gMaxSimultaneousNotes * 4 * sizeof(struct SharedDma) * gAudioBufferParameters.presetUnk4);
    256 
    257     for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) {
    258         if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) {
    259             break;
    260         }
    261         sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
    262         sSampleDmas[gSampleDmaNumListItems].source = 0;
    263         sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
    264         sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
    265         sSampleDmas[gSampleDmaNumListItems].ttl = 0;
    266         gSampleDmaNumListItems++;
    267     }
    268 
    269     for (i = 0; (u32) i < gSampleDmaNumListItems; i++) {
    270         sSampleDmaReuseQueue1[i] = (u8) i;
    271         sSampleDmas[i].reuseIndex = (u8) i;
    272     }
    273 
    274     for (i = gSampleDmaNumListItems; i < 0x100; i++) {
    275         sSampleDmaReuseQueue1[i] = 0;
    276     }
    277 
    278     sSampleDmaReuseQueueTail1 = 0;
    279     sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems;
    280     sSampleDmaListSize1 = gSampleDmaNumListItems;
    281 
    282     sDmaBufSize = 0x2D0;
    283     for (i = 0; i < gMaxSimultaneousNotes; i++) {
    284         if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) {
    285             break;
    286         }
    287         sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
    288         sSampleDmas[gSampleDmaNumListItems].source = 0;
    289         sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
    290         sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
    291         sSampleDmas[gSampleDmaNumListItems].ttl = 0;
    292         gSampleDmaNumListItems++;
    293     }
    294 
    295     for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) {
    296         sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i;
    297         sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1);
    298     }
    299 
    300     // This probably meant to touch the range size1..size2 as well... but it
    301     // doesn't matter, since these values are never read anyway.
    302     for (i = gSampleDmaNumListItems; i < 0x100; i++) {
    303         sSampleDmaReuseQueue2[i] = sSampleDmaListSize1;
    304     }
    305 
    306     sSampleDmaReuseQueueTail2 = 0;
    307     sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1;
    308 }
    309 
    310 void patch_seq_file(ALSeqFile *seqFile, u8 *data, u16 arg2) {
    311     s32 i;
    312 
    313     seqFile->unk2 = arg2;
    314     seqFile->data = data;
    315     for (i = 0; i < seqFile->seqCount; i++) {
    316         if (seqFile->seqArray[i].len != 0 && seqFile->seqArray[i].medium == 2) {
    317             seqFile->seqArray[i].offset += (uintptr_t)data;
    318         }
    319     }
    320 }
    321 
    322 struct AudioBank *load_banks_immediate(s32 seqId, s32 *outDefaultBank) {
    323     u8 bank;
    324     s32 offset;
    325     s32 i;
    326     void *ret;
    327 
    328     offset = ((u16 *)gAlBankSets)[canonicalize_index(0, seqId)];
    329     bank = 0xFF;
    330     for (i = gAlBankSets[offset++]; i > 0; i--) {
    331         bank = gAlBankSets[offset++];
    332         ret = func_sh_802f3688(bank);
    333     }
    334     *outDefaultBank = bank;
    335     return ret;
    336 }
    337 
    338 void preload_sequence(u32 seqId, s32 preloadMask) {
    339     UNUSED s32 pad;
    340     s32 temp;
    341 
    342     seqId = canonicalize_index(0, seqId);
    343     if (preloadMask & PRELOAD_BANKS) {
    344         load_banks_immediate(seqId, &temp);
    345     }
    346     if (preloadMask & PRELOAD_SEQUENCE) {
    347         func_sh_802f3564(seqId);
    348     }
    349 }
    350 
    351 s32 func_sh_802f2f38(struct AudioBankSample *sample, s32 bankId) {
    352     u8 *sp24;
    353 
    354     if (sample->isPatched == TRUE && sample->medium != 0) {
    355         sp24 = func_sh_802f1d90(sample->size, bankId, sample->sampleAddr, sample->medium);
    356         if (sp24 == NULL) {
    357             return -1;
    358         }
    359         if (sample->medium == 1) {
    360             func_sh_802f3d78((uintptr_t) sample->sampleAddr, sp24, sample->size, gAlTbl->unk2);
    361         } else {
    362             func_sh_802f3c38((uintptr_t) sample->sampleAddr, sp24, sample->size, sample->medium);
    363         }
    364         sample->medium = 0;
    365         sample->sampleAddr = sp24;
    366     }
    367 #ifdef AVOID_UB
    368     return 0;
    369 #endif
    370 }
    371 
    372 s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2) {
    373     struct Instrument *instr;
    374     struct Drum *drum;
    375 
    376     if (instId < 0x7F) {
    377         instr = get_instrument_inner(bankId, instId);
    378         if (instr == NULL) {
    379             return -1;
    380         }
    381         if (instr->normalRangeLo != 0) {
    382             func_sh_802f2f38(instr->lowNotesSound.sample, bankId);
    383         }
    384         func_sh_802f2f38(instr->normalNotesSound.sample, bankId);
    385         if (instr->normalRangeHi != 0x7F) {
    386             func_sh_802f2f38(instr->highNotesSound.sample, bankId);
    387         }
    388         //! @bug missing return
    389     } else if (instId == 0x7F) {
    390         drum = get_drum(bankId, arg2);
    391         if (drum == NULL) {
    392             return -1;
    393         }
    394         func_sh_802f2f38(drum->sound.sample, bankId);
    395         return 0;
    396     }
    397 #ifdef AVOID_UB
    398     return 0;
    399 #endif
    400 }
    401 
    402 void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3) {
    403     if (func_802f3f08(2, canonicalize_index(2, arg0), arg1, arg2, arg3) == 0) {
    404         osSendMesg(arg3, 0, 0);
    405     }
    406 }
    407 
    408 void func_sh_802f3158(s32 seqId, s32 numChunks, s32 arg2, OSMesgQueue *retQueue) {
    409     s32 val;
    410     s32 v;
    411 
    412     val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)];
    413     v = gAlBankSets[val++];
    414 
    415     while (v > 0) {
    416         func_802f3f08(1, canonicalize_index(1, gAlBankSets[val++]), numChunks, arg2, retQueue);
    417         v--;
    418     }
    419 }
    420 
    421 u8 *func_sh_802f3220(u32 seqId, u32 *a1) {
    422     s32 val;
    423 
    424     val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)];
    425     *a1 = gAlBankSets[val++];
    426     if (*a1 == 0) {
    427         return NULL;
    428     }
    429     return &gAlBankSets[val];
    430 }
    431 
    432 void func_sh_802f3288(s32 idx) {
    433     s32 bankId;
    434     s32 s2;
    435 
    436     idx = ((u16*)gAlBankSets)[canonicalize_index(0, idx)];
    437     s2 = gAlBankSets[idx++];
    438     while (s2 > 0) {
    439         s2--;
    440         bankId = canonicalize_index(1, gAlBankSets[idx++]);
    441 
    442         if (unk_pool1_lookup(1, bankId) == NULL) {
    443             func_sh_802f3368(bankId);
    444             if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
    445                 gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_NOT_LOADED;
    446             }
    447 
    448             continue;
    449         }
    450 
    451     }
    452 }
    453 
    454 BAD_RETURN(s32) func_sh_802f3368(s32 bankId) {
    455     struct SoundMultiPool *pool = &gBankLoadedPool;
    456     struct TemporaryPool *temporary = &pool->temporary;
    457     struct PersistentPool *persistent;
    458     u32 i;
    459 
    460     if (temporary->entries[0].id == bankId) {
    461         temporary->entries[0].id = -1;
    462     } else if (temporary->entries[1].id == bankId) {
    463         temporary->entries[1].id = -1;
    464     }
    465 
    466     persistent = &pool->persistent;
    467     for (i = 0; i < persistent->numEntries; i++) {
    468         if (persistent->entries[i].id == bankId) {
    469             persistent->entries[i].id = -1;
    470         }
    471 
    472     }
    473 
    474     discard_bank(bankId);
    475 }
    476 
    477 
    478 void load_sequence_internal(s32 player, s32 seqId, s32 loadAsync);
    479 void load_sequence(u32 player, u32 seqId, s32 loadAsync) {
    480     load_sequence_internal(player, seqId, loadAsync);
    481 }
    482 
    483 void load_sequence_internal(s32 player, s32 seqId, UNUSED s32 loadAsync) {
    484     struct SequencePlayer *seqPlayer;
    485     u8 *sequenceData;
    486     u32 s0;
    487     s32 count;
    488     u8 bank;
    489     s32 i;
    490 
    491     seqPlayer = &gSequencePlayers[player];
    492 
    493     seqId = canonicalize_index(0, seqId);
    494     sequence_player_disable(seqPlayer);
    495 
    496     s0 = ((u16 *) gAlBankSets)[seqId];
    497     count = gAlBankSets[s0++];
    498     bank = 0xff;
    499 
    500     while (count > 0) {
    501         bank = gAlBankSets[s0++];
    502         func_sh_802f3688(bank);
    503         count--;
    504     }
    505 
    506     sequenceData = func_sh_802f3564(seqId);
    507     init_sequence_player(player);
    508     seqPlayer->seqId = seqId;
    509     seqPlayer->defaultBank[0] = bank;
    510     seqPlayer->enabled = 1;
    511     seqPlayer->seqData = sequenceData;
    512     seqPlayer->scriptState.pc = sequenceData;
    513     seqPlayer->scriptState.depth = 0;
    514     seqPlayer->delay = 0;
    515     seqPlayer->finished = 0;
    516 
    517     for (i = 0; i < 0x10; i++) {
    518     }
    519 }
    520 
    521 void *func_sh_802f3564(s32 seqId) {
    522     s32 seqId2 = canonicalize_index(0, seqId);
    523     s32 temp;
    524     return func_sh_802f3764(0, seqId2, &temp);
    525 }
    526 
    527 extern u8 gUnkLoadStatus[0x40];
    528 
    529 void *func_sh_802f3598(s32 idx, s32 *medium) {
    530     void *ret;
    531     ALSeqFile *f;
    532     s32 temp;
    533     s32 sp28;
    534 
    535     f = get_audio_file_header(2);
    536     idx = canonicalize_index(2, idx);
    537     ret = get_bank_or_seq_wrapper(2, idx);
    538     if (ret != NULL) {
    539         if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    540             gUnkLoadStatus[idx] = SOUND_LOAD_STATUS_COMPLETE;
    541         }
    542 
    543         *medium = 0;
    544         return ret;
    545     }
    546 
    547     temp = f->seqArray[idx].magic;
    548     if (temp == 4) {
    549         *medium = f->seqArray[idx].medium;
    550         return f->seqArray[idx].offset;
    551     } else {
    552         ret = func_sh_802f3764(2, idx, &sp28);
    553         if (ret != 0) {
    554             *medium = 0;
    555             return ret;
    556         }
    557 
    558         *medium = f->seqArray[idx].medium;
    559     }
    560     return f->seqArray[idx].offset;
    561 
    562 }
    563 
    564 void *func_sh_802f3688(s32 bankId) {
    565     void *ret;
    566     s32 bankId1;
    567     s32 bankId2;
    568     s32 sp38;
    569     struct PatchStruct patchInfo;
    570 
    571     bankId = canonicalize_index(1, bankId);
    572     bankId1 = gCtlEntries[bankId].bankId1;
    573     bankId2 = gCtlEntries[bankId].bankId2;
    574 
    575     patchInfo.bankId1 = bankId1;
    576     patchInfo.bankId2 = bankId2;
    577 
    578     if (patchInfo.bankId1 != 0xFF) {
    579         patchInfo.baseAddr1 = func_sh_802f3598(patchInfo.bankId1, &patchInfo.medium1);
    580     } else {
    581         patchInfo.baseAddr1 = NULL;
    582     }
    583 
    584     if (bankId2 != 0xFF) {
    585         patchInfo.baseAddr2 = func_sh_802f3598(bankId2, &patchInfo.medium2);
    586     } else {
    587         patchInfo.baseAddr2 = NULL;
    588     }
    589 
    590     if ((ret = func_sh_802f3764(1, bankId, &sp38)) == NULL) {
    591         return NULL;
    592     }
    593 
    594     if (sp38 == 1) {
    595         func_sh_802f5310(bankId, ret, &patchInfo, 0);
    596     }
    597 
    598     return ret;
    599 }
    600 
    601 void *func_sh_802f3764(s32 poolIdx, s32 idx, s32 *arg2) {
    602     s32 size;
    603     ALSeqFile *f;
    604     void *vAddr;
    605     s32 medium;
    606     UNUSED u32 pad2;
    607     u8 *devAddr;
    608     s8 loadStatus;
    609     s32 sp18;
    610 
    611     vAddr = get_bank_or_seq_wrapper(poolIdx, idx);
    612     if (vAddr != NULL) {
    613         *arg2 = 0;
    614         loadStatus = SOUND_LOAD_STATUS_COMPLETE;
    615     } else {
    616         f = get_audio_file_header(poolIdx);
    617         size = f->seqArray[idx].len;
    618         size = ALIGN16(size);
    619         medium = f->seqArray[idx].medium;
    620         sp18 = f->seqArray[idx].magic;
    621         devAddr = f->seqArray[idx].offset;
    622 
    623 
    624         switch (sp18) {
    625             case 0:
    626                 vAddr = unk_pool1_alloc(poolIdx, idx, size);
    627                 if (vAddr == NULL) {
    628                     return vAddr;
    629                 }
    630                 break;
    631             case 1:
    632                 vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx);
    633                 if (vAddr == NULL) {
    634                     return vAddr;
    635                 }
    636                 break;
    637             case 2:
    638                 vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx);
    639                 if (vAddr == NULL) {
    640                     return vAddr;
    641                 }
    642                 break;
    643 
    644             case 3:
    645             case 4:
    646                 vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx);
    647                 if (vAddr == NULL) {
    648                     return vAddr;
    649                 }
    650                 break;
    651         }
    652 
    653         *arg2 = 1;
    654         if (medium == 1) {
    655             func_sh_802f3d78((uintptr_t) devAddr, vAddr, size, f->unk2);
    656         } else {
    657             func_sh_802f3c38((uintptr_t) devAddr, vAddr, size, medium);
    658         }
    659 
    660         switch (sp18) {
    661             case 0:
    662                 loadStatus = SOUND_LOAD_STATUS_5;
    663                 break;
    664 
    665             default:
    666                 loadStatus = SOUND_LOAD_STATUS_COMPLETE;
    667                 break;
    668         }
    669     }
    670 
    671     switch (poolIdx) {
    672         case 0:
    673             if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    674                 gSeqLoadStatus[idx] = loadStatus;
    675             }
    676             break;
    677 
    678         case 1:
    679             if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    680                 gBankLoadStatus[idx] = loadStatus;
    681             }
    682             break;
    683 
    684         case 2:
    685             if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    686                 gUnkLoadStatus[idx] = loadStatus;
    687             }
    688             break;
    689     }
    690 
    691     return vAddr;
    692 }
    693 
    694 s32 canonicalize_index(s32 poolIdx, s32 idx) {
    695     ALSeqFile *f;
    696 
    697     f = get_audio_file_header(poolIdx);
    698     if (f->seqArray[idx].len == 0) {
    699         idx = (s32) (uintptr_t) f->seqArray[idx].offset;
    700     }
    701     return idx;
    702 }
    703 
    704 void *get_bank_or_seq_wrapper(s32 poolIdx, s32 id) {
    705     void *ret;
    706 
    707     ret = unk_pool1_lookup(poolIdx, id);
    708     if (ret != NULL) {
    709         return ret;
    710     }
    711     ret = get_bank_or_seq(poolIdx, 2, id);
    712     if (ret != 0) {
    713         return ret;
    714     }
    715     return NULL;
    716 }
    717 
    718 ALSeqFile *get_audio_file_header(s32 poolIdx) {
    719     ALSeqFile *ret;
    720     switch (poolIdx) {
    721         default:
    722             ret = NULL;
    723             break;
    724         case 0:
    725             ret = gSeqFileHeader;
    726             break;
    727         case 1:
    728             ret = gAlCtlHeader;
    729             break;
    730         case 2:
    731             ret = gAlTbl;
    732             break;
    733     }
    734     return ret;
    735 }
    736 
    737 void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo) {
    738     struct Instrument *instrument;
    739     void **itInstrs;
    740     struct Instrument **end;
    741     s32 i;
    742     void *patched;
    743     struct Drum *drum;
    744     s32 numDrums;
    745     s32 numInstruments;
    746 
    747 #define BASE_OFFSET(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base)
    748 #define PATCH(x, base) (patched = BASE_OFFSET(x, base))
    749 #define PATCH_MEM(x) x = PATCH(x, mem)
    750 
    751     numDrums = gCtlEntries[bankId].numDrums;
    752     numInstruments = gCtlEntries[bankId].numInstruments;
    753     itInstrs = (void **) mem->drums;
    754     if (mem->drums) {
    755     }
    756     if (itInstrs != NULL && numDrums != 0) {
    757         if (1) {
    758             mem->drums = PATCH(itInstrs, mem);
    759         }
    760         for (i = 0; i < numDrums; i++) {
    761             patched = mem->drums[i];
    762             if (patched != NULL) {
    763                 drum = PATCH(patched, mem);
    764                 mem->drums[i] = drum;
    765                 if (drum->loaded == 0) {
    766                     patch_sound(&drum->sound, mem, patchInfo);
    767                     patched = drum->envelope;
    768                     drum->envelope = BASE_OFFSET(patched, mem);
    769                     drum->loaded = 1;
    770                 }
    771 
    772             }
    773         }
    774     }
    775 
    776     if (numInstruments > 0) {
    777         itInstrs = (void **) mem->instruments;
    778         end = numInstruments + (struct Instrument **) itInstrs;
    779 
    780         do {
    781             if (*itInstrs != NULL) {
    782                 *itInstrs = BASE_OFFSET(*itInstrs, mem);
    783                 instrument = *itInstrs;
    784 
    785                 if (instrument->loaded == 0) {
    786                     if (instrument->normalRangeLo != 0) {
    787                         patch_sound(&instrument->lowNotesSound, mem, patchInfo);
    788                     }
    789                     patch_sound(&instrument->normalNotesSound, mem, patchInfo);
    790                     if (instrument->normalRangeHi != 0x7F) {
    791                         patch_sound(&instrument->highNotesSound, mem, patchInfo);
    792                     }
    793                     patched = instrument->envelope;
    794 
    795                     instrument->envelope = BASE_OFFSET(patched, mem);
    796                     instrument->loaded = 1;
    797                 }
    798             }
    799             itInstrs = (void **) ((struct Instrument **) itInstrs) + 1;
    800         } while ((struct Instrument **) itInstrs != ((void) 0, end)); //! This is definitely fake
    801     }
    802     gCtlEntries[bankId].drums = mem->drums;
    803     gCtlEntries[bankId].instruments = mem->instruments;
    804 #undef PATCH_MEM
    805 #undef PATCH
    806 #undef BASE_OFFSET
    807 }
    808 
    809 extern char shindouDebugPrint81[]; // "FastCopy"
    810 extern char shindouDebugPrint82[]; // "FastCopy"
    811 void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium) {
    812     nbytes = ALIGN16(nbytes);
    813     osInvalDCache(vAddr, nbytes);
    814 
    815 again:
    816     if (gAudioLoadLockSH != 0) {
    817         goto again;
    818     }
    819 
    820     if (nbytes >= 0x400U) {
    821         func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, 0x400, &gAudioDmaMesgQueue, medium, shindouDebugPrint81);
    822         osRecvMesg(&gAudioDmaMesgQueue, NULL, 1);
    823         nbytes = nbytes - 0x400;
    824         devAddr = devAddr + 0x400;
    825         vAddr = (u8*)vAddr + 0x400;
    826         goto again;
    827     }
    828 
    829     if (nbytes != 0) {
    830         func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, nbytes, &gAudioDmaMesgQueue, medium, shindouDebugPrint82);
    831         osRecvMesg(&gAudioDmaMesgQueue, NULL, 1);
    832     }
    833 }
    834 
    835 void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
    836     uintptr_t sp1C;
    837 
    838     sp1C = devAddr;
    839     osInvalDCache(vAddr, nbytes);
    840     func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
    841 }
    842 
    843 s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr, void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason) {
    844     OSPiHandle *handle;
    845     if (gAudioLoadLockSH >= 0x11U) {
    846         return -1;
    847     }
    848     switch (medium) {
    849         case 2:
    850             handle = osCartRomInit();
    851             break;
    852         case 3:
    853             handle = osDriveRomInit();
    854             break;
    855         default:
    856             return 0;
    857     }
    858     if ((size & 0xf) != 0) {
    859         size = ALIGN16(size);
    860     }
    861     m->hdr.pri = pri;
    862     m->hdr.retQueue = retQueue;
    863     m->dramAddr = dramAddr;
    864     m->devAddr = devAddr;
    865     m->size = size;
    866     handle->transferInfo.cmdType = 2;
    867     osEPiStartDma(handle, m, direction);
    868     return 0;
    869 }
    870 
    871 s32 func_sh_802f3ec4(UNUSED s32 arg0, UNUSED uintptr_t *arg1) {
    872     return 0;
    873 }
    874 
    875 void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes) {
    876 }
    877 
    878 void *func_sh_802f3ee8(s32 poolIdx, s32 idx) {
    879     s32 temp;
    880     return func_sh_802f3764(poolIdx, idx, &temp);
    881 }
    882 
    883 void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue) {
    884     s32 size;
    885     ALSeqFile *f;
    886     void *vAddr;
    887     s32 medium;
    888     s32 sp18;
    889     uintptr_t devAddr;
    890     s32 loadStatus;
    891 
    892     switch (poolIdx) {
    893         case 0:
    894             if (gSeqLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
    895                 return 0;
    896             }
    897             break;
    898         case 1:
    899             if (gBankLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
    900                 return 0;
    901             }
    902             break;
    903         case 2:
    904             if (gUnkLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
    905                 return 0;
    906             }
    907             break;
    908 
    909     }
    910     vAddr = get_bank_or_seq_wrapper(poolIdx, idx);
    911     if (vAddr != NULL) {
    912         loadStatus = 2;
    913         osSendMesg(retQueue, (OSMesg) (arg3 << 0x18), 0);
    914     } else {
    915         f = get_audio_file_header(poolIdx);
    916         size = f->seqArray[idx].len;
    917         size = ALIGN16(size);
    918         medium = f->seqArray[idx].medium;
    919         sp18 = f->seqArray[idx].magic;
    920         devAddr = (uintptr_t) f->seqArray[idx].offset;
    921         loadStatus = 2;
    922 
    923         switch (sp18) {
    924             case 0:
    925                 vAddr = unk_pool1_alloc(poolIdx, idx, size);
    926                 if (vAddr == NULL) {
    927                     return vAddr;
    928                 }
    929                 loadStatus = SOUND_LOAD_STATUS_5;
    930                 break;
    931             case 1:
    932                 vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx);
    933                 if (vAddr == NULL) {
    934                     return vAddr;
    935                 }
    936                 break;
    937             case 2:
    938                 vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx);
    939                 if (vAddr == NULL) {
    940                     return vAddr;
    941                 }
    942                 break;
    943 
    944             case 4:
    945             case 3:
    946                 vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx);
    947                 if (vAddr == NULL) {
    948                     return vAddr;
    949                 }
    950                 break;
    951         }
    952 
    953         func_sh_802f4cb4(devAddr, vAddr, size, medium, numChunks, retQueue, (arg3 << 0x18) | (poolIdx << 0x10) | (idx << 8) | loadStatus);
    954         loadStatus = SOUND_LOAD_STATUS_IN_PROGRESS;
    955     }
    956 
    957     switch (poolIdx) {
    958         case 0:
    959             if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    960                 gSeqLoadStatus[idx] = loadStatus;
    961             }
    962             break;
    963 
    964         case 1:
    965             if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    966                 gBankLoadStatus[idx] = loadStatus;
    967             }
    968             break;
    969 
    970         case 2:
    971             if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
    972                 gUnkLoadStatus[idx] = loadStatus;
    973             }
    974             break;
    975     }
    976 
    977     return vAddr;
    978 }
    979 
    980 void func_sh_802f41e4(s32 audioResetStatus) {
    981     func_sh_802f4a4c(audioResetStatus);
    982     func_sh_802f573c(audioResetStatus);
    983     func_sh_802f4dcc(audioResetStatus);
    984 }
    985 
    986 u8 gShindouSoundBanksHeader[] = {
    987 #include "sound/ctl_header.inc.c"
    988 };
    989 
    990 u8 gBankSetsData[] = {
    991 #include "sound/bank_sets.inc.c"
    992 };
    993 
    994 u8 gShindouSampleBanksHeader[] = {
    995 #include "sound/tbl_header.inc.c"
    996 };
    997 
    998 u8 gShindouSequencesHeader[] = {
    999 #include "sound/sequences_header.inc.c"
   1000 };
   1001 
   1002 // (void) must be omitted from parameters
   1003 void audio_init() {
   1004     UNUSED s8 pad[0x34];
   1005     s32 i, j, k;
   1006     s32 lim;
   1007     u64 *ptr64;
   1008     void *data;
   1009     UNUSED u8 pad2[4];
   1010     s32 seqCount;
   1011 
   1012     gAudioLoadLockSH = 0;
   1013 
   1014     for (i = 0; i < gAudioHeapSize / 8; i++) {
   1015         ((u64 *) gAudioHeap)[i] = 0;
   1016     }
   1017 
   1018 #ifdef TARGET_N64
   1019     // It seems boot.s doesn't clear the .bss area for audio, so do it here.
   1020     lim = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
   1021     ptr64 = &gAudioGlobalsStartMarker;
   1022     for (k = lim; k >= 0; k--) {
   1023         *ptr64++ = 0;
   1024     }
   1025 #endif
   1026 
   1027     D_EU_802298D0 = 16.713f;
   1028     gRefreshRate = 60;
   1029     port_eu_init();
   1030 
   1031 #ifdef TARGET_N64
   1032     eu_stubbed_printf_3(
   1033         "Clear Workarea %x -%x size %x \n",
   1034         (uintptr_t) &gAudioGlobalsStartMarker,
   1035         (uintptr_t) &gAudioGlobalsEndMarker,
   1036         (uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
   1037     );
   1038 #endif
   1039 
   1040     eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
   1041 
   1042     for (i = 0; i < NUMAIBUFFERS; i++) {
   1043         gAiBufferLengths[i] = 0xa0;
   1044     }
   1045 
   1046     gAudioFrameCount = 0;
   1047     gAudioTaskIndex = 0;
   1048     gCurrAiBufferIndex = 0;
   1049     gSoundMode = 0;
   1050     gAudioTask = NULL;
   1051     gAudioTasks[0].task.t.data_size = 0;
   1052     gAudioTasks[1].task.t.data_size = 0;
   1053     osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1);
   1054     osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs,
   1055                       ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs));
   1056     osCreateMesgQueue(&gUnkQueue1, gUnkMesgBufs1, 0x10);
   1057     osCreateMesgQueue(&gUnkQueue2, gUnkMesgBufs2, 0x10);
   1058     gCurrAudioFrameDmaCount = 0;
   1059     gSampleDmaNumListItems = 0;
   1060 
   1061     sound_init_main_pools(gAudioInitPoolSize);
   1062 
   1063     for (i = 0; i < NUMAIBUFFERS; i++) {
   1064         gAiBuffers[i] = sound_alloc_uninitialized(&gAudioInitPool, AIBUFFER_LEN);
   1065 
   1066         for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) {
   1067             gAiBuffers[i][j] = 0;
   1068         }
   1069     }
   1070 
   1071     gAudioResetPresetIdToLoad = 0;
   1072     gAudioResetStatus = 1;
   1073     audio_shut_down_and_reset_step();
   1074 
   1075     // Not sure about these prints
   1076     eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
   1077     eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0);
   1078     eu_stubbed_printf_0("Main Heap Initialize.\n");
   1079 
   1080     // Load headers for sounds and sequences
   1081     gSeqFileHeader = (ALSeqFile *) gShindouSequencesHeader;
   1082     gAlCtlHeader = (ALSeqFile *) gShindouSoundBanksHeader;
   1083     gAlTbl = (ALSeqFile *) gShindouSampleBanksHeader;
   1084     gAlBankSets = gBankSetsData;
   1085     gSequenceCount = (s16) gSeqFileHeader->seqCount;
   1086     patch_seq_file(gSeqFileHeader, gMusicData, D_SH_80315EF4);
   1087     patch_seq_file(gAlCtlHeader, gSoundDataADSR, D_SH_80315EF8);
   1088     patch_seq_file(gAlTbl, gSoundDataRaw, D_SH_80315EFC);
   1089     seqCount = gAlCtlHeader->seqCount;
   1090     gCtlEntries = sound_alloc_uninitialized(&gAudioInitPool, seqCount * sizeof(struct CtlEntry));
   1091     for (i = 0; i < seqCount; i++) {
   1092         gCtlEntries[i].bankId1 = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf >> 8) & 0xff);
   1093         gCtlEntries[i].bankId2 = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf & 0xff);
   1094         gCtlEntries[i].numInstruments = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums >> 8) & 0xff);
   1095         gCtlEntries[i].numDrums = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums & 0xff);
   1096     }
   1097     data = sound_alloc_uninitialized(&gAudioInitPool, D_SH_80315EF0);
   1098     if (data == NULL) {
   1099         D_SH_80315EF0 = 0;
   1100     }
   1101     sound_alloc_pool_init(&gUnkPool1.pool, data, D_SH_80315EF0);
   1102     init_sequence_players();
   1103 }
   1104 
   1105 s32 func_sh_802f47c8(s32 bankId, u8 idx, s8 *io) {
   1106     struct AudioBankSample *sample = func_sh_802f4978(bankId, idx);
   1107     struct PendingDmaSample *temp;
   1108     if (sample == NULL) {
   1109         *io = 0;
   1110         return -1;
   1111     }
   1112     if (sample->medium == 0) {
   1113         *io = 2;
   1114         return 0;
   1115     }
   1116     temp = &D_SH_80343D00.arr[D_SH_80343D00.someIndex];
   1117     if (temp->state == 3) {
   1118         temp->state = 0;
   1119     }
   1120     temp->sample = *sample;
   1121     temp->io = io;
   1122     temp->vAddr = func_sh_802f1d40(sample->size, bankId, sample->sampleAddr, sample->medium);
   1123     if (temp->vAddr == NULL) {
   1124         if (sample->medium == 1 || sample->codec == CODEC_SKIP) {
   1125             *io = 0;
   1126             return -1;
   1127         } else {
   1128             *io = 3;
   1129             return -1;
   1130         }
   1131     }
   1132     temp->state = 1;
   1133     temp->remaining = ALIGN16(sample->size);
   1134     temp->resultSampleAddr = (u8 *) temp->vAddr;
   1135     temp->devAddr = (uintptr_t) sample->sampleAddr;
   1136     temp->medium = sample->medium;
   1137     temp->bankId = bankId;
   1138     temp->idx = idx;
   1139     D_SH_80343D00.someIndex ^= 1;
   1140     return 0;
   1141 }
   1142 
   1143 struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx) {
   1144     struct Drum *drum;
   1145     struct Instrument *inst;
   1146     struct AudioBankSample *ret;
   1147 
   1148     if (idx < 128) {
   1149         inst = get_instrument_inner(bankId, idx);
   1150         if (inst == 0) {
   1151             return NULL;
   1152         }
   1153         ret = inst->normalNotesSound.sample;
   1154     } else {
   1155         drum = get_drum(bankId, idx - 128);
   1156         if (drum == 0) {
   1157             return NULL;
   1158         }
   1159         ret = drum->sound.sample;
   1160     }
   1161     return ret;
   1162 }
   1163 
   1164 void stub_sh_802f49dc(void) {
   1165 }
   1166 
   1167 void func_sh_802f49e4(struct PendingDmaSample *arg0) {
   1168     struct AudioBankSample *sample = func_sh_802f4978(arg0->bankId, arg0->idx);
   1169     if (sample != NULL) {
   1170         arg0->sample = *sample;
   1171         sample->sampleAddr = arg0->resultSampleAddr;
   1172         sample->medium = 0;
   1173     }
   1174 }
   1175 
   1176 void func_sh_802f4a4c(s32 audioResetStatus) {
   1177     ALSeqFile *alTbl;
   1178     struct PendingDmaSample *entry;
   1179 
   1180     s32 i;
   1181 
   1182     alTbl = gAlTbl;
   1183 
   1184     for (i = 0; i < 2; i++) {
   1185         entry = &D_SH_80343D00.arr[i];
   1186         switch (entry->state) {
   1187             case 2:
   1188                 osRecvMesg(&entry->queue, NULL, 1);
   1189                 if (audioResetStatus != 0) {
   1190                     entry->state = 3;
   1191                     break;
   1192                 }
   1193                 // fallthrough
   1194             case 1:
   1195                 entry->state = 2;
   1196                 if (entry->remaining == 0) {
   1197                     func_sh_802f49e4(entry);
   1198                     entry->state = 3;
   1199                     *entry->io = 1;
   1200                 } else if (entry->remaining < 0x1000) {
   1201                     if (entry->medium == 1) {
   1202                         func_sh_802f4c5c(entry->devAddr, entry->vAddr, entry->remaining, alTbl->unk2);
   1203                     } else {
   1204                         func_sh_802f4bd8(entry, entry->remaining);
   1205                     }
   1206                     entry->remaining = 0;
   1207                 } else {
   1208                     if (entry->medium == 1) {
   1209                         func_sh_802f4c5c(entry->devAddr, entry->vAddr, 0x1000, alTbl->unk2);
   1210                     } else {
   1211                         func_sh_802f4bd8(entry, 0x1000);
   1212                     }
   1213                     entry->remaining = (s32) (entry->remaining - 0x1000);
   1214                     entry->vAddr = (u8 *) entry->vAddr + 0x1000;
   1215                     entry->devAddr = entry->devAddr + 0x1000;
   1216                 }
   1217                 break;
   1218         }
   1219     }
   1220 }
   1221 
   1222 extern char shindouDebugPrint102[]; // "SLOWCOPY"
   1223 void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len) { // len must be signed
   1224     osInvalDCache(arg0->vAddr, len);
   1225     osCreateMesgQueue(&arg0->queue, arg0->mesgs, 1);
   1226     func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->queue, arg0->medium, shindouDebugPrint102);
   1227 }
   1228 
   1229 void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
   1230     uintptr_t sp1C;
   1231 
   1232     sp1C = devAddr;
   1233     osInvalDCache(vAddr, nbytes);
   1234     func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
   1235 }
   1236 
   1237 struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo) {
   1238     struct PendingDmaAudioBank *item;
   1239     s32 i;
   1240 
   1241     for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) {
   1242         if (sPendingDmaAudioBanks[i].inProgress == 0) {
   1243             item = &sPendingDmaAudioBanks[i];
   1244             break;
   1245         }
   1246     }
   1247     if (i == ARRAY_COUNT(sPendingDmaAudioBanks)) {
   1248         return NULL;
   1249     }
   1250 
   1251     item->inProgress = 1;
   1252     item->devAddr = devAddr;
   1253     item->audioBank = vAddr;
   1254     item->vAddr = vAddr;
   1255     item->remaining = size;
   1256     if (numChunks == 0) {
   1257         item->transferSize = 0x1000;
   1258     } else {
   1259         item->transferSize = ((size / numChunks) + 0xFF) & ~0xFF;
   1260         if (item->transferSize < 0x100) {
   1261             item->transferSize = 0x100;
   1262         }
   1263     }
   1264     item->retQueue = retQueue;
   1265     item->timer = 3;
   1266     item->medium = medium;
   1267     item->encodedInfo = encodedInfo;
   1268     osCreateMesgQueue(&item->dmaRetQueue, item->mesgs, 1);
   1269     return item;
   1270 }
   1271 
   1272 void func_sh_802f4dcc(s32 audioResetStatus) {
   1273     s32 i;
   1274 
   1275     if (gAudioLoadLockSH != 1) {
   1276         for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) {
   1277             if (sPendingDmaAudioBanks[i].inProgress == 1) {
   1278                 func_sh_802f4e50(&sPendingDmaAudioBanks[i], audioResetStatus);
   1279             }
   1280         }
   1281     }
   1282 }
   1283 
   1284 void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus) {
   1285     ALSeqFile *alSeqFile;
   1286     u32 *encodedInfo;
   1287     OSMesg mesg;
   1288     u32 temp;
   1289     u32 bankId;
   1290     s32 bankId1;
   1291     s32 bankId2;
   1292     struct PatchStruct patchStruct;
   1293     alSeqFile = gAlTbl;
   1294     if (audioBank->timer >= 2) {
   1295         audioBank->timer--;
   1296         return;
   1297     }
   1298     if (audioBank->timer == 1) {
   1299         audioBank->timer = 0;
   1300     } else {
   1301         if (audioResetStatus != 0) {
   1302             osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_BLOCK);
   1303             audioBank->inProgress = 0;
   1304             return;
   1305         }
   1306         if (osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_NOBLOCK) == -1) {
   1307             return;
   1308         }
   1309     }
   1310 
   1311     encodedInfo = &audioBank->encodedInfo;
   1312     if (audioBank->remaining == 0) {
   1313         mesg = (OSMesg) audioBank->encodedInfo;
   1314 #pragma GCC diagnostic push
   1315 #if defined(__clang__)
   1316 #pragma GCC diagnostic ignored "-Wself-assign"
   1317 #endif
   1318         mesg = mesg;    //! needs an extra read from mesg here to match...
   1319 #pragma GCC diagnostic pop
   1320         temp = *encodedInfo;
   1321         bankId = (temp >> 8) & 0xFF;
   1322         switch ((u8) (temp >> 0x10)) {
   1323             case 0:
   1324                 if (gSeqLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
   1325                     gSeqLoadStatus[bankId] = (u8) (temp & 0xFF);
   1326                 }
   1327                 break;
   1328             case 2:
   1329                 if (gUnkLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
   1330                     gUnkLoadStatus[bankId] = (u8) (temp & 0xFF);
   1331                 }
   1332                 break;
   1333             case 1:
   1334                 if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
   1335                     gBankLoadStatus[bankId] = (u8) (temp & 0xFF);
   1336                 }
   1337                 bankId1 = gCtlEntries[bankId].bankId1;
   1338                 bankId2 = gCtlEntries[bankId].bankId2;
   1339                 patchStruct.bankId1 = bankId1;
   1340                 patchStruct.bankId2 = bankId2;
   1341                 if (bankId1 != 0xFF) {
   1342                     patchStruct.baseAddr1 = func_sh_802f3598(bankId1, &patchStruct.medium1);
   1343                 } else {
   1344                     patchStruct.baseAddr1 = NULL;
   1345                 }
   1346                 if (bankId2 != 0xFF) {
   1347                     patchStruct.baseAddr2 = func_sh_802f3598(bankId2, &patchStruct.medium2);
   1348                 } else {
   1349                     patchStruct.baseAddr2 = NULL;
   1350                 }
   1351 
   1352                 func_sh_802f5310(bankId, audioBank->audioBank, &patchStruct, 1);
   1353                 break;
   1354         }
   1355         mesg = (OSMesg) audioBank->encodedInfo;
   1356         audioBank->inProgress = 0;
   1357         osSendMesg(audioBank->retQueue, mesg, OS_MESG_NOBLOCK);
   1358     } else if (audioBank->remaining < audioBank->transferSize) {
   1359         if (audioBank->medium == 1) {
   1360             func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->remaining, alSeqFile->unk2);
   1361         } else {
   1362             func_sh_802f50ec(audioBank, audioBank->remaining);
   1363         }
   1364 
   1365         audioBank->remaining = 0;
   1366     } else {
   1367         if (audioBank->medium == 1) {
   1368             func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->transferSize, alSeqFile->unk2);
   1369         } else {
   1370             func_sh_802f50ec(audioBank, audioBank->transferSize);
   1371         }
   1372 
   1373         audioBank->remaining -= audioBank->transferSize;
   1374         audioBank->devAddr   += audioBank->transferSize;
   1375         audioBank->vAddr = ((u8 *) audioBank->vAddr) + audioBank->transferSize;
   1376     }
   1377 }
   1378 
   1379 extern char shindouDebugPrint110[]; // "BGCOPY"
   1380 void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len) {
   1381     len += 0xf;
   1382     len &= ~0xf;
   1383     osInvalDCache(arg0->vAddr, len);
   1384     osCreateMesgQueue(&arg0->dmaRetQueue, arg0->mesgs, 1);
   1385     func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->dmaRetQueue, arg0->medium, shindouDebugPrint110);
   1386 }
   1387 
   1388 
   1389 void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
   1390     uintptr_t sp1C;
   1391 
   1392     sp1C = devAddr;
   1393     osInvalDCache(vAddr, nbytes);
   1394     func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
   1395 }
   1396 
   1397 void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo) {
   1398     struct AudioBankSample *sample;
   1399     void *patched;
   1400 
   1401 #define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base))
   1402 
   1403     if ((uintptr_t) sound->sample <= 0x80000000) {
   1404         sample = sound->sample = PATCH(sound->sample, memBase);
   1405         if (sample->size != 0 && sample->isPatched != TRUE) {
   1406             sample->loop = PATCH(sample->loop, memBase);
   1407             sample->book = PATCH(sample->book, memBase);
   1408             switch (sample->medium) {
   1409                 case 0:
   1410                     sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr1);
   1411                     sample->medium = patchInfo->medium1;
   1412                     break;
   1413                 case 1:
   1414                     sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr2);
   1415                     sample->medium = patchInfo->medium2;
   1416                     break;
   1417 
   1418                 case 2:
   1419                 case 3:
   1420                     break;
   1421             }
   1422             sample->isPatched = TRUE;
   1423             if (sample->bit1 && sample->medium != 0) {
   1424                 D_SH_8034EA88[D_SH_8034F688++] = sample;
   1425             }
   1426         }
   1427     }
   1428 #undef PATCH
   1429 }
   1430 
   1431 BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3) {
   1432     UNUSED u32 pad[2];
   1433     u8 *addr;
   1434     UNUSED u32 pad1[3];
   1435     s32 sp4C;
   1436     struct AudioBankSample *temp_s0;
   1437     s32 i;
   1438     uintptr_t count;
   1439     s32 temp;
   1440 
   1441     sp4C = 0;
   1442     if (D_SH_8034F68C != 0) {
   1443         sp4C = 1;
   1444     } else {
   1445         D_SH_80343CF0 = 0;
   1446     }
   1447     D_SH_8034F688 = 0;
   1448     patch_audio_bank(bankId, mem, patchInfo);
   1449 
   1450     count = 0;
   1451     for (i = 0; i < D_SH_8034F688; i++) {
   1452         count += ALIGN16(D_SH_8034EA88[i]->size);
   1453     }
   1454 
   1455     for (i = 0; i < D_SH_8034F688; i++) {
   1456         if (D_SH_8034F68C != 0x78) {
   1457             temp_s0 = D_SH_8034EA88[i];
   1458             switch (arg3) {
   1459                 case 0:
   1460                     temp = temp_s0->medium = patchInfo->medium1;
   1461                     if (temp != 0) {
   1462                         if (temp_s0->size) {
   1463                         }
   1464                         addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium);
   1465                     } else {
   1466                         temp = temp_s0->medium = patchInfo->medium2;
   1467                         if (temp != 0) {
   1468                             addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium);
   1469                         }
   1470                     }
   1471                     break;
   1472 
   1473                 case 1:
   1474                     temp = temp_s0->medium = patchInfo->medium1;
   1475                     if (temp != 0) {
   1476                         addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium);
   1477                     } else {
   1478                         temp = temp_s0->medium = patchInfo->medium2;
   1479                         if (temp != 0) {
   1480                             addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium);
   1481                         }
   1482                     }
   1483                     break;
   1484             }
   1485             switch ((uintptr_t) addr) {
   1486                 case 0:
   1487                     break;
   1488                 default:
   1489                 switch (arg3) {
   1490                     case 0:
   1491                         if (temp_s0->medium == 1) {
   1492                             func_sh_802f3d78((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, gAlTbl->unk2);
   1493                             temp_s0->sampleAddr = addr;
   1494                             temp_s0->medium = 0;
   1495                         } else {
   1496                             func_sh_802f3c38((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, temp_s0->medium);
   1497                             temp_s0->sampleAddr = addr;
   1498                             temp_s0->medium = 0;
   1499                         }
   1500                         break;
   1501 
   1502                     case 1:
   1503                         D_SH_8034EC88[D_SH_8034F68C].sample = temp_s0;
   1504                         D_SH_8034EC88[D_SH_8034F68C].ramAddr = addr;
   1505                         D_SH_8034EC88[D_SH_8034F68C].encodedInfo = (D_SH_8034F68C << 24) | 0xffffff;
   1506                         D_SH_8034EC88[D_SH_8034F68C].isFree = FALSE;
   1507                         D_SH_8034EC88[D_SH_8034F68C].endAndMediumIdentification = temp_s0->sampleAddr + temp_s0->size + temp_s0->medium;
   1508                         D_SH_8034F68C++;
   1509                         break;
   1510                 }
   1511             }
   1512             continue;
   1513         }
   1514         break;
   1515     }
   1516 
   1517     D_SH_8034F688 = 0;
   1518     if (D_SH_8034F68C != 0 && sp4C == 0) {
   1519         temp_s0 = D_SH_8034EC88[D_SH_8034F68C - 1].sample;
   1520         temp = (temp_s0->size >> 12);
   1521         temp += 1;
   1522         count = (uintptr_t) temp_s0->sampleAddr;
   1523         func_sh_802f4cb4(
   1524             count,
   1525             D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr,
   1526             temp_s0->size,
   1527             temp_s0->medium,
   1528             temp,
   1529             &gUnkQueue2,
   1530             D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo);
   1531     }
   1532 }
   1533 
   1534 s32 func_sh_802f573c(s32 audioResetStatus) {
   1535     struct AudioBankSample *sample;
   1536     u32 idx;
   1537     u8 *sampleAddr;
   1538     u32 size;
   1539     s32 unk;
   1540     u8 *added;
   1541 
   1542     if (D_SH_8034F68C > 0) {
   1543         if (audioResetStatus != 0) {
   1544             if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK)) {
   1545             }
   1546             D_SH_8034F68C = 0;
   1547             return 0;
   1548         }
   1549         if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK) == -1) {
   1550             return 0;
   1551         }
   1552         idx >>= 0x18;
   1553         if (D_SH_8034EC88[idx].isFree == FALSE) {
   1554             sample = D_SH_8034EC88[idx].sample;
   1555             added = (sample->sampleAddr + sample->size + sample->medium);
   1556             if (added == D_SH_8034EC88[idx].endAndMediumIdentification) {
   1557                 sample->sampleAddr = D_SH_8034EC88[idx].ramAddr;
   1558                 sample->medium = 0;
   1559             }
   1560             D_SH_8034EC88[idx].isFree = TRUE;
   1561         }
   1562 
   1563 next:
   1564         if (D_SH_8034F68C > 0) {
   1565             if (D_SH_8034EC88[D_SH_8034F68C - 1].isFree == TRUE) {
   1566                 D_SH_8034F68C--;
   1567                 goto next;
   1568             }
   1569             sample = D_SH_8034EC88[D_SH_8034F68C - 1].sample;
   1570             sampleAddr = sample->sampleAddr;
   1571             size = sample->size;
   1572             unk = size >> 0xC;
   1573             unk += 1;
   1574             added = ((sampleAddr + size) + sample->medium);
   1575             if (added != D_SH_8034EC88[D_SH_8034F68C - 1].endAndMediumIdentification) {
   1576                 D_SH_8034EC88[D_SH_8034F68C - 1].isFree = TRUE;
   1577                 D_SH_8034F68C--;
   1578                 goto next;
   1579             }
   1580             size = sample->size;
   1581             func_sh_802f4cb4((uintptr_t) sampleAddr, D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, size, sample->medium,
   1582                              unk, &gUnkQueue2, D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo);
   1583         }
   1584     }
   1585     return 1;
   1586 }
   1587 
   1588 s32 func_sh_802f5900(struct AudioBankSample *sample, s32 numLoaded, struct AudioBankSample *arg2[]) {
   1589     s32 i;
   1590 
   1591     for (i = 0; i < numLoaded; i++) {
   1592         if (sample->sampleAddr == arg2[i]->sampleAddr) {
   1593             break;
   1594         }
   1595     }
   1596     if (i == numLoaded) {
   1597         arg2[numLoaded++] = sample;
   1598     }
   1599     return numLoaded;
   1600 }
   1601 
   1602 s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) {
   1603     s32 i;
   1604     struct Drum *drum;
   1605     struct Instrument *inst;
   1606     s32 numLoaded;
   1607     s32 numDrums;
   1608     s32 numInstruments;
   1609 
   1610     numLoaded = 0;
   1611     numDrums = gCtlEntries[bankId].numDrums;
   1612     numInstruments = gCtlEntries[bankId].numInstruments;
   1613 
   1614     for (i = 0; i < numDrums; i++) {
   1615         drum = get_drum(bankId, i);
   1616         if (drum == NULL) {
   1617             continue;
   1618         }
   1619         numLoaded = func_sh_802f5900(drum->sound.sample, numLoaded, list);
   1620     }
   1621     for (i = 0; i < numInstruments; i++) {
   1622         inst = get_instrument_inner(bankId, i);
   1623         if (inst == NULL) {
   1624             continue;
   1625 
   1626         }
   1627         if (inst->normalRangeLo != 0) {
   1628             numLoaded = func_sh_802f5900(inst->lowNotesSound.sample, numLoaded, list);
   1629         }
   1630         if (inst->normalRangeHi != 127) {
   1631             numLoaded = func_sh_802f5900(inst->highNotesSound.sample, numLoaded, list);
   1632         }
   1633         numLoaded = func_sh_802f5900(inst->normalNotesSound.sample, numLoaded, list);
   1634     }
   1635     return numLoaded;
   1636 }
   1637 #endif