#include "global.h" UNK_TYPE4 D_80096C30 = 2; #ifdef NON_MATCHING // This needs lots of work. Mostly regalloc and getting the address of D_80096C30 placed in s5 at the beginning of the // function void Load2_Relocate(u32 allocatedVRamAddr, OverlayRelocationSection* overlayInfo, u32 vRamStart) { s32 sectionLocations[4]; u32* regReferences[32]; u32 regValues[32]; u32 i; u32 relocatedAddress; s32 signedOffset; u32* lastInst; u32* inst; u32 relocation; u32 relocationIndex; sectionLocations[0] = 0; sectionLocations[1] = allocatedVRamAddr; sectionLocations[2] = overlayInfo->textSize + allocatedVRamAddr; sectionLocations[3] = sectionLocations[2] + overlayInfo->dataSize; for (i = 0, relocationIndex = 0; i < overlayInfo->nRelocations; relocationIndex++) { relocation = overlayInfo->relocations[relocationIndex]; i++; inst = (u32*)(sectionLocations[relocation >> 0x1e] + (relocation & 0xffffff)); switch (relocation & 0x3f000000) { case 0x2000000: if ((*inst & 0xf000000) == 0) { *inst = (*inst - vRamStart) + allocatedVRamAddr; } else { if (D_80096C30 > 2) ; } break; case 0x4000000: *inst = (*inst & 0xfc000000) | (((((*inst & 0x3ffffff) << 2 | 0x80000000) - vRamStart) + allocatedVRamAddr & 0xfffffff) >> 2); break; case 0x5000000: regReferences[*inst >> 0x10 & 0x1f] = inst; regValues[*inst >> 0x10 & 0x1f] = *inst; break; case 0x6000000: lastInst = regReferences[*inst >> 0x15 & 0x1f]; signedOffset = (s16)*inst; if ((signedOffset + *lastInst * 0x10000 & 0xf000000) == 0) { relocatedAddress = ((signedOffset + regValues[*inst >> 0x15 & 0x1f] * 0x10000) - vRamStart) + allocatedVRamAddr; *lastInst = (((relocatedAddress >> 0x10) & 0xFFFF) + ((relocatedAddress & 0x8000) ? 1 : 0)) | (*lastInst & 0xffff0000); *inst = *inst & 0xffff0000 | relocatedAddress & 0xffff; } break; } } } #else #pragma GLOBAL_ASM("asm/non_matchings/boot/loadfragment2/Load2_Relocate.s") #endif #ifdef NON_MATCHING // Very minor stack stuff with a saved value s32 Load2_LoadOverlay(u32 vRomStart, u32 vRomEnd, u32 vRamStart, u32 vRamEnd, u32 allocatedVRamAddr) { int nbytes; u32 pad; u32 size; void* end; OverlayRelocationSection* overlayInfo; size = vRomEnd - vRomStart; if (1) { ; } DmaMgr_SendRequest0(allocatedVRamAddr, vRomStart, size); end = (void*)(allocatedVRamAddr + size); overlayInfo = (OverlayRelocationSection*)((int)end - *(int*)((int)end + -4)); if (1) { ; } Load2_Relocate(allocatedVRamAddr, overlayInfo, vRamStart); if (overlayInfo->bssSize != 0) { bzero(end, overlayInfo->bssSize); } nbytes = vRamEnd - vRamStart; osWritebackDCache((void*)allocatedVRamAddr, nbytes); osInvalICache((void*)allocatedVRamAddr, nbytes); return nbytes; } #else #pragma GLOBAL_ASM("asm/non_matchings/boot/loadfragment2/Load2_LoadOverlay.s") #endif void* Load2_AllocateAndLoad(u32 vRomStart, u32 vRomEnd, u32 vRamStart, u32 vRamEnd) { void* allocatedVRamAddr; u32 size; size = vRamEnd - vRamStart; allocatedVRamAddr = StartHeap_AllocR(size); if (allocatedVRamAddr != NULL) { Load2_LoadOverlay(vRomStart, vRomEnd, vRamStart, vRamEnd, (u32)allocatedVRamAddr); } return allocatedVRamAddr; }