joeylib2/installer/lib/win16.sh

171 lines
6.6 KiB
Bash

# shellcheck shell=bash
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# The Win16 port's Windows: Windows for Workgroups 3.11 set up on a DOSBox
# Staging PC (scripts/dosbox-win16.conf) as a host folder that is drive C:,
# for the win311 component. Sourced, not executed.
#
# Windows is not downloaded from anywhere: its files are private ones
# (installer/files.sha1), the owner's install disc and display driver disk,
# brought in with ./install.sh import or the private bundle. From them:
#
# 1. Windows' own Setup runs unattended in DOSBox (SETUP /H: with the
# answers in win16SetupAnswers): no network, the stock VGA driver and
# PS/2 mouse, nothing optional, Setup back to DOS at the end. Then the
# Sound Blaster 1.5 driver and its virtual device are expanded from the
# disc with its own EXPAND.EXE.
# 2. The S3 Trio64V+ 1.70.04 driver is put in at 800x600 in 256 colours,
# and the Sound Blaster driver turned on, editing SYSTEM.INI the way
# the driver disk's OEMSETUP.INF (its D808S profile) and Control Panel
# would. The swap file is off.
#
# The win16 gates and joey-run (scripts/lib/win16Gate.sh) copy the result
# for each run and name the program as Windows' shell, so Windows ends when
# the program does. Win16 code only ever runs on DOSBox's emulated CPU:
# running it natively (the 32-bit Wine's winevdm) crashed the host's kernel.
WIN16_FIRMWARE="toolchains/firmware/win16"
WIN16_ISO="$WIN16_FIRMWARE/wfw311.iso"
WIN16_S3_FILES="S3TRIO.DRV VDDS3764.386 VGA_ENG.3GR"
WIN16_DOSBOX_CONF="scripts/dosbox-win16.conf"
WIN16_INI_TOOL="tools/winIni.py"
# Setup takes about 20 s at full speed.
WIN16_SETUP_SECONDS=300
# win16Configure CDIR -- step 2: the S3 driver, the Sound Blaster, no swap
# file.
win16Configure() {
local windows="$1/WINDOWS"
local name
for name in $WIN16_S3_FILES; do
cp "$JOEY_REPO/$WIN16_FIRMWARE/s3/$name" "$windows/SYSTEM/$name"
done
python3 "$JOEY_REPO/$WIN16_INI_TOOL" "$windows/SYSTEM.INI" \
set boot display.drv s3trio.drv \
set boot 386grabber vga_eng.3gr \
set boot.description display.drv "S3 Trio64V 1.70.04 800x600 256 C SF" \
set 386Enh display vdds3764.386 \
set 386Enh Paging no \
add 386Enh device vsbd.386 \
set DISPLAY dac-type nbt \
set DISPLAY polygon-support on \
set DISPLAY ellipse-support on \
set DISPLAY scache on \
set DISPLAY textrmw 0 \
set DISPLAY fastmmio on \
set DISPLAY screen-size 800 \
set DISPLAY color-format 8 \
set DISPLAY dpi 96 \
set Debug OutputTo NUL \
set drivers wave sndblst2.drv \
set sndblst.drv port 220 \
set sndblst.drv int 7
}
# win16Files -- every private file the image is made from.
win16Files() {
local name
printf '%s\n' "$WIN16_ISO"
for name in $WIN16_S3_FILES; do
printf '%s\n' "$WIN16_FIRMWARE/s3/$name"
done
}
# win16Pin -- changes with the private files and with the recipe.
win16Pin() {
local file
{
for file in $(win16Files); do
privateSha1For "$file"
done
declare -f win16Configure win16Prepare win16Setup win16SetupAnswers
cat "$JOEY_REPO/$WIN16_DOSBOX_CONF" "$JOEY_REPO/$WIN16_INI_TOOL"
} | sha256sum | cut -d' ' -f1
}
# win16Prepare OUTDIR -- make OUTDIR/c, Windows set up and configured.
win16Prepare() {
local out="$1"
local build
local file
for file in $(win16Files); do
privateEnsure "$file"
done
build="$(freshBuildDir "$compId")"
mkdir -p "$build/c"
win16SetupAnswers > "$build/c/SETUP.SHH"
info "setting up Windows for Workgroups 3.11 in DOSBox (unattended)"
win16Setup "$build" || die "Windows Setup did not finish; its DOSBox log: $build/dosbox.log"
rm -f "$build/c/SETUP.SHH"
win16Configure "$build/c"
win16Verify "$build/c" || die "the Windows set up in $build/c is incomplete"
rm -rf "${out:?}/c"
mkdir -p "$out"
mv "$build/c" "$out/c"
dropBuildDir "$compId"
}
# win16Setup BUILD -- step 1, on a private display: Setup, then the Sound
# Blaster driver off the disc. DOSBox exits when the last command has run.
win16Setup() {
local build="$1"
local windows='C:\WINDOWS\SYSTEM'
local xvfb
local display
local rc
Xvfb -displayfd 3 -screen 0 1024x768x24 -nolisten tcp 3> "$build/display" > /dev/null 2>&1 &
xvfb=$!
for _ in 1 2 3 4 5 6 7 8 9 10; do
[ -s "$build/display" ] && break
sleep 0.5
done
display=":$(cat "$build/display")"
XDG_CONFIG_HOME="$build/xdg" DISPLAY="$display" SDL_AUDIODRIVER=dummy \
timeout -s KILL "$WIN16_SETUP_SECONDS" "$JOEY_OPT/dosbox/dosbox" --noprimaryconf --nolocalconf \
--conf "$JOEY_REPO/$WIN16_DOSBOX_CONF" --set "nosound=true" \
-c "MOUNT C \"$build/c\"" \
-c "IMGMOUNT D \"$JOEY_REPO/$WIN16_ISO\" -t iso" \
-c "C:" \
-c 'D:\SETUP /H:C:\SETUP.SHH' \
-c "D:\\EXPAND D:\\SNDBLST2.DR_ $windows\\SNDBLST2.DRV" \
-c "D:\\EXPAND D:\\VSBD.38_ $windows\\VSBD.386" \
-c "EXIT" > "$build/dosbox.log" 2>&1
rc=$?
kill "$xvfb" 2> /dev/null || true
wait "$xvfb" 2> /dev/null || true
[ "$rc" -eq 0 ] && [ -f "$build/c/WINDOWS/WIN.COM" ]
}
# win16SetupAnswers -- Setup's answer file (SETUP.SHH, the format of the
# sample on the disc), CRLF.
win16SetupAnswers() {
printf '%s\r\n' \
'[sysinfo]' 'showsysinfo=no' '' \
'[configuration]' 'machine=ibm_compatible' 'display=vga' 'mouse=ps2mouse' 'network=nonet' \
'keyboard=t4s0enha' 'language=enu' 'kblayout=nodll' '' \
'[windir]' 'c:\windows' '' \
'[userinfo]' '"JoeyLib"' '' \
'[dontinstall]' 'accessories' 'readmes' 'games' 'screensavers' 'bitmaps' '' \
'[endinstall]' 'configfiles=save' 'endopt=exit'
}
# win16Verify CDIR -- Windows is there and set up for the port.
win16Verify() {
local windows="$1/WINDOWS"
local name
[ -f "$windows/WIN.COM" ] || return 1
for name in $WIN16_S3_FILES SNDBLST2.DRV VSBD.386; do
[ -s "$windows/SYSTEM/$name" ] || return 1
done
tr -d '\r' < "$windows/SYSTEM.INI" | grep -qx 'display.drv=s3trio.drv' || return 1
tr -d '\r' < "$windows/SYSTEM.INI" | grep -qx 'wave=sndblst2.drv'
}