Match autoload callback in ROM header

This commit is contained in:
Aetias
2023-10-21 12:54:05 +02:00
parent d2f2636774
commit 08220bd2a4
8 changed files with 70 additions and 24 deletions
+1 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+5
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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
View File
@@ -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;
+26
View File
@@ -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