From 15f4eee6f3e7270f7dcbb69b0ae0e38428fffe59 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 22:33:21 +0300 Subject: [PATCH 01/12] stub: move things out of no32pl check --- src/djdev64/stub/stub.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 46a8b1eb..30643cbc 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -365,25 +365,24 @@ int djstub_main(int argc, char *argv[], char *envp[], pfile = ifile; if (stub_ver >= 7 && dyn) moff = 4; + coffset = offs; + noffset = offs; + if ((stub_ver >= 7 && !dyn) || !(buf[FLG2_OFF] & STFLG2_EMBOV)) { + memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); + noffset += coffsize; + } if (buf[FLG1_OFF] & STFLG1_NO32PL) { - noffset = offs; - moff = 4; done = 1; assert(dyn); OPEN_DYN(); } else { pl32++; - coffset = offs; if (stub_ver == 6) { /* static crt0 in emb_ov - deprecated */ uint32_t ooffs; memcpy(&ooffs, &buf[0x2c], sizeof(ooffs)); coffset += ooffs; } - memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); - noffset = offs; - if ((stub_ver >= 7 && !dyn) || !(buf[FLG2_OFF] & STFLG2_EMBOV)) - noffset += coffsize; } if (buf[FLG1_OFF] & STFLG1_COMPACT) compact_va = 1; From 5f8e15923cfb7ac53ecf26ff29efd67ec9218e67 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 22:35:33 +0300 Subject: [PATCH 02/12] stub: hard-code STFLAGS_OFF It was changed in v4, which is no longer relevant. --- src/djdev64/stub/stub.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 30643cbc..c675ec7b 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -58,6 +58,8 @@ #define STFLG2_C32PL 0x40 // have core 32bit payload #define STFLG2_EMBOV 0x80 // embedded overlay layout +static const int STFLAGS_OFF = 0x38; + #define MB (1024 * 1024) #define VA_SZ (2*MB) @@ -221,7 +223,6 @@ int djstub_main(int argc, char *argv[], char *envp[], _GO32_StubInfo stubinfo = {0}; _GO32_StubInfo *stubinfo_p; struct ldops *ops = NULL; - int STFLAGS_OFF = 0x2c; int compact_va = 0; int dj32 = 0; struct dos_ops *ioops = dosops; @@ -353,8 +354,6 @@ int djstub_main(int argc, char *argv[], char *envp[], cnt++; #endif stubinfo.stubinfo_ver |= stub_ver << 16; - if (stub_ver >= 6) - STFLAGS_OFF = 0x38; if (stub_ver >= 7) stubinfo.flags |= SIFLG_SPLITPL; stub_debug("Found exe header %i at 0x%lx\n", cnt, coffset); From 00671c9de4e26a5f9e011ef721a64a41373f99ba Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 22:37:34 +0300 Subject: [PATCH 03/12] stub: remove v6 remnants --- src/djdev64/stub/stub.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index c675ec7b..48a9722f 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -366,7 +366,7 @@ int djstub_main(int argc, char *argv[], char *envp[], moff = 4; coffset = offs; noffset = offs; - if ((stub_ver >= 7 && !dyn) || !(buf[FLG2_OFF] & STFLG2_EMBOV)) { + if (stub_ver >= 7 && !dyn) { memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); noffset += coffsize; } @@ -376,12 +376,6 @@ int djstub_main(int argc, char *argv[], char *envp[], OPEN_DYN(); } else { pl32++; - if (stub_ver == 6) { - /* static crt0 in emb_ov - deprecated */ - uint32_t ooffs; - memcpy(&ooffs, &buf[0x2c], sizeof(ooffs)); - coffset += ooffs; - } } if (buf[FLG1_OFF] & STFLG1_COMPACT) compact_va = 1; From fa9a69432e6ae6c44c27b80466f0835a16518d29 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 22:42:42 +0300 Subject: [PATCH 04/12] stub: vacate NO32PL flag In v7 it is no longer needed. crt0 goes to ovl0 and upl goes into emb_ov. --- src/djdev64/stub/stub.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index 48a9722f..ea70cd93 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -53,11 +53,13 @@ * They can't be set together, and as such, when we have a core payload, * there is no indication of whether or not the user payload is also * present. */ -#define STFLG1_NO32PL 0x80 // no 32bit payload +#define STFLG1_rsv 0x80 // no 32bit payload - pre-v7 stubs #define STFLG2_DJ32 0x20 // dj32 payload #define STFLG2_C32PL 0x40 // have core 32bit payload #define STFLG2_EMBOV 0x80 // embedded overlay layout +#define HAS_32PL(buf) (buf[FLG2_OFF] & STFLG2_EMBOV) + static const int STFLAGS_OFF = 0x38; #define MB (1024 * 1024) @@ -223,7 +225,6 @@ int djstub_main(int argc, char *argv[], char *envp[], _GO32_StubInfo stubinfo = {0}; _GO32_StubInfo *stubinfo_p; struct ldops *ops = NULL; - int compact_va = 0; int dj32 = 0; struct dos_ops *ioops = dosops; uint8_t stub_ver = 0; @@ -370,15 +371,8 @@ int djstub_main(int argc, char *argv[], char *envp[], memcpy(&coffsize, &buf[0x1c], sizeof(coffsize)); noffset += coffsize; } - if (buf[FLG1_OFF] & STFLG1_NO32PL) { - done = 1; - assert(dyn); - OPEN_DYN(); - } else { + if (HAS_32PL(buf)) pl32++; - } - if (buf[FLG1_OFF] & STFLG1_COMPACT) - compact_va = 1; if (buf[FLG2_OFF] & STFLG2_DJ32) { done = 1; dj32 = 1; @@ -421,7 +415,6 @@ int djstub_main(int argc, char *argv[], char *envp[], if (is_64) { dyn++; OPEN_DYN(); - compact_va = 1; // TODO - evaluate? stubinfo.flags = ((STFLG2_EMBOV) << 8) | STFLG1_COMPACT; stubinfo.flags |= SHM_FLAGS; nsize = dosops->_dos_seek(ifile, 0, SEEK_END); @@ -435,9 +428,7 @@ int djstub_main(int argc, char *argv[], char *envp[], } else if (is_64 && (stub_ver < 7 || !dyn)) { error("djstub: 64bit ELF at position %lx\n", coffset); return -1; - } else if (dyn) { - OPEN_DYN(); - } else { + } else if (!dyn) { ops = &elf_ops; } done = 1; @@ -447,7 +438,7 @@ int djstub_main(int argc, char *argv[], char *envp[], } dosops->_dos_seek(ifile, coffset, SEEK_SET); } - if (dyn && !pl32 && coffset) + if (dyn && coffset) OPEN_DYN(); assert(ops); assert(pfile != -1); @@ -508,7 +499,7 @@ int djstub_main(int argc, char *argv[], char *envp[], if (!dj32 && va_size > MB) exit(EXIT_FAILURE); /* if we load 2 payloads, use larger estimate */ - if ((dyn && pl32) || compact_va) { + if (pl32) { stubinfo.initial_size = VA_SZ; stubinfo.upl_base = va; stubinfo.upl_size = VA_SZ; From 0464e6d633fff1e9ce904b38f1658830e4301109 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 8 Jul 2026 01:14:17 +0300 Subject: [PATCH 05/12] stub: vacate COMPACT flag Not needed in v7. --- src/djdev64/stub/stub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index ea70cd93..db3b9d8c 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -47,7 +47,7 @@ #define FLG1_OFF STFLAGS_OFF #define FLG2_OFF (STFLAGS_OFF + 1) -#define STFLG1_COMPACT 0x20 // compact 32bit VA layout +#define STFLG1_rsv2 0x20 // compact 32bit VA layout - pre-v7 stubs #define STFLG1_STATIC SIFLG_STATIC // 0x40 - static linking /* 2 flags below are chosen for compatibility between v4 and v5 stubs. * They can't be set together, and as such, when we have a core payload, @@ -415,7 +415,7 @@ int djstub_main(int argc, char *argv[], char *envp[], if (is_64) { dyn++; OPEN_DYN(); - stubinfo.flags = ((STFLG2_EMBOV) << 8) | STFLG1_COMPACT; + stubinfo.flags = (STFLG2_EMBOV) << 8; stubinfo.flags |= SHM_FLAGS; nsize = dosops->_dos_seek(ifile, 0, SEEK_END); } else { From 2cf6533c4bc271986accafddc915270dd26f4cc4 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 22:58:19 +0300 Subject: [PATCH 06/12] demos: adapt to automated runs All demos except rmcb, are now non-interactive, and can serve for auto-testing. --- demos/asmsimp/djgpp/makefile | 2 +- demos/file/32/makefile | 2 +- demos/file/djgpp/makefile | 2 +- demos/file/file.c | 4 ++-- demos/file/makefile | 2 +- demos/int86/32/makefile | 2 +- demos/int86/djgpp/makefile | 2 +- demos/int86/file.c | 4 ++-- demos/int86/makefile | 2 +- demos/rmcb/32/makefile | 8 +++++--- demos/rmcb/djgpp/makefile | 8 +++++--- demos/rmcb/makefile | 8 +++++--- 12 files changed, 26 insertions(+), 20 deletions(-) diff --git a/demos/asmsimp/djgpp/makefile b/demos/asmsimp/djgpp/makefile index fb54cff9..ba9f202d 100644 --- a/demos/asmsimp/djgpp/makefile +++ b/demos/asmsimp/djgpp/makefile @@ -28,7 +28,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: $(TGT) djstubify $< diff --git a/demos/file/32/makefile b/demos/file/32/makefile index 1f1bc87e..7e860d8a 100644 --- a/demos/file/32/makefile +++ b/demos/file/32/makefile @@ -25,7 +25,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: tmp.elf dosemu -dumb -K . -E "elfexec2 $<" diff --git a/demos/file/djgpp/makefile b/demos/file/djgpp/makefile index f6cbf7e9..e348cc01 100644 --- a/demos/file/djgpp/makefile +++ b/demos/file/djgpp/makefile @@ -26,7 +26,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: $(TGT) djstubify $< diff --git a/demos/file/file.c b/demos/file/file.c index ff3da050..4c8a97ae 100644 --- a/demos/file/file.c +++ b/demos/file/file.c @@ -15,7 +15,7 @@ int main() puts("\n"); while (fgets(buf, sizeof(buf), f)) fputs(buf, stdout); - puts("\n\npress any key to exit"); - getch(); +// puts("\n\npress any key to exit"); +// getch(); return EXIT_SUCCESS; } diff --git a/demos/file/makefile b/demos/file/makefile index b669c565..1cd70e1d 100644 --- a/demos/file/makefile +++ b/demos/file/makefile @@ -22,7 +22,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: libtmp.so dosemu -dumb -K . -E "elfexec $<" diff --git a/demos/int86/32/makefile b/demos/int86/32/makefile index 1f1bc87e..7e860d8a 100644 --- a/demos/int86/32/makefile +++ b/demos/int86/32/makefile @@ -25,7 +25,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: tmp.elf dosemu -dumb -K . -E "elfexec2 $<" diff --git a/demos/int86/djgpp/makefile b/demos/int86/djgpp/makefile index f6cbf7e9..e348cc01 100644 --- a/demos/int86/djgpp/makefile +++ b/demos/int86/djgpp/makefile @@ -26,7 +26,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: $(TGT) djstubify $< diff --git a/demos/int86/file.c b/demos/int86/file.c index 1c53536e..fcc53c54 100644 --- a/demos/int86/file.c +++ b/demos/int86/file.c @@ -80,7 +80,7 @@ int main() sz = do_read(fd, buf, sizeof(buf)); if (sz > 0) do_write(STDOUT_FILENO, buf, sz); - puts("\n\npress any key to exit"); - getch(); +// puts("\n\npress any key to exit"); +// getch(); return EXIT_SUCCESS; } diff --git a/demos/int86/makefile b/demos/int86/makefile index b669c565..1cd70e1d 100644 --- a/demos/int86/makefile +++ b/demos/int86/makefile @@ -22,7 +22,7 @@ info: $(TGT) djstubify -i $< run: $(TGT) - dosemu -t $< + dosemu -dumb $< runelf: libtmp.so dosemu -dumb -K . -E "elfexec $<" diff --git a/demos/rmcb/32/makefile b/demos/rmcb/32/makefile index 3dc9606f..9165f494 100644 --- a/demos/rmcb/32/makefile +++ b/demos/rmcb/32/makefile @@ -31,11 +31,13 @@ clean: clean_dj32 info: $(TGT) djstubify -i $< -run: $(TGT) +run: +runi: $(TGT) dosemu -t $< -runelf: tmp.elf - dosemu -dumb -l $< -g 1 +runelf: +runelfi: tmp.elf + dosemu -t -l $< -g 1 # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj32) diff --git a/demos/rmcb/djgpp/makefile b/demos/rmcb/djgpp/makefile index 149c3907..00e27c08 100644 --- a/demos/rmcb/djgpp/makefile +++ b/demos/rmcb/djgpp/makefile @@ -28,9 +28,11 @@ clean: info: $(TGT) djstubify -i $< -run: $(TGT) +run: +runi: $(TGT) dosemu -t $< -runelf: $(TGT) +runelf: +runelfi: $(TGT) djstubify $< - dosemu -dumb $< + dosemu -t $< diff --git a/demos/rmcb/makefile b/demos/rmcb/makefile index 56141181..3d6dcfd3 100644 --- a/demos/rmcb/makefile +++ b/demos/rmcb/makefile @@ -25,11 +25,13 @@ clean: clean_dj64 info: $(TGT) djstubify -i $< -run: $(TGT) +run: +runi: $(TGT) dosemu -t $< -runelf: libtmp.so - dosemu -dumb -l $< +runelf: +runelfi: libtmp.so + dosemu -t -l $< # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) From 51afd43365155b2d58cbe070fdc56b4e9479b541 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 23:00:36 +0300 Subject: [PATCH 07/12] demos: propagate errors --- demos/makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demos/makefile b/demos/makefile index 9cad613e..5598dc4e 100644 --- a/demos/makefile +++ b/demos/makefile @@ -20,9 +20,9 @@ clean: $(foreach D,$(DEMOS),$(MAKE) -C $(D)/32 clean;) run runelf: - $(foreach D,$(DEMOS),$(MAKE) -C $(D) $@;) - $(foreach D,$(DEMOS),$(MAKE) -C $(D)/32 $@;) - $(foreach D,$(DEMOS),$(MAKE) -C $(D)/djgpp $@;) + set -e; $(foreach D,$(DEMOS),$(MAKE) -C $(D) $@;) + set -e; $(foreach D,$(DEMOS),$(MAKE) -C $(D)/32 $@;) + set -e; $(foreach D,$(DEMOS),$(MAKE) -C $(D)/djgpp $@;) rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) From 62e6d88493f189ddcaa44a04bd7eb19073c267e7 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 23:04:16 +0300 Subject: [PATCH 08/12] demos: test more ELF loaders --- demos/asmsimp/makefile | 1 + demos/file/makefile | 1 + demos/hello/makefile | 1 + demos/helloasm/makefile | 1 + demos/int86/makefile | 1 + 5 files changed, 5 insertions(+) diff --git a/demos/asmsimp/makefile b/demos/asmsimp/makefile index 5a37518e..15109600 100644 --- a/demos/asmsimp/makefile +++ b/demos/asmsimp/makefile @@ -29,6 +29,7 @@ run: $(TGT) runelf: libtmp.so dosemu -dumb -l $< + dosemu -dumb -l $< -g 1 # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) diff --git a/demos/file/makefile b/demos/file/makefile index 1cd70e1d..8afa57e6 100644 --- a/demos/file/makefile +++ b/demos/file/makefile @@ -26,6 +26,7 @@ run: $(TGT) runelf: libtmp.so dosemu -dumb -K . -E "elfexec $<" + dosemu -dumb -K . -E "elfexec2 $<" # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) diff --git a/demos/hello/makefile b/demos/hello/makefile index b9fee2fe..69640e72 100644 --- a/demos/hello/makefile +++ b/demos/hello/makefile @@ -23,6 +23,7 @@ run: $(TGT) runelf: libtmp.so dosemu -dumb -l $< + dosemu -dumb -l $< -g 1 # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) diff --git a/demos/helloasm/makefile b/demos/helloasm/makefile index 131de777..8b6a7f22 100644 --- a/demos/helloasm/makefile +++ b/demos/helloasm/makefile @@ -30,6 +30,7 @@ run: $(TGT) runelf: libtmp.so dosemu -dumb -l $< + dosemu -dumb -l $< -g 1 # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) diff --git a/demos/int86/makefile b/demos/int86/makefile index 1cd70e1d..8afa57e6 100644 --- a/demos/int86/makefile +++ b/demos/int86/makefile @@ -26,6 +26,7 @@ run: $(TGT) runelf: libtmp.so dosemu -dumb -K . -E "elfexec $<" + dosemu -dumb -K . -E "elfexec2 $<" # hook in dj64 - make sure to not do that before defining `all:` target DJMK = $(shell pkg-config --silence-errors --variable=makeinc dj64) From 9458c8406f2d1d878843829e47c268d7aa00b28f Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Tue, 7 Jul 2026 23:05:54 +0300 Subject: [PATCH 09/12] ci: run autotests on demos This covers quite a lot of stub functionality, which was exceptionally buggy all the time. That needs to be changed. --- ci_test.sh | 7 ++++++- ci_test_prereq.sh | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ci_test.sh b/ci_test.sh index fc5247c2..20f9b569 100755 --- a/ci_test.sh +++ b/ci_test.sh @@ -2,7 +2,12 @@ set -e -x -make demos -j 9 +make demos_static +make -C demos run +make -C demos runelf +make demos_clean demos +make -C demos run +make -C demos runelf cd demos/hello ls -l hello make host.elf diff --git a/ci_test_prereq.sh b/ci_test_prereq.sh index e098537b..f7e604bd 100755 --- a/ci_test_prereq.sh +++ b/ci_test_prereq.sh @@ -2,4 +2,5 @@ sudo add-apt-repository ppa:stsp-0/dj64 sudo add-apt-repository ppa:dosemu2/ppa -sudo apt install -y djstub dj64-host dos2unix +sudo add-apt-repository -y ppa:jwt27/djgpp-toolchain +sudo apt install -y djstub dj64-host dos2unix gcc-djgpp djgpp-dev From 970946a6acc092342c83fb5bad90096b00ce17c2 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 8 Jul 2026 01:43:33 +0300 Subject: [PATCH 10/12] ci: split test action --- .github/workflows/ci-build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 7a043687..2229a20e 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -40,4 +40,7 @@ jobs: - name: Set up test environment run: | ./ci_test_prereq.sh + + - name: Run tests + run: | ./ci_test.sh From 5136241c711fc5f62c8a07b690820f5699f72ece Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 8 Jul 2026 02:11:44 +0300 Subject: [PATCH 11/12] stub: prefix debug messages --- src/djdev64/stub/stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/djdev64/stub/stub.c b/src/djdev64/stub/stub.c index db3b9d8c..9fb9d510 100644 --- a/src/djdev64/stub/stub.c +++ b/src/djdev64/stub/stub.c @@ -39,7 +39,7 @@ #define STUB_DEBUG 1 #if STUB_DEBUG -#define stub_debug(...) J_printf(do_printf, DJ64_PRINT_LOG, __VA_ARGS__) +#define stub_debug(f, ...) J_printf(do_printf, DJ64_PRINT_LOG, "stub: " f, ##__VA_ARGS__) #else #define stub_debug(...) #endif From 3b74a5c4cfdf45463663cfbe418bf54445c99513 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Wed, 8 Jul 2026 02:39:22 +0300 Subject: [PATCH 12/12] ci: install missing djdev libs --- .github/workflows/ci-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 2229a20e..9629d2fa 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -27,8 +27,11 @@ jobs: id: build run: | make deb - sudo dpkg -i ../dj64*.deb sudo dpkg -i ../dj32*.deb + sudo dpkg -i ../dj64*.deb + sudo dpkg -i ../libdjdev64*.deb + sudo dpkg -i ../libdjstub64*.deb + sudo dpkg -i ../djdev64*.deb - name: Upload failure logs if: ${{ always() && (steps.build.outcome == 'failure') }}