[comp.sys.atari.8bit] UUDECODE.LST Version 1.1

jhs@MITRE-BEDFORD.ARPA.UUCP (02/14/87)

Here is an updated version of my UUDECODE program for the Atari 8-bitters.
This version has worked correctly on the few cases I have tried.  Bug reports
will be cheerfully accepted, however.

Version 1.1 differs from 1.0 chiefly in that it will accept a <RETURN> instead
of a filename for the output file when decoding.  In this case it will assume
the device id D1: and will extract the filename, if possible from the "begin"
header line of the file.  If it can't figure out a valid filename, it will
again prompt you for a filename, but since this happens after it has displayed
the "begin" line on the screen, you will at least have a clue as to what might
be a reasonable filename.  (NOTE:  I sidestepped the thorny problem of parsing
filenames by letting the O/S do it:  I used a TRAP statement to tell me that
the O/S didn't like the filename.)

This version will also skip header and trailer text.  This means that you can
uudecode from a message that contains explanatory comments before and/or after
the actual uuencoded data, and uudecode will still produce a correct output
file.  The only requirements are that the uuencoded data must begin with a
"begin" line and end with a line containing a space in the first character
position, followed by a line beginning with "end".

I still have not included the masking that Hans Breitenlohner suggested in the
assembly language routine.  I hope to get to that soon.  Meanwhile, if $60
appears in a uuencoded file that you wish to decode, it will be necessary to
map it into $20.  This can be done for example on unix systems with a "tr"
command.  Also, if the network removes trailing blanks, that may cause
problems.  Sorry for the inconvenience.

I suggest the name UUDECODF.LST rather than UUDECODE.LST ("F" for filename
handling) at least until you decide that you don't need the older version.

Here goes...

-John S.
------------------c-u-t---h-e-r-e---f-o-r---UUDECODF.LST----------------------
1 GOTO 100:REM jump around time-critical stuff to start up program.
2 M=USR(UUDADR)
10 IF M=0 THEN 2090
20 IF M>OBUFDIM THEN ? "Dimension error at line 20":GOTO 3000
30 PRINT #2;OBUF$;:BYTES=BYTES+M
40 INPUT #1,IBUF$:GOTO 2
100 ? "Uudecode Ver. 1.1":? "Report errors to John Sangster at"
101 ? "(617) 235-8753 or jhs@mitre-bedford.arpa":? 
102 REM Modified to count bytes 1/14/86 - JHS
103 POKE 6,1:REM Temporary fix for improved OMNIVIEW/800 compatibility.
104 REM This version modified to take filename from header in .uue file.
105 DIM OBUF$(80),IBUF$(80),OFILE$(16),IFILE$(16),A$(1)
110 DIM UUDECODE$(400),UUENCODE$(400)
120 UUDADR=ADR(UUDECODE$):UUEADR=ADR(UUENCODE$):IBUF=ADR(IBUF$):OBUF=ADR(OBUF$)
130 OBUFDIM=80:UUDDIM=400
500 REM COMMAND DISPATCHER
520 ? "Encode (E) or Decode (D)";:INPUT A$
521 IF A$<>"D" THEN ? "Sorry, Encode not implemented yet!":GOTO 570
530 ? "INPUT FILE";:INPUT IFILE$:IF LEN(IFILE$)=0 THEN 530
540 ? "OUTPUT FILE";:INPUT OFILE$:L=LEN(OFILE$):IF A$<>"D" AND L=0 THEN 540
550 IF A$="E" THEN 1000
555 IF A$="D" AND L=0 THEN OBUF$="D1:"
560 IF A$="D" THEN 2000
570 SOUND 1,25,12,15:FOR I=1 TO 60:NEXT I:SOUND 1,0,0,0:GOTO 520
1000 GOTO 520
2000 ? "Loading UUDECODE subroutine...":REM (general purpose DATA loader)
2001 RESTORE 4000:POKADR=UUDADR:MAXADR=POKADR+UUDDIM-1:PRGTOP=UUDADR-1
2002 READ X:IF X=255 THEN READ X:IF X=255 THEN 2004
2003 ? "BAD LOAD FILE FOR UUD":END 
2004 READ LO1,HI1,LO2,HI2:BYTES=HI2*256+LO2-(HI1*256+LO1)+1:PRGTOP=PRGTOP+BYTES
2005 IF BYTES<0 OR BYTES>UUDDIM THEN ? "BYTE COUNT ERROR FOR UUD":END 
2006 FOR I=1 TO BYTES:READ X:POKE POKADR,X:POKADR=POKADR+1:IF POKADR>MAXADR THEN ? "UUD STRG OVFLOW!":END 
2007 NEXT I
2008 TRAP 2009:READ LO1,HI1,LO2,HI2:BYTES=256*HI2+LO2-(256*HI1+LO1)+1
2009 PRGTOP=PRGTOP+BYTES:IF LO1<>224 OR HI1<>2 THEN 2006
2010 ? "Beginning uudecode processing..."
2011 IBUF$(1,1)=" ":M=USR(UUDADR,IBUF,OBUF):IF M<>0 THEN ? "Error in initializing UUDECODE, line 2011; M=";M:? :END 
2019 CLOSE #1:OPEN #1,4,0,IFILE$
2030 INPUT #1,IBUF$:BYTES=0
2035 L=LEN(IBUF$):IF L>5 THEN L=5
2036 IF L=0 THEN L=1:IBUF$=" "
2040 TRAP 2095:IF IBUF$(1,L)<>"begin" THEN 2030:REM skip header
2042 ? IBUF$:REM Print "begin" line to screen & get OFILE$ if default case.
2044 TRAP 2050:IF LEN(OFILE$)<>0 THEN ? "Using ";OFILE$;" as output file.":CLOSE #2:OPEN #2,8,0,OFILE$:GOTO 40
2046 L=LEN(IBUF$):FOR I=L TO 1 STEP -1
2047 IF IBUF$(I,I)<>" " THEN 2049
2048 OFILE$(4)=IBUF$(I+1,L):GOTO 2044
2049 NEXT I
2050 ? "OUTPUT FILENAME":INPUT OFILE$:IF LEN(OFILE$)=0 THEN 2050
2052 GOTO 2044
2090 INPUT #1,IBUF$:IF IBUF$(1,3)="end" THEN PRINT IBUF$:GOTO 3000
2095 NERR=PEEK(195):IF NERR=136 THEN PRINT "EOF unexpected!":GOTO 3000
2097 ? "Error Code=";NERR
3000 ? "Done!":CLOSE #1:CLOSE #2:? "Output byte count = ";BYTES:END 
4000 DATA 255,255,8,6,3,7
4010 DATA 104,240,67,170,56,233
4020 DATA 2,240,14,104,104,202
4030 DATA 208,251,169,254,133,212
4040 DATA 169,255,133,213,96,104
4050 DATA 141,1,6,104,141,0
4060 DATA 6,104,141,3,6,104
4070 DATA 141,2,6,165,6,240
4080 DATA 100,165,134,133,203,165
4090 DATA 135,133,204,173,2,6
4100 DATA 56,229,140,133,208,173
4110 DATA 3,6,229,141,133,209
4120 DATA 162,128,208,2,240,72
4130 DATA 160,0,177,203,201,129
4140 DATA 208,42,160,2,177,203
4150 DATA 56,229,208,208,33,200
4160 DATA 177,203,229,209,208,26
4170 DATA 165,203,141,6,6,165
4180 DATA 204,141,7,6,160,6
4190 DATA 177,203,141,4,6,200
4200 DATA 177,203,141,5,6,24
4210 DATA 144,22,24,165,203,105
4220 DATA 8,133,203,144,2,230
4230 DATA 204,202,208,192,169,255
4240 DATA 133,212,133,213,96,234
4250 DATA 173,0,6,133,204,173
4260 DATA 1,6,133,205,160,0
4270 DATA 132,213,177,204,56,233
4280 DATA 32,133,212,208,24,165
4290 DATA 6,240,19,173,6,6
4300 DATA 133,208,173,7,6,133
4310 DATA 209,160,4,169,0,145
4320 DATA 208,200,145,208,96,165
4330 DATA 6,240,43,173,4,6
4340 DATA 56,229,212,173,5,6
4350 DATA 229,213,16,9,169,255
4360 DATA 133,212,133,213,32,54
4370 DATA 185,173,6,6,133,208
4380 DATA 173,7,6,133,209,169
4390 DATA 0,160,5,145,208,136
4400 DATA 165,212,145,208,230,204
4410 DATA 208,2,230,205,173,2
4420 DATA 6,133,206,173,3,6
4430 DATA 4,7,102,7,133,207
4440 DATA 166,212,160,1,177,204
4450 DATA 56,233,32,133,203,6
4460 DATA 203,6,203,136,177,204
4470 DATA 56,233,32,6,203,42
4480 DATA 6,203,42,145,206,202
4490 DATA 240,64,169,0,133,208
4500 DATA 160,2,177,204,56,233
4510 DATA 32,74,102,208,74,102
4520 DATA 208,5,203,136,145,206
4530 DATA 202,240,39,160,3,177
4540 DATA 204,56,233,32,5,208
4550 DATA 136,145,206,202,240,24
4560 DATA 24,165,204,105,4,133
4570 DATA 204,144,2,230,205,24
4580 DATA 165,206,105,3,133,206
4590 DATA 144,166,230,207,176,162
4600 DATA 96,224,2,225,2,0