#!/bin/bash
# machine/sun/tme-make-machs - downloads firmware & OS setup files and makes Sun machines:

# Copyright (c) 2023 Ruben Agin
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Matt Fredette.
# 4. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Default values of various locations to download from/to. 

# Machines to build in machine_root. Templates come from machine_dir and are
# put in directories named after the template files. If unset, default template
# directory is <tme_install_prefix>/share/tme/examples. 
machine_root=./machine
machine_dir=
machines=

# Firmware downloads for various machines
firmware_root=./sun-fw
firmware_site=https://people.csail.mit.edu/~fredette/tme
firmwares="sun2-multi-rev-R sun3-carrera-rev-3.0 sun4-75-rev-2.9 SUNW,501-1415 SUNW,501-1561 SUNW,501-2325 SUNW,501-3082-update7"

# NetBSD location/release to download
netbsd_root=./NetBSD
netbsd_site=https://cdn.netbsd.org/pub/NetBSD
netbsd_rel=10.0

# NetBSD binary sets to install via tape
# Remember, skip "etc" for an upgrade.
#netbsd_sets="etc base comp games man misc rescue text"
chksum=MD5
#chksum=SHA512

tape=tape0

# The command to use for downloading files
download_cmd() {
    [ -s $2 ] || wget -np -r -nH --cut-dirs=2 $1/$2
}

inc_tape() {
    mt=`printf mt/%02d $num`
    mkdir -p $mt
    ((num+=1))
}

# The command to make a tape segment. Run once to link, twice to decompress
make_seg() {
    local seg
    local suf
    
    inc_tape
    seg=$mt/$2
    
    if [ -s $1/$2.tgz ]; then
	ln -sf $1/$2.tgz $mt
	seg=$seg.tgz
	suf=.tar
    fi
    if [ -s $1/$2.gz ]; then
	ln -sf $1/$2.gz $mt
	seg=$seg.gz
	suf=
    fi
    if [ -s $seg ]; then
	echo -n "$seg " >> $3-zlib
	[ -s $mt/$2$suf ] || zcat -f $seg > $mt/$2$suf
	seg=$mt/$2$suf
	echo -n "$seg " >> $3
    fi
}

# Download the firmware for each machine type, if needed
mkdir -p $firmware_root
pushd $firmware_root
for fw in $firmwares; do
    download_cmd $firmware_site $fw.bin
done
popd

mkdir -p $netbsd_root
pushd $netbsd_root
# Download arch-specific NetBSD install files
for arch in {sun2,sun3}; do
    netbsd_path=NetBSD-$netbsd_rel/$arch
    # Only download if necessary
    download_cmd $netbsd_site $netbsd_path/INSTALL.html
    download_cmd $netbsd_site $netbsd_path/INSTALL.more
    download_cmd $netbsd_site $netbsd_path/INSTALL.ps
    download_cmd $netbsd_site $netbsd_path/INSTALL.txt
    download_cmd $netbsd_site $netbsd_path/installation/tapeimage/tapeboot
    download_cmd $netbsd_site $netbsd_path/installation/miniroot/miniroot.fs.gz
    for bin in {kernel,sets}; do
	download_cmd $netbsd_site $netbsd_path/binary/$bin/$chksum
	for f in `awk '{print $2}' $netbsd_path/binary/$bin/$chksum | sed -e 's%(\(.*\))%\1%'`; do
	    download_cmd $netbsd_site $netbsd_path/binary/$bin/$f
	done
	pushd $netbsd_path/binary/$bin
	${chksum,,}sum -c $chksum
	popd
    done
done

for arch in {sparc,sparc64}; do
    # Only download if necessary
    download_cmd $netbsd_site images/$netbsd_rel/NetBSD-$netbsd_rel-$arch.iso
done
popd

# First, try to find installed location of tme
if [ -z ${MINGW_PREFIX+set} ]; then
   prefix=$(dirname `which tmesh`)/..
else
   prefix=${MINGW_PREFIX}
fi

loc=`realpath $prefix/share/tme/examples`

# Next, key off of the machine descriptions in the examples dir to create config dirs
for mach in `ls $loc/SUN*`; do
    mach=`basename $mach`
    machd=${mach,,}
    # Only create config if corresponding dir doesn't already exist
    if [ ! -d "$machd" ]; then
       echo $mach
       mkdir $machd
       cp $loc/$mach $machd/MY-$mach 2>/dev/null
       cp $loc/{my-sun-macros.txt,sun-keyboards.txt,$machd*} $machd 2>/dev/null
       # if there is a site- or mach-specific config, copy those files
       [ -d "$loc/$machd" ] && cp $loc/$machd/* $machd 2>/dev/null
    fi
done

# Replace with absolute pathnames to avoid symlink issues
firmware_root=$(realpath $firmware_root)
netbsd_root=$(realpath $netbsd_root)

# Finally, set up the links to the NetBSD installation files and device configuration
for arch in {sun2,sun3,sun4,sun-ultra}; do
    netbsd_path=$netbsd_root/NetBSD-$netbsd_rel/$arch
    netbsd_iso=$netbsd_root/images/$netbsd_rel/NetBSD-$netbsd_rel-sparc
    netbsd=netbsd-$arch
    prom=my-$arch-eeprom.bin
    for machd in `ls -d $arch-*`; do
	pushd $machd
	echo "Making $machd"
	if [ $arch = "sun4" ]; then
	    [ -d $firmware_root ] && ln -sf $firmware_root/$arch* .
	    [ -d $firmware_root ] && ln -sf $firmware_root/SUNW,501-1* .
	    [ -s "${netbsd_iso}.iso" ] && ln -sf "${netbsd_iso}.iso" $netbsd.iso
	    macht="SS2"
	    cnt=2008
	    arch+=c
	    prom=my-$arch-nvram.bin
	    sz=10G
	elif [ $arch = "sun-ultra" ]; then
	    [ -d $firmware_root ] && ln -sf $firmware_root/SUNW* .
	    [ -s "${netbsd_iso}64.iso" ] && ln -sf "${netbsd_iso}64.iso" $netbsd.iso
	    cnt=8176
	    arch=sun4u
	    prom=my-$arch-nvram.bin
	    sz=10G
	else
	    if [ -d "$netbsd_path" ]; then
		echo "# tmesh script for loading tape from compressed files for $arch" > mt-$arch-zlib
		echo "# tmesh script for loading tape for uncompressed files for $arch" > mt-$arch
		[ -d $firmware_root ] && ln -sf $firmware_root/$arch* .
		num=1
		inc_tape
		ln -sf $netbsd_path/installation/tapeimage/tapeboot $mt
		echo -n "command $tape load $mt/tapeboot " >> mt-$arch-zlib
		echo -n "command $tape load $mt/tapeboot " >> mt-$arch
		if [ $arch = "sun2" ]; then
		    inc_tape
		    touch $mt/blank
		    echo -n "$mt/blank " >> mt-$arch-zlib
		    echo -n "$mt/blank " >> mt-$arch
		fi
		[ $arch = "sun3" ] && make_seg $netbsd_path/binary/kernel netbsd-RAMDISK mt-$arch
		inc_tape
		touch $mt/blank
		echo -n "$mt/blank " >> mt-$arch-zlib
		echo -n "$mt/blank " >> mt-$arch
		make_seg $netbsd_path/installation/miniroot miniroot.fs mt-$arch
		[ $arch = "sun2" ] && make_seg $netbsd_path/binary/kernel netbsd-RAMDISK mt-$arch
		for f in `awk '{print $2}' $netbsd_path/binary/$bin/$chksum | sed -e 's%(\(.*\).tgz)%\1%'`; do
		    make_seg $netbsd_path/binary/sets $f mt-$arch
		done
	    fi
	    if [ $arch = "sun3" ]; then
		macht="3/150"
		[ -s $prom ] || tme-sun-eeprom < $machd-eeprom.txt > $prom
	    else
		macht="2/120"
	    fi
	    cnt=0
	    prom=my-$arch-idprom.bin
	    sz=3G
	fi
	if [ ! -s $prom ]; then
	    dd if=/dev/zero bs=1 count=$cnt of=$prom
	    if [ $arch != "sun4u" ]; then
		macaddr=`printf 8:0:20:%02X:%02X:%02X $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]`
		echo "$macht $macaddr"
		tme-sun-idprom $macht $macaddr >> $prom
	    fi
	fi
	[ -s my-$arch-disk.img ] || dd if=/dev/zero of=my-$arch-disk.img bs=1 count=1 seek=$sz
	popd
    done
done
