Skip to content

Instantly share code, notes, and snippets.

@steakknife
Last active Oct 12, 2019
Embed
What would you like to do?
macOS: Make a directory into an MS-DOS floppy image
#!/bin/bash
set -e
SIZE=1440 # TODO: handle 160, 180, 320, 360, 640, 720, 1200, 1232, 1440, 2880
NONFLAGS=()
OVERWRITE=
BOOTABLE=
help() {
/bin/cat >&2 << HELP
Usage: $0 [-f] [-b] {directory} [volumename]
-f Force overwrite image file
-b Bootable floppy image
HELP
}
bootsector() {
local DAT
if [ -n "$BOOTABLE" ]; then
# From MS-DOS 6.22 English full installation disk 1
DAT=Dw0qHE
else
# From MS-DOS 6.22 English full installation disk 2
DAT=CyQrM0
fi
/usr/bin/base64 -D << BOOTSECTOR
6zyQTVNET1M1LjAAAgEBAALgAEAL8AkAEgACAAAAAAAAAAAAAAAp${DAT}5PIE5BTUUgICAgRkFUMT
IgICD6M8CO0LwAfBYHu3gANsU3HlYWU78+fLkLAPzzpAYfxkX+D4sOGHyITfmJRwLHBz58+80Tcnkz
wDkGE3x0CIsOE3yJDiB8oBB89yYWfAMGHHwTFh58AwYOfIPSAKNQfIkWUnyjSXyJFkt8uCAA9yYRfI
seC3wDw0j38wEGSXyDFkt8ALsABYsWUnyhUHzokgByHbAB6KwAchaL+7kLAL7mffOmdQqNfyC5CwDz
pnQYvp596F8AM8DNFl4fjwSPRALNGVhYWOvoi0caSEiKHg18Mv/34wMGSXwTFkt8uwAHuQMAUFJR6D
oActiwAehUAFlaWHK7BQEAg9IAAx4LfOLiii4VfIoWJHyLHkl8oUt86gAAcACsCsB0KbQOuwcAzRDr
8jsWGHxzGfc2GHz+wogWT3wz0vc2GnyIFiV8o018+MP5w7QCixZNfLEG0uYKNk98i8qG6YoWJHyKNi
V8zRPDDQpOb24tU3lzdGVtIGRpc2sgb3IgZGlzayBlcnJvcg0KUmVwbGFjZSBhbmQgcHJlc3MgYW55
IGtleSB3aGVuIHJlYWR5DQoASU8gICAgICBTWVNNU0RPUyAgIFNZUwAAVao=
BOOTSECTOR
}
fatal() {
echo "$1" >&2
exit 1
}
absname() {
echo "$(dirname "$1")/$(basename "$1")"
}
while [[ $# -gt 0 ]]; do
case "$1" in
-b) BOOTABLE=1 ;;
-f) OVERWRITE=1 ;;
-h|--help) help; exit 1 ;;
-*) echo "$0: unknown argument" >&2; help; exit 1 ;;
*) NONFLAGS+=("$1") ;;
esac
shift
done
FOLDER="${NONFLAGS[0]}"
VOLNAME="${NONFLAGS[1]-$(basename "$FOLDER")}"
TMPIMG="$VOLNAME.$$.img"
IMG="$VOLNAME.img"
DISKPATH=
if [ -z "$FOLDER" ]; then
fatal "$0: missing folder to turn into floppy disk image"
fi
if [[ ! -e "$FOLDER" ]]; then
fatal "$0: $FOLDER doesn't exist to turn into floppy disk image"
fi
if [[ -z "$OVERWRITE" && -e "$IMG" ]]; then
fatal "$0: $IMG already exists"
fi
trap 'E=$?; rm -f "$TMPBOOTSEC" || true; rm -f "$TMPIMG" || true; /usr/bin/hdiutil eject "$DISKPATH" >/dev/null 2>&1 || true; exit $E' INT QUIT ERR EXIT HUP PIPE TERM
/bin/dd if=/dev/zero of="$TMPIMG" bs=512 count=$((SIZE * 2))
TMPBOOTSEC="$(/usr/bin/mktemp)"
bootsector > "$TMPBOOTSEC"
/sbin/newfs_msdos \
-B "$(absname "$TMPBOOTSEC")" \
-v "$VOLNAME" \
-F 12 \
-S 512 \
-f $SIZE \
"$(absname "$TMPIMG")"
DISKPATH="$(/usr/bin/hdiutil attach "$TMPIMG" -mountrandom /Volumes -nobrowse | /usr/bin/sed -E 's!^/dev/disk[0-9]+[[:space:]]+!!')"
/usr/bin/rsync -a "$FOLDER"/ "$DISKPATH"
/bin/mv "$TMPIMG" "$IMG"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment