From 912a8b067ca91630763dc995360302fdd9b4df3d Mon Sep 17 00:00:00 2001 From: sup39 Date: Fri, 22 Apr 2022 18:03:49 +0900 Subject: [PATCH] Handle freezing code of blue coin properly Also fix gpMarDirector r13 offset for all versions --- changelog.md | 2 +- .../components/codes/qft/code/GMSE01.js | 2 + .../components/codes/qft/code/GMSJ01.js | 2 + .../components/codes/qft/code/GMSJ0A.js | 2 + .../components/codes/qft/code/GMSP01.js | 2 + .../.vuepress/components/codes/qft/codegen.js | 77 +++++++++++++++---- 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index b5b665f..df7f499 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,5 @@ # Changelog -## Apr 21, 2022 +## Apr 22, 2022 ### Shortened QFT - Shortened QFT's freeze code by replacing C2 with 04(bl@event) and 07. - Reserve `817F0348`~`817F03BF` (120 bytes) diff --git a/site/.vuepress/components/codes/qft/code/GMSE01.js b/site/.vuepress/components/codes/qft/code/GMSE01.js index 5c40295..4f66692 100644 --- a/site/.vuepress/components/codes/qft/code/GMSE01.js +++ b/site/.vuepress/components/codes/qft/code/GMSE01.js @@ -1,3 +1,5 @@ +export const r13off = -0x6048; + /** * @type {{[key: string]: [addr: number, orig: number]}} */ diff --git a/site/.vuepress/components/codes/qft/code/GMSJ01.js b/site/.vuepress/components/codes/qft/code/GMSJ01.js index 73c2808..9b9b2ff 100644 --- a/site/.vuepress/components/codes/qft/code/GMSJ01.js +++ b/site/.vuepress/components/codes/qft/code/GMSJ01.js @@ -1,3 +1,5 @@ +export const r13off = -0x6818; + /** * @type {{[key: string]: [addr: number, orig: number]}} */ diff --git a/site/.vuepress/components/codes/qft/code/GMSJ0A.js b/site/.vuepress/components/codes/qft/code/GMSJ0A.js index b0f88b3..2d38036 100644 --- a/site/.vuepress/components/codes/qft/code/GMSJ0A.js +++ b/site/.vuepress/components/codes/qft/code/GMSJ0A.js @@ -1,3 +1,5 @@ +export const r13off = -0x6188; + /** * @type {{[key: string]: [addr: number, orig: number]}} */ diff --git a/site/.vuepress/components/codes/qft/code/GMSP01.js b/site/.vuepress/components/codes/qft/code/GMSP01.js index c4cc33b..2168202 100644 --- a/site/.vuepress/components/codes/qft/code/GMSP01.js +++ b/site/.vuepress/components/codes/qft/code/GMSP01.js @@ -1,3 +1,5 @@ +export const r13off = -0x6120; + /** * @type {{[key: string]: [addr: number, orig: number]}} */ diff --git a/site/.vuepress/components/codes/qft/codegen.js b/site/.vuepress/components/codes/qft/codegen.js index c0cf8f9..91c7a0f 100644 --- a/site/.vuepress/components/codes/qft/codegen.js +++ b/site/.vuepress/components/codes/qft/codegen.js @@ -65,44 +65,95 @@ export const codes = { GMSJ01, GMSE01, GMSP01, GMSJ0A }; bl 817fxxxx ****/ const freezeCodeAddr = 0x817f0348; -const freezeCode = [0x3d80817f, 0x916c00bc, 0x816d97e8, 0x816b005c, 0x916c00b8, 0x4e800020]; - export default function codegen(version) { const config = getConfig(); - const { freezeCodeInfo, baseCode } = codes[version] ?? {}; + const { freezeCodeInfo, baseCode, r13off } = codes[version] ?? {}; if (baseCode == null) return ''; let code = baseCode; - // freeze code - const code04 = []; - const code07 = [...freezeCode]; - let dst = freezeCodeAddr + 24; + // freezing code + const freezeConfigs = []; for (const [key, frame] of Object.entries(config.freeze)) { const info = freezeCodeInfo[key]; if (frame > 0 && info) { const [addr, orig] = info; + if (key === 'blueCoin') { + // special: needs to adjust QF -> use separate C2 instead + code += [ + 0xc2000000 + (addr & 0x1ffffff), + 0x00000005, + orig, + 0x80a3005c, + 0x38a50003, + 0x54a0003a, + 0x3ca0817f, + 0x900500b8, + 0x38000000 | (frame & 0xffff), + 0x900500bc, + 0x60000000, + 0x00000000, + ] + .map(int32) + .join(''); + } else { + // handle regular freezing code later + freezeConfigs.push({ frame, addr, orig }); + } + } + } + // handle regular freezing code + if (freezeConfigs.length <= 1) { + // use C2 directly + code += freezeConfigs + .flatMap(({ frame, addr, orig }) => [ + 0xc2000000 + (addr & 0x1ffffff), + 0x00000004, + 0x39600000 | (frame & 0xffff), // li r11, frame + 0x3d80817f, // lis r12, 0x817F + 0x916c00bc, // stw r11, 0xBC(r12) + 0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13) + 0x816b005c, // lwz r11, 0x5C(r11) + 0x916c00b8, // stw r11, 0xB8(r12) + orig, + 0x00000000, + ]) + .map(int32) + .join(''); + } else { + let dst = freezeCodeAddr + 24; + const code04 = []; + const code07 = [ + 0x3d80817f, // lis r12, 0x817F + 0x916c00bc, // stw r11, 0xBC(r12) + 0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13) + 0x816b005c, // lwz r11, 0x5C(r11) + 0x916c00b8, // stw r11, 0xB8(r12) + 0x4e800020, // blr + ]; + // put code together + for (const { frame, addr, orig } of freezeConfigs) { code07.push( orig, // [dst] original instruction 0x39600000 | (frame & 0xffff), // li r11, $frame 0x4c000000 + (freezeCodeAddr - dst - 8), // b freezeCode ); code04.push( - 0x04000000 | (addr & 0x1ffffff), // 04xxxxxx - 0x48000001 | (dst - addr), // bl + 0x04000000 | (addr & 0x1ffffff), // 04 addr + 0x48000001 | (dst - addr), // bl dst ); dst += 12; } - } - if (code04.length) { + // make 07 code code07.unshift( - 0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07xxxxxx + 0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07 freezeCodeAddr code07.length * 4, ); if (code07.length & 1) { - // odd -> add 0 + // odd => pad with 0 code07.push(0); } + // apply code code += [...code04, ...code07].map(int32).join(''); }