#!/usr/bin/env sh

#  helper script: create ROM images for a given mainboard
#
#	Copyright (C) 2020,2021,2023 Leah Rowe <info@minifree.org>
#	Copyright (C) 2021,2022 Ferass El Hafidi
#				<vitali64pmemail@protonmail.com>
#	Copyright (C) 2022 Caleb La Grange <thonkpeasant@protonmail.com>
#	Copyright (C) 2022 Alper Nebi Yasak <alpernebiyasak@gmail.com>
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# This script assumes that the working directory is the root
# of git or release archive


[ "x${DEBUG+set}" = 'xset' ] && set -v
set -u -e

projectname="$(cat projectname)"

cbcfgdir="resources/coreboot"
boardcfgdir=""
kmapdir="resources/grub/keymap"
displaymodes=""
payloads=""
keyboard_layouts=""
board=""

grub_scan_disk="undefined"
cbtree="undefined"
romtype="normal" # optional parameter in board.cfg. "normal" is default
arch="undefined"

# Disable all payloads by default.
# board.cfg files have to specifically enable [a] payload(s)
payload_grub="n"
payload_grub_withseabios="n" # seabios chainloaded from grub
payload_seabios="n"
payload_seabios_withgrub="n" # i386-coreboot grub from SeaBIOS boot menu
payload_memtest="n"
payload_uboot="n"
uboot_config="undefined"

romdir=""
cbdir=""
cbfstool=""
corebootrom=""
seavgabiosrom=""

CROSS_COMPILE=""

main()
{
	while [ $# -gt 0 ]; do
		case ${1} in
			-d)
			displaymodes="${displaymodes}${2}" 
			shift ;;
			-p)
			payloads="${payloads}${2}"
			shift ;;
			-k)
			keyboard_layouts="${keyboard_layouts}${2}"
			shift ;;
			*)
			board=${1} ;;
		esac
		shift
	done

	printf "board %s , kb %s , displaymode %s , payloads %s\n" \
			${board} ${keyboard_layouts} ${displaymodes} \
			${payloads}

	if [ "${board}" = "" ]; then
		printf "build/roms: undefined board. Exiting\n"
		exit 1
	fi

	load_config
	build_dependencies
	build_rom_images
}

load_config()
{
	boardcfgdir="${cbcfgdir}/${board}"

	if [ ! -d "${boardcfgdir}" ]; then
		printf "build/roms: Target not defined: %s\n" ${board}
		exit 1
	fi
	if [ ! -f "${boardcfgdir}/board.cfg" ]; then
		printf "build/roms %s: Missing board.cfg\n" ${board}
		exit 1
	fi

	. "${boardcfgdir}/board.cfg"

	if [ "${board}" != "${cbtree}" ]; then
		cbdir="coreboot/${cbtree}"
	else
		cbdir="coreboot/${board}"
	fi

	romdir="bin/${board}"
	cbfstool="${cbdir}/util/cbfstool/cbfstool"
	seavgabiosrom="payload/seabios/seavgabios.bin"
	corebootrom="${cbdir}/build/coreboot.rom"

	if [ "${grub_scan_disk}" = "undefined" ]; then
		printf "build/roms '%s': grub_scan_disk is undefined. " \
				${board}
		printf "Defaulting to 'both'.\n"
		grub_scan_disk="both"
	fi
	if [ "${grub_scan_disk}" != "both" ] && \
			[ "${grub_scan_disk}" != "ata" ] && \
			[ "${grub_scan_disk}" != "ahci" ]; then
		printf "build/roms '%s': invalid grub_scan_disk config. " \
				${board}
		printf "Defaulting to 'both'.\n"
		grub_scan_disk="both"
		# erroring out would be silly. just use the default
	fi

	if [ "${cbtree}" = "undefined" ]; then
		printf "build/roms '%s': undefined coreboot tree. " \
				${board}
		printf "Skipping build.\n"
		exit 1
	fi
	if [ "${arch}" = "undefined" ]; then
		printf "build/roms '%s': undefined CPU type. " \
				${board}
		printf "Skipping build.\n"
		exit 1
	fi

	if [ "${payload_memtest}" != "n" ] && \
			[ "${payload_memtest}" != "y" ]; then
		payload_memtest="n"
	fi
	if [ "${payload_grub_withseabios}" = "y" ]; then
		payload_grub="y"
	fi
	if [ "${payload_grub_withseabios}" = "y" ]; then
		payload_seabios="y"
		payload_seabios_withgrub="y"
	fi
	if [ "${payload_seabios_withgrub}" = "y" ]; then
		payload_seabios="y"
	fi
	if [ "${payload_uboot}" != "n" ] && \
			[ "${payload_uboot}" != "y" ]; then
		payload_uboot="n"
	fi
	if [ "${payload_uboot}" = "y" ] && \
			[ "${uboot_config}" = "undefined" ]; then
		uboot_config="default"
	fi

	load_config_overrides
	die_if_cbconfig_and_nopayload
}

load_config_overrides()
{
	# Override all payload directives with cmdline args
	if [ -z ${payloads} ]; then
		return 0
	fi

	echo "setting payloads $payloads"
	payload_grub="n"
	payload_grub_withseabios="n" # seabios chainloaded from grub
	payload_seabios="n"
	payload_seabios_withgrub="n" # grub from SeaBIOS menu
	payload_uboot="n"
	payload_memtest="n"

	for payload in ${payloads} ; do
		eval "payload_${payload}=y"
	done
}

die_if_cbconfig_and_nopayload()
{
	# if a coreboot config exists, and payloads are not
	# defined in the lbmk config, exit with error
	# if no configs exist, this won't fail. this way, cbtrees
	# like "default" can exist which just contain patches

	if [ "${payload_grub}" = "y" ] || [ "${payload_seabios}" = "y" ] \
				|| [ "${payload_uboot}" = "y" ]; then
		return 0
	fi

	for configfile in "${boardcfgdir}/config/"*; do
		if [ ! -e "${configfile}" ]; then
			continue
		fi
		printf "build/roms %s: Payload undefined. Exiting.\n" \
				${board}
		exit 1
	done
}

build_dependencies()
{
	if [ ! -d "${cbdir}" ]; then
		./download coreboot ${cbtree}
	fi
	if [ ! -f "${cbfstool}" ]; then
		./build module cbutils ${cbtree} || exit 1
	fi
	cat version > "${cbdir}/.coreboot-version"

	build_dependency_crossgcc

	build_dependency_seabios
	build_dependency_grub
	build_dependency_uboot
}

build_dependency_crossgcc()
{
	if [ "${arch}" = "x86_32" ] || [ "${arch}" = "x86_64" ]; then
		if [ ! -d "${cbdir}/util/crossgcc/xgcc/i386-elf/" ]; then
			# Even for 64-bit machines, coreboot builds 32-bit ROM
			# images, so we only need to worry about i386-elf
			make -C "${cbdir}" crossgcc-i386 CPUS=$(nproc)
		fi
		case "$(uname -m)" in
			x86*|i*86|amd64) : ;;
			*) export CROSS_COMPILE=i386-elf- ;;
		esac
	elif [ "${arch}" = "ARMv7" ]; then
		if [ ! -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ]; then
			make -C "${cbdir}" crossgcc-arm CPUS=$(nproc)
		fi
		case "$(uname -m)" in
			arm|arm32|armv6*|armv7*) : ;;
			*) export CROSS_COMPILE=arm-eabi- ;;
		esac
	elif [ "${arch}" = "AArch64" ]; then
		if [ ! -d "${cbdir}/util/crossgcc/xgcc/aarch64-elf/" ]; then
			make -C "${cbdir}" crossgcc-aarch64 CPUS=$(nproc)
		fi
		# aarch64 also needs armv7 toolchain for arm-trusted-firmware
		if [ ! -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ]; then
			make -C "${cbdir}" crossgcc-arm CPUS=$(nproc)
		fi
		case "$(uname -m)" in
			arm64|aarch64) : ;;
			*) export CROSS_COMPILE=aarch64-elf- ;;
		esac
	fi

	export PATH="$(pwd)/${cbdir}/util/crossgcc/xgcc/bin:$PATH"
}

build_dependency_seabios()
{
	if [ ! -f "${seavgabiosrom}" ] \
			|| [ ! -f payload/seabios/seabios_libgfxinit.elf ] \
			|| [ ! -f payload/seabios/seabios_vgarom.elf ] \
			|| [ ! -f payload/seabios/seabios_normal.elf ]; then
		if [ "${payload_seabios}" = "y" ]; then
			./build payload seabios
		elif [ "${payload_grub}" = "y" ] \
				&& [ "${payload_grub_withseabios}" = "y" ]
		then
			./build payload seabios
		fi
	fi
	if [ "${payload_memtest}" = "y" ] && [ ! -f "memtest86plus/memtest" ]
	then
		./build module memtest86plus
	fi
}

build_dependency_grub()
{
	if [ "${payload_grub}" != "y" ] \
			&& [ "${payload_seabios_withgrub}" != "y" ]; then
		return 0
	fi

	if [ -f "payload/grub/grub_usqwerty.cfg" ]; then
		sha1cmd="sha1sum resources/grub/config/grub.cfg"
		grubrefchecksum="$(${sha1cmd} | awk '{print $1}')"

		sha1cmd="sha1sum payload/grub/grub_usqwerty.cfg"
		grubsha1="$(${sha1cmd} | awk '{print $1}')"

		if [ "${grubrefchecksum}" != "${grubsha1}" ]; then
			rm -Rf payload/grub/
			printf "GRUB change detected. Rebuilding:\n"
		fi
	else
		printf "GRUB payloads needed. Building:\n"
		rm -Rf payload/grub/ # just in case
	fi
	for keymapfile in ${kmapdir}/*; do
		if [ ! -f "${keymapfile}" ]; then
			continue
		fi

		keymap="${keymapfile##*/}"
		keymap="${keymap%.gkb}"

		grubelf="payload/grub/grub_${keymap}.elf"
		grubcfg="payload/grub/grub_${keymap}.cfg"
		grubtestcfg="payload/grub/grub_${keymap}_test.cfg"

		if [ ! -f "${grubelf}" ] || [ ! -f "${grubcfg}" ] || \
				[ ! -f "${grubtestcfg}" ]; then
			./build payload grub
		fi
	done
}

build_dependency_uboot()
{
	if [ "${payload_uboot}" != "y" ]; then
		return 0
	fi

	ubdir=""
	if [ "${uboot_config}" = "default" ]; then
		ubdir="payload/u-boot/${board}"
	else
		ubdir="payload/u-boot/${board}/${uboot_config}"
	fi

	if [ -f "${ubdir}/u-boot.elf" ]; then
		ubootelf="${ubdir}/u-boot.elf"
	elif [ -f "${ubdir}/u-boot" ]; then
		ubootelf="${ubdir}/u-boot"
	else
		printf "U-Boot needed. Building:\n"
		rm -Rf "payload/u-boot/${board}" # just in case
		./build payload u-boot "${board}"
	fi
}

build_rom_images()
{
	[ -d "${romdir}/" ] || mkdir -p "${romdir}/"
	rm -f "${romdir}"/*

	for initmode in "normal" "vgarom" "libgfxinit"; do
		hmode="vesafb"
		if [ "${initmode}" != "vgarom" ]; then
			hmode="corebootfb"
		fi
		modes="${hmode} txtmode"
		if [ ! -z ${displaymodes} ]; then
			modes="${displaymodes}"
		fi
		for displaymode in ${modes}; do
			if [ "${initmode}" = "normal" ] \
					&& [ "$displaymode" != "txtmode" ]; then
				continue
			fi
			cbcfg="${boardcfgdir}/config/${initmode}"
			cbcfg="${cbcfg}_${displaymode}"
			if [ "${initmode}" = "normal" ]; then
				cbcfg="${cbcfg%_*}"
			fi
			mkRoms "${cbcfg}" "${displaymode}" "${initmode}"
		done
	done

	make distclean -BC "${cbdir}"
}

# Main ROM building function. This calls all other functions
mkRoms()
{
	_cbcfg="${1}"
	displaymode="${2}"
	initmode="${3}"

	if [ ! -f "${_cbcfg}" ]; then
		printf "'%s' does not exist. Skipping build for %s %s %s\n" \
				${_cbcfg} ${board} \
				${displaymode} ${initmode}
		return 0
	fi

	# make coreboot ROM without a payload in it
	mkCoreboot "${_cbcfg}"

	# now add payloads, per user config:

	if [ "${displaymode}" = "txtmode" ] \
				&& [ "${payload_memtest}" = "y" ]; then
		"${cbfstool}" "${corebootrom}" add-payload \
				-f memtest86plus/memtest -n img/memtest \
				-c lzma || exit 1
	fi

	if [ "${payload_seabios}" = "y" ]; then
		if [ "${payload_seabios_withgrub}" = "n" ]; then
			x=${corebootrom}
			y=${initmode}
			t=$(mkSeabiosRom "$x" "fallback/payload" "$y")

			_newrom="${romdir}/seabios_${board}_${initmode}.rom"
			if [ "${initmode}" != "normal" ]; then
				_newrom="${_newrom%.rom}_${displaymode}.rom"
			fi

			# rom image ready to be flashed:
			moverom "${t}" "${_newrom}" "${romtype}"
			rm -f "${t}"
		else
			tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
			cp "${corebootrom}" "${tmprom}"
			mkRomsWithGrub "${tmprom}" "${initmode}" \
					"${displaymode}" "seabios_withgrub"
			rm -f "${tmprom}"
		fi
	fi

	if [ "${payload_grub}" = "y" ]; then
		mkRomsWithGrub "${corebootrom}" "${initmode}" \
				"${displaymode}" "grub"
	fi

	if [ "${payload_uboot}" = "y" ]; then
		x=${corebootrom}
		y=${uboot_config}
		z=${cbfstool}
		tmpubootrom="$(mkUbootRom "$x" "fallback/payload" "$y" "$z")"
		if [ "${initmode}" = "normal" ]; then
			_newrom="${romdir}/uboot_payload_${board}_"
			_newrom="${_newrom}${initmode}.rom"
		else
			_newrom="${romdir}/uboot_payload_${board}_"
			_newrom="${_newrom}${initmode}_${displaymode}.rom"
		fi

		# rom image ready to be flashed:
		moverom "${tmpubootrom}" "${_newrom}" "${romtype}"
		rm -f "${tmpubootrom}"
	fi
}

# expected: configs must not specify a payload
mkCoreboot()
{
	_cbcfg="${1}" # eg. resources/coreboot/e6400nvidia_4mb/config/normal

	if [ ! -f "${_cbcfg}" ]; then
		printf "\nmkCoreboot: coreboot config '%s' does not exist. " \
				${_cbcfg}
		printf "Skipping build.\n"
		return 0
	fi

	printf "%s-%s\n" "$(cat projectname)" "$(cat version)" \
			> "${cbdir}/.coreboot-version"

	if [ -f "${cbfstool}" ]; then
		mv "${cbfstool}" "${cbdir}/cbfstool"
	fi
	make clean -BC "${cbdir}"

	if [ -f "${cbdir}/cbfstool" ]; then
		mv "${cbdir}/cbfstool" "${cbfstool}"
	fi

	cp "${_cbcfg}" "${cbdir}"/.config
	./build module cbutils ${cbdir#coreboot/} || exit 1

	make -j$(nproc) -BC "${cbdir}"
}

# make a rom in /tmp/ and then print the path of that ROM
mkSeabiosRom()
{
	target_cbrom="${1}" # rom to insert seabios in. will not be touched
		# (a tmpfile will be made instead)
	target_seabios_cbfs_path="${2}" # e.g. fallback/payload
	target_initmode="${3}" # e.g. libgfxinit

	target_seabioself="payload/seabios/seabios_${target_initmode}.elf"
	target_seavgabios_rom="payload/seabios/seavgabios.bin"

	tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)

	cp "${target_cbrom}" "${tmprom}"

	"${cbfstool}" "${tmprom}" add-payload -f "${target_seabioself}" \
			-n ${target_seabios_cbfs_path} -c lzma || exit 1
	"${cbfstool}" "${tmprom}" add-int -i 3000 -n etc/ps2-keyboard-spinup \
			|| exit 1

	if [ "${target_initmode}" = "normal" ] \
			|| [ "${target_initmode}" = "libgfxinit" ]; then
		"${cbfstool}" "${tmprom}" add-int -i 2 \
				-n etc/pci-optionrom-exec || exit 1
	elif [ "${target_initmode}" = "vgarom" ]; then # coreboot executes it
		"${cbfstool}" "${tmprom}" add-int -i 0 \
				-n etc/pci-optionrom-exec || exit 1
	fi # for undefined modes, don't add this integer. use SeaBIOS defaults

	"${cbfstool}" "${tmprom}" add-int -i 0 -n etc/optionroms-checksum \
			|| exit 1

	if [ "${target_initmode}" = "libgfxinit" ]; then
		"${cbfstool}" "${tmprom}" add -f "${target_seavgabios_rom}" \
				-n vgaroms/seavgabios.bin -t raw || exit 1
	fi

	printf "%s\n" "${tmprom}"
}

# Make separate ROM images with GRUB payload, for each supported keymap
mkRomsWithGrub()
{
	tmprompath="${1}"
	initmode="${2}"
	displaymode="${3}"
	firstpayloadname="${4}" # allow values: grub, seabios, seabios_withgrub

	x=${tmprompath}
	y=${initmode}
	if [ "${payload_grub_withseabios}" = "y" ] \
			&& [ "${firstpayloadname}" = "grub" ]; then
		mv "$(mkSeabiosRom "${x}" "seabios.elf" "${y}")" \
				"${tmprompath}"
	elif [ "${payload_seabios_withgrub}" ] \
			&& [ "${firstpayloadname}" != "grub" ]; then
		mv "$(mkSeabiosRom "${x}" "fallback/payload" "${y}")" \
				"${tmprompath}"
	fi

	keymaps=""
	if [ -z ${keyboard_layouts} ]; then
		for kmapfile in "${kmapdir}"/*; do
			keymaps="${keymaps} ${kmapfile}"
		done
	else
		for keymapname in ${keyboard_layouts}; do
			keymaps="${keymaps} ${kmapdir}/${keymapname}.gkb"
		done
	fi
	for keymapfile in ${keymaps}; do
		if [ ! -f "${keymapfile}" ]; then
			continue
		fi

		keymap="${keymapfile##*/}"
		keymap="${keymap%.gkb}"

		grub_path_in_cbfs="fallback/payload"
		if [ "${firstpayloadname}" != "grub" ]; then
			grub_path_in_cbfs="img/grub2"
		fi

		# evil bofh rfc 2646 compliance hack
		x=${keymap}
		y=${tmprompath}
		z=${grub_path_in_cbfs}
		tmpgrubrom="$(mkGrubRom "${x}" "${y}" "${z}")"

		_newrom="${romdir}/${firstpayloadname}_${board}_${initmode}_"
		if [ "${initmode}" = "normal" ]; then
			_newrom="${_newrom}${keymap}.rom"
		else
			_newrom="${_newrom}${displaymode}_${keymap}.rom"
		fi

		# rom image ready to be flashed:
		moverom "${tmpgrubrom}" "${_newrom}" "${romtype}"
		rm -f "${tmpgrubrom}"
	done
}

# make a rom in /tmp/ and then print the path of that ROM
mkGrubRom()
{
	target_keymap="${1}"
	target_cbrom="${2}"
	target_grubelf_cbfs_path="${3}" # e.g. fallback/payload

	grubelf="payload/grub/grub_${target_keymap}.elf"
	grubcfg="payload/grub/grub_${target_keymap}.cfg"
	grubtestcfg="payload/grub/grub_${target_keymap}_test.cfg"

	tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX) || exit 1

	cp "${target_cbrom}" "${tmprom}" || exit 1

	"${cbfstool}" "${tmprom}" add-payload -f "${grubelf}" \
			-n ${target_grubelf_cbfs_path} -c lzma || exit 1

	tmpgrubcfg=$(mktemp -t grub.cfg.XXXXXXXXXX)
	tmpgrubtestcfg=$(mktemp -t grubtest.cfg.XXXXXXXXXX)
	if [ "${grub_scan_disk}" = "ahci" ]; then
		sed \
		's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ahci\"/' \
				"${grubcfg}" > "${tmpgrubcfg}"
		sed \
		's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ahci\"/' \
				"${grubtestcfg}" > "${tmpgrubtestcfg}"
	elif [ "${grub_scan_disk}" = "ata" ]; then
		sed \
		's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ata\"/' \
				"${grubcfg}" > "${tmpgrubcfg}"
		sed \
		's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ata\"/' \
				"${grubtestcfg}" > "${tmpgrubtestcfg}"
	else
		cp "${grubcfg}" "${tmpgrubcfg}"
		cp "${grubtestcfg}" "${tmpgrubtestcfg}"
	fi

	"${cbfstool}" "${tmprom}" add -f "${tmpgrubcfg}" -n grub.cfg -t raw \
			|| exit 1
	"${cbfstool}" "${tmprom}" add -f "${tmpgrubtestcfg}" -n grubtest.cfg \
			-t raw || exit 1
	rm -f "${tmpgrubcfg}" "${tmpgrubtestcfg}"

	backgroundfile="background1280x800.png"
	if [ "${board}" = "x60" ] || [ "${board}" = "t60_intelgpu" ]; then
		# TODO: don't hardcode this. do it in board.cfg per board
		backgroundfile="background1024x768.png"
	fi
	backgroundfile="resources/grub/background/${backgroundfile}"
	"${cbfstool}" "${tmprom}" add -f ${backgroundfile} -n background.png \
			-t raw || exit 1

	printf "%s\n" "${tmprom}"
}

# make a rom in /tmp/ and then print the path of that ROM
mkUbootRom()
{
	target_cbrom="${1}" # rom to insert u-boot in. it won't be touched
		# (a tmpfile will be made instead)
	target_uboot_cbfs_path="${2}" # e.g. fallback/payload
	target_uboot_config="${3}"
	cbfstool_path="${4}"

	if [ "${target_uboot_config}" = "default" ]; then
		target_ubdir="payload/u-boot/${board}"
	else
		target_ubdir="payload/u-boot/${board}/${target_uboot_config}"
	fi

	if [ -f "${target_ubdir}/u-boot.elf" ]; then
		target_ubootelf="${target_ubdir}/u-boot.elf"
	elif [ -f "${target_ubdir}/u-boot" ]; then
		target_ubootelf="${target_ubdir}/u-boot"
	fi

	tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)

	cp "${target_cbrom}" "${tmprom}"
	"${cbfstool}" "${tmprom}" add-payload -f "${target_ubootelf}" \
			-n ${target_uboot_cbfs_path} -c lzma || exit 1

	printf "%s\n" "${tmprom}"
}

# it is assumed that no other work will be done on the ROM
# after calling this function. therefore this function is "final"
moverom()
{
	rompath="$1"
	_newrom="$2"
	cuttype="$3"

	printf "\nCreating new ROM image: %s\n" "${_newrom}"

	cp ${rompath} ${_newrom}

	if [ "${cuttype}" = "i945 laptop" ]; then
		dd if=${_newrom} of=top64k.bin bs=1 \
				skip=$(($(stat -c %s ${_newrom}) - 0x10000)) \
				count=64k
		dd if=top64k.bin of=${_newrom} bs=1 \
				seek=$(($(stat -c %s ${_newrom}) - 0x20000)) \
				count=64k conv=notrunc
		rm -f top64k.bin
		return 0
	fi

	for romsize in 4 8 16; do
		for x in "IFD" "IFD NOGBE"; do
			if [ "${romsize}MiB ICH9 ${x} NOR flash" \
					!= "${cuttype}" ]; then
				continue
			fi
			c=4
			ifdgbe="descriptors/ich9m/ich9fdnogbe_${romsize}m.bin"
			if [ "${x}" = "IFD" ]; then
			c=12
			ifdgbe="descriptors/ich9m/ich9fdgbe_${romsize}m.bin"
			fi
			if [ ! -f "${ifdgbe}" ]; then
				./build descriptors ich9m
			fi
			dd if=${ifdgbe} of=${_newrom} bs=${c}k count=1 \
					conv=notrunc
		done
	done
}

main $@