[comp.sys.cbm] UUENCODE listing

bowen@sunybcs (Devon E Bowen) (01/31/88)

Ok, I guess it's a little longer than 20 lines (it only seemed that long
while I was writing it). But here's the BASIC program I have to uuencode
C64/128 programs. I'm posting it due to its short length and at the request
of a number of people who have contacted me. This code is *far* from
perfect. It is very slow (just be patient with it). Some suggestions as
to how to improve it are:

1) Change the code to read a data file block by block rather than character
   by character. Of course, if you're going to do this, you might as well
   write it in assembly language.

2) Save up an entire line for the output file before writing it. Again,
   don't do it character by character.

3) Compile it!

4) Write it in assembly!!

I guess I should give a little description of how uuencoding works so that
some fun loving programmer can write the uudecode for this (or so that someone
can improve this one). Uuencoding basically consists of taking 3 bytes at a
time and expanding them into 4 printable ascii characters. Since each byte
contains 8 bits there is a total of 24 bits to translate. Since 24 divided
by 4 equals 6, it makes sense to break up the bytes into 6 bit chunks. The
bytes are broken up as:

              b b b b b b b b  b b b b b b b b  b b b b b b b b
                         ^            ^            ^
                char 1       char 2       char 3       char 4

where a "b" represents a bit in each of the 3 bytes. If all the bits for
each character are 0, the character is translated into the ' character.
Otherwise, the character number is added to 32 (decimal) to get a printable
ascii character. These four bytes are then printed to the file. As a matter
of convention, this is done 15 times per line making 45 data bytes encoded
into one 61 character line (The first character of the line is just a
character that tells how many data bytes are in the line. This is usually
an M since there are usually 15 bytes per line and chr$(15 + 32) is an
M). Also given in the file is a header line that contains the word 'begin',
the name of the binary file and the mode it will become (this will usually
be 600 - readable and writable by the user). There is also a final line
with a ' on it signifying a line with 0 bytes and an 'end' line. Well,
that's all there is to it...

If anyone improves this in any way, I'd be interested in the code. Also,
if someone gets a uudecode written, please send me the code. If anyone has
any questions or comments, just send me mail. Enjoy...

				    Devon Bowen (KA2NRC)
				    University of Buffalo

*********************************************************
uucp:	   ..!{ames,boulder,decvax,rutgers}!sunybcs!bowen
Internet:  bowen@cs.Buffalo.EDU
BITNET:    bowen@sunybcs.BITNET
*********************************************************


100 REM  UUECODE BY DEVON BOWEN FOR THE COMMODORE 64/128
110 REM  MUCH WORK IS NEEDED. FEEL FREE TO HACK AND DISTRIBUTE.
120 REM
130 PRINT:PRINT"C64 - UUENCODE"
140 PRINT"--------------":PRINT
150 INPUT"ENCODE WHAT FILE"; F$
160 IF F$="" THEN GOTO 150
170 PRINT"IS IT <S>EQ OR <P>RG? ";
180 GET FT$:IF FT$="" THEN GOTO 180
190 PRINT FT$:IF FT$<>"S" AND FT$<>"P" THEN GOTO 170
200 PRINT
210 INPUT"WRITE IT TO WHAT FILE"; O$
220 IF O$="" THEN GOTO 210
230 PRINT"IS IT <S>EQ OR <P>RG? ";
240 GET OT$:IF OT$="" THEN GOTO 240
250 PRINT OT$:IF OT$<>"S" AND OT$<>"P" THEN GOTO 230
260 PRINT
270 INPUT"WHAT IS THE UNIX NAME"; D$
280 IF D$="" THEN GOTO 270
290 INPUT"WHAT IS THE FILE MODE"; M$
300 IF M$="" THEN GOTO 290
310 DIM BF(50):SU=0
320 OPEN 2,8,2,F$+","+FT$+",R"
330 OPEN 3,8,3,O$+","+OT$+",W"
340 FOR I = 1 TO LEN(D$)
350 E$=E$+CHR$(ASC(MID$(D$,I,1))+32)
360 NEXT
370 PRINT#3,CHR$(98)+CHR$(101)+CHR$(103)+CHR$(105)+CHR$(110);
380 PRINT#3," "+M$+" "+E$+CHR$(13);
390 GOSUB 610
400 C1 = P1 AND 63
410 IF C1 <> 0 THEN C1 = C1 + 32:GOTO 430
420 C1 = 96
430 PRINT#3,CHR$(C1);
440 CO = 1
450 IF CO > P1 THEN 550
460 C(1) = INT(BF(CO)/4)
470 C(2) = INT(BF(CO+1)/16) AND 15
480 C(2) = C(2) OR (INT(BF(CO)*16) AND 48)
490 C(3) = INT(BF(CO+2)/64) AND 3
500 C(3) = C(3) OR (INT(BF(CO+1)*4) AND 60)
510 C(4) = BF(CO+2) AND 63
520 GOSUB 740
530 CO = CO + 3
540 GOTO 450
550 PRINT#3,CHR$(13);
560 IF P1 <> 0 THEN 390
570 PRINT#3,CHR$(101)+CHR$(110)+CHR$(100)+CHR$(13);
580 CLOSE 3
590 CLOSE 2
600 END
610 REM
620 REM   THIS ROUTINE READS DATA FROM THE FILE IN 45 BYTE BLOCKS
630 REM
640 P1 = 0
650 IF SU <> 0 THEN RETURN
660 GET#2,C$
670 SU = ST
680 P1 = P1 + 1
690 IF C$="" THEN BF(P1)=0:GOTO 710
700 BF(P1) = ASC(C$)
710 IF P1 = 45 THEN RETURN
720 GOTO 650
730 REM
740 REM   THIS ROUTINE PRINTS THE CHARACTERS IN THE C ARRAY AFTER
750 REM   RUNNING THEM THROUGH A SIMPLE FORMULA
760 REM
770 FOR I = 1 TO 4
780 C(I) = C(I) AND 63
790 IF C(I) <> 0 THEN C(I) = C(I) + 32:GOTO 810
800 C(I) = 96
810 PRINT#3,CHR$(C(I));
820 NEXT
830 RETURN