#!/bin/sh

# This script will convert a .TD0 Teledisk floppy image to an .img RAW floppy image.

## NOTE: THIS SCRIPT REQUIRES THE SAMdisk.exe EXECUTABLE TO BE PRESENT
# IN THE SAME DIRECTORY WITH THIS SCRIPT.

# Argument #1 is name of .TD0 file (without the ".TD0" extension).
# NOTE: run winecfg and set to Windows 2000 or else SAMdisk will not run
# and of course make sure SAMdisk.exe exists in current dir.
# Argument #2 (0...79) is optional and specifies the number of first track to extract.
# (if not specified, extraction starts with track 0)
# Argument #3 (0...79) is optional and requires arg #2. It specifies the number of last track to extract.
# (if not specified, extraction starts with track 79)

# ########### PART 1: Convert from .TD0 to a text file containing
# a hex dump of the floppy image contents, in physical track order,
# each track starting with side 0 and continuing with side 1 of it.

if [ -z "$1" -o ! -f "$1.TD0" ]; then
	echo "File $1.TD0 not found, exiting."
	exit 0
fi

if [ ! -f "SAMdisk.exe" ]; then
	echo "SAMdisk.exe not present, exiting"
	exit 0
else
	if [ "$(md5sum SAMdisk.exe | awk '{print $1}')" != "1691c1c43ff72f73da65afc2b6e3a2ae" ]; then
		echo "Wrong checksum for SAMdisk.exe utility, exiting."
		exit 0
	fi
	if [ -n "$(wine SAMdisk.exe scan \"$1.TD0\" | grep 'This program requires Windows 2000 or later')" ]; then
		echo "PLEASE RUN winecfg AND SET WINDBLOWS VERSION TO 2000 OR LATER."; exit 0
	fi
fi

max_track=$(wine SAMdisk.exe info "$1.TD0" | grep 'Size:' | awk '{print $2}')

if [ ! -f hexdumptxt2bin ]; then
	echo -e "\n\n------------------------------------------------\nThe hexdumptxt2bin executable was not found!\nConversion to binary will take 1 hour or more,\nso you can safely go shopping or take a nap in the meantime.\n------------------------------------------------"
#else	# uncomment next 4 lines when you have a working compiled executable
#	if [ "$(md5sum hexdumptxt2bin | awk '{print $1}')" != "83d7cdcefef8524581d1e3d059330b42" ]; then
#		echo "Wrong checksum for hexdumptxt2bin utility, exiting."
#		exit 0
#	fi
fi

# ----------------- Cleanup ----------------- #
[ -f "$1.bin" ]		&& rm -fv "$1.bin"
[ -f "$1.hexdump" ]	&& rm -fv "$1.hexdump"
[ -f "$1.hexdump.txt" ] && rm -fv "$1.hexdump.txt"
[ -f "$1.img" ]		&& rm -fv "$1.img"
[ -f "SYS.img" ]	&& rm -fv "SYS.img"
# ------------------------------------------- #

if [ -n "$2" ]; then first_track=$2; else first_track=0; fi
if [ -n "$3" ]; then last_track=$3;  else last_track=79; fi
if [ $first_track -lt 0 -o $last_track -lt 0 ]; then echo "Track numbers are always positive, duh!??"; exit 0; fi
if [ $first_track -gt $last_track ]; then echo "First track# must be less than last track#. Aborting."; exit 0; fi
if [ $last_track -gt $max_track ]; then echo "This image has only $max_track tracks, aborting."; exit 0; fi

echo -e "\nExtracting tracks $first_track to $last_track from Teledisk image:\n------------------------------------------------"
i=$first_track
while [ $i -le $last_track ]; do
    echo -n "$(printf %02d $i)"
    wine SAMdisk.exe view $1.TD0 -c$i >> $1.hexdump.txt 2>/dev/null
    echo -en "\b\b"
    let "i = i + 1"
done
echo -e "  DONE.\n------------------------------------------------\n"
dos2unix "$1.hexdump.txt"

echo -n "Deleting extra info from hexdump text file... "
cat "$1.hexdump.txt" | sed -e '/^$/d' -e '/^\ /d' -e '/^\[/d' -e '/^...Kbps/d' -e '/^Sector/d' > "$1.hexdump"
echo -e "done.\n"

# ########### PART 2: Convert from hexdump text file to binary RAW floppy image
# This can be done 2 ways: if the hexdumptxt2bin Linux executable is present,
# then it will be used and the conversion will happen in a snap.
# If hexdumptxt2bin is not present, the conversion will be done by Bash means
# and it will take an eternity (about 1 hour or more).

# This part takes a standard hexdump textfile as input and saves its contents in the original binary format.
# The hexdump textfile must have line numbers at beginning of each line, 16 bytes per line separated by spaces
# and the ASCII representation at the end as a 16 character string (no spaces in between).
# An example of hexdump textfile acceptable as input is this:
: <<HEXDUMP_TEXT_SAMPLE
0000  00 F3 E5 3E C9 32 00 00 CD 00 00 3B 3B E1 3E 41  ...>.2.....;;.>A
0010  D3 FE 01 30 00 09 11 00 5A 06 20 C5 4E 06 08 3E  ...0....Z. .N..>
0020  00 CB 01 30 02 3E 12 12 13 10 F4 C1 23 10 EC 18  ...0.>......#...
0030  4A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07  J...............
0040  10 48 C0 04 90 49 00 04 90 49 C0 07 10 48 20 04  .H...I...I...H .
0050  10 49 20 04 1E 30 C0 00 00 00 00 00 00 00 00 00  .I ..0..........
0060  00 00 00 00 00 00 00 00 FF FF 00 00 FF FF 00 00  ................
0070  FF FF 00 00 FF FF 00 00 FF FF 00 3E 01 D3 FE E1  ...........>....
0080  EB 2A 9A 00 4B 44 ED B8 EB CB E5 CB FD E9 00 00  .*..KD..........
0090  18 20 09 FD FC FC 00 20 FF 3F 00 04 03 03 08 01  . ..... .?......
00A0  04 02 0F 03 4A 02 C6 09 EF 3F 00 00 00 00 00 00  ....J....?......
00B0  FF FF F3 F9 ED 5E 7C ED 47 7D D3 E3 3E FF D3 E3  .....^|.G}..>...
00C0  3E 01 D3 E3 3E 7B D3 FB 2A 92 FC CD 0C FD CD 4F  >...>{..*......O
00D0  FD 21 A8 FC ED 4B 9C FC CD 2F FD D9 ED 4B A0 FC  .!...K.../...K..
00E0  CD 2C FD CD 4F FD CB 6F D9 20 05 34 CB 96 18 EB  .,..O..o. .4....
00F0  CD 71 FD CD 71 FD E9 ED A2 FB ED 4D E5 2A 92 FC  .q..q......M.*..
0100  22 90 FC 21 F0 FC 36 FF E1 FB ED 4D F3 22 90 FC  "..!..6....M."..
0110  3E 7F D3 EB 3A 96 FC D3 EB 3E FF D3 F3 3A 97 FC  >..:....>...:..
0120  D3 F3 C9 DB F5 CB 7F 28 FA CB 77 C9 21 AA FC DB  ......(..w.!...
0130  F5 CB 67 20 FA 18 02 4E 23 F3 CD 23 FD 20 22 59  ..g ...N#..#. "Y
0140  0E FD ED 59 10 F1 FB C9 ED 4B 9E FC CD 2F FD 21  ...Y.....K.../.!
0150  B2 FC 06 08 CD 23 FD 28 13 36 FF DB FD 77 23 10  .....#.(.6...w#.
0160  F3 F3 AF 6F 67 F6 C1 D3 FE ED 4F E9 21 B2 FC 7E  ...og.....O.!..~
0170  C9 ED 4B A2 FC CD 2C FD CD 48 FD CB 6F 28 F9 E6  ..K...,..H..o(..
0180  50 20 DE CD 48 FD FE 80 20 F9 DB F5 E6 0F 20 FA  P ..H... ..... .
0190  06 03 D9 ED 4B A4 FC CD 2C FD CD 4F FD E6 C0 D9  ....K...,..O....
01A0  28 04 10 EE 18 BB 21 B5 FC 11 AB FC 01 04 00 ED  (.....!.........
01B0  B0 2B 46 2B 7E 12 C5 AF 32 F0 FC 21 F7 FC CD 0C  .+F+~...2..!....
01C0  FD 23 CB DE ED 4B A6 FC CD 2C FD 2A 98 FC 76 DB  .#...K...,.*..v.
01D0  F5 E6 20 20 F9 22 9A FC 2A 92 FC CD 0C FD CD 4F  ..  ."..*......O
01E0  FD 3A F0 FC B7 C1 28 05 7E E6 D8 28 05 10 C7 C3  .:....(.~..(....
01F0  61 FD 21 AB FC 34 2A 9A FC 22 98 FC 23 C9 00 00  a.!..4*.."..#...
HEXDUMP_TEXT_SAMPLE

echo -e "Converting hexdump text to binary...\n------------------------------------------------"

if [ -f hexdumptxt2bin ]; then

	./hexdumptxt2bin "$1.hexdump"
	[ $? -eq 0 ] || exit 0

else

	# the read command below needed a -r parameter in order to avoid continuing reading into the next line when the current one ends with a "/" character (forward slash).
	# In such a case, loss of binary code occurs...
	i=1	# line counter
	total_hexdump_lines=$(wc -l $1.hexdump | awk '{print $1}')
	echo -n "processing hexdump line: "
	while read -r adr b00 b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 rest; do
		echo -n "$(printf %5d $i) / $total_hexdump_lines"
		for a in $b00 $b01 $b02 $b03 $b04 $b05 $b06 $b07 $b08 $b09 $b10 $b11 $b12 $b13 $b14 ${b15}; do
		echo -n "$a" | xxd -r -p >> "$1.bin"
		done
		let "i = i + 1"
		echo -en "\b\b\b\b\b\b\b\b\b\b\b\b\b"
	done <<EOT
$(cat "$1.hexdump")
EOT

fi

echo -e "  DONE.\n------------------------------------------------"

if [ $first_track -gt 0 ]; then
	echo -e "\nGenerating $(( 9 * $first_track )) KB formatted data block...\n------------------------------------------------"
	dd if=/dev/zero bs=1k count=$(( 9 * $first_track )) | tr '\000' '\345' > SYS.img
	echo -e "  DONE.\n------------------------------------------------\n"
	echo -n "Joining formatted data block with floppy data tracks... "
	cat SYS.img "$1.bin" > "$1.img"
	echo -e "done.\n"
	rm -fv "$1.bin"
else
	mv -f "$1.bin" "$1.img"
fi

#rm -fv "$1.hexdump"
#rm -fv "$1.hexdump.txt"
rm -fv "SYS.img"

echo -e "\nOutput is $1.img"

exit 0