mirror of
https://github.com/RasppleII/a2cloud.git
synced 2025-01-27 00:32:44 +00:00
Add image utility scripts to archive
This commit is contained in:
parent
7eeed445e5
commit
a2809e85e9
151
docs/ivanx/setup/acmd.txt
Normal file
151
docs/ivanx/setup/acmd.txt
Normal file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
|
||||
decToHex () {
|
||||
# converts single-byte decimal value to hexadecimal equivalent
|
||||
# arg: decimal value from 0-255
|
||||
# out: two-digit hex value from 00-FF
|
||||
#exit: 8=extraneous arg, 11=missing arg, 21=invalid arg
|
||||
[[ $arg1 ]] || return 11
|
||||
[[ $2 ]] && return 8
|
||||
[[ ( $(printf %d "$arg1" 2> /dev/null) == $arg1 ) \
|
||||
&& ( $arg1 -ge 0 ) && ( $arg1 -le 255 ) ]] || return 21
|
||||
# args are valid
|
||||
printf %02X "$arg1"
|
||||
}
|
||||
|
||||
echoerr() {
|
||||
echo "$@" 1>&2;
|
||||
}
|
||||
|
||||
helpExit () {
|
||||
if [[ -s $acmdStdErr ]]; then
|
||||
if [[ $(grep CommandLineHelp $acmdStdErr) ]]; then
|
||||
grep -v ^-[pge][[:space:]] $acmdStdErr | grep -v '^ or' | grep -v 0x2000 1>&2
|
||||
echoerr "-g <imagename> <filename> [<outputFilename>] copy filename out of any"
|
||||
echoerr " disk image. Using - for outputFilename will copy to stdout."
|
||||
echoerr "-e <imagename> <filename> [<outputFilename>] like -g, with conversion"
|
||||
echoerr " to modern file format if possible."
|
||||
echoerr "-p <imagename> <filename> [[$|0x]<type>] [[$|0x]<auxtype>] copy filename"
|
||||
echoerr " into ProDOS disk image. <type> is either three-letter or numeric"
|
||||
echoerr " ProDOS file type (BIN if omitted). Will read from stdin if supplied."
|
||||
echoerr " ProDOS subdirectories in <filename> will be created if needed."
|
||||
echoerr "-c <filename> <imagename> [[$|0x]<type>] [[$|0x]<auxtype>] synonym for -p"
|
||||
echoerr " with filename and imagename reversed."
|
||||
else
|
||||
cat $acmdStdErr
|
||||
fi
|
||||
if [[ $arg1 == "-h" ]]; then
|
||||
exitVal=0
|
||||
else
|
||||
exitVal=1
|
||||
fi
|
||||
else
|
||||
if [[ $vsd1_md5 && ( "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ) ]]; then
|
||||
if [[ "$vsd1_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual.po)" || "$vsd2_md5" != "$(md5sum /usr/local/adtpro/disks/Virtual2.po)" ]]; then
|
||||
echoerr "One of the virtual drive image files has changed while ADTPro server is active."
|
||||
echoerr " If using VSDRIVE, type 'vsdsync' now to see changes and prevent corruption."
|
||||
fi
|
||||
fi
|
||||
exitval=0
|
||||
fi
|
||||
rm $acmdStdErr &> /dev/null
|
||||
exit $exitVal
|
||||
}
|
||||
|
||||
arg1=$1
|
||||
|
||||
acmdStdErr="/tmp/acmd_$RANDOM$RANDOM"
|
||||
|
||||
[[ -f /usr/local/adtpro/adtpro.sh ]] && adtPath="/usr/local/adtpro" || adtPath=$(ls -1d /Applications/ADTPro* | head -1);
|
||||
|
||||
if [[ ! $2 || $arg1 == "-h" ]]; then
|
||||
java -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar 2> $acmdStdErr
|
||||
[[ $? -eq 127 ]] && exit 127 || helpExit $arg1
|
||||
fi
|
||||
|
||||
if [[ $arg1 != "-i" && $arg1 != "-ls" && $arg1 != "-l" && $arg1 != "-ll" && $arg1 != "-x" && $arg1 != "-g" && $arg1 != "-e" && $(ps aux | grep [A]DTPro) ]]; then
|
||||
vsd1_md5="$(md5sum /usr/local/adtpro/disks/Virtual.po)"
|
||||
vsd2_md5="$(md5sum /usr/local/adtpro/disks/Virtual2.po)"
|
||||
fi
|
||||
|
||||
if [[ ( $arg1 == "-p" || $arg1 == "-c" || $arg1 == "-g" || $arg1 == "-e" ) && $2 && $3 ]]; then
|
||||
|
||||
getArg=
|
||||
if [[ $arg1 == "-p" ]]; then
|
||||
prodosArg="$3"
|
||||
imageArg="$2"
|
||||
elif [[ $arg1 == "-c" ]]; then
|
||||
prodosArg="$2"
|
||||
imageArg="$3"
|
||||
elif [[ $arg1 == "-g" || $arg1 == "-e" ]]; then
|
||||
fileArg="$3"
|
||||
imageArg="$2"
|
||||
getArg="$arg1"
|
||||
else
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
if [[ $getArg ]]; then # get file
|
||||
outFile=
|
||||
[[ $3 && $3 != "-" ]] && outFile="$3"
|
||||
[[ ! $3 ]] && outFile="${2##*/}"
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar $getArg "$imageArg" "$fileArg" $outFile 2> $acmdStdErr
|
||||
else # put file
|
||||
|
||||
# test ProDOS name legitimacy
|
||||
prodosPath=$(tr [:lower:] [:upper:] <<< $prodosArg )
|
||||
IFS_orig="$IFS"; IFS="/";
|
||||
prodosPathParts="$prodosPath"
|
||||
for thisProdosPathPart in $prodosPathParts; do
|
||||
if [[ ${#thisProdosPathPart} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $thisProdosPathPart) ]]; then
|
||||
echoerr "Invalid ProDOS name: $prodosPath"; exit 1;
|
||||
fi
|
||||
done
|
||||
IFS="$IFS_orig"
|
||||
|
||||
# process filetype
|
||||
[[ ${3:0:2} == "0x" ]] && ftArg="\$${3:2}" || ftArg="$3"
|
||||
auxType="$4"
|
||||
|
||||
# assume BIN/$2000 if filetype omitted
|
||||
if [[ ! $ftArg ]]; then
|
||||
ft="BIN"
|
||||
auxType="\$2000"
|
||||
# accept hex or decimal number for file type
|
||||
elif [[ ( ${ftArg:0:1} == '$' && ${#ftArg} -eq 3 ) || $(grep [0-9] <<< ${ftArg:0:1}) ]]; then
|
||||
if [[ ${ftArg:0:1} == '$' ]]; then
|
||||
fc=$(tr [:upper:] [:lower:] <<< ${ftArg:1:2})
|
||||
else
|
||||
fc=$(decToHex $ftArg | tr [:upper:] [:lower:])
|
||||
fi
|
||||
P_00=UNK; P_01=BAD; P_02=PCD; P_03=PTX; P_04=TXT; P_05=PDA; P_06=BIN; P_07=FNT; P_08=FOT; P_09=BA3; P_0a=DA3; P_0b=WPF; P_0c=SOS; P_0f=DIR; P_10=RPD; P_11=RPI; P_12=AFD; P_13=AFM; P_14=AFR; P_15=SCL; P_16=PFS; P_19=ADB; P_1a=AWP; P_1b=ASP; P_20=TDM; P_21=IPS; P_22=UPV; P_29=3SD; P_2a=8SC; P_2b=8OB; P_2c=8IC; P_2d=8LD; P_2e=P8C; P_41=OCR; P_42=FTD; P_50=GWP; P_51=GSS; P_52=GDB; P_53=DRW; P_54=GDP; P_55=HMD; P_56=EDU; P_57=STN; P_58=HLP; P_59=COM; P_5a=CFG; P_5b=ANM; P_5c=MUM; P_5d=ENT; P_5e=DVU; P_60=PRE; P_6b=BIO; P_6d=DVR; P_6e=PRE; P_6f=HDV; P_80=GEZ; P_81=GE1; P_82=GEO; P_83=GE3; P_84=GE4; P_85=GE5; P_86=GE6; P_87=GE7; P_88=GE8; P_89=GE9; P_8a=GEA; P_8b=GEB; P_8c=GEC; P_8d=GED; P_8e=GEE; P_8f=GEF; P_a0=WP_; P_ab=GSB; P_ac=TDF; P_ad=BDF; P_b0=SRC; P_b1=OBJ; P_b2=LIB; P_b3=S16; P_b4=RTL; P_b5=EXE; P_b6=STR; P_b7=TSF; P_b8=NDA; P_b9=CDA; P_ba=TOL; P_bb=DRV; P_bc=LDF; P_bd=FST; P_bf=DOC; P_c0=PNT; P_c1=PIC; P_c2=ANI; P_c3=PAL; P_c5=OOG; P_c6=SCR; P_c7=CDV; P_c8=FON; P_c9=FND; P_ca=ICN; P_d5=MUS; P_d6=INS; P_d7=MDI; P_d8=SND; P_db=DBM; P_e0=SHK; P_e2=DTS; P_ee=R16; P_ef=PAS; P_f0=CMD; P_f9=P16; P_fa=INT; P_fb=IVR; P_fc=BAS; P_fd=VAR; P_fe=REL; P_ff=SYS;
|
||||
ftVar="P_$fc";
|
||||
[[ ${!ftVar} ]] && ft=${!ftVar} || ft="\$$fc";
|
||||
else
|
||||
ft="$ftArg"
|
||||
fi
|
||||
|
||||
# set auxtype to $0801 for Applesoft programs if not specified
|
||||
[[ $ft == "BAS" && ! $auxType ]] && auxType="\$0801"
|
||||
|
||||
# test for absence of stdin [[ -t 0 ]] and if absent use ProDOS name
|
||||
if [[ -t 0 ]]; then
|
||||
[[ ! -f $prodosArg ]] && { echoerr "$prodosArg not found."; exit 1; }
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -d "$imageArg" $prodosPath &> /dev/null
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -p "$imageArg" $prodosPath $ft $auxType < $prodosArg 2> $acmdStdErr
|
||||
else
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -d "$imageArg" $prodosPath &> /dev/null
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar -p "$imageArg" $prodosPath $ft $auxType 2> $acmdStdErr
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
imageArg="$2"
|
||||
java -Xmx128m -jar "$adtPath"/lib/AppleCommander/AppleCommander-ac.jar "$@" 2> $acmdStdErr
|
||||
|
||||
fi
|
||||
|
||||
helpExit
|
80
docs/ivanx/setup/dopo.txt
Normal file
80
docs/ivanx/setup/dopo.txt
Normal file
@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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;
|
124
docs/ivanx/setup/dos2pro.txt
Normal file
124
docs/ivanx/setup/dos2pro.txt
Normal file
@ -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
|
160
docs/ivanx/setup/mkpo.txt
Normal file
160
docs/ivanx/setup/mkpo.txt
Normal file
@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ID-bashByter routines
|
||||
|
||||
function binToDec ()
|
||||
{
|
||||
dec=0;
|
||||
bits=$1;
|
||||
while (( ${#bits} < 8 )); do
|
||||
bits="0$bits";
|
||||
done;
|
||||
for n in {0..7};
|
||||
do
|
||||
(( dec+=( ${bits:$n:1} * ( 2**(7-$n) ) ) ));
|
||||
done;
|
||||
echo -n $dec
|
||||
};
|
||||
|
||||
function writecharDec ()
|
||||
{
|
||||
[[ -n $1 ]] || return 11;
|
||||
[[ -n $2 ]] || return 12;
|
||||
[[ -n $3 ]] || return 13;
|
||||
[[ -n $4 ]] && return 8;
|
||||
[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22;
|
||||
[[ ( $(printf %d "$3" 2> /dev/null) == $3 ) && ( $3 -ge 0 ) && ( $3 -lt 255 ) ]] || return 23;
|
||||
echo -n -e "\x$(printf %02X "$3")" | dd of="$1" bs=1 seek=$(($2)) conv=notrunc 2> /dev/null
|
||||
};
|
||||
|
||||
function writecharsHex ()
|
||||
{
|
||||
[[ -n $1 ]] || return 11;
|
||||
[[ -n $2 ]] || return 12;
|
||||
[[ -n $3 ]] || return 13;
|
||||
[[ -n $4 ]] && return 8;
|
||||
[[ ( $(printf %d "$2" 2> /dev/null) == $2 ) && ( $2 -ge 0 ) ]] || return 22;
|
||||
p=0;
|
||||
offset=$2;
|
||||
len=${#3};
|
||||
while (( p < len )); do
|
||||
outByte=${3:$p:2};
|
||||
[[ $(printf %02X "0x$outByte" 2> /dev/null) == $(echo -n "$outByte" | tr [a-z] [A-Z]) ]] || return 23;
|
||||
echo -n -e "\x$outByte" | dd of="$1" bs=1 seek=$offset conv=notrunc 2> /dev/null;
|
||||
(( p += 3 ));
|
||||
(( offset++ ));
|
||||
done
|
||||
};
|
||||
|
||||
# mkpo
|
||||
|
||||
[[ ! -n $1 ]] && { echo "Usage: mkpo [-b totalBlocks] newImageName [PRODOS.VOL.NAME]"; exit 1; };
|
||||
|
||||
[[ -f /usr/local/adtpro/adtpro.sh ]] && adtPath="/usr/local/adtpro" || adtPath=$(ls -1d /Applications/ADTPro* | head -1);
|
||||
[[ ! -d "$adtPath" ]] && { echo "AppleCommander not found."; exit 1; }
|
||||
|
||||
if [[ $1 == "-b" ]]; then
|
||||
totalBlocks="$2"
|
||||
shift
|
||||
shift
|
||||
fi
|
||||
|
||||
[[ -f $1 ]] && { echo "Image '$1' already exists."; exit 1; }
|
||||
|
||||
[[ $2 ]] && prodosVolName="$2" || prodosVolName="UNTITLED"
|
||||
# test ProDOS name legitimacy
|
||||
prodosVolName=$(tr [:lower:] [:upper:] <<< $prodosVolName )
|
||||
if [[ ${#prodosVolName} -gt 15 || ! $(grep ^[A-Z][0-9A-Z\.]*$ <<< $prodosVolName) ]]; then
|
||||
echo "Invalid ProDOS name: $prodosVolName"; exit 1;
|
||||
fi
|
||||
|
||||
# see if nulib2 is available; if so, acmd -convert will create image
|
||||
# with specified block size
|
||||
nulib2 &> /dev/null
|
||||
[[ $? == 2 ]] && nulib2=1 || nulib2=
|
||||
if [[ $nulib2 ]]; then
|
||||
if [[ $totalBlocks ]]; then
|
||||
imageBlocks="$totalBlocks"
|
||||
else
|
||||
if [[ $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then
|
||||
imageBlocks=280
|
||||
else
|
||||
imageBlocks=1600
|
||||
fi
|
||||
fi
|
||||
rm /tmp/blank.shk &> /dev/null
|
||||
orig_dir="$PWD"
|
||||
cd /tmp
|
||||
rm blank.shk EMPTY &> /dev/null
|
||||
touch EMPTY
|
||||
nulib2 -a blank.shk EMPTY &> /dev/null
|
||||
cd "$orig_dir"
|
||||
acmd -convert /tmp/blank.shk "$1" $imageBlocks
|
||||
acmd -d "$1" EMPTY
|
||||
rm /tmp/blank.shk /tmp/EMPTY
|
||||
acmd -n "$1" "$prodosVolName"
|
||||
else
|
||||
# make the disk image without converting archive
|
||||
if [[ $totalBlocks || $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then
|
||||
acmd -pro140 "$1" $prodosVolName;
|
||||
else
|
||||
acmd -pro800 "$1" $prodosVolName;
|
||||
fi
|
||||
fi
|
||||
|
||||
# make the disk bootable
|
||||
if [ -f "$adtPath"/disks/ADTPRO*PO ]; then
|
||||
dd bs=512 count=1 of="$1" conv=notrunc < "$adtPath"/disks/ADTPRO*PO 2> /dev/null
|
||||
fi
|
||||
|
||||
# change .DSK to DOS-ordered
|
||||
if [[ ! $totalBlocks && $(tr [:upper:] [:lower:] <<< "${1##*.}") == "dsk" ]]; then
|
||||
mv "$1" "$1".tmp
|
||||
for t in {0..34}; do
|
||||
for s in 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15; do
|
||||
dd bs=256 count=1 if="$1".tmp of="$1" skip=$(( $t*16 + $s )) seek=$(( $t*16 + ( $s==0||$s==15 ? $s : 15-$s ) )) 2> /dev/null;
|
||||
done;
|
||||
done
|
||||
rm "$1".tmp
|
||||
fi
|
||||
|
||||
# if nulib2 isn't available, patch the disk image to use specified block size
|
||||
if [[ ! $nulib2 && $totalBlocks ]]; then
|
||||
# change total block count
|
||||
bcHex=$(printf "%04X" $totalBlocks);
|
||||
writecharsHex "$1" 1065 "${bcHex:2:2}.${bcHex:0:2}";
|
||||
|
||||
# fix FSB
|
||||
dd if=/dev/zero of="$1" bs=512 seek=280 count=$(( $totalBlocks - 280 )) 2> /dev/null;
|
||||
dd if="$1" of="$1" bs=1 skip=3073 seek=3107 count=$(( ($totalBlocks / 8) - 35 )) conv=notrunc 2> /dev/null;
|
||||
bits=$(( $totalBlocks % 8 ));
|
||||
if (( bits > 0 )); then
|
||||
usedString="00000000";
|
||||
freeString=;
|
||||
for ((b=0; b<$bits; b++))
|
||||
do
|
||||
freeString=$freeString"1";
|
||||
done;
|
||||
binString=$freeString${usedString:$bits};
|
||||
writecharDec "$1" $(( ( ($totalBlocks / 8) - 35) + 3107 )) $(binToDec $binString);
|
||||
fi;
|
||||
|
||||
# assign extra blocks to FSB if needed
|
||||
fsbExtraBlocks=$(( ($totalBlocks-1)/4096 ));
|
||||
if (( fsbExtraBlocks > 0 )); then
|
||||
dd if=/dev/zero of="$1" bs=1 seek=3072 count=$(( (fsbExtraBlocks > 8) + 1 )) conv=notrunc 2> /dev/null;
|
||||
(( fsbExtraBlocks-- ));
|
||||
fi;
|
||||
|
||||
bits=$(( fsbExtraBlocks % 8 ));
|
||||
if (( bits > 0 )); then
|
||||
freeString="11111111";
|
||||
usedString=;
|
||||
for ((b=0; b<$bits; b++))
|
||||
do
|
||||
usedString=$usedString"0";
|
||||
done;
|
||||
binString=$usedString${freeString:$bits};
|
||||
writecharDec "$1" $(( (fsbExtraBlocks>7)+3073 )) $(binToDec $binString);
|
||||
fi;
|
||||
fi
|
24
docs/ivanx/setup/shk2image.txt
Normal file
24
docs/ivanx/setup/shk2image.txt
Normal file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
origDir="$PWD"
|
||||
[[ ! -n $1 || ! -n $2 ]] && { echo "Usage: shk2image archiveFileName imageFileName [PRODOS.DIR.NAME]"; exit 1; };
|
||||
imageFileName="$2";
|
||||
prodosDir="$3";
|
||||
[[ ! -f "$1" ]] && { echo "Archive file '$1' was not found."; exit 1; };
|
||||
[[ ! -f "$imageFileName" ]] && mkpo "$imageFileName";
|
||||
[[ -n $prodosDir ]] && dirName="$prodosDir/" || dirName=;
|
||||
IFS="";
|
||||
[[ ${1:0:1} == "/" ]] && archiveFile="$1" || archiveFile="$origDir/$1"
|
||||
mkdir -p /tmp/shk2image_temp
|
||||
cd /tmp/shk2image_temp
|
||||
shkFiles=$(nulib2 -xse "$archiveFile" | tr "\r" "~" | cut -d "~" -f 2 | cut -c 18-);
|
||||
cd "$origDir"
|
||||
while read thisFile; do
|
||||
fileName=${thisFile%%#*};
|
||||
fileType=${thisFile##*#};
|
||||
echo "extracting $fileName...";
|
||||
acmd -d "$imageFileName" $dirName$fileName &>/dev/null;
|
||||
acmd -p "$imageFileName" $dirName$fileName \$${fileType:0:2} \$${fileType:2:4} < /tmp/shk2image_temp/"$thisFile"
|
||||
rm /tmp/shk2image_temp/"$thisFile"
|
||||
done <<< $shkFiles
|
||||
rm -r /tmp/shk2image_temp
|
Loading…
x
Reference in New Issue
Block a user