Files
rgbds/test/link/test.sh
T
ISSOtm ef709fade6 Refactor and fix sect packing's bank iteration
Moving both pieces of related code together, as it were.
This also ends up changing the behaviour of scrambling,
where sections could “leak” out of the scrambling's bank pool
and resume being placed normally.

We have discussed it offline, and decided that this was a bug.
The test suite has been updated accordingly, which even gives
the occasion to move this test from a special case to the main
generic loop!
2026-09-18 21:19:37 +02:00

516 lines
13 KiB
Bash
Executable File

#!/usr/bin/env bash
set -o pipefail
export LC_ALL=C
# Screen width for help/usage text (for reproducible test results)
export COLUMNS=79
shopt -u checkwinsize # Prevent subsequent commands from resetting `COLUMNS`
otemp="$(mktemp)"
gbtemp="$(mktemp)"
gbtemp2="$(mktemp)"
outtemp="$(mktemp)"
outtemp2="$(mktemp)"
outtemp3="$(mktemp)"
# shellcheck disable=SC2064 # (Immediate expansion is the desired behavior.)
trap "rm -f ${otemp@Q} ${gbtemp@Q} ${gbtemp2@Q} ${outtemp@Q} ${outtemp2@Q} ${outtemp3@Q}" EXIT
tests=0
failed=0
rc=0
bold="$(tput bold)"
resbold="$(tput sgr0)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
rescolors="$(tput op)"
RGBASM=../../rgbasm
RGBLINK=../../rgblink
RGBFIX=../../rgbfix
startTest () {
echo "${bold}${green}${test} assembling...${rescolors}${resbold}"
}
continueTest () {
(( tests++ ))
our_rc=0
echo "${bold}${green}${test}$1...${rescolors}${resbold}"
}
tryDiff () {
if ! diff -au --strip-trailing-cr "$1" "$2"; then
echo "${bold}${red}$1 mismatch!${rescolors}${resbold}"
false
fi
(( our_rc = our_rc || $? ))
}
tryCmp () {
if ! cmp "$1" "$2"; then
../../contrib/gbdiff.bash "$1" "$2"
echo "${bold}${red}${test}.out.bin mismatch!${rescolors}${resbold}"
false
fi
(( our_rc = our_rc || $? ))
}
tryCmpRom () {
rom_size=$(wc -c <"$1")
# 'rgblink -x' implies '-t', so we cannot use '-x' to trim the ROM output
dd if="$gbtemp" count=1 bs="$rom_size" >"$otemp" 2>/dev/null
tryCmp "$1" "$otemp"
}
rgblinkQuiet () {
out="$(env "$RGBLINK" -Weverything -Bcollapse "$@")" || return $?
if [[ -n "$out" ]]; then
echo "$bold${red}Linking shouldn't produce anything on stdout!${rescolors}${resbold}"
false
fi
(( our_rc = our_rc || $? ))
}
evaluateTest () {
if [[ "$our_rc" -ne 0 ]]; then
(( failed++ ))
rc=1
fi
}
for i in *.asm; do
test=${i%.asm}
startTest
"$RGBASM" -o "$otemp" "${test}.asm"
RGBLINKFLAGS=()
if [ -f "${test}.flags" ]; then
RGBLINKFLAGS+=("@${test}.flags")
fi
# Some tests have variants depending on flags
ran_flag=false
for flag in '-d' '-t' '-w'; do
if [ -f "${test}-no${flag}.out" ]; then
continueTest "-no${flag}"
rgblinkQuiet "${RGBLINKFLAGS[@]}" -o "$gbtemp" "$otemp" 2>"$outtemp"
tryDiff "${test}-no${flag}.out" "$outtemp"
evaluateTest
ran_flag=true
fi
if [ -f "${test}${flag}.out" ]; then
continueTest "$flag"
rgblinkQuiet "${RGBLINKFLAGS[@]}" ${flag} -o "$gbtemp" "$otemp" 2>"$outtemp"
tryDiff "${test}${flag}.out" "$outtemp"
evaluateTest
ran_flag=true
fi
done
if "$ran_flag"; then
continue
fi
# Other tests have several linker scripts
for script in "$test"*.link; do
[[ -e "$script" ]] || break # If the glob doesn't match, it just... doesn't expand!
continueTest "${script#${test}}"
rgblinkQuiet "${RGBLINKFLAGS[@]}" -l "$script" -o "$gbtemp" "$otemp" 2>"$outtemp"
tryDiff "${script%.link}.out" "$outtemp"
evaluateTest
ran_flag=true
done
if "$ran_flag"; then
continue
fi
# The rest of the tests just links a file, and maybe checks the binary
continueTest
rgblinkQuiet "${RGBLINKFLAGS[@]}" -o "$gbtemp" "$otemp" 2>"$outtemp"
tryDiff "${test}.out" "$outtemp"
bin=${test}.out.bin
if [ -f "$bin" ]; then
tryCmpRom "$bin"
fi
evaluateTest
done
# These tests do their own thing
test="bank-const"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="constant-parent"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryDiff "$test"/ref.out.sym "$outtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="export-all"
startTest
"$RGBASM" -E -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryDiff "$test"/ref.out.sym "$outtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
for test in fragment-align/*; do
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
if [[ -f "$test"/out.gb ]]; then
tryCmpRom "$test"/out.gb
fi
evaluateTest
done
test="fragment-literals"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -m "$outtemp" -n "$outtemp2" "$otemp"
tryCmpRom "$test"/ref.out.bin
tryDiff "$test"/ref.out.map "$outtemp"
tryDiff "$test"/ref.out.sym "$outtemp2"
evaluateTest
test="jr-wraparound"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$outtemp" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$outtemp"
tryCmpRom "$test"/ref.out.bin
tryDiff "$test"/ref.out.sym "$outtemp2"
evaluateTest
test="jr-truncation"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$outtemp" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$outtemp" 2>"$outtemp3"
tryDiff "$test"/out.err "$outtemp3"
tryCmpRom "$test"/ref.out.bin
tryDiff "$test"/ref.out.sym "$outtemp2"
evaluateTest
test="high-low"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$outtemp" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp"
rgblinkQuiet -o "$gbtemp2" "$outtemp"
tryCmp "$gbtemp" "$gbtemp2"
evaluateTest
test="load-fragment/base"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp" "$otemp"
tryCmpRom "$test"/ref.out.bin
tryDiff "$test"/ref.out.sym "$outtemp"
evaluateTest
test="load-fragment/multiple-objects"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="load-fragment/section-fragment"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$outtemp" "$test"/b.asm
"$RGBASM" -o "$outtemp2" "$test"/c.asm
continueTest
rgblinkQuiet -o "$gbtemp" -m "$outtemp3" -n "$gbtemp2" "$otemp" "$outtemp" "$outtemp2"
tryCmpRom "$test"/ref.out.bin
tryDiff "$test"/ref.out.map "$outtemp3"
tryDiff "$test"/ref.out.sym "$gbtemp2"
evaluateTest
test="map-file"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -m "$outtemp2" "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryDiff "$test"/ref.out.map "$outtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="overlay/smaller"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -p 0x42 -O "$test"/overlay.gb "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
# This test does not trim its output with 'dd' because it needs to verify the correct output size
tryCmp "$test"/out.gb "$gbtemp"
evaluateTest
test="overlay/smaller-32k"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -t -O "$test"/overlay.gb "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
# This test does not trim its output with 'dd' because it needs to verify the correct output size
tryCmp "$test"/out.gb "$gbtemp"
evaluateTest
test="overlay/unfixed"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -O "$test"/overlay.gb "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="overlay/tiny"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -t -O "$test"/overlay.gb "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
# This test does not trim its output with 'dd' because it needs to verify the correct output size
tryCmp "$test"/out.gb "$gbtemp"
evaluateTest
test="pipeline"
startTest
continueTest
("$RGBASM" -o - - | "$RGBLINK" -o - - | "$RGBFIX" -v -p 0xff -) < "$test"/a.asm > "$gbtemp"
# This test does not trim its output with 'dd' because it needs to verify the correct output size
tryCmp "$test"/out.gb "$gbtemp"
evaluateTest
test="same-consts"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="scramble-invalid"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
# This `-S` argument contains spaces, so cannot be specified in a .flags file.
rgblinkQuiet -o "$gbtemp" -S "romx := 4" "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="script-ds"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="script-include"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="sdcc/good"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" -l "$test"/script.link "$otemp" "$test"/b.rel "$test"/c.rel 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryDiff "$test"/ref.out.sym "$outtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="sdcc/no-script"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet "$otemp" "$test"/b.rel 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="section-conflict/different-mod"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp" "$test"/b.asm
continueTest
rgblinkQuiet "$otemp" "$gbtemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="section-fragment/good"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="section-fragment/size-overflow"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
continueTest
rgblinkQuiet "$otemp" "$otemp" "$otemp" "$otemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="section-fragment/jr-offset"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="section-fragment/jr-offset-load"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="section-normal/same-name"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp" "$test"/b.asm
continueTest
rgblinkQuiet "$otemp" "$gbtemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="section-union/compat"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="section-union/good"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="section-union/same-export"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="section-union/same-label"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryCmpRom "$test"/ref.out.bin
evaluateTest
for i in section-union/*.asm section-fragment/*.asm; do
test=${i%.asm}
startTest
"$RGBASM" -o "$otemp" "${test}.asm"
"$RGBASM" -o "$gbtemp2" "${test}.asm" -DSECOND
continueTest
if rgblinkQuiet "$otemp" "$gbtemp2" 2>"$outtemp"; then
echo -e "${bold}${red}${test}.asm didn't fail to link!${rescolors}${resbold}"
our_rc=1
fi
echo --- >>"$outtemp"
# Ensure RGBASM also errors out
cat "${test}.asm" - "${test}.asm" <<<'def SECOND equs "1"' | "$RGBASM" - 2>>"$outtemp"
tryDiff "${test}.out" "$outtemp"
evaluateTest
done
test="symbols/conflict"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp" "$test"/b.asm
continueTest
rgblinkQuiet "$otemp" "$gbtemp" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
evaluateTest
test="symbols/good"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp2" "$test"/b.asm
continueTest
rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$gbtemp2" 2>"$outtemp"
tryDiff "$test"/out.err "$outtemp"
tryDiff "$test"/ref.out.sym "$outtemp2"
tryCmpRom "$test"/ref.out.bin
evaluateTest
test="symbols/unknown"
startTest
"$RGBASM" -o "$otemp" "$test"/a.asm
"$RGBASM" -o "$gbtemp" "$test"/b.asm
"$RGBASM" -o "$gbtemp2" "$test"/c.asm
"$RGBASM" -o "$outtemp" "$test"/d.asm
"$RGBASM" -o "$outtemp2" "$test"/e.asm
continueTest
rgblinkQuiet "$otemp" "$gbtemp" "$gbtemp2" "$outtemp" "$outtemp2" 2>"$outtemp3"
tryDiff "$test"/out.err "$outtemp3"
evaluateTest
if [[ "$failed" -eq 0 ]]; then
echo "${bold}${green}All ${tests} tests passed!${rescolors}${resbold}"
else
echo "${bold}${red}${failed} of the tests failed!${rescolors}${resbold}"
fi
exit $rc