2015-10-30 12:34:48 +00:00
|
|
|
#! /bin/bash
|
|
|
|
# vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh:
|
2015-10-30 11:05:25 +00:00
|
|
|
|
|
|
|
readcharDec () {
|
|
|
|
# read one character from file & convert to equivalent decimal value
|
|
|
|
# arg1: filename
|
|
|
|
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
|
|
# out: decimal value from 0-255
|
|
|
|
# exit: 8=extraneous arg, 11=missing arg1,
|
|
|
|
# 21=invalid arg1, 22=invalid arg2
|
|
|
|
[[ $1 ]] || return 11
|
|
|
|
[[ $3 ]] && return 8
|
|
|
|
[[ -f $1 ]] || return 21
|
|
|
|
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
|
|
&& ( $2 -ge 0 ) ]] || return 22; }
|
|
|
|
# args are valid
|
|
|
|
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
|
|
|
count=1 2> /dev/null; echo -n X)"
|
|
|
|
[[ ${#charX} -gt 1 ]] || { echo -n 0; return 0; }
|
|
|
|
echo -n "${charX:0:1}" | od -t u1 | \
|
|
|
|
head -1 | sed 's/[0\ ]*//' | tr -d ' \n'
|
|
|
|
}
|
|
|
|
|
|
|
|
readcharHex () {
|
|
|
|
# read one character from file & convert to corresponding hex value
|
|
|
|
# arg1: filename
|
|
|
|
# arg2: (optional) offset (# of bytes to skip before reading)
|
|
|
|
# out: two-digit hex value from 00-FF
|
|
|
|
# exit: 8=extraneous arg, 11=missing arg1,
|
|
|
|
# 21=invalid arg1, 22=invalid arg2
|
|
|
|
[[ $1 ]] || return 11
|
|
|
|
[[ $3 ]] && return 8
|
|
|
|
[[ -f $1 ]] || return 21
|
|
|
|
[[ $2 ]] && { [[ ( $(printf %d "$2" 2> /dev/null) == $2 ) \
|
|
|
|
&& ( $2 -ge 0 ) ]] || return 22; }
|
|
|
|
# args are valid
|
|
|
|
charX="$(dd if="$1" bs=1 skip=$(($2)) \
|
|
|
|
count=1 2> /dev/null; echo -n X)"
|
|
|
|
[[ ${#charX} -gt 1 ]] || { echo -n "00"; return 0; }
|
|
|
|
printf %02X $(echo -n "${charX:0:1}" | od -t u1 | \
|
|
|
|
head -1 | sed 's/[0\ ]*//' | tr -d ' \n')
|
|
|
|
}
|
|
|
|
|
|
|
|
### start
|
|
|
|
|
|
|
|
usage () {
|
|
|
|
echo "Usage:"
|
|
|
|
echo "all files: dos2pro dosImageName"
|
|
|
|
echo "one file : dos2pro dosImageName DOSFILE"
|
|
|
|
echo "notes:"
|
|
|
|
echo " Wildcard matching (*) is not supported."
|
|
|
|
echo " Illegal prodos characters will be made into periods, and names"
|
|
|
|
echo " will be truncated at 15 characters and possibly overwrite"
|
|
|
|
echo " other files if they match a previous name conversion."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
[[ $1 == "-h" || $1 == "--help" || ! $1 || ! -f "$1" ]] && usage
|
|
|
|
|
|
|
|
dosImage="$1"
|
|
|
|
fileName="$2"
|
|
|
|
|
|
|
|
dosImageBasename=$(basename "$dosImage")
|
|
|
|
proImage="${dosImageBasename%.*}_prodos.po"
|
|
|
|
|
|
|
|
if [[ ! -f "$proImage" ]]; then
|
|
|
|
echo "Creating $proImage..."
|
|
|
|
mkpo -b 280 "$proImage"
|
|
|
|
else
|
|
|
|
echo "Found $proImage..."
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ ! $(acmd -i "$dosImage" 2> /dev/null | grep "Disk Format: DOS 3.3") ]]; then
|
|
|
|
echo "The file '$dosImage' doesn't appear to be a DOS 3.3 disk image."
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
dosLines=$(acmd -ll "$dosImage")
|
|
|
|
|
|
|
|
IFS=''
|
|
|
|
while read thisLine; do
|
|
|
|
if [[ ${thisLine:0:2} == "* " || ${thisLine:0:2} == " " ]]; then
|
|
|
|
dosName=$(cut -c 5- <<< $thisLine | rev | sed 's/^[^ ]* [^ ]* [^ ]* [^ ]* [^ ]* \(.*$\)/\1/' | rev)
|
|
|
|
if [[ ! $fileName || "$fileName" == "$dosName" ]]; then
|
2015-10-30 12:38:31 +00:00
|
|
|
|
2015-10-30 11:05:25 +00:00
|
|
|
dosType=$(cut -c 3 <<< $thisLine)
|
|
|
|
if [[ $dosType == "A" ]]; then
|
|
|
|
proType="BAS"
|
|
|
|
binAddr="0801"
|
|
|
|
elif [[ $dosType == "I" ]]; then
|
|
|
|
proType="INT"
|
|
|
|
elif [[ $dosType == "T" ]]; then
|
|
|
|
proType="TXT"
|
|
|
|
elif [[ $dosType == "B" ]]; then
|
|
|
|
proType="BIN"
|
|
|
|
sector=$(rev <<< $thisLine | cut -f2 -d ' ' | rev | cut -c 2-)
|
|
|
|
track=$(rev <<< $thisLine | cut -f3 -d ' ' | rev | cut -c 2-)
|
|
|
|
offset=$(( (track * 16 + sector) * 256 + 12 ))
|
|
|
|
track=$(readcharDec "$dosImage" $offset)
|
|
|
|
sector=$(readcharDec "$dosImage" $((offset+1)))
|
|
|
|
offset=$(( (track * 16 + sector) * 256 ))
|
|
|
|
binAddr=$(readcharHex "$dosImage" $((offset+1)))$(readcharHex "$dosImage" $offset)
|
|
|
|
else
|
|
|
|
echo "Error: Unknown DOS 3.3 file type."
|
|
|
|
exit 2
|
|
|
|
fi
|
2015-10-30 12:38:31 +00:00
|
|
|
|
2015-10-30 11:05:25 +00:00
|
|
|
proName=$(sed 's/^[^A-Za-z]/A/' <<< $dosName | sed 's/[^A-Za-z0-9\.]/./g')
|
2015-10-30 12:38:31 +00:00
|
|
|
|
2015-10-30 11:05:25 +00:00
|
|
|
auxType=
|
|
|
|
[[ $binAddr ]] && auxType="\$$binAddr"
|
|
|
|
echo "Copying '$dosName' to '$proName'"
|
|
|
|
acmd -g "$dosImage" "$dosName" - | acmd -p "$proImage" "$proName" "$proType" "$auxType"
|
|
|
|
filesCopied=1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done <<< $dosLines
|
|
|
|
|
|
|
|
if [[ ! $filesCopied ]]; then
|
|
|
|
if [[ $fileName ]]; then
|
|
|
|
echo "File '$fileName' not found on DOS 3.3 disk image."
|
|
|
|
else
|
|
|
|
echo "No files copied."
|
|
|
|
fi
|
2015-10-30 12:34:48 +00:00
|
|
|
fi
|