#! /bin/bash

# Usage of the works is permitted provided that this
# instrument is retained with the works, so that any entity
# that uses the works is notified of this instrument.
#
# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

if [ -n "$UPDATEDL" ]
then
  unset UPDATEDL
  if [ "$UPDATEDLNAME" == lcdebug ]
  then
    INICOMP_METHOD="lz4 lzd exodecr apl lzsa2" INICOMP_WINNER=lzsa2 \
      use_build_decomp_test=1 INICOMP_PROGRESS=1 \
      build_name=cdebug build_options="-D_DEBUG -D_DEBUG_COND" ./mak.sh
    INICOMP_METHOD="lz4 lzd exodecr apl lzsa2" INICOMP_WINNER=lzsa2 \
      use_build_decomp_test=1 INICOMP_PROGRESS=1 \
      build_name=cdebugx build_options="-D_DEBUG -D_DEBUG_COND -D_PM" ./mak.sh
    INSTSECT_BOOT_NAME=LCDEBUG ./makinst.sh
  elif [ "$UPDATEDLNAME" == lddebug ]
  then
    INICOMP_METHOD="lz4 lzd exodecr apl lzsa2" INICOMP_WINNER=lzsa2 \
      use_build_decomp_test=1 INICOMP_PROGRESS=1 ./maked
    INSTSECT_BOOT_NAME=LDDEBUG ./makinst.sh
  else
    INICOMP_METHOD="lz4 lzd exodecr apl lzsa2" INICOMP_WINNER=lzsa2 \
      use_build_decomp_test=1 INICOMP_PROGRESS=1 ./make
    INSTSECT_BOOT_NAME=LDEBUG ./makinst.sh
  fi
  exit $?
fi

rootpath="../"
miscpath=""

comext="com"
mapext="map"
lstext="lst"
binbigext="big"
[ -z "$RESULTEXT" ] && RESULTEXT="$comext"

lstdir="lst/"
mapdir="lst/"

spre="s"
ppre="p"
tpre="t"
usuf="u"
csuf="c"
lpre="l"

blzext="blz"
lz4ext="lz4"
szext="sz"
exoext="exo"
xext="x"
hsext="hs"
lzext="lz"
lzoext="lzo"
lzsa2ext="sa2"
aplext="apl"
bzpext="bzp"
zerocompext="zer"
mvcompext="mv"
lzexedatext="lze"
zx0ext="zx0"


function fun_delete_compressed {
  [ "$1" != "silent" ] && echo "Deleting $lpre${build_name}.$RESULTEXT"
  rm -f ${rootpath}bin/$lpre"$build_name.$RESULTEXT" \
    ${rootpath}${lstdir}$lpre"$build_name"$csuf.$lstext ${rootpath}${mapdir}$lpre"$build_name"$csuf.$mapext
}

. cfg.sh

[ -z "$NPROC" ] && NPROC=nproc

if [ -n "$LMACROS_DIR" ]; then {
  options_i_lmacros=-I"${LMACROS_DIR%/}"/
} fi

if [ -n "$LDOSBOOT_DIR" ]; then {
  options_i_ldosboot=-I"${LDOSBOOT_DIR%/}"/
} fi

if [ -n "$SCANPTAB_DIR" ]; then {
  options_i_scanptab=-I"${SCANPTAB_DIR%/}"/
} fi

if [ -n "$BOOTIMG_DIR" ]; then {
  options_i_bootimg=-I"${BOOTIMG_DIR%/}"/
} fi

if [ -n "$INSTSECT_DIR" ]; then {
  options_i_instsect=-I"${INSTSECT_DIR%/}"/
} fi

if [ -n "$SYMSNIP_DIR" ]; then {
  options_i_symsnip=-I"${SYMSNIP_DIR%/}"/
} fi


[ -z "$build_name" ] && build_name=debug
reproducedir=${rootpath}tmp/"$build_name".rep

function shellquote() {
  local sp=""
#  local ii=0
  for param; do
    echo -ne "$sp"
#    ((debug)) && echo -ne "$ii:"
#    ((ii += 1))
    printf "%q" "$param"
    sp=" "
  done
  echo
}

if [ "$1" == reproduce ]; then
  shift
  echo Reproducing the "$build_name" build
  if ! [ -f "$reproducedir"/nasmenv ] || \
      ! [ -f "$reproducedir"/options ] || \
      ! [ -f "$reproducedir"/usevars ] || \
      ! [ -f "$reproducedir"/cmdline ] || \
      ! [ -f "$reproducedir"/dt ]; then
    echo Error: Reproduce files not found
    exit 1
  fi
  altervar="havedt reproducing"
  if [ "$1" == alter ]; then
    shift
    altervar="havedt"
    echo Altering the reproduce files
    if [ "$1" == newdt ]; then
      shift
      altervar=""
    fi
  fi
  unset NASMENV
  eval "$(cat "$reproducedir"/nasmenv)"
  unset STACKSIZE
  unset INICOMP_METHOD
  unset INICOMP_WINNER
  unset INICOMP_SPEED_TEST
  unset INICOMP_SPEED_SCALE
  unset INICOMP_PROGRESS
  unset INICOMP_EXOMIZER_P
  unset INICOMP_HEATSHRINK_Z
  unset INICOMP_LZEXEDAT_4
  unset INICOMP_LZEXEDAT_L
  unset INICOMP_ZX0_Q
  unset INICOMP_LZSA_M
  unset INICOMP_LZSA_N
  unset INICOMP_LZSA_S
  unset build_options
  unset build_inicomp_options
  unset build_iniload_options
  eval "$(cat "$reproducedir"/options)"
  export use_build_revision_id=0
#  unset use_build_revision_id
  unset use_build_decomp_test
  unset use_build_decomp_test_xms
  unset use_build_decomp_test_file
  unset use_build_inicheck
  unset use_build_inicheck_new
  unset use_build_shim
  unset use_build_bootable
  unset use_build_help_external
  unset use_build_help_compressed
  unset use_build_help_compressed_lzexedat
  unset use_build_help_compressed_lzexedat_l
  unset use_build_help_compressed_maximum
  unset use_build_time
  unset use_build_qimg
  unset use_build_bimg
  unset use_build_double_compressed
  unset use_build_compress_only
  unset use_build_inicomp_only
  unset use_build_skip_help
  unset use_build_make
  eval "$(cat "$reproducedir"/usevars)"
  eval "$(printf "%q" "$0") $altervar $(cat "$reproducedir"/cmdline) $(shellquote "$@")"
  exit $?
fi

if (($use_build_revision_id)); then {
  [ -z "$build_revision_id" ] \
    && build_revision_id="hg $(hg id -i) ($( \
      hg log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)"
  [ -z "$build_revision_id_lmacros" -a -n "$LMACROS_DIR" ] \
    && var="hg $(hg -R "$LMACROS_DIR" id -i) ($( \
      hg -R "$LMACROS_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_lmacros="'Uses lmacros:  Revision ID $var',13,10"
  [ -z "$build_revision_id_symsnip" -a -n "$SYMSNIP_DIR" -a -d "$SYMSNIP_DIR" ] \
    && var="hg $(hg -R "$SYMSNIP_DIR" id -i) ($( \
      hg -R "$SYMSNIP_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_symsnip="'Uses symsnip:  Revision ID $var',13,10"
  [ -z "$build_revision_id_inicomp" ] \
    && var="hg $(hg -R "$INICOMP_DIR" id -i) ($( \
      hg -R "$INICOMP_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_inicomp="'Uses inicomp:  Revision ID $var',13,10"
  [ -z "$build_revision_id_inicheck" ] \
    && var="hg $(hg -R "$INICHECK_DIR" id -i) ($( \
      hg -R "$INICHECK_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_inicheck="'Uses inicheck: Revision ID $var',13,10"
  [ -z "$build_revision_id_scanptab" ] \
    && var="hg $(hg -R "$SCANPTAB_DIR" id -i) ($( \
      hg -R "$SCANPTAB_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_scanptab="'Uses scanptab: Revision ID $var',13,10"
  [ -z "$build_revision_id_ldosboot" ] \
    && var="hg $(hg -R "$LDOSBOOT_DIR" id -i) ($( \
      hg -R "$LDOSBOOT_DIR" log -r 'ancestors(.)' --template '1' | wc --bytes) ancestors)" \
    && [ "$var" != "$build_revision_id" ] \
    && build_revision_id_ldosboot="'Uses ldosboot: Revision ID $var',13,10"
} fi

mkdir -p "$reproducedir"

if [ "$1" != havedt ]; then
  nasm ${miscpath}passdt.asm -o ${rootpath}tmp/scratch 2>&1 \
  -D_REVISIONID="'$build_revision_id'" \
  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
  -D_REVISIONID_INSTSECT="${build_revision_id_instsect:-''}" \
  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
  -D_CHECKSUM="$use_build_inicheck" \
  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
  | perl -ne 'if (/.*(?:warning: using define )(-[UD].*?)( \[-w\+user\])?$/) { print $1."\n"; };' \
     > "$reproducedir"/dt
else
  shift
fi

if [ "$1" != reproducing ]; then
  export NASMENV
  export -p | grep -E "^declare -x NASMENV=" > "$reproducedir"/nasmenv
  export STACKSIZE
  export INICOMP_METHOD
  export INICOMP_WINNER
  export INICOMP_SPEED_TEST
  export INICOMP_SPEED_SCALE
  export INICOMP_PROGRESS
  export INICOMP_EXOMIZER_P
  export INICOMP_HEATSHRINK_Z
  export INICOMP_LZEXEDAT_4
  export INICOMP_LZEXEDAT_L
  export INICOMP_ZX0_Q
  export INICOMP_LZSA_M
  export INICOMP_LZSA_N
  export INICOMP_LZSA_S
  export build_options
  export build_inicomp_options
  export build_iniload_options
  export -p | grep -E "^declare -x (build_(|inicomp_|iniload_)options|INICOMP_(ZX0_Q|LZSA_M|LZSA_N|LZSA_S|LZEXEDAT_4|LZEXEDAT_L|HEATSHRINK_Z|EXOMIZER_P|METHOD|WINNER|SPEED_TEST|SPEED_SCALE|PROGRESS)|STACKSIZE)=" > "$reproducedir"/options
#  export use_build_revision_id
  export use_build_decomp_test
  export use_build_decomp_test_xms
  export use_build_decomp_test_file
  export use_build_inicheck
  export use_build_inicheck_new
  export use_build_shim
  export use_build_bootable
  export use_build_help_external
  export use_build_help_compressed
  export use_build_help_compressed_lzexedat
  export use_build_help_compressed_lzexedat_l
  export use_build_help_compressed_maximum
  export use_build_time
  export use_build_qimg
  export use_build_bimg
  export use_build_double_compressed
  export use_build_compress_only
  export use_build_inicomp_only
  export use_build_skip_help
  export use_build_make
  export -p | grep -E "^declare -x use_build_(decomp_test|decomp_test_xms|decomp_test_file|inicheck|inicheck_new|shim|bootable|help_external|help_compressed|help_compressed_lzexedat|help_compressed_lzexedat_l|help_compressed_maximum|time|qimg|bimg|double_compressed|compress_only|inicomp_only|skip_help|make)=" > "$reproducedir"/usevars
  shellquote "$@" > "$reproducedir"/cmdline
else
  shift
fi

if ((use_build_time))
then
  time_command=command
  time_time=time
  time_switch1='--format=%M KiB, %E time, %x rc'
  time_switch2=--quiet
else
  unset time_command
  unset time_time
  time_switch1=command
  unset time_switch2
fi

# based on https://stackoverflow.com/a/22517974/738287
declare -a dtarray=()
while IFS='' read -r item; do
  dtarray+=("$item")
done < "$reproducedir"/dt

[ -z "$STACKSIZE" ] && STACKSIZE=2048

if ! (( $use_build_compress_only + $use_build_inicomp_only ))
then

((use_build_shim)) && [ -f ${rootpath}bin/"$build_name.$RESULTEXT" ] && rm ${rootpath}bin/"$build_name.$RESULTEXT"
((use_build_bootable)) && [ -f ${rootpath}bin/$lpre"$build_name.$RESULTEXT" ] && rm ${rootpath}bin/$lpre"$build_name.$RESULTEXT"
((use_build_bootable)) && [ -f ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT" ] && rm ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT"
# Delete the file first so in case the actual assembly fails,
#  there doesn't remain a stale result of the shim assembly.

mkdir -p "../tmp/$build_name.obj/"
mkdir -p "../tmp/$build_name.txt/"

echo "BUILDNAME=$build_name" > "../tmp/lastname.upd"
diff -Nq ../tmp/lastname.dat ../tmp/lastname.upd \
  || cp -a ../tmp/lastname.upd ../tmp/lastname.dat

echo OPTIONS="$*" > "../tmp/$build_name.obj/option.upd"
echo BUILDOPTIONS="$build_options" >> "../tmp/$build_name.obj/option.upd"
diff -Nq ../tmp/$build_name.obj/option.dat ../tmp/$build_name.obj/option.upd \
  || cp -a ../tmp/$build_name.obj/option.upd ../tmp/$build_name.obj/option.dat

inicomp_help_def_z=""
inicomp_help_switch_z=""
help_def_lzexedat=""
export EXTERNALHELPTARGET=none
if ((use_build_help_external))
then
  EXTERNALHELPTARGET=helptxt
  if ((use_build_help_compressed_maximum))
  then
    HELP_COMPRESSED_MAXIMUM=0
    HELP_MAXIMUM_NAME=""
  fi
  ZHINTSHOWN=0
  options_i_help=-I"${rootpath}tmp/$build_name.txt"/
    if ((use_build_help_compressed))
    then
      if ((use_build_help_compressed_lzexedat))
      then
        EXTERNALHELPTARGET=helphlz
	[ -z "$INICOMP_LZEXEDAT" ] && INICOMP_LZEXEDAT=lzexedat.sh
        help_def_lzexedat="-D_LZEXEDAT"
        help_switch_lzexedat_l=""
        if ((use_build_help_compressed_lzexedat_l))
        then
          help_def_lzexedat="-D_LZEXEDAT -D_LONGLITERAL"
          help_switch_lzexedat_l="-l"
        fi
      else
        EXTERNALHELPTARGET=helphhs
	[ -z "$INICOMP_HEATSHRINK" ] && INICOMP_HEATSHRINK=heatshrink
	if [ -n "$INICOMP_HEATSHRINK_Z" ]
	then
	  if ! (( ZHINTSHOWN ))
	  then
	    echo "Using Z = $INICOMP_HEATSHRINK_Z"
	    ZHINTSHOWN=1
	  fi
	fi
      	if [ -z "$INICOMP_HEATSHRINK_Z" ]
      	then {
      	  echo placeholder> "${rootpath}tmp/pholder.tmp"
      	  if "$INICOMP_HEATSHRINK" -z "${rootpath}tmp/pholder.tmp" "${rootpath}tmp/scratch" &> /dev/null
      	  then {
      	    INICOMP_HEATSHRINK_Z=1
      	  } else {
      	    INICOMP_HEATSHRINK_Z=0
      	  } fi
      	  echo "Auto-detected Z = $INICOMP_HEATSHRINK_Z"
	  ZHINTSHOWN=1
      	  rm "${rootpath}tmp/pholder.tmp"
      	} fi
	((INICOMP_HEATSHRINK_Z)) && inicomp_help_def_z="-D_Z"
	((INICOMP_HEATSHRINK_Z)) && inicomp_help_switch_z="-z"
      fi
  fi
fi
echo "EXTERNALHELPTARGET=$EXTERNALHELPTARGET" > "../tmp/$build_name.obj/exthelp.upd"
diff -Nq ../tmp/$build_name.obj/exthelp.dat ../tmp/$build_name.obj/exthelp.upd \
  || cp -a ../tmp/$build_name.obj/exthelp.upd ../tmp/$build_name.obj/exthelp.dat

if ((use_build_help_external))
then
 if ! (( use_build_skip_help ))
 then
  echo "Creating $build_name help pages"
  if ((use_build_help_compressed))
  then
    if ((use_build_help_compressed_lzexedat))
    then
      echo LZEXEDAT_L_SWITCH="$help_switch_lzexedat_l" > "../tmp/$build_name.txt/optionlz.upd"
      diff -Nq ../tmp/$build_name.txt/optionlz.dat ../tmp/$build_name.txt/optionlz.upd \
  || cp -a ../tmp/$build_name.txt/optionlz.upd ../tmp/$build_name.txt/optionlz.dat
    else
      echo HEATSHRINK_Z_SWITCH="$inicomp_help_switch_z" > "../tmp/$build_name.txt/optionhs.upd"
      diff -Nq ../tmp/$build_name.txt/optionhs.dat ../tmp/$build_name.txt/optionhs.upd \
  || cp -a ../tmp/$build_name.txt/optionhs.upd ../tmp/$build_name.txt/optionhs.dat
    fi
  fi
  export NASM
  export DOSEMU
  export HEATSHRINK="$INICOMP_HEATSHRINK"
  export LZEXEDAT="$INICOMP_LZEXEDAT"
  make "$EXTERNALHELPTARGET" BUILDNAME="$build_name" -j$("$NPROC")
  rc=$?
 else
  rc=0
 fi
  options_d_maximum=""
  if ((use_build_help_compressed_maximum))
  then
    for file in help/*.asm
    do
      textfilebasename="${file#help/}"
      textfilebasename="${textfilebasename%.asm}"
      if ((use_build_help_compressed_maximum))
      then
        txtsize="$(("$(stat -c %s ${rootpath}tmp/"$build_name".txt/"$textfilebasename".txt)" + 1))"
        if (( $txtsize > $HELP_COMPRESSED_MAXIMUM ))
        then
          HELP_COMPRESSED_MAXIMUM="$txtsize"
          HELP_MAXIMUM_NAME="$textfilebasename"
        fi
      fi
    done
    echo "Maximum size: $HELP_COMPRESSED_MAXIMUM in file $HELP_MAXIMUM_NAME"
    options_d_maximum="-D_HELP_COMPRESSED_LARGEST=$HELP_COMPRESSED_MAXIMUM"
  fi
else
  rc=0
fi

if (($rc == 0))
then
if ((use_build_make))
then
  binbigfile="${rootpath}tmp/${build_name}l.$binbigext"
  echo "Creating ${build_name}l.$binbigext"
  export NASM
  export DOSEMU
echo DEPACKOPTIONS=" \
      -D_HELP_EXTERNAL=$use_build_help_external \
      -D_HELP_COMPRESSED=$use_build_help_compressed \
      $inicomp_help_def_z \
      $help_def_lzexedat \
      $options_d_maximum \
      " > "../tmp/$build_name.obj/optionde.upd"
diff -Nq ../tmp/$build_name.obj/optionde.dat ../tmp/$build_name.obj/optionde.upd \
  || cp -a ../tmp/$build_name.obj/optionde.upd ../tmp/$build_name.obj/optionde.dat
"$NASM" -Ox iniloadc.asm -f bin \
  "$options_i_lmacros" \
  "$options_i_symsnip" \
  "$options_i_scanptab" \
  "$options_i_help" \
  -o${rootpath}tmp/"$build_name"c.mac \
  -D_HELP_EXTERNAL="$use_build_help_external" \
  -D_HELP_COMPRESSED="$use_build_help_compressed" \
  -D_REVISIONID="'$build_revision_id'" \
  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
  -D_CHECKSUM="$use_build_inicheck" \
  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
  $options_d_maximum \
  "${dtarray[@]}" $build_options "$@" && \
"$NASM" -Ox revision.asm -f bin \
  "$options_i_lmacros" \
  "$options_i_symsnip" \
  "$options_i_scanptab" \
  "$options_i_help" \
  -o${rootpath}tmp/"$build_name"r.mac \
  -D_HELP_EXTERNAL="$use_build_help_external" \
  -D_HELP_COMPRESSED="$use_build_help_compressed" \
  -D_REVISIONID="'$build_revision_id'" \
  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
  -D_CHECKSUM="$use_build_inicheck" \
  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
  $options_d_maximum \
  "${dtarray[@]}" $build_options "$@" && \
$time_command $time_time "$time_switch1" $time_switch2 \
  make BUILDNAME="$build_name" -j$("$NPROC")
#  -D_REVISIONID="'$build_revision_id'" \
#  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
#  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
#  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
#  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
#  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
#  -D_CHECKSUM="$use_build_inicheck" \
#  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
#  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
#  "${dtarray[@]}" $build_options "$@"
rc=$?
else
  binbigfile="${rootpath}tmp/${build_name}.$binbigext"
  echo "Creating ${build_name}.$binbigext"
"$NASM" -Ox iniloadc.asm -f bin \
  "$options_i_lmacros" \
  "$options_i_symsnip" \
  "$options_i_scanptab" \
  "$options_i_help" \
  -o${rootpath}tmp/"$build_name"c.mac \
  -D_HELP_EXTERNAL="$use_build_help_external" \
  -D_HELP_COMPRESSED="$use_build_help_compressed" \
  -D_REVISIONID="'$build_revision_id'" \
  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
  -D_CHECKSUM="$use_build_inicheck" \
  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
  $options_d_maximum \
  "${dtarray[@]}" $build_options "$@" && \
$time_command $time_time "$time_switch1" $time_switch2 \
  "$NASM" -Ox debug.asm -f bin \
  -w+reloc-rel -w+error=reloc-rel \
  "$options_i_lmacros" \
  "$options_i_symsnip" \
  "$options_i_scanptab" \
  "$options_i_help" \
  -o "$binbigfile" \
  -l ${rootpath}${lstdir}"$build_name".$lstext -D_MAP=${rootpath}${mapdir}"$build_name".$mapext \
  -D_HELP_EXTERNAL="$use_build_help_external" \
  -D_HELP_COMPRESSED="$use_build_help_compressed" \
  $inicomp_help_def_z \
  $help_def_lzexedat \
  -D_REVISIONID="'$build_revision_id'" \
  -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
  -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
  -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
  -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
  -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
  -D_CHECKSUM="$use_build_inicheck" \
  -D_CHECKSUM_NEW="$use_build_inicheck_new" \
  -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
  $options_d_maximum \
  "${dtarray[@]}" $build_options "$@"
rc=$?
fi
fi

else	# compress only
if ((use_build_make))
then
  binbigfile="${rootpath}tmp/${build_name}l.$binbigext"
else
  binbigfile="${rootpath}tmp/${build_name}.$binbigext"
fi
rc=0
fi

if [ $rc -eq 0 ]
then
  tellsize="$(( $("$TELLSIZE" "$binbigfile") * 16 - $STACKSIZE ))"
fi
if [ $? -eq 0 -a $rc -eq 0 ] && ((use_build_shim)); then {
  echo "Creating $build_name.$RESULTEXT"
  "$NASM" mzshim.asm "$options_i_lmacros" "${dtarray[@]}" \
    -D_FILE="$binbigfile" -o${rootpath}bin/"$build_name.$RESULTEXT" \
    -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
    -D_IMAGE_EXE_MIN_CALC="((( - (payload.actual_end - payload) \
      + $tellsize + _IMAGE_EXE_AUTO_STACK) + 15) & ~15)" \
  && perl -0777i -pe 's/(Uses (inicomp|inicheck|ldosboot|scanptab)[^\0]*\0)/"\0" x length $1/ge' \
    ${rootpath}bin/"$build_name.$RESULTEXT"
  ls -lgG --time-style='+' ${rootpath}bin/"$build_name.$RESULTEXT"
} fi

if [ $rc -eq 0 -a -n "$LDOSBOOT_DIR" ] && ((use_build_bootable)); then {
  if [ -f "$binbigfile" ] \
  && grep -qaEi "^\s*Boot loader\s*$" "$binbigfile"; then {
    echo "Creating $lpre${build_name}$usuf.$RESULTEXT"
    rc=0
    payloadfile="$binbigfile"
    build_pl_zero_offset_option_checkpl=""
    if ((use_build_inicheck_new)); then
    "$NASM" -Ox "${LDOSBOOT_DIR%/}"/checkpl.asm -f bin \
      -w+reloc-rel -w+error=reloc-rel \
      "$options_i_lmacros" \
      "$options_i_ldosboot" \
      "$options_i_scanptab" \
      -D_REVISIONID="'$build_revision_id'" \
      -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
      -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
      -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
      -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
      -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
      -D_CHECKSUM="$use_build_inicheck" \
      -D_CHECKSUM_NEW="$use_build_inicheck_new" \
      -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
      "${dtarray[@]}" \
      -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
      -I"${INICHECK_DIR%/}"/iniload/ \
      $build_checkpl_options -o${rootpath}tmp/"$build_name$usuf.cbi" \
      -l${rootpath}${lstdir}"$build_name"$usuf.cls -D_MAP=${rootpath}${mapdir}"$build_name"${usuf}.cma \
      -D_PAYLOAD_FILE="'$binbigfile'" -D_EXEC_OFFSET=32 \
      -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK=1 \
        $build_pl_no_image_exe_option
    build_pl_zero_offset_option_checkpl="$build_pl_zero_offset_option"
    rc=$?
    payloadfile=${rootpath}tmp/"$build_name$usuf.cbi"
    fi
    ((rc == 0)) && \
    "$NASM" -Ox "${LDOSBOOT_DIR%/}"/iniload.asm -f bin \
      -w+reloc-rel -w+error=reloc-rel \
      "$options_i_lmacros" \
      "$options_i_ldosboot" \
      "$options_i_scanptab" \
      -D_REVISIONID="'$build_revision_id'" \
      -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
      -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
      -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
      -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
      -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
      -D_CHECKSUM="$use_build_inicheck" \
      -D_CHECKSUM_NEW="$use_build_inicheck_new" \
      -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
      "${dtarray[@]}" \
      -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
      -I"${INICHECK_DIR%/}"/iniload/ -D_CHECKSUM="$use_build_inicheck" \
      $build_iniload_options -o${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT" \
      -l${rootpath}${lstdir}$lpre"$build_name"$usuf.$lstext -D_MAP=${rootpath}${mapdir}$lpre"$build_name"$usuf.$mapext \
      -D_PAYLOAD_FILE="'$payloadfile'" -D_EXEC_OFFSET=32 \
      -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
      -D_IMAGE_EXE_MIN_CALC="((( - (payload.actual_end - payload) \
        + $tellsize + _IMAGE_EXE_AUTO_STACK) + 15) & ~15)" \
        $build_pl_no_image_exe_option \
        $build_pl_zero_offset_option_checkpl \
    && perl -0777i -pe 's/(Uses inicomp[^\0]*\0)/"\0" x length $1/ge' \
      ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT" \
    && ((use_build_inicheck + use_build_inicheck_new)) \
      && "$CHECKSUM" ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT"
    ls -lgG --time-style='+' ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT"
    if [ -z "$INICOMP_METHOD" -o "$INICOMP_METHOD" == "none" ]; then {
      fun_delete_compressed
    } else {
      if (( use_build_double_compressed ))
      then
	cp -a "$binbigfile" "${rootpath}tmp/$build_name.one"
	binbigfile="${binbigfile%.$binbigext}.bi2"
	binbigext=bi2
	cat "${rootpath}tmp/$build_name.one" "${rootpath}tmp/$build_name.one" > "$binbigfile"
      fi
      winmethod=""
      winduration=""
      rm -f "${rootpath}tmp/$build_name.spd"
      rm -f "${rootpath}tmp/$build_name.pro"
      rm -f "${rootpath}tmp/$build_name.siz"
      nonesize="$(stat -c %s ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT")"
      printf " %7u bytes (%6.2f%%), method %16s\n" \
	"$nonesize" \
	"$(echo "scale=2; $nonesize * 100 / $nonesize" | bc)" \
	"none" \
      | tee -a "${rootpath}tmp/$build_name.siz"
      fun_delete_compressed silent
      for method in $INICOMP_METHOD; do
	minsize="$tellsize"
	((debug)) && echo "tellsize=$tellsize"
      	inicomp_additional_memory=0
	inicomp_def_progress=""
	inicomp_def_progressamount=""
	inicomp_def_p=""
	inicomp_switch_p=""
	inicomp_def_z=""
	inicomp_switch_z=""
	inicomp_def_4=""
	inicomp_switch_4=""
	inicomp_def_l=""
	inicomp_switch_l=""
	inicomp_switch_q=""
	inicomp_def_M=""
	inicomp_switch_M=""
	inicomp_def_N=""
	inicomp_switch_N=""
	inicomp_def_S=""
	inicomp_switch_S=""
	if (( $INICOMP_PROGRESS ))
	then
	  if ! (( use_build_decomp_test ))
	  then
	    echo "Error: INICOMP_PROGRESS set but use_build_decomp_test cleared!"
	  else
	    inicomp_def_progress="-D_COUNTER -D_PROGRESS=$INICOMP_PROGRESS"
	  fi
	fi
      	if [ "$method" == "brieflz" ]; then {
      	  [ -z "$INICOMP_BLZPACK" ] && INICOMP_BLZPACK=blzpack
      	  inicomp_suffix=$blzext
      	  inicomp_option=-D_BRIEFLZ
      	} elif [ "$method" == "lz4" ]; then {
      	  [ -z "$INICOMP_LZ4" ] && INICOMP_LZ4=lz4
      	  inicomp_suffix=$lz4ext
          inicomp_option=-D_LZ4
      	} elif [ "$method" == "snappy" ]; then {
      	  [ -z "$INICOMP_SNZIP" ] && INICOMP_SNZIP=snzip
      	  inicomp_suffix=$szext
      	  inicomp_option=-D_SNAPPY
      	} elif [ "$method" == "exodecr" ]; then {
      	  [ -z "$INICOMP_EXOMIZER" ] && INICOMP_EXOMIZER=exomizer
      	  inicomp_suffix=$exoext
      	  inicomp_option=-D_EXODECR
	  [ -n "$INICOMP_EXOMIZER_P" ] && echo "Using P = $INICOMP_EXOMIZER_P"
      	  if [ -z "$INICOMP_EXOMIZER_P" ]
      	  then {
      	    echo placeholder> "${rootpath}tmp/pholder.tmp"
      	    if "$INICOMP_EXOMIZER" raw -P39 -P39 "${rootpath}tmp/pholder.tmp" -o "${rootpath}tmp/scratch" &> /dev/null
      	    then {
      	      INICOMP_EXOMIZER_P=39
      	    } else {
      	      INICOMP_EXOMIZER_P=7
      	    } fi
      	    rm "${rootpath}tmp/pholder.tmp"
      	    echo "Auto-detected P = $INICOMP_EXOMIZER_P"
      	  } fi
	  [ -n "$INICOMP_EXOMIZER_P" ] && inicomp_def_p="-D_P=$INICOMP_EXOMIZER_P"
	  [ -n "$INICOMP_EXOMIZER_P" ] && inicomp_switch_p="-P$INICOMP_EXOMIZER_P"
      	} elif [ "$method" == "x" ]; then {
      	  [ -z "$INICOMP_X" ] && INICOMP_X=x
      	  inicomp_suffix=$xext
      	  inicomp_option=-D_X
      	  inicomp_additional_memory="$(( 4 * 256 * 256 + 16384 ))"
		# 4 * 256 * 256 = CONTEXTSIZE
		# 16384 = threshold for multi-layer decompression
	} elif [ "$method" == "heatshrink" ]; then {
	  [ -z "$INICOMP_HEATSHRINK" ] && INICOMP_HEATSHRINK=heatshrink
	  inicomp_suffix=$hsext
	  inicomp_option=-D_HEATSHRINK
	  [ -n "$INICOMP_HEATSHRINK_Z" ] && echo "Using Z = $INICOMP_HEATSHRINK_Z"
      	  if [ -z "$INICOMP_HEATSHRINK_Z" ]
      	  then {
      	    echo placeholder> "${rootpath}tmp/pholder.tmp"
      	    if "$INICOMP_HEATSHRINK" -z "${rootpath}tmp/pholder.tmp" "${rootpath}tmp/scratch" &> /dev/null
      	    then {
      	      INICOMP_HEATSHRINK_Z=1
      	    } else {
      	      INICOMP_HEATSHRINK_Z=0
      	    } fi
      	    echo "Auto-detected Z = $INICOMP_HEATSHRINK_Z"
      	    rm "${rootpath}tmp/pholder.tmp"
      	  } fi
	  ((INICOMP_HEATSHRINK_Z)) && inicomp_def_z="-D_Z"
	  ((INICOMP_HEATSHRINK_Z)) && inicomp_switch_z="-z"
	} elif [ "$method" == "lzd" ]; then {
	  [ -z "$INICOMP_LZIP" ] && INICOMP_LZIP=lzip
	  inicomp_suffix=$lzext
	  inicomp_option=-D_LZD
      	  inicomp_additional_memory="$(( 32 * 1024 ))"
		# 32 KiB for the probability tables
	} elif [ "$method" == "lzo" ]; then {
	  [ -z "$INICOMP_LZOP" ] && INICOMP_LZOP=lzop
	  inicomp_suffix=$lzoext
	  inicomp_option=-D_LZO
	} elif [ "$method" == "lzsa2" ]; then {
	  [ -z "$INICOMP_LZSA" ] && INICOMP_LZSA=lzsa
	  inicomp_suffix=$lzsa2ext
	  inicomp_option=-D_LZSA2
      	  if [ -z "$INICOMP_LZSA_N" ]
          then {
      	    echo placeholder> "${rootpath}tmp/pholder.tmp"
      	    if "$INICOMP_LZSA" -N -c "${rootpath}tmp/pholder.tmp" "${rootpath}tmp/scratch" &> /dev/null
      	    then {
      	      INICOMP_LZSA_N=1
      	    } else {
      	      INICOMP_LZSA_N=0
      	    } fi
      	    echo "Auto-detected N = $INICOMP_LZSA_N"
      	    rm "${rootpath}tmp/pholder.tmp"
      	  } fi
      	  if [ -z "$INICOMP_LZSA_S" ]
          then {
      	    echo placeholder> "${rootpath}tmp/pholder.tmp"
      	    if "$INICOMP_LZSA" -S -c "${rootpath}tmp/pholder.tmp" "${rootpath}tmp/scratch" &> /dev/null
      	    then {
      	      INICOMP_LZSA_S=1
      	    } else {
      	      INICOMP_LZSA_S=0
      	    } fi
      	    echo "Auto-detected S = $INICOMP_LZSA_S"
      	    rm "${rootpath}tmp/pholder.tmp"
      	  } fi
	  ((INICOMP_LZSA_M)) && inicomp_def_M="-D_M"
	  ((INICOMP_LZSA_M)) && inicomp_switch_M="-M"
	  ((INICOMP_LZSA_N)) && inicomp_def_N="-D_N"
	  ((INICOMP_LZSA_N)) && inicomp_switch_N="-N"
	  ((INICOMP_LZSA_S)) && inicomp_def_S="-D_S"
	  ((INICOMP_LZSA_S)) && inicomp_switch_S="-S"
	} elif [ "$method" == "apl" ]; then {
	  [ -z "$INICOMP_APULTRA" ] && INICOMP_APULTRA=apultra
	  inicomp_suffix=$aplext
	  inicomp_option=-D_APL
      	} elif [ "$method" == "bzp" ]; then {
      	  [ -z "$INICOMP_BZPACK" ] && INICOMP_BZPACK=bzpack
      	  inicomp_suffix=$bzpext
          inicomp_option=-D_BZP
      	} elif [ "$method" == "zerocomp" ]; then {
      	  [ -z "$INICOMP_ZEROCOMP" ] && INICOMP_ZEROCOMP=zerocomp
      	  inicomp_suffix=$zerocompext
          inicomp_option=-D_ZEROCOMP
      	} elif [ "$method" == "mvcomp" ]; then {
      	  [ -z "$INICOMP_MVCOMP" ] && INICOMP_MVCOMP=mvcomp
      	  inicomp_suffix=$mvcompext
          inicomp_option=-D_MVCOMP
      	} elif [ "$method" == "lzexedat" ]; then {
      	  [ -z "$INICOMP_LZEXEDAT" ] && INICOMP_LZEXEDAT=lzexedat.sh
      	  inicomp_suffix=$lzexedatext
          inicomp_option=-D_LZEXEDAT
	  ((INICOMP_LZEXEDAT_4)) && inicomp_def_4="-D_4"
	  ((INICOMP_LZEXEDAT_4)) && inicomp_switch_4="-4"
	  ((INICOMP_LZEXEDAT_L)) && inicomp_def_l="-D_LONGLITERAL"
	  ((INICOMP_LZEXEDAT_L)) && inicomp_switch_l="-l"
	} elif [ "$method" == "zx0" ]; then {
	  [ -z "$INICOMP_ZX0" ] && INICOMP_ZX0=zx0.exe
	  inicomp_suffix=$zx0ext
	  inicomp_option=-D_ZX0
	  ((INICOMP_ZX0_Q)) && inicomp_switch_q="-q"
	} elif [ "$method" == "none" ]; then {
	  continue
	} else {
	  echo "Invalid compression method selected: $method"
	  exit 1
	} fi
      mkdir -p ${rootpath}tmp/"$inicomp_suffix"
      rm -f ${rootpath}tmp/"$inicomp_suffix"/$ppre"$build_name".$binbigext
      if ! (( $use_build_inicomp_only ))
      then
      rm -f ${rootpath}tmp/"$inicomp_suffix"/"$build_name"."$inicomp_suffix"
      echo "Creating $lpre${build_name}.$RESULTEXT"
      if [ "$method" == "brieflz" ]; then {
        "$INICOMP_BLZPACK" "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$blzext"
      } elif [ "$method" == "lz4" ]; then {
        "$INICOMP_LZ4" -12zfk "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$lz4ext"
      } elif [ "$method" == "snappy" ]; then {
        "$INICOMP_SNZIP" -ck "$binbigfile" > "${rootpath}tmp/$inicomp_suffix/$build_name.$szext"
      } elif [ "$method" == "exodecr" ]; then {
        "$INICOMP_EXOMIZER" raw $inicomp_switch_p $inicomp_switch_p "$binbigfile" -o "${rootpath}tmp/$inicomp_suffix/$build_name.$exoext"
      } elif [ "$method" == "x" ]; then {
        "$INICOMP_X" -9zfk "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$xext"
      } elif [ "$method" == "heatshrink" ]; then {
	HEATSHRINK="$INICOMP_HEATSHRINK" ./heatshr.sh \
	  "$binbigfile" \
	  "${rootpath}tmp/$inicomp_suffix/$build_name" ".$hsext" \
	  $inicomp_switch_z
      } elif [ "$method" == "lzd" ]; then {
        "$INICOMP_LZIP" -9vvfkc "$binbigfile" > "${rootpath}tmp/$inicomp_suffix/$build_name.$lzext"
      } elif [ "$method" == "lzo" ]; then {
        "$INICOMP_LZOP" -9vf -o "${rootpath}tmp/$inicomp_suffix/$build_name.$lzoext" "$binbigfile"
      } elif [ "$method" == "lzsa2" ]; then {
        "$INICOMP_LZSA" $inicomp_switch_M $inicomp_switch_N $inicomp_switch_S -c -f2 --prefer-ratio -v "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$lzsa2ext"
      } elif [ "$method" == "apl" ]; then {
        "$INICOMP_APULTRA" -c -v "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$aplext"
      } elif [ "$method" == "bzp" ]; then {
        "$INICOMP_BZPACK" "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$bzpext" -e
      } elif [ "$method" == "zerocomp" ]; then {
        "$INICOMP_ZEROCOMP" "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$zerocompext"
      } elif [ "$method" == "mvcomp" ]; then {
        "$INICOMP_MVCOMP" "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$mvcompext"
      } elif [ "$method" == "lzexedat" ]; then {
        "$INICOMP_LZEXEDAT" $inicomp_switch_4 $inicomp_switch_l "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$lzexedatext"
      } elif [ "$method" == "zx0" ]; then {
        "$INICOMP_ZX0" $inicomp_switch_q "$binbigfile" "${rootpath}tmp/$inicomp_suffix/$build_name.$zx0ext"
      } else {
        echo "Internal error!"
        exit 1
      } fi
      rc=$?
      else
      rc=0
      fi
      decompsize=0
      rc2=0
      if (($use_build_decomp_test)) && [ $rc -eq 0 ]
      then
        xmsdef=
        nonxmsadjust="$(stat -c %s "${rootpath}tmp/$inicomp_suffix/$build_name.$inicomp_suffix")"
        if (($use_build_decomp_test_xms))
        then
          xmsdef="-D_RELOAD_XMS"
          nonxmsadjust=0
        fi
        if (($use_build_decomp_test_file))
        then
          xmsdef="$xmsdef -D_RELOAD_FILE"
          nonxmsadjust=0
        fi
        scandef=
        if (($use_build_decomp_scan)) &&
        "$NASM" "${INICOMP_DIR%/}"/inicomp.asm "$options_i_lmacros" \
        -w+reloc-rel -w+error=reloc-rel \
        -I"${INICOMP_DIR%/}"/ "$inicomp_option" \
        -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
        -D_LCFG_CFG="'${rootpath}tmp/${build_name}l.mac'" \
        $options_lcfg_pass $options_lcfg_exec_offset \
	$inicomp_def_progress -D_PROGRESSAMOUNT=1 $inicomp_def_p \
	$inicomp_def_z \
	$inicomp_def_4 \
	$inicomp_def_l \
	$inicomp_def_M \
	$inicomp_def_N \
	$inicomp_def_S \
        $build_inicomp_options -o${rootpath}tmp/"$inicomp_suffix"/$spre"$build_name".$binbigext \
        -l ${rootpath}tmp/"$inicomp_suffix"/scan.lst \
        -D_MAP="${rootpath}tmp/$inicomp_suffix/$spre$build_name.$mapext" \
        -D_SCAN;
        then
          scandef=-D_USESCAN
        fi
        if "$NASM" "${INICOMP_DIR%/}"/inicomp.asm "$options_i_lmacros" \
        -w+reloc-rel -w+error=reloc-rel \
        -I"${INICOMP_DIR%/}"/ "$inicomp_option" \
        "${dtarray[@]}" \
        -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
	$inicomp_def_progress -D_PROGRESSAMOUNT=1 $inicomp_def_p \
	$inicomp_def_z \
	$inicomp_def_4 \
	$inicomp_def_l \
	$inicomp_def_M \
	$inicomp_def_N \
	$inicomp_def_S \
	$scandef \
        -D_SCANBINARY="'${rootpath}tmp/$inicomp_suffix/$spre$build_name.$binbigext'" \
        -D_PAYLOAD_PREFIX_LST="'${rootpath}tmp/$inicomp_suffix/'" \
        $build_inicomp_options -o${rootpath}tmp/"$inicomp_suffix"/$tpre"$build_name".$binbigext \
        -l ${rootpath}tmp/"$inicomp_suffix"/$tpre"$build_name".$lstext \
        -D_MAP="${rootpath}tmp/$inicomp_suffix/$tpre$build_name.$mapext" \
        -D_PAYLOAD_FILE="'${rootpath}tmp/$inicomp_suffix/$build_name.$inicomp_suffix'" -D_EXEC_OFFSET=32 \
        -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
        -D_TEST_PROGRAM \
        -D_TEST_PROGRESS \
        $xmsdef \
        -D_TEST_PROGRAM_DECOMPRESSED_SIZE="$(stat -c %s "$binbigfile")" \
        -D_INCLUDE_UNCOMPRESSED -D_INCLUDE_UNCOMPRESSED_IN_IMAGE=0 \
      && "$NASM" "${LDOSBOOT_DIR%/}"/iniload.asm "$options_i_lmacros" \
	"$options_i_ldosboot" \
	"$options_i_scanptab" \
        -w+reloc-rel -w+error=reloc-rel \
        "${dtarray[@]}" \
	-D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
        -I"${INICHECK_DIR%/}"/iniload/ -D_CHECKSUM="$use_build_inicheck" \
        $build_iniload_options -o${rootpath}tmp/"$inicomp_suffix"/$tpre"$build_name".$comext \
        -D_PAYLOAD_FILE="'${rootpath}tmp/$inicomp_suffix/$tpre$build_name.$binbigext'" -D_EXEC_OFFSET=32 \
        -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
        -D_IMAGE_EXE_MIN_CALC="((+0 \
          + $nonxmsadjust \
          + $(stat -c %s "$binbigfile") \
          + _IMAGE_EXE_AUTO_STACK + 15 \
	  + $inicomp_additional_memory) & ~15)"
	then
	  cat "$binbigfile" >> ${rootpath}tmp/"$inicomp_suffix"/$tpre"$build_name".$comext
          if (($use_build_decomp_test_file))
          then
	    cat "${rootpath}tmp/$inicomp_suffix/$build_name.$inicomp_suffix" >> ${rootpath}tmp/"$inicomp_suffix"/$tpre"$build_name".$comext
          fi
	  if [[ "$DEFAULT_MACHINE" == dosemu ]]
	  then
	    decompsize="$(( ( $( \
            "$DOSEMU" < /dev/null -K "${PWD}/${rootpath}tmp/$inicomp_suffix" \
            -E $tpre"$build_name".$comext -dumb -quiet -te 2> /dev/null \
            | tee /dev/stderr | sed -re '/^(about to execute|error:|note:|info:|Terminated with signal )/Id;s/[\r\n]+$//g' \
            | sed -re 's/^Allocation of DOS memory failed.$/0/' \
            ) + 0 ) * 16 ))"
            rc2=$?
	    if (( $decompsize == 0 ))
	    then
	      echo "Error: Decompression test failed" >&2
	      ((pass)) || rc2=1
	    else
	      if (( $INICOMP_SPEED_TEST ))
	      then
		start="$(date +%s.%3N)"
		"$DOSEMU" < /dev/null -K "${PWD}/${rootpath}tmp/$inicomp_suffix" \
		-E $tpre"$build_name".$comext" b $INICOMP_SPEED_TEST" -dumb -quiet -te 2> /dev/null \

#		| sed -re '/^(about to execute|error:|note:|info:)/Id;s/[\r\n]+$//g' \

		end="$(date +%s.%3N)"
		duration="$(echo "scale=3; $end - $start" | bc)"
		printf " %7.2fs for %3u runs (%$((5 + ${INICOMP_SPEED_SCALE:-0}))sms / run), method %16s\n" \
		  "$duration" "$INICOMP_SPEED_TEST" \
		  "$(echo "scale=${INICOMP_SPEED_SCALE:-0}; $duration * 1000 / $INICOMP_SPEED_TEST" | bc)" \
		  "$method" \
		| tee -a "${rootpath}tmp/$build_name.spd"
	      fi
	      if (( $INICOMP_PROGRESS ))
	      then
	        progressamount="$(( $( \
		"$DOSEMU" < /dev/null -K "${PWD}/${rootpath}tmp/$inicomp_suffix" \
		-E $tpre"$build_name".$comext" c" -dumb -quiet -te 2> /dev/null \
		| tee /dev/stderr | sed -re '/^(about to execute|error:|note:|info:|Terminated with signal )/Id;s/[\r\n]+$//g' \
		) + 0 ))"
		printf " %6u progress dots, method %16s\n" \
		  "$progressamount" \
		  "$method" \
		| tee -a "${rootpath}tmp/$build_name.pro"
		inicomp_def_progressamount="-D_PROGRESSAMOUNT=$progressamount"
	      fi
	    fi
          elif [[ "$DEFAULT_MACHINE" == qemu ]]
          then
            mkdir -p "${rootpath}tmp/boottest"
	    cp -aL "$BOOT_KERNEL" "${rootpath}tmp/boottest/${BOOT_KERNEL##*/}"
	    cp -aL "$BOOT_COMMAND" "${rootpath}tmp/boottest/${BOOT_COMMAND##*/}"
	    echo -ne "@echo off\r\n$tpre$build_name.$comext > output.txt\r\n" > "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "if errorlevel 1 goto :end\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "echo success> result.txt\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne ":end\r\nquit.com\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    "$NASM" "${rootpath}misc/quit.asm" \
	     "$options_i_lmacros" \
	     -o "${rootpath}tmp/boottest/"quit.com &&
	    "$NASM" "${LDOSBOOT_DIR%/}"/boot.asm -w-user \
	     "$options_i_lmacros" \
	     -D_COMPAT_"$BOOT_PROTOCOL"=1 \
	     -D_LBA=0 -D_USE_PART_INFO=0 -D_QUERY_GEOMETRY=0 \
	     $BOOT_OPTIONS \
	     -D_MAP="${rootpath}tmp/boottest/"boot.map \
	     -l "${rootpath}tmp/boottest/"boot.lst \
	     -o "${rootpath}tmp/boottest/"boot.bin &&
	    "$NASM" "${BOOTIMG_DIR%/}"/bootimg.asm \
	     -I ./ \
	     -I "${rootpath}tmp/boottest/" \
	     -I "${rootpath}tmp/$inicomp_suffix/" \
	     "$options_i_bootimg" \
	     "$options_i_lmacros" \
	     -o "${rootpath}tmp/boottest/"diskette.img \
	     -l "${rootpath}tmp/boottest/"diskette.lst \
	     -D_PAYLOADFILE="${BOOT_KERNEL##*/},${BOOT_COMMAND##*/},autoexec.bat,$tpre$build_name.$comext,quit.com" \
	     -D_BOOTFILE="'boot.bin'"
	    (($?)) && exit 1
	    "$QEMU" -fda "${rootpath}tmp/boottest/diskette.img" -boot order=a -display none 2> /dev/null
	    if [[ "$(mtype -t -i "${rootpath}tmp/boottest/"diskette.img ::RESULT.TXT 2> /dev/null)" != success ]]
	    then
	      echo "Error: Decompression test failed" >&2
	      decompsize=0
	      ((pass)) || rc2=1
	    else
	      decompsize="$(( $(mtype -t -i "${rootpath}tmp/boottest/"diskette.img ::OUTPUT.TXT 2> /dev/null) * 16))"
	      if (( $INICOMP_SPEED_TEST ))
	      then
	    echo -ne "@echo off\r\n$tpre$build_name.$comext b $INICOMP_SPEED_TEST\r\n" > "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "if errorlevel 1 goto :end\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "echo success> result.txt\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne ":end\r\nquit.com\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    "$NASM" "${BOOTIMG_DIR%/}"/bootimg.asm \
	     -I ./ \
	     -I "${rootpath}tmp/boottest/" \
	     -I "${rootpath}tmp/$inicomp_suffix/" \
	     "$options_i_bootimg" \
	     "$options_i_lmacros" \
	     -o "${rootpath}tmp/boottest/"diskette.img \
	     -l "${rootpath}tmp/boottest/"diskette.lst \
	     -D_PAYLOADFILE="${BOOT_KERNEL##*/},${BOOT_COMMAND##*/},autoexec.bat,$tpre$build_name.$comext,quit.com" \
	     -D_BOOTFILE="'boot.bin'"
	    (($?)) && exit 1
		start="$(date +%s.%3N)"
		"$QEMU" -fda "${rootpath}tmp/boottest/diskette.img" -boot order=a -display none 2> /dev/null
		end="$(date +%s.%3N)"
		duration="$(echo "scale=3; $end - $start" | bc)"
		printf " %7.2fs for %3u runs (%$((5 + ${INICOMP_SPEED_SCALE:-0}))sms / run), method %16s\n" \
		  "$duration" "$INICOMP_SPEED_TEST" \
		  "$(echo "scale=${INICOMP_SPEED_SCALE:-0}; $duration * 1000 / $INICOMP_SPEED_TEST" | bc)" \
		  "$method" \
		| tee -a "${rootpath}tmp/$build_name.spd"
	      fi
	      if (( $INICOMP_PROGRESS ))
	      then
	    echo -ne "@echo off\r\n$tpre$build_name.$comext c > output.txt\r\n" > "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "if errorlevel 1 goto :end\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne "echo success> result.txt\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    echo -ne ":end\r\nquit.com\r\n" >> "${rootpath}tmp/boottest/"autoexec.bat
	    "$NASM" "${BOOTIMG_DIR%/}"/bootimg.asm \
	     -I ./ \
	     -I "${rootpath}tmp/boottest/" \
	     -I "${rootpath}tmp/$inicomp_suffix/" \
	     "$options_i_bootimg" \
	     "$options_i_lmacros" \
	     -o "${rootpath}tmp/boottest/"diskette.img \
	     -l "${rootpath}tmp/boottest/"diskette.lst \
	     -D_PAYLOADFILE="${BOOT_KERNEL##*/},${BOOT_COMMAND##*/},autoexec.bat,$tpre$build_name.$comext,quit.com" \
	     -D_BOOTFILE="'boot.bin'"
	    (($?)) && exit 1
		"$QEMU" -fda "${rootpath}tmp/boottest/diskette.img" -boot order=a -display none 2> /dev/null
	    if [[ "$(mtype -t -i "${rootpath}tmp/boottest/"diskette.img ::RESULT.TXT 2> /dev/null)" != success ]]
	    then
	      echo "Error: Decompression progress test failed" >&2
	      progressamount=0
	    else
	      progressamount="$(( $(mtype -t -i "${rootpath}tmp/boottest/"diskette.img ::OUTPUT.TXT 2> /dev/null) ))"
	    fi
		printf " %6u progress dots, method %16s\n" \
		  "$progressamount" \
		  "$method" \
		| tee -a "${rootpath}tmp/$build_name.pro"
		inicomp_def_progressamount="-D_PROGRESSAMOUNT=$progressamount"
	      fi
	    fi
          else
	    echo "Error: invalid machine \"$DEFAULT_MACHINE\" selected" >&2
	    exit 1
          fi
        else
          rc2=1
        fi
      fi
      if (( $decompsize == 0 ))
      then
        decompsize="$(( \
        + $(stat -c %s "${rootpath}tmp/$inicomp_suffix/$build_name.$inicomp_suffix") \
        + $(stat -c %s "$binbigfile") \
	+ $inicomp_additional_memory \
        + 4096 ))"
        # 4096 is a heuristic guess for larger than size of the decompressor
      fi
      ((debug)) && echo "decompsize=$decompsize"
      [ "$decompsize" -gt "$minsize" ] && minsize="$decompsize"
      ((debug)) && echo "minsize=$minsize"
      rm -f ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT"
      [ $rc2 -eq 0 -a $rc -eq 0 ] \
      && "$NASM" "${INICOMP_DIR%/}"/inicomp.asm "$options_i_lmacros" \
        -w+reloc-rel -w+error=reloc-rel \
        -I"${INICOMP_DIR%/}"/ "$inicomp_option" \
        "${dtarray[@]}" \
        -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
	$inicomp_def_progress $inicomp_def_progressamount $inicomp_def_p \
	$inicomp_def_z \
	$inicomp_def_4 \
	$inicomp_def_l \
	$inicomp_def_M \
	$inicomp_def_N \
	$inicomp_def_S \
        $build_inicomp_options -o${rootpath}tmp/"$inicomp_suffix"/$ppre"$build_name".$binbigext \
        -l ${rootpath}tmp/"$inicomp_suffix"/$ppre"$build_name".$lstext \
        -D_PAYLOAD_FILE="'${rootpath}tmp/$inicomp_suffix/$build_name.$inicomp_suffix'" -D_EXEC_OFFSET=32 \
        -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
        $build_pl_no_image_exe_option
      rc=$?
      payloadfile=${rootpath}tmp/"$inicomp_suffix"/$ppre"$build_name".$binbigext
      if ((rc == 0 && use_build_inicheck_new)); then
      "$NASM" -Ox "${LDOSBOOT_DIR%/}"/checkpl.asm -f bin \
        -w+reloc-rel -w+error=reloc-rel \
        "$options_i_lmacros" \
        "$options_i_ldosboot" \
        "$options_i_scanptab" \
        -D_REVISIONID="'$build_revision_id'" \
        -D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
        -D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
        -D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
        -D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
        -D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
        -D_CHECKSUM="$use_build_inicheck" \
        -D_CHECKSUM_NEW="$use_build_inicheck_new" \
        -D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
        "${dtarray[@]}" \
        -D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
        -I"${INICHECK_DIR%/}"/iniload/ \
        $build_checkpl_options -o "${rootpath}tmp/$inicomp_suffix/$ppre$build_name.cbi" \
        -l ${rootpath}tmp/"$inicomp_suffix"/"$build_name"$csuf.cls -D_MAP=${rootpath}tmp/"$inicomp_suffix"/"$build_name"${csuf}.cma \
        -D_PAYLOAD_FILE="'${rootpath}tmp/$inicomp_suffix/$ppre$build_name.$binbigext'" -D_EXEC_OFFSET=32 \
        -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK=1 \
        $build_pl_no_image_exe_option \
        $build_pl_zero_offset_option
      rc=$?
      payloadfile="${rootpath}tmp/$inicomp_suffix/$ppre$build_name.cbi"
      fi
      ((rc == 0)) \
      && "$NASM" -Ox "${LDOSBOOT_DIR%/}"/iniload.asm -f bin \
        -w+reloc-rel -w+error=reloc-rel \
	"$options_i_lmacros" \
	"$options_i_ldosboot" \
	"$options_i_scanptab" \
	-D_REVISIONID="'$build_revision_id'" \
	-D_REVISIONID_LMACROS="${build_revision_id_lmacros:-''}" \
	-D_REVISIONID_SCANPTAB="${build_revision_id_scanptab:-''}" \
	-D_REVISIONID_SYMSNIP="${build_revision_id_symsnip:-''}" \
	-D_REVISIONID_INICOMP="${build_revision_id_inicomp:-''}" \
	-D_REVISIONID_INICHECK="${build_revision_id_inicheck:-''}" \
	-D_CHECKSUM="$use_build_inicheck" \
        -D_CHECKSUM_NEW="$use_build_inicheck_new" \
	-D_REVISIONID_LDOSBOOT="${build_revision_id_ldosboot:-''}" \
        "${dtarray[@]}" \
	-D_INILOAD_CFG="'${rootpath}tmp/${build_name}c.mac'" \
        -I"${INICHECK_DIR%/}"/iniload/ -D_CHECKSUM="$use_build_inicheck" \
        $build_iniload_options -o${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT" \
        -l ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name"$csuf.$lstext -D_MAP=${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name"$csuf.$mapext \
        -D_PAYLOAD_FILE="'$payloadfile'" -D_EXEC_OFFSET=32 \
        -D_IMAGE_EXE -D_IMAGE_EXE_AUTO_STACK="$STACKSIZE" -D_IMAGE_EXE_MAX=0 \
        -D_IMAGE_EXE_MIN_CALC="(( \
          - (payload.actual_end - payload) \
          + "$minsize" \
          + _IMAGE_EXE_AUTO_STACK + 15) & ~15)" \
        $build_pl_no_image_exe_option \
        $build_pl_zero_offset_option \
      && ((use_build_inicheck + use_build_inicheck_new)) \
        && "$CHECKSUM" ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT"
	if [ -f ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT" ]; then
	  compsize="$(stat -c %s ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT")"
	  printf " %7u bytes (%6.2f%%), method %16s\n" \
	    "$compsize" \
	    "$(echo "scale=2; $compsize * 100 / $nonesize" | bc)" \
	    "$method" \
	  | tee -a "${rootpath}tmp/$build_name.siz"
	  if [[ -z "$INICOMP_WINNER" || "$INICOMP_WINNER" == "smallest" ]] && \
	    { [ ! -f "${rootpath}bin/$lpre$build_name.$RESULTEXT" ] \
	      || (( $compsize < $(stat -c %s "${rootpath}bin/$lpre$build_name.$RESULTEXT") ))
	      } || \
	    [[ "$INICOMP_WINNER" == "$method" ]] || \
	    { [[ "$INICOMP_WINNER" == "fastest" ]] && \
	      (( $use_build_decomp_test )) && \
	      (( $INICOMP_SPEED_TEST )) && \
	      [[ -z "$winduration" || "$(echo "$winduration > $duration" | bc)" == 1 ]]
	    }; then
	    winduration="$duration"
	    winmethod="$method"
	    cp -a ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name.$RESULTEXT" ${rootpath}bin
	    cp -a ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name"$csuf.$lstext ${rootpath}${lstdir}
	    cp -a ${rootpath}tmp/"$inicomp_suffix"/$lpre"$build_name"$csuf.$mapext ${rootpath}${mapdir}
	  fi
	fi
      done
	if [ -n "$winmethod" ]; then
	  echo "Note: Method $winmethod selected."
	  if (( $use_build_decomp_test )) && (( $INICOMP_SPEED_TEST ))
	  then
	    printf "Note: Duration is %7.2fs for %3u runs (%$((5 + ${INICOMP_SPEED_SCALE:-0}))sms / run).\n" \
	      "$winduration" "$INICOMP_SPEED_TEST" \
	      "$(echo "scale=${INICOMP_SPEED_SCALE:-0}; $winduration * 1000 / $INICOMP_SPEED_TEST" | bc)"
	  fi
	  ls -lgG --time-style='+' ${rootpath}bin/$lpre"$build_name.$RESULTEXT"
	else
	  echo Error: No compression method succeeded.
	  false
	fi
    } fi
    ((use_build_qimg)) && ./makqimg.sh
    ((use_build_bimg)) && ./makbimg.sh
  } else {
    echo "Deleting $lpre${build_name}$usuf.$RESULTEXT"
    rm -f ${rootpath}bin/$lpre"$build_name$usuf.$RESULTEXT" \
      ${rootpath}${lstdir}$lpre"$build_name"$usuf.$lstext ${rootpath}${mapdir}$lpre"$build_name"$usuf.$mapext
    fun_delete_compressed
  } fi
} fi
