[Coco] Printing utility for linux users

Gene Heskett gene.heskett at verizon.net
Fri May 16 06:56:58 EDT 2008


Greetings;

Because many of us do not have decent printers that still understand ascii 
from the coco's we all love, here is a couple of utils that can restore your 
ability to make hard copy of your program listings and such.  And no, I 
didn't write very much of this, a fellow named Jon LaBadie on the amanda-user 
list did 95% of it.  He is a script genius.

The hardware lashup I have setup uses a pair of usb extension cables of the 
sort with a booster hub in the end, 16 feet long cuz my coco is in the 
basement.  The coco's bitbanger port is set for 9600 baud, and in my case I 
had to "tuneport -s=30 /p" to get that baud rate as it was running at about 
13k when an xmode bau=6 had been done.  In my case the cable from /p is 
plugged into a db25 to db9 adaptor, that is plugged into an FDTI based 
usb<->serial adaptor and that adaptor plugged into the end of the USB cable 
that comes up to this machine.  Watch your dmesg when you plug it in and you 
should see a new /dev/ttyUSB# created.

The first one, which is a bash script, can be cut & pasted, and stored 
in /usr/local/libexec.  Then add this line to your /etc/rc.d/rc.local file 
near the bottom:

/usr/local/libexec/cocod </dev/ttyUSB1 &

Change the 1 on the end to make it what you see in dmesg.

Here is the first file, and you will need to do a 'chmod +x' as root on it 
after picking it out of this message.  Save is as 'cocod'
----------------------------------
#!/bin/bash

#### Initialize Variables ####

SEP="<<<END>>>"		# special line indicating the end of a transmitted file
    # output file name

CollectDir=/tmp/CoCo
BaseFN=CoCoFile
SeqNo=0			# start at zero, incremented before first opening

    # input data source

DefDev=/dev/ttyUSB1	# if not given as argument 1 on cmd line
InDev=${1:-${DefDev}}
exec 0< ${InDev}        # changes input for while read inp

    # sub command

CoCoPrCmd=/usr/local/libexec/coco_print

    # timed read constants

MaxTime=10	# seconds
MaxRpts=3	# number of repeat timeouts

#### define functions ####

next_output_file () {
	# deal with currently open tmp file (if any)
	if (( SeqNo > 0 ))
	then
		1>&-	# close stdout (TmpOutFile)
		mv ${TmpOutFile} ${OutFile}
	fi

	# determine name of new tmp file
	SeqNo=$(( SeqNo + 1))
	OutFile=${CollectDir}/${BaseFN}-${SeqNo}
	TmpOutFile=${OutFile}.tmp
	# open/create new tmp file as stdout
	exec 1> ${TmpOutFile}
	StartedWriting=0	# false
	TimeOuts=0
}

next_output_file

%
while :		# infinite loop
do
	# At start of each output file need to do a
	# blocked read, subsequently a timed read
	# Reads are from stdin, the $InDev above
	if (( StartedWriting ))
	then
		IFS= read -t $MaxTime inp
	else
		IFS= read  inp
	fi

	ReadStatus=$?

	# after the above read there are several situations possible
	#   1) read exits 0 (successful)
	#     a) a line of file data was received
	#     b) the special file separator line was received
	#   2) read exits 1 (non-zero, failed)
	#     a) partial line of file data received
	#     b) no file data received
	#     c) EOF meaning communications link was dropped
	#        (not handled in current code)

	if (( ReadStatus == 0 ))
	then				# got a whole line
		if [[ $inp == $SEP ]]
		then
			${CoCoPrCmd} $TmpOutFile &
			next_output_file
		else
			printf "%s\n" "$inp"
			StartedWriting=1
			TimeOuts=0
		fi
		continue
	else				# timeout of read cmd
		if (( ${#inp} > 0 ))
		then			# received part line
			printf "%s" "$inp"	# no \n
			StartedWriting=1
			TimeOuts=0
		else			# no data read in
			TimeOuts=$(( TimeOuts + 1))
			if (( TimeOuts == MaxRpts ))
			then
				${CoCoPrCmd} $TmpOutFile &
				next_output_file
				TimeOuts=0
			fi
		fi
		continue
	fi
done
-----------------------------------------

Now, the $CoCoPrCMD above is also saved in the same location, and here it is.

-----------------------------------------
#!/bin/bash
# the above line is optional since bash called it, a few microseconds faster  
# without it & the rest of these comments.

# child still has $TmpOutFile open as stdout, close it
exec 1>&-   # check syntax for closing a file descriptor

FileToPrint=${1:?need a file name}

if ! [[ -f $FileToPrint ]] || ! [[ -r $FileToPrint ]]
then
        # error handling for missing file
	echo No file to print, sorry. >&2
	exit
fi
# adjust the lp3 below to match your cups setup
lp -d lp3 < $FileToPrint
------------------------

Save this one as coco_print & 'chmod +x' it as root also.

The printer can be located anywhere your cables can reach, in my case I set it 
on the top shelf of my coco's computer desk, and it likewise is hooked up via 
a usb extension cable.  The printer is a band new Brother HL-2140 laser, 
quicker than stink too.  A big buck by the time I get the 20 dollar rebate 
back.  And it gives me better output than even the old daisy wheels did.

One thing of note, it will be nominally one minute after the data stops coming 
in before the printing will be launched, so there is a lag.  This seemed like 
a better idea than modifying everything that can output readable data with an 
<<<END>>> appended as the last line.

And one final item:  You will have to set this virtual serial port over USB to 
the proper parameters, and these work for me.

root at coyote libexec]# stty -F /dev/ttyUSB1
speed 9600 baud; line = 0;
min = 1; time = 0;
-brkint -imaxbel
-opost ocrnl -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

Note in particular the enabled cr to nl translation.  So its not quite 
raw.  "Man stty" will help explain it.

And finally, the usb<->serial adaptor s/b FDTI based, the pl2303 based ones 
from many vendors are at best funkity.  Throwing away data at random seems to 
be their favorite trick.  FDTI stuff Just Works(TM).

Enjoy!

-- 
Cheers, Gene
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
I don't have any solution but I certainly admire the problem.
		-- Ashleigh Brilliant



More information about the Coco mailing list