diff --git a/Makefile b/Makefile index 90dd69b3ad..3b61acf88f 100644 --- a/Makefile +++ b/Makefile @@ -607,13 +607,31 @@ SND_OBJDIR := build/psyq/snd SND_SYMS := build/psyq/snd_externals.ld SND_STUBS := snd1,snd2,snd3,snd4,snd5,snd6,snd7,snd8,snd9,snd10,snd11,snd12 -# Combined libapi+libcard 800c2 region (Phase 8): 22 objects in 4 blocks (apicard1..4). Curated dir -# .run/obj40/apicard_used (tools/make_apicard_used.py). Window 0x61F38..0x62888. (libapi's ~22 objects -# in the 800c3 region are DEFERRED — lowest value.) -APICARD_ELF := .run/obj40/apicard_used +# Combined libapi+libcard 800c2 region (Phase 8; S79 #5): 26 objects in 7 blocks (apicard1..7) tiling +# 0x80061F38..0x80062888 with no game code left between them. Curated dir .run/obj42/apicard_used +# (tools/make_apicard_used.py: libapi from tools/psyq/lib421 = 4.2, the EXE's real libapi; libcard 4.0). +# Window 0x61F38..0x62888. The former 800c2/800c2_2/800c2_3 "game code" rows were FIRST.o / PAD.o / +# PATCH.o+CHCLRPAD.o (libapi 4.2 C objects) — apicard5/6/7. +APICARD_ELF := .run/obj42/apicard_used APICARD_OBJDIR := build/psyq/apicard APICARD_SYMS := build/psyq/apicard_externals.ld -APICARD_STUBS := apicard1,apicard2,apicard3,apicard4 +APICARD_STUBS := apicard1,apicard2,apicard3,apicard4,apicard5,apicard6,apicard7 + +# The libapi 4.2 + libpad 4.2.1 band (S78 #12 named it, S79 #13 found the archive, S79 #5 wired it): +# 0x8005CE18..0x8005FC68 = 33 interleaved Sony objects, all byte-identical from tools/psyq/lib421 +# (SCE's 1998-02-26 "libpad.lib 4.2.1 for the DUAL SHOCK" patch + libapi.lib 4.2; ELF regenerated into +# .run/obj42/{libapi42,libpad421} by psyq_lib_split.py + psyq-obj-parser — see docs/SETUP.md). Two raw +# dirs, two calls, each windowed to its own objects and tiling its own stubs (libapi1/libapi2, +# libpad1/libpad2). This was the src/800c3.c "REORDER_TUS island" — 129 hand-matched "C", 62 verbatim +# bodies, 19 stubs incl. the four §332 "%lo-in-a-delay-slot walls": Sony code assembled in reorder mode. +LIBAPI42_ELF := .run/obj42/libapi42 +LIBAPI42_OBJDIR := build/psyq/libapi42 +LIBAPI42_SYMS := build/psyq/libapi42_externals.ld +LIBAPI42_STUBS := libapi1,libapi2 +LIBPAD_ELF := .run/obj42/libpad421 +LIBPAD_OBJDIR := build/psyq/libpad +LIBPAD_SYMS := build/psyq/libpad_externals.ld +LIBPAD_STUBS := libpad1,libpad2 # Assembler flags (docs/SETUP.md §6.2). -G0 is confirmed by the disassembly # (ledger #8: zero $gp-relative addressing). -no-pad-sections keeps section ends @@ -763,7 +781,10 @@ CC1FLAGS := -quiet -O2 -G0 -mips1 -mcpu=3000 -mgas -msoft-float -fgnu-linker # `lui at / jr ra / sw a0,lo(at)` read as COMPILER-INEXPRESSIBLE (P31 S75): a probe showed cc1 + # reorder_passthrough + `as -O2` emits exactly that sequence. It was a build-config gap, not a # gcc limit (cookbook §452 corrected). -REORDER_TUS := 800c2 800c2_2 800c2_3 800c3 +# S79 #5: the island is EMPTY — all four TUs (800c2, 800c2_2, 800c2_3, 800c3) were libapi 4.2 / libpad 4.2.1 +# objects and are LINKED now (apicard5-7, libapi1/2, libpad1/2). The mechanism stays for any future +# reorder-assembled TU (cookbook §332b); match_one/rtu_match read this list and tolerate it empty. +REORDER_TUS := ASFLAGS_REORDER := -Iinclude -march=r3000 -mtune=r3000 -no-pad-sections -O2 -G0 build/src/%.o: src/%.c @@ -880,10 +901,20 @@ ifeq ($(BINARY),main) if [ -d "$(APICARD_ELF)" ]; then $(PYTHON) tools/psyq_integrate.py --vram-base $(main_VRAM_BASE) --exe $(main_EXE) --symbols $(main_SYMBOLS) --yaml $(main_SPLAT_YAML) $(APICARD_ELF) $(LD_SCRIPT) $(APICARD_OBJDIR) $(APICARD_SYMS) $(APICARD_STUBS) 0x80061F38 0x80062888 else - echo " (no $(APICARD_ELF) — apicard region stays asm stubs; run tools/psyq_build_libs.sh LIBAPI LIBCARD + tools/make_apicard_used.py)" + echo " (no $(APICARD_ELF) — apicard region stays asm stubs; run tools/psyq_build_libs.sh LIBCARD + the lib421 ELF step in docs/SETUP.md + tools/make_apicard_used.py)" + fi + if [ -d "$(LIBAPI42_ELF)" ]; then + $(PYTHON) tools/psyq_integrate.py --vram-base $(main_VRAM_BASE) --exe $(main_EXE) --symbols $(main_SYMBOLS) --yaml $(main_SPLAT_YAML) $(LIBAPI42_ELF) $(LD_SCRIPT) $(LIBAPI42_OBJDIR) $(LIBAPI42_SYMS) $(LIBAPI42_STUBS) 0x8005CE18 0x8005E188 + else + echo " (no $(LIBAPI42_ELF) — libapi band blocks stay asm stubs; convert tools/psyq/lib421/LIBAPI.LIB per docs/SETUP.md)" + fi + if [ -d "$(LIBPAD_ELF)" ]; then + $(PYTHON) tools/psyq_integrate.py --vram-base $(main_VRAM_BASE) --exe $(main_EXE) --symbols $(main_SYMBOLS) --yaml $(main_SPLAT_YAML) $(LIBPAD_ELF) $(LD_SCRIPT) $(LIBPAD_OBJDIR) $(LIBPAD_SYMS) $(LIBPAD_STUBS) 0x8005D0D8 0x8005FC68 + else + echo " (no $(LIBPAD_ELF) — libpad band blocks stay asm stubs; convert tools/psyq/lib421/LIBPAD.LIB per docs/SETUP.md)" fi endif - SYMS=""; [ -f "$(LIBCD_SYMS)" ] && SYMS="-T $(LIBCD_SYMS)"; [ -f "$(LIBGS_SYMS)" ] && SYMS="$$SYMS -T $(LIBGS_SYMS)"; [ -f "$(LIBETC_SYMS)" ] && SYMS="$$SYMS -T $(LIBETC_SYMS)"; [ -f "$(LIBGPU_SYMS)" ] && SYMS="$$SYMS -T $(LIBGPU_SYMS)"; [ -f "$(LIBMCRD_SYMS)" ] && SYMS="$$SYMS -T $(LIBMCRD_SYMS)"; [ -f "$(LIBC2_SYMS)" ] && SYMS="$$SYMS -T $(LIBC2_SYMS)"; [ -f "$(LIBGTE_SYMS)" ] && SYMS="$$SYMS -T $(LIBGTE_SYMS)"; [ -f "$(SND_SYMS)" ] && SYMS="$$SYMS -T $(SND_SYMS)"; [ -f "$(APICARD_SYMS)" ] && SYMS="$$SYMS -T $(APICARD_SYMS)" + SYMS=""; [ -f "$(LIBCD_SYMS)" ] && SYMS="-T $(LIBCD_SYMS)"; [ -f "$(LIBGS_SYMS)" ] && SYMS="$$SYMS -T $(LIBGS_SYMS)"; [ -f "$(LIBETC_SYMS)" ] && SYMS="$$SYMS -T $(LIBETC_SYMS)"; [ -f "$(LIBGPU_SYMS)" ] && SYMS="$$SYMS -T $(LIBGPU_SYMS)"; [ -f "$(LIBMCRD_SYMS)" ] && SYMS="$$SYMS -T $(LIBMCRD_SYMS)"; [ -f "$(LIBC2_SYMS)" ] && SYMS="$$SYMS -T $(LIBC2_SYMS)"; [ -f "$(LIBGTE_SYMS)" ] && SYMS="$$SYMS -T $(LIBGTE_SYMS)"; [ -f "$(SND_SYMS)" ] && SYMS="$$SYMS -T $(SND_SYMS)"; [ -f "$(APICARD_SYMS)" ] && SYMS="$$SYMS -T $(APICARD_SYMS)"; [ -f "$(LIBAPI42_SYMS)" ] && SYMS="$$SYMS -T $(LIBAPI42_SYMS)"; [ -f "$(LIBPAD_SYMS)" ] && SYMS="$$SYMS -T $(LIBPAD_SYMS)" echo " LD $(ELF)" $(LD) -T $(LD_SCRIPT) -T $(UNDEF_SYMS) -T $(UNDEF_FUNCS) $$SYMS --no-check-sections -Map $(MAPFILE) -o $(ELF) echo " OBJCOPY $@" diff --git a/config/splat.us.exe.yaml b/config/splat.us.exe.yaml index 8339e04397..efb0115b2f 100644 --- a/config/splat.us.exe.yaml +++ b/config/splat.us.exe.yaml @@ -201,21 +201,35 @@ segments: - [0x4CAC8, c, libc2_1] # libc2 main block (16 objs) -> src/libc2_1.c (vram 0x8005C2C8-0x8005CE18); # end = SETJMP.o's .text SECTION size (0x80, 8-aligned), NOT its 30-ins # count (0x78) — the trailing 8-byte align pad belongs to the object. - - [0x4D618, c, 800c3] # -O2 game code -> src/800c3.c (vram 0x8005CE18-0x8005FC68) + # PsyQ LIBAPI 4.2 + LIBPAD 4.2.1 band (P31 S78 #12 named it, S79 #13 found the archive, S79 #5 wired it): + # 0x8005CE18-0x8005FC68 is ONE contiguous run of 33 Sony objects, interleaved libapi/libpad, every one + # byte-identical from tools/psyq/lib421 (SCE's 1998-02-26 "libpad.lib 4.2.1 for the DUAL SHOCK" patch, + # shipped with libapi.lib 4.2 — the EXE's 4.2 / 4.2.1x `Ps` stamps). It used to be src/800c3.c: 129 + # hand-matched "C", 62 verbatim bodies and 19 stubs incl. the four §332 "%lo-in-a-delay-slot walls" — + # all of it Sony code assembled in reorder mode (§332b), none of it game code. Split into 4 rows because + # psyq_integrate tiles each stub with ONE library's objects (windows: libapi 0x8005CE18..0x8005E188, + # libpad 0x8005D0D8..0x8005FC68). Object sizes are .text SECTION sizes (exact tile, verified S79). + - [0x4D618, c, libapi1] # libapi 4.2 block 1: C57 C68 C73 C114 A07-A13 A23-A25 A36 A37 A52 A53 A91 L10 (21 trampolines) + COUNTER (92) -> src/libapi1.c (vram 0x8005CE18-0x8005D0D8) + - [0x4D8D8, c, libpad1] # libpad 4.2.1 block 1: PADENTRY (300) + PADMAIN (760) -> src/libpad1.c (vram 0x8005D0D8-0x8005E168) + - [0x4E968, c, libapi2] # libapi 4.2 block 2: L02 + L03 (SysEnqIntRP/SysDeqIntRP) -> src/libapi2.c (vram 0x8005E168-0x8005E188) + - [0x4E988, c, libpad2] # libpad 4.2.1 block 2: PADCMD (600) PADIF (376) PADPORTD (408) PADSEQD (288) WAITRC2 (48) -> src/libpad2.c (vram 0x8005E188-0x8005FC68) # PsyQ libmcrd (Phase 8): 2 objects — LIBMCRD.o (2186 ins; the 55 LIBMCRD_OBJ_* + _card_* memcard # I/O) and USERFUNC.o (68 ins, at the very end), 2 non-adjacent blocks split by game/libc2/libapi/ # libcard code (800c2). psyq_integrate libmcrd1,libmcrd2. (The GAME save logic / Q#5 is Phase 12.) - [0x50468, c, libmcrd1] # libmcrd block 1: LIBMCRD.o -> src/libmcrd1.c (vram 0x8005FC68-0x80061E90) - [0x52690, c, libc2_2] # libc2 block 2: STRCAT.o -> src/libc2_2.c (vram 0x80061E90-0x80061F38) - # PsyQ libapi+libcard COMBINED 800c2 region (Phase 8): BIOS syscall trampolines + card I/O, - # 22 objects in 4 blocks (curated by tools/make_apicard_used.py; C112.o shared, no exclusions). - # integrate window 0x61F38..0x62888. (libapi's ~22 objects in the 800c3 region are DEFERRED.) + # PsyQ libapi+libcard COMBINED 800c2 region (Phase 8; S79 #5): BIOS syscall trampolines + card I/O, + # now 26 objects in 7 blocks tiling 0x80061F38-0x80062888 with NO game code between them (curated by + # tools/make_apicard_used.py: libapi from tools/psyq/lib421 = 4.2, the EXE's real libapi; libcard 4.0, + # byte-identical; C112.o shared, no exclusions). integrate window 0x61F38..0x62888. The three former + # "game code" rows were libapi 4.2's C objects: 800c2 = FIRST.o (168 ins, `firstfile` + the "wall" + # stub func_80062144), 800c2_2 = PAD.o (192), 800c2_3 = PATCH.o (40) + CHCLRPAD.o (28) — exact tiles. - [0x52738, c, apicard1] # apicard block 1: 7 obj (C112.o..A69.o) vram 0x80061F38-0x80061FA8 - - [0x527A8, c, 800c2] # game code (vram 0x80061FA8-0x80062248) + - [0x527A8, c, apicard5] # apicard block 5 (S79 #5): FIRST.o (168 ins, exact tile) vram 0x80061FA8-0x80062248 — was '800c2' - [0x52A48, c, apicard2] # apicard block 2: 7 obj (A66.o..INIT.o) vram 0x80062248-0x80062388 - - [0x52B88, c, 800c2_2] # game code (vram 0x80062388-0x80062688) + - [0x52B88, c, apicard6] # apicard block 6 (S79 #5): PAD.o (192 ins, exact tile) vram 0x80062388-0x80062688 — was '800c2_2' - [0x52E88, c, apicard3] # apicard block 3: 4 obj (A18.o..A21.o) vram 0x80062688-0x800626C8 - - [0x52EC8, c, 800c2_3] # game code (vram 0x800626C8-0x800627D8) + - [0x52EC8, c, apicard7] # apicard block 7 (S79 #5): PATCH.o (40) + CHCLRPAD.o (28), exact tile, vram 0x800626C8-0x800627D8 — was '800c2_3' - [0x52FD8, c, apicard4] # apicard block 4: 4 obj (A74.o..END.o) vram 0x800627D8-0x80062888 - [0x53088, c, libmcrd2] # libmcrd block 2: USERFUNC.o -> src/libmcrd2.c (vram 0x80062888-0x80062998) # Phase 7 (Task 2' / LZSS) — SURGICAL rodata carve for the LZSS switch only. diff --git a/config/verbatim_manifest.json b/config/verbatim_manifest.json index 9bcfa31a4b..52c6e96ad9 100644 --- a/config/verbatim_manifest.json +++ b/config/verbatim_manifest.json @@ -12,246 +12,6 @@ ], "generated": "P31 S75 from .run/S75/triage/taxonomy.json", "rows": [ - { - "binary": "main", - "fn": "ChangeClearPAD", - "addr": "0x8005cf48", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "ChangeClearPAD", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "ChangeClearRCnt", - "addr": "0x8005cf58", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "ChangeClearRCnt", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "CloseEvent", - "addr": "0x8005ce88", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "CloseEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "DeliverEvent", - "addr": "0x8005ce68", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "DeliverEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "DisableEvent", - "addr": "0x8005cec8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "DisableEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "DisablePAD", - "addr": "0x800626dc", - "nins": 5, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_800626dc", - "unit_nins": 5, - "path": "src/800c2_3.c", - "why": "lui/lw/nop/jr $t1 through jtbl_80078D24 \u2014 vector hook" - }, - { - "binary": "main", - "fn": "EnableEvent", - "addr": "0x8005ceb8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "EnableEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "EnablePAD", - "addr": "0x800626c8", - "nins": 5, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_800626c8", - "unit_nins": 5, - "path": "src/800c2_3.c", - "why": "lui/lw/nop/jr $t1 through jtbl_80078D20 \u2014 vector hook" - }, - { - "binary": "main", - "fn": "FlushCache", - "addr": "0x8005ce28", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "FlushCache", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "HookEntryInt", - "addr": "0x8005cef8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "HookEntryInt", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "InitHeap", - "addr": "0x8005ce18", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "InitHeap", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "OpenEvent", - "addr": "0x8005ce78", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "OpenEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "ResetEntryInt", - "addr": "0x8005cee8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "ResetEntryInt", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "ReturnFromException", - "addr": "0x8005ced8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "ReturnFromException", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "SetInitPadFlag", - "addr": "0x80062388", - "nins": 3, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "SetInitPadFlag", - "unit_nins": 3, - "path": "src/800c2_2.c", - "why": "lui $at; jr $ra; sw $a0,lo($at) \u2014 hand-written setter (libcard region, 800c2 reorder island)" - }, - { - "binary": "main", - "fn": "SysDeqIntRP", - "addr": "0x8005e178", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "SysDeqIntRP", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "SysEnqIntRP", - "addr": "0x8005e168", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "SysEnqIntRP", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "TestEvent", - "addr": "0x8005cea8", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "TestEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "WaitEvent", - "addr": "0x8005ce98", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "WaitEvent", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "_96_remove", - "addr": "0x8005ce50", - "nins": 6, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "_96_remove", - "unit_nins": 6, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, { "binary": "main", "fn": "__do_global_dtors", @@ -276,78 +36,6 @@ "path": "src/boot.c", "why": "libgcc2.c C compiled -O2 inside the -O0 boot TU (per src comment); gcc-2.7.2 has no per-function opt level" }, - { - "binary": "main", - "fn": "_padInitDirSeq", - "addr": "0x8005f728", - "nins": 13, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_8005f728", - "unit_nins": 13, - "path": "src/800c3.c", - "why": "jr-slot symbolic store shape (as -O2 reorder island form)" - }, - { - "binary": "main", - "fn": "_patch_pad", - "addr": "0x800626f0", - "nins": 30, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_800626f0", - "unit_nins": 30, - "path": "src/800c2_3.c", - "why": "hand-written (sibling of _remove_ChgclrPAD)" - }, - { - "binary": "main", - "fn": "_remove_ChgclrPAD", - "addr": "0x80062768", - "nins": 28, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "_remove_ChgclrPAD", - "unit_nins": 28, - "path": "src/800c2_3.c", - "why": "splat Handwritten; B0-table call with $ra stashed in D_80078D28" - }, - { - "binary": "main", - "fn": "func_8005CE38", - "addr": "0x8005ce38", - "nins": 0, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_8005ce38", - "unit_nins": 0, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "read", - "addr": "0x8005cf28", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "read", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, - { - "binary": "main", - "fn": "setRC2wait", - "addr": "0x8005fba8", - "nins": 8, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "func_8005fba8", - "unit_nins": 8, - "path": "src/800c3.c", - "why": "jr-slot symbolic store; reads 0x1F801120 (RCNT) \u2014 hand-written" - }, { "binary": "main", "fn": "start", @@ -360,18 +48,6 @@ "path": "src/boot.c", "why": "crt0: `addi` (trapping add), break 1, $gp load; splat Handwritten" }, - { - "binary": "main", - "fn": "write", - "addr": "0x8005cf38", - "nins": 4, - "cls": "SDK-ASM", - "disposition": "PERMANENT-VERBATIM", - "unit_entry": "write", - "unit_nins": 4, - "path": "src/800c3.c", - "why": "BIOS A/B/C-table trampoline: li $t2,0xA0/B0/C0; jr $t2; li $t1,N; pad nop (or li $a0; syscall)" - }, { "binary": "md_MAIN_003", "fn": "func_800D3204", diff --git a/config/wave_exclude.txt b/config/wave_exclude.txt index f7aa0fba26..51bb45b667 100644 --- a/config/wave_exclude.txt +++ b/config/wave_exclude.txt @@ -1,24 +1,7 @@ # regenerated by tools/exclude_audit.py from config/wave_exclude.txt -# 11 still-valid of 27; 16 dropped as stale (banked / linked / blocker-since-fixed). +# 3 still-valid of 11; 8 dropped as stale (banked / linked / blocker-since-fixed). # An exclude list records what the TOOLING could not do — regenerate it as # part of every tool fix, or it becomes a list of work you decided not to do. -main:PopMatrix # WALL: compiler wall (merged from S68_walls_332.txt) -main:PushMatrix # WALL: compiler wall (merged from S68_walls_332.txt) -main:_padInitSioMode # WALL: no jump table — curated compiler fact, not a tooling limit -main:func_8005ECC0 # NEAR-2/35 (DELAY-SLOT) — NOT a wall. Same wrong-oracle provenance as -# PadInitDirect; re-measured S77 at 2 of 35. permuter_ils 4 cycles reached 5, not 0. -# Excluded as UNSOLVED, not as impossible. -main:PadInitDirect # NEAR-3/88 (ADDRESSING/move!=lui) — NOT a wall. The S68 'compiler wall' -# verdict was measured under the WRONG oracle (800c3 is a REORDER_TUS island; S76 fixed -# match_one/rtu_match to use reorder_passthrough + as -O2). Re-measured S77: 3 of 88. -# permuter_ils 4 cycles reached 3, not 0. Excluded as UNSOLVED, not as impossible. -main:func_80062144 # WALL: no jump table — curated compiler fact, not a tooling limit md_MAIN_034:func_800CB00C # WALL: compiler wall (merged from S68_walls_332.txt) ov_SC03_105:func_801834A4 # WALL: loop.c movable ordering, closeness 6 (S71) ov_SC06_022:func_8017DF28 # WALL: expand_block_move copy_addr_to_reg pseudo + cse reuse, closeness 2 (S71) -# S77: wall_sweep named these and the list did not carry them — an agent handed one -# always returns a NEAR with an unexplainable tail, indistinguishable from a hard function. -main:func_8005D734 # WALL: §332 %lo in a delay slot (wall_sweep, 1 site) — no C can place it -main:_padStartCom # WALL: §332 %lo in a delay slot (wall_sweep, 1 site) — no C can place it -main:func_8005ED4C # WALL: §332 %lo in a delay slot (wall_sweep, 2 sites) — no C can place it -main:func_8005F450 # WALL: §332 %lo in a delay slot (wall_sweep, 2 sites) — no C can place it diff --git a/docs/SETUP.md b/docs/SETUP.md index 3c09c6bd99..6d56a415d9 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -739,7 +739,7 @@ Every script under `tools/` (plus the two report make-targets), grouped by purpo | | `tools/make_libgs.sh` | Build/link the `libgs` block (cookbook §9). | | | `tools/gen_lib_subsegs.py` | **(Phase 8)** Generate splat subseg lines + integrate stub list for a multi-block library (section-size-correct boundaries; cookbook §9.6). | | | `tools/make_snd_used.py` | **(Phase 8)** Build the combined libspu+libsnd curated dir (alias dedup by byte-match; 3 address exclusions since S78 #4 — VM_F rejoined via the `.bss` split; §9.6). | -| | `tools/make_apicard_used.py` | **(Phase 8)** Build the combined libapi+libcard curated dir (§9.6). | +| | `tools/make_apicard_used.py` | **(Phase 8; S79 #5)** Build the combined libapi+libcard curated dir `.run/obj42/apicard_used` — libapi **4.2** (`.run/obj42/libapi42`, the EXE's real libapi, incl. FIRST/PAD/PATCH/CHCLRPAD) + libcard 4.0 (§9.6, §490). | | | `tools/ld_interleave.py` | Interleave linker inputs to match the original section ordering. Three forms: `--front/--tail` (the original data->rodata->data sandwich), **`--order`** (P31 S72 — an address-ordered leaf list, needed once a binary owns SEVERAL `.rodata` carves: a `*.data.o` leaf contributes its `(.data)`, a code-object leaf its `(.rodata)`; main's island is a 7-piece sandwich `--front/--tail` cannot express), and **`--pre`** (P31 S74, cookbook §440 — a piece that must land BEFORE the text). `--pre` exists for the **resident**, which opens with `- [0x0, rodata, hdr]`, a 1-word `.rodata` header ahead of its code: every `--order` piece is emitted after TEXT_START, so `hdr.rodata.o(.rodata)` would fall into the unchecked `empties` bucket, be parked after the text, and move every byte in the binary. | | | `tools/jtbl_rodata_pads.py` | **(Phase 29, cookbook §8e)** Post-maspsx filter for multi-table `.rodata` carve spans: REPLACES each cc1 `.align 3` (which is section-relative and would mis-pad a merged/4-mod-8 span) with the ORIGINAL's exact pad bytes per the object's `JTBL_PADS` spec (written by `jtbl_carve` into `config/overlays.mk`; armed via `$(if $(JTBL_PADS),…)` in the Makefile `build/src/%.o` recipe). Fail-loud on table-count drift / non-`.align 3` / non-jtbl rodata content. Unset var ⇒ pipeline byte-identical. | | | `tools/split_src_region.py` | Split a `src/` region file at object boundaries. | @@ -999,7 +999,9 @@ fills fast). Nothing is leaking — but the host does not get the memory back on | `tools/psyq_link.py` / `psyq_link_region.py` / `psyq_integrate.py` | the NOBITS predicate is `^\.s?bss\d*$` (was the literal pair `.bss`/`.sbss`), so split pieces are NOLOAD-placed from their own section symbols; `link_object` links with `--no-check-sections` like the build (piece extents tile the PACKED section, so unreferenced commons overlap other pieces harmlessly) | automatic | | `LIBGPU_ELF := .run/obj40/libgpu` | the `libgpu_used` curated dir is retired (it existed only to exclude SYS.o); `psyq_identify` drops the 8 objects the EXE never links | fresh clone: `tools/psyq_build_libs.sh LIBGPU` is now the whole libgpu step | | `tools/make_libgs.sh` (+GS_001) / `tools/make_snd_used.py` (VM_F rejoined) | curated dirs now carry the two objects the split unlocked: libgs 34 objects / 8 blocks (`libgs8`), sound 63 / 12 (`snd12`) | re-run after `psyq_build_libs.sh` on a fresh clone | -| `tools/psyq/lib42/` + `lib421/` (task #13) | PsyQ RTL 4.2 + the 1998-02-26 libpad 4.2.1 patch (see the archive table above); `.run/obj42/libpad421` (7 placed) + `.run/obj42/libapi42` (39 placed), all byte-identical | task #5 wires them (band + apicard region); regenerate the ELF dirs with `psyq_lib_split.py .run/obj42/` + `psyq-obj-parser` per object | +| `tools/psyq/lib42/` + `lib421/` (task #13) | PsyQ RTL 4.2 + the 1998-02-26 libpad 4.2.1 patch (see the archive table above); `.run/obj42/libpad421` (7 placed) + `.run/obj42/libapi42` (39 placed), all byte-identical | **wired in task #5** (below); fresh clone: `7z x tools/psyq/PlayStation_Programmer_Tool_-_Runtime_Library_Version_4.2.7z -o.run/psyq_hunt/rtl42 && unzip .run/psyq_hunt/rtl42/LIB/42PATCH/J421PD.ZIP -d tools/psyq/lib421`, then for each of `lib421/LIBPAD.LIB`→`.run/obj42/libpad421` and `lib421/LIBAPI.LIB`→`.run/obj42/libapi42`: `python3 tools/psyq_lib_split.py ` and `for o in /*.obj; do tools/psyq/psyq-obj-parser "$o" -o "${o%.obj}.o"; done` | +| Makefile `LIBAPI42_*` / `LIBPAD_*` blocks + `APICARD_ELF := .run/obj42/apicard_used` (task #5) | the band 0x8005CE18–0x8005FC68 = 4 stub rows (`libapi1`, `libpad1`, `libapi2`, `libpad2`) fed by two WINDOWED `psyq_integrate` calls from the raw obj42 dirs; the apicard region = 7 rows (`apicard1..7`, the former `800c2`/`800c2_2`/`800c2_3` game-code rows were FIRST/PAD/PATCH+CHCLRPAD) from `tools/make_apicard_used.py`, which now takes libapi from `.run/obj42/libapi42` (4.2) and libcard from `.run/obj40/libcard` (4.0). `REORDER_TUS` is EMPTY (all four island TUs were Sony objects; the mechanism stays) | automatic in `make build BINARY=main`; the build is byte-identical WITHOUT any of the obj dirs (stub fallback), as always | +| `tools/exclude_audit.py` | LINKED now outranks a pinned `# WALL` (a function in a linked PsyQ subseg is never a target, whatever compiler fact was recorded about it): dropped the four §332 walls + `func_80062144` + `PopMatrix`/`PushMatrix` (libgte3 since Phase 8) | every regeneration of `config/wave_exclude.txt` | **Oracle corrections — re-read any verdict recorded before these:** * `match_one` and `rtu_match` now route the Makefile's `REORDER_TUS` (`800c2 800c2_2 800c2_3 800c3`) diff --git a/docs/accelerators.md b/docs/accelerators.md index 695d4a7ee2..1d8f523f5b 100644 --- a/docs/accelerators.md +++ b/docs/accelerators.md @@ -677,3 +677,12 @@ independent oracle (here the other objects' by-name recoveries agreed on all sev the transformation in the shared prepare path, not in a curated artifact, so it is re-derived from the bytes on every build and negative-controlled over the whole placed population for free. +## S79 (2) — provenance → archive → link → compiler, in that order + +Twelve stubs in one band carried compiler-wall verdicts from three sessions of wall-sweeping. The band was +Sony's controller library; the exact library was a 383 KB archive.org download away; every object linked +byte-identical on the first try. Accelerator: **before any wall verdict on a function in a mixed binary, +ask whose code it is and whether the shipped object exists** — the loader's signature sets name the +library and version for free (§487), and the SDK archives are indexed on archive.org by version. A wall +verdict on code you were never going to compile is correct and worthless. + diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 05032e7355..70e3e29b62 100644 --- a/docs/cookbook-index.md +++ b/docs/cookbook-index.md @@ -2,7 +2,7 @@ > **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section. > -> `docs/matching-cookbook.md` is ~716 KB / 1157 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. +> `docs/matching-cookbook.md` is ~716 KB / 1158 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. **How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win. @@ -1080,7 +1080,7 @@ - **§442** — ★★★ — A RECOVERY RUNG THAT REWRITES A LEGAL CONSTRUCT INTO AN ILLEGAL ONE READS EXACTLY LIKE A CODEGEN WALL (P31 S75; `reconcile_tu`, 344 ins unblocked) L34647 - **§477** — ★★★ — THE `self_decl_tu` CLASS IS A SOLVED, MECHANICAL LANE: 16 DRAFTS, 16 BANKS (P31 S77) L35713 -### build graph, splat & the harness (209) +### build graph, splat & the harness (210) - **§4** — Flag/toolchain gotchas L190 - **Build** — mechanism — per-file opt override (splat resegmentation) L307 @@ -1291,6 +1291,7 @@ - **§487** — ★★★ — THE PSX LOADER'S PER-VERSION SIGNATURE SETS ARE A FREE PROVENANCE ORACLE: main's "WALL" BAND IS LIBPAD 4.2.1 (P31 S78) L36150 - **§488** — ★★ — THE "GAME CODE" GAPS BETWEEN LIBRARY BLOCKS WERE LIBRARY OBJECTS: 13 SUBSEGS → LINKED, EXACT-TILED, ZERO TOKENS (P31 S78) L36202 - **§489** — ★★★ — SCATTERED `.bss` IS A PARTITION PROBLEM: SPLIT THE SECTION INTO PER-BASE PIECES AT LINK-PREPARE (P31 S78 #4; closes the §9.1 exclusion class 3/3) L36242 +- **§490** — ★★★ — THE "WALL" BAND WAS A LIBRARY VERSION AWAY: LIBPAD 4.2.1 + LIBAPI 4.2 FOUND, THE WHOLE 0x8005CE18–0x8005FC68 BAND + THE APICARD REGION LINKED FROM REAL OBJECTS (P31 S79 #13/#5) L36300 ### process, measurement & doctrine (141) @@ -2936,6 +2937,7 @@ - **§487** — ★★★ — THE PSX LOADER'S PER-VERSION SIGNATURE SETS ARE A FREE PROVENANCE ORACLE: main's "WALL" BAND IS LIBPAD 4.2.1 (P31 S78) L36150 - **§488** — ★★ — THE "GAME CODE" GAPS BETWEEN LIBRARY BLOCKS WERE LIBRARY OBJECTS: 13 SUBSEGS → LINKED, EXACT-TILED, ZERO TOKENS (P31 S78) L36202 - **§489** — ★★★ — SCATTERED `.bss` IS A PARTITION PROBLEM: SPLIT THE SECTION INTO PER-BASE PIECES AT LINK-PREPARE (P31 S78 #4; closes the §9.1 exclusion class 3/3) L36242 +- **§490** — ★★★ — THE "WALL" BAND WAS A LIBRARY VERSION AWAY: LIBPAD 4.2.1 + LIBAPI 4.2 FOUND, THE WHOLE 0x8005CE18–0x8005FC68 BAND + THE APICARD REGION LINKED FROM REAL OBJECTS (P31 S79 #13/#5) L36300 --- @@ -4105,3 +4107,4 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: ` | L36150 | §487 | ★★★ — THE PSX LOADER'S PER-VERSION SIGNATURE SETS ARE A FREE PROVENANCE ORACLE: main's "WA | | L36202 | §488 | ★★ — THE "GAME CODE" GAPS BETWEEN LIBRARY BLOCKS WERE LIBRARY OBJECTS: 13 SUBSEGS → LINKED | | L36242 | §489 | ★★★ — SCATTERED `.bss` IS A PARTITION PROBLEM: SPLIT THE SECTION INTO PER-BASE PIECES AT L | +| L36300 | §490 | ★★★ — THE "WALL" BAND WAS A LIBRARY VERSION AWAY: LIBPAD 4.2.1 + LIBAPI 4.2 FOUND, THE WHO | diff --git a/docs/decision-log.md b/docs/decision-log.md index 78517f031b..3a66fd2837 100644 --- a/docs/decision-log.md +++ b/docs/decision-log.md @@ -3141,3 +3141,32 @@ probe's stricter test then ratified one of them as a wall. General form: when a X reproduces it", the next question is "can X be partitioned", and the partition should follow the structure the ORIGINAL producer used (here: symbols), not the structure the measurement happened to group by. + +### S79 addendum 2 (2026-09-04, tasks #13/#5) — the band's twelve "walls" were a library version away; the §332 wall verdicts are closed + +**Belief (S68 → S78).** Twelve of main's open stubs sat in `800c3`/`800c2`, four of them curated as §332 +"%lo-in-a-delay-slot" compiler walls, one as a "no jump table" wall, all excluded from waves as facts about +gcc. S78 named the band (libpad 4.2.1 + libapi 4.2, §487) but expected to finish it as C under the +reorder island because no archive we held could link it; the S78 brief budgeted a bounded hunt (#13) with +three leads and a fallback to C. + +**What happened.** The first lead — archive.org — held a 383 KB 7z of the Runtime Library 4.2 with SCE's +February-1998 libpad 4.2.1 patch inside. Every one of the 46 objects it places in main links byte-identical +(cookbook §490). Task #5 then linked the whole band and the apicard region's C objects (FIRST, PAD, PATCH, +CHCLRPAD) in one pass: four TUs deleted, the `REORDER_TUS` island empty, main byte-identical with and +without the SDK dirs, fleet 213/213. + +**Why the walls were wrong as WORK while right as FACTS.** §332 is a true statement about cc1 + `as -O2` +reorder output: no C source reproduces a `%lo` in a delay slot through our pipeline. But Sony never +compiled that C through our pipeline; they shipped the object. A wall verdict answers "can we match this +function?"; it never asks "is this function ours to match?" — and that provenance question, once asked +(§487), was answered by a 383 KB download. The exclude audit had the same blind spot in code: a pinned +`# WALL` outranked LINKED, so `PopMatrix`/`PushMatrix` sat as walls for eleven sessions while living in +libgte3, linked since Phase 8. Fixed: LINKED dominates. + +**Hindsight.** The order of questions for any stubborn function in a mixed binary is provenance → archive +→ link → (only then) compiler. We ran it backwards for the band: wall_sweep in S68/S77, names in S78, +archive in S79. The §487 sentence — "a wall inside bytes no archive you hold can place is a provenance +question before it is a compiler question" — now has its second half: **and a provenance answer is an +archive to go and find, not a label to match under.** + diff --git a/docs/difficulty.md b/docs/difficulty.md index de57d7bcc4..cb18ecd0ba 100644 --- a/docs/difficulty.md +++ b/docs/difficulty.md @@ -1,9 +1,9 @@ # Unmatched difficulty inventory (generated by tools/difficulty.py — harvest queue) -unmatched functions : 1179 -trivial (<=5 ins) : 238 -non-jtbl leaves : 797 (best harvest targets) -jump-table funcs : 36 (deferred — need the rodata-island workflow, Task 2') +unmatched functions : 1272 +trivial (<=5 ins) : 267 +non-jtbl leaves : 842 (best harvest targets) +jump-table funcs : 58 (deferred — need the rodata-island workflow, Task 2') ## Easiest 120 unmatched (score asc) — the work queue | score | name | nins | br | calls | jtbl | leaf | @@ -56,7 +56,9 @@ jump-table funcs : 36 (deferred — need the rodata-island workflow, Task | 3 | SetDQB | 3 | 0 | 0 | - | Y | | 3 | SetData32 | 3 | 0 | 0 | - | Y | | 3 | SetIR0 | 3 | 0 | 0 | - | Y | +| 3 | SetInitPadFlag | 3 | 0 | 0 | - | Y | | 3 | UT_KEYV_OBJ_174 | 3 | 0 | 0 | - | Y | +| 3 | _padSetAct | 3 | 0 | 0 | - | Y | | 4 | CD_set_test_parmnum | 4 | 0 | 0 | - | Y | | 4 | C_011_OBJ_960 | 4 | 0 | 0 | - | Y | | 4 | CdLastCom | 4 | 0 | 0 | - | Y | @@ -71,6 +73,7 @@ jump-table funcs : 36 (deferred — need the rodata-island workflow, Task | 4 | LIBMCRD_OBJ_84C | 4 | 0 | 0 | - | Y | | 4 | LIBMCRD_OBJ_A5C | 4 | 0 | 0 | - | Y | | 4 | MIDIREAD_OBJ_6AC | 4 | 0 | 0 | - | Y | +| 4 | ReadInitPadFlag | 4 | 0 | 0 | - | Y | | 4 | SPU_OBJ_510 | 4 | 0 | 0 | - | Y | | 4 | SPU_OBJ_AC4 | 4 | 0 | 0 | - | Y | | 4 | SSSTART_OBJ_240 | 2 | 0 | 1 | - | - | @@ -92,6 +95,7 @@ jump-table funcs : 36 (deferred — need the rodata-island workflow, Task | 4 | UT_KEYV_OBJ_3FC | 4 | 0 | 0 | - | Y | | 4 | VSYNC_OBJ_1D4 | 4 | 0 | 0 | - | Y | | 4 | VS_VH_OBJ_180 | 4 | 0 | 0 | - | Y | +| 4 | _padSetCmd | 4 | 0 | 0 | - | Y | | 4 | func_800426D4 | 4 | 0 | 0 | - | Y | | 4 | func_80043078 | 4 | 0 | 0 | - | Y | | 4 | func_80043410 | 4 | 0 | 0 | - | Y | @@ -100,6 +104,9 @@ jump-table funcs : 36 (deferred — need the rodata-island workflow, Task | 4 | func_800491EC | 4 | 0 | 0 | - | Y | | 4 | func_8004923C | 4 | 0 | 0 | - | Y | | 4 | func_8005C4CC | 4 | 0 | 0 | - | Y | +| 4 | func_8005CF08 | 4 | 0 | 0 | - | Y | +| 4 | func_8005CF18 | 4 | 0 | 0 | - | Y | +| 4 | func_8005F384 | 4 | 0 | 0 | - | Y | | 4 | func_80062988 | 4 | 0 | 0 | - | Y | | 4 | gfx2D_COM0_OBJ_30 | 4 | 0 | 0 | - | Y | | 5 | C_004_OBJ_DC | 5 | 0 | 0 | - | Y | @@ -121,10 +128,3 @@ jump-table funcs : 36 (deferred — need the rodata-island workflow, Task | 5 | PRNT_OBJ_1E8 | 2 | 1 | 0 | - | Y | | 5 | PRNT_OBJ_1F0 | 2 | 1 | 0 | - | Y | | 5 | PRNT_OBJ_1F8 | 2 | 1 | 0 | - | Y | -| 5 | PRNT_OBJ_340 | 2 | 1 | 0 | - | Y | -| 5 | PRNT_OBJ_64C | 2 | 1 | 0 | - | Y | -| 5 | PRNT_OBJ_C8 | 2 | 1 | 0 | - | Y | -| 5 | PRNT_OBJ_EC | 2 | 1 | 0 | - | Y | -| 5 | PRNT_OBJ_F4 | 2 | 1 | 0 | - | Y | -| 5 | RATAN_OBJ_148 | 5 | 0 | 0 | - | Y | -| 5 | SPU_OBJ_848 | 5 | 0 | 0 | - | Y | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index c7337a25fc..6592d9e8b7 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -36297,3 +36297,49 @@ retired (`LIBGPU_ELF` = the raw dir; identify drops the 8 objects the EXE never with and without the SDK objects. The class that remains in the sound region — `S_R`/`S_W`, `S_GRMDT*` — has NO `.bss` of its own (cross-object commons at a minority address): a different wall, not this one. +#### §490 ★★★ — THE "WALL" BAND WAS A LIBRARY VERSION AWAY: LIBPAD 4.2.1 + LIBAPI 4.2 FOUND, THE WHOLE 0x8005CE18–0x8005FC68 BAND + THE APICARD REGION LINKED FROM REAL OBJECTS (P31 S79 #13/#5) + +**Where §487 left it.** The psx loader's per-version signature sets named the band (libpad 4.2.1 + libapi +4.2) but no archive we held could LINK it: 4.0 has no libpad, 4.6/4.7 differ, and the loader's own 4.2 +signatures showed PADMAIN drifting +4/+12. The plan was "C under the reorder island with real names" and +twelve stubs — the four §332 "%lo-in-a-delay-slot walls" among them — sat in `config/wave_exclude.txt` as +curated compiler facts. + +**The hunt took one lead.** archive.org's `play-station-programmer-tool-runtime-library-version-4.2.7z` +(383 KB) is the PsyQ Runtime Library 4.2 (1998-01-21) plus `LIB/42PATCH/J421PD.ZIP`: SCE R&D's 1998-02-26 +notice "Libpad.lib version 4.2.1 for the Analog Controller (DUAL SHOCK)" with LIBPAD.LIB 4.2.1, LIBAPI.LIB +4.2 and their headers. Converted with `psyq_lib_split.py` + `psyq-obj-parser`, `psyq_identify` places +libpad 4.2.1 7/11 and libapi 4.2 39/88 over 0x8005CE18–0x800629DC, and `psyq_link.py` PASSES all 46 — +PADMAIN at 760 ins exactly. Neighbours for the record: plain libpad 4.2 (the loader's signature source) and +the 4.3 disc (DTL-S2340, 1998-05-18: PADMAIN 832, PADIF 380, PADSEQD 292) each place only 4. 4.2.1 is the +unique exact match, which also dates the build to between February and May 1998. + +**The wiring is §488's procedure, twice.** The band is ONE contiguous run of 33 interleaved objects +(21 libapi trampolines · COUNTER · PADENTRY · PADMAIN · L02/L03 · PADCMD · PADIF · PADPORTD · PADSEQD · +WAITRC2) and every yaml-relevant boundary sits on an object edge (checked against `.text` SECTION sizes — +§9.6's align-pad gotcha). Because `psyq_integrate` tiles each stub with ONE library's objects, `800c3` +became four rows — `libapi1`, `libpad1`, `libapi2`, `libpad2` — fed by two windowed calls from the RAW +dirs (`.run/obj42/libapi42` 0x8005CE18..0x8005E188, `.run/obj42/libpad421` 0x8005D0D8..0x8005FC68). The +apicard region's three "game code" rows were libapi 4.2's C objects to the byte — `800c2` = FIRST.o +(`firstfile` + the "wall" stub `func_80062144`), `800c2_2` = PAD.o, `800c2_3` = PATCH.o+CHCLRPAD.o — so +they became `apicard5/6/7`, `make_apicard_used.py` now sources libapi from 4.2 (the EXE's real libapi; +libcard stays 4.0, byte-identical) and the region tiles 0x80061F38–0x80062888 with no game code left. +Four TUs deleted (`800c3.c`: 129 hand-matched "C" + 62 verbatim bodies + 19 stubs; the three `800c2*`), +and the `REORDER_TUS` island (§332b) is EMPTY — the variable stays for any future reorder-assembled TU. +main `143dbb89` with all SDK dirs and, from a fresh extract, with none. + +**What the four "walls" were.** `_padInitSioMode`, `_padStartCom`, `func_8005ED4C`, `func_8005F450` +(§332 "%lo in a delay slot — no C can place it") were TRUE as compiler facts and irrelevant as work: Sony +assembled libpad in reorder mode and shipped the object. The same for `func_80062144` ("no jump table") +inside FIRST.o and for `PopMatrix`/`PushMatrix`, which had sat in the exclude list since S68 while living +in libgte3 — LINKED since Phase 8. The exclude audit kept all seven because its pinned-WALL class was +decided BEFORE its LINKED class; fixed S79 (LINKED dominates: a function that is not a target has no +wall). Law: **a wall verdict is a statement about a compiler and a function; whether the function is +OURS to match is a provenance question that precedes it** (§487 → §490: name the band, find the archive, +link it — in that order, before any C). + +**Fresh clone.** `tools/psyq/PlayStation_Programmer_Tool_-_Runtime_Library_Version_4.2.7z` is tracked; +`7z x` it, `psyq_lib_split.py` + `psyq-obj-parser` the two lib421 LIBs into `.run/obj42/{libpad421,libapi42}`, +`tools/psyq_build_libs.sh LIBCARD`, `tools/make_apicard_used.py` — docs/SETUP.md carries the exact commands. +The build is byte-identical without any of it (the seven stub TUs), as always. + diff --git a/docs/progress.fleet.md b/docs/progress.fleet.md index 2eeaf485ae..03165e9e16 100644 --- a/docs/progress.fleet.md +++ b/docs/progress.fleet.md @@ -4,21 +4,21 @@ # cross-binary collapsible-byte leverage: docs/duplicates.cross.md. # THREE progress metrics (all matter — see the labels): -FLEET fn-count byte-ident: 363105 / 363156 = 99.99% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) -FLEET instr-weighted : 13481631 / 13489225 = 99.9% (shipped .text across main + resident + 211 overlays; the decomp.dev-DISPLAY number) -FLEET distinct-code(uniq): 5809877 / 5817332 = 99.9% (90909/90929 unique fns; the DISTINCT-RE number) -MAIN game-code weighted : 40895 / 44870 = 91.1% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-08-05; boundaries INDEPENDENTLY VERIFIED since P31 S77 — `make sig-main-oracle` + `make audit-corpus`: 0 phantom, 0 truncated, 1 explained pad-tail) +FLEET fn-count byte-ident: 363119 / 363157 = 99.99% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) +FLEET instr-weighted : 13479484 / 13485889 = 100.0% (shipped .text across main + resident + 211 overlays; the decomp.dev-DISPLAY number) +FLEET distinct-code(uniq): 5807730 / 5813996 = 99.9% (90909/90929 unique fns; the DISTINCT-RE number) +MAIN game-code weighted : 38748 / 41534 = 93.3% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-08-05; boundaries INDEPENDENTLY VERIFIED since P31 S77 — `make sig-main-oracle` + `make audit-corpus`: 0 phantom, 0 truncated, 1 explained pad-tail) (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 13440736 / 13444355 = 100.0%) -FLEET REAL substantive : 360708 (of which dedup-shared 255632 via 2220 groups / 255708 instances) -FLEET LINKED PsyQ objs : 1150 +FLEET REAL substantive : 360642 (of which dedup-shared 255632 via 2220 groups / 255708 instances) +FLEET LINKED PsyQ objs : 1256 FLEET NON_MATCHING : 0 (0 in any default build — G4) -FLEET INCLUDE_ASM stubs : 51 -FLEET matchable : 363156 +FLEET INCLUDE_ASM stubs : 38 +FLEET matchable : 363157 | binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % | |---|---:|---:|---:|---:|---:|---:| -| main | 839 | 2 | 1150 | 2061 | 2090 | 98.6% | +| main | 773 | 2 | 1256 | 2075 | 2091 | 99.2% | | resident | 141 | 0 | 0 | 143 | 145 | 98.6% | | md_MAIN_001 | 11 | 0 | 0 | 11 | 11 | 100.0% | | md_MAIN_003 | 53 | 0 | 0 | 59 | 64 | 92.2% | diff --git a/docs/progress.md b/docs/progress.md index 96806c3c82..5f07198aea 100644 --- a/docs/progress.md +++ b/docs/progress.md @@ -1,20 +1,20 @@ # BFM matching progress (generated by tools/progress.py — authoritative) -REAL substantive matches : 839 <- the Gen1-exit >=25 bar counts THIS +REAL substantive matches : 773 <- the Gen1-exit >=25 bar counts THIS (of which dedup-shared : 2 one body -> N sites, config/dedup.us.yaml) -LINKED real PsyQ objects : 1150 <- byte-identical via linked SDK objects -VERBATIM __asm__ bodies : 29 <- §265: BYTES, NOT A DECOMPILE (byte-identical by construction, unexplained; NOT counted in REAL) +LINKED real PsyQ objects : 1256 <- byte-identical via linked SDK objects +VERBATIM __asm__ bodies : 3 <- §265: BYTES, NOT A DECOMPILE (byte-identical by construction, unexplained; NOT counted in REAL) NON_MATCHING (near-miss) : 0 splat-auto empty no-ops : 43 -INCLUDE_ASM stubs : 29 -data blobs (excluded) : 1 +INCLUDE_ASM stubs : 16 +data blobs (excluded) : 2 ---------------------------------------- -matchable functions : 2090 -REAL / matchable : 839 / 2090 = 40.14% -byte-identical/ matchable: 2061 / 2090 = 98.61% (REAL+LINKED+empties+VERBATIM) +matchable functions : 2091 +REAL / matchable : 773 / 2091 = 36.97% +byte-identical/ matchable: 2075 / 2091 = 99.23% (REAL+LINKED+empties+VERBATIM) -LINKED subsegs: apicard1 apicard2 apicard3 apicard4 libc2_1 libc2_2 libcd1 libcd2 libetc libgpu libgpu2 libgs1 libgs2 libgs3 libgs4 libgs5 libgs6 libgs7 libgs8 libgte1 libgte10 libgte11 libgte12 libgte13 libgte14 libgte15 libgte16 libgte17 libgte18 libgte19 libgte2 libgte20 libgte21 libgte22 libgte23 libgte24 libgte25 libgte26 libgte27 libgte28 libgte29 libgte3 libgte30 libgte4 libgte5 libgte6 libgte7 libgte8 libgte9 libmcrd1 libmcrd2 snd1 snd10 snd11 snd12 snd2 snd3 snd4 snd5 snd6 snd7 snd8 snd9 (1150 fns) -REAL matches: CdQueueBusy CdReadRequest CdReadSectorReadyCB CdReadStateMachine DebugMenuHandler DsDataCallback DsReadyCallback DsSyncCallback GameModeDispatch GetRCnt GsTMDfastF3GL GsTMDfastF3GNL GsTMDfastF4GL GsTMDfastF4GNL GsTMDfastG3GL GsTMDfastG3GNL GsTMDfastG4GL GsTMDfastG4GNL InitPAD LoaderInitFileTable LoaderResetReadState LzssDecodeSector PAD_init PadChkMtap PadChkVsync PadEnableCom PadGetState PadInfoComb PadInfoMode PadSetAct PadSetActAlign PadSetMainMode PadStartCom PadStopCom ReadInitPadFlag ResetRCnt ResourceGetCdLoc ResourceLoadStateMachine SetRCnt SpuWrite SsGetMute SsUtReverbOff StartPAD StartRCnt StopPAD StopRCnt StreamLoadStateMachine _SsSndPlay _padClrIntSio0 _padCmdParaMode _padGetActSize _padLoadActInfo _padRecvAtLoadInfo _padSendAtLoadInfo _padSetAct _padSetActAlign _padSetCmd _padSetVsyncParam _padSioRW _padSioRW2 _padStopCom _padWaitRXready aF800301A4 chkRC2wait firstfile func_8001096C func_8001099C func_80010A08 func_80010A98 func_80010AE0 func_80010B10 func_80010BB4 func_80010C7C func_80010CEC func_80010D60 func_80010DA0 func_80010DE0 func_80010E14 func_80010E48 func_80010E7C func_80010ED4 func_80010F80 func_800110CC func_800111BC func_80011220 func_8001125C func_800112C8 func_80011320 func_80011350 func_80011680 func_800116E0 func_80011778 func_80011818 func_800118AC func_80011928 func_80011998 func_800119F0 func_80011A3C func_80011ADC func_80011B7C func_80011C10 func_80011C8C func_80011CFC func_80011D54 func_80011DA0 func_80011DCC func_80011DF4 func_80011E24 func_80011E84 func_80011EB4 func_800120DC func_8001212C func_800123F0 func_80012558 func_800126C4 func_8001282C func_800128B4 func_800128EC func_800129CC func_80012A60 func_80012AB0 func_80012ABC func_80012B04 func_80012B58 func_80012C6C func_80012CB8 func_80012D0C func_80012DBC func_80012E0C func_80012E6C func_80012F74 func_80012FC8 func_80013028 func_800130D0 func_8001311C func_80013154 func_80013200 func_80013228 func_80013294 func_800132BC func_80013328 func_80013350 func_800133BC func_800133E4 func_80013450 func_80013478 func_800134FC func_80013694 func_8001382C func_800139C8 func_80013B64 func_80013CFC func_80013E94 func_80013ED0 func_80013F3C func_80013F68 func_80013F98 func_80013FBC func_80013FE0 func_80014004 func_80014028 func_8001404C func_80014070 func_80014094 func_800140B8 func_80014128 func_80014148 func_80014168 func_800141AC func_800141F0 func_80014238 func_800142C8 func_80014338 func_80014390 func_800143AC func_80014444 func_800144D4 func_80014564 func_80014588 func_800145EC func_800146B0 func_80014774 func_800147B8 func_80014928 func_80014960 func_80014998 func_800149E0 func_80014B10 func_80014BFC func_80014C28 func_80014C54 func_80014CAC func_80014CF8 func_80014D30 func_80014D68 func_80014D94 func_80014DC0 func_80014DEC func_80014E24 func_80014E80 func_80014ED4 func_80015018 func_80015118 func_80015144 func_80015208 func_800152F4 func_80015310 func_8001534C func_800153A4 func_800153CC func_80015424 func_8001544C func_80015498 func_80015908 func_80015954 func_80015978 func_8001599C func_800159C0 func_800159E4 func_80015A08 func_80015A2C func_80015A50 func_80015A74 func_80015AD0 func_80015D4C func_80015F04 func_80016110 func_80016224 func_80016450 func_80016638 func_800166E8 func_80016714 func_800167B8 func_800167F0 func_800168B4 func_800168C4 func_80016940 func_80016978 func_80016A3C func_80016A5C func_80016A7C func_80016B60 func_80016C28 func_80016D78 func_80016EB0 func_80016ED4 func_80016EF8 func_80016F18 func_80017168 func_80017254 func_80017274 func_80017294 func_8001739C func_800173BC func_800173DC func_800174DC func_800174FC func_8001751C func_800176F0 func_80017714 func_80017738 func_80017758 func_80017778 func_800178C8 func_800178EC func_80017910 func_80017930 func_80017B98 func_80017D98 func_80017DC4 func_80017DF8 func_80017E30 func_80017E68 func_80017E8C func_80017F14 func_80018094 func_80018194 func_8001820C func_80018384 func_800183E0 func_80018450 func_800184F0 func_80018918 func_800189A8 func_80018A20 func_80018C64 func_80018CE8 func_80018E78 func_80018E9C func_80018F20 func_80018F88 func_80018FC8 func_80019018 func_80019028 func_8001903C func_80019064 func_800190AC func_80019198 func_800191A8 func_800191BC func_800191D4 func_8001923C func_8001931C func_80019378 func_80019388 func_80019398 func_800193A8 func_800193B8 func_80019930 func_80019A10 func_8001A0FC func_8001A114 func_8001A9D8 func_8001A9F8 func_8001AA78 func_8001AA88 func_8001AAA0 func_8001AAD0 func_8001ABBC func_8001ACF0 func_8001AE90 func_8001AF04 func_8001AF34 func_8001B0D4 func_8001B22C func_8001B23C func_8001B26C func_8001B324 func_8001B34C func_8001B374 func_8001B384 func_8001B394 func_8001B710 func_8001B7C4 func_8001B85C func_8001B86C func_8001BA84 func_8001BADC func_8001BB60 func_8001BBBC func_8001BDA0 func_8001BE20 func_8001BE30 func_8001BFA0 func_8001BFB0 func_8001BFD0 func_8001BFE8 func_8001BFF8 func_8001C00C func_8001C044 func_8001C0C8 func_8001C14C func_8001C1E4 func_8001C214 func_8001C2C4 func_8001C320 func_8001C448 func_8001C4A4 func_8001C558 func_8001C5B8 func_8001C6E4 func_8001C744 func_8001C7B0 func_8001C810 func_8001C8C4 func_8001C924 func_8001C97C func_8001C9D0 func_8001CA1C func_8001CA88 func_8001CB00 func_8001CB6C func_8001CBDC func_8001CC3C func_8001CCA0 func_8001CD04 func_8001CD50 func_8001CD9C func_8001CDE8 func_8001CE28 func_8001CE68 func_8001CEC0 func_8001CF00 func_8001CF30 func_8001CF48 func_8001CFB8 func_8001CFDC_impl func_8001D050 func_8001D074_impl func_8001D0E8 func_8001D0F4 func_8001D130 func_8001D150 func_8001D16C func_8001D1C4 func_8001D388 func_8001D3FC func_8001D70C func_8001D8C4 func_8001DA34 func_8001E094 func_8001E378 func_8001E668 func_8001E7E0 func_8001EA14 func_8001F730 func_8001F97C func_8001F9F8 func_8001FB8C func_8001FC08 func_80020248 func_80020598 func_80020A28 func_80020F34 func_80021008 func_80021050 func_8002109C func_80021120 func_80021174 func_80021284 func_800215F4 func_80021D38 func_800221A8 func_800226C0 func_80023138 func_800233CC func_800234E4 func_80023570 func_8002374C func_80024054 func_800241C0 func_800242D0 func_800243EC func_80024448 func_800249F0 func_80024BC0 func_80024DE8 func_80025000 func_8002528C func_80025504 func_80025818 func_80025A30 func_80025CBC func_80025EB8 func_80026128 func_800262D8 func_80026514 func_800268D0 func_80026D64 func_80027058 func_80027200 func_800273F4 func_800275BC func_800277DC func_800279AC func_80027BF0 func_80027C10 func_80027D20 func_80027F4C func_80028200 func_8002823C func_80028304 func_80028394 func_80028428 func_80028488 func_80028558 func_800285CC func_80028620 func_80028694 func_80028A48 func_80028C50 func_80028D58 func_80028D78 func_80028D9C func_80028DBC func_80028DE0 func_80028E00 func_80028E24 func_80028E44 func_80028E68 func_80028E88 func_80028EAC func_80028ECC func_80028EF0 func_80028F10 func_80028F34 func_80028F54 func_80028F78 func_80028F98 func_80028FBC func_80028FDC func_80029000 func_80029020 func_80029044 func_8002906C func_80029094 func_800290BC func_800290E0 func_80029104 func_80029124 func_80029178 func_800291A0 func_800291B4 func_800291C8 func_800291DC func_800291F0 func_80029204 func_80029218 func_80029240 func_80029254 func_80029264 func_80029274 func_8002931C func_80029344 func_8002941C func_80029444 func_80029504 func_80029514 func_80029524 func_8002953C func_8002954C func_8002955C func_8002957C func_8002958C func_8002959C func_800295D4 func_80029664 func_80029690 func_800296F8 func_80029774 func_800298BC func_8002992C func_80029A58 func_80029A94 func_80029AAC func_80029AF4 func_80029B4C func_80029BC8 func_80029C44 func_80029CD4 func_80029D3C func_80029DB4 func_80029E30 func_80029E94 func_80029EC0 func_80029ED4 func_80029FD4 func_80029FE4 func_8002A04C func_8002A088 func_8002A108 func_8002A1B4 func_8002A200 func_8002A234 func_8002A26C func_8002A27C func_8002A28C func_8002A2B0 func_8002A2D4 func_8002A354 func_8002A400 func_8002A44C func_8002A480 func_8002A4B8 func_8002A4C8 func_8002A4D8 func_8002A4FC func_8002A520 func_8002A544 func_8002A5C4 func_8002A670 func_8002A6BC func_8002A6F0 func_8002A728 func_8002A738 func_8002A748 func_8002A76C func_8002A790 func_8002A7B4 func_8002A834 func_8002A8E0 func_8002A92C func_8002A960 func_8002A998 func_8002A9A8 func_8002A9B8 func_8002A9DC func_8002AA00 func_8002AA3C func_8002AAB4 func_8002AB64 func_8002AC00 func_8002AE60 func_8002AED0 func_8002AEE4 func_8002AEF8 func_8002AF08 func_8002AF18 func_8002AF48 func_8002AF60 func_8002AF70 func_8002B00C func_8002B064 func_8002B08C func_8002B0B4 func_8002C320 func_8002C3B0 func_8002C410 func_8002C8BC func_8002C8F4 func_8002CC4C func_8002CCB4 func_8002CCD8 func_8002CDD8 func_8002CFE4 func_8002D034 func_8002D1F0 func_8002D240 func_8002D29C func_8002D320 func_8002D4B8 func_8002D4C8 func_8002D59C func_8002D678 func_8002D6D8 func_8002D7FC func_8002D80C func_8002D834 func_8002D844 func_8002D858 func_8002D8A8 func_8002D8D4 func_8002D904 func_8002DC68 func_8002DF80 func_8002E138 func_8002E5BC func_8002E5F8 func_8002E638 func_8002E700 func_8002E79C func_8002E818 func_8002E8DC func_8002E94C func_8002EA10 func_8002EAB0 func_8002EB10 func_8002EBAC func_8002EC10 func_8002ED90 func_8002EDE4 func_8002EE64 func_8002EE90 func_8002EEB8 func_8002EED8 func_8002EFD0 func_8002EFF8 func_8002F064 func_8002F0D0 func_8002F0F4 func_8002F12C func_8002F150 func_8002F1CC func_8002F248 func_8002F4E4 func_8002F5C8 func_8002F620 func_8002F648 func_8002F658 func_8002F67C func_8002F714 func_8002F80C func_8002FA3C func_8002FAE0 func_8002FB08 func_8002FC64 func_8002FD14 func_8002FDC8 func_8002FF0C func_800301C8 func_80030470 func_800304C8 func_80030538 func_80030634 func_80030730 func_80030A14 func_80030CA4 func_80030D80 func_80030F80 func_800314DC func_800316F8 func_80031988 func_80031A98 func_80031B7C func_80031BE0 func_80031CC8 func_80031D70 func_80031DEC func_80031E94 func_80031F14 func_80031FC8 func_80032048 func_800322A8 func_800324A4 func_80032774 func_8003310C func_800331D4 func_8003324C func_80033324 func_80033398 func_8003350C func_800335B8 func_800336A8 func_8003388C func_800342E8 func_80034314 func_80034650 func_800346D0 func_800347C8 func_80034844 func_800348A8 func_8003491C func_80034A54 func_80034A9C func_80034AE0 func_80034B0C func_80034B3C func_80034C24 func_80034CF0 func_80034DFC func_8003500C func_800351E8 func_80035210 func_80035270 func_800359B0 func_80035C4C func_8003602C func_80036130 func_800361CC func_8003621C func_80036260 func_80036AF8 func_80036D24 func_80036D58 func_80036EB4 func_80036EE8 func_80036F18 func_80036F98 func_80036FB0 func_80037004 func_80037028 func_80037144 func_80037334 func_80037358 func_80037368 func_800373D0 func_800374CC func_8003750C func_8003775C func_800377D8 func_80037CC8 func_80037CD8 func_80037D74 func_80037D98 func_80037EA0 func_80037F3C func_80037FC4 func_8003819C func_800381E4 func_80038210 func_80038308 func_8003834C func_8003836C func_800383A4 func_800384A8 func_800385C0 func_80038638 func_80038668 func_800387C0 func_80038838 func_800388E8 func_80038908 func_80038958 func_80038A00 func_80038A58 func_80038FC4 func_80038FFC func_8003916C func_80039C5C func_80039C70 func_80039F14 func_80039F50 func_8003A098 func_8003A0D0 func_8003A0E4 func_8003A234 func_8003A3D8 func_8003A404 func_8003A424 func_8003D424 func_8003D630 func_8003DC90 func_8003DF8C func_8003FA54 func_80040DE8 func_80041354 func_800413B8 func_80041400 func_80041448 func_8005CF08 func_8005CF18 func_8005D6CC func_8005DBD8 func_8005E480 func_8005E528 func_8005E804 func_8005E820 func_8005E980 func_8005E9D4 func_8005EA54 func_8005EA68 func_8005EA88 func_8005EAA8 func_8005EAC8 func_8005EAE8 func_8005EB28 func_8005EC00 func_8005F228 func_8005F384 func_8005F394 func_8005F6CC func_8005F704 func_8005F75C func_8005FB70 func_8006252C func_800625A4 func_800625DC func_80062644 main +LINKED subsegs: apicard1 apicard2 apicard3 apicard4 apicard5 apicard6 apicard7 libapi1 libapi2 libc2_1 libc2_2 libcd1 libcd2 libetc libgpu libgpu2 libgs1 libgs2 libgs3 libgs4 libgs5 libgs6 libgs7 libgs8 libgte1 libgte10 libgte11 libgte12 libgte13 libgte14 libgte15 libgte16 libgte17 libgte18 libgte19 libgte2 libgte20 libgte21 libgte22 libgte23 libgte24 libgte25 libgte26 libgte27 libgte28 libgte29 libgte3 libgte30 libgte4 libgte5 libgte6 libgte7 libgte8 libgte9 libmcrd1 libmcrd2 libpad1 libpad2 snd1 snd10 snd11 snd12 snd2 snd3 snd4 snd5 snd6 snd7 snd8 snd9 (1256 fns) +REAL matches: CdQueueBusy CdReadRequest CdReadSectorReadyCB CdReadStateMachine DebugMenuHandler DsDataCallback DsReadyCallback DsSyncCallback GameModeDispatch GsTMDfastF3GL GsTMDfastF3GNL GsTMDfastF4GL GsTMDfastF4GNL GsTMDfastG3GL GsTMDfastG3GNL GsTMDfastG4GL GsTMDfastG4GNL LoaderInitFileTable LoaderResetReadState LzssDecodeSector ResourceGetCdLoc ResourceLoadStateMachine SpuWrite SsGetMute SsUtReverbOff StreamLoadStateMachine _SsSndPlay aF800301A4 func_8001096C func_8001099C func_80010A08 func_80010A98 func_80010AE0 func_80010B10 func_80010BB4 func_80010C7C func_80010CEC func_80010D60 func_80010DA0 func_80010DE0 func_80010E14 func_80010E48 func_80010E7C func_80010ED4 func_80010F80 func_800110CC func_800111BC func_80011220 func_8001125C func_800112C8 func_80011320 func_80011350 func_80011680 func_800116E0 func_80011778 func_80011818 func_800118AC func_80011928 func_80011998 func_800119F0 func_80011A3C func_80011ADC func_80011B7C func_80011C10 func_80011C8C func_80011CFC func_80011D54 func_80011DA0 func_80011DCC func_80011DF4 func_80011E24 func_80011E84 func_80011EB4 func_800120DC func_8001212C func_800123F0 func_80012558 func_800126C4 func_8001282C func_800128B4 func_800128EC func_800129CC func_80012A60 func_80012AB0 func_80012ABC func_80012B04 func_80012B58 func_80012C6C func_80012CB8 func_80012D0C func_80012DBC func_80012E0C func_80012E6C func_80012F74 func_80012FC8 func_80013028 func_800130D0 func_8001311C func_80013154 func_80013200 func_80013228 func_80013294 func_800132BC func_80013328 func_80013350 func_800133BC func_800133E4 func_80013450 func_80013478 func_800134FC func_80013694 func_8001382C func_800139C8 func_80013B64 func_80013CFC func_80013E94 func_80013ED0 func_80013F3C func_80013F68 func_80013F98 func_80013FBC func_80013FE0 func_80014004 func_80014028 func_8001404C func_80014070 func_80014094 func_800140B8 func_80014128 func_80014148 func_80014168 func_800141AC func_800141F0 func_80014238 func_800142C8 func_80014338 func_80014390 func_800143AC func_80014444 func_800144D4 func_80014564 func_80014588 func_800145EC func_800146B0 func_80014774 func_800147B8 func_80014928 func_80014960 func_80014998 func_800149E0 func_80014B10 func_80014BFC func_80014C28 func_80014C54 func_80014CAC func_80014CF8 func_80014D30 func_80014D68 func_80014D94 func_80014DC0 func_80014DEC func_80014E24 func_80014E80 func_80014ED4 func_80015018 func_80015118 func_80015144 func_80015208 func_800152F4 func_80015310 func_8001534C func_800153A4 func_800153CC func_80015424 func_8001544C func_80015498 func_80015908 func_80015954 func_80015978 func_8001599C func_800159C0 func_800159E4 func_80015A08 func_80015A2C func_80015A50 func_80015A74 func_80015AD0 func_80015D4C func_80015F04 func_80016110 func_80016224 func_80016450 func_80016638 func_800166E8 func_80016714 func_800167B8 func_800167F0 func_800168B4 func_800168C4 func_80016940 func_80016978 func_80016A3C func_80016A5C func_80016A7C func_80016B60 func_80016C28 func_80016D78 func_80016EB0 func_80016ED4 func_80016EF8 func_80016F18 func_80017168 func_80017254 func_80017274 func_80017294 func_8001739C func_800173BC func_800173DC func_800174DC func_800174FC func_8001751C func_800176F0 func_80017714 func_80017738 func_80017758 func_80017778 func_800178C8 func_800178EC func_80017910 func_80017930 func_80017B98 func_80017D98 func_80017DC4 func_80017DF8 func_80017E30 func_80017E68 func_80017E8C func_80017F14 func_80018094 func_80018194 func_8001820C func_80018384 func_800183E0 func_80018450 func_800184F0 func_80018918 func_800189A8 func_80018A20 func_80018C64 func_80018CE8 func_80018E78 func_80018E9C func_80018F20 func_80018F88 func_80018FC8 func_80019018 func_80019028 func_8001903C func_80019064 func_800190AC func_80019198 func_800191A8 func_800191BC func_800191D4 func_8001923C func_8001931C func_80019378 func_80019388 func_80019398 func_800193A8 func_800193B8 func_80019930 func_80019A10 func_8001A0FC func_8001A114 func_8001A9D8 func_8001A9F8 func_8001AA78 func_8001AA88 func_8001AAA0 func_8001AAD0 func_8001ABBC func_8001ACF0 func_8001AE90 func_8001AF04 func_8001AF34 func_8001B0D4 func_8001B22C func_8001B23C func_8001B26C func_8001B324 func_8001B34C func_8001B374 func_8001B384 func_8001B394 func_8001B710 func_8001B7C4 func_8001B85C func_8001B86C func_8001BA84 func_8001BADC func_8001BB60 func_8001BBBC func_8001BDA0 func_8001BE20 func_8001BE30 func_8001BFA0 func_8001BFB0 func_8001BFD0 func_8001BFE8 func_8001BFF8 func_8001C00C func_8001C044 func_8001C0C8 func_8001C14C func_8001C1E4 func_8001C214 func_8001C2C4 func_8001C320 func_8001C448 func_8001C4A4 func_8001C558 func_8001C5B8 func_8001C6E4 func_8001C744 func_8001C7B0 func_8001C810 func_8001C8C4 func_8001C924 func_8001C97C func_8001C9D0 func_8001CA1C func_8001CA88 func_8001CB00 func_8001CB6C func_8001CBDC func_8001CC3C func_8001CCA0 func_8001CD04 func_8001CD50 func_8001CD9C func_8001CDE8 func_8001CE28 func_8001CE68 func_8001CEC0 func_8001CF00 func_8001CF30 func_8001CF48 func_8001CFB8 func_8001CFDC_impl func_8001D050 func_8001D074_impl func_8001D0E8 func_8001D0F4 func_8001D130 func_8001D150 func_8001D16C func_8001D1C4 func_8001D388 func_8001D3FC func_8001D70C func_8001D8C4 func_8001DA34 func_8001E094 func_8001E378 func_8001E668 func_8001E7E0 func_8001EA14 func_8001F730 func_8001F97C func_8001F9F8 func_8001FB8C func_8001FC08 func_80020248 func_80020598 func_80020A28 func_80020F34 func_80021008 func_80021050 func_8002109C func_80021120 func_80021174 func_80021284 func_800215F4 func_80021D38 func_800221A8 func_800226C0 func_80023138 func_800233CC func_800234E4 func_80023570 func_8002374C func_80024054 func_800241C0 func_800242D0 func_800243EC func_80024448 func_800249F0 func_80024BC0 func_80024DE8 func_80025000 func_8002528C func_80025504 func_80025818 func_80025A30 func_80025CBC func_80025EB8 func_80026128 func_800262D8 func_80026514 func_800268D0 func_80026D64 func_80027058 func_80027200 func_800273F4 func_800275BC func_800277DC func_800279AC func_80027BF0 func_80027C10 func_80027D20 func_80027F4C func_80028200 func_8002823C func_80028304 func_80028394 func_80028428 func_80028488 func_80028558 func_800285CC func_80028620 func_80028694 func_80028A48 func_80028C50 func_80028D58 func_80028D78 func_80028D9C func_80028DBC func_80028DE0 func_80028E00 func_80028E24 func_80028E44 func_80028E68 func_80028E88 func_80028EAC func_80028ECC func_80028EF0 func_80028F10 func_80028F34 func_80028F54 func_80028F78 func_80028F98 func_80028FBC func_80028FDC func_80029000 func_80029020 func_80029044 func_8002906C func_80029094 func_800290BC func_800290E0 func_80029104 func_80029124 func_80029178 func_800291A0 func_800291B4 func_800291C8 func_800291DC func_800291F0 func_80029204 func_80029218 func_80029240 func_80029254 func_80029264 func_80029274 func_8002931C func_80029344 func_8002941C func_80029444 func_80029504 func_80029514 func_80029524 func_8002953C func_8002954C func_8002955C func_8002957C func_8002958C func_8002959C func_800295D4 func_80029664 func_80029690 func_800296F8 func_80029774 func_800298BC func_8002992C func_80029A58 func_80029A94 func_80029AAC func_80029AF4 func_80029B4C func_80029BC8 func_80029C44 func_80029CD4 func_80029D3C func_80029DB4 func_80029E30 func_80029E94 func_80029EC0 func_80029ED4 func_80029FD4 func_80029FE4 func_8002A04C func_8002A088 func_8002A108 func_8002A1B4 func_8002A200 func_8002A234 func_8002A26C func_8002A27C func_8002A28C func_8002A2B0 func_8002A2D4 func_8002A354 func_8002A400 func_8002A44C func_8002A480 func_8002A4B8 func_8002A4C8 func_8002A4D8 func_8002A4FC func_8002A520 func_8002A544 func_8002A5C4 func_8002A670 func_8002A6BC func_8002A6F0 func_8002A728 func_8002A738 func_8002A748 func_8002A76C func_8002A790 func_8002A7B4 func_8002A834 func_8002A8E0 func_8002A92C func_8002A960 func_8002A998 func_8002A9A8 func_8002A9B8 func_8002A9DC func_8002AA00 func_8002AA3C func_8002AAB4 func_8002AB64 func_8002AC00 func_8002AE60 func_8002AED0 func_8002AEE4 func_8002AEF8 func_8002AF08 func_8002AF18 func_8002AF48 func_8002AF60 func_8002AF70 func_8002B00C func_8002B064 func_8002B08C func_8002B0B4 func_8002C320 func_8002C3B0 func_8002C410 func_8002C8BC func_8002C8F4 func_8002CC4C func_8002CCB4 func_8002CCD8 func_8002CDD8 func_8002CFE4 func_8002D034 func_8002D1F0 func_8002D240 func_8002D29C func_8002D320 func_8002D4B8 func_8002D4C8 func_8002D59C func_8002D678 func_8002D6D8 func_8002D7FC func_8002D80C func_8002D834 func_8002D844 func_8002D858 func_8002D8A8 func_8002D8D4 func_8002D904 func_8002DC68 func_8002DF80 func_8002E138 func_8002E5BC func_8002E5F8 func_8002E638 func_8002E700 func_8002E79C func_8002E818 func_8002E8DC func_8002E94C func_8002EA10 func_8002EAB0 func_8002EB10 func_8002EBAC func_8002EC10 func_8002ED90 func_8002EDE4 func_8002EE64 func_8002EE90 func_8002EEB8 func_8002EED8 func_8002EFD0 func_8002EFF8 func_8002F064 func_8002F0D0 func_8002F0F4 func_8002F12C func_8002F150 func_8002F1CC func_8002F248 func_8002F4E4 func_8002F5C8 func_8002F620 func_8002F648 func_8002F658 func_8002F67C func_8002F714 func_8002F80C func_8002FA3C func_8002FAE0 func_8002FB08 func_8002FC64 func_8002FD14 func_8002FDC8 func_8002FF0C func_800301C8 func_80030470 func_800304C8 func_80030538 func_80030634 func_80030730 func_80030A14 func_80030CA4 func_80030D80 func_80030F80 func_800314DC func_800316F8 func_80031988 func_80031A98 func_80031B7C func_80031BE0 func_80031CC8 func_80031D70 func_80031DEC func_80031E94 func_80031F14 func_80031FC8 func_80032048 func_800322A8 func_800324A4 func_80032774 func_8003310C func_800331D4 func_8003324C func_80033324 func_80033398 func_8003350C func_800335B8 func_800336A8 func_8003388C func_800342E8 func_80034314 func_80034650 func_800346D0 func_800347C8 func_80034844 func_800348A8 func_8003491C func_80034A54 func_80034A9C func_80034AE0 func_80034B0C func_80034B3C func_80034C24 func_80034CF0 func_80034DFC func_8003500C func_800351E8 func_80035210 func_80035270 func_800359B0 func_80035C4C func_8003602C func_80036130 func_800361CC func_8003621C func_80036260 func_80036AF8 func_80036D24 func_80036D58 func_80036EB4 func_80036EE8 func_80036F18 func_80036F98 func_80036FB0 func_80037004 func_80037028 func_80037144 func_80037334 func_80037358 func_80037368 func_800373D0 func_800374CC func_8003750C func_8003775C func_800377D8 func_80037CC8 func_80037CD8 func_80037D74 func_80037D98 func_80037EA0 func_80037F3C func_80037FC4 func_8003819C func_800381E4 func_80038210 func_80038308 func_8003834C func_8003836C func_800383A4 func_800384A8 func_800385C0 func_80038638 func_80038668 func_800387C0 func_80038838 func_800388E8 func_80038908 func_80038958 func_80038A00 func_80038A58 func_80038FC4 func_80038FFC func_8003916C func_80039C5C func_80039C70 func_80039F14 func_80039F50 func_8003A098 func_8003A0D0 func_8003A0E4 func_8003A234 func_8003A3D8 func_8003A404 func_8003A424 func_8003D424 func_8003D630 func_8003DC90 func_8003DF8C func_8003FA54 func_80040DE8 func_80041354 func_800413B8 func_80041400 func_80041448 main NON_MATCHING: build SHA1: 143dbb89f34491258bbc27810d0a12ec8b43a8dd (byte-identical) diff --git a/docs/psyq-worklist.md b/docs/psyq-worklist.md index e0b87e8fc0..e1dd136d66 100644 --- a/docs/psyq-worklist.md +++ b/docs/psyq-worklist.md @@ -17,7 +17,8 @@ | 2 | **libetc** | 5 / 7 | 800 tail (`0x8004239C`) | ~3.3k | VSYNC/INTR/INTR_VB/INTR_DMA/VMODE **contiguous**, ends exactly at libcd1 (`0x80043088`). Clean. | | 3 | **libmcrd** | 2 / 2 | 800b2 (`0x8005FC68`,`0x80062888`) | ~9.0k | LIBMCRD.o (2186 ins, huge, holds the 55 `LIBMCRD_OBJ_*`) + USERFUNC.o — **2 blocks**. `_card_*` h_norm dups collapse inside LIBMCRD. | | 4 | **libc2** | 17 / 46 | 800b2 (`0x8005C2C8`–`0x5CD98` + STRCAT `0x80061E90`) | ~3.1k | C stdlib (BZERO/MEMCPY/STRCMP/PRINTF/PRNT…); contiguous run + 1 outlier. **PRNT.o (418 ins) has an internal jtbl** — verify NOLOAD `.rodata` placement (the `PRNT_OBJ_24C` rodata note). | -| 5+6 | **libapi+libcard** | 22 (800c2) | 800c2 (`0x80061F38`–`0x80062888`) | ~0.7k | ✅ **DONE (combined apicard region): 22 objs / 4 blocks / +24 fns** (`tools/make_apicard_used.py`, C112 dedup, 0 exclusions). **libapi's ~22 objects in the 800c3 region (`0x5CE18`..) DEFERRED** — lowest value, separate resegmentation. | +| 5+6 | **libapi+libcard** | 26 (800c2) + 23 (band) | 800c2 (`0x80061F38`–`0x80062888`) + the band (`0x8005CE18`–`0x8005E188`) | ~2.6k | ✅ **DONE (S79 #5): apicard region 26 objs / 7 blocks tiling the whole range** (`tools/make_apicard_used.py`, libapi **4.2** from `tools/psyq/lib421` + libcard 4.0; FIRST/PAD/PATCH/CHCLRPAD were the "game code" rows 800c2/800c2_2/800c2_3) **+ the band's 23 libapi 4.2 objects (libapi1/libapi2)** from the raw `.run/obj42/libapi42` dir, windowed. | +| 9 | **libpad 4.2.1** | 7 / 11 | the band (`0x8005D0D8`–`0x8005FC68`) | ~11.5k | ✅ **DONE (S79 #13 found it, #5 wired it): PADENTRY PADMAIN PADCMD PADIF PADPORTD PADSEQD WAITRC2 as libpad1/libpad2** from the raw `.run/obj42/libpad421` dir (SCE's 1998-02-26 J421PD patch, `tools/psyq/lib421`). Absent: PADGUN/PADPORTM/PADSEQM/GUNHOOK (no gun, no multitap). | | 7+8 | **libspu+libsnd** | 63 / (38+32) | 800 sound (`0x8003A444`–`0x8004239C`) | ~24k | ✅ **DONE (combined region; S78 #3/#4): 63 objs / 12 blocks.** The two libs interleave, so linked as ONE region (`tools/make_snd_used.py` dedups + excludes 3 addresses; `gen_lib_subsegs.py` + window). **Excluded:** S_R/S_W `0x3C438`, S_GRMDT* `0x3D424` (cross-object commons — these objects have NO `.bss`, so the S78 split cannot apply), S_IH/UT_RON `0x3D94C` (false-positive, inside SSSTART). VM_F `0x3FA64` (237 ins) rejoined in S78 #4 (`snd12`, `.bss` split at `_svm_sreg_buf`). SSGM.o `0x1BD80` deferred (isolated in matched-C, 8 ins). | | 9 | **libgte** | 58 / 381 | 800b (`0x8004787C`–`0x5082C`) + **libgs gaps** | ~48k | ✅ **DONE (T11): 53 objs / 22 blocks linked** in 800b (subsegs via `gen_lib_subsegs.py`; integrate window 0x4787C..0x51804). **5 libgs-gap objects DEFERRED** (MTX_05/07/11/REG03/REG11 → gsgap1/2/4/5 stay stubs; gsgap2≠MTX_07 exactly so needs sub-split). | @@ -69,7 +70,7 @@ references resolve to >1 base in the EXE. Curate the library's `_used` dir to dr | `MTX_05/07/11`,`REG03`,`REG11` | libgte | sit in libgs gaps gsgap1/2/4/5; gsgap2(48B)≠MTX_07(36B) so the gap stub needs a sub-split | **deferred (T11)**; small GTE fns; link byte-identical, just need the gsgap region resegmented (low priority) | | `0x3C438`,`0x3D424`,`0x3D94C` (S_R/S_GRMDT/S_IH) | libspu/snd | cross-object commons referenced at a minority address (S_R/S_GRMDT — these objects have NO `.bss` of their own, so the S78 split does not apply) + a false placement inside SSSTART (S_IH) | **excluded (sound region)**; stay stubs (24+4+24 ins). VM_F `0x3FA64` (237 ins) left this row in S78 #4 → `snd12` | | `SSGM.o` | libsnd | isolated @0x1BD80, inside the matched-C region (near func_8001Bxxx) | **deferred**; 8 ins; would need a 1-object carve amid matched C | -| libapi 800c3 cluster (~22 objs) | libapi | C57..L10/L02/L03 @0x5CE18.. in the 800c3 region (separate from the 800c2 apicard region) | **deferred**; ~22 4-ins BIOS syscall stubs; lowest value; another region resegmentation | +| libapi 800c3 cluster (~22 objs) | libapi | C57..L10/L02/L03 @0x5CE18.. in the 800c3 region (separate from the 800c2 apicard region) | **LINKED S79 #5** (`libapi1`/`libapi2`, from libapi **4.2** — the EXE's real libapi, cookbook §490); the row's "lowest value" verdict missed that the same region held libpad 4.2.1's 2,780 ins | *~~If scattered-`.bss` proves prevalent across libgte/libspu/libsnd, escalate to a Max general fix (split each object's `.bss` into per-common NOLOAD sections at their EXE-resolved addresses); otherwise excluding the few affected objects is the GS_001-precedent decision.~~ **Done in P31 S78 #4 — exactly that fix, twenty-three phases later: `tools/psyq_bss_split.py` runs inside the link-prepare step of `psyq_link` / `psyq_link_region` / `psyq_integrate` and tiles any such section into per-base NOBITS pieces from the bytes (cookbook §489). All three excluded objects link byte-identical; 235 placed objects across the 9 curated dirs, 0 refusals (R39 negative control).*** @@ -248,3 +249,26 @@ places the same 4 objects as plain 4.2 (PADENTRY, PADCMD, PADPORTD, WAITRC2) — PADSEQD 292 against the EXE's 760 / 376 / 288 — and its LIBAPI.LIB places 38 (no 4.2 `C114`). So 4.2.1 is the unique exact match: the game was built between the February 1998 patch and the May 1998 4.3 disc. Not banked (>100 MB, R20 exception; the item id is the pointer; the two LIBs sit in `.run/psyq_hunt/rtl43/lib43/`). + +### S79 task #5 — the band and the apicard region LINKED from libapi 4.2 + libpad 4.2.1 (0 tokens; cookbook §490) + +| new block | was | objects | ins | note | +|---|---|---|---|---| +| `libapi1` | 800c3 head | C57 C68 C73 C114 A07–A13 A23–A25 A36 A37 A52 A53 A91 L10 + COUNTER | 176 | 21 BIOS trampolines + the RCnt object; window 0x8005CE18–0x8005E188 | +| `libpad1` | 800c3 | PADENTRY + PADMAIN | 1,060 | PADMAIN 760 = the 4.2.1 build | +| `libapi2` | 800c3 | L02 + L03 | 8 | SysEnqIntRP / SysDeqIntRP | +| `libpad2` | 800c3 tail | PADCMD PADIF PADPORTD PADSEQD WAITRC2 | 1,720 | window 0x8005D0D8–0x8005FC68 | +| `apicard5` | 800c2 | FIRST | 168 | `firstfile` (REAL C until now) + the "no jump table wall" stub `func_80062144` | +| `apicard6` | 800c2_2 | PAD | 192 | SetInitPadFlag … StopPAD + 4 statics (hand-matched C + 4 verbatims until now) | +| `apicard7` | 800c2_3 | PATCH + CHCLRPAD | 68 | `_patch_pad`, `_remove_ChgclrPAD` (4 verbatims until now) | + +Two windowed integrate calls from the raw `.run/obj42/{libapi42,libpad421}` dirs (the band is one interleaved +run and `psyq_integrate` tiles each stub with one library) + the apicard call from the re-sourced +`.run/obj42/apicard_used` (libapi 4.2 + libcard 4.0, 26 objects / 7 blocks, no game code left in +0x80061F38–0x80062888). TUs gone: `src/800c3.c` (129 hand-matched "C", 62 verbatim bodies, 19 stubs — Sony's +reorder-assembled code all along, §332b), `src/800c2.c`, `src/800c2_2.c`, `src/800c2_3.c`; the `REORDER_TUS` +island is EMPTY (the Makefile mechanism stays). main `143dbb89` with every SDK dir and, from a fresh extract, +with none. `config/wave_exclude.txt` regenerated (`exclude_audit` now lets LINKED outrank a pinned WALL: the +four §332 walls, `func_80062144`, and `PopMatrix`/`PushMatrix` — in libgte3 since Phase 8 — dropped); +verbatim manifest 33 → 6 rows. Located-but-unwired SDK code left in main: `SSGM.o` (8 ins, inside matched C) +and the sound region's two cross-object-common walls (S_R/S_W, S_GRMDT*). diff --git a/phase-ends/CURRENT_PHASE.md b/phase-ends/CURRENT_PHASE.md index 99b3f50f23..db0a6f035b 100644 --- a/phase-ends/CURRENT_PHASE.md +++ b/phase-ends/CURRENT_PHASE.md @@ -105,6 +105,22 @@ Instead of roadmap-v2 P31's per-function grind, Phase 31 organizes the 12,059 re LINKABLE from real objects → #5 is re-scoped to a carve + wire (S79 FINAL block §6). The 4.3 disc is not banked (>100 MB; the item id is the pointer; its two LIBs kept in `.run/psyq_hunt/rtl43/lib43/`). Records: worklist "S79 task #13", SETUP archive table + §5.1 + S79 tool table. + **#5 DONE (S79, 2026-09-04, `commit:orphan-24`):** the whole band + the apicard region LINKED from libapi 4.2 + + libpad 4.2.1 (cookbook **§490**). `800c3` → 4 rows `libapi1` (21 trampolines + COUNTER, 176 ins) / + `libpad1` (PADENTRY+PADMAIN, 1,060) / `libapi2` (L02/L03, 8) / `libpad2` (PADCMD…WAITRC2, 1,720) fed by + two WINDOWED integrate calls from the raw `.run/obj42/{libapi42,libpad421}` dirs (integrate tiles each + stub with one library); `800c2`/`800c2_2`/`800c2_3` were FIRST.o / PAD.o / PATCH+CHCLRPAD → `apicard5/6/7`, + and `make_apicard_used.py` now sources libapi from 4.2 (`.run/obj42/apicard_used`, 26 objs / 7 blocks, + no game code left in 0x80061F38–0x80062888). Four TUs deleted; `REORDER_TUS` EMPTY (mechanism kept). + main `143dbb89` WITH all SDK dirs and, from a fresh extract, WITHOUT (`.run/S79_build_band_*.log`). + `exclude_audit` fixed (LINKED outranks a pinned WALL): `config/wave_exclude.txt` 13 → 3 (the four §332 + walls, `func_80062144`, and `PopMatrix`/`PushMatrix` — libgte3 since Phase 8 — dropped); verbatim + manifest 33 → 6 (`--update`). Metrics: main REAL 839→**773** · LINKED 1,150→**1,256** · VERBATIM 29→**3** · + stubs 29→**16** · byte-identical 2,075/2,091 = 99.2% · **game-code 93.3% (38,748 / 41,534)**, remainder + 2,786 = the open-stub sum; fleet stubs 51→**38**. Docs: cookbook §490 (+index), worklist rows + "S79 task + #5", SETUP (fresh-clone obj42 commands, Makefile blocks, exclude_audit), decision-log "S79 addendum 2", + accelerators "S79 (2)". `frontier_classify` had a HARD-CODED LINKED set (R51) — derived from the Makefile + now. tools-health OK; R22 fleet 213/213 (`.run/S79_check_all_band.log`). - [ ] **Tclose — PhaseEnd** (gate 2). (Max) ## Standing verification (every task) @@ -8022,19 +8038,23 @@ for free. Three of our own measuring tools were lying (one hid a broken build, o saved names, one under-counted the main program by 32 points); all fixed, and the main program is now honestly 91.8% real C. Next: a small piece of linker surgery so two more Sony objects can be linked. -## 🛑 SESSION CHECKPOINT — S79 FINAL (2026-09-04). SUPERSEDES every earlier block in this file. Phase 31 T10 CONTINUES — the COMPLETION SPRINT, tasks #5 → #11 remain (#4 and #13 DONE this session). +## 🛑 SESSION CHECKPOINT — S79 FINAL (2026-09-04). SUPERSEDES every earlier block in this file. Phase 31 T10 CONTINUES — the COMPLETION SPRINT, tasks #6 → #11 remain (#4, #13 and #5 DONE this session). Written for a FRESH SESSION with none of this context. Read it in full before doing anything. -**HEAD = the S79 task-#13 commit, on top of the task-#4 commit `commit:3865` (Drew pushes, R6); no -`Claude-Session:`/`Co-Authored-By` trailers (R5 + the S78 decision).** Model Fable 5.1; effort **xHigh** default -for #5–#10, **Max** for #11 (R27: prompt Drew and WAIT for the actual `/effort` line). No Ultracode / no waves in this sprint. The Ghidra MCP server +**HEAD = the S79 task-#5 commit `commit:orphan-24` (amended with this block), on top of #13 `commit:3866` and #4 +`commit:3865` (Drew pushes, R6); no `Claude-Session:`/`Co-Authored-By` trailers (R5 + the S78 decision).** Model +Fable 5.1; effort **xHigh** default for #6–#10, **Max** for #11 (R27: prompt Drew and WAIT for the actual +`/effort` line). No Ultracode / no waves in this sprint. The Ghidra MCP server restarts via the SessionStart hook → Drew runs `/mcp` (R29); no RE task is next, so no G2 ping needed until one is. Ghidra DB churn (`db.*.gbf`, `~index`) is R23 restart-noise: do NOT stage it. -**Verified at close (R22/R58):** main `143dbb89f34491258bbc27810d0a12ec8b43a8dd` byte-identical WITH the SDK -objects (`.run/S79_build_main_sdk.log`) and WITHOUT them from a FRESH extract (`.run/S79_build_main_fallback.log`); -`make tools-health` (`.run/S79_tools_health.log`) and the fleet `make clean && make extract-all && make -check-all` (`.run/S79_check_all.log`): extract-all **212/212** (+ main), check-all **213 passed, 0 failed of 213** (rc=0, 2m42s). +**Verified at close (R22/R58):** main `143dbb89f34491258bbc27810d0a12ec8b43a8dd` byte-identical WITH every SDK +dir (`.run/obj40` + `.run/obj42`; `.run/S79_build_band_sdk.log`) and WITHOUT them from a FRESH extract +(`.run/S79_build_band_fallback.log`); `make tools-health` (`.run/S79_tools_health_band.log`, rc=0); the fleet +`make clean && make extract-all && make check-all` (`.run/S79_check_all_band.log`): extract-all **212/212** +(+ main), check-all **213 passed, 0 failed of 213** (rc=0, 2m32s); `frontier_classify` regenerated after it: +**39 rows = 38 stubs + the data word**, main 16. (The task-#4 state was verified the same way earlier in the +session: `.run/S79_check_all.log` 213/213.) # 1. THE SESSION IN ONE PARAGRAPH @@ -8049,44 +8069,55 @@ the SDK objects; the game-code metric moved 91.8% → 91.1% only because 3,667 S numerator and its denominator (the open remainder is unchanged at 3,975 ins). Then task #13, the bounded hunt, succeeded on its first lead: an archive.org 7z of the PsyQ Runtime Library 4.2 carries SCE's February-1998 "libpad.lib 4.2.1 for the DUAL SHOCK" patch — the EXE's exact libpad and libapi. -All 46 objects it places in main link byte-identical, so the whole 0x8005CE18–0x8005FC68 band (the twelve -"wall"/plumbing stubs, the eight reorder verbatims and the band's hand-matched C) is Sony code that task #5 -now links instead of matching (§5/§6 below). +All 46 objects it places in main link byte-identical, so task #5 linked the whole 0x8005CE18–0x8005FC68 band +(the twelve "wall"/plumbing stubs, the reorder verbatims, the band's hand-matched C) and the apicard region's +three C objects from the real objects: four TUs gone, the `REORDER_TUS` island empty, main's open stubs 29 → 16, +fleet 51 → 38, game-code 93.3% with the remainder still equal to the open-stub sum. Two instruments were +found stale on the way and fixed (the exclude audit's WALL-before-LINKED order; the frontier census's +hard-coded LINKED set). # 2. THE CENSUS (S79 close; every number with its denominator, R41) -* **Stubs: 51 of 363,151 matchable = 7,710 ins — UNCHANGED by #4** (`.run/frontier_s78.json`, - `tools/frontier_classify.py`; the three objects were REAL/VERBATIM, not stubs). Classes and names exactly as - the S78 FINAL block §2 listed them: A-TWIN-REMAP 2 · B-CARVE jtbl 6 · C-PLUMBING 7 · D-NEAR 14 · F-FAR 10 · - G-DRAFTED-UNKNOWN 12 · H-VIRGIN 1 (`D_800D3200`, a data word). Per binary: **main 29 (3,975 ins)** · - resident 2 · md 7 · overlays 14 across 11 binaries. - main's 29 by name: PadInfoAct (jtbl carve) · `_padSetMainMode` (plumbing) · `func_80011380` 192 (boot -O0 - floor §474), `_padInitSioMode` 133, `func_80015760` 106, `func_8005D734` 91, `PadInitDirect` 88, - `func_80015608` 86, `func_80039B20` 79, `func_80038698` 74, `func_80062144` 65, `func_8005F290` 61, - `_dirFailAuto` 55, `_padStartCom` 51, `func_8005ECC0` 35 (D-NEAR) · `func_80032A74` 422, `func_8005F830` - 153, `func_80015B6C` 120, `func_8002AC98` 114, `func_80020DA4` 100, `func_800391D4` 75, `func_80039DEC` 74, - `func_8002FDE8` 73, `func_8001BC6C` 69 (F-FAR) · `func_80039308` 518, `func_8001EFE0` 468, `func_80023BF0` - 281, `func_8005ED4C` 223, `func_8005F450` 159 (G). -* **Verbatim `__asm__` bodies: 33 in tree** (main 29 + 4 elsewhere); manifest `config/verbatim_manifest.json` - now **33 rows** (S79 `--update`, subtractive: 200 → 33; 32 PERMANENT-VERBATIM + 1 DECOMPILE-NOW). #10 - ratifies the PERMANENT set (S78 estimated ≈ 9 genuinely permanent: crt0 `start`/`__main`/`__do_global_dtors`, - GAME-ASM `md_MAIN_003:func_800D3204/3234`, GAME-GTE `ov_SC05_005:func_80181828` + `ov_SC06_032:func_8017D810`, - 2 SDK frags) and decompiles `main()` (509 ins) + the md_MAIN_003 -O0 cluster; the GAME-GTE UNCERTAIN ×3 - (`ov_SC01_001:func_80181E04` 269, `ov_SC03_105:func_80185810` 489, `ov_SC07_002:func_8017DC80` 346) need a - verbatim-vs-C verdict first (#9). -* **Located-but-unwired SDK objects** (the build PRINTS them per library as `~~ N located object(s) …`): after - #4 there is NO `~~` line for libgpu / libgs / snd. Still open: the libpad/libapi band pieces (#5), `SSGM.o` - 8 ins @0x8001BD80 inside matched C (`800`), and the sound region's two cross-object-common walls `S_R`/`S_W` - @0x8003C438 + `S_GRMDT*` @0x8003D424 (these objects have NO `.bss` — a DIFFERENT class from §489; 24+4 ins). +* **Stubs: 38 of 363,157 matchable (`.run/frontier_s79.json`, `tools/frontier_classify.py` — regenerated after + the fleet; #5 removed the 13 band stubs; #4 removed none, its objects were REAL/VERBATIM).** Classes: + A-TWIN-REMAP 2 (ov_SC04_018 `func_80181804` 77 / `func_80181CB8` 67, proven twin ov_SC04_019) · + B-CARVE jtbl 5 (resident `func_800D06E8` 344 + `func_800D128C` 243, ov_SC02_017 `func_80186C64` 209, + md_MAIN_034 `func_800CB00C` 152, ov_SC05_010 `func_8017FFA8` 88) · C-PLUMBING close=0 6 (ov_SC05_005 + `func_80181828` 87, ov_SC05_018 `func_80180BE0` 65, ov_SC06_010 `func_801809E4` 33, md_MAIN_003 + `func_800D06BC` 33 + `func_800D0100` 29, md_MAIN_020 `func_800CB17C` 30) · D-NEAR ≤25 6 (main + `func_80011380` 192 boot -O0 floor §474, `func_80015760` 106, `func_80015608` 86, `func_80039B20` 79, + `func_80038698` 74; ov_SC03_105 `func_801834A4` 106) · F-FAR 9 (main `func_80032A74` 422, `func_80015B6C` + 120, `func_8002AC98` 114, `func_80020DA4` 100, `func_800391D4` 75, `func_80039DEC` 74, `func_8002FDE8` 73, + `func_8001BC6C` 69; ov_SC02_027 `func_80180B3C` 297) · G-DRAFTED-UNKNOWN 10 (main `func_80039308` 518, + `func_8001EFE0` 468, `func_80023BF0` 281; ov_SC03_105 `func_80185810` 489; md_MAIN_003 `func_800CF3E8` + 469 + `func_800D1D14` 65 + `func_800D0174` 36; ov_SC07_002 `func_8017DC80` 346; ov_SC01_001 `func_80181E04` + 269; ov_SC06_022 `func_8017DF28` 119) · H-VIRGIN 1 (md_MAIN_003 `D_800D3200`, a data word → splat fix). + Per binary: **main 16 (2,786 ins)** · resident 2 · md 7 · overlays 13 across 10 binaries. The 13 that + left with #5: PadInfoAct, `_padSetMainMode`, `_padInitSioMode`, `func_8005D734`, `PadInitDirect`, + `func_80062144`, `func_8005F290`, `_dirFailAuto`, `_padStartCom`, `func_8005ECC0`, `func_8005F830`, + `func_8005ED4C`, `func_8005F450` — all libpad 4.2.1 / libapi 4.2 objects. +* **Verbatim `__asm__` bodies: 6 in tree** (main 3 + md_MAIN_003 2 + ov_SC03_107 1); manifest + `config/verbatim_manifest.json` = **6 rows** after two subtractive `--update`s this session (200 → 33 → 6): + crt0 `start`/`__main`/`__do_global_dtors` (CRT, PERMANENT), GAME-ASM `md_MAIN_003:func_800D3204/3234` + (PERMANENT), and `ov_SC03_107:func_8017D878` (GAME-C, DECOMPILE-NOW). #10 ratifies the PERMANENT five in the + manifest `_README`, decompiles the one GAME-C, `main()` (509 ins) and the md_MAIN_003 -O0 cluster; the + GAME-GTE UNCERTAIN ×3 (`ov_SC01_001:func_80181E04` 269, `ov_SC03_105:func_80185810` 489, + `ov_SC07_002:func_8017DC80` 346) are G-class STUBS now, not verbatims — verdict first (#9). +* **Located-but-unwired SDK objects** (the build PRINTS them per library as `~~ N located object(s) …`): NO + `~~` line remains for any library. Still unlinked by design: `SSGM.o` 8 ins @0x8001BD80 inside matched C + (`800`), and the sound region's two cross-object-common walls `S_R`/`S_W` @0x8003C438 + `S_GRMDT*` + @0x8003D424 (these objects have NO `.bss` — a DIFFERENT class from §489; 24+4 ins, byte-identical stubs). * **Disc: 5 unclaimed code payloads of 220** (MAIN/7, MAIN/9, SC03/53/54/56) — the explicit exclusion the 100% claim cites (`docs/disc-completeness.md`). * **Metrics at close** (`docs/progress.md` / `progress.fleet.md`, regenerated by tools-health): main REAL - **839** · LINKED **1,150** · VERBATIM **29** · stubs **29** · matchable 2,090 · byte-identical 2,061/2,090 = - 98.6%; **MAIN game-code weighted 91.1% (40,895 / 44,870)**, remainder 3,975 = the open-stub sum exactly; - fleet instr 99.9% (13,481,631 / 13,489,225), distinct 99.9%, stubs 51. Linked libraries: libcd 18/2, - libgs 34/8, libetc 5/1, libgpu 3/2, libmcrd 2/2, libc2 17/2, libgte 70/30, snd 63/12, apicard 22/4. + **773** · LINKED **1,256** · VERBATIM **3** · stubs **16** · matchable 2,091 · byte-identical 2,075/2,091 = + **99.2%**; **MAIN game-code weighted 93.3% (38,748 / 41,534)**, remainder 2,786 = the open-stub sum exactly + (S78 close: 91.8% / 44,562 / 48,537 — both terms have since lost ~7,000 Sony instructions that were counted + as matched game code); fleet instr 99.9%, distinct 99.9%, stubs **38** of 363,157. Linked libraries: + libcd 18/2, libgs 34/8, libetc 5/1, libgpu 3/2, libmcrd 2/2, libc2 17/2, libgte 70/30, snd 63/12, + apicard 26/7 (libapi 4.2 + libcard 4.0), libapi42 23/2, libpad421 7/2 — 268 objects / 70 blocks. -# 3. THE TASK LIST (harness tasks; Drew-confirmed order 2026-09-04) — DONE: #1 #2 #12 #3 #4 #13 +# 3. THE TASK LIST (harness tasks; Drew-confirmed order 2026-09-04) — DONE: #1 #2 #12 #3 #4 #13 #5 | # | task | status | effort | |---|---|---|---| @@ -8095,9 +8126,9 @@ now links instead of matching (§5/§6 below). | 12 | name the band (46 names, Ghidra mirrored, provenance docs) | DONE `commit:3861` | — | | 3 | wire the exact-tile library subsegs (13 subsegs → LINKED) | DONE `commit:3863` | — | | 4 | SYS.o + VM_F (+ GS_001) `.bss` split → LINKED (`libgpu2`, `snd12`, `libgs8`) | DONE S79 `commit:3865` | — | -| 13 | bounded hunt for LIBPAD.LIB 4.2.1 / 4.3 — **FOUND** (RTL 4.2 + the J421PD 4.2.1 patch; 46/46 byte-identical) | DONE S79 (this commit) | — | -| **5** | **the band: LINK ALL OF IT from libpad 4.2.1 + libapi 4.2 (carve `800c3`/`800c2*` at object boundaries; re-source the apicard region's libapi from 4.2)** | **NEXT** | **xHigh** | -| 6 | mechanical: A-TWIN-REMAP 2 + B-CARVE 6 + `D_800D3200` | pending | xHigh | +| 13 | bounded hunt for LIBPAD.LIB 4.2.1 / 4.3 — **FOUND** (RTL 4.2 + the J421PD 4.2.1 patch; 46/46 byte-identical) | DONE S79 `commit:3866` | — | +| 5 | the band + the apicard region LINKED from libpad 4.2.1 + libapi 4.2 (`libapi1/2`, `libpad1/2`, `apicard5-7`; 13 stubs, 4 TUs, the reorder island gone) | DONE S79 `commit:orphan-24` | — | +| **6** | **mechanical: A-TWIN-REMAP 2 + B-CARVE 5 + `D_800D3200`** | **NEXT** | **xHigh** | | 7 | C-PLUMBING 7 via `recover_route` / §376–§378 | pending | xHigh | | 8 | D-NEAR non-band 6: permuter/ILS/§31 or §474 wall-proof each | pending | xHigh | | 9 | F-FAR 10 + G-UNKNOWN 12: one journal-noted agent per function | pending | xHigh | @@ -8144,65 +8175,62 @@ mv back; make extract BINARY=main`) after ANY change to `psyq_identify`/`psyq_in yaml; `lint_symbol_refs` — read its WHOLE output; a splat symbol comment must not contain `name:`; verify a build from its EXIT CODE (R53). -# 5. TASK #13 — DONE: THE ARCHIVE EXISTS (facts, not to re-derive) +# 5. WHAT #13 AND #5 CHANGED (facts, not to re-derive) -`tools/psyq/PlayStation_Programmer_Tool_-_Runtime_Library_Version_4.2.7z` (tracked; sha256 `e4f5a678…`) → -`tools/psyq/lib42/*.LIB` (RTL 4.2, 1998-01-21; 23 libs + `42PATCH/` + `MC42PTCH/`) and `tools/psyq/lib421/` -(J421PD payload: `LIBPAD.LIB` 4.2.1 sha `eb41454b…`, `LIBAPI.LIB` 4.2 sha `88294cd8…`, `LIBPAD.H`, `LIBAPI.H`, -`KERNEL.H`, `J421PD.txt`). ELF: `.run/obj42/libpad421/` (11 objects) and `.run/obj42/libapi42/` (88); regenerate -with `python3 tools/psyq_lib_split.py ` then `tools/psyq/psyq-obj-parser -o ` per object. -Placement over 0x8005CE18–0x800629DC (`psyq_identify … 0x8005CE18 0x800629DC`): libpad421 7/11, libapi42 39/88, -every one `psyq_link.py` PASS. Neighbours for the record: plain libpad 4.2 and libpad 4.3 (disc DTL-S2340, -1998-05-18, `.run/psyq_hunt/rtl43/lib43/`, `.run/obj43/`) each place only 4 — 4.2.1 is the unique exact match. -The 4.2.1 headers, not 4.7's, are the band's prototype oracle from now on. +**(a) The archive.** `tools/psyq/PlayStation_Programmer_Tool_-_Runtime_Library_Version_4.2.7z` (tracked; sha256 +`e4f5a678…`) → `tools/psyq/lib42/*.LIB` (RTL 4.2, 1998-01-21) and `tools/psyq/lib421/` (J421PD: `LIBPAD.LIB` +4.2.1 sha `eb41454b…`, `LIBAPI.LIB` 4.2 sha `88294cd8…`, `LIBPAD.H`, `LIBAPI.H`, `KERNEL.H` = the band's +prototype oracle). ELF: `.run/obj42/libpad421/` (11 objects) and `.run/obj42/libapi42/` (88); regenerate with +`python3 tools/psyq_lib_split.py ` then `tools/psyq/psyq-obj-parser -o ` (SETUP has the +commands). Placement 0x8005CE18–0x800629DC: libpad421 7/11, libapi42 39/88, every one `psyq_link.py` PASS. +Neighbours: plain libpad 4.2 and the 4.3 disc (DTL-S2340, 1998-05-18; `.run/psyq_hunt/rtl43/lib43/`) place 4 +each — 4.2.1 is the unique exact match; the game was built between Feb and May 1998. +**(b) The wiring** (cookbook §490). Yaml: `800c3` → `libapi1` [0x4D618] · `libpad1` [0x4D8D8] · `libapi2` +[0x4E968] · `libpad2` [0x4E988]; `800c2` → `apicard5`, `800c2_2` → `apicard6`, `800c2_3` → `apicard7`. +Makefile: `LIBAPI42_*` (raw `.run/obj42/libapi42`, window 0x8005CE18 0x8005E188, stubs libapi1,libapi2), +`LIBPAD_*` (raw `.run/obj42/libpad421`, window 0x8005D0D8 0x8005FC68, stubs libpad1,libpad2), +`APICARD_ELF := .run/obj42/apicard_used` with `APICARD_STUBS` apicard1..7; the SYMS line carries the two new +`*_externals.ld`; `REORDER_TUS :=` (empty, mechanism kept). `tools/make_apicard_used.py`: `SOURCES = +(.run/obj42/libapi42, .run/obj40/libcard)` → 26 objects. TUs: `git rm src/800c3.c src/800c2.c src/800c2_2.c +src/800c2_3.c`; splat emitted the 7 stub TUs (`libapi1.c` 25 stubs, `libpad1.c` 24, `libapi2.c` 2, `libpad2.c` +40, `apicard5.c` 2, `apicard6.c` 10, `apicard7.c` 4) for the no-SDK fallback. `psyq_integrate` printed 26/7 · +23/2 · 7/2 blocks, no `~~`, no `!!`. +**(c) Instruments fixed.** `tools/exclude_audit.py`: LINKED now outranks a pinned `# WALL` (`config/wave_exclude.txt` +13 → 3: the four §332 walls, `func_80062144`, `PopMatrix`/`PushMatrix` — the last two in libgte3 since Phase 8). +`tools/frontier_classify.py`: its LINKED set was a hard-coded 49-name literal (R51) and reported 337 "stubs" after +#5; derived from the Makefile now (`progress._main_linked_segs_from_makefile`). +**(d) Still true from S78/S79 #4:** §4 above (the `.bss` split, the band identity, ApplySymbols for renames, +main's LINKED path only exercised in-tree with the obj dirs present, R53 exit codes, `lint_symbol_refs` whole +output, no `name:` in splat symbol comments). -# 6. TASK #5 — WIRE THE WHOLE BAND (start here; xHigh; design before code, X1) +# 6. TASK #6 — MECHANICAL: A-TWIN-REMAP 2 + B-CARVE 5 + `D_800D3200` (start here; xHigh; design before code, X1) -**Target:** every byte of 0x8005CE18–0x8005FC68 becomes LINKED, plus `FIRST.o`/`PAD.o`/`PATCH.o`/`CHCLRPAD.o` -and the apicard trampolines re-sourced from libapi 4.2. Object tiling of the band, in vram order (all -verified byte-identical S79): 21 libapi trampolines C57 C68 C73 C114 A07 A08 A09 A10 A11 A12 A13 A23 A24 A25 -A36 A37 A52 A53 A91 L10 at 0x8005CE18 + 0x10·k (4 ins each, 0x8005CE18–0x8005CF68) · COUNTER 0x8005CF68 (92) -· PADENTRY 0x8005D0D8 (300) · PADMAIN 0x8005D588 (760, ends 0x8005E168) · L02 0x8005E168 · L03 0x8005E178 · -PADCMD 0x8005E188 (600) · PADIF 0x8005EAE8 (376) · PADPORTD 0x8005F0C8 (408) · PADSEQD 0x8005F728 (288) · -WAITRC2 0x8005FBA8 (48, ends 0x8005FC68). Check the tiling has NO gap (0x8005CE18 + 21·0x10 = 0x8005CF68 ✓; -PADMAIN 760·4 = 0xBE0 → 0x8005D588+0xBE0 = 0x8005E168 ✓; PADENTRY ends 0x8005D588 ✓ …) before carving — -integrate's exact-tiling check will refuse otherwise (R43). -**The carve.** Today the band lives in the C TUs of the `REORDER_TUS` island (`800c3` = 0x8005CE18…, plus -`800c2`, `800c2_2`, `800c2_3` for the apicard-side pieces; §332b). Follow the §486/§488 procedure: yaml rows -at each object-block boundary (block names e.g. `libapi42_1` = the 21 trampolines + COUNTER 0x8005CE18–0x8005D0D8, -`libpad1` = PADENTRY+PADMAIN 0x8005D0D8–0x8005E168, `libapi42_2` = L02/L03 0x8005E168–0x8005E188, `libpad2` = -PADCMD…WAITRC2 0x8005E188–0x8005FC68 — or one block per object; pick what tiles the yaml cleanly), each -row commented with objects + ins + "exact tile", then `git rm` the TUs that become 100% SDK (`800c3` is -entirely band? CHECK the row range vs 0x8005FC68 — anything after the band inside `800c3` stays game C in a -carved-off TU: split the TU at the object end, keep its game C, per §488). Curated dir: build -`.run/obj42/band_used` = the 7 libpad421 objects + the band's 23 libapi42 objects (the apicard-region 16 go to -the apicard call), or pass the raw dirs with WINDOWS (`lo hi`) so each call places only its region — two -integrate calls: libpad421 window 0x8005D0D8–0x8005FC68, libapi42 window 0x8005CE18–0x8005E188 (+ a third -libapi42 call for the apicard window 0x80061F38–0x80062888 REPLACING the 4.0 `apicard_used` libapi objects; -`make_apicard_used.py` merges libapi+libcard — point its libapi source at obj42 and keep libcard 4.0, then -`FIRST.o` needs a carved stub for the REAL-C `firstfile` in `800c2` [0x80061FA8,0x80062248) and `PATCH`+ -`CHCLRPAD` = all of `800c2_3` after A18–A21). Makefile: new `*_ELF/_OBJDIR/_SYMS` triples + stub lists; -`$(main_SPLAT_YAML)` on every call; `progress.py` picks the blocks up from the Makefile automatically. -**Names.** `config/symbols.us.txt` already carries the 46 band names (S78 #12); the objects export them -(`--redefine-sym` covers any curated-vs-object spelling, R15). `PadInfoAct`'s jtbl (B-CARVE) disappears with -the object — remove it from `config/wave_exclude.txt` via `exclude_audit.py --write` (a stale list is refused). -Ghidra: no renames needed (names already mirrored S78); if any curated name changes, `tools/ghidra_apply_symbols.sh` + R9. -**Gate exactly as #3/#4:** in-tree `make extract BINARY=main` → `make build BINARY=main -j` with `.run/obj40`+`obj42` -present (watch the `integrate` lines: block counts, `~~` residue must be EMPTY for the band, `!!` unresolved -none) → the fresh-extract fallback WITHOUT the SDK dirs → `make tools-health` → R22 fleet (background) → docs -(cookbook § for "the band links", worklist rows incl. the "5+6 libapi+libcard" footprint row and the §332 -wall verdicts now VOID, SETUP, decision-log R31: the §332 "walls" were reorder-assembled SDK code — recorded -S78, close the loop) → `verbatim_check --update` (the 8 SDK-C-REORDER verbatims go) → commit. Expect: main's -open stubs 29 → 17 (the 12 band stubs), VERBATIM −8, REAL −(the band's hand-matched C incl. `firstfile`), -LINKED +~60, game-code denominator −~3,200 ins with the remainder = the new open-stub sum (reconcile it, R41). -Fresh-clone note (SETUP): `.run/obj42` is regenerable from the tracked 7z — document the two commands. +**A-TWIN-REMAP (2, ov_SC04_018):** `func_80181804` (77) and `func_80181CB8` (67) have a PROVEN twin in +ov_SC04_019 (banked). Run `tools/twin_rescan.py` first (a bank changes the twin graph; §397) to confirm the +pairing, then `family_remap` / the structural-family mechanical remap (memory `structural-family-mechanical-remap`: +h_exact remaps bank at 88.5%). Gate ov_SC04_018 with the parallel gate in a worktree (memory +`parallel-gate-via-worktrees`; never xargs -P over gate_stage). Then `twin_rescan` again. +**B-CARVE jtbl (5):** resident `func_800D06E8` (344) + `func_800D128C` (243) need the RESIDENT carve path +(`jtbl_carve` / `jtbl_family_bank`; `o0_subsplit` refuses main only — check what it says for resident); +ov_SC02_017 `func_80186C64` (209), ov_SC05_010 `func_8017FFA8` (88) via `jtbl_carve`; md_MAIN_034 +`func_800CB00C` (152) sits in `config/wave_exclude.txt` as "WALL: compiler wall (S68)" — it is B-CARVE in the +census, so re-probe it under the CURRENT carve tooling before believing the S68 label (memory +`reprobe-exclude-lists-after-tool-fixes`; `exclude_audit` keeps it only because it is pinned). `split_indicator.py` +is the carve oracle (tools-health runs it as a hard gate): a subseg owning raw tables in >1 non-adjacent span +must be split before any switch function in it can bank. Read `docs/matching-cookbook.md` §486 (the 5-piece +manual carve) and §53 before carving. +**H-VIRGIN `D_800D3200` (md_MAIN_003):** a data word mis-sliced as a stub — a splat symbol type fix in +`config/splat.md_MAIN_003.yaml` / its symbols file (declare the word as data), then re-extract md_MAIN_003; it +should vanish from `corpus.stubs` without any C. +**Gate/verify per binary:** overlays/modules through `gate_stage`/`parallel_gate` (each carve edits that +binary's yaml — R60: a gate commits only its own binary's carve-state lines; `interleave_check` + `pads_audit` +after any yaml touch); resident through its own path; then `twin_rescan`, R22 fleet, `frontier_classify --json`, +docs (cookbook idioms if any new), checkpoint, one commit per binary or per class (R42: commit before the next +command that can touch src/). # 7. TASKS #6–#11 — CARRIED CONTEXT -* #6: `tools/twin_rescan.py` / `family_remap` for the ov_SC04_018 pair (`func_80181804`/`func_80181CB8`, - twin ov_SC04_019); jtbl carves via `jtbl_carve`/`jtbl_family_bank` (resident `func_800D06E8` 344 + - `func_800D128C` 243 need the resident carve path; `o0_subsplit` refuses main → the §486 manual 5-piece - procedure for `PadInfoAct`); `D_800D3200` = splat symbol type fix. +* #6: see §6 above (`PadInfoAct` is gone with the band — no main carve left in this class). * #7: bodies proven (close=0); the TU's spelling refuses — `recover_route.py` (routes a DROP to the applicable tool), `cast_self_callers`, `sync_tu_decls`, `--sync-decls`; prove plumbing byte-neutral BEFORE gating and commit the plumbing before the gate (S77 laws). `gate_main.py` is the ONLY main gate. @@ -8212,10 +8240,11 @@ Fresh-clone note (SETUP): `.run/obj42` is regenerable from the tracked 7z — do * #9: single agents with `journal_notes.py` + `neighbor_ref` (via `claude_wave_packs`); the 3 GAME-GTE UNCERTAIN bodies get a verbatim-vs-C verdict first. Route models per the ladder (Haiku ≤50 ins → Sonnet → Opus; Fable only for a NEW wall class). -* #10: ratify PERMANENT in the manifest `_README` (33 rows now; expected ≈ 9 truly permanent); decompile - `main()` (509 ins, GAME-C) + the md_MAIN_003 -O0 cluster. -* #11: PhaseEnd per the format; the 5 unclaimed payloads as the explicit exclusion; wall ledger with proofs; - the dashboard on the corrected denominators (main 91.1%-class numbers, LINKED 1,150). +* #10: ratify the 5 PERMANENT rows in the manifest `_README` (6 rows now); decompile `ov_SC03_107:func_8017D878` + (GAME-C, the one DECOMPILE-NOW), `main()` (509 ins) + the md_MAIN_003 -O0 cluster. +* #11: PhaseEnd per the format; the 5 unclaimed payloads as the explicit exclusion; wall ledger with proofs + (3 pinned walls left: md_MAIN_034 `func_800CB00C` (re-probe in #6), ov_SC03_105 `func_801834A4`, ov_SC06_022 + `func_8017DF28`); the dashboard on the corrected denominators (main 93.3% / 99.2% byte-identical, LINKED 1,256). # 8. HABITS THIS SESSION PAID FOR (keep) * Design before code, and probe the design's PREDICTION before trusting it: the raw objects failed by exactly @@ -8225,6 +8254,11 @@ Fresh-clone note (SETUP): `.run/obj42` is regenerable from the tracked 7z — do * Put a transformation in the shared prepare path, then negative-control it over the whole population it now touches (235 objects) — the R39 control caught the end-pointer refusal that the three targets never showed. * Confirm every derived cut against an oracle that did not derive it (the other objects' by-name recoveries). +* Provenance → archive → link → compiler, in that order (§490): twelve "walls" and a 383 KB download. +* Every "linked" list must be DERIVED from the Makefile (R51): two hard-coded copies (exclude pins, the census) + each lied the day the link state changed. +* Edit the LIVE checkpoint block through a slice of the file that starts at its own header: the S78 and S79 + blocks share every section heading, and `str.index` on a heading duplicated a region twice this session. # 9. PLAIN ENGLISH Three chunks of the main program had been treated for months as "Sony library code we can't link because @@ -8237,5 +8271,8 @@ changed; the accounting is just more honest: 47 fewer "hand-matched" functions t 110 more linked library functions, and the remaining work is exactly what it was — 51 functions with named reasons. Then the bounded search for the exact Sony controller-library version the game shipped with found it in under an hour: a small archive on archive.org holds Sony's February-1998 controller-library patch, and every -one of its pieces matches the game byte for byte. The hardest-looking stretch of the main program can now be -linked straight from Sony's library instead of rewritten by hand. Next: wire it in. +one of its pieces matches the game byte for byte. We then wired it in: the hardest-looking stretch of the main +program — twelve functions carried as "compiler walls", plus the controller and BIOS-call code around it — +now links straight from Sony's library instead of being rewritten by hand. Main's open functions went from 29 +to 16 and the whole game's from 51 to 38; nothing about the game changed. Next: the mechanical leftovers (two +twin functions, five jump-table carves, one mis-typed data word). diff --git a/src/800c2.c b/src/800c2.c deleted file mode 100644 index 1982901df2..0000000000 --- a/src/800c2.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "common.h" - -#include "common.h" - -struct Rec { - char *name; /* 0x00 */ - u8 pad04[0x30]; /* 0x04 */ - s32 (*callback)(); /* 0x34 */ - u8 pad38[0x18]; /* 0x38 */ -}; - -extern u8 D_80078CE0[]; -extern s32 D_80078CD8; -extern s32 func_8005C4DC(); -extern s32 firstfile2(); -extern void func_80062144(); - -s32 firstfile(char *name, s32 mode) -{ - u8 *src; - u8 *dst; - struct Rec *base; - struct Rec *rec; - u32 n; - s32 found; - - src = (u8 *)name; - dst = D_80078CE0; - while ((s8)*src > ':') { - *dst++ = *src++; - } - *dst = 0; - - n = *(u32 *)0x154 / 80; - base = *(struct Rec **)0x150; - for (rec = base; rec < base + n; rec++) { - if (rec->name != NULL && func_8005C4DC(rec->name, D_80078CE0) == 0) { - D_80078CD8 = (s32)rec->callback; - found = 1; - goto done; - } - } - found = 0; -done: - if (found == 0) { - return 0; - } - - n = *(u32 *)0x154 / 80; - base = *(struct Rec **)0x150; - for (rec = base; rec < base + n; rec++) { - if (rec->name != NULL && func_8005C4DC(rec->name, D_80078CE0) == 0) { - rec->callback = (s32 (*)())func_80062144; - break; - } - } - return firstfile2(name, mode); -} - - -INCLUDE_ASM("asm/nonmatchings/800c2", func_80062144); diff --git a/src/800c2_2.c b/src/800c2_2.c deleted file mode 100644 index b796b43e98..0000000000 --- a/src/800c2_2.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "common.h" - -__asm__( - ".text\n" - ".align 2\n" - ".globl SetInitPadFlag\n" - ".ent\tSetInitPadFlag\n" - "SetInitPadFlag:\n" - ".frame $sp,0,$31\n" - ".mask 0x00000000,0\n" - ".fmask 0x00000000,0\n" - ".set\tnoreorder\n" - "lui $at, %hi(D_80072A24)\n" - "jr $ra\n" - "sw $a0, %lo(D_80072A24)($at)\n" - ".set\treorder\n" - ".end\tSetInitPadFlag\n" -); - -extern s32 D_80072A24; - -s32 ReadInitPadFlag(void) -{ - return D_80072A24; -} - -extern void _remove_ChgclrPAD(void); -extern void func_8005CF08(void); -extern void _patch_pad(void); -extern void func_8005CF18(void); -extern s32 ChangeClearPAD(s32 mode); -extern s32 func_8006252C(void); -extern s32 PAD_init2(s32, s32, s32, s32); -extern s32 D_80072A24; - -void PAD_init(s32 a0, s32 a1, s32 a2, s32 a3) -{ - _remove_ChgclrPAD(); - func_8005CF08(); - _patch_pad(); - func_8005CF18(); - ChangeClearPAD(0); - ((s32 (*)())func_8006252C)(); - PAD_init2(a0, a1, a2, a3); - D_80072A24 = 1; -} - - - -extern void _remove_ChgclrPAD(void); -extern void func_8005CF08(void); -extern void _patch_pad(void); -extern void func_8005CF18(void); -extern s32 ChangeClearPAD(s32 mode); -extern s32 func_8006252C(void); -extern void InitPAD2(s32 a0, s32 a1, s32 a2, s32 a3); -extern s32 D_80072A24; - -void InitPAD(s32 a0, s32 a1, s32 a2, s32 a3) -{ - _remove_ChgclrPAD(); - func_8005CF08(); - _patch_pad(); - func_8005CF18(); - ChangeClearPAD(0); - ((s32 (*)())func_8006252C)(); - InitPAD2(a0, a1, a2, a3); - D_80072A24 = 1; -} - -extern void StartPAD2(void); -extern s32 ChangeClearPAD(s32 mode); -extern void EnablePAD(void); - -s32 StartPAD(void) -{ - StartPAD2(); - ChangeClearPAD(0); - EnablePAD(); - return 1; -} - -extern void DisablePAD(void); -extern void StopPAD2(void); -extern s32 func_800625A4(void); -extern s32 D_80072A24; - -void StopPAD(void) -{ - DisablePAD(); - StopPAD2(); - func_800625A4(); - D_80072A24 = 0; -} - -extern void func_8005CF08(void); -extern void func_8005CF18(void); -extern s32 SysDeqIntRP(s32 priority, void *intr); -extern s32 SysEnqIntRP(s32 priority, void *intr); -extern s32 func_800625DC(void); -extern s32 func_80062644(void); -extern s32 D_80078D0C; -extern u8 D_80078D08[]; -extern s32 D_80078D14; - -s32 func_8006252C(void) { - s32 *p; - s32 *q; - s32 pri; - - func_8005CF08(); - pri = 1; - __asm__ __volatile__("" : "=r"(pri) : "0"(pri)); - p = &D_80078D0C; - __asm__ __volatile__("" : "=r"(p) : "0"(p)); - q = p - 1; - p[0] = (s32)func_800625DC; - p[1] = (s32)func_80062644; - *(s32 *)D_80078D08 = 0; - D_80078D14 = 0; - SysDeqIntRP(pri, q); - SysEnqIntRP(1, q); - func_8005CF18(); - return 1; -} - -extern void func_8005CF08(void); -extern void func_8005CF18(void); -extern s32 SysDeqIntRP(s32 priority, void *intr); -extern unsigned char D_80078D08[]; - -s32 func_800625A4(void) { - func_8005CF08(); - SysDeqIntRP(1, &D_80078D08); - func_8005CF18(); - return 1; -} - -extern u8 *D_80072A28; - -s32 func_800625DC(void) { - volatile s32 i; - s32 frame_pad[2]; - - (void)&frame_pad; - *(u16 *)(D_80072A28 + 10) = 0; - i = 10; - if (--i != -1) { - do { - } while (--i != -1); - } - return 0; -} - -s32 func_80062644(void) { - extern s32 *D_80072A2C; - s32 *p = D_80072A2C; - - if ((p[1] & 1) == 0) { - return 0; - } - if ((p[0] & 1) != 0) { - return 1; - } - if ((p[0] & 1) != 0) { - return 1; - } - return 0; -} - -__asm__(".word 0x00000000\n"); diff --git a/src/800c2_3.c b/src/800c2_3.c deleted file mode 100644 index 1af2276fd5..0000000000 --- a/src/800c2_3.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "common.h" - -__asm__( - ".text\n" - ".align 2\n" - ".globl EnablePAD\n" - ".ent\tEnablePAD\n" - "EnablePAD:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "lui $t1, %hi(jtbl_80078D20_main)\n" - "lw $t1, %lo(jtbl_80078D20_main)($t1)\n" - "nop\n" - "jr $t1\n" - "nop\n" - ".set\treorder\n" - ".end\tEnablePAD\n" -); - -__asm__( - ".text\n" - ".align 2\n" - ".globl DisablePAD\n" - ".ent\tDisablePAD\n" - "DisablePAD:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "lui $t1, %hi(jtbl_80078D24_main)\n" - "lw $t1, %lo(jtbl_80078D24_main)($t1)\n" - "nop\n" - "jr $t1\n" - "nop\n" - ".set\treorder\n" - ".end\tDisablePAD\n" -); - -__asm__( - ".text\n" - ".align 2\n" - ".globl _patch_pad\n" - ".ent\t_patch_pad\n" - "_patch_pad:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "lui $at, %hi(D_80078D18)\n" - "sw $ra, %lo(D_80078D18)($at)\n" - "jal func_8005CF08\n" - "nop\n" - "addiu $t1, $0, 87\n" - "addiu $t2, $0, 176\n" - "jalr $t2\n" - "nop\n" - "lw $v0, 364($v0)\n" - "addiu $t1, $0, 11\n" - "addi $v1, $v0, 2180\n" - "lui $at, %hi(jtbl_80078D20_main)\n" - "sw $v1, %lo(jtbl_80078D20_main)($at)\n" - "addi $v1, $v0, 2196\n" - "lui $at, %hi(jtbl_80078D24_main)\n" - "sw $v1, %lo(jtbl_80078D24_main)($at)\n" - ".L80062730:\n" - "sw $0, 1428($v0)\n" - "addiu $v0, $v0, 4\n" - "addiu $t1, $t1, -1\n" - "bnez $t1, .L80062730\n" - "nop\n" - "jal FlushCache\n" - "nop\n" - "lui $ra, %hi(D_80078D18)\n" - "lw $ra, %lo(D_80078D18)($ra)\n" - "nop\n" - "jr $ra\n" - "nop\n" - ".set\treorder\n" - ".end\t_patch_pad\n" - "nop\n" - "nop\n" -); - -/* Handwritten function (splat header) — banked verbatim per §265 form 1. - * Recovered semantics: - * D_80078D28 = return address; func_8005CF08(); call vector 0xB0 ($t2=176); - * p = (*(ret + 0x16C)) + 0x62C; for (i = 9; i; --i) *p++ = 0; - * FlushCache(); func_8005CF18(); return via saved $ra. - * NOTE: maspsx did NOT auto-insert load-delay nops here (after - * "lw $v0,364($v0)" and "lw $ra,%lo(D_80078D28)($ra)") — both written by - * hand, matching the banked sibling _patch_pad in this same TU; this - * contradicts §179-B rule 4 as observed on this build. - */ -__asm__( - ".text\n" - ".align 2\n" - ".globl _remove_ChgclrPAD\n" - ".ent\t_remove_ChgclrPAD\n" - "_remove_ChgclrPAD:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "lui $at, %hi(D_80078D28)\n" - "sw $ra, %lo(D_80078D28)($at)\n" - "jal func_8005CF08\n" - "nop\n" - "addiu $t1, $0, 87\n" - "addiu $t2, $0, 176\n" - "jalr $t2\n" - "nop\n" - "addiu $t2, $0, 9\n" - "lw $v0, 364($v0)\n" - "nop\n" - "addi $v1, $v0, 1580\n" - ".L80062798:\n" - "sw $0, 0($v1)\n" - "addiu $v1, $v1, 4\n" - "addiu $t2, $t2, -1\n" - "bnez $t2, .L80062798\n" - "nop\n" - "jal FlushCache\n" - "nop\n" - "jal func_8005CF18\n" - "nop\n" - "lui $ra, %hi(D_80078D28)\n" - "lw $ra, %lo(D_80078D28)($ra)\n" - "nop\n" - "jr $ra\n" - "nop\n" - ".set\treorder\n" - ".end\t_remove_ChgclrPAD\n" - "nop\n" - "nop\n" -); diff --git a/src/800c3.c b/src/800c3.c deleted file mode 100644 index b2ac114fb5..0000000000 --- a/src/800c3.c +++ /dev/null @@ -1,1771 +0,0 @@ -#include "common.h" -/* hoisted by gate_main so drafts above can reuse them (§181) */ -typedef struct Entry { - /* 0x00 */ u8 b0; - /* 0x01 */ u8 unk1[3]; - /* 0x04 */ u8 *p4; -} Entry; /* size 8 */ -typedef struct Ctx { - /* 0x00 */ s16 *p00; - /* 0x04 */ u8 *p04; - /* 0x08 */ Entry *p08; - /* 0x0C */ u8 unk0C[0x3C - 0x0C]; - /* 0x3C */ u8 *p3C; - /* 0x40 */ u8 unk40[0x46 - 0x40]; - /* 0x46 */ u8 b46; - /* 0x47 */ u8 b47; - /* 0x48 */ u8 b48; - /* 0x49 */ u8 b49; - /* 0x4A */ u8 unk4A[0xE3 - 0x4A]; - /* 0xE3 */ u8 bE3; - /* 0xE4 */ u8 unkE4[0xE9 - 0xE4]; - /* 0xE9 */ u8 bE9; - /* 0xEA */ u8 bEA; -} Ctx; - -__asm__(".text\n.align 2\n.globl InitHeap\n.ent\tInitHeap\n" - "InitHeap:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xA0\n" - "jr $t2\n" - "addiu $t1, $zero, 0x39\n" - "nop\n" - ".set\treorder\n.end\tInitHeap\n"); - - -__asm__(".text\n.align 2\n.globl FlushCache\n.ent\tFlushCache\n" - "FlushCache:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 160\n" - "jr $t2\n" - "addiu $t1, $zero, 68\n" - "nop\n" - ".set\treorder\n.end\tFlushCache\n"); - - -__asm__(".text\n.align 2\n.globl func_8005CE38\n.ent\tfunc_8005CE38\n" - "func_8005CE38:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xA0\n" - "jr $t2\n" - "addiu $t1, $zero, 0x49\n" - "nop\n" - ".word 0x21007350\n" - ".word 0x004236AD\n" - ".set\treorder\n.end\tfunc_8005CE38\n"); - -__asm__(".text\n.align 2\n.globl _96_remove\n.ent\t_96_remove\n" - "_96_remove:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 160\n" - "jr $t2\n" - "addiu $t1, $zero, 114\n" - "nop\n" - "nop\n" - "nop\n" - ".set\treorder\n.end\t_96_remove\n"); - -asm( - ".section .text\n" - ".globl DeliverEvent\n" - ".set noreorder\n" - "DeliverEvent:\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 7\n" - "nop\n" - ".set reorder\n" -); - -__asm__(".text\n.align 2\n.globl OpenEvent\n.ent\tOpenEvent\n" - "OpenEvent:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xB0\n" - "jr $t2\n" - "addiu $t1, $zero, 0x8\n" - "nop\n" - ".set\treorder\n.end\tOpenEvent\n"); - -__asm__(".text\n.align 2\n.globl CloseEvent\n.ent\tCloseEvent\n" - "CloseEvent:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xB0\n" - "jr $t2\n" - "addiu $t1, $zero, 0x9\n" - "nop\n" - ".set\treorder\n.end\tCloseEvent\n"); - -__asm__( - ".text\n" - ".align 2\n" - ".globl WaitEvent\n" - ".ent\tWaitEvent\n" - "WaitEvent:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "addiu $t2, $0, 176\n" - "jr $t2\n" - "addiu $t1, $0, 10\n" - ".set\treorder\n" - ".end\tWaitEvent\n" - "nop\n" -); - -__asm__(".text\n.align 2\n.globl TestEvent\n.ent\tTestEvent\n" - "TestEvent:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xB0\n" - "jr $t2\n" - "addiu $t1, $zero, 0xB\n" - "nop\n" - ".set\treorder\n.end\tTestEvent\n"); - -__asm__(".text\n.align 2\n.globl EnableEvent\n.ent\tEnableEvent\n" - "EnableEvent:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 12\n" - "nop\n" - ".set\treorder\n.end\tEnableEvent\n"); - -__asm__( - ".text\n" - ".align 2\n" - ".globl DisableEvent\n" - ".ent\tDisableEvent\n" - "DisableEvent:\n" - ".frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $10, $0, 176\n" - "jr $10\n" - "addiu $9, $0, 13\n" - "nop\n" - ".set\treorder\n" - ".end\tDisableEvent\n" -); - - -__asm__( - ".text\n" - ".align 2\n" - ".globl ReturnFromException\n" - ".ent\tReturnFromException\n" - "ReturnFromException:\n" - ".frame $sp, 0, $31\n" - ".mask 0x00000000, 0\n" - ".fmask 0x00000000, 0\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 23\n" - ".set\treorder\n" - ".end\tReturnFromException\n" - "nop\n" -); - -/* §295 kernel-trap trampoline: A/B/C dispatch vector in $t2, syscall # in the jr delay slot; - * unreachable from C (§179-C) -> file-scope verbatim asm (§265 form 1). Pad nop is load-bearing (stride 0x10). */ -__asm__(".text\n.align 2\n.globl ResetEntryInt\n.ent\tResetEntryInt\n" - "ResetEntryInt:\n.frame $sp,0,$31\n.mask 0x00000000,0\n.fmask 0x00000000,0\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 24\n" - "nop\n" - ".set\treorder\n.end\tResetEntryInt\n"); - -/* §295 kernel-trap trampoline: A/B/C dispatch vector in $t2, syscall # in the jr delay slot; - * unreachable from C (§179-C) -> file-scope verbatim asm (§265 form 1). Pad nop is load-bearing (stride 0x10). */ -__asm__(".text\n.align 2\n.globl HookEntryInt\n.ent\tHookEntryInt\n" - "HookEntryInt:\n.frame $sp,0,$31\n.mask 0x00000000,0\n.fmask 0x00000000,0\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 25\n" - "nop\n" - ".set\treorder\n.end\tHookEntryInt\n"); - -void func_8005CF08(void) { - __asm__ volatile( - "addiu $a0, $zero, 0x1\n\t" - "syscall" - ); -} - -void func_8005CF18() { - __asm__ __volatile__( - ".set\tnoreorder\n" - "addiu $a0, $zero, 2\n" - "syscall 0\n" - ".set\treorder\n" - ); -} - -/* §295 kernel-trap trampoline: A/B/C dispatch vector in $t2, syscall # in the jr delay slot; - * unreachable from C (§179-C) -> file-scope verbatim asm (§265 form 1). Pad nop is load-bearing (stride 0x10). */ -__asm__(".text\n.align 2\n.globl read\n.ent\tread\n" - "read:\n.frame $sp,0,$31\n.mask 0x00000000,0\n.fmask 0x00000000,0\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 176\n" - "jr $t2\n" - "addiu $t1, $zero, 52\n" - "nop\n" - ".set\treorder\n.end\tread\n"); - -__asm__(".text\n.align 2\n.globl write\n.ent\twrite\n" - "write:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xB0\n" - "jr $t2\n" - "addiu $t1, $zero, 0x35\n" - "nop\n" - ".set\treorder\n.end\twrite\n"); - -__asm__(".text\n.align 2\n.globl ChangeClearPAD\n.ent\tChangeClearPAD\n" - "ChangeClearPAD:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $10, $0, 0xB0\n" - "jr $10\n" - "addiu $9, $0, 0x5B\n" - ".set\treorder\n.end\tChangeClearPAD\n" - "nop\n"); - -__asm__(".text\n.align 2\n.globl ChangeClearRCnt\n.ent\tChangeClearRCnt\n" - "ChangeClearRCnt:\n.frame $sp,0,$31\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 0xC0\n" - "jr $t2\n" - "addiu $t1, $zero, 0xA\n" - "nop\n" - ".set\treorder\n.end\tChangeClearRCnt\n"); - - -extern u32 D_80072938; - -s32 SetRCnt(s32 a0, s16 a1, s32 a2) { - register s32 t0 __asm__("$8"); - register s32 a3 __asm__("$7"); - register s32 a0p __asm__("$4"); - u32 v1; - - t0 = a0 & 0xFFFF; - - if (t0 >= 3) { - return 0; - } - - a3 = 0x48; - v1 = (t0 << 4) + *(u32*)&D_80072938; - - *(u16*)(v1 + 4) = 0; - { - s32 lt2 = t0 < 2U; - *(u16*)(v1 + 8) = a1; - __asm__ __volatile__("" : : "r"(lt2)); - if (lt2) { - if (a2 & 0x10) { - a3 = 0x49; - } - if (!(a2 & 0x1)) { - a3 |= 0x100; - } - } else if (t0 == 2U) { - if (!(a2 & 0x1)) { - a3 = 0x248; - } - } - } - - if (a2 & 0x1000) { - a3 |= 0x10; - } - - { - register s32 ret __asm__("$2"); - ret = 1; - __asm__ __volatile__("" : : "r"(ret)); - a0p = *(s32*)&D_80072938; - v1 = t0 << 4; - v1 = v1 + (u32)a0p; - *(u16*)(v1 + 4) = a3; - return ret; - } -} - -extern u32 D_80072938; - -s32 GetRCnt(s32 spec) { - register s32 v1 __asm__("$3"); - s32 ret; - - v1 = spec & 0xFFFF; - if (v1 < 3) { - v1 = (v1 << 4) + D_80072938; - ret = *(u16 *) v1; - } else { - ret = 0; - } - return ret; -} - -extern s32 D_80072934; -extern s32 D_8007293C[]; - -s32 StartRCnt(s32 spec) { - s32 t; - - t = spec & 0xFFFF; - *(s32 *)(D_80072934 + 4) |= D_8007293C[t]; - return t < 3; -} - -extern s32 D_80072934; -extern s32 D_8007293C[]; - -s32 StopRCnt(s32 spec) { - s32 t; - - t = spec & 0xFFFF; - *(s32 *)(D_80072934 + 4) &= ~D_8007293C[t]; - return 1; -} - -extern u32 D_80072938; - -s32 ResetRCnt(s32 spec) { - s32 v1 = spec & 0xFFFF; - if (v1 >= 3) { - return 0; - } - *(u16 *)((v1 << 4) + *(u32 *)&D_80072938) = 0; - return 1; -} - -__asm__(".word 0x00000000"); - -extern s32 _padChkVsync(void); - -void PadChkVsync(void) { - _padChkVsync(); -} - -extern void _padStartCom(void); - -void PadStartCom(void) { - _padStartCom(); -} - -extern void _padStopCom(void); - -void PadStopCom(void) { - _padStopCom(); -} - -extern s32 D_800729A8; -extern s32 D_80072990; - -s32 PadChkMtap(s32 arg0) { - if (D_800729A8 != 0) { - return *(u8 *)(D_80072990 + (arg0 >> 4) * 0xF0 + 0xE8) == 8; - } - return 0; -} - - -extern void* (*D_80072970)(void); - -s32 PadGetState(s32 arg0) { - void* v0; - register s32 v1 __asm__("$3"); - - v0 = D_80072970(); - - if ((*(u32*)((u8*)v0 + 0x34) & 0xFFFF0000) != 0) { - goto do_switch; - } - if ((u32)v0 == *(u32*)((u8*)v0 + 0x10)) { - goto check30; - } - if (*(u8*)((u8*)v0 + 0x38) != 0) { - goto do_switch; - } -check30: - if (*(u8*)*(u32*)((u8*)v0 + 0x30) == 0) { - goto return_byte; - } - -do_switch: - v1 = *(u8*)((u8*)v0 + 0x49); - - if (v1 == 3) { - goto return_one; - } - if (v1 < 4) { - if (v1 == 2) { - goto return_one; - } - goto return_byte; - } - if (v1 == 6) { - goto return_four; - } - goto return_byte; - -return_one: - return 1; - -return_four: - return 4; - -return_byte: - return *(u8*)((u8*)v0 + 0x49); -} - -extern void* (*D_80072970)(void); - -s32 PadInfoMode(s32 arg0, s32 arg1, s32 arg2) { - void *p; - - p = (*D_80072970)(); - switch (arg1) { - case 1: - return *(u8 *)((char *)p + 0xE8); - case 2: - return *(u16 *)((char *)p + 0xE6); - case 3: - return *(u8 *)((char *)p + 0xE4); - case 4: - if (arg2 < 0) { - return *(u8 *)((char *)p + 0xE3); - } - if (arg2 < *(u8 *)((char *)p + 0xE3)) { - return *(u16 *)(*(u32 *)p + arg2 * 2); - } - return 0; - case 100: - return *(u32 *)((char *)p + 0x4C); - default: - return 0; - } -} - - -INCLUDE_ASM("asm/nonmatchings/800c3", PadInfoAct); - -extern void* (*D_80072970)(void); - -extern void* (*D_80072970)(void); - -extern void* (*D_80072970)(void); - -s32 PadInfoComb(s32 arg0, s32 arg1, s32 arg2) { - u8 *p; - - p = (u8 *)(*D_80072970)(); - if (arg1 < 0) { - return *(p + 0xEA); - } - if (arg1 >= *(p + 0xEA)) { - return 0; - } - p = *(u8 **)(p + 8) + (arg1 << 3); - if (arg2 < 0) { - return *p; - } - if (arg2 >= *p) { - return 0; - } - return *(*(u8 **)(p + 4) + arg2); -} - -extern void* (*D_80072970)(void); -extern s32 _padSetActAlign(void *a0, void *a1); - -void PadSetActAlign(void *a0, void *a1) { - ((s32 (*)())_padSetActAlign)(D_80072970(), a1); -} - -extern void* (*D_80072970)(void); - -void PadSetMainMode(s32 arg0, s32 arg1, s32 arg2) { - _padSetMainMode(D_80072970(), (u8)arg1, (u8)arg2); -} - -extern void* (*D_80072970)(void); - -void PadSetAct(s32 arg0, void *arg1, s32 arg2) { - _padSetAct(D_80072970(), arg1, arg2); -} -__asm__("nop\nnop\n"); - - - - - -u32 PadEnableCom(u32 arg0) { - - extern void (*D_80072960)(void *); - extern u32 D_80072994; - extern u32 D_800729AC; - extern u32 D_800729B0; - extern s32 D_80078998; - extern s32 D_8007899C; - u32 ret; - s32 *p1; - s32 *p2; - - ret = (D_800729B0 << 1) | (D_800729AC == 0); - if (ret == arg0) { - return ret; - } - D_80072994 = 0; - if (arg0 & 1) { - p1 = &D_80078998; - D_800729AC = 0; - if (*p1 > 0x95) { - (*D_80072960)(D_80072990); - } - *p1 = 0; - } else { - D_800729AC = 1; - } - if (arg0 & 2) { - p2 = &D_8007899C; - D_800729B0 = 1; - if (*p2 > 0x95) { - (*D_80072960)(D_80072990 + 0xF0); - } - *p2 = 0; - } else { - D_800729B0 = 0; - } - D_80072994 = 1; - return ret; -} - -void _padSetVsyncParam(void) { - extern s32 D_8007898C; - extern void func_8005D734(void); - extern void func_8005D6CC(void); - s32 *base = (s32 *)&D_8007898C; - __asm__ __volatile__("" : "=r"(base) : "0"(base)); - *(s32 *)((s32)base + 0x0) = (s32)func_8005D734; - *(s32 *)((s32)base + 0x4) = (s32)func_8005D6CC; - *(s32 *)((s32)base - 0x4) = 0; - *(s32 *)((s32)base + 0x8) = 0; -} - -extern s32 *D_800729BC; -extern void (*D_80072984)(void); - -s32 func_8005D6CC(void) { - s32 *ptr = D_800729BC; - - if ((*(s32 *)((s8 *)ptr + 4) & 1) == 0) { - return 0; - } - if ((*ptr & 1) == 0) { - return 0; - } - if (D_80072984 != NULL) { - (*D_80072984)(); - } - return 1; -} - -/* func_8005D734 — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/func_8005D734.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005D734); - -extern s32 D_800729C4; - -asm( - ".section .text\n" - ".set noreorder\n" - "_padChkVsync:\n" - "lui $v0, %hi(D_800729C4)\n" - "lw $v0, %lo(D_800729C4)($v0)\n" - "lui $at, %hi(D_800729C4)\n" - "jr $ra\n" - "sw $zero, %lo(D_800729C4)($at)\n" - ".set reorder\n"); - -s32 _padChkVsync(void); - - - -INCLUDE_ASM("asm/nonmatchings/800c3", _padStartCom); - -extern void func_8005CF08(void); -extern void func_8005CF18(void); -extern s32 ChangeClearRCnt(s32 intr, s32 mode); -extern s32 SysDeqIntRP(s32 priority, void *intr); -extern unsigned char D_80078988[]; - -void _padStopCom(void) -{ - func_8005CF08(); - ChangeClearRCnt(3, 1); - SysDeqIntRP(2, &D_80078988); - func_8005CF18(); -} - -INCLUDE_ASM("asm/nonmatchings/800c3", _padInitSioMode); - -extern s32 D_800729A0; -extern s32 (*D_800729E0[])(); -extern s32 (*D_8007295C)(); - -s32 _padClrIntSio0(void); -void setRC2wait(s32 a0); - -void func_8005DBD8(void) { - s32 (*fp)(); - register s32 idx __asm__("$3"); - register s32 ret __asm__("$4"); - register s32 *p __asm__("$5"); - - p = &D_800729A0; - idx = p[0]; - fp = D_800729E0[idx]; - p[0] = idx + 1; - ret = fp(); - if (ret >= 0) { - if (D_800729A0 != 0) { - setRC2wait(0x3C); - if (_padClrIntSio0() == 0) { - (*D_8007295C)(-3); - } - } - if (D_800729A0 >= 5) { - D_800729A0 = D_800729A0 - 1; - } - return; - } - (*D_8007295C)(ret); -} - - -extern s32 *D_800729BC; -extern s32 *D_800729C0; -extern volatile s32 D_80078F24; -extern volatile s32 D_800C5320; - -s32 chkRC2wait(void); - -s32 _padSioRW(s32 ctx, s32 cmd) { - u8 tmp; - s32 first; - u16 t; - s32 hw; - u16 status; - s32 c; - u16 *port; - - if (cmd < 0) { - tmp = *(u8 *)D_800729C0; - *(u8 *)(ctx + 0x44) = 0xFF; - *(u8 *)(ctx + 0x45) = 1; - *(u8 *)*(s32 *)(ctx + 0x40) = ~cmd; - first = tmp; - if ((*(volatile u16 *)((s8 *)D_800729C0 + 0x4) & 1) == 0) { - do {} while ((*(volatile u16 *)((s8 *)D_800729C0 + 0x4) & 1) == 0); - } - while (chkRC2wait() == 0) {} - { - register u8 nv __asm__("$2"); - nv = ~cmd; - *(u8 *)D_800729C0 = nv; - } - return first; - } - t = 0x88; - c = *(u8 *)*(s32 *)(ctx + 0x3C); - if ((c >> 4) == 8 && *(u8 *)(ctx + 0x44) >= 9) { - t = 0x22; - } - port = (u16 *)0x1F801120; - __asm__("" : "=r"(port) : "0"(port)); - hw = *port; - status = *(volatile u16 *)((s8 *)D_800729C0 + 0x4); - D_800C5320 = 0x1AE; - D_80078F24 = hw; - if ((status & 2) == 0) { - do {} while ((*(volatile u16 *)((s8 *)D_800729C0 + 0x4) & 2) == 0); - } - { - s32 *ptr = D_800729BC; - tmp = *(u8 *)D_800729C0; - *(u16 *)((s8 *)D_800729C0 + 0xE) = t; - first = tmp; - if ((*ptr & 0x80) == 0) { - do { - if (chkRC2wait() != 0) { - goto err; - } - } while ((*D_800729BC & 0x80) == 0); - } - } - *(u8 *)D_800729C0 = cmd; - *(u8 *)(ctx + 0x45) += 1; - *(u8 *)(*(s32 *)(ctx + 0x3C) + *(u8 *)(ctx + 0x44)) = first; - { - register u8 inc __asm__("$2"); - inc = *(u8 *)(ctx + 0x44); - inc += 1; - *(u8 *)(ctx + 0x44) = inc; - } - return first; -err: - return -20; -} - - -/* _padSioRW2 — libcd command issue with a root-counter-1 timeout spin. - * Structure is _padSioRW's (same TU) with chkRC2wait's body INLINED as the - * loop test; the four levers that closed it: - * 1. `u8 tmp; s32 first; tmp = *(volatile u8 *)p; first = tmp;` — the volatile QI - * load blocks combine from folding the u8->s32 promotion into the lbu, so the - * zero-extend survives as its own `andi $s2,$v0,0xFF` (same idiom that produces - * `andi $v1,$v0,0xFFFF` after the 0x1F801120 lhu in banked chkRC2wait). - * 2. `if (A || B) {store t} else {store 0x22}` — do_jump's TRUTH_ORIF drop-through - * label puts the `t` arm as the fall-through; the `&&` spelling swaps the arms. - * 3. The 0xE store is VOLATILE: reorg's resource_conflicts_p returns 1 whenever - * either resource set is volatil, so `sh $s1,0xE($a0)` can never be stolen into - * the `j`'s delay slot — that is where the target's `nop` comes from. - * 4. A "memory"-clobber barrier inside the `!= 0xFF` arm kills the CSE that would - * otherwise reuse the compare's `lbu 0x44` for the index, forcing the reload. - * (A volatile index read reloads too, but flips the addu's operand order and - * lands the byte in $v0 instead of $v1.) - * D_80078F24/D_800C5320 are volatile, so they are read ONCE inside the `if` guard — - * loop.c cannot hoist a volatile MEM, and the target has them in the preheader. - */ - -extern s32 *D_800729BC; -extern s32 *D_800729C0; -extern volatile s32 D_80078F24; -extern volatile s32 D_800C5320; -extern s32 D_800729A0; - -void setRC2wait(s32 a0); -s32 chkRC2wait(void); - -s32 _padSioRW2(s32 ctx, s32 cmd) { - u8 tmp; - s32 first; - u16 t; - s32 c; - u16 val1; - s32 a0; - u16 status; - s32 base; - s32 lim; - - t = 0x88; - c = *(u8 *)*(s32 *)(ctx + 0x3C); - if ((c >> 4) == 8 && *(u8 *)(ctx + 0x44) >= 9) { - t = 0x22; - } - do {} while ((*(volatile u16 *)((s8 *)D_800729C0 + 0x4) & 2) == 0); - setRC2wait(0x190); - tmp = *(volatile u8 *)D_800729C0; - first = tmp; - if (*(u8 *)(ctx + 0x44) != 0 || (first >> 4) != 8) { - *(volatile u16 *)((s8 *)D_800729C0 + 0xE) = t; - } else { - *(volatile u16 *)((s8 *)D_800729C0 + 0xE) = 0x22; - } - if ((*D_800729BC & 0x80) == 0) { - base = D_80078F24; - lim = D_800C5320; - do { - val1 = *(volatile u16 *)0x1F801120; - a0 = val1; - if ((u32)a0 < (u32)base) { - if (*(volatile u16 *)0x1F801128 != 0) { - a0 += *(volatile u16 *)0x1F801128; - } else { - a0 += 0x10000; - } - } - status = *(volatile u16 *)0x1F801124; - if (status & 0x200) { - if ((u32)(a0 - base) >= (u32)lim) { - return -2; - } - } - if (((u32)(a0 - base) >> 3) >= (u32)lim) { - return -2; - } - } while ((*D_800729BC & 0x80) == 0); - } - if (*(u8 *)(ctx + 0xE8) != 8 && D_800729A0 == 2) { - setRC2wait(0x3C); - while (chkRC2wait() == 0) {} - } - *(u8 *)D_800729C0 = cmd; - *(u8 *)(ctx + 0x45) += 1; - if (*(u8 *)(ctx + 0x44) != 0xFF) { - __asm__ __volatile__("" : : : "memory"); - *(u8 *)(*(s32 *)(ctx + 0x3C) + *(u8 *)(ctx + 0x44)) = first; - } - *(u8 *)(ctx + 0x44) += 1; - return first; -} - - -extern s32 *D_800729BC; -extern s32 *D_800729C0; - -s32 chkRC2wait(void); - -s32 _padClrIntSio0(void) { - s32 *ptr1 = D_800729BC; - s32 *ptr2; - u16 v1_val; - - { - register s32 *pre_ptr2 __asm__("$4") = D_800729C0; - *ptr1 = -0x81; - if ((*(u16 *)((s8 *)pre_ptr2 + 0x4) & 0x80) != 0) { - do { - if (chkRC2wait() != 0) { - return 0; - } - } while ((*(u16 *)((s8 *)D_800729C0 + 0x4) & 0x80) != 0); - } - } - - ptr2 = D_800729C0; - v1_val = *(u16 *)((s8 *)ptr2 + 0xA); - *(u16 *)((s8 *)ptr2 + 0xA) = v1_val | 0x10; - return 1; -} - - -extern s32 *D_800729C0; - - -extern s32 *D_800729C0; - -void _padWaitRXready(void) { - s32 *ptr; - - ptr = D_800729C0; - __asm__ __volatile__("nop"); - while ((*(volatile u16 *)((s8 *)ptr + 0x4) & 0x2) == 0) - ; -} - -/* The word at 0x8005E164 is an orphan inter-function pad: _padWaitRXready's own - * .size is 0x28 (ends 0x8005E164) but SysEnqIntRP (config/symbols.us.txt) is - * fixed at 0x8005E168 — a 4-byte gap belonging to neither function. It is - * currently supplied by the INCLUDE_ASM stub's own verbatim .s inclusion; - * reproduce it here so the byte stream stays contiguous once this stub is - * replaced with real C. */ -__asm__(".text\n\tnop\n"); - -/* §295 kernel-trap trampoline: A/B/C dispatch vector in $t2, syscall # in the jr delay slot; - * unreachable from C (§179-C) -> file-scope verbatim asm (§265 form 1). Pad nop is load-bearing (stride 0x10). */ -__asm__(".text\n.align 2\n.globl SysEnqIntRP\n.ent\tSysEnqIntRP\n" - "SysEnqIntRP:\n.frame $sp,0,$31\n.mask 0x00000000,0\n.fmask 0x00000000,0\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 192\n" - "jr $t2\n" - "addiu $t1, $zero, 2\n" - "nop\n" - ".set\treorder\n.end\tSysEnqIntRP\n"); - -__asm__( - ".text\n" - ".align\t2\n" - ".globl\tSysDeqIntRP\n" - ".ent\tSysDeqIntRP\n" - "SysDeqIntRP:\n" - ".set\tnoreorder\n" - "addiu $t2, $zero, 192\n" - "jr $t2\n" - "addiu $t1, $zero, 3\n" - ".set\treorder\n" - ".end\tSysDeqIntRP\n" - "nop\n" -); - -void _padSetAct(s32 arg0, s32 arg1, s8 arg2) { - *(s32*)(arg0 + 0x28) = arg1; - *(u8*)(arg0 + 0x34) = arg2; -} - -void _padSetCmd(void *arg0, u8 arg1, u32 arg2, u8 arg3) { - *(u8 *)((u8 *)arg0 + 0x36) = arg1; - *(u32 *)((u8 *)arg0 + 0x2C) = arg2; - *(u8 *)((u8 *)arg0 + 0x35) = arg3; -} - -extern void func_8005EA54(); -extern void func_8005EA68(void *arg0, s32 arg1); -extern void func_8005EAA8(void *arg0, s32 arg1); - -void _padSendAtLoadInfo(void *arg0) { - switch (*(u8 *)((u8 *)arg0 + 0x46)) { - case 2: - func_8005EA54(arg0); - break; - case 3: - func_8005EA68(arg0, *(u8 *)((u8 *)arg0 + 0xE4)); - break; - case 4: - func_8005EAA8(arg0, *(u8 *)((u8 *)arg0 + 0x47)); - break; - } -} - -typedef struct { - /* 0x00 */ s16 *p00; - /* 0x04 */ u8 *p04; - /* 0x08 */ u8 *p08; - /* 0x0C */ u8 unk0C[0x3C - 0x0C]; - /* 0x3C */ u8 *p3C; - /* 0x40 */ u8 unk40[0x46 - 0x40]; - /* 0x46 */ u8 b46; - /* 0x47 */ u8 b47; - /* 0x48 */ u8 b48; - /* 0x49 */ u8 b49; - /* 0x4A */ u8 unk4A[0xE3 - 0x4A]; - /* 0xE3 */ u8 bE3; - /* 0xE4 */ u8 bE4; - /* 0xE5 */ u8 unkE5[0xE6 - 0xE5]; - /* 0xE6 */ u16 hE6; - /* 0xE8 */ u8 unkE8[0xE9 - 0xE8]; - /* 0xE9 */ u8 bE9; - /* 0xEA */ u8 bEA; - /* 0xEB */ u8 unkEB; - /* 0xEC */ u32 wEC; -} Ctx_8005E228; - -s32 _padGetActSize(); -s32 _padLoadActInfo(); - -s32 _padRecvAtLoadInfo(Ctx_8005E228 *s) { - u8 t; - switch (s->b46) { - case 2: - s->bE3 = s->p3C[3]; - s->bE4 = s->p3C[4]; - s->hE6 = 0; - s->bE9 = s->p3C[5]; - s->bEA = s->p3C[6]; - s->wEC = 0; - break; - case 3: - s->hE6 = (s->p3C[4] << 8) + s->p3C[5]; - s->b47 = 0; - break; - case 4: - s->wEC += 8 + ((s->p3C[4] + 3) & 0x1FC); - t = ++s->b47; - if (t < s->bEA) { - return 0; - } - if (_padGetActSize(s) >= 0x81) { - s->b46 = 0xFE; - s->b49 = 2; - } else { - s->b46 = 0xFF; - ((s32 (*)())_padLoadActInfo)(s, (u8 *)s + 0x63); - s->b46 = 2; - } - return 0; - } - return 1; -} - - -s32 _padGetActSize(u8 *a0) { - s32 t = ((a0[0xE3] + 1) / 2) * 4; - s32 m = (((a0[0xE9] * 5) + 3) & 0xFFC) + 4; - return t + m + *(u32 *)(a0 + 0xEC); -} - - - -extern s32 (*D_80072978)(void); -extern void func_8005E480(void *arg0); -extern s32 func_8005E528(Ctx *s); - -s32 _padLoadActInfo(Ctx *s, s32 size) { - register s32 ret __asm__("$2"); - register s32 t __asm__("$5"); - s32 tmp; - u8 n1; - u8 n2; - - if (size == 0) { - return 0; - } - if (s->p04 != 0) { - return 0; - } - if ((*D_80072978)() == 0) { - ret = 1; - __asm__ __volatile__("" : : "r"(ret)); - tmp = 4; - __asm__("" : "=r"(tmp) : "0"(tmp)); - t = (size + 3) >> 2; - s->b49 = tmp; - s->b46 = 1; - *(u32 *)((s8 *)s + 0x14) = (u32)func_8005E480; - n1 = s->bE3; - *(u32 *)((s8 *)s + 0x18) = (u32)func_8005E528; - n2 = s->bE9; - t *= 4; - *(s32 *)((s8 *)s + 0x00) = t; - s->b47 = 0; - t += ((n1 + 1) >> 1) * 4; - *(s32 *)((s8 *)s + 0x04) = t; - t += (n2 * 5 + 3) & ~3; - *(s32 *)((s8 *)s + 0x08) = t; - return ret; - } - return 0; -} - -extern void func_8005EA68(void *arg0, s32 arg1); -extern void func_8005EA88(void *arg0, s32 arg1); -extern void func_8005EAA8(void *arg0, s32 arg1); -extern void func_8005EAC8(void *arg0); - -void func_8005E480(void *arg0) { - switch (*(u8 *)((s32)arg0 + 0x46)) { - case 2: - func_8005EA68(arg0, *(u8 *)((s32)arg0 + 0x47)); - break; - case 3: - func_8005EA88(arg0, *(u8 *)((s32)arg0 + 0x47)); - break; - case 4: - if (*(u8 *)((s32)arg0 + 0x48) == 0) { - func_8005EAA8(arg0, *(u8 *)((s32)arg0 + 0x47)); - } else { - ((void (*)())func_8005EAC8)(); - } - break; - } -} - - - - -extern u8 *D_800789A8; - -s32 func_8005E528(Ctx *s) { - Entry *e; - u8 *src; - u8 *p; - u8 **gp; - u8 *g; - s32 t; - register u8 *q __asm__("$4"); - s32 n; - - switch (s->b46) { - case 2: - s->p00[s->b47] = (s->p3C[4] << 8) + s->p3C[5]; - if (++s->b47 < s->bE3) { - return 0; - } - s->b47 = 0; - break; - - case 3: - p = &s->p04[s->b47 * 5]; - q = s->p3C; - p[0] = q[4]; - p[1] = s->p3C[5] & 0x7F; - p[2] = s->p3C[6]; - p[3] = s->p3C[7]; - t = s->p3C[5]; - p[4] = t >> 7; - if (++s->b47 < s->bE9) { - return 0; - } - s->b47 = 0; - s->b48 = 0; - break; - - case 4: - e = &s->p08[s->b47]; - if (s->b48 == 0) { - e->b0 = s->b48 = s->p3C[4]; - n = 3; - src = s->p3C + 5; - if (s->b47 == 0) { - p = (u8 *)&s->p08[s->bEA]; - } else { - p = e[-1].p4 + ((e[-1].b0 + 3) & 0x1FC); - } - e->p4 = p; - D_800789A8 = p; - } else { - n = 6; - src = s->p3C + 2; - } - for (n--; n != -1; n--) { - if (s->b48 == 0) goto adv; - gp = &D_800789A8; - g = *gp; - *g++ = *src++; - *gp = g; - s->b48--; - } - if (s->b48 == 0) goto adv; - ret0: - return 0; - adv: - if (++s->b47 >= s->bEA) { - s->b49 = 6; - s->b46 = 0xFE; - return 0; - } - s->b48 = 0; - goto ret0; - } - return 1; -} - -extern void func_8005E804(u8 *arg0); -extern s32 func_8005E820(void *a0); - -s32 _padSetActAlign(void *a0, void *a1) { -extern s32 (*D_80072978)(void); - s32 v0 = ((s32 (*)(void *, void *))D_80072978)(a0, a1); - if (v0 != 0) - return 0; - *(u8 *)((u8 *)a0 + 0x46) = 1; - *(s32 *)((s32)a0 + 0x14) = (s32)func_8005E804; - *(s32 *)((s32)a0 + 0x20) = (s32)a1; - *(s32 *)((s32)a0 + 0x18) = (s32)func_8005E820; - return 1; -} - -void func_8005E804(u8 *arg0) { - u32 v1; - - v1 = *(u32 *)(arg0 + 0x20); - *(u8 *)(arg0 + 0x36) = 0x4D; - *(u8 *)(arg0 + 0x35) = 6; - *(u32 *)(arg0 + 0x2C) = v1; -} - - -s32 func_8005E820(void *a0) -{ - u8 v0; - u8 *a1; - s32 a3; - s32 v1; - s32 t1; - s32 t2; - s32 t3; - s32 t0; - - v0 = *(u8 *)((u8 *)a0 + 0xE9); - t0 = 0; - if (v0 == 0) { - *(u8 *)((u8 *)a0 + 0x46) = 0xFE; - return 0; - } - - t3 = 0xFF; - t2 = 0; - - do { - a1 = *(u8 **)((u8 *)a0 + 0x20); - a3 = 0; - - for (v1 = 5; v1 >= 0; v1--) { - if (*a1++ == t0) { - a3++; - } - } - - t1 = *(u8 *)(t2 + (u32)*(u8 **)((u8 *)a0 + 0x4) + 2); - a1 = *(u8 **)((u8 *)a0 + 0x20); - if (t1 == 0) { - t1 = 1; - } - for (v1 = 0; v1 < 6; v1++) { - if (*a1++ == t0) { - if (a3 < t1) { - ((u8 *)a0)[v1 + 0x5D] = t3; - a3--; - } else { - ((u8 *)a0)[v1 + 0x5D] = t0; - } - } - } - - t2 += 5; - } while (*(u8 *)((u8 *)a0 + 0xE9) > ++t0); - - *(u8 *)((u8 *)a0 + 0x46) = 0xFE; - return 0; -} - -INCLUDE_ASM("asm/nonmatchings/800c3", _padSetMainMode); - -void func_8005E980(void) -{ - register u8 *s __asm__("$4"); - s32 v = s[0x46]; - switch (v) { - case 2: - s[0x36] = 0x44; - *(u32 *)(s + 0x2C) = (u32)(s + 0x51); - s[0x35] = v; - break; - case 3: - s[0x36] = 0x4D; - *(u32 *)(s + 0x2C) = (u32)(s + 0x5D); - s[0x35] = 6; - break; - } -} - -extern void (*D_80072960)(void); - -s32 func_8005E9D4(s32 a0) -{ - if (*(u8 *)((u8 *)a0 + 0x53) != 0) { - if (*(u8 *)((u8 *)a0 + 0x46) == 2) { - return 1; - } - *(u8 *)((u8 *)a0 + 0x46) = 0xFE; - return 0; - } - D_80072960(); - return 0; -} - -extern void _padCmdParaMode(void *arg0, s32 arg1); - -void _padCmdParaMode(void *arg0, s32 arg1) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x43; - *(s32 *)((u8 *)arg0 + 0x2C) = (s32)((u8 *)arg0 + 0x24); - *(u8 *)((u8 *)arg0 + 0x24) = arg1; - *(u8 *)((u8 *)arg0 + 0x35) = 1; -} - - -void func_8005EA54(void *arg0) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x45; - *(s32 *)((u8 *)arg0 + 0x2C) = 0; - *(u8 *)((u8 *)arg0 + 0x35) = 0; -} - -void func_8005EA68(void *arg0, s32 arg1) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x4C; - *(s32 *)((u8 *)arg0 + 0x2C) = (s32)((u8 *)arg0 + 0x24); - *(u8 *)((u8 *)arg0 + 0x24) = arg1; - *(u8 *)((u8 *)arg0 + 0x35) = 1; -} - -void func_8005EA88(void *arg0, s32 arg1) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x46; - *(s32 *)((u8 *)arg0 + 0x2C) = (s32)((u8 *)arg0 + 0x24); - *(u8 *)((u8 *)arg0 + 0x24) = arg1; - *(u8 *)((u8 *)arg0 + 0x35) = 1; -} - -void func_8005EAA8(void *arg0, s32 arg1) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x47; - *(s32 *)((u8 *)arg0 + 0x2C) = (s32)((u8 *)arg0 + 0x24); - *(u8 *)((u8 *)arg0 + 0x24) = arg1; - *(u8 *)((u8 *)arg0 + 0x35) = 1; -} - -void func_8005EAC8(void *arg0) { - *(u8 *)((u8 *)arg0 + 0x36) = 0x4B; - *(u32 *)((u8 *)arg0 + 0x2C) = 0; - *(u8 *)((u8 *)arg0 + 0x35) = 0; -} - -__asm__(".text\n\tnop\n\tnop\n\tnop\n"); - -extern void (*D_80072974)(void *); -extern u32 D_800729DC; - -s32 _padSioRW(s32 ctx, s32 cmd); - -void func_8005EAE8(void *arg0) { - D_800729DC = ((s32 (*)(void *))D_80072974)(arg0); - _padSioRW((s32)arg0, -2); -} - -/* - * func_8005EB28 -- the target's epilogue restores TWO callee-saved registers - * ($ra and $s0) yet still ends in a bare `jr $ra` / `addiu $sp,$sp,0x18` - * delay-slot pair. Per cookbook §188 (gcc-2.7.2 mips.c:5081/5174/5204, - * mips_epilogue_delay_slots): cc1 offers the epilogue a delay slot ONLY when - * mask == RA_MASK && fmask == 0 (i.e. only $ra saved) -- with $s0 also saved, - * that branch is structurally unreachable, so NO C source can make cc1 emit - * this tail under the project's pinned `as -O1` (confirmed here with - * tools/oracle_reorder.py: bypass+`as -O2` on the ordinary-C draft gives 0 - * diffs, i.e. the C was already right and only the assembler's schedule pass - * was missing). This is the §265 "no -O2 C can ever match" class, form 1: - * the whole body is transcribed verbatim as a raw __asm__ block so gcc passes - * it through untouched. See src/md_MAIN_003/md_MAIN_003.c:524 (func_800D0440) - * for the precedent this follows. - */ -/* - * func_8005EB28 -- the target's epilogue restores TWO callee-saved registers - * ($ra and $s0) yet still ends in a bare `jr $ra` / `addiu $sp,$sp,0x18` - * delay-slot pair. Per cookbook §188 (gcc-2.7.2 mips.c:5081/5174/5204, - * mips_epilogue_delay_slots): cc1 offers the epilogue a delay slot ONLY when - * mask == RA_MASK && fmask == 0 (i.e. only $ra saved) -- with $s0 also saved, - * that branch is structurally unreachable, so NO C source can make cc1 emit - * this tail under the project's pinned `as -O1` (confirmed here with - * tools/oracle_reorder.py: bypass+`as -O2` on the ordinary-C draft gives 0 - * diffs, i.e. the C was already right and only the assembler's schedule pass - * was missing). This is the §265 "no -O2 C can ever match" class, form 1: - * the whole body is transcribed verbatim as a raw __asm__ block so gcc passes - * it through untouched. See src/md_MAIN_003/md_MAIN_003.c:524 (func_800D0440) - * for the precedent this follows. - */ -extern u32 D_8007299C; -extern u32 D_800729AC; -extern u32 D_80072998; -extern void (*D_8007298C)(void); -extern void (*D_80072988)(void); -extern u32 D_800729DC; -extern void (*D_80072974)(void *); - -void func_8005EB28(void *param_1) { - if ((D_8007299C == D_800729AC) && (D_80072998 != 0)) { - D_8007298C(); - D_80072988(); - } - if (D_800729DC != 0) { - D_80072974(*(void **)((u8 *)param_1 + 0xC)); - D_80072974((void *)(*(s32 *)((u8 *)param_1 + 0xC) + 0xF0)); - } - if (*(volatile u8 *)((u8 *)param_1 + 0x36) == 0) { - _padSioRW2((s32)param_1, 0x42); - } else { - _padSioRW2((s32)param_1, *(u8 *)((u8 *)param_1 + 0x36)); - } -} - -/* - * func_8005EC00 -- same wall as func_8005EB28 (src/800c3.c:1338): the target - * restores TWO callee-saved registers ($ra and $s0) yet the epilogue still - * ends in a bare `jr $ra` / `addiu $sp,$sp,0x18` delay-slot pair. Per - * cookbook §188 (gcc-2.7.2 mips.c:5081/5174/5204, mips_epilogue_delay_slots): - * cc1 offers the epilogue a delay slot ONLY when mask == RA_MASK && fmask==0 - * (only $ra saved) -- with $s0 also saved that branch is structurally - * unreachable, so no C source can make cc1 emit this tail under the - * project's pinned `as -O1`. Banked verbatim per §265 (file-scope raw - * __asm__ form; decimal immediates -- maspsx rejects hex inside the string). - * - * Recovered C semantics (for the eventual real decomp; NOT compiled here -- - * §265 says ship no C externs with the file-scope form): - * s32 func_8005EC00(void *arg0) { - * s32 v1, v0, a1; - * if (D_800729DC != 0) { - * (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x1E0)); - * (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x2D0)); - * } - * a1 = 0; - * if (*(u8 *)((char *)arg0 + 0x36) == 0) { - * a1 = D_800729A8; - * } - * v1 = _padSioRW2(arg0, a1); - * if (v1 < 0) { - * return v1; - * } - * v0 = v1 & 0xF0; - * if (v0 == 0) { - * return -9; - * } - * v0 = (v1 & 0xF) * 2; - * D_800729D4 = v0; - * if (v0 == 0) { - * D_800729D4 = 0x20; - * } - * return 0; - * } - */ -/* - * func_8005EC00 -- same wall as func_8005EB28 (src/800c3.c:1338): the target - * restores TWO callee-saved registers ($ra and $s0) yet the epilogue still - * ends in a bare `jr $ra` / `addiu $sp,$sp,0x18` delay-slot pair. Per - * cookbook §188 (gcc-2.7.2 mips.c:5081/5174/5204, mips_epilogue_delay_slots): - * cc1 offers the epilogue a delay slot ONLY when mask == RA_MASK && fmask==0 - * (only $ra saved) -- with $s0 also saved that branch is structurally - * unreachable, so no C source can make cc1 emit this tail under the - * project's pinned `as -O1`. Banked verbatim per §265 (file-scope raw - * __asm__ form; decimal immediates -- maspsx rejects hex inside the string). - * - * Recovered C semantics (for the eventual real decomp; NOT compiled here -- - * §265 says ship no C externs with the file-scope form): - * s32 func_8005EC00(void *arg0) { - * s32 v1, v0, a1; - * if (D_800729DC != 0) { - * (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x1E0)); - * (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x2D0)); - * } - * a1 = 0; - * if (*(u8 *)((char *)arg0 + 0x36) == 0) { - * a1 = D_800729A8; - * } - * v1 = _padSioRW2(arg0, a1); - * if (v1 < 0) { - * return v1; - * } - * v0 = v1 & 0xF0; - * if (v0 == 0) { - * return -9; - * } - * v0 = (v1 & 0xF) * 2; - * D_800729D4 = v0; - * if (v0 == 0) { - * D_800729D4 = 0x20; - * } - * return 0; - * } - */ -extern u32 D_800729DC; -extern void (*D_80072974)(void *); -extern s32 D_800729A8; -extern s32 D_800729D4; - - -s32 func_8005EC00(void *arg0) { - s32 v1; - s32 v0; - s32 a1; - - if (D_800729DC != 0) { - (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x1E0)); - (*D_80072974)((void *)(*(s32 *)((char *)arg0 + 0xC) + 0x2D0)); - } - - a1 = 0; - if (*(u8 *)((char *)arg0 + 0x36) == 0) { - a1 = D_800729A8; - } - - v1 = _padSioRW2((s32)arg0, a1); - if (v1 < 0) { - return v1; - } - - v0 = v1 & 0xF0; - if (v0 == 0) { - return -9; - } - - v0 = (v1 & 0xF) * 2; - D_800729D4 = v0; - if (v0 == 0) { - D_800729D4 = 0x20; - } - return 0; -} - -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005ECC0); - -/* func_8005ED4C — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/func_8005ED4C.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -/* func_8005ED4C — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/func_8005ED4C.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005ED4C); - -INCLUDE_ASM("asm/nonmatchings/800c3", PadInitDirect); - -void func_8005F228(void *arg0) { - u8 *p; - s32 i; - - if (*(u8 *)((u8 *)arg0 + 0x49) == 0) { - return; - } - p = (u8 *)arg0 + 0x5D; - *(u8 *)((u8 *)arg0 + 0x49) = 0; - *(u8 *)((u8 *)arg0 + 0x46) = 0; - *(u16 *)((u8 *)arg0 + 0xE6) = 0; - *(u32 *)((u8 *)arg0 + 0x14) = 0; - *(u32 *)((u8 *)arg0 + 0x18) = 0; - *(u8 *)((u8 *)arg0 + 0xE3) = 0; - *(u8 *)((u8 *)arg0 + 0xE4) = 0; - *(u16 *)((u8 *)arg0 + 0xE6) = 0; - *(u8 *)((u8 *)arg0 + 0xE9) = 0; - *(u8 *)((u8 *)arg0 + 0xEA) = 0; - *(u32 *)((u8 *)arg0 + 0x00) = 0; - *(u32 *)((u8 *)arg0 + 0x04) = 0; - *(u32 *)((u8 *)arg0 + 0x08) = 0; - for (i = 0; i < 6; i++) { - *p++ = 0xFF; - } -} - -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005F290); - -void func_8005F384(void *arg0) { - u8 temp; - - temp = *(u8 *)((u8 *)arg0 + 0x36); - *(u8 *)((u8 *)arg0 + 0x36) = 0; - *(u8 *)((u8 *)arg0 + 0x37) = temp; -} - -s32 func_8005F394(u8 *arg0) { - s32 idx = arg0[0x45] - 3; - s32 base; - - switch (arg0[0x36]) { - case 0: - if (idx < 6 && *(arg0 + idx + 0x57) == 0) { - return 0; - } - if (idx >= arg0[0x34]) { - return 0; - } - base = *(s32 *)(arg0 + 0x28); - load_it: - return *(u8 *)(base + idx); - case 0x4D: - if (idx >= arg0[0x35]) { - return 0xFF; - } - base = *(s32 *)(arg0 + 0x2C); - goto load_it; - default: { - u8 val; - if (idx >= arg0[0x35]) { - return 0; - } - val = *(u8 *)(*(s32 *)(arg0 + 0x2C) + idx); - __asm__ __volatile__("" ::: "memory"); - return val; - } - } -} - -/* func_8005F450 — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/func_8005F450.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -/* func_8005F450 — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/func_8005F450.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005F450); - - -extern u8 D_80078A48; - -s32 func_8005F6CC(void *a0) -{ - s32 i; - s32 ret; - u8 *p; - s32 res; - - i = 0; - ret = 0x10; - p = &D_80078A48; - do { - if (a0 == p) { - res = ret; - goto done; - } - ret += 0x10; - i++; - p += 0xF0; - } while (i < 2); - res = 0xFF; -done: - return res; -} - -extern u8 D_80078A48; - -s32 func_8005F704(s32 arg0) { - s32 var_v0 = (s32)&D_80078A48; - if (arg0 & 0xF0) { - var_v0 += 0xF0; - } - return var_v0; -} - -__asm__(".word 0x00000000\n"); - - -__asm__( - ".text\n" - ".align\t2\n" - ".globl\t_padInitDirSeq\n" - ".ent\t_padInitDirSeq\n" - "_padInitDirSeq:\n" - ".set\tnoreorder\n" - "lui $v0, %hi(func_8005F75C)\n" - "addiu $v0, $v0, %lo(func_8005F75C)\n" - "lui $at, %hi(D_80072974)\n" - "sw $v0, %lo(D_80072974)($at)\n" - "lui $v0, %hi(func_8005FB70)\n" - "addiu $v0, $v0, %lo(func_8005FB70)\n" - "lui $at, %hi(D_80072978)\n" - "sw $v0, %lo(D_80072978)($at)\n" - "lui $v0, %hi(func_8005F830)\n" - "addiu $v0, $v0, %lo(func_8005F830)\n" - "lui $at, %hi(D_8007297C)\n" - "jr $ra\n" - "sw $v0, %lo(D_8007297C)($at)\n" - ".set\treorder\n" - ".end\t_padInitDirSeq\n" -); - - -extern void _padCmdParaMode(void *arg0, s32 arg1); -extern void _padSendAtLoadInfo(void *arg0); - -s32 func_8005F75C(void *arg0) { - void *v0; - s32 v1; - - v0 = M2C_FIELD(arg0, void **, 0x3C); - if (M2C_FIELD(v0, u8 *, 0x0) == 0xF3) { - if (M2C_FIELD(arg0, u8 *, 0xE8) == 0) { - goto L8005F7E8; - } - } - - v1 = M2C_FIELD(arg0, u8 *, 0x46); - if (v1 == 1) { - goto L8005F7D8; - } - __asm__ volatile("" ::: "memory"); - if (v1 < 2) { - if (v1 == 0) { - goto L8005F820; - } - goto L8005F7F8; - } - if (v1 == 0xFE) { - goto L8005F7E8; - } - __asm__ volatile("" ::: "memory"); - if (v1 == 0xFF) { - goto L8005F820; - } - goto L8005F7F8; - -L8005F7D8: - _padCmdParaMode(arg0, 1); - goto L8005F820; - -L8005F7E8: - _padCmdParaMode(arg0, 0); - goto L8005F820; - -L8005F7F8: - { - void (*fp)(void *) = M2C_FIELD(arg0, void (**)(void *), 0x14); - if (fp != NULL) { - fp(arg0); - goto L8005F820; - } - } - _padSendAtLoadInfo(arg0); - -L8005F820: - return 0; -} - -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005F830); - -/* _dirFailAuto — cookbook §265 VERBATIM-ASM bank (file-scope form), generated by - * tools/asm_verbatim.py from asm/nonmatchings/800c3/_dirFailAuto.s. - * Byte-equivalent to the INCLUDE_ASM stub by construction; the function is NOT - * decompiled (§265 ACCOUNTING). Immediates/offsets are decimal for maspsx (§383). - */ -INCLUDE_ASM("asm/nonmatchings/800c3", _dirFailAuto); - -s32 func_8005FB70(void *arg0) { - register s32 ff __asm__("$2"); - - if (*(u16 *)((u8 *)arg0 + 0xE6) == 0) { - return 1; - } - ff = 0xFF; - __asm__ __volatile__("" : "=r"(ff) : "0"(ff)); - if (*(u8 *)((u8 *)arg0 + 0x46) == ff) { - return 0; - } - return 1; -} - -__asm__(".nop\n.nop\n.nop"); - -__asm__( - ".text\n" - ".align\t2\n" - ".globl\tsetRC2wait\n" - ".ent\tsetRC2wait\n" - "setRC2wait:\n" - ".set\tnoreorder\n" - "lui $v0, 0x1F80\n" - "ori $v0, $v0, 0x1120\n" - "lhu $v0, 0($v0)\n" - "lui $at, %hi(D_800C5320)\n" - "sw $a0, %lo(D_800C5320)($at)\n" - "lui $at, %hi(D_80078F24)\n" - "jr $ra\n" - "sw $v0, %lo(D_80078F24)($at)\n" - ".set\treorder\n" - ".end\tsetRC2wait\n" -); - - -extern volatile s32 D_80078F24; -extern volatile s32 D_800C5320; - -s32 chkRC2wait(void) { - u16 val1; - s32 a0; - u16 status; - - val1 = *(volatile u16*)0x1F801120; - a0 = val1; - - if ((u32)a0 < (u32)D_80078F24) { - if (*(volatile u16*)0x1F801128 != 0) { - a0 += *(volatile u16*)0x1F801128; - } else { - a0 += 0x10000; - } - } - - status = *(volatile u16*)0x1F801124; - - if (status & 0x200) { - return (u32)(a0 - D_80078F24) >= (u32)D_800C5320; - } else { - return ((u32)(a0 - D_80078F24) >> 3) >= (u32)D_800C5320; - } -} diff --git a/src/apicard5.c b/src/apicard5.c new file mode 100644 index 0000000000..22c7399482 --- /dev/null +++ b/src/apicard5.c @@ -0,0 +1,5 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/apicard5", firstfile); + +INCLUDE_ASM("asm/nonmatchings/apicard5", func_80062144); diff --git a/src/apicard6.c b/src/apicard6.c new file mode 100644 index 0000000000..c688e3e6bc --- /dev/null +++ b/src/apicard6.c @@ -0,0 +1,21 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/apicard6", SetInitPadFlag); + +INCLUDE_ASM("asm/nonmatchings/apicard6", ReadInitPadFlag); + +INCLUDE_ASM("asm/nonmatchings/apicard6", PAD_init); + +INCLUDE_ASM("asm/nonmatchings/apicard6", InitPAD); + +INCLUDE_ASM("asm/nonmatchings/apicard6", StartPAD); + +INCLUDE_ASM("asm/nonmatchings/apicard6", StopPAD); + +INCLUDE_ASM("asm/nonmatchings/apicard6", func_8006252C); + +INCLUDE_ASM("asm/nonmatchings/apicard6", func_800625A4); + +INCLUDE_ASM("asm/nonmatchings/apicard6", func_800625DC); + +INCLUDE_ASM("asm/nonmatchings/apicard6", func_80062644); diff --git a/src/apicard7.c b/src/apicard7.c new file mode 100644 index 0000000000..fd9954de49 --- /dev/null +++ b/src/apicard7.c @@ -0,0 +1,9 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/apicard7", EnablePAD); + +INCLUDE_ASM("asm/nonmatchings/apicard7", DisablePAD); + +INCLUDE_ASM("asm/nonmatchings/apicard7", _patch_pad); + +INCLUDE_ASM("asm/nonmatchings/apicard7", _remove_ChgclrPAD); diff --git a/src/libapi1.c b/src/libapi1.c new file mode 100644 index 0000000000..943950f968 --- /dev/null +++ b/src/libapi1.c @@ -0,0 +1,51 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/libapi1", InitHeap); + +INCLUDE_ASM("asm/nonmatchings/libapi1", FlushCache); + +INCLUDE_ASM("asm/nonmatchings/libapi1", func_8005CE38); + +INCLUDE_ASM("asm/nonmatchings/libapi1", _96_remove); + +INCLUDE_ASM("asm/nonmatchings/libapi1", DeliverEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", OpenEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", CloseEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", WaitEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", TestEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", EnableEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", DisableEvent); + +INCLUDE_ASM("asm/nonmatchings/libapi1", ReturnFromException); + +INCLUDE_ASM("asm/nonmatchings/libapi1", ResetEntryInt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", HookEntryInt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", func_8005CF08); + +INCLUDE_ASM("asm/nonmatchings/libapi1", func_8005CF18); + +INCLUDE_ASM("asm/nonmatchings/libapi1", read); + +INCLUDE_ASM("asm/nonmatchings/libapi1", write); + +INCLUDE_ASM("asm/nonmatchings/libapi1", ChangeClearPAD); + +INCLUDE_ASM("asm/nonmatchings/libapi1", ChangeClearRCnt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", SetRCnt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", GetRCnt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", StartRCnt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", StopRCnt); + +INCLUDE_ASM("asm/nonmatchings/libapi1", ResetRCnt); diff --git a/src/libapi2.c b/src/libapi2.c new file mode 100644 index 0000000000..e4f1956146 --- /dev/null +++ b/src/libapi2.c @@ -0,0 +1,5 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/libapi2", SysEnqIntRP); + +INCLUDE_ASM("asm/nonmatchings/libapi2", SysDeqIntRP); diff --git a/src/libpad1.c b/src/libpad1.c new file mode 100644 index 0000000000..01244c59b6 --- /dev/null +++ b/src/libpad1.c @@ -0,0 +1,49 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadChkVsync); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadStartCom); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadStopCom); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadChkMtap); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadGetState); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadInfoMode); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadInfoAct); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadInfoComb); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadSetActAlign); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadSetMainMode); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadSetAct); + +INCLUDE_ASM("asm/nonmatchings/libpad1", PadEnableCom); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padSetVsyncParam); + +INCLUDE_ASM("asm/nonmatchings/libpad1", func_8005D6CC); + +INCLUDE_ASM("asm/nonmatchings/libpad1", func_8005D734); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padChkVsync); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padStartCom); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padStopCom); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padInitSioMode); + +INCLUDE_ASM("asm/nonmatchings/libpad1", func_8005DBD8); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padSioRW); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padSioRW2); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padClrIntSio0); + +INCLUDE_ASM("asm/nonmatchings/libpad1", _padWaitRXready); diff --git a/src/libpad2.c b/src/libpad2.c new file mode 100644 index 0000000000..e4eb53237a --- /dev/null +++ b/src/libpad2.c @@ -0,0 +1,81 @@ +#include "common.h" + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padSetAct); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padSetCmd); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padSendAtLoadInfo); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padRecvAtLoadInfo); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padGetActSize); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padLoadActInfo); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E480); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E528); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padSetActAlign); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E804); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E820); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padSetMainMode); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E980); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005E9D4); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padCmdParaMode); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EA54); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EA68); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EA88); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EAA8); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EAC8); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EAE8); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EB28); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005EC00); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005ECC0); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005ED4C); + +INCLUDE_ASM("asm/nonmatchings/libpad2", PadInitDirect); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F228); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F290); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F384); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F394); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F450); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F6CC); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F704); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _padInitDirSeq); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F75C); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005F830); + +INCLUDE_ASM("asm/nonmatchings/libpad2", _dirFailAuto); + +INCLUDE_ASM("asm/nonmatchings/libpad2", func_8005FB70); + +INCLUDE_ASM("asm/nonmatchings/libpad2", setRC2wait); + +INCLUDE_ASM("asm/nonmatchings/libpad2", chkRC2wait); diff --git a/tools/exclude_audit.py b/tools/exclude_audit.py index e25cbb7b01..5af0a60a27 100644 --- a/tools/exclude_audit.py +++ b/tools/exclude_audit.py @@ -116,14 +116,19 @@ def classify(path=None, rows=None): st = stubs.get(f) if st is None: out.append((b, f, 'BANKED', 'no INCLUDE_ASM stub in the source')); continue + sub = os.path.basename(os.path.dirname(st.asm_path)) + if sub in linked_of.get(b, ()): + # LINKED outranks a pinned WALL (P31 S79 #5). A wall verdict is a fact about a compiler and + # a function; whether the function is OURS to match is a provenance question that precedes + # it. With the pin checked first, PopMatrix/PushMatrix sat here as "compiler walls" for + # eleven sessions while living in libgte3 (LINKED since Phase 8), and the four §332 + # "%lo-in-a-delay-slot" walls survived the day libpad 4.2.1 linked their objects (§490). + out.append((b, f, 'LINKED', f'subseg {sub} is linked PsyQ — never a target')); continue if pinned == 'WALL': - # BANKED still wins above -- a wall that got matched is simply no longer a wall. + # BANKED and LINKED win above -- a wall that got matched or linked is simply no longer a wall. out.append((b, f, 'WALL', why or 'curated compiler fact (pinned in the list; not re-derivable)')) continue - sub = os.path.basename(os.path.dirname(st.asm_path)) - if sub in linked_of.get(b, ()): - out.append((b, f, 'LINKED', f'subseg {sub} is linked PsyQ — never a target')); continue txt = open(st.asm_path, errors='replace').read() # §401: a jtbl function jumps through a register that is NOT $ra; `jr $ra` ends every function if re.search(r'\bjr\s+\$(?!ra\b)\w+', txt): diff --git a/tools/frontier_classify.py b/tools/frontier_classify.py index bc4c7fd0d4..4ed268698f 100644 --- a/tools/frontier_classify.py +++ b/tools/frontier_classify.py @@ -22,11 +22,17 @@ def _load(m, rel): s = importlib.util.spec_from_file_location(m, os.path.join(REPO, rel)) x = importlib.util.module_from_spec(s); sys.modules[m] = x; s.loader.exec_module(x); return x -LINKED = set('apicard1 apicard2 apicard3 apicard4 libc2_1 libc2_2 libcd1 libcd2 libetc libgpu ' - 'libgs1 libgs2 libgs3 libgs4 libgs5 libgs6 libgte1 libgte10 libgte11 libgte12 libgte13 ' - 'libgte14 libgte15 libgte16 libgte17 libgte18 libgte19 libgte2 libgte20 libgte21 ' - 'libgte22 libgte3 libgte4 libgte5 libgte6 libgte7 libgte8 libgte9 libmcrd1 libmcrd2 ' - 'snd1 snd2 snd3 snd4 snd5 snd6 snd7 snd8 snd9'.split()) +def _linked_subsegs(): + """main's LINKED subsegs, DERIVED from the Makefile's psyq_integrate stub lists (progress.py's parser). + P31 S79: this was a hard-coded 49-name set (R51 — a derived property stored as config goes stale and + takes a metric with it). It missed every block wired after it was written (libgte23-30, libgs7/8, + snd10-12, libgpu2, libapi1/2, libpad1/2, apicard5-7) and reported 337 "open stubs" — 300 of them the + INCLUDE_ASM records of linked Sony objects — while progress.py, reading the same Makefile, said 16.""" + progress = _load('progress', 'tools/progress.py') + return set(progress._main_linked_segs_from_makefile()) + + +LINKED = _linked_subsegs() INS = re.compile(r'\s*/\* [0-9A-F]+ [0-9A-F]{8} ') diff --git a/tools/make_apicard_used.py b/tools/make_apicard_used.py index 3ef9b44c21..6808ca2dd0 100644 --- a/tools/make_apicard_used.py +++ b/tools/make_apicard_used.py @@ -1,10 +1,15 @@ #!/usr/bin/env python3 -"""Build .run/obj40/apicard_used = the combined libapi+libcard objects in the 800c2 region (Phase 8). +"""Build .run/obj42/apicard_used = the combined libapi+libcard objects in the 800c2 region (Phase 8; S79 #5). -libapi (BIOS syscall trampolines) and libcard interleave in 0x80061F38..0x80062888 with one shared -object (C112.o, identical in both libs). Linked as one 22-object combined region. No exclusions — every -object byte-matches. (libapi ALSO has ~22 objects in the 800c3 region 0x5CE18.., DEFERRED — lowest -value, separate resegmentation.) Regenerate: tools/psyq_build_libs.sh LIBAPI LIBCARD first. +libapi (BIOS syscall trampolines + the C objects FIRST/PAD/PATCH/CHCLRPAD) and libcard interleave in +0x80061F38..0x80062888 with one shared object (C112.o, identical in both libs). Linked as one 26-object +combined region tiling the whole range (apicard1..7). No exclusions — every object byte-matches. +P31 S79 #5: libapi comes from `.run/obj42/libapi42` — PsyQ LIBAPI.LIB **4.2**, the EXE's real libapi (its 4.2 +`Ps` stamp is C114 at 0x8005CE48; tools/psyq/lib421, cookbook §490) — which also supplies FIRST.o (168 ins, +`firstfile`, formerly REAL C in 800c2), PAD.o (192, formerly 800c2_2) and PATCH.o + CHCLRPAD.o (formerly +800c2_3). libcard stays 4.0 (`.run/obj40/libcard`): byte-identical in this region. libapi 4.2's band objects +(0x8005CE18..0x8005E188) are wired separately by the Makefile's LIBAPI42 call from the raw dir. +Regenerate: tools/psyq_build_libs.sh LIBCARD + the lib421 ELF step (docs/SETUP.md) first. """ import os, re, shutil, subprocess, sys from collections import defaultdict @@ -18,8 +23,12 @@ VRAM_BASE = 0x8000F800 RLO, RHI = 0x80061F38, 0x80062888 +# object sources: libapi 4.2 (S79 #5) + libcard 4.0 — see the module docstring +SOURCES = (".run/obj42/libapi42", ".run/obj40/libcard") + + def place(lib, exe, vram_base): - out = subprocess.check_output(["python3", "tools/psyq_identify.py", f".run/obj40/{lib}", + out = subprocess.check_output(["python3", "tools/psyq_identify.py", lib, "--vram-base", hex(vram_base), "--exe", exe], text=True) return {m.group(2): int(m.group(1), 16) for ln in out.splitlines() @@ -35,10 +44,10 @@ def main(): exe_path, vram_base = args.exe, int(args.vram_base, 0) exe = open(exe_path, "rb").read() byaddr = defaultdict(list) - for lib in ("libapi", "libcard"): + for lib in SOURCES: for nm, a in place(lib, exe_path, vram_base).items(): byaddr[a].append((lib, nm)) - dst = ".run/obj40/apicard_used" + dst = ".run/obj42/apicard_used" shutil.rmtree(dst, ignore_errors=True) os.makedirs(dst) n = 0 @@ -46,12 +55,12 @@ def main(): if not (RLO <= a < RHI): continue lib, nm = next(((l, m) for l, m in byaddr[a] - if link_object(f".run/obj40/{l}/{m}", a, name=m, exe_bytes=exe, + if link_object(f"{l}/{m}", a, name=m, exe_bytes=exe, vram_base=vram_base)["ok"]), byaddr[a][0]) - shutil.copy(f".run/obj40/{lib}/{nm}", f"{dst}/{nm}") + shutil.copy(f"{lib}/{nm}", f"{dst}/{nm}") n += 1 - print(f"apicard_used: {n} objects (libapi+libcard combined, 800c2 region)") + print(f"apicard_used: {n} objects (libapi 4.2 + libcard 4.0 combined, 800c2 region) -> {dst}") if __name__ == "__main__":