#!/usr/bin/env bash # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # verify-dvx-serial.sh - both-directions RS-232 gate for the DVX port. # # Runs SERTEST (examples/sertest: banner, then echo) as the desktop of a # scratch DVX in DOSBox Staging, with COM1 a nullmodem connecting to the # host peer (scripts/lib/serialLoopPeer.py), which waits for the banner, # sends a probe and expects it echoed. That exercises the chain: JoeyLib's # serial layer -> the DVX port (src/dvx/serial.c) -> DVX's rs232 library and # its interrupt -> DOSBox's UART -> host. # # Then the DTR check (--dtr-check): the nullmodem runs non-transparent, so # DOSBox reports the guest's modem lines to the peer in the byte stream, and # SERTEST drops and raises DTR, closes and reopens the port, then hangs up # (DTR dropped, port closed). jlSerialSetDtr must reach the line, and # jlSerialClose must leave DTR as it is, up or down: DVX's serial library # used to reset the modem lines when it closed a port. # # Usage: scripts/verify-dvx-serial.sh # Env: DVX_SERIAL_PORT TCP port the peer listens on (default 6803) # Requires: DOSBox Staging, Xvfb, python3, the dvx component; the sertest # program (make dvx). set -uo pipefail repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) source "$repo/scripts/lib/joeyEnv.sh" source "$repo/scripts/lib/dvxGate.sh" joeyNeed DOSBOX dosbox joeyNeed DVX_ROOT dvx program=sertest port="${DVX_SERIAL_PORT:-6803}" peerWall=95 # DVX boot, the banner and the echo, then the DTR check runSeconds=110 # SERTEST idles forever after the check: DOSBox ends by timeout dvxNeedBuild "$program" work=$(mktemp -d -t joeylib-dvx-serial.XXXXXX) peerPid="" guard="" dosbox="" xvfb="" # 2>/dev/null: bash reports the SIGKILLed timeout wrapper as "Killed". cleanup() { joeyStop "$dosbox" "$guard" "$peerPid" "$xvfb" 2> /dev/null rm -rf "$work" } trap cleanup EXIT dvxStage "$work/c" "$(dvxAppDir "$program")" dvxDosboxConf "$work/dosbox.conf" "$work/c" printf '\n[serial]\nserial1 = nullmodem server:127.0.0.1 port:%s transparent:0\n' "$port" >> "$work/dosbox.conf" mkdir -p "$work/xdg" python3 "$repo/scripts/lib/serialLoopPeer.py" tcp-server "$port" "$peerWall" --dtr-check > "$work/peer.log" 2>&1 & peerPid=$! sleep 1 display=":$((RANDOM % 400 + 3300))" Xvfb "$display" -screen 0 1024x768x24 -nolisten tcp > /dev/null 2>&1 & xvfb=$! sleep 1 XDG_CONFIG_HOME="$work/xdg" DISPLAY="$display" SDL_AUDIODRIVER=dummy \ timeout -s KILL "$runSeconds" "$DOSBOX" "${JOEY_DOSBOX_ISOLATE[@]}" \ --conf "$work/dosbox.conf" > "$work/dosbox.log" 2>&1 & guard=$! dosbox=$(joeyChild "$guard") wait "$peerPid" rc=$? peerPid="" joeyStop "$dosbox" "$guard" 2> /dev/null dosbox="" guard="" cat "$work/peer.log" if [ "$rc" -eq 0 ]; then echo "verify-dvx-serial: PASS (banner out, probe echoed through COM1 and DVX's serial library; DTR follows jlSerialSetDtr and survives jlSerialClose)" else echo "verify-dvx-serial: FAIL (DVX.LOG follows)" >&2 dvxDvxLog "$work/c" >&2 fi exit "$rc"