mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-23 04:59:41 +00:00
Use PSP platform to disassemble PSP overlays (#1118)
Having `platform: psx` will not correctly disassemble PSP functions with opcodes that are not part of the R3000 (the PSX CPU) architecture. These functions would be disassembled by Splat as a bunch of `.word 0xBLAHBLAH`. Changing the platform to `psp` introduces all sort of new challenges. Function prototypes needs to be declared earlier. But also the MWCC compiler will not accept the `%lo` and `%hi` dialect from GNU AS. There were some patches on `mwcpp.py` to use `la SYMBOL_NAME` that would expand into a `lui / addiu` combo. But even though symbols needs to be declared like function prototypes at the top of the file. This is simply not feasible on bigger overlays. As a solution to the problem above, I replaced the existing patches by converting instructions into `.word`. The overlay cannot longer be relocated with this approach, but it is not an issue as the final goal is to decompile these functions any way. The labels in the jump table has the same problem, which forced me to change the segment type from `rodata` to `data. This is just another single step to create the conditions to start including bigger re-compilable PSP overlays. I am sure the `mwcpp.py` solution will be thrown into the bin at some point, but this PR improves our current situation.
This commit is contained in:
parent
78e0739a6c
commit
18f2bde385
@ -1,5 +1,5 @@
|
||||
options:
|
||||
platform: psx
|
||||
platform: psp
|
||||
basename: tt_000
|
||||
base_path: ..
|
||||
build_path: build/pspeu
|
||||
@ -37,6 +37,6 @@ segments:
|
||||
subsegments:
|
||||
- [0x80, c, 10E8]
|
||||
- [0x4C80, data]
|
||||
- [0x5E00, rodata]
|
||||
- [0x5E00, data] # rodata, not data
|
||||
- {type: bss, vram: 0x092ed480}
|
||||
- [0x5E80]
|
||||
|
@ -1,3 +1,6 @@
|
||||
abs = 0x08906AF0;
|
||||
memcpy = 0x08909F84;
|
||||
rand = 0x0890B954;
|
||||
LoadImage = 0x0891bfe4;
|
||||
SquareRoot12 = 0x08927ccc;
|
||||
ratan2 = 0x08927cfc;
|
||||
|
@ -16,3 +16,5 @@ extern void* malloc(size_t // Size of memory block to be allocated
|
||||
);
|
||||
extern void free(void*);
|
||||
int printf(char*, ...);
|
||||
|
||||
int abs(int x);
|
||||
|
@ -66,7 +66,6 @@ extern EntitySearch D_80171094[];
|
||||
|
||||
#ifdef VERSION_PSP
|
||||
extern ServantDesc D_8D1DC40;
|
||||
void func_8909F84(ServantDesc* dst, ServantDesc* src, int len);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
#include <servant.h>
|
||||
#include <sfx.h>
|
||||
#include <psxsdk/libc.h>
|
||||
|
||||
#define SFX_BAT_SCREECH SOUND_BAT_SCREECH
|
||||
#define SFX_BAT_NOTIFY SE_UI_OVERWRITE_MSG
|
||||
@ -71,8 +72,12 @@ extern s32 D_80174D3C;
|
||||
|
||||
void DestroyEntity();
|
||||
s32 func_80174864(void);
|
||||
void func_8909F84();
|
||||
s32 func_801746A0(s32 arg0);
|
||||
void ProcessEvent();
|
||||
void CreateEventEntity(Entity* entityParent, s32 entityId, s32 params);
|
||||
|
||||
void func_80173F74();
|
||||
void func_80173F30();
|
||||
|
||||
#endif
|
||||
|
||||
@ -1490,6 +1495,6 @@ s32 func_80174864(void) {
|
||||
|
||||
#ifdef VERSION_PSP
|
||||
void func_092EC220(void) {
|
||||
func_8909F84(&D_8D1DC40, &g_ServantDesc, sizeof(ServantDesc));
|
||||
memcpy((u8*)&D_8D1DC40, (u8*)&g_ServantDesc, sizeof(ServantDesc));
|
||||
}
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@ from typing import TextIO
|
||||
|
||||
r_lui = r"\s*lui\s*\$(.*),\s\%hi\((.*)\)"
|
||||
r_lui_addiu_combo = r"\s*addiu\s*\$(.*),\s\$(.*),\s\%lo\((.*)\)"
|
||||
r_hilo = r"\/\*\s*\w*\s*\w*\s*(\w*)\s*\*\/\s*\w*\s*\$\w*,.*(?:%hi|%lo).*"
|
||||
r_hi = r"%hi\((.*)\)"
|
||||
r_lo = r"%lo\((.*)\)\(|%lo\((.*)\)"
|
||||
r_jalr = r"jalr\s*\$([a-z][a-z0-9])"
|
||||
@ -37,41 +38,18 @@ def process_asm_line(asm_f: TextIO, line: str) -> str | None:
|
||||
if "#" in line:
|
||||
line = line.split("#")[0] + "\n"
|
||||
|
||||
# look for a LUI/ADDIU combo
|
||||
match_lui = re.search(r_lui, line)
|
||||
if match_lui:
|
||||
dst_reg = match_lui.group(1)
|
||||
src_sym = match_lui.group(2)
|
||||
second_line = asm_f.readline()
|
||||
match_lui_addiu_combo = re.search(r_lui_addiu_combo, second_line)
|
||||
if match_lui_addiu_combo:
|
||||
dst_reg_2 = match_lui_addiu_combo.group(1)
|
||||
src_reg_2 = match_lui_addiu_combo.group(2)
|
||||
src_sym_2 = match_lui_addiu_combo.group(3)
|
||||
if dst_reg == dst_reg_2 and src_reg_2 == dst_reg_2 and src_sym == src_sym_2:
|
||||
return f"la ${dst_reg}, {src_sym}\n"
|
||||
second_line = process_asm_line(asm_f, second_line)
|
||||
line = line.replace(f"%hi({src_sym})", f"({src_sym})@ha")
|
||||
return line + second_line
|
||||
|
||||
# use symbol@h instead of %hi(symbol)
|
||||
himatch = re.search(r_hi, line)
|
||||
if himatch:
|
||||
symbol_name = himatch.group(1)
|
||||
return line.replace(f"%hi({symbol_name})", f"({symbol_name})@ha")
|
||||
|
||||
# use symbol@l instead of %lo(symbol)
|
||||
lomatch = re.search(r_lo, line)
|
||||
if lomatch:
|
||||
symbol_name = lomatch.group(1)
|
||||
return line.replace(f"%lo({symbol_name})", f"({symbol_name}@l)")
|
||||
|
||||
# jalr needs two arguments
|
||||
jalr_match = re.search(r_jalr, line)
|
||||
if jalr_match:
|
||||
reg_name = jalr_match.group(1)
|
||||
return line.replace(reg_name, f"ra, ${reg_name}")
|
||||
|
||||
r_hilo_match = re.search(r_hilo, line)
|
||||
if r_hilo_match:
|
||||
raw_data = r_hilo_match.group(1)
|
||||
if len(raw_data) == 8:
|
||||
return f".word 0x{raw_data[6:8]}{raw_data[4:6]}{raw_data[2:4]}{raw_data[0:2]}\n"
|
||||
|
||||
# return unpatched assembly line
|
||||
return line
|
||||
|
||||
|
@ -87,41 +87,16 @@ LHELLO:
|
||||
""",
|
||||
)
|
||||
|
||||
def test_fix_lui_addiu_combo(self):
|
||||
def test_fix_lo_hi(self):
|
||||
self.assertEqual(
|
||||
self.helper_process_lines(
|
||||
"""lui $a0, %hi(D_8D1DC40)
|
||||
/* some stuff */ addiu $a0, $a0, %lo(D_8D1DC40)
|
||||
"""/* XXXX 09012348 DEADBEEF */ lui $v1, %hi(D_92EFFDE)
|
||||
/* XXXX 09012344 BADC0FFE */ lh $a0, %lo(D_92EFFDE)
|
||||
"""
|
||||
),
|
||||
"""asm void func_name() {
|
||||
la $a0, D_8D1DC40
|
||||
}
|
||||
""",
|
||||
)
|
||||
|
||||
def test_fix_lui_lh_combo(self):
|
||||
self.assertEqual(
|
||||
self.helper_process_lines(
|
||||
"""lui $v1, %hi(D_92EFFDE)
|
||||
/* some stuff */ lh $a0, -0x2948($v1)
|
||||
"""
|
||||
),
|
||||
"""asm void func_name() {
|
||||
lui $v1, (D_92EFFDE)@ha
|
||||
/* some stuff */ lh $a0, -0x2948($v1)
|
||||
}
|
||||
""",
|
||||
)
|
||||
|
||||
def test_fix_lower_16bit(self):
|
||||
self.assertEqual(
|
||||
self.helper_process_lines(
|
||||
"""lw $s1, %lo(g_EventQueue)($v1)
|
||||
"""
|
||||
),
|
||||
"""asm void func_name() {
|
||||
lw $s1, (g_EventQueue@l)($v1)
|
||||
.word 0xEFBEADDE
|
||||
.word 0xFE0FDCBA
|
||||
}
|
||||
""",
|
||||
)
|
||||
|
@ -11,10 +11,10 @@ mapfile-parser==2.1.4
|
||||
tabulate
|
||||
requests
|
||||
graphviz
|
||||
splat64>=0.23.2,<0.24.0
|
||||
splat64>=0.24.1,<0.25.0
|
||||
crunch64
|
||||
spimdisasm>=1.24.3,<1.25.0
|
||||
rabbitizer>=1.9.5,<1.10.0
|
||||
spimdisasm>=1.25.0
|
||||
rabbitizer>=1.10.0
|
||||
n64img==0.3.3
|
||||
PyYAML
|
||||
pylibyaml
|
||||
|
Loading…
Reference in New Issue
Block a user