From c767f4945595f558ce8639d0d723560a538c7243 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Mon, 27 Jan 2025 08:15:16 -0800 Subject: [PATCH] Extract Incbins (#1776) * extract incbins infastructure * rspboot incbin * rsptext incbin * rspdata incbin * aspMainStack incbin * ipl3 incbin --- Makefile | 1 + baseroms/n64-us/config.yml | 44 ++++++++++++++++++++++ include/macro.inc | 7 ++++ linker_scripts/final/undefined_syms.ld | 6 --- spec | 13 ++----- src/audio/lib/stack.s | 6 +++ src/boot/rspboot.s | 7 ++++ src/code/rspdata.s | 23 ++++++++++++ src/code/rsptext.s | 15 ++++++++ src/makerom/ipl3.s | 5 ++- tools/extract_incbins.py | 52 ++++++++++++++++++++++++++ 11 files changed, 162 insertions(+), 17 deletions(-) create mode 100644 src/audio/lib/stack.s create mode 100644 src/boot/rspboot.s create mode 100644 src/code/rspdata.s create mode 100644 src/code/rsptext.s create mode 100755 tools/extract_incbins.py diff --git a/Makefile b/Makefile index 42f5c2fc47d..6c0787e77f2 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,7 @@ setup: $(MAKE) -C tools $(PYTHON) tools/decompress_baserom.py -v $(VERSION) $(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 $(EXTRACTED_DIR)/baserom -v $(VERSION) + $(PYTHON) tools/extract_incbins.py $(EXTRACTED_DIR)/baserom $(EXTRACTED_DIR)/incbin -v $(VERSION) $(PYTHON) tools/extract_yars.py $(EXTRACTED_DIR)/baserom -v $(VERSION) assets: diff --git a/baseroms/n64-us/config.yml b/baseroms/n64-us/config.yml index 0423060b451..27b714e25d1 100644 --- a/baseroms/n64-us/config.yml +++ b/baseroms/n64-us/config.yml @@ -15,4 +15,48 @@ archives: - icon_item_24_static_yar - schedule_dma_static_yar incbins: + - name: ipl3 + segment: makerom + vram: 0x8007F040 + size: 0xFC0 + - name: rspbootText + segment: boot + vram: 0x800969C0 + size: 0x160 + - name: aspMainText + segment: code + vram: 0x801AAAB0 + size: 0x1000 + - name: gspS2DEX2_fifoText + segment: code + vram: 0x801ABAB0 + size: 0x18C0 + - name: njpgdspMainText + segment: code + vram: 0x801AD370 + size: 0xAF0 + - name: aspMainData + segment: code + vram: 0x801E1E80 + size: 0x2E0 + - name: gspF3DZEX2_NoN_PosLight_fifoText + segment: code + vram: 0x801E2160 + size: 0x1630 + - name: gspF3DZEX2_NoN_PosLight_fifoData + segment: code + vram: 0x801E3790 + size: 0x420 + - name: gspS2DEX2_fifoData + segment: code + vram: 0x801E3BB0 + size: 0x390 + - name: njpgdspMainData + segment: code + vram: 0x801E3F40 + size: 0x60 + - name: aspMainStack + segment: code + vram: 0x801D6200 + size: 0x400 assets: diff --git a/include/macro.inc b/include/macro.inc index 6b66399f9ad..4840002b99d 100644 --- a/include/macro.inc +++ b/include/macro.inc @@ -1,3 +1,8 @@ +# Evaluate this file only once in case it's included more than once +.ifndef _MACRO_INC_GUARD +.internal _MACRO_INC_GUARD +.set _MACRO_INC_GUARD, 1 + .macro glabel label .global \label .ent \label @@ -90,3 +95,5 @@ .set $fs4f, $f29 .set $fs5, $f30 .set $fs5f, $f31 + +.endif diff --git a/linker_scripts/final/undefined_syms.ld b/linker_scripts/final/undefined_syms.ld index 85d27e3a808..958a3426086 100644 --- a/linker_scripts/final/undefined_syms.ld +++ b/linker_scripts/final/undefined_syms.ld @@ -1,9 +1,3 @@ -// Ucode symbols - -rspbootTextEnd = rspbootTextStart + 0x160; -aspMainTextEnd = aspMainTextStart + 0x1000; -aspMainDataEnd = aspMainDataStart + 0x2E0; - // Segmented Addresses // segment 0x01 diff --git a/spec b/spec index 095afc9bac5..814df763c88 100644 --- a/spec +++ b/spec @@ -21,7 +21,7 @@ beginseg name "boot" address 0x80080060 include "$(BUILD_DIR)/src/boot/boot_main.o" - include "$(BUILD_DIR)/data/boot/rspboot.data.o" + include "$(BUILD_DIR)/src/boot/rspboot.o" include "$(BUILD_DIR)/src/boot/idle.o" include "$(BUILD_DIR)/src/boot/viconfig.o" include "$(BUILD_DIR)/src/boot/carthandle.o" @@ -606,9 +606,7 @@ beginseg name "code" compress after "dmadata" - include "$(BUILD_DIR)/data/code/aspMain.data.o" - include "$(BUILD_DIR)/data/code/gspS2DEX2.fifo.data.o" - include "$(BUILD_DIR)/data/code/njpgdspMain.data.o" + include "$(BUILD_DIR)/src/code/rsptext.o" include "$(BUILD_DIR)/src/code/z_en_a_keep.o" include "$(BUILD_DIR)/src/code/z_en_item00.o" include "$(BUILD_DIR)/src/code/z_eff_blure.o" @@ -758,7 +756,7 @@ beginseg include "$(BUILD_DIR)/src/audio/lib/playback.o" include "$(BUILD_DIR)/src/audio/lib/effects.o" include "$(BUILD_DIR)/src/audio/lib/seqplayer.o" - include "$(BUILD_DIR)/data/code/audio_dramStack.data.o" + include "$(BUILD_DIR)/src/audio/lib/stack.o" include "$(BUILD_DIR)/asm/code/code_8019AE40.text.o" // handwritten pad_text include "$(BUILD_DIR)/asm/code/code_8019AEC0.text.o" // handwritten @@ -779,10 +777,7 @@ beginseg include "$(BUILD_DIR)/assets/audio/sequence_font_table.o" include "$(BUILD_DIR)/src/audio/tables/sequence_table.o" include "$(BUILD_DIR)/src/audio/tables/samplebank_table.o" - include "$(BUILD_DIR)/data/code/aspMain.rodata.o" - include "$(BUILD_DIR)/data/code/gspF3DZEX2.NoN.PosLight.fifo.rodata.o" - include "$(BUILD_DIR)/data/code/gspS2DEX2.fifo.rodata.o" - include "$(BUILD_DIR)/data/code/njpgdspMain.rodata.o" + include "$(BUILD_DIR)/src/code/rspdata.o" endseg // The game expects all the segments after the `code` segment and before the first overlay to be `NOLOAD` ones diff --git a/src/audio/lib/stack.s b/src/audio/lib/stack.s new file mode 100644 index 00000000000..831b1b1598f --- /dev/null +++ b/src/audio/lib/stack.s @@ -0,0 +1,6 @@ +.include "macro.inc" + +.section .data + +dlabel aspMainStack + .incbin "incbin/aspMainStack" diff --git a/src/boot/rspboot.s b/src/boot/rspboot.s new file mode 100644 index 00000000000..bc1d5d4f5ba --- /dev/null +++ b/src/boot/rspboot.s @@ -0,0 +1,7 @@ +.include "macro.inc" + +.section .data + +dlabel rspbootTextStart + .incbin "incbin/rspbootText" +dlabel rspbootTextEnd diff --git a/src/code/rspdata.s b/src/code/rspdata.s new file mode 100644 index 00000000000..812bcf5d5cc --- /dev/null +++ b/src/code/rspdata.s @@ -0,0 +1,23 @@ +.include "macro.inc" + +.section .rodata + +dlabel aspMainDataStart + .incbin "incbin/aspMainData" +dlabel aspMainDataEnd + +dlabel gspF3DZEX2_NoN_PosLight_fifoTextStart + .incbin "incbin/gspF3DZEX2_NoN_PosLight_fifoText" +dlabel gspF3DZEX2_NoN_PosLight_fifoTextEnd + +dlabel gspF3DZEX2_NoN_PosLight_fifoDataStart + .incbin "incbin/gspF3DZEX2_NoN_PosLight_fifoData" +dlabel gspF3DZEX2_NoN_PosLight_fifoDataEnd + +dlabel gspS2DEX2_fifoDataStart + .incbin "incbin/gspS2DEX2_fifoData" +dlabel gspS2DEX2_fifoDataEnd + +dlabel njpgdspMainDataStart + .incbin "incbin/njpgdspMainData" +dlabel njpgdspMainDataEnd diff --git a/src/code/rsptext.s b/src/code/rsptext.s new file mode 100644 index 00000000000..d8d3290bd97 --- /dev/null +++ b/src/code/rsptext.s @@ -0,0 +1,15 @@ +.include "macro.inc" + +.section .data + +dlabel aspMainTextStart + .incbin "incbin/aspMainText" +dlabel aspMainTextEnd + +dlabel gspS2DEX2_fifoTextStart + .incbin "incbin/gspS2DEX2_fifoText" +dlabel gspS2DEX2_fifoTextEnd + +dlabel njpgdspMainTextStart + .incbin "incbin/njpgdspMainText" +dlabel njpgdspMainTextEnd diff --git a/src/makerom/ipl3.s b/src/makerom/ipl3.s index 22ae6525042..c2dc845b5d1 100644 --- a/src/makerom/ipl3.s +++ b/src/makerom/ipl3.s @@ -1,2 +1,3 @@ -.text -.incbin "extracted/n64-us/baserom/makerom", 0x40, 0xFC0 +.section .text + +.incbin "incbin/ipl3" diff --git a/tools/extract_incbins.py b/tools/extract_incbins.py new file mode 100755 index 00000000000..30d8e70bace --- /dev/null +++ b/tools/extract_incbins.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +# SPDX-FileCopyrightText: © 2024 ZeldaRET +# SPDX-License-Identifier: CC0-1.0 + +from __future__ import annotations + +import argparse +from pathlib import Path + +from version import version_config + + +def main(): + parser = argparse.ArgumentParser( + description="Extract incbin pieces from an uncompressed ROM." + ) + parser.add_argument( + "baserom_segments_dir", + type=Path, + help="Directory of uncompressed ROM segments", + ) + parser.add_argument( + "output_dir", + type=Path, + help="Output directory for incbin pieces", + ) + parser.add_argument( + "-v", + "--version", + required=True, + help="MM version", + ) + + args = parser.parse_args() + + config = version_config.load_version_config(args.version) + + args.output_dir.mkdir(parents=True, exist_ok=True) + for incbin in config.incbins: + incbin_path = args.output_dir / incbin.name + with open(args.baserom_segments_dir / incbin.segment, "rb") as f: + offset = incbin.vram - config.dmadata_segments[incbin.segment].vram + f.seek(offset) + incbin_data = f.read(incbin.size) + incbin_path.write_bytes(incbin_data) + + print(f"Extracted {len(config.incbins)} incbin pieces to {args.output_dir}") + + +if __name__ == "__main__": + main()