diff --git a/setup/dos2pro.txt b/setup/dos2pro.txt new file mode 100644 index 0000000..19cf44e --- /dev/null +++ b/setup/dos2pro.txt @@ -0,0 +1,124 @@ +#!/bin/bash + +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 + + 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 + + proName=$(sed 's/^[^A-Za-z]/A/' <<< $dosName | sed 's/[^A-Za-z0-9\.]/./g') + + 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 +fi \ No newline at end of file