#! /bin/bash # vim: set tabstop=4 shiftwidth=4 expandtab filetype=sh: # follows gzip syntax -- acts in place if filename provided, outputs to # stdout with -c, accepts stdin and outputs to stdout if filename is - or absent # output to stdout? if [[ "$1" == "-c" ]]; then shift; stdout=1; else stdout= fi # use stdin? if [[ ! $1 || "$1" == "-" ]]; then stdin=1 stdout=1 elif [[ $1 && ! -f "$1" ]]; then echo "usage: dopo [-c] [-|140KdiskImageFilename] 1>&2"; exit 1; else stdin= fi if [[ ! $stdout ]]; then #get filename extension, in lowercase f="$(tr [:upper:] [:lower:] <<< ${1##*.})"; #if it's dsk/do/po, get name without extension [[ "$f" == "dsk" || "$f" == "do" || "$f" == "po" ]] && of="${1%.*}" || of="$1"; #if name had .po extension, append .dsk to outfile name, otherwise append .po [[ "$f" == "po" ]] && of="$of.dsk" || of="$of.po" # set outfile param for dd ofile="$of" else ofile="/tmp/$$.dopo_out" fi if [[ ! $stdin ]]; then # set infile param for dd ifile="$1" elif [[ -t 0 ]]; then echo "usage: dopo [-c] [-|140KdiskImageFilename]" 1>&2; exit 1; else ifile="/tmp/$$.dopo_in" cat > "$ifile" fi # verify file is 140K by successfully reading 140K'th byte, and failing to read the one past [[ $(dd if="$ifile" of=/dev/null bs=1 skip=143359 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 1 || $(dd if="$ifile" of=/dev/null bs=1 skip=143360 2>&1 | tail -1 | cut -d ' ' -f 1) -ne 0 ]] && badInput=1 || badInput= if [[ $badInput ]]; then if [[ ! $stdin ]]; then echo -n "$1 doesn't appear to be a 140K image. Continue? " 1>&2; read [[ ${REPLY:0:1} == "y" || ${REPLY:0:1} == "Y" ]] || exit 1; else echo "warning: Input file doesn't appear to be a 140K image." 1>&2 echo " Output file is likely to be useless." 1>&2 fi fi # for each track for t in {0..34}; do # read each sector in the right sequence to make (or unmake) # valid ProDOS blocks (sector pairs) for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do # copy the sector from the old file to the new one dd if="$ifile" of="$ofile" bs=256 count=1 skip=$(( t*16 + s )) seek=$(( t*16 + (s==0 || s==15 ? s : 15-s) )) 2> /dev/null done done # remove the old one [[ ! $stdin && ! $stdout ]] && rm "$1" &> /dev/null # dump to stdout if -c or stdin used [[ $stdout ]] && { cat $ofile; rm $ofile &> /dev/null; } [[ $stdin ]] && rm $ifile &> /dev/null;