Handle freezing code of blue coin properly
Also fix gpMarDirector r13 offset for all versions
This commit is contained in:
parent
d9bb06f3ba
commit
912a8b067c
6 changed files with 73 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
## Apr 21, 2022
|
## Apr 22, 2022
|
||||||
### Shortened QFT
|
### Shortened QFT
|
||||||
- Shortened QFT's freeze code by replacing C2 with 04(bl@event) and 07.
|
- Shortened QFT's freeze code by replacing C2 with 04(bl@event) and 07.
|
||||||
- Reserve `817F0348`~`817F03BF` (120 bytes)
|
- Reserve `817F0348`~`817F03BF` (120 bytes)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
export const r13off = -0x6048;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
export const r13off = -0x6818;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
export const r13off = -0x6188;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
export const r13off = -0x6120;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -65,44 +65,95 @@ export const codes = { GMSJ01, GMSE01, GMSP01, GMSJ0A };
|
||||||
bl 817fxxxx
|
bl 817fxxxx
|
||||||
****/
|
****/
|
||||||
const freezeCodeAddr = 0x817f0348;
|
const freezeCodeAddr = 0x817f0348;
|
||||||
const freezeCode = [0x3d80817f, 0x916c00bc, 0x816d97e8, 0x816b005c, 0x916c00b8, 0x4e800020];
|
|
||||||
|
|
||||||
export default function codegen(version) {
|
export default function codegen(version) {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
const { freezeCodeInfo, baseCode } = codes[version] ?? {};
|
const { freezeCodeInfo, baseCode, r13off } = codes[version] ?? {};
|
||||||
if (baseCode == null) return '';
|
if (baseCode == null) return '';
|
||||||
|
|
||||||
let code = baseCode;
|
let code = baseCode;
|
||||||
|
|
||||||
// freeze code
|
// freezing code
|
||||||
const code04 = [];
|
const freezeConfigs = [];
|
||||||
const code07 = [...freezeCode];
|
|
||||||
let dst = freezeCodeAddr + 24;
|
|
||||||
for (const [key, frame] of Object.entries(config.freeze)) {
|
for (const [key, frame] of Object.entries(config.freeze)) {
|
||||||
const info = freezeCodeInfo[key];
|
const info = freezeCodeInfo[key];
|
||||||
if (frame > 0 && info) {
|
if (frame > 0 && info) {
|
||||||
const [addr, orig] = 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(
|
code07.push(
|
||||||
orig, // [dst] original instruction
|
orig, // [dst] original instruction
|
||||||
0x39600000 | (frame & 0xffff), // li r11, $frame
|
0x39600000 | (frame & 0xffff), // li r11, $frame
|
||||||
0x4c000000 + (freezeCodeAddr - dst - 8), // b freezeCode
|
0x4c000000 + (freezeCodeAddr - dst - 8), // b freezeCode
|
||||||
);
|
);
|
||||||
code04.push(
|
code04.push(
|
||||||
0x04000000 | (addr & 0x1ffffff), // 04xxxxxx
|
0x04000000 | (addr & 0x1ffffff), // 04 addr
|
||||||
0x48000001 | (dst - addr), // bl
|
0x48000001 | (dst - addr), // bl dst
|
||||||
);
|
);
|
||||||
dst += 12;
|
dst += 12;
|
||||||
}
|
}
|
||||||
}
|
// make 07 code
|
||||||
if (code04.length) {
|
|
||||||
code07.unshift(
|
code07.unshift(
|
||||||
0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07xxxxxx
|
0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07 freezeCodeAddr
|
||||||
code07.length * 4,
|
code07.length * 4,
|
||||||
);
|
);
|
||||||
if (code07.length & 1) {
|
if (code07.length & 1) {
|
||||||
// odd -> add 0
|
// odd => pad with 0
|
||||||
code07.push(0);
|
code07.push(0);
|
||||||
}
|
}
|
||||||
|
// apply code
|
||||||
code += [...code04, ...code07].map(int32).join('');
|
code += [...code04, ...code07].map(int32).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue