--- /dev/null
+#include <exec/types.h>
+#include <graphics/gfx.h>
+#include <graphics/gfxmacros.h>
+#include <graphics/rastport.h>
+#include <intuition/intuition.h>
+#include <intuition/screens.h>
+#include <libraries/Picasso96.h>
+#include <proto/dos.h>
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/Picasso96.h>
+#include <stdlib.h>
+
+struct Library *P96Base;
+
+static void draw_smoke(struct Screen *screen)
+{
+ static UWORD pattern[] = { 0xaaaa, 0x5555 };
+ static const char label[] = "P96 draw";
+ struct RastPort *rp = &screen->RastPort;
+ PLANEPTR plane;
+
+ SetAPen(rp, 1);
+ RectFill(rp, 8, 8, 80, 40);
+
+ SetAPen(rp, 2);
+ SetBPen(rp, 0);
+ Move(rp, 12, 70);
+ Text(rp, (STRPTR)label, sizeof label - 1);
+
+ SetAfPt(rp, pattern, 1);
+ SetAPen(rp, 3);
+ SetBPen(rp, 0);
+ RectFill(rp, 96, 8, 160, 48);
+ SetAfPt(rp, NULL, 0);
+
+ plane = AllocRaster(16, 16);
+ if (plane) {
+ struct BitMap bitmap;
+ UWORD *words = (UWORD *)plane;
+ int i;
+
+ InitBitMap(&bitmap, 1, 16, 16);
+ bitmap.Planes[0] = plane;
+ BltClear(plane, RASSIZE(16, 16), 0);
+ for (i = 0; i < 16; i++) {
+ words[i] = (i & 1) ? 0x0f0f : 0xf0f0;
+ }
+ BltBitMap(&bitmap, 0, 0, rp->BitMap, 176, 16, 16, 16, 0xc0, 0xff, NULL);
+ FreeRaster(plane, 16, 16);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ ULONG display_id = 0x50031000;
+ ULONG width = 640;
+ ULONG height = 480;
+ ULONG depth = 16;
+ RGBFTYPE rgb_format = RGBFB_R5G6B5PC;
+
+ if (argc > 1) {
+ display_id = strtoul(argv[1], 0, 0);
+ }
+ if (argc > 2) {
+ width = strtoul(argv[2], 0, 0);
+ }
+ if (argc > 3) {
+ height = strtoul(argv[3], 0, 0);
+ }
+ if (argc > 4) {
+ depth = strtoul(argv[4], 0, 0);
+ }
+
+ switch (depth) {
+ case 15:
+ rgb_format = RGBFB_R5G5B5PC;
+ break;
+ case 16:
+ rgb_format = RGBFB_R5G6B5PC;
+ break;
+ case 24:
+ rgb_format = RGBFB_R8G8B8;
+ break;
+ case 32:
+ rgb_format = RGBFB_B8G8R8A8;
+ break;
+ default:
+ rgb_format = RGBFB_CLUT;
+ break;
+ }
+
+ P96Base = OpenLibrary(P96NAME, 0);
+ if (!P96Base) {
+ Printf("OPENSCREEN FAILED no %s\n", (ULONG)P96NAME);
+ return 5;
+ }
+
+ ULONG best_id = p96BestModeIDTags(
+ P96BIDTAG_NominalWidth, width,
+ P96BIDTAG_NominalHeight, height,
+ P96BIDTAG_Depth, depth,
+ P96BIDTAG_FormatsAllowed, 1UL << rgb_format,
+ TAG_DONE);
+ if (best_id != ~0UL) {
+ display_id = best_id;
+ }
+
+ struct Screen *screen = p96OpenScreenTags(
+ P96SA_DisplayID, display_id,
+ P96SA_Width, width,
+ P96SA_Height, height,
+ P96SA_Depth, depth,
+ P96SA_RGBFormat, rgb_format,
+ P96SA_Title, (ULONG)"Unix P96 direct-color smoke",
+ TAG_DONE);
+ if (!screen) {
+ Printf("OPENSCREEN FAILED %08lx %ldx%ldx%ld\n", display_id, width, height, depth);
+ CloseLibrary(P96Base);
+ return 5;
+ }
+
+ Printf("OPENSCREEN OK %08lx %ldx%ldx%ld\n", display_id, width, height, depth);
+ draw_smoke(screen);
+ Printf("DRAW OK\n");
+ Delay(100);
+ p96CloseScreen(screen);
+ CloseLibrary(P96Base);
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_smoke.log}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-5}
+A2065=${WINUAE_SMOKE_A2065:-0}
+SANA2=${WINUAE_SMOKE_SANA2:-0}
+RTG_Z3=${WINUAE_SMOKE_RTG_Z3:-0}
+UAEGFX=${WINUAE_SMOKE_UAEGFX:-0}
+UAEGFX_DRIVER=${WINUAE_SMOKE_UAEGFX_DRIVER:-0}
+UAEGFX_SCREEN=${WINUAE_SMOKE_UAEGFX_SCREEN:-0}
+DRIVECLICK=${WINUAE_SMOKE_DRIVECLICK:-0}
+SKIP_AUDIO_CHECK=${WINUAE_SMOKE_SKIP_AUDIO_CHECK:-0}
+
+ROM=${WINUAE_KICKSTART_ROM:-}
+ADF=${WINUAE_FLOPPY0:-}
+
+if [ -z "$ROM" ] || [ -z "$ADF" ]; then
+ echo "Set WINUAE_KICKSTART_ROM and WINUAE_FLOPPY0 before running this smoke test." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$ADF" ]; then
+ echo "ADF image not found: $ADF" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+set -- "$@"
+if [ "$A2065" = "1" ]; then
+ set -- "$@" -s a2065=slirp
+fi
+if [ "$SANA2" = "1" ]; then
+ set -- "$@" -s sana2=true
+fi
+if [ "$RTG_Z3" = "1" ]; then
+ set -- "$@" \
+ -s cpu_24bit_addressing=false \
+ -s gfxcard_size=16 \
+ -s gfxcard_type=ZorroIII
+fi
+if [ "$DRIVECLICK" = "1" ]; then
+ set -- "$@" \
+ -s floppy0sound=1 \
+ -s floppy0soundvolume_empty=0 \
+ -s floppy0soundvolume_disk=0
+fi
+
+"$EXE" \
+ -s use_gui=no \
+ -s kickstart_rom_file="$ROM" \
+ -s floppy0="$ADF" \
+ -s nr_floppies=1 \
+ -s chipset=aga \
+ -s chipset_compatible=A1200 \
+ -s cpu_model=68020 \
+ -s chipmem_size=4 \
+ -s cachesize=0 \
+ "$@" \
+ > "$LOG" 2>&1 &
+
+pid=$!
+trap 'kill -INT "$pid" 2>/dev/null || true' INT TERM EXIT
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+trap - INT TERM EXIT
+
+grep -q "Known ROM" "$LOG"
+if [ "$SKIP_AUDIO_CHECK" != "1" ]; then
+ grep -q "SDL3: audio initialized" "$LOG"
+fi
+grep -q "hardreset, memory cleared" "$LOG"
+if [ "$A2065" = "1" ]; then
+ grep -q "A2065" "$LOG"
+fi
+if [ "$SANA2" = "1" ]; then
+ grep -q "uaenet.device reset" "$LOG"
+ grep -q "SLIRP User Mode NAT" "$LOG"
+fi
+if [ "$RTG_Z3" = "1" ]; then
+ grep -q "UAE RTG" "$LOG"
+ grep -q "RTG RAM" "$LOG"
+fi
+if [ "$UAEGFX" = "1" ]; then
+ grep -q "Unix uaegfx.card" "$LOG"
+ grep -q "Unix RTG P96 RESINFO" "$LOG"
+fi
+if [ "$UAEGFX_DRIVER" = "1" ]; then
+ grep -q "Unix RTG FindCard:" "$LOG"
+ grep -q "Unix RTG InitCard:" "$LOG"
+ grep -q "Unix RTG uaegfx.card code:" "$LOG"
+fi
+if [ "$UAEGFX_SCREEN" = "1" ]; then
+ grep -q "Unix RTG SetGC:" "$LOG"
+ grep -q "Unix RTG SetPanning:" "$LOG"
+ grep -q "Unix RTG SetSwitch:" "$LOG"
+fi
+if [ "$DRIVECLICK" = "1" ]; then
+ grep -q "Unix driveclick: loaded built-in A500 sample set" "$LOG"
+fi
+if grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected config load failure in smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_SMOKE_A2065=1
+export WINUAE_SMOKE_A2065
+
+exec "$(dirname -- "$0")/unix-smoke-a1200.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_a4091_hdf_smoke.log}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-8}
+
+ROM=${WINUAE_A4000_KICKSTART_ROM:-${WINUAE_KICKSTART_ROM:-}}
+A4091_ROM=${WINUAE_A4091_ROM:-}
+HDF=${WINUAE_A4091_HDF:-${WINUAE_HARDFILE0:-}}
+
+if [ -z "$ROM" ] || [ -z "$A4091_ROM" ] || [ -z "$HDF" ]; then
+ echo "Set WINUAE_A4000_KICKSTART_ROM, WINUAE_A4091_ROM, and WINUAE_A4091_HDF before running this smoke test." >&2
+ echo "WINUAE_KICKSTART_ROM can be used instead of WINUAE_A4000_KICKSTART_ROM, and WINUAE_HARDFILE0 can be used instead of WINUAE_A4091_HDF." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "A4000 Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$A4091_ROM" ]; then
+ echo "A4091 ROM not found: $A4091_ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$HDF" ]; then
+ echo "A4091 HDF image not found: $HDF" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+"$EXE" \
+ -s use_gui=no \
+ -s kickstart_rom_file="$ROM" \
+ -s a4091_rom_file="$A4091_ROM" \
+ -s hardfile2="rw,DH0:$HDF,0,0,0,512,0,,scsi0_a4091" \
+ -s chipset=aga \
+ -s chipset_compatible=A4000 \
+ -s cpu_model=68030 \
+ -s cpu_24bit_addressing=false \
+ -s cachesize=0 \
+ > "$LOG" 2>&1 &
+
+pid=$!
+trap 'kill -INT "$pid" 2>/dev/null || true' INT TERM EXIT
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+trap - INT TERM EXIT
+
+grep -q "Known ROM" "$LOG"
+grep -q "Adding SCSI HD 'a4091' unit 0" "$LOG"
+grep -q "Card 02: 'A4091'" "$LOG"
+grep -q "NCR53C700/800" "$LOG"
+grep -q "hardreset, memory cleared" "$LOG"
+if grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected config load failure in smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix A4091 HDF smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_IDE_EXPANSION_BOARD=alfapower
+export WINUAE_IDE_EXPANSION_BOARD
+exec "$(dirname -- "$0")/unix-smoke-ide-expansion-hdf.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_SMOKE_DRIVECLICK=1
+export WINUAE_SMOKE_DRIVECLICK
+
+exec "$(dirname -- "$0")/unix-smoke-a1200.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-8}
+
+BOARD=${WINUAE_IDE_EXPANSION_BOARD:-alfapower}
+ROM=${WINUAE_A1200_KICKSTART_ROM:-${WINUAE_KICKSTART_ROM:-}}
+HDF=${WINUAE_IDE_EXPANSION_HDF:-${WINUAE_HARDFILE0:-}}
+HDF_CREATED=0
+
+case "$BOARD" in
+ alfapower)
+ ROM_KEY=alfapower_rom_file
+ CONTROLLER=ide0_alfapower
+ EXPECTED_CARD="AlfaPower/AT-Bus 2008"
+ ;;
+ ripple)
+ ROM_KEY=ripple_rom_file
+ CONTROLLER=ide0_ripple,ATA2+
+ EXPECTED_CARD="RIPPLE"
+ ;;
+ *)
+ echo "Unsupported WINUAE_IDE_EXPANSION_BOARD: $BOARD" >&2
+ echo "Supported values: alfapower, ripple" >&2
+ exit 2
+ ;;
+esac
+
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_${BOARD}_hdf_smoke.log}
+
+if [ -z "$ROM" ]; then
+ echo "Set WINUAE_A1200_KICKSTART_ROM or WINUAE_KICKSTART_ROM before running this smoke test." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "A1200 Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ -z "$HDF" ]; then
+ HDF=$(mktemp "${TMPDIR:-/tmp}/winuae_${BOARD}_hdf.XXXXXX")
+ HDF_CREATED=1
+ dd if=/dev/zero of="$HDF" bs=1048576 count="${WINUAE_IDE_EXPANSION_HDF_MB:-8}" >/dev/null 2>&1
+elif [ ! -f "$HDF" ]; then
+ echo "IDE expansion HDF image not found: $HDF" >&2
+ exit 2
+fi
+
+cleanup() {
+ if [ "$HDF_CREATED" = 1 ]; then
+ rm -f "$HDF"
+ fi
+}
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+"$EXE" \
+ -s use_gui=no \
+ -s kickstart_rom_file="$ROM" \
+ -s "$ROM_KEY=:ENABLED" \
+ -s hardfile2="rw,DH0:$HDF,0,0,0,512,0,,$CONTROLLER" \
+ -s chipset=aga \
+ -s chipset_compatible=A1200 \
+ -s cpu_model=68020 \
+ -s cpu_24bit_addressing=true \
+ -s cachesize=0 \
+ > "$LOG" 2>&1 &
+
+pid=$!
+trap 'kill -INT "$pid" 2>/dev/null || true; cleanup' INT TERM EXIT
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+trap - INT TERM EXIT
+cleanup
+
+grep -q "Known ROM" "$LOG"
+grep -q "Adding IDE HD '$BOARD' unit 0" "$LOG"
+grep -q "Card 03: '$EXPECTED_CARD'" "$LOG"
+grep -q "hardreset, memory cleared" "$LOG"
+if grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected config load failure in smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix $EXPECTED_CARD HDF smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_smoke_jit.log}
+CACHE_SIZE=${WINUAE_JIT_CACHE_SIZE:-8192}
+
+export WINUAE_SMOKE_LOG="$LOG"
+export WINUAE_SMOKE_SKIP_AUDIO_CHECK=1
+
+"$ROOT_DIR/tools/unix-smoke-a1200.sh" \
+ -s sound_output=none \
+ -s cycle_exact=false \
+ -s cachesize="$CACHE_SIZE" \
+ -s cpu_speed=max \
+ "$@"
+
+grep -q "JIT: cache=$CACHE_SIZE" "$LOG"
+grep -q "translation cache" "$LOG"
+if grep -q "JIT=0" "$LOG"; then
+ echo "JIT did not stay enabled. Log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix JIT smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_15bit_open_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x15}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-20}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x20
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_16bit_modes_smoke.log}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-10}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+export WINUAE_SMOKE_LOG WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x10
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_16bit_open_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x16}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-10}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x10
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_24bit_open_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x24}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-4}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x4
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_32bit_open_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x32}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-200}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x200
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+WINUAE_P96_SCREENMODE=${WINUAE_P96_SCREENMODE:-800x600x8}
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_800x600_smoke.log}
+export WINUAE_P96_SCREENMODE WINUAE_SMOKE_LOG
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@"
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_draw_16bit_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x16}
+WINUAE_P96_EXPECT_DRAW_BLITS=${WINUAE_P96_EXPECT_DRAW_BLITS:-direct}
+WINUAE_P96_EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-10}
+WINUAE_P96_EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-1280}
+WINUAE_UNIX_RTG_TRACE_BLITS=${WINUAE_UNIX_RTG_TRACE_BLITS:-1}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_DRAW_BLITS WINUAE_P96_EXPECT_MODE_MASK WINUAE_P96_EXPECT_RESINFO_BYTES WINUAE_UNIX_RTG_TRACE_BLITS
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@" -s rtg_modes=0x10
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
+
+WINUAE_SMOKE_LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_draw_8bit_smoke.log}
+WINUAE_P96_OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-640x480x8}
+WINUAE_P96_EXPECT_DRAW_BLITS=${WINUAE_P96_EXPECT_DRAW_BLITS:-chunky}
+WINUAE_UNIX_RTG_TRACE_BLITS=${WINUAE_UNIX_RTG_TRACE_BLITS:-1}
+export WINUAE_SMOKE_LOG WINUAE_P96_OPEN_SCREEN WINUAE_P96_EXPECT_DRAW_BLITS WINUAE_UNIX_RTG_TRACE_BLITS
+
+exec "$SCRIPT_DIR/unix-smoke-p96-guest.sh" "$@"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_P96_Z3=1
+: "${WINUAE_SMOKE_LOG:=/tmp/winuae_unix_p96_guest_z3_smoke.log}"
+export WINUAE_P96_Z3 WINUAE_SMOKE_LOG
+
+exec "$(dirname -- "$0")/unix-smoke-p96-guest.sh" "$@"
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_p96_guest_smoke.log}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-45}
+Z3=${WINUAE_P96_Z3:-0}
+USER_ARGS=("$@")
+
+if [ "$Z3" = "1" ]; then
+ ROM=${WINUAE_A4000_KICKSTART_ROM:-${WINUAE_KICKSTART_ROM:-}}
+else
+ ROM=${WINUAE_KICKSTART_ROM:-}
+fi
+WORKBENCH=${WINUAE_P96_WORKBENCH_DIR:-}
+SCREENMODE=${WINUAE_P96_SCREENMODE:-}
+OPEN_SCREEN=${WINUAE_P96_OPEN_SCREEN:-}
+OPEN_SCREEN_BINARY=${WINUAE_P96_OPEN_SCREEN_BINARY:-}
+OPEN_SCREEN_CC=${WINUAE_M68K_CC:-m68k-amigaos-gcc}
+EXPECT_DRAW_BLITS=${WINUAE_P96_EXPECT_DRAW_BLITS:-}
+EXPECT_MODE_MASK=${WINUAE_P96_EXPECT_MODE_MASK:-}
+EXPECT_RESINFO_BYTES=${WINUAE_P96_EXPECT_RESINFO_BYTES:-}
+EXPECT_HARDWARE_SPRITE=${WINUAE_P96_EXPECT_HARDWARE_SPRITE:-}
+EXPECT_HARDWARE_VBLANK=${WINUAE_P96_EXPECT_HARDWARE_VBLANK:-}
+KEEP_WORKDIR=${WINUAE_KEEP_SMOKE_WORKDIR:-0}
+
+if [ -z "$ROM" ] || [ -z "$WORKBENCH" ]; then
+ echo "Set WINUAE_KICKSTART_ROM and WINUAE_P96_WORKBENCH_DIR before running this smoke test." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ ! -d "$WORKBENCH" ]; then
+ echo "P96 Workbench directory not found: $WORKBENCH" >&2
+ exit 2
+fi
+
+if [ ! -f "$WORKBENCH/Devs/Monitors/uaegfx" ] || [ ! -f "$WORKBENCH/Libs/Picasso96API.library" ]; then
+ echo "P96 Workbench directory must contain Devs/Monitors/uaegfx and Libs/Picasso96API.library: $WORKBENCH" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+WORKDIR=$(mktemp -d "${TMPDIR:-/tmp}/winuae_p96_guest.XXXXXX")
+pid=
+cleanup() {
+ if [ "$KEEP_WORKDIR" = "1" ]; then
+ echo "Keeping P96 guest smoke workdir: $WORKDIR" >&2
+ else
+ rm -rf "$WORKDIR"
+ fi
+}
+trap 'kill -INT "$pid" 2>/dev/null || true; cleanup' INT TERM EXIT
+
+cp -R "$WORKBENCH" "$WORKDIR/Workbench"
+
+write_screenmode_prefs() {
+ mode=$1
+ file=$2
+ case "$mode" in
+ 640x480x8)
+ display_id='\120\003\020\000'
+ depth='\000\010'
+ ;;
+ 800x600x8)
+ display_id='\120\004\020\000'
+ depth='\000\010'
+ ;;
+ 1024x768x8)
+ display_id='\120\005\020\000'
+ depth='\000\010'
+ ;;
+ 640x480x15)
+ display_id='\120\003\020\000'
+ depth='\000\017'
+ ;;
+ 800x600x15)
+ display_id='\120\004\020\000'
+ depth='\000\017'
+ ;;
+ 1024x768x15)
+ display_id='\120\005\020\000'
+ depth='\000\017'
+ ;;
+ 640x480x16)
+ display_id='\120\003\020\000'
+ depth='\000\020'
+ ;;
+ 800x600x16)
+ display_id='\120\004\020\000'
+ depth='\000\020'
+ ;;
+ 1024x768x16)
+ display_id='\120\005\020\000'
+ depth='\000\020'
+ ;;
+ *)
+ echo "Unsupported WINUAE_P96_SCREENMODE: $mode" >&2
+ exit 2
+ ;;
+ esac
+
+ mkdir -p "$(dirname "$file")"
+ {
+ printf 'FORM\000\000\000\066PREFPRHD\000\000\000\006\000\000\000\000\000\000'
+ printf 'SCRM\000\000\000\034'
+ printf '\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000'
+ printf "$display_id"
+ printf '\377\377\377\377'
+ printf "$depth"
+ printf '\000\001'
+ } > "$file"
+}
+
+if [ -n "$SCREENMODE" ]; then
+ write_screenmode_prefs "$SCREENMODE" "$WORKDIR/Workbench/Prefs/Env-Archive/Sys/ScreenMode.prefs"
+ mkdir -p "$WORKDIR/Workbench/Prefs/Env-Archive/Picasso96"
+ printf 'All' > "$WORKDIR/Workbench/Prefs/Env-Archive/Picasso96/ShowModes"
+fi
+
+open_screen_args=
+if [ -n "$OPEN_SCREEN" ]; then
+ case "$OPEN_SCREEN" in
+ 640x480x8)
+ open_screen_args='0x50031000 640 480 8'
+ ;;
+ 800x600x8)
+ open_screen_args='0x50041000 800 600 8'
+ ;;
+ 1024x768x8)
+ open_screen_args='0x50051000 1024 768 8'
+ ;;
+ 640x480x15)
+ open_screen_args='0x50031000 640 480 15'
+ ;;
+ 800x600x15)
+ open_screen_args='0x50041000 800 600 15'
+ ;;
+ 1024x768x15)
+ open_screen_args='0x50051000 1024 768 15'
+ ;;
+ 640x480x16)
+ open_screen_args='0x50031000 640 480 16'
+ ;;
+ 800x600x16)
+ open_screen_args='0x50041000 800 600 16'
+ ;;
+ 1024x768x16)
+ open_screen_args='0x50051000 1024 768 16'
+ ;;
+ 640x480x24)
+ open_screen_args='0x50031000 640 480 24'
+ ;;
+ 800x600x24)
+ open_screen_args='0x50041000 800 600 24'
+ ;;
+ 1024x768x24)
+ open_screen_args='0x50051000 1024 768 24'
+ ;;
+ 640x480x32)
+ open_screen_args='0x50031000 640 480 32'
+ ;;
+ 800x600x32)
+ open_screen_args='0x50041000 800 600 32'
+ ;;
+ 1024x768x32)
+ open_screen_args='0x50051000 1024 768 32'
+ ;;
+ *)
+ echo "Unsupported WINUAE_P96_OPEN_SCREEN: $OPEN_SCREEN" >&2
+ exit 2
+ ;;
+ esac
+ if [ -n "$OPEN_SCREEN_BINARY" ]; then
+ cp "$OPEN_SCREEN_BINARY" "$WORKDIR/Workbench/p96-open-screen"
+ else
+ if ! command -v "$OPEN_SCREEN_CC" >/dev/null 2>&1; then
+ echo "P96 open-screen smoke requires $OPEN_SCREEN_CC or WINUAE_P96_OPEN_SCREEN_BINARY." >&2
+ exit 2
+ fi
+ "$OPEN_SCREEN_CC" -noixemul -m68020 -Os \
+ "$ROOT_DIR/tools/amiga/p96-open-screen.c" \
+ -o "$WORKDIR/Workbench/p96-open-screen"
+ fi
+fi
+
+{
+cat <<'EOF'
+C:MakeDir RAM:T RAM:ENV RAM:ENV/Sys RAM:Clipboards
+C:Copy >NIL: ENVARC: RAM:ENV ALL NOREQ
+Assign ENV: RAM:ENV
+Assign T: RAM:T
+Assign CLIPS: RAM:Clipboards
+Assign LIBS: SYS:Classes ADD
+Echo "before uaegfx smoke" >DH0:unix-p96-before-uaegfx-smoke
+DEVS:Monitors/uaegfx
+C:IPrefs
+EOF
+if [ -n "$open_screen_args" ]; then
+ printf 'DH0:p96-open-screen %s >DH0:unix-p96-open-screen-smoke\n' "$open_screen_args"
+fi
+cat <<'EOF'
+C:LoadWB
+Echo "after uaegfx smoke" >DH0:unix-p96-after-uaegfx-smoke
+Wait 20
+EndCLI >NIL:
+EOF
+} > "$WORKDIR/Workbench/S/Startup-Sequence"
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+set -- \
+ -s use_gui=no \
+ -s kickstart_rom_file="$ROM" \
+ -s filesystem2="rw,DH0:System:$WORKDIR/Workbench,10" \
+ -s nr_floppies=0 \
+ -s chipset=aga \
+ -s cachesize=0
+
+if [ "$Z3" = "1" ]; then
+ set -- "$@" \
+ -s chipset_compatible=A4000 \
+ -s cpu_model=68040 \
+ -s fpu_model=68040 \
+ -s cpu_24bit_addressing=false \
+ -s chipmem_size=4 \
+ -s a3000mem_size=8 \
+ -s gfxcard_size=16 \
+ -s gfxcard_type=ZorroIII
+else
+ set -- "$@" \
+ -s chipset_compatible=A1200 \
+ -s cpu_model=68020 \
+ -s chipmem_size=2 \
+ -s fastmem_size=4 \
+ -s gfxcard_size=4 \
+ -s gfxcard_type=ZorroII
+fi
+
+"$EXE" "$@" "${USER_ARGS[@]}" > "$LOG" 2>&1 &
+
+pid=$!
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+pid=
+trap cleanup EXIT
+
+test -f "$WORKDIR/Workbench/unix-p96-before-uaegfx-smoke"
+test -f "$WORKDIR/Workbench/unix-p96-after-uaegfx-smoke"
+grep -q "Known ROM" "$LOG"
+grep -q "FS: mounted virtual unit DH0" "$LOG"
+grep -q "Unix uaegfx.card" "$LOG"
+grep -q "Unix RTG P96 RESINFO" "$LOG"
+grep -q "Unix RTG FindCard:" "$LOG"
+grep -q "Unix RTG InitCard:" "$LOG"
+grep -q "Unix RTG SetGC:" "$LOG"
+grep -q "Unix RTG SetPanning:" "$LOG"
+grep -q "Unix RTG SetSwitch:" "$LOG"
+if [ -n "$EXPECT_HARDWARE_SPRITE" ]; then
+ grep -q "Unix RTG hardware sprite support enabled" "$LOG"
+fi
+if [ -n "$EXPECT_HARDWARE_VBLANK" ]; then
+ grep -q "Unix RTG vblank interrupt support enabled" "$LOG"
+fi
+if [ -n "$EXPECT_MODE_MASK" ]; then
+ grep -qi "Unix RTG mode mask: $EXPECT_MODE_MASK" "$LOG"
+fi
+if [ -n "$EXPECT_RESINFO_BYTES" ]; then
+ grep -Eq "Unix RTG P96 RESINFO: .*\($EXPECT_RESINFO_BYTES bytes\)" "$LOG"
+fi
+if [ -n "$SCREENMODE" ]; then
+ grep -q "Unix RTG SetGC: $SCREENMODE" "$LOG"
+fi
+if [ -n "$OPEN_SCREEN" ]; then
+ grep -q "OPENSCREEN OK" "$WORKDIR/Workbench/unix-p96-open-screen-smoke"
+ grep -q "Unix RTG SetGC: $OPEN_SCREEN" "$LOG"
+fi
+if [ -n "$EXPECT_DRAW_BLITS" ]; then
+ grep -q "DRAW OK" "$WORKDIR/Workbench/unix-p96-open-screen-smoke"
+ grep -q "Unix RTG FillRect" "$LOG"
+ grep -q "Unix RTG BlitTemplate" "$LOG"
+ grep -q "Unix RTG BlitPattern" "$LOG"
+ case "$EXPECT_DRAW_BLITS" in
+ chunky)
+ grep -q "Unix RTG BlitPlanar2Chunky" "$LOG"
+ ;;
+ direct)
+ grep -q "Unix RTG BlitPlanar2Direct" "$LOG"
+ ;;
+ *)
+ echo "Unsupported WINUAE_P96_EXPECT_DRAW_BLITS: $EXPECT_DRAW_BLITS" >&2
+ exit 2
+ ;;
+ esac
+fi
+if grep -q "not executable" "$LOG" || grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected failure in P96 guest smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix P96 guest smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_path_config_smoke.log}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-5}
+TMPBASE=${TMPDIR:-/tmp}
+WORKDIR="$TMPBASE/winuae-path-smoke-$$"
+
+ROM=${WINUAE_KICKSTART_ROM:-}
+ADF=${WINUAE_FLOPPY0:-}
+
+if [ -z "$ROM" ] || [ -z "$ADF" ]; then
+ echo "Set WINUAE_KICKSTART_ROM and WINUAE_FLOPPY0 before running this smoke test." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$ADF" ]; then
+ echo "ADF image not found: $ADF" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+cleanup()
+{
+ rm -f "$WORKDIR/path-smoke.uae" "$WORKDIR/roms/kick.rom" "$WORKDIR/disks/install.adf"
+ rmdir "$WORKDIR/roms" "$WORKDIR/disks" "$WORKDIR" 2>/dev/null || true
+}
+trap cleanup EXIT
+
+mkdir -p "$WORKDIR/roms" "$WORKDIR/disks"
+ln -sf "$ROM" "$WORKDIR/roms/kick.rom"
+ln -sf "$ADF" "$WORKDIR/disks/install.adf"
+
+{
+ printf '%s\n' 'use_gui=no'
+ printf '%s\n' 'kickstart_rom_file=roms/kick.rom'
+ printf '%s\n' 'nr_floppies=1'
+ printf '%s\n' 'chipset=aga'
+ printf '%s\n' 'chipset_compatible=A1200'
+ printf '%s\n' 'cpu_model=68020'
+ printf '%s\n' 'chipmem_size=4'
+ printf '%s\n' 'cachesize=0'
+} > "$WORKDIR/path-smoke.uae"
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+WINUAE_PATH_SMOKE_ADF=disks/install.adf
+export SDL_AUDIODRIVER SDL_VIDEODRIVER WINUAE_PATH_SMOKE_ADF
+
+sh -c 'cd "$1" && exec "$2" -f path-smoke.uae -s "floppy0=\$WINUAE_PATH_SMOKE_ADF"' sh "$WORKDIR" "$EXE" > "$LOG" 2>&1 &
+
+pid=$!
+trap 'kill -INT "$pid" 2>/dev/null || true; cleanup' INT TERM EXIT
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+trap cleanup EXIT
+
+grep -q "Known ROM" "$LOG"
+grep -q "SDL3: audio initialized" "$LOG"
+grep -q "hardreset, memory cleared" "$LOG"
+if grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected config load failure in smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix path config smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_IDE_EXPANSION_BOARD=ripple
+export WINUAE_IDE_EXPANSION_BOARD
+exec "$(dirname -- "$0")/unix-smoke-ide-expansion-hdf.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_SMOKE_RTG_Z3=1
+export WINUAE_SMOKE_RTG_Z3
+
+exec "$(dirname -- "$0")/unix-smoke-a1200.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_SMOKE_SANA2=1
+export WINUAE_SMOKE_SANA2
+
+exec "$(dirname -- "$0")/unix-smoke-a1200.sh"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG=${WINUAE_SMOKE_LOG:-/tmp/winuae_unix_serial_tcp_smoke.log}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-5}
+CONNECT_TIMEOUT=${WINUAE_SERIAL_TCP_TIMEOUT:-20}
+CONNECT_HOST=${WINUAE_SERIAL_TCP_CONNECT_HOST:-127.0.0.1}
+LISTEN_HOST=${WINUAE_SERIAL_TCP_LISTEN_HOST:-$CONNECT_HOST}
+PORT=${WINUAE_SERIAL_TCP_PORT:-51234}
+WAIT_MODE=${WINUAE_SERIAL_TCP_WAIT:-1}
+NC=${WINUAE_NC:-nc}
+
+ROM=${WINUAE_KICKSTART_ROM:-}
+ADF=${WINUAE_FLOPPY0:-}
+
+if [ -z "$ROM" ] || [ -z "$ADF" ]; then
+ echo "Set WINUAE_KICKSTART_ROM and WINUAE_FLOPPY0 before running this smoke test." >&2
+ exit 2
+fi
+
+if [ ! -f "$ROM" ]; then
+ echo "Kickstart ROM not found: $ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$ADF" ]; then
+ echo "ADF image not found: $ADF" >&2
+ exit 2
+fi
+
+if ! command -v "$NC" >/dev/null 2>&1; then
+ echo "Netcat command not found: $NC" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+SERIAL_SPEC="TCP://$LISTEN_HOST:$PORT"
+if [ "$WAIT_MODE" = "1" ]; then
+ SERIAL_SPEC="$SERIAL_SPEC/wait"
+fi
+
+: > "$LOG"
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+"$EXE" \
+ -s use_gui=no \
+ -s kickstart_rom_file="$ROM" \
+ -s floppy0="$ADF" \
+ -s nr_floppies=1 \
+ -s chipset=aga \
+ -s chipset_compatible=A1200 \
+ -s cpu_model=68020 \
+ -s chipmem_size=4 \
+ -s cachesize=0 \
+ -s unix.serial_port="$SERIAL_SPEC" \
+ -s serial_on_demand=false \
+ > "$LOG" 2>&1 &
+
+pid=$!
+trap 'kill -INT "$pid" 2>/dev/null || true' INT TERM EXIT
+
+i=0
+while ! grep -q "SERIAL_TCP: listening on" "$LOG"; do
+ if grep -q "SERIAL_TCP: failed to listen" "$LOG" || grep -q "SERIAL: Could not open device" "$LOG"; then
+ echo "TCP serial listener failed to start. Log: $LOG" >&2
+ exit 1
+ fi
+ if ! kill -0 "$pid" 2>/dev/null; then
+ echo "Emulator exited before TCP serial listener started. Log: $LOG" >&2
+ exit 1
+ fi
+ if [ "$i" -ge "$CONNECT_TIMEOUT" ]; then
+ echo "Timed out waiting for TCP serial listener. Log: $LOG" >&2
+ exit 1
+ fi
+ i=$((i + 1))
+ sleep 1
+done
+
+(
+ printf 'serial-smoke\r\n'
+ sleep 1
+) | "$NC" "$CONNECT_HOST" "$PORT" >/dev/null 2>&1 &
+nc_pid=$!
+sleep 1
+kill "$nc_pid" 2>/dev/null || true
+wait "$nc_pid" 2>/dev/null || true
+
+sleep "$RUN_SECONDS"
+if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+fi
+wait "$pid" || true
+trap - INT TERM EXIT
+
+grep -q "SERIAL_TCP: listening on" "$LOG"
+grep -q "SERIAL_TCP: connection accepted" "$LOG"
+grep -q "Known ROM" "$LOG"
+grep -q "SDL3: audio initialized" "$LOG"
+grep -q "hardreset, memory cleared" "$LOG"
+if grep -q "SERIAL_TCP: failed to listen" "$LOG" || grep -q "SERIAL: Could not open device" "$LOG"; then
+ echo "TCP serial listener failed during smoke test. Log: $LOG" >&2
+ exit 1
+fi
+if grep -q "failed to load config" "$LOG" || grep -q "cfgfile_load_2 failed" "$LOG"; then
+ echo "Unexpected config load failure in smoke log: $LOG" >&2
+ exit 1
+fi
+
+echo "Unix TCP serial smoke test passed. Log: $LOG"
--- /dev/null
+#!/usr/bin/env bash
+set -eu
+
+ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+BUILD_DIR=${WINUAE_BUILD_DIR:-/tmp/winuae_cmake_build}
+EXE=${WINUAE_EXE:-"$BUILD_DIR/winuae_unix"}
+LOG_DIR=${WINUAE_SMOKE_LOG_DIR:-/tmp}
+RUN_SECONDS=${WINUAE_SMOKE_SECONDS:-5}
+
+A1200_ROM=${WINUAE_A1200_KICKSTART_ROM:-${WINUAE_KICKSTART_ROM:-}}
+A4000_ROM=${WINUAE_A4000_KICKSTART_ROM:-}
+
+if [ -z "$A1200_ROM" ] || [ -z "$A4000_ROM" ]; then
+ echo "Set WINUAE_A1200_KICKSTART_ROM and WINUAE_A4000_KICKSTART_ROM before running this smoke test." >&2
+ echo "WINUAE_KICKSTART_ROM can be used instead of WINUAE_A1200_KICKSTART_ROM." >&2
+ exit 2
+fi
+
+if [ ! -f "$A1200_ROM" ]; then
+ echo "A1200 Kickstart ROM not found: $A1200_ROM" >&2
+ exit 2
+fi
+
+if [ ! -f "$A4000_ROM" ]; then
+ echo "A4000 Kickstart ROM not found: $A4000_ROM" >&2
+ exit 2
+fi
+
+if [ ! -x "$EXE" ]; then
+ cmake -S "$ROOT_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ cmake --build "$BUILD_DIR" --target winuae_unix
+fi
+
+SDL_AUDIODRIVER=${SDL_AUDIODRIVER:-dummy}
+SDL_VIDEODRIVER=${SDL_VIDEODRIVER:-dummy}
+export SDL_AUDIODRIVER SDL_VIDEODRIVER
+
+base_a1200=(
+ -s chipset=aga
+ -s chipset_compatible=A1200
+ -s cpu_model=68020
+ -s chipmem_size=4
+ -s cachesize=0
+ -s sound_output=none
+)
+
+base_a4000=(
+ -s chipset=aga
+ -s chipset_compatible=A4000
+ -s cpu_model=68030
+ -s cpu_24bit_addressing=false
+ -s chipmem_size=2
+ -s cachesize=0
+ -s sound_output=none
+)
+
+last_log=
+
+run_case()
+{
+ local name=$1
+ local rom=$2
+ shift 2
+
+ last_log="$LOG_DIR/winuae_unix_sound_${name}.log"
+ : > "$last_log"
+
+ "$EXE" \
+ -s use_gui=no \
+ -s kickstart_rom_file="$rom" \
+ "$@" \
+ > "$last_log" 2>&1 &
+
+ local pid=$!
+ sleep "$RUN_SECONDS"
+ if kill -0 "$pid" 2>/dev/null; then
+ kill -INT "$pid" 2>/dev/null || true
+ fi
+ wait "$pid" || true
+
+ if grep -q "failed to load config" "$last_log" || grep -q "cfgfile_load_2 failed" "$last_log"; then
+ echo "Unexpected config load failure in smoke log: $last_log" >&2
+ exit 1
+ fi
+ grep -q "hardreset, memory cleared" "$last_log"
+}
+
+require_log()
+{
+ local pattern=$1
+ if ! grep -Eq "$pattern" "$last_log"; then
+ echo "Missing expected log pattern '$pattern' in $last_log" >&2
+ exit 1
+ fi
+}
+
+run_pci_case()
+{
+ local name=$1
+ local bridge_pattern=$2
+ local board_pattern=$3
+ shift 3
+
+ run_case "$name" "$A4000_ROM" "${base_a4000[@]}" "$@"
+ require_log "$bridge_pattern"
+ require_log "$board_pattern"
+}
+
+run_case toccata "$A1200_ROM" "${base_a1200[@]}" -s toccata_rom_file=:ENABLED
+require_log "Card [0-9]+: 'Toccata'"
+require_log "Toccata"
+
+run_case prelude "$A1200_ROM" "${base_a1200[@]}" -s prelude_rom_file=:ENABLED
+require_log "Card [0-9]+: 'Prelude'"
+require_log "mapped_malloc .* Prelude"
+
+run_case prelude1200 "$A1200_ROM" "${base_a1200[@]}" -s prelude1200_rom_file=:ENABLED
+require_log "Prelude1200"
+
+run_case uaesnd_z2 "$A1200_ROM" "${base_a1200[@]}" -s uaesnd_z2_rom_file=:ENABLED
+require_log "Card [0-9]+: 'UAESND Z2'"
+require_log "Card [0-9]+: Z2 .*uaesnd z2"
+require_log "UAESND memory"
+
+run_case uaesnd_z3 "$A4000_ROM" "${base_a4000[@]}" -s uaesnd_z3_rom_file=:ENABLED
+require_log "Card [0-9]+: 'UAESND Z3'"
+require_log "Card [0-9]+: Z3 .*uaesnd z3"
+require_log "UAESND memory"
+
+run_case uaeboard_z2 "$A1200_ROM" "${base_a1200[@]}" -s uaeboard_z2_rom_file=:ENABLED
+require_log "Card [0-9]+: 'UAEBOARD Z2'"
+require_log "Card [0-9]+: Z2 .*uaesnd z2"
+require_log "UAESND memory"
+
+run_case uaeboard_z3 "$A4000_ROM" "${base_a4000[@]}" -s uaeboard_z3_rom_file=:ENABLED
+require_log "Card [0-9]+: 'UAEBOARD Z3'"
+require_log "Card [0-9]+: Z3 .*uaesnd z3"
+require_log "UAESND memory"
+
+run_pci_case es1370_prometheus "PCI bridge 'Prometheus'" "ES1370" \
+ -s prometheus_rom_file=:ENABLED \
+ -s es1370_rom_file=:ENABLED
+
+run_pci_case es1370_prometheusfirestorm \
+ "PCI bridge 'Prometheus FireStorm'" "ES1370" \
+ -s prometheusfirestorm_rom_file=:ENABLED \
+ -s es1370_rom_file=:ENABLED
+
+run_pci_case es1370_mediator4000 "PCI bridge 'Mediator 4000'" "ES1370" \
+ -s mediator_rom_file=:ENABLED \
+ -s mediator_rom_options=subtype=4000mkii \
+ -s es1370_rom_file=:ENABLED
+
+run_pci_case es1370_grex "PCI bridge 'G-REX'" "ES1370" \
+ -s grex_rom_file=:ENABLED \
+ -s es1370_rom_file=:ENABLED
+
+run_pci_case fm801_prometheus "PCI bridge 'Prometheus'" "FM801" \
+ -s prometheus_rom_file=:ENABLED \
+ -s fm801_rom_file=:ENABLED
+
+run_pci_case fm801_prometheusfirestorm \
+ "PCI bridge 'Prometheus FireStorm'" "FM801" \
+ -s prometheusfirestorm_rom_file=:ENABLED \
+ -s fm801_rom_file=:ENABLED
+
+run_pci_case fm801_mediator4000 "PCI bridge 'Mediator 4000'" "FM801" \
+ -s mediator_rom_file=:ENABLED \
+ -s mediator_rom_options=subtype=4000mkii \
+ -s fm801_rom_file=:ENABLED
+
+run_pci_case fm801_grex "PCI bridge 'G-REX'" "FM801" \
+ -s grex_rom_file=:ENABLED \
+ -s fm801_rom_file=:ENABLED
+
+echo "Unix sound-board smoke test passed. Logs: $LOG_DIR/winuae_unix_sound_*.log"
--- /dev/null
+#!/usr/bin/env sh
+set -eu
+
+WINUAE_SMOKE_RTG_Z3=1
+WINUAE_SMOKE_UAEGFX=1
+: "${WINUAE_SMOKE_SECONDS:=25}"
+export WINUAE_SMOKE_RTG_Z3 WINUAE_SMOKE_UAEGFX WINUAE_SMOKE_SECONDS
+
+exec "$(dirname -- "$0")/unix-smoke-a1200.sh" "$@"