mirror of
https://github.com/zeldaret/ph
synced 2026-05-24 07:10:52 -04:00
Match autoload callback in ROM header
This commit is contained in:
+1
-2
@@ -217,7 +217,6 @@
|
||||
.extern data_02000934
|
||||
.extern data_02000938
|
||||
.extern data_02000a70
|
||||
.extern data_02000a74
|
||||
.extern data_02000b30
|
||||
.extern data_02000b34
|
||||
.extern data_02000b38
|
||||
@@ -251116,7 +251115,7 @@
|
||||
.extern func_02000a40
|
||||
.extern func_02000a50
|
||||
.extern func_02000a6c
|
||||
.extern func_02000a74
|
||||
.extern AutoloadDoneCallback
|
||||
.extern func_02000a78
|
||||
.extern func_02000b60
|
||||
.extern func_02000c30
|
||||
|
||||
+5
-5
@@ -195,16 +195,16 @@ _02000a50:
|
||||
blt _02000a50
|
||||
b _02000a0c
|
||||
_02000a6c:
|
||||
b func_02000a74
|
||||
b AutoloadDoneCallback
|
||||
.align 2, 0
|
||||
arm_func_end func_020009fc
|
||||
_02000a70: .word spAutoloadBlockInfosStart
|
||||
|
||||
.global func_02000a74
|
||||
arm_func_start func_02000a74
|
||||
func_02000a74:
|
||||
.global AutoloadDoneCallback
|
||||
arm_func_start AutoloadDoneCallback
|
||||
AutoloadDoneCallback:
|
||||
bx lr
|
||||
arm_func_end func_02000a74
|
||||
arm_func_end AutoloadDoneCallback
|
||||
|
||||
.global func_02000a78
|
||||
arm_func_start func_02000a78
|
||||
|
||||
+2
-2
@@ -5619,7 +5619,7 @@ _020f2b9e:
|
||||
bne _020f2b9e
|
||||
_020f2bb4:
|
||||
ldr r0, [sp, #0x14]
|
||||
ldr r1, _020f2be8 ; =func_02000a74
|
||||
ldr r1, _020f2be8 ; =AutoloadDoneCallback
|
||||
ldr r2, [r0, #0x48]
|
||||
ldr r0, [r6, #0x28]
|
||||
sub r1, r1, r0
|
||||
@@ -5642,7 +5642,7 @@ _020f2bd8: .word 0x027ffe00
|
||||
_020f2bdc: .word data_ov01_020f890c
|
||||
_020f2be0: .word 0x00406000
|
||||
_020f2be4: .word data_ov01_020f8908
|
||||
_020f2be8: .word func_02000a74
|
||||
_020f2be8: .word AutoloadDoneCallback
|
||||
_020f2bec: .word 0xe12fff1e
|
||||
|
||||
.global func_ov01_020f2bf0
|
||||
|
||||
@@ -225,6 +225,7 @@ with open(f'{BUILD}arm9_linker_script.lcf', 'w') as file:
|
||||
file.write(' DTCM : ORIGIN = 0x27e0000 >> arm9.bin\n')
|
||||
file.write(' AUTOLOADS : ORIGIN = 0 >> arm9.bin\n')
|
||||
file.write(' FOOTER : ORIGIN = 0 > arm9_footer.bin\n')
|
||||
file.write(' METADATA : ORIGIN = 0 > arm9_metadata.bin\n')
|
||||
file.write('\n')
|
||||
file.write(' OV_TABLE : ORIGIN = 0 > arm9_ovt.bin\n')
|
||||
file.write('\n')
|
||||
@@ -279,6 +280,10 @@ with open(f'{BUILD}arm9_linker_script.lcf', 'w') as file:
|
||||
file.write(' WRITEW 0;\n')
|
||||
file.write(' } > FOOTER\n')
|
||||
file.write('\n')
|
||||
file.write(' .metadata : {\n')
|
||||
file.write(' WRITEW AutoloadDoneCallback;\n')
|
||||
file.write(' } > METADATA\n')
|
||||
file.write('\n')
|
||||
for ov in OVERLAYS:
|
||||
file.write(f' .{ov.name} : ' + '{\n')
|
||||
file.write(f' {ov.name}_start = .;\n')
|
||||
|
||||
+28
-13
@@ -160,8 +160,8 @@ void InitHeader(Header *pHeader, const BuildInfo *info) {
|
||||
pHeader->bannerOffset = 0; // will be 256-aligned after file alloc table
|
||||
pHeader->secureAreaCrc = 0; // TODO: Calculate
|
||||
pHeader->secureAreaDelay = 0x0d7e;
|
||||
pHeader->arm9AutoloadList = 0; // TODO: Get from linker (always 2000a74)
|
||||
pHeader->arm7AutoloadList = 0x2380158;
|
||||
pHeader->arm9AutoloadCallback = 0; // TODO: Get from linker (always 2000a74)
|
||||
pHeader->arm7AutoloadCallback = 0x2380158;
|
||||
pHeader->secureAreaDisable = 0;
|
||||
pHeader->romSize = 0; // Will be set
|
||||
pHeader->headerSize = sizeof(Header);
|
||||
@@ -513,12 +513,22 @@ bool RewriteFat(FILE *fpRom, size_t fatStart, const FatEntry *entries, size_t nu
|
||||
fseek(fpRom, 0, SEEK_END);
|
||||
}
|
||||
|
||||
bool FinalizeHeader(FILE *fpRom, Header *pHeader, const char *arm7bios, uint32_t *secureArea) {
|
||||
typedef struct {
|
||||
uint32_t autoloadCallback;
|
||||
} Arm9Metadata;
|
||||
|
||||
bool FinalizeHeader(FILE *fpRom, Header *pHeader, const char *arm7bios) {
|
||||
Header header;
|
||||
memcpy(&header, pHeader, sizeof(header));
|
||||
|
||||
if (arm7bios != NULL) {
|
||||
FILE *fp = fopen(arm7bios, "rb");
|
||||
FILE *fp = fopen(ARM9_PROGRAM_FILE, "rb");
|
||||
if (fp == NULL) FATAL("Failed to open ARM9 program '" ARM9_PROGRAM_FILE "'\n");
|
||||
uint32_t secureArea[0x1000];
|
||||
if (fread(secureArea, sizeof(secureArea), 1, fp) != 1) FATAL("Failed to read secure area\n");
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen(arm7bios, "rb");
|
||||
if (fp == NULL) FATAL("Failed to open ARM7 BIOS '%s'\n", arm7bios);
|
||||
fseek(fp, 0x30, SEEK_SET);
|
||||
uint8_t encKey[sizeof(Blowfish)];
|
||||
@@ -536,6 +546,13 @@ bool FinalizeHeader(FILE *fpRom, Header *pHeader, const char *arm7bios, uint32_t
|
||||
header.secureAreaCrc = Crc(secureArea, 0x4000);
|
||||
}
|
||||
|
||||
FILE *fp = fopen(ARM9_METADATA_FILE, "rb");
|
||||
if (fp == NULL) FATAL("Failed to open ARM9 metadata '" ARM9_METADATA_FILE "'\n");
|
||||
Arm9Metadata metadata;
|
||||
if (fread(&metadata, sizeof(metadata), 1, fp) != 1) FATAL("Failed to read ARM9 metadata '" ARM9_METADATA_FILE "'\n");
|
||||
fclose(fp);
|
||||
header.arm9AutoloadCallback = metadata.autoloadCallback;
|
||||
|
||||
header.headerCrc = Crc(&header, offsetof(Header, headerCrc));
|
||||
|
||||
size_t prevPos = ftell(fpRom);
|
||||
@@ -573,7 +590,7 @@ int main(int argc, const char **argv) {
|
||||
const char *baseDir = NULL;
|
||||
const char *buildDir = NULL;
|
||||
const char *romFile = NULL;
|
||||
const char *arm7bios = NULL;
|
||||
const char *arm7biosFile = NULL;
|
||||
Region region = 0;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "-o") == 0) {
|
||||
@@ -599,7 +616,7 @@ int main(int argc, const char **argv) {
|
||||
fprintf(stderr, "Expected pathname after -7\n");
|
||||
return 1;
|
||||
}
|
||||
arm7bios = argv[i];
|
||||
arm7biosFile = argv[i];
|
||||
} else if (strcmp(argv[i], "-r") == 0) {
|
||||
if (++i >= argc) {
|
||||
fprintf(stderr, "Expected region after -r\n");
|
||||
@@ -755,6 +772,9 @@ int main(int argc, const char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *arm7bios = NULL;
|
||||
if (arm7biosFile != NULL && !AllocFullPath(arm7biosFile, &arm7bios)) return 1;
|
||||
|
||||
header.romSize = address;
|
||||
header.capacity = 15 - __builtin_clz(header.romSize);
|
||||
size_t romEnd = 1 << (17 + header.capacity);
|
||||
@@ -765,19 +785,14 @@ int main(int argc, const char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(ARM9_PROGRAM_FILE, "rb");
|
||||
if (fp == NULL) FATAL("Failed to open ARM9 program '" ARM9_PROGRAM_FILE "'\n");
|
||||
uint32_t secureArea[0x1000];
|
||||
if (fread(secureArea, sizeof(secureArea), 1, fp) != 1) FATAL("Failed to read secure area\n");
|
||||
fclose(fp);
|
||||
if (!FinalizeHeader(fpRom, &header, arm7bios)) return false;
|
||||
FreeFullPath(&arm7bios);
|
||||
|
||||
if (chdir(rootDir) != 0) {
|
||||
fprintf(stderr, "Failed to leave build directory '%s'\n", buildDir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!FinalizeHeader(fpRom, &header, arm7bios, secureArea)) return false;
|
||||
|
||||
free(readBuffer);
|
||||
fclose(fpRom);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#define ARM9_PROGRAM_FILE "arm9.lz"
|
||||
#define ARM9_FOOTER_FILE "arm9_footer.bin"
|
||||
#define ARM9_METADATA_FILE "arm9_metadata.bin"
|
||||
#define ARM9_OVERLAY_TABLE_FILE "arm9_ovt.bin"
|
||||
#define OVERLAYS_SUBDIR "overlays"
|
||||
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ typedef struct {
|
||||
/* 0068 */ uint32_t bannerOffset;
|
||||
/* 006c */ uint16_t secureAreaCrc;
|
||||
/* 006e */ uint16_t secureAreaDelay;
|
||||
/* 0070 */ uint32_t arm9AutoloadList;
|
||||
/* 0074 */ uint32_t arm7AutoloadList;
|
||||
/* 0070 */ uint32_t arm9AutoloadCallback;
|
||||
/* 0074 */ uint32_t arm7AutoloadCallback;
|
||||
/* 0078 */ uint64_t secureAreaDisable;
|
||||
/* 0080 */ uint32_t romSize;
|
||||
/* 0084 */ uint32_t headerSize;
|
||||
|
||||
@@ -59,4 +59,30 @@ bool Utf8ToWchar(char *in, size_t inSize, wchar_t *out, size_t outSize) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AllocFullPath(const char *path, char **pFullPath) {
|
||||
#ifdef _WIN32
|
||||
if (path[0] == '/') {
|
||||
// Remove drive letter, e.g. /c/Projects/ph/ -> /Projects/ph/
|
||||
const char *root = strchr(path + 1, '/');
|
||||
if (root - path == 2) path = root;
|
||||
}
|
||||
size_t size = GetFullPathNameA(path, 0, NULL, NULL);
|
||||
char *fullPath = malloc(size);
|
||||
size_t resultSize = GetFullPathNameA(path, size, fullPath, NULL);
|
||||
if (resultSize == 0 || resultSize > size) FATAL("Failed to get full path for '%s'\n", path);
|
||||
*pFullPath = fullPath;
|
||||
return true;
|
||||
#elif __linux__
|
||||
char *fullPath = realpath(path, NULL);
|
||||
if (fullPath == NULL) FATAL("Failed to get full path for '%s'\n", path);
|
||||
*pFullPath = fullPath;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FreeFullPath(char **pFullPath) {
|
||||
free(*pFullPath);
|
||||
*pFullPath = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user