diff --git a/.vscode/settings.json b/.vscode/settings.json index e83759f6b..e4043e21c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,15 +3,14 @@ "bitflags", "byteorder", "cdrom", + "mkpsexe", "mkpsxiso", + "objs", "psexe", "seeked", "thiserror" ], "python.formatting.provider": "yapf", "rust-analyzer.checkOnSave.allTargets": false, - "rust-analyzer.linkedProjects": [ - "tools/Cargo.toml", - "dw2003_exe_data/Cargo.toml" - ] + "rust-analyzer.linkedProjects": ["tools/Cargo.toml"] } diff --git a/dw2003/SLES_039.36/f0.s b/asm/dw2003/exe/f0.s similarity index 92% rename from dw2003/SLES_039.36/f0.s rename to asm/dw2003/exe/f0.s index 5164fabc7..63b1e7f6c 100644 --- a/dw2003/SLES_039.36/f0.s +++ b/asm/dw2003/exe/f0.s @@ -1,5 +1,8 @@ +.include "macros.s" + # Returns the pointer to the current digimon stat # `fn f0(u32 value) -> *u32` +.section "section_f0" .global f0 f0: addiu $sp, -24 @@ -26,4 +29,3 @@ f0: nop jr $ra addiu $sp, 24 -f0_end: diff --git a/dw2003/SLES_039.36/f1.s b/asm/dw2003/exe/f1.s similarity index 94% rename from dw2003/SLES_039.36/f1.s rename to asm/dw2003/exe/f1.s index 98986607c..f16734c61 100644 --- a/dw2003/SLES_039.36/f1.s +++ b/asm/dw2003/exe/f1.s @@ -1,5 +1,8 @@ +.include "macros.s" + # Returns the digimon stat index of the first digimon with `value0 = value` # `fn f1(u32 value) -> u32` +.section "section_f1" .global f1 f1: cur_idx=$v1 @@ -32,7 +35,3 @@ digimon_profiles_ptr=$a1 .Lfound$: jr $ra nop - -cur_idx=$ -digimon_profiles_ptr=$ -f1_end: diff --git a/dw2003/SLES_039.36.s b/asm/dw2003/exe/fns.s similarity index 99% rename from dw2003/SLES_039.36.s rename to asm/dw2003/exe/fns.s index 382ba6d99..644d96e4f 100644 --- a/dw2003/SLES_039.36.s +++ b/asm/dw2003/exe/fns.s @@ -1,22 +1,6 @@ -.set noat -.set noreorder -.global start +.include "macros.s" -# `$zr` -> `$zero` -.set $zr, $zero - -# `la` but using `addiu` -.macro la_ reg, addr -lui \reg, %hi(\addr) -addiu \reg, \reg, %lo(\addr) -.endm - -# `move` but using `addu` -.macro move_ lhs, rhs -addu \lhs, \rhs, $zr -.endm - -.section "dw2003_fns" +.section "fns0" .L80010000: .word .L80011134 .L80010004: .word .L8001114c .L80010008: .word .L80011224 @@ -1049,6 +1033,7 @@ D0x80010c06: .L80010e84: .word 0x0000000a .L80010e88: jr $ra .L80010e8c: nop +.global start start: .L80010e90: la_ $v0, D0x8005cce8 .L80010e98: la_ $v1, D0x80082cb0 @@ -3466,10 +3451,8 @@ start: .L800134a4: jr $ra .L800134a8: addiu $sp, 32 -.include "SLES_039.36/f1.s" -.include "SLES_039.36/f0.s" - +.section "fns1" .global F0x80013534 F0x80013534: .L80013534: li $v1, 7 diff --git a/asm/macros.s b/asm/macros.s new file mode 100644 index 000000000..cb863457d --- /dev/null +++ b/asm/macros.s @@ -0,0 +1,16 @@ +.set noat +.set noreorder + +# `$zr` -> `$zero` +.set $zr, $zero + +# `la` but using `addiu` +.macro la_ reg, addr +lui \reg, %hi(\addr) +addiu \reg, \reg, %lo(\addr) +.endm + +# `move` but using `addu` +.macro move_ lhs, rhs +addu \lhs, \rhs, $zr +.endm diff --git a/checksums.sha256 b/checksums.sha256 index 34dc3fac9..8629b0100 100644 --- a/checksums.sha256 +++ b/checksums.sha256 @@ -1,2 +1,2 @@ 5da33ac4211c21cc969161d82aea17f43958da38b259cab865b850d3999f0744 build/misc/DUMMY -15f37849a81b9f00e7f20d00de7a465b663a9e86b9d08b05d32dd386be95c546 build/psexe/dw2003/SLES_039.36.psexe +15f37849a81b9f00e7f20d00de7a465b663a9e86b9d08b05d32dd386be95c546 build/psexe/dw2003/exe.psexe diff --git a/dw2003.xml b/dw2003.xml index dc808f9e2..de26426dc 100644 --- a/dw2003.xml +++ b/dw2003.xml @@ -8,7 +8,7 @@ - + diff --git a/dw2003/SLES_039.36.ld b/dw2003/SLES_039.36.ld deleted file mode 100644 index c6bcb75d7..000000000 --- a/dw2003/SLES_039.36.ld +++ /dev/null @@ -1,12 +0,0 @@ -SECTIONS { - _.text = 0x80010000; - .text _.text : { - KEEP(*(dw2003_fns dw2003_data)); - } -} - -SECTIONS { - /DISCARD/ : { *(*) } -} - -ENTRY(start) \ No newline at end of file diff --git a/elf/dw2003/exe.yaml b/elf/dw2003/exe.yaml new file mode 100644 index 000000000..bc27aa647 --- /dev/null +++ b/elf/dw2003/exe.yaml @@ -0,0 +1,13 @@ +--- +entry: start +objs: + - /build/asm/dw2003/exe/fns.o + - /build/asm/dw2003/exe/f0.o + - /build/asm/dw2003/exe/f1.o + - /build/rust/dw2003_exe_data.a +sections: + - fns0 + - section_f1 + - section_f0 + - fns1 + - dw2003_exe_data diff --git a/psexe/dw2003/exe.yaml b/psexe/dw2003/exe.yaml new file mode 100644 index 000000000..b2156cc0f --- /dev/null +++ b/psexe/dw2003/exe.yaml @@ -0,0 +1,3 @@ +--- +elf: /build/elf/dw2003/exe.elf +license: /licenses/psexe-eu.dat diff --git a/dw2003_exe_data/.cargo/config.toml b/rust/.cargo/config.toml similarity index 100% rename from dw2003_exe_data/.cargo/config.toml rename to rust/.cargo/config.toml diff --git a/dw2003_exe_data/Cargo.lock b/rust/Cargo.lock similarity index 100% rename from dw2003_exe_data/Cargo.lock rename to rust/Cargo.lock diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 000000000..a1499d3ef --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,3 @@ +[workspace] + +members = ["dw2003_exe_data"] diff --git a/dw2003_exe_data/Cargo.toml b/rust/dw2003_exe_data/Cargo.toml similarity index 100% rename from dw2003_exe_data/Cargo.toml rename to rust/dw2003_exe_data/Cargo.toml diff --git a/dw2003_exe_data/src/data.rs b/rust/dw2003_exe_data/src/data.rs similarity index 99% rename from dw2003_exe_data/src/data.rs rename to rust/dw2003_exe_data/src/data.rs index 36e6a9b17..29fbeb294 100644 --- a/dw2003_exe_data/src/data.rs +++ b/rust/dw2003_exe_data/src/data.rs @@ -6,7 +6,7 @@ use crate::DigimonProfile; pub macro decl_static($($vis:vis static mut $NAME:ident: $T:ty = $value:expr; )*) { $( #[no_mangle] - #[link_section = "dw2003_data"] + #[link_section = "dw2003_exe_data"] $vis static mut $NAME: $T = $value; )* } diff --git a/dw2003_exe_data/src/digimon_profile.rs b/rust/dw2003_exe_data/src/digimon_profile.rs similarity index 100% rename from dw2003_exe_data/src/digimon_profile.rs rename to rust/dw2003_exe_data/src/digimon_profile.rs diff --git a/dw2003_exe_data/src/lib.rs b/rust/dw2003_exe_data/src/lib.rs similarity index 100% rename from dw2003_exe_data/src/lib.rs rename to rust/dw2003_exe_data/src/lib.rs diff --git a/dw2003_exe_data/src/util.rs b/rust/dw2003_exe_data/src/util.rs similarity index 100% rename from dw2003_exe_data/src/util.rs rename to rust/dw2003_exe_data/src/util.rs diff --git a/dw2003_exe_data/mipsel-sony-psx.json b/rust/mipsel-sony-psx.json similarity index 100% rename from dw2003_exe_data/mipsel-sony-psx.json rename to rust/mipsel-sony-psx.json diff --git a/tools/ld_from_yaml.py b/tools/ld_from_yaml.py new file mode 100755 index 000000000..db21932df --- /dev/null +++ b/tools/ld_from_yaml.py @@ -0,0 +1,68 @@ +#!/bin/env python3 + +# Import +import yaml +import argparse +from pathlib import Path +import subprocess + + +def process_path(path: str | Path, input_dir: Path) -> Path: + path = Path(path) + if path.is_absolute(): + # TODO: Make this work on windows? + return path.relative_to("/") + else: + return input_dir.joinpath(path) + + +def main(args): + config = yaml.safe_load(open(args.input_yaml)) + input_dir = Path(args.input_yaml).parent + + entry = config["entry"] + objs = config["objs"] + objs = list(map(lambda obj_path: str(process_path(obj_path, input_dir)), objs)) + + sections = config["sections"] + sections = map(lambda section: f"KEEP(*({section}));", sections) + sections = '\n\t\t'.join(sections) + + # Create the linker script + with open(args.linker_script_output, "w") as linker_script_file: + + linker_script_file.write(f"""\ +SECTIONS {{ + _.text = 0x80010000; + .text _.text : {{ + {sections} + }} +}} + +SECTIONS {{ + /DISCARD/ : {{ *(*) }} +}} + +ENTRY({entry})""") + + args = [ + args.ld_bin, + "-o", + args.output, + "-EL", + "--script", + args.linker_script_output, + "--warn-section-align", + ] + objs + subprocess.run(args) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="`ld` wrapper") + parser.add_argument("input_yaml", type=str) + parser.add_argument("-o", dest="output", type=str, required=True) + parser.add_argument("--linker-script-output", dest="linker_script_output", type=str, required=True) + parser.add_argument("--ld-bin", dest="ld_bin", type=str, required=True) + + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/tools/ld_from_yaml_deps.py b/tools/ld_from_yaml_deps.py new file mode 100755 index 000000000..57f7a973c --- /dev/null +++ b/tools/ld_from_yaml_deps.py @@ -0,0 +1,37 @@ +#!/bin/env python3 + +# Import +import yaml +import argparse +from pathlib import Path + + +def process_path(path: str | Path, input_dir: Path): + path = Path(path) + if path.is_absolute(): + # TODO: Make this work on windows? + return path.relative_to("/") + else: + return input_dir.joinpath(path) + + +def main(args): + config = yaml.safe_load(open(args.input_yaml)) + input_dir = Path(args.input_yaml).parent + + deps_file = open(args.deps_file, "w") + deps_file.write(f"{args.output}: ") + + for obj_path in config["objs"]: + obj_path = process_path(obj_path, input_dir) + deps_file.write(f"{obj_path} ") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="`ld` dependency creator") + parser.add_argument("input_yaml", type=str) + parser.add_argument("-o", dest="output", type=str, required=True) + parser.add_argument("--deps", dest="deps_file", type=str, required=True) + + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/tools/mkpsexe_from_yaml.py b/tools/mkpsexe_from_yaml.py new file mode 100755 index 000000000..f4a7dc03b --- /dev/null +++ b/tools/mkpsexe_from_yaml.py @@ -0,0 +1,36 @@ +#!/bin/env python3 + +# Import +import yaml +import argparse +from pathlib import Path +import subprocess + + +def process_path(path: str | Path, input_dir: Path): + path = Path(path) + if path.is_absolute(): + # TODO: Make this work on windows? + return path.relative_to("/") + else: + return input_dir.joinpath(path) + + +def main(args): + config = yaml.safe_load(open(args.input_yaml)) + input_dir = Path(args.input_yaml).parent + + elf_path = process_path(config["elf"], input_dir) + license_path = process_path(config["license"], input_dir) + + subprocess.run([args.mkpsexe_bin, elf_path, "-o", args.output, "--license", license_path]) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="`mkpsexe` wrapper") + parser.add_argument("input_yaml", type=str) + parser.add_argument("-o", dest="output", type=str, required=True) + parser.add_argument("--mkpsexe-bin", dest="mkpsexe_bin", type=str, required=True) + + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/tools/mkpsexe_from_yaml_deps.py b/tools/mkpsexe_from_yaml_deps.py new file mode 100755 index 000000000..55bf93efb --- /dev/null +++ b/tools/mkpsexe_from_yaml_deps.py @@ -0,0 +1,39 @@ +#!/bin/env python3 + +# Import +import yaml +import argparse +from pathlib import Path + + +def process_path(path: str | Path, input_dir: Path): + path = Path(path) + if path.is_absolute(): + # TODO: Make this work on windows? + return path.relative_to("/") + else: + return input_dir.joinpath(path) + + +def main(args): + config = yaml.safe_load(open(args.input_yaml)) + input_dir = Path(args.input_yaml).parent + + deps_file = open(args.deps_file, "w") + deps_file.write(f"{args.output}: ") + + elf_path = process_path(config["elf"], input_dir) + deps_file.write(f"{elf_path} ") + + license_path = process_path(config["license"], input_dir) + deps_file.write(f"{license_path} ") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="`mkpsexe` dependency creator") + parser.add_argument("input_yaml", type=str) + parser.add_argument("-o", dest="output", type=str, required=True) + parser.add_argument("--deps", dest="deps_file", type=str, required=True) + + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/zbuild.yaml b/zbuild.yaml index b120237a0..5ebd01c80 100644 --- a/zbuild.yaml +++ b/zbuild.yaml @@ -9,13 +9,18 @@ alias: sha256sum: sha256sum # Other tools - generate_psx_iso_deps: tools/generate_psx_iso_deps.py - generate_compare_deps: tools/generate_compare_deps.py + generate_psx_iso_deps : tools/generate_psx_iso_deps.py + generate_compare_deps : tools/generate_compare_deps.py + mkpsexe_from_yaml : tools/mkpsexe_from_yaml.py + mkpsexe_from_yaml_deps: tools/mkpsexe_from_yaml_deps.py + ld_from_yaml_deps : tools/ld_from_yaml_deps.py + ld_from_yaml : tools/ld_from_yaml.py # Cargo tools mkpsexe: $(tools_dir)/ddw3-mkpsexe # Directories + # TODO: Rename these to `build_*_dir` build_dir : build tools_dir : $(build_dir)/tools misc_dir : $(build_dir)/misc @@ -23,7 +28,7 @@ alias: asm_dir : $(build_dir)/asm elf_dir : $(build_dir)/elf psexe_dir : $(build_dir)/psexe - rs_dir : $(build_dir)/rs + rust_dir : $(build_dir)/rust # Files checksums : checksums.sha256 @@ -46,24 +51,22 @@ alias: # Assembly asm_obj : $(asm_dir)/^(path).o asm_obj_deps: $(asm_dir)/^(path).d - asm_src : ^(path).s + asm_src : asm/^(path).s # Elf - # TODO: Not hardcode where the object files come from - elf : $(elf_dir)/^(path).elf - elf_obj: $(asm_dir)/^(path).o - elf_ld : ^(path).ld + elf : $(elf_dir)/^(path).elf + elf_deps : $(elf_dir)/^(path).d + elf_linker_script: $(elf_dir)/^(path).ld + elf_yaml : elf/^(path).yaml # Psexe - # TODO: Not hardcode where the elf or license come from - psexe : $(psexe_dir)/^(path).psexe - psexe_elf: $(elf_dir)/^(path).elf + psexe : $(psexe_dir)/^(path).psexe + psexe_deps: $(psexe_dir)/^(path).d + psexe_yaml: psexe/^(path).yaml # Rust library - # TODO: Allow dashes in name? - rs_lib : $(rs_dir)/lib^(name).a - rs_lib_dep: $(rs_dir)/lib^(name).d - rs_src_dir: ^(name) + rust_lib : $(rust_dir)/^(name).a + rust_lib_deps: $(rust_dir)/^(name).d # By default built the final `iso`s default: @@ -166,42 +169,69 @@ rules: - [truncate, --size=35283682, $(dummy_buffer)] # Psexe - # TODO: Hardcode less psexe: out: [$(psexe)] deps: - - $(psexe_elf) - - $(license_psexe_eu) + - $(psexe_yaml) + - $(mkpsexe_from_yaml) - $(mkpsexe) + - deps_file: $(psexe_deps) - static: $(psexe::dir_name)/ exec: - - - $(mkpsexe) - - $(psexe_elf) + - - $(mkpsexe_from_yaml) + - $(psexe_yaml) - -o - $(psexe) - - --license - - $(license_psexe_eu) + - --mkpsexe-bin + - $(mkpsexe) + + # Psexe dependencies + psexe_deps: + out: [$(psexe_deps)] + deps: + - $(psexe_yaml) + - $(mkpsexe_from_yaml_deps) + - static: $(psexe_deps::dir_name)/ + exec: + - - $(mkpsexe_from_yaml_deps) + - $(psexe_yaml) + - -o + - $(psexe) + - --deps + - $(psexe_deps) # Elf - # TODO: Hardcode less elf: out: [$(elf)] deps: - - $(elf_obj) - - $(elf_ld) - - $(rs_dir)/libdw2003_exe_data.a + - $(elf_yaml) + - $(ld_from_yaml) + - deps_file: $(elf_deps) - static: $(elf::dir_name)/ exec: - - - $(ld) - - $(elf_obj) + - - $(ld_from_yaml) + - $(elf_yaml) - -o - $(elf) - - -EL - - --script - - $(elf_ld) - - --warn-section-align - - -L$(rs_dir) - - -ldw2003_exe_data + - --linker-script-output + - $(elf_linker_script) + - --ld-bin + - $(ld) + + # Elf dependencies + elf_deps: + out: [$(elf_deps)] + deps: + - $(elf_yaml) + - $(ld_from_yaml_deps) + - static: $(elf_deps::dir_name)/ + exec: + - - $(ld_from_yaml_deps) + - $(elf_yaml) + - -o + - $(elf) + - --deps + - $(elf_deps) # Assembly asm: @@ -219,6 +249,7 @@ rules: - -march=r3000 - -msoft-float - -O2 + - -Iasm/ - -I$(asm_src::dir_name) # Zbuild doesn't support `\\\n` yet - - sed @@ -229,26 +260,26 @@ rules: - $(asm_obj_deps) # Rust library - rs_lib: + rust_lib: alias: target_dir: target/mipsel-sony-psx/release out: - - $(rs_lib) - - deps_file: $(rs_lib_dep) + - $(rust_lib) + - deps_file: $(rust_lib_deps) deps: - - static: $(rs_lib::dir_name)/ + - static: $(rust_lib::dir_name)/ exec: - cwd: $(rs_src_dir)/ + cwd: rust/ cmds: - - $(cargo) - build - --release - --package=^(name) - -Z=unstable-options - - --out-dir=../$(rs_dir)/ - - [cp, $(target_dir)/lib^(name).d, ../$(rs_dir)] + - [cp, $(target_dir)/lib^(name).a, ../$(rust_lib)] + - [cp, $(target_dir)/lib^(name).d, ../$(rust_lib_deps)] - - sed - -i - -e - - 's,$(rs_src_dir)/$(target_dir)/,$(rs_dir)/,g' - - ../$(rs_lib_dep) + - 's,rust/$(target_dir)/lib^(name).a,$(rust_dir)/^(name).a,g' + - ../$(rust_lib_deps)