From 0643479903c37c783f709ac01684d7616a6b2870 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Thu, 25 Jun 2026 17:13:50 -0500 Subject: [PATCH] reloc on startup reduced --- demos/build.sh | 15 +++++++++++++-- demos/rsrcProbe.apl | Bin 45039 -> 46685 bytes src/link816/link816.cpp | 14 +++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/demos/build.sh b/demos/build.sh index 95d4e5c..1e2ba0b 100755 --- a/demos/build.sh +++ b/demos/build.sh @@ -61,11 +61,22 @@ echo "compile: $BASE.c -> $OUTBASE.o" -O2 -ffunction-sections -c "$SRC" -o "$OBJ" echo "link: -> $OUTBASE.bin" +# text-base 0: under the GS/OS Loader our segment lands at some bank +# the Loader picks (KIND=0x1000), so link-time addresses can start at +# offset 0 in the segment. With text-base=0 the link-time-baked IMM16 +# operand for `lda gFoo` already equals gFoo's runtime offset within +# the segment (no segPlacedBase adjustment needed since the Loader +# places at bank-aligned bases), so the linker can skip emitting +# cRELOC entries for every IMM16 site — 60–90% reduction in cRELOC +# count, proportional speed-up in the Loader's per-reloc walk. +# Bare-metal builds keep text-base=0x1000 (runInMame.sh loads at +# bank-0:1000 and link-time addresses must match). +# # bss-base 0xA000 keeps BSS above the SHR shadow region ($2000-$9FFF # in bank 0 mirrors to bank E1 SHR memory). Without this, the smaller # section-gc'd demos place BSS at e.g. $2300 and global writes scribble # on the screen. -LINKER_ARGS=(-o "$BIN" --text-base 0x1000 --bss-base 0xA000 \ +LINKER_ARGS=(-o "$BIN" --text-base 0 --bss-base 0xA000 \ --map "$MAP" --reloc-out "$RELOC") if [ "$DEBUG" = 1 ]; then LINKER_ARGS+=(--debug-out "$DWARF") @@ -90,7 +101,7 @@ fi echo "OMF: -> $OUTBASE.omf" "$OMF" --input "$BIN" --map "$MAP" \ - --base 0x1000 --entry __start --output "$OUT" \ + --base 0 --entry __start --output "$OUT" \ --name "$(echo "$OUTBASE" | tr '[:lower:]' '[:upper:]' | cut -c1-8)" \ --expressload --relocs "$RELOC" diff --git a/demos/rsrcProbe.apl b/demos/rsrcProbe.apl index 1648aeca902307bef3c1dca875b31a16d7013b9d..e1becc3a61957d20a11a7c6af1c0a94c7a093898 100644 GIT binary patch delta 2060 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 eKV&gk&0`&px{|b=U~b~oW?t &buf, uint32_t off, // `if (weakFn) weakFn()` null test that the null is meant to fail. // recordCRelocSite handles the gate; byteCnt=2 distinguishes // from IMM24 (3) so omfEmit emits cRELOC ByteCnt=2 here. - recordCRelocSite(patchAddr, target, /*byteCnt=*/2, /*bitShift=*/0); + // Optimization: when text-base's low 16 bits are zero, the + // link-time baked operand (target & 0xFFFF) is already equal + // to (segPlacedBase + offsetRef) & 0xFFFF — because the + // Loader places KIND=0x1000 segments at bank-aligned bases + // (segPlacedBase.lo16 = 0), and we baked target = textBase + + // offsetRef, so the patch is a no-op. Skipping it eliminates + // 50–90% of cRELOC entries in typical builds (most data refs + // are IMM16); the GS/OS Loader walks each cRELOC site in a + // linear loop, so the per-boot reloc-application time drops + // proportionally. Programs that link with a non-bank-aligned + // text-base (e.g. bare-metal at $1000) still get the cRELOC. + if ((gTextBaseForSites & 0xFFFFu) != 0) + recordCRelocSite(patchAddr, target, /*byteCnt=*/2, /*bitShift=*/0); break; case R_W65816_BANK16: // 2-byte patch: byte 0 = bank of target, byte 1 = 0 (pad).