From f5f503c7b1a24a7410fc27972b8195901b0ba54e Mon Sep 17 00:00:00 2001 From: Eldred Habert Date: Sun, 27 Sep 2026 01:27:41 +0200 Subject: [PATCH 01/15] Bump our Ubuntu runners (#2168) chore: No supported no moar :(( --- .github/workflows/testing.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 054e7038..ca868c7c 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -40,15 +40,15 @@ jobs: unix: strategy: matrix: - os: [ubuntu-22.04, macos-15-intel, macos-26] + os: [ubuntu-24.04, ubuntu-26.04-arm, macos-15-intel, macos-26] cxx: [g++, clang++] buildsys: [make, cmake] exclude: # Don't use `g++` on macOS; it's just an alias to `clang++`. - { os: macos-15-intel, cxx: g++ } - { os: macos-26, cxx: g++ } include: # Use `g++-10`, the earliest GCC version we support, on the earliest Ubuntu runner. - - { os: ubuntu-22.04, cxx: g++-10, buildsys: make } - - { os: ubuntu-22.04, cxx: g++-10, buildsys: cmake } + - { os: ubuntu-24.04, cxx: g++-10, buildsys: make } + - { os: ubuntu-24.04, cxx: g++-10, buildsys: cmake } fail-fast: false runs-on: ${{ matrix.os }} steps: From 321ad497fa4b248421ce73aa4f812b41dc3311bc Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:31:53 -0400 Subject: [PATCH 02/15] Fix RGBFIX `--output` with a pre-existing or same-as-input file (#2145) --- include/platform.hpp | 6 ++++++ src/fix/fix.cpp | 21 +++++++++++++++++++-- test/fix/test.sh | 25 +++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/platform.hpp b/include/platform.hpp index ab7d4fc6..bbee456e 100644 --- a/include/platform.hpp +++ b/include/platform.hpp @@ -53,6 +53,12 @@ #define O_TEXT 0 // Assume that it's not defined either #endif // _MSC_VER +// MSVC doesn't have POSIX `ftruncate`, use a suitable replacement +#if defined(_MSC_VER) + #include // IWYU pragma: export + #define ftruncate _chsize_s +#endif + // Windows has stdin and stdout open as text by default, which we may not want #if defined(_MSC_VER) || defined(__MINGW32__) #include // IWYU pragma: export diff --git a/src/fix/fix.cpp b/src/fix/fix.cpp index 9cf7d613..d447f3fe 100644 --- a/src/fix/fix.cpp +++ b/src/fix/fix.cpp @@ -381,6 +381,24 @@ static void if (options.padValue == UNSPECIFIED) { rom0Len = headerSize; } + } else if (output != STDOUT_FILENO) { + // Truncate a pre-existing output file before writing to it + if (ftruncate(output, 0) != 0) { + // LCOV_EXCL_START + int errnum = errno; + if (errnum == EINVAL) { + // We do not support FIFOs or symlinks + if (struct stat stat; fstat(output, &stat) == 0 && !S_ISREG(stat.st_mode)) { + error( + "\"%s\" is not a regular file, and thus cannot be modified in-place", name + ); + return; + } + } + error("Failed to truncate \"%s\": %s", name, strerror(errnum)); + return; + // LCOV_EXCL_STOP + } } writeLen = writeBytes(output, rom0, rom0Len); @@ -498,8 +516,7 @@ bool fix_ProcessFile(char const *name, char const *outputName) { error("Failed to open \"%s\" for reading+writing: %s", name, strerror(errno)); } else { Defer closeInput{[&] { xclose(input); }}; - struct stat stat; - if (fstat(input, &stat) == -1) { + if (struct stat stat; fstat(input, &stat) == -1) { error("Failed to stat \"%s\": %s", name, strerror(errno)); // LCOV_EXCL_LINE } else if (!S_ISREG(stat.st_mode)) { // We do not support FIFOs or symlinks // LCOV_EXCL_START diff --git a/test/fix/test.sh b/test/fix/test.sh index 7c48a24d..0c286727 100755 --- a/test/fix/test.sh +++ b/test/fix/test.sh @@ -44,7 +44,7 @@ tryDiff () { tryCmp () { if ! cmp "$1" "$2"; then - "$src/../../gbdiff.bash" "$1" "$2" + "$src/../../contrib/gbdiff.bash" "$1" "$2" | head echo "${bold}${red}${3:-$1} mismatch!${rescolors}${resbold}" false fi @@ -130,6 +130,26 @@ for i in "$src"/*.flags; do runTest "$(basename "$i" .flags)" "$src" done +# Check that RGBFIX truncates a pre-existing output file +name=pre-existing-output +echo "${bold}${green}${name}...${rescolors}${resbold}" +dd if=/dev/zero of=input.gb bs=1 count=336 >/dev/null 2>&1 +dd if=/dev/zero of=out.gb bs=1 count=16384 >/dev/null 2>&1 +eval "$RGBFIX" -o out.gb input.gb '>out.out' '2>out.err' +tryDiff out.out /dev/null "${name}.out" +tryDiff out.err /dev/null "${name}.err" +tryCmp input.gb out.gb "${name}.gb" + +# Check that RGBFIX handles an output file identical to the input file +name=equivalent-output +echo "${bold}${green}${name}...${rescolors}${resbold}" +dd if=/dev/zero of=input.gb bs=1 count=336 >/dev/null 2>&1 +cp input.gb out.gb +eval "$RGBFIX" -o out.gb out.gb '>out.out' '2>out.err' +tryDiff out.out /dev/null "${name}.out" +tryDiff out.err /dev/null "${name}.err" +tryCmp input.gb out.gb "${name}.gb" + # Check that RGBFIX errors out when inputting a non-existent file runSpecialTest no-exist no-exist @@ -149,7 +169,8 @@ for (( i=0; i < 10; ++i )); do echo "$padding..." for suffix in '' -large -larger; do cat <<<"-p $padding" >padding$suffix.flags - tr '\377' \\$((padding / 64))$(((padding / 8) % 8))$((padding % 8)) <"$src/padding$suffix.gb" >padding$suffix.gb # OK because $FF bytes are only used for padding + # `tr`ing &377 aka $FF is OK because $FF bytes are only used for padding + tr '\377' \\$((padding / 64))$(((padding / 8) % 8))$((padding % 8)) <"$src/padding$suffix.gb" >padding$suffix.gb runTest padding${suffix} . done done From fcd40310342a34fa088235bb84f3db27ee1b64b4 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sat, 26 Sep 2026 22:05:39 -0400 Subject: [PATCH 03/15] Combine `sect_BinaryFile` and `sect_BinaryFileSlice` (#2169) --- include/asm/section.hpp | 4 +- src/asm/parser.y | 6 +-- src/asm/section.cpp | 114 ++++++++++++---------------------------- 3 files changed, 39 insertions(+), 85 deletions(-) diff --git a/include/asm/section.hpp b/include/asm/section.hpp index e7a92ef9..3421a0c6 100644 --- a/include/asm/section.hpp +++ b/include/asm/section.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -100,8 +101,7 @@ void sect_RelBytes(uint32_t n, std::vector const &exprs); void sect_RelWord(Expression const &expr, uint32_t pcShift); void sect_RelLong(Expression const &expr, uint32_t pcShift); void sect_PCRelByte(Expression const &expr, uint32_t pcShift); -bool sect_BinaryFile(std::string const &name, uint32_t startPos); -bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length); +bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional length); void sect_EndSection(); void sect_PushSection(); diff --git a/src/asm/parser.y b/src/asm/parser.y index dbe8c6e4..8a84f309 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -1035,17 +1035,17 @@ include: incbin: POP_INCBIN string { - if (sect_BinaryFile($2, 0)) { + if (sect_BinaryFile($2, 0, std::nullopt)) { YYACCEPT; } } | POP_INCBIN string COMMA uconst { - if (sect_BinaryFile($2, $4)) { + if (sect_BinaryFile($2, $4, std::nullopt)) { YYACCEPT; } } | POP_INCBIN string COMMA uconst COMMA uconst { - if (sect_BinaryFileSlice($2, $4, $6)) { + if (sect_BinaryFile($2, $4, $6)) { YYACCEPT; } } diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 4e0f081b..3ff28016 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -978,10 +978,13 @@ void sect_PCRelByte(Expression const &expr, uint32_t pcShift) { } } -bool sect_BinaryFile(std::string const &name, uint32_t startPos) { +bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional length) { if (!requireCodeSection()) { return false; } + if (length.has_value() && *length == 0) { // Don't even bother with 0-byte slices + return false; + } FILE *file = nullptr; if (std::optional fullPath = fstk_FindFile(name); fullPath) { @@ -1002,6 +1005,16 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos) { *fileSize ); return false; + } else if (length.has_value() && *length > *fileSize - startPos) { + error( + "Specified range in `INCBIN` file \"%s\" is out of bounds (%" PRIu32 " + %" PRIu32 + " > %" PRIu64 ")", + name.c_str(), + startPos, + *length, + *fileSize + ); + return false; } // The file is seekable; skip to the specified start position fseek(file, startPos, SEEK_SET); @@ -1024,8 +1037,26 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos) { // LCOV_EXCL_STOP } - for (int byte; (byte = fgetc(file)) != EOF;) { - writeByte(byte); + if (length.has_value()) { + uint32_t remaining = *length; + for (; remaining; --remaining) { + if (int byte = fgetc(file); byte == EOF) { + break; // LCOV_EXCL_LINE + } else { + writeByte(byte); + } + } + if (remaining > 0 && !ferror(file)) { + error( + "Premature end of `INCBIN` file \"%s\" (%" PRId32 " bytes left to read)", + name.c_str(), + remaining + ); + } + } else { + for (int byte; (byte = fgetc(file)) != EOF;) { + writeByte(byte); + } } if (ferror(file)) { @@ -1036,83 +1067,6 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos) { return false; } -bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length) { - if (!requireCodeSection()) { - return false; - } - if (length == 0) { // Don't even bother with 0-byte slices - return false; - } - - FILE *file = nullptr; - if (std::optional fullPath = fstk_FindFile(name); fullPath) { - file = fopen(fullPath->c_str(), "rb"); - } - if (!file) { - return fstk_FileError(name, "`INCBIN`"); - } - Defer closeFile{[&] { xfclose(file); }}; - - if (std::optional fileSize = seekSize(file); fileSize.has_value()) { - if (startPos > *fileSize) { - error( - "Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%" PRIu64 - ")", - startPos, - name.c_str(), - *fileSize - ); - return false; - } else if (length > *fileSize - startPos) { - error( - "Specified range in `INCBIN` file \"%s\" is out of bounds (%" PRIu32 " + %" PRIu32 - " > %" PRIu64 ")", - name.c_str(), - startPos, - length, - *fileSize - ); - return false; - } - // The file is seekable; skip to the specified start position - fseek(file, startPos, SEEK_SET); - } else { - // LCOV_EXCL_START - if (errno != ESPIPE) { - error( - "Error determining size of `INCBIN` file \"%s\": %s", name.c_str(), strerror(errno) - ); - } - // The file isn't seekable, so we'll just skip bytes one at a time - while (startPos--) { - if (fgetc(file) == EOF) { - error( - "Specified start position is greater than length of file \"%s\"", name.c_str() - ); - return false; - } - } - // LCOV_EXCL_STOP - } - - while (length--) { - if (int byte = fgetc(file); byte != EOF) { - writeByte(byte); - // LCOV_EXCL_START - } else if (ferror(file)) { - error("Error reading `INCBIN` file \"%s\": %s", name.c_str(), strerror(errno)); - } else { - error( - "Premature end of `INCBIN` file \"%s\" (%" PRId32 " bytes left to read)", - name.c_str(), - length + 1 - ); - // LCOV_EXCL_STOP - } - } - return false; -} - void sect_PushSection() { sectionStack.push_front({ .section = currentSection, From dc585eb30207a849baef6d2fa5939c1979520f57 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sat, 26 Sep 2026 22:46:39 -0400 Subject: [PATCH 04/15] Bump the Ubuntu runner for creating release artifacts from 22.04 to 24.04 Follow-up to #2168 --- .github/workflows/create-release-artifacts.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-release-artifacts.yml b/.github/workflows/create-release-artifacts.yml index 29c12147..f9bd8341 100644 --- a/.github/workflows/create-release-artifacts.yml +++ b/.github/workflows/create-release-artifacts.yml @@ -87,13 +87,13 @@ jobs: if-no-files-found: error linux: - runs-on: ubuntu-22.04 # Oldest supported, for best glibc compatibility. + runs-on: ubuntu-24.04 # Oldest supported, for best glibc compatibility. steps: - name: Checkout repo uses: actions/checkout@v7 - name: Install deps run: | - ./.github/scripts/install-deps.sh ubuntu-22.04 + ./.github/scripts/install-deps.sh ubuntu-24.04 - name: Build binaries run: | make -k -j "$(getconf _NPROCESSORS_ONLN)" WARNFLAGS="-Werror -Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q= From f37e289fde13c76d9c96666cde1c34d52d82345f Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sun, 27 Sep 2026 09:07:33 -0400 Subject: [PATCH 05/15] Fix off-by-one error in transparent palette count --- src/gfx/reverse.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/gfx/reverse.cpp b/src/gfx/reverse.cpp index 617504e4..da7dd3a7 100644 --- a/src/gfx/reverse.cpp +++ b/src/gfx/reverse.cpp @@ -87,7 +87,7 @@ static void flushPng(png_structp png) { } static void printColor(std::optional const &color) { - if (color) { + if (color.has_value()) { fprintf(stderr, "#%08x", color->toCSS()); } else { fputs(" ", stderr); @@ -533,22 +533,16 @@ void reverse() { png_color pngPalette[4] = {}; png_byte pngTrans[4] = {}; int nbPngColors = 0, nbPngTrans = 0; - for (auto const &color : palettes[0]) { - if (color.has_value()) { - pngPalette[nbPngColors].red = color->red; - pngPalette[nbPngColors].green = color->green; - pngPalette[nbPngColors].blue = color->blue; - pngTrans[nbPngColors] = color->alpha; - if (color->alpha < 255) { - nbPngTrans = nbPngColors; - } - } else { - pngPalette[nbPngColors].red = 255; - pngPalette[nbPngColors].green = 255; - pngPalette[nbPngColors].blue = 255; - pngTrans[nbPngColors] = 255; - } + for (auto const &slot : palettes[0]) { + Rgba color = slot.has_value() ? *slot : Rgba(255, 255, 255, 255); + pngPalette[nbPngColors].red = color.red; + pngPalette[nbPngColors].green = color.green; + pngPalette[nbPngColors].blue = color.blue; + pngTrans[nbPngColors] = color.alpha; ++nbPngColors; + if (color.alpha < 255) { + nbPngTrans = nbPngColors; + } } png_set_PLTE(png, pngInfo, pngPalette, nbPngColors); if (nbPngTrans > 0) { From 6df932c0102cbd3b625d6109d27c3617d896d8f7 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 09:16:07 -0400 Subject: [PATCH 06/15] Fix `rgbgfx_test.cpp` 8-to-5 bit color conversion (#2172) --- test/gfx/rgbgfx_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gfx/rgbgfx_test.cpp b/test/gfx/rgbgfx_test.cpp index 8691d80e..c3df737a 100644 --- a/test/gfx/rgbgfx_test.cpp +++ b/test/gfx/rgbgfx_test.cpp @@ -466,7 +466,7 @@ int main(int argc, char *argv[]) { auto cgbColor = [](Rgba const &rgba) { auto field = [](uint16_t component, uint8_t shift) { - return (component & 0x1F) << shift; + return (component >> 3) << shift; }; return rgba.isTransparent() ? Rgba::transparent From 74ee2b217ffe10f8cec4d11161257d47fd46ea6f Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 11:37:31 -0400 Subject: [PATCH 07/15] Fix RGBFIX test harness's special tests (#2173) --- test/fix/test.sh | 66 ++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/test/fix/test.sh b/test/fix/test.sh index 0c286727..ff9dcdc5 100755 --- a/test/fix/test.sh +++ b/test/fix/test.sh @@ -35,6 +35,13 @@ rescolors="$(tput op)" RGBFIX="$src/../../rgbfix" +startTest () { + (( tests++ )) + if [[ $progress -ne 0 ]]; then + echo "${bold}${green}$1...${rescolors}${resbold}" + fi +} + tryDiff () { if ! diff -au --strip-trailing-cr "$1" "$2"; then echo "${bold}${red}${3:-$1} mismatch!${rescolors}${resbold}" @@ -61,11 +68,7 @@ runTest () { fi for variant in '' ' piped' ' output'; do - (( tests++ )) - our_rc=0 - if [[ $progress -ne 0 ]]; then - echo "${bold}${green}$1${variant}...${rescolors}${resbold}" - fi + startTest "$1${variant}" if [[ -r "$2/$1.bin" ]]; then desired_input="$2/$1.bin" else @@ -96,7 +99,7 @@ runTest () { desired_errname=/dev/null fi sed -e "s/$subst//g" -e "s#$src_subst##g" out.out | tryDiff "$desired_outname" - "$1.out${variant}" - (( our_rc = our_rc || $? )) + our_rc=$? sed -e "s/$subst//g" -e "s#$src_subst##g" out.err | tryDiff "$desired_errname" - "$1.err${variant}" (( our_rc = our_rc || $? )) @@ -116,11 +119,36 @@ runTest () { runSpecialTest () { name="$1" shift - echo "${bold}${green}${name}...${rescolors}${resbold}" + startTest "$name" + + eval "$RGBFIX" "$@" -o out.gb '>out.out' '2>out.err' + tryDiff out.out /dev/null "${name}.out" + our_rc=$? + tryDiff out.err /dev/null "${name}.err" + (( our_rc = our_rc || $? )) + tryCmp input.gb out.gb "${name}.gb" + (( our_rc = our_rc || $? )) + + (( rc = rc || our_rc )) + if [[ $our_rc -ne 0 ]]; then + (( failed++ )) + fi +} + +runTestExpectingFailure () { + name="$1" + shift + startTest "$name" + eval "$RGBFIX" "$@" '2>out.err' - rc=$((rc || $? != 1)) + our_rc=$(($? != 1)) tryDiff "$src/${name}.err" out.err "${name}.err" - rc=$((rc || $?)) + our_rc=$((our_rc || $?)) + + rc=$((rc || our_rc)) + if [[ $our_rc -ne 0 ]]; then + (( failed++ )) + fi } rm -f padding*_* # Delete padding test cases generated but not deleted (e.g. interrupted) @@ -131,33 +159,23 @@ for i in "$src"/*.flags; do done # Check that RGBFIX truncates a pre-existing output file -name=pre-existing-output -echo "${bold}${green}${name}...${rescolors}${resbold}" dd if=/dev/zero of=input.gb bs=1 count=336 >/dev/null 2>&1 dd if=/dev/zero of=out.gb bs=1 count=16384 >/dev/null 2>&1 -eval "$RGBFIX" -o out.gb input.gb '>out.out' '2>out.err' -tryDiff out.out /dev/null "${name}.out" -tryDiff out.err /dev/null "${name}.err" -tryCmp input.gb out.gb "${name}.gb" +runSpecialTest pre-existing-output input.gb # Check that RGBFIX handles an output file identical to the input file -name=equivalent-output -echo "${bold}${green}${name}...${rescolors}${resbold}" dd if=/dev/zero of=input.gb bs=1 count=336 >/dev/null 2>&1 cp input.gb out.gb -eval "$RGBFIX" -o out.gb out.gb '>out.out' '2>out.err' -tryDiff out.out /dev/null "${name}.out" -tryDiff out.err /dev/null "${name}.err" -tryCmp input.gb out.gb "${name}.gb" +runSpecialTest equivalent-output out.gb # Check that RGBFIX errors out when inputting a non-existent file -runSpecialTest no-exist no-exist +runTestExpectingFailure no-exist no-exist # Check that RGBFIX errors out when not inputting any file -runSpecialTest no-input +runTestExpectingFailure no-input # Check that RGBFIX errors out when inputting multiple files with an output file -runSpecialTest multiple-to-one one two three -o multiple-to-one +runTestExpectingFailure multiple-to-one one two three -o multiple-to-one # Check the result with all different padding bytes echo "${bold}Checking padding...${resbold}" From 877ce79a3919025339057b0dbf5e6136360da8eb Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 11:51:24 -0400 Subject: [PATCH 08/15] Remove non-functioning and unused `--installed-rgbds` flag from `run-tests.sh` (#2174) --- test/run-tests.sh | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/test/run-tests.sh b/test/run-tests.sh index 1d209f7c..61b8315f 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -18,8 +18,6 @@ Options: --only-free skip tests that build nonfree codebases --jobs build external codebases with `make -j` --os skip tests known to fail on (e.g. `macos-14`) - --installed-rgbds use the system installed RGBDS - (only compatible with external codebases) EOF } @@ -28,7 +26,6 @@ EOF nonfree=true internal=true external=true -installedrgbds=false make_jobs= osname= while [[ $# -gt 0 ]]; do @@ -46,9 +43,6 @@ while [[ $# -gt 0 ]]; do --only-free) nonfree=false ;; - --installed-rgbds) - installedrgbds=true - ;; --jobs) shift make_jobs="-j$1" @@ -73,26 +67,10 @@ if ! "$internal" && ! "$external"; then false fi -if "$internal" && "$installedrgbds"; then - echo "Please specify --only-external with --installed-rgbds" - echo "(internal tests don't support running with system-installed RGBDS)" - false -fi - # Refuse to run if RGBDS isn't available -if "$installedrgbds"; then - is_installed() { - command -v "$1" >/dev/null 2>&1 - } - if ! (is_installed rgbasm && is_installed rgblink && is_installed rgbfix && is_installed rgbgfx); then - echo "Please install RGBDS before running the tests" - false - fi -else - if [[ ! ( -x ../rgbasm && -x ../rgblink && -x ../rgbfix && -x ../rgbgfx ) ]]; then - echo "Please build RGBDS before running the tests" - false - fi +if [[ ! ( -x ../rgbasm && -x ../rgblink && -x ../rgbfix && -x ../rgbgfx ) ]]; then + echo "Please build RGBDS before running the tests" + false fi # Tests included with the repository From e06140be46fb54a357f063d780a523f3a0837cb2 Mon Sep 17 00:00:00 2001 From: Rangi Date: Sun, 27 Sep 2026 11:35:59 -0400 Subject: [PATCH 09/15] Actually use `-C` for `reverse_curve` test now that #2110 supports it --- test/gfx/reverse_curve.flags | 1 + test/gfx/reverse_curve.pal | Bin 16 -> 16 bytes test/gfx/reverse_no_curve.2bpp | 1 + test/gfx/reverse_no_curve.attrmap | Bin 0 -> 4 bytes test/gfx/reverse_no_curve.flags | 4 ++++ test/gfx/reverse_no_curve.pal | Bin 0 -> 16 bytes test/gfx/reverse_no_curve.tilemap | Bin 0 -> 4 bytes 7 files changed, 6 insertions(+) create mode 100644 test/gfx/reverse_no_curve.2bpp create mode 100644 test/gfx/reverse_no_curve.attrmap create mode 100644 test/gfx/reverse_no_curve.flags create mode 100644 test/gfx/reverse_no_curve.pal create mode 100644 test/gfx/reverse_no_curve.tilemap diff --git a/test/gfx/reverse_curve.flags b/test/gfx/reverse_curve.flags index 6f3e38c1..dffb5de7 100644 --- a/test/gfx/reverse_curve.flags +++ b/test/gfx/reverse_curve.flags @@ -1,3 +1,4 @@ +-C -m -t reverse_curve.tilemap -a reverse_curve.attrmap diff --git a/test/gfx/reverse_curve.pal b/test/gfx/reverse_curve.pal index 9f2400f84681d87f46e44ebf79e20bba8e4a19cf..9b443f7a8bb34e716aecece9f224c921e53e38d9 100644 GIT binary patch literal 16 Ucmexg|DRc*hJoQfkhTZX06<6vSO5S3 literal 16 Wcmexg|DTzmhJoQfkd{wjU;qF<00sa6 diff --git a/test/gfx/reverse_no_curve.2bpp b/test/gfx/reverse_no_curve.2bpp new file mode 100644 index 00000000..d8eb117d --- /dev/null +++ b/test/gfx/reverse_no_curve.2bpp @@ -0,0 +1 @@ +? @Lóˆóˆ˙€˙€˙€˙‰~G|C<# \ No newline at end of file diff --git a/test/gfx/reverse_no_curve.attrmap b/test/gfx/reverse_no_curve.attrmap new file mode 100644 index 0000000000000000000000000000000000000000..61516adee3ed082269ab6875ccab2dfe5c67a6ca GIT binary patch literal 4 LcmZQjU{nME0EYlW literal 0 HcmV?d00001 diff --git a/test/gfx/reverse_no_curve.flags b/test/gfx/reverse_no_curve.flags new file mode 100644 index 00000000..4730c870 --- /dev/null +++ b/test/gfx/reverse_no_curve.flags @@ -0,0 +1,4 @@ +-m +-t reverse_no_curve.tilemap +-a reverse_no_curve.attrmap +-p reverse_no_curve.pal diff --git a/test/gfx/reverse_no_curve.pal b/test/gfx/reverse_no_curve.pal new file mode 100644 index 0000000000000000000000000000000000000000..9f2400f84681d87f46e44ebf79e20bba8e4a19cf GIT binary patch literal 16 Wcmexg|DTzmhJoQfkd{wjU;qF<00sa6 literal 0 HcmV?d00001 diff --git a/test/gfx/reverse_no_curve.tilemap b/test/gfx/reverse_no_curve.tilemap new file mode 100644 index 0000000000000000000000000000000000000000..dee9c4c8adafc2e6af2ee0379ef082b7b43cd95f GIT binary patch literal 4 LcmZQzU}OXU00#gA literal 0 HcmV?d00001 From 721df27ae19dd6973e411f05522cdf452dabcc7e Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 12:08:32 -0400 Subject: [PATCH 10/15] Use Bash array for `run-tests.sh` args to `make` (#2175) --- test/run-tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/run-tests.sh b/test/run-tests.sh index 61b8315f..2b054758 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -26,7 +26,7 @@ EOF nonfree=true internal=true external=true -make_jobs= +make_args=() osname= while [[ $# -gt 0 ]]; do case "$1" in @@ -45,7 +45,7 @@ while [[ $# -gt 0 ]]; do ;; --jobs) shift - make_jobs="-j$1" + make_args+=(-j "$1") ;; --os) shift @@ -106,6 +106,6 @@ for cfg in *.cfg; do ( # Run nonfree tests only if they are opted into. if ! "$EXT_TEST_IS_NONFREE" || "$nonfree"; then - ./test.sh "$test_name" "$make_jobs" + ./test.sh "$test_name" "${make_args[@]}" fi ); done From ac7d7edf4d501e19d36a45c711cc245c911e2df2 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 13:02:37 -0400 Subject: [PATCH 11/15] Consistently compare .out.bin test results for RGBLINK tests (#2176) Tests with variant flags or linker scripts were not checking ROM output --- test/link/test.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/test/link/test.sh b/test/link/test.sh index 419485fd..785b622d 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -92,31 +92,39 @@ for i in *.asm; do continue fi - RGBLINKFLAGS=() if [ -f "${test}.flags" ]; then RGBLINKFLAGS+=("@${test}.flags") fi + ran_test=false + # 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" + bin=${test}-no${flag}.out.bin + if [ -f "$bin" ]; then + tryCmpRom "$bin" + fi evaluateTest - ran_flag=true + ran_test=true fi if [ -f "${test}${flag}.out" ]; then continueTest "$flag" rgblinkQuiet "${RGBLINKFLAGS[@]}" ${flag} -o "$gbtemp" "$otemp" 2>"$outtemp" tryDiff "${test}${flag}.out" "$outtemp" + bin=${test}${flag}.out.bin + if [ -f "$bin" ]; then + tryCmpRom "$bin" + fi evaluateTest - ran_flag=true + ran_test=true fi done - if "$ran_flag"; then + if "$ran_test"; then continue fi @@ -127,10 +135,14 @@ for i in *.asm; do continueTest "${script#${test}}" rgblinkQuiet "${RGBLINKFLAGS[@]}" -l "$script" -o "$gbtemp" "$otemp" 2>"$outtemp" tryDiff "${script%.link}.out" "$outtemp" + bin=${script%.link}.out.bin + if [ -f "$bin" ]; then + tryCmpRom "$bin" + fi evaluateTest - ran_flag=true + ran_test=true done - if "$ran_flag"; then + if "$ran_test"; then continue fi From c0a16e4bad7fe529c45d9f617b685215897be625 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 13:19:05 -0400 Subject: [PATCH 12/15] Move `File`-opening of PNG image into `Png` constructor (#2161) Also rename `File::c_str` to `display_name` for clarity --- include/file.hpp | 2 +- include/gfx/png.hpp | 5 +++++ src/gfx/main.cpp | 11 +---------- src/gfx/png.cpp | 13 +++++++++++++ src/gfx/process.cpp | 18 +++++++++++------- src/gfx/reverse.cpp | 10 ++++++---- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/file.hpp b/include/file.hpp index 6c9dd583..d781464d 100644 --- a/include/file.hpp +++ b/include/file.hpp @@ -47,7 +47,7 @@ public: } std::streambuf *operator->() { return &**this; } - char const *c_str(std::string const &path) const { + char const *display_name(std::string const &path) const { return std::holds_alternative(_file) ? path.c_str() : std::get(_file) == std::cin.rdbuf() ? "" : ""; diff --git a/include/gfx/png.hpp b/include/gfx/png.hpp index 87f15db6..74268514 100644 --- a/include/gfx/png.hpp +++ b/include/gfx/png.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include "gfx/rgba.hpp" @@ -17,7 +18,11 @@ struct Png { bool isIndexed = false; Png() {} + Png(std::string const &path); Png(char const *filename, std::streambuf &file); + +private: + void initialize(char const *filename, std::streambuf &file); }; #endif // RGBDS_GFX_PNG_HPP diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index 38dfc388..1406632c 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -5,7 +5,6 @@ #include "gfx/main.hpp" #include -#include #include #include #include @@ -19,7 +18,6 @@ #include "cli.hpp" #include "diagnostics.hpp" -#include "file.hpp" #include "helpers.hpp" #include "style.hpp" // style_Parse #include "usage.hpp" @@ -681,14 +679,7 @@ int main(int argc, char *argv[]) { bool useInputImage = !options.input.empty() && !localOptions.reverse; Png png; if (useInputImage) { - if (File image; - image.open(options.input, std::ios_base::in | std::ios_base::binary) == nullptr) { - fatal( - "Failed to open PNG image (\"%s\"): %s", image.c_str(options.input), strerror(errno) - ); - } else { - png = Png(image.c_str(options.input), *image); - } + png = Png(options.input); } // Execute deferred pal spec parsing, now that all other params are known. diff --git a/src/gfx/png.cpp b/src/gfx/png.cpp index 739a74d8..31ac5495 100644 --- a/src/gfx/png.cpp +++ b/src/gfx/png.cpp @@ -15,6 +15,7 @@ #include #include "diagnostics.hpp" +#include "file.hpp" #include "helpers.hpp" #include "verbosity.hpp" @@ -61,7 +62,19 @@ static void readData(png_structp png, png_bytep data, size_t length) { } } +Png::Png(std::string const &path) { + if (File image; image.open(path, std::ios_base::in | std::ios_base::binary) == nullptr) { + fatal("Failed to open PNG image (\"%s\"): %s", image.display_name(path), strerror(errno)); + } else { + initialize(image.display_name(path), *image); + } +} + Png::Png(char const *filename, std::streambuf &file) { + initialize(filename, file); +} + +void Png::initialize(char const *filename, std::streambuf &file) { Input input(filename, file); verbosePrint(VERB_NOTICE, "Reading PNG file \"%s\"\n", input.filename); diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 5cee407a..54154ac2 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -491,7 +491,11 @@ static void outputPalettes(std::vector const &palettes) { File output; if (!output.open(options.palettes, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.palettes), strerror(errno)); + fatal( + "Failed to create \"%s\": %s", + output.display_name(options.palettes), + strerror(errno) + ); // LCOV_EXCL_STOP } @@ -646,7 +650,7 @@ static void outputUnoptimizedTileData( File output; if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.output), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.display_name(options.output), strerror(errno)); // LCOV_EXCL_STOP } @@ -699,7 +703,7 @@ static void outputUnoptimizedMaps( file.emplace(); if (!file->open(path, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", file->c_str(path), strerror(errno)); + fatal("Failed to create \"%s\": %s", file->display_name(path), strerror(errno)); // LCOV_EXCL_STOP } } @@ -873,7 +877,7 @@ static void outputTileData(UniqueTiles const &tiles) { File output; if (!output.open(options.output, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.output), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.display_name(options.output), strerror(errno)); // LCOV_EXCL_STOP } @@ -913,7 +917,7 @@ static void outputTilemap(std::vector const &attrmap) { File output; if (!output.open(options.tilemap, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.tilemap), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.display_name(options.tilemap), strerror(errno)); // LCOV_EXCL_STOP } @@ -929,7 +933,7 @@ static void File output; if (!output.open(options.attrmap, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.attrmap), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.display_name(options.attrmap), strerror(errno)); // LCOV_EXCL_STOP } @@ -950,7 +954,7 @@ static void File output; if (!output.open(options.palmap, std::ios_base::out | std::ios_base::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", output.c_str(options.palmap), strerror(errno)); + fatal("Failed to create \"%s\": %s", output.display_name(options.palmap), strerror(errno)); // LCOV_EXCL_STOP } diff --git a/src/gfx/reverse.cpp b/src/gfx/reverse.cpp index da7dd3a7..362d2db7 100644 --- a/src/gfx/reverse.cpp +++ b/src/gfx/reverse.cpp @@ -31,7 +31,7 @@ static std::vector readInto(std::string const &path) { File file; if (!file.open(path, std::ios::in | std::ios::binary)) { - fatal("Failed to open \"%s\": %s", file.c_str(path), strerror(errno)); + fatal("Failed to open \"%s\": %s", file.display_name(path), strerror(errno)); } std::vector data(128 * 16); // Begin with some room pre-allocated @@ -207,7 +207,9 @@ void reverse() { if (!options.palettes.empty()) { File file; if (!file.open(options.palettes, std::ios::in | std::ios::binary)) { - fatal("Failed to open \"%s\": %s", file.c_str(options.palettes), strerror(errno)); + fatal( + "Failed to open \"%s\": %s", file.display_name(options.palettes), strerror(errno) + ); } palettes.clear(); @@ -478,12 +480,12 @@ void reverse() { File pngFile; if (!pngFile.open(options.input, std::ios::out | std::ios::binary)) { // LCOV_EXCL_START - fatal("Failed to create \"%s\": %s", pngFile.c_str(options.input), strerror(errno)); + fatal("Failed to create \"%s\": %s", pngFile.display_name(options.input), strerror(errno)); // LCOV_EXCL_STOP } png_structp png = png_create_write_struct( PNG_LIBPNG_VER_STRING, - const_cast(pngFile.c_str(options.input)), + const_cast(pngFile.display_name(options.input)), pngError, pngWarning ); From 32a9d3a01b0b6ed54f30083e9b791d61ebc4d47a Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 13:21:06 -0400 Subject: [PATCH 13/15] Consistently compare outputs for RGBGFX tests even when .err exists (#2177) --- test/gfx/test.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/gfx/test.sh b/test/gfx/test.sh index 3d3b50b7..727c44db 100755 --- a/test/gfx/test.sh +++ b/test/gfx/test.sh @@ -89,20 +89,26 @@ for f in *.png; do done newTest "$RGBGFX" $flags "$f" + test_rc=0 if [[ -e "${f%.png}.err" ]]; then runTest 2>"$errtmp" - diff -au --strip-trailing-cr "${f%.png}.err" "$errtmp" || failTest + diff -au --strip-trailing-cr "${f%.png}.err" "$errtmp" || test_rc=$? else - runTest && checkOutput "${f%.png}" || failTest $? + runTest || test_rc=$? fi + checkOutput "${f%.png}" || test_rc=$? + (( test_rc )) && failTest $test_rc newTest "$RGBGFX" $flags - "<$f" + test_rc=0 if [[ -e "${f%.png}.err" ]]; then runTest 2>"$errtmp" - diff -au --strip-trailing-cr "${f%.png}.err" <(sed "s##${f//#/\\#}#g" "$errtmp") || failTest + diff -au --strip-trailing-cr "${f%.png}.err" <(sed "s##${f//#/\\#}#g" "$errtmp") || test_rc=$? else - runTest && checkOutput "${f%.png}" || failTest $? + runTest || test_rc=$? fi + checkOutput "${f%.png}" || test_rc=$? + (( test_rc )) && failTest $test_rc done for f in *.[12]bpp; do @@ -122,7 +128,7 @@ for f in *.[12]bpp; do if [[ -e "${f%.[12]bpp}.err" ]]; then newTest "$RGBGFX $flags -o $f -r 1 result.png" runTest 2>"$errtmp" - diff -au --strip-trailing-cr "${f%.[12]bpp}.err" <(sed "s##${f//#/\\#}#g" "$errtmp") || failTest + diff -au --strip-trailing-cr "${f%.[12]bpp}.err" <(sed "s##${f//#/\\#}#g" "$errtmp") || failTest $? else newTest "$RGBGFX $flags -o $f -r 1 result.png && $RGBGFX $flags -o result.2bpp result.png" runTest && tryCmp "$f" result.2bpp || failTest $? From 093024c53400e162f2e11c5e53e04e423d66fcd3 Mon Sep 17 00:00:00 2001 From: Rangi Date: Sun, 27 Sep 2026 13:50:49 -0400 Subject: [PATCH 14/15] Verify that successful RGBLINK runs have no stderr output --- test/link/test.sh | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/test/link/test.sh b/test/link/test.sh index 785b622d..2d08afc6 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -14,9 +14,10 @@ gbtemp2="$(mktemp)" outtemp="$(mktemp)" outtemp2="$(mktemp)" outtemp3="$(mktemp)" +errtemp="$(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 +trap "rm -f ${otemp@Q} ${gbtemp@Q} ${gbtemp2@Q} ${outtemp@Q} ${outtemp2@Q} ${outtemp3@Q} ${errtemp@Q}" EXIT tests=0 failed=0 @@ -207,7 +208,8 @@ test="fragment-literals" startTest "$RGBASM" -o "$otemp" "$test"/a.asm continueTest -rgblinkQuiet -o "$gbtemp" -m "$outtemp" -n "$outtemp2" "$otemp" +rgblinkQuiet -o "$gbtemp" -m "$outtemp" -n "$outtemp2" "$otemp" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin tryDiff "$test"/ref.out.map "$outtemp" tryDiff "$test"/ref.out.sym "$outtemp2" @@ -218,7 +220,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$outtemp" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$outtemp" +rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$outtemp" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin tryDiff "$test"/ref.out.sym "$outtemp2" evaluateTest @@ -239,8 +242,10 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$outtemp" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" "$otemp" -rgblinkQuiet -o "$gbtemp2" "$outtemp" +rgblinkQuiet -o "$gbtemp" "$otemp" 2>"$errtemp" +tryDiff /dev/null "$errtemp" +rgblinkQuiet -o "$gbtemp2" "$outtemp" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmp "$gbtemp" "$gbtemp2" evaluateTest @@ -248,7 +253,8 @@ test="load-fragment/base" startTest "$RGBASM" -o "$otemp" "$test"/a.asm continueTest -rgblinkQuiet -o "$gbtemp" -n "$outtemp" "$otemp" +rgblinkQuiet -o "$gbtemp" -n "$outtemp" "$otemp" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin tryDiff "$test"/ref.out.sym "$outtemp" evaluateTest @@ -258,7 +264,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest @@ -268,7 +275,8 @@ startTest "$RGBASM" -o "$outtemp" "$test"/b.asm "$RGBASM" -o "$outtemp2" "$test"/c.asm continueTest -rgblinkQuiet -o "$gbtemp" -m "$outtemp3" -n "$gbtemp2" "$otemp" "$outtemp" "$outtemp2" +rgblinkQuiet -o "$gbtemp" -m "$outtemp3" -n "$gbtemp2" "$otemp" "$outtemp" "$outtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin tryDiff "$test"/ref.out.map "$outtemp3" tryDiff "$test"/ref.out.sym "$gbtemp2" @@ -399,7 +407,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest @@ -416,7 +425,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest @@ -425,7 +435,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest @@ -452,7 +463,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest @@ -461,7 +473,8 @@ startTest "$RGBASM" -o "$otemp" "$test"/a.asm "$RGBASM" -o "$gbtemp2" "$test"/b.asm continueTest -rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" +rgblinkQuiet -o "$gbtemp" -l "$test"/script.link "$otemp" "$gbtemp2" 2>"$errtemp" +tryDiff /dev/null "$errtemp" tryCmpRom "$test"/ref.out.bin evaluateTest From 1d4c741975ee130c6c6812f6d0ee9a846ef8108f Mon Sep 17 00:00:00 2001 From: Rangi Date: Sun, 27 Sep 2026 14:01:36 -0400 Subject: [PATCH 15/15] Test division and modulo at link time as well as asm time --- test/asm/div-mod.asm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/asm/div-mod.asm b/test/asm/div-mod.asm index 2103429d..baf56f8d 100644 --- a/test/asm/div-mod.asm +++ b/test/asm/div-mod.asm @@ -13,12 +13,10 @@ MACRO test_mod def x = \1 ; dividend def y = \2 ; divisor shift 2 - def q = x / y ; quotient - def r = x % y ; remainder ; identity laws - test (V (q * y + r)) == (V x) - test (V (x + y) % y) == (V r) - test (V (x - y) % y) == (V r) + test (V x) / y * y + (V x) % y == (V x) + test (V (x + y)) % y == (V x) % y + test (V (x - y)) % y == (V x) % y ENDM MACRO test_each_mod