#!/bin/bash #================================================================================ # HEADER #================================================================================ # # Sharp Pocket Computer Program Uploader # -------------------------------------- # # by B.Lex, 2017-11-22 # #================================================================================ #% SYNOPSIS #+ ${SCRIPT_NAME} [-vh] [-x|k] [-p sharp-model-#] [-c audio-card-#] [-d audio-dev-#] #% #% DESCRIPTION #% Uploading a SHARP Pocket Computer BASIC program from a PC to the SHARP Pocket Computer. #% #% This script uses Torsten Mücker's Pocket Tools (http://www.peil-partner.de/ifhe.de/sharp/) #% to upload BASIC programs from many SHARP Pocket Computers. #% #% The program will convert the ASCII Basic program to a audiofile (wav) and play it to #% the SHARP cassette interface. #% #% Program upload procedure: #% 1. Start CLOAD on your SHARP Pocket Computer. #% Alternatively CLOAD can also be started on your SHARP after starting the PC script. #% 2. Start the program ${SCRIPT_NAME} on your PC. #% 3. The program will transfer the BASIC program via it's audio interface and the #% SHARP cassette interface to the SHARP Pocket Computer. #% #% REQUIREMENTS #% Hardware: SHARP CE-126P, CE-124 or a compatible cassette interface. #% Software: sox (Sound eXchange); amixer (command-line ALSA mixer) #% #% OPTIONS #% -h print this help #% -v print version information #% -p set model number of Sharp (without "PC-") #% -s skip autosensing of CLOAD (start transfer immediately) #% -c set audio card number (as reported by 'arecord -l') #% -d set audio device number (as reported by 'arecord -l') #% -x don't keep interim files (delete generated img and wav file after uploading) #% -k keep all interim files #% #% Options can be used to override the settings in the configuration file settings. #% #================================================================================ #- IMPLEMENTATION ## version 0.1 #- author Bernhard Lex #- copyright 2017 #- license GNU General Public License #- #================================================================================ # END_OF_HEADER #================================================================================ # --- general variables # program is installed or local INSTALLED=1 # name of configuration file CONFIGFILE="sharppc.cfg" # system's standard configuration directory (applies only when program is installed) CONFIGDIR="/etc" # interim files are kept (this setting can be overruled by config file) KEEPFILES=1 # interim files are saved in /tmp folder; applies only when deletion of interim files is enabled USE_TMPDIR=1 # --- display help functions SCRIPT_HEADSIZE=$(head -200 ${0} |grep -n "^# END_OF_HEADER" | cut -f1 -d:) SCRIPT_NAME="$(basename ${0})" # scriptname without path usage() { printf "Usage: "; head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#+" | sed -e "s/^#+[ ]*//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" ; } usagefull() { head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#[%#+-]" | sed -e "s/^#[%#+-][ ]\?//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" -e "s/\${APPEND}/${APPEND}/g" ; } version() { head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^##" | sed -e "s/^##[ ]*//g" -e "s/[ ]\+/ /g" ; } # if program is installed, config file is found in /etc if [ $INSTALLED -eq 1 ] then CONFIGFILE="$CONFIGDIR/$CONFIGFILE" PROGDIR="" else PROGDIR="./" fi # load config file if [ -f $CONFIGFILE ] then source $CONFIGFILE else echo "Configuration file $CONFIGFILE not found!" exit fi # check if delete-interim-files is set in config # convert DEL_INTERFILES to lower case DEL_INTERFILES=$(echo "$DEL_INTERFILES" | tr '[:upper:]' '[:lower:]') if [[ $DEL_INTERFILES == "yes" ]] then KEEPFILES=0 else KEEPFILES=1 fi # set TMPDIR parameter for mktemp if [ $USE_TMPDIR -eq 1 ] then USE_TMPDIR="--tmpdir" else USE_TMPDIR="" fi # check if CLOAD autosensing is set in config, then convert CLOAD_AUTOSENSE to lower case CLOAD_AUTOSENSE=$(echo "$CLOAD_AUTOSENSE" | tr '[:upper:]' '[:lower:]') # set flag-arguments while getopts :c:d:p:sxkvh option do case "${option}" in c) AUDIOCARD=${OPTARG};; d) AUDIODEVICE=${OPTARG};; p) SHARPPC=${OPTARG};; s) CLOAD_AUTOSENSE="no";; x) KEEPFILES=0;; k) KEEPFILES=1;; v) version exit 0 ;; h) usagefull exit 0 ;; \?) echo "Invalid option: -$OPTARG" >&2 usage exit 1 ;; :) echo "Option -$OPTARG requires an argument." >&2 usage exit 1 ;; esac done shift $((OPTIND-1)) # get the filename argument if [ -n "$1" ] then FILENAME="$1" FILENAME_WO_EXT="${FILENAME%.*}" # check if file is existing if [ ! -e "$FILENAME" ] then echo "File $FILENAME does not exist!" exit 1 fi else #echo "Please provide a filename!" usagefull exit 1 fi # prevent temporary files from overwriting existing files with same name if [ $KEEPFILES -eq 0 ] then # temporary files WAV_FILE=$(mktemp $USE_TMPDIR --suffix=.wav "${FILENAME_WO_EXT}_XXXX") IMG_FILE=$(mktemp $USE_TMPDIR --suffix=.img "${FILENAME_WO_EXT}_XXXX") else # permanent files WAV_FILE="${FILENAME_WO_EXT}.wav" IMG_FILE="${FILENAME_WO_EXT}.img" fi # Set record-level if scontrol mic-name is defined # used only for detecting when CLOAD has been started on SHARP if [ ! -z $MICNAME ] then amixer -c $AUDIOCARD sset $MICNAME $MICLEVEL fi # Set playback-level if scontrol headphone-name is defined if [ ! -z $PLAYNAME ] then amixer -c $AUDIOCARD sset $PLAYNAME $PLAYLEVEL fi # convert ASCII Basic to IMG ${PROGDIR}bas2img -t img -p $SHARPPC "$FILENAME" "$IMG_FILE" # convert IMG to audio ${PROGDIR}bin2wav -t img -p $SHARPPC "$IMG_FILE" "$WAV_FILE" # check if CLOAD autosensing is set if [[ $CLOAD_AUTOSENSE == "yes" ]] then # waiting until CLOAD has been started on SHARP (no file being created) sox -c 1 -e s -t alsa hw:$AUDIOCARD,$AUDIODEVICE -n silence 1 0.1 5% trim 0 0.1 fi # upload file to Sharp sox "$WAV_FILE" -t alsa hw:$AUDIOCARD,$AUDIODEVICE # delete interim files if requested if [ $KEEPFILES -eq 0 ] then rm "$IMG_FILE" rm "$WAV_FILE" fi