Metropoli BBS
VIEWER: uud20.asm MODE: TEXT (ASCII)
		name	UUD
		page	55,132
		title   'UUDECODE.ASM'
;
; UUDECODE.ASM -- UUDecodes a UUEncoded Binary File
;
; Copyright (C) 1988, by Theodore A. Kaldis
;
; To assemble and link this program into the executable UUDECODE.COM:
; (It will NOT run assembled as an .EXE program!)

;		MASM UUD;
;		LINK UUD;
;		(If you just have EXE2BIN:
;		  EXE2BIN UUD
;		  REN UUD.BIN UUDECODE.COM (or whatever)
;		(If you have Public Domain EXE2COM or equivalent:
;		  EXE2COM UUD
;		  REN UUD.COM UUDECODE.COM (or whatever)
;		(Delete the .OBJ file)

; See version 1.1 for .EXE equivalent.

Comment ~
v2.0, 10 Mar 91
- Keith Petersen says we must handle "begin 0600 foobar.arc" type
  headers .. which we surprisingly can't!
  He found the bug:
|David, I found the bug in TOADUU19's uudecode.  I added one line to the
|source code and changed a comment which said that AH already had a
|space in it.
|
|Here's the fix:
|
|;Put a space into AH for fast comparisons
|	mov	ah,' '
|Strip_Spc:

- He also wanted file overwrite protection like TOADXX, so I added that
  as well.  New command line parm (/o or /O) to force overwrite if
  file exists.  Else abort without overwrite.

- He then found a bug in the "no filename" handling.  I added usage
  before the filename prompt.

- While I'm here, tightened up error msg writing a little (preceding
  and following all msgs with CR/LF, etc.)

v1.8, 5 Jul 89

Thanks to Karl-L. Noell <NOELL%DWIFH1.BITNET@CUNYVM.CUNY.EDU>
for a bug report:

|  When I call up UUE12 or UUD17 without filename, a prompt appears:
|  Input path/file:
|  but answering to that prompt always yields the message
|  "Input file error."

Karl-L's right .. stupid .. donno how I missed it.  Fixed.

Added a little logo at the end (overrun by buffers) just to identify
the program.

Toad Hall
~

;v1.7, 9 Nov 88
; - Versions since 1.3 BROKE (a new Truncated line test).
;   Trying again.
; - Handling headers, tailers, truncated lines ok.
; - Moving some start-up data and code down into buffer space
;   just as an exercise.
; - Previously cut down input buffer size to limit buffer requirements.
;   However, since DOS needs 64Kb to load a .COM file anyway,
;   might as well use the entire 64Kb segment allocated us.

;(notes on versions 1.4 thru 1.6 discarded.)

;v1.3, 7 Sep 88
; - Tightened up seeking for 'begin' and 'end'.
; - Added 'start' error.
; - Tightened up line reading, uudecoding a little.
; - made console/error msgs REALLY go to standard ErrOut device (2)
; - Renamed to UUD13.ASM (differenciate from UUE, UU).

;V1.2, 6 Sep 88
; - Changing to .COM format.
; - moved a bunch of buffers (file names, input and output buffers)
;   to be just pointers at code end (not taking up file space).
; - Reduced max file read from 0FE00H to 0F000H (to stay within 64Kb
;   for program and buffers).

;V1.1, 6 Sep 88
; Toad Hall Tweak
; - General tightening.
; - Added comments.
;
;
; David Kirschbaum
; Toad Hall
; kirsch@braggvax.ARPA

;-------------------------------------------
CR		EQU	0DH
LF		EQU	0AH
SPC		EQU	20H
FALSE		EQU	0
TRUE		EQU	NOT FALSE
;-------------------------------------------
CSEG	SEGMENT PARA PUBLIC 'CODE'
	ASSUME  CS:CSEG,DS:CSEG, ES:CSEG

	org	0
cseg_ofs	label	byte		;fake out MASM			v1.9
	org	80H

cmd_tail	label	byte		;v1.8

	org	100H

;-------------------------------------------
Uudecode	PROC	near
	jmp	Start		;jump over data

;This data will be used during the uudecode run.

err_inp		DB	'Input file error.'
ERR_INP_LEN	EQU	$-err_inp
err_out		DB	'Output file error.'
ERR_OUT_LEN	EQU	$-err_out
err_begin	db	'start not found.'
ERR_START_LEN	EQU	$-err_begin

err_end		DB	'End not found.'
ERR_END_LEN	EQU	$-err_end

exist$		db	' exists. Aborting!'				;v2.0
EXIST$_LEN	equ	$ - exist$					;v2.0

inp_handle	DW	0
out_handle	DW	0
uuptr		DW	UUBUFF		;points at next byte in uuencoded
					; input buffer UUBUFF
uuEndptr	DW	UUBUFF		;points beyond uuencoded data
					; (e.g., buffer end)
outptr		DW	OUT_BUF		;pointer to binary output buffer 
					; (where to stuff NEXT uudecoded byte)

overwrite	db	FALSE		;is set to true for overwriting	v2.0

;-------------------------------------------

Start:
	call	Init			;cmd line parsing, file opening

;v1.7 If we make it back, all's ok.
;We should have input file opened.

	call	Read_File		;do the initial read

Get_Out_Fil:
	mov	di,offset OUT_BUF	;clear DI
	call	Get_Line		;read a line of input

;Look for uuencoded file's 'begin'
;(Don't like this very much .. could be stuck here until we've gone
;through the entire doggone file!  Oh, well ..it works anyway..
;(Also gobbles up any headers or other garbage at file start.)
;Tried a 'CMPSB'  or 'SCASB' of the input buffer against a 'begin'
;in our own code space, but it was a mess!

	lodsw				;snarf 2 plaintext chars
	cmp	ax,'eb'			;'be'?
	jne	Get_Out_Fil		;nope, next line
	lodsw				;next 2
	cmp	ax,'ig'			;'gi'?
	jne	Get_Out_Fil		;nope, next line
	lodsw				;next 2
	cmp	ax,' n'			;'n '?
	jne	Get_Out_Fil		;nope, next line

	mov	di,offset OUT_FIL	;to output buffer

;Put a space into AH for fast comparisons
	mov	ah,' '
Strip_Spc:

;Gobble spaces until we hit the mode number after 'begin'
	lodsb
	cmp	al,ah			;space?
	jbe	Strip_Spc		;gobble spaces, tabs, ctrl chars 

Strip_Num:
;Hit the number, now gobble until the space after number
	lodsb
	cmp	al,ah			;space?
	jne	Strip_Num		;gobble until space

;v1.7 now gobble any spaces between number and name ... sigh ...
Strip_Spc2:
	lodsb
	cmp	al,ah			;space?
	jbe	Strip_Spc2		;gobble until real char

;We should now be at the first char of the original target's filename.
;Move output filename from LINE_IN buffer to our output filename buffer.
;Since LINE_IN has been padded with spaces, a space will indicate
;name end.
Get_Out:
	cmp	al,ah			;space means done
	je	Out_Fin			;yep, name end
	stosb				;input byte > OUT_FIL filename buff
	lodsb				;next filename char
	jmp	Get_Out			;and keep going

;-------------------------------------------
Out_Fin:
	mov	dx,offset OUT_FIL	;output filename buffer
	xor	cx,cx			;normal file attribs (R/W)
	mov	[di],cl			;AsciiZ output filename

;v2.0	User requested overwrite protection for the output filename.
;	Ok .. let's check for output filename existence before we
;	do the create.

	cmp	overwrite,TRUE		;"-o" commandline switch?
	jz	Out_Create		;yep, no checking
 
	mov	ah,4EH			;find first
	int	21H
	cmp	al,2			;file not found?
	jz	Out_Create		;fine, doesn't exist
	cmp	al,18			;no more files to be found?
	jz	Out_Create		;fine

;v2.0 File exists.  Error message, die.
;     DI -> filename AsciiZ 0
;     DX -> filename 1st char

	mov	cx,di			;last char
	sub	cx,dx			;- first char = chars to write
	call	Say_Error		;display filename

	mov	dx,OFFSET exist$	;'File exists'
	mov	cx,EXIST$_LEN		;msg length
	mov	al,5			;fake "Access denied" errorlevel
	jmp	Fatal_Error		;display, terminate


Out_Create:				;v2.0
;End of v2.0 change

	mov	ah,3Ch			;create output file
	int 	21h
	jnc	Out_Open		;went ok
	 jmp	Out_Err			;output file create error


;-------------------------------------------
Out_Open:
	mov	out_handle,ax		;remember output file handle
	mov	di,offset OUT_BUF	;prepare to clear outptr
New_Line:
	call	Get_Line		;read in uuencoded line

;First char is nr of binary bytes used to produce this line. (Asciified)
;If there's an empty last line, it'll just be a space or '`'
	lodsb				;snarf uuencoded binary byte count
	or	al,al			;empty line?
	jz	Prog_End		;yep

	mov	bx,2020H		;a handy constant
	sub	al,bl	;20H		;Deasciify
	or	al,al			;null?
	je	Prog_End		;yep, must be done

;v1.7 keeping line's binary byte count in BP
	xor	ah,ah			;clear msb
	mov	bp,ax			;BP=binary byte count

;uuencoded stuff (input) is in 'quads' (4-char packets),
;binary output is in 'hunks' (3 byte packets)
;4 chars = 3 bytes
NN_0:
	mov	cx,0604H		;handy constant
					;CL=4, CH=6

	lodsb				;quad[1]
	mov	ah,al			;AH=quad[1]
	lodsb				;AL=quad[2]
	mov	dl,al			;save quad[2]
	sub	ax,bx			;remove standard offset

	shl	ah,1			;quad[1] SHL 2
	shl	ah,1			;(faster this way)
	shr	al,cl			;quad[2] SHR 4
	or	al,ah			;shifted quad[2] OR shifted quad[1]
	stosb				;=hunk[1], stuff in OUT_BUF
	dec	bp			;decr binary byte ctr
	jz	New_Line		;uuencoded line is done

	mov	ah,dl			;AH=unshifted quad[2]
	lodsb				;AL=quad[3]
	mov	dl,al			;save quad[3]
	sub	ax,bx			;remove standard offset

	shl	ah,cl			;quad[2] SHL 4
	shr	al,1			;quad[2] SHR 2
	shr	al,1			;(faster this way)
	or	al,ah			;shifted quad[3] OR shifted quad[2]
	stosb				;=hunk[2], stuff in OUT_BUF
	dec	bp			;decr binary byte ctr
	jz	New_Line		;uuencoded line is done

	mov	ah,dl			;AH=unshifted quad[3]
	lodsb				;AL=quad[4]
	sub	ax,bx			;remove standard offset

	mov	cl,ch			;6
	shl	ah,cl			;quad[3] SHL 6
	or	al,ah			;shifted quad[4] OR shifted quad[3]
	stosb				;=hunk[3], stuff in OUT_BUF
	dec	bp			;decr binary byte ctr
	jnz	NN_0			;uuencoded line not done
	jmp	short New_Line		;line done, get new line

;-------------------------------------------
;Now we look for the uuencoded file's 'end'.
;We'll write out what we've got, even if we don't find the 'end'.

Prog_End:
	call	Get_Line		;should be file's last line
	lodsw				;load next 2 chars
	cmp	ax,'ne'			;'en'?
	jne	End_Err_C		;'No end found'
	 lodsb
	 cmp	al,'d'
	 je	File_End		;ok, got the 'end'
End_Err_C:
	call	End_Err			;say we had an end error
File_End:
	call	Write_File		;do our final output write
;Seems there's no need to close files .. DOS must do it!
File_End_X:
	mov	ah,4Ch			;terminate, ERRORLEVEL ?
	int 	21h
Uudecode	endp

;-------------------------------------------
;Reads in a line of uuencoded text
;Didn't like the original logic here (how it physically looks for a CR (0DH)
;as an End of Line indicator (EOL), then gobbles until a LF (0DH).
;Unix text and uuencoded files only have LFs as EOL,
;MACs only have CR EOLs (I think).
;Well, we're handling CR/LF and LF EOLs, and that'll do for now.

;The first char of a uuencoded line is usually an 'M' (ASCII 77).  This is
;the nr of binary bytes used to create this uuencoded line (Asciified).

Get_Line	PROC	NEAR
	mov	si,uuptr		;current raw input buffer psn

;This is looped to (from below) if the line was garbage (e.g., some sort
;of file header.  It refreshes the outbuf pointer to buffer start,
;and sets up the uuencoded line buffer LINE_IN anew.

Flush_Lin:
	mov	outptr,di		;save outbuf ptr in outptr
					;for Write_File test

;BP holds the constant 'maximum line length'.
;I never heard of a uuencode that used lines longer than 60 bytes,
;plus length byte and CR/LF.
	mov	bp,80			;max allowable uuencoded line len 

;Prepare our uuencoded line buffer LINE_IN for transfer of a line.
;Remember, this same sequence is used to get the uuencode protocol's
;first line ('begin 6xx filename.typ'),normal uuencoded lines,
;and the last uuencode protocol line ('end').
;We're preparing an 80-char line (maximum allowed).

	mov	di,offset LINE_IN	;uuencoded line buffer start
	xor	ax,ax
	stosw				;clear first 2 bytes
	mov	cx,(78/2)		;clear remaining 78 bytes	v1.9
	mov	ax,2020H		;fill with spaces
	rep	stosw
	mov	di,offset LINE_IN	;uuencoded line buffer start

Next_Chr:
	cmp	si,uuEndptr		;hit end yet?
	jb	Not_Mt			;not empty yet
	 call	Write_File		;write our binary output (if any)
	 call	Read_File		;read more uuencoded input
Not_Mt:
	lodsb				;snarf uuencoded line char
	cmp	al,96			;special '`' in place of spaces
	jne	Not_Hi			;wasn't a space substitute
	 mov	al,' '			;replace with space
	 jmp	short Was_Space		;and skip the next test

;We check for both CR End-Of_Line (EOL) and LF EOL.			v1.9
;(This handles DOS and Unix files.)

Not_Hi:	cmp	al,CR			;CR means line end
	je	Eol_CR			;end of line, got line
	cmp	al,LF			;How about Unix EOL?
	je	Eol_LF			;Yep, was Unix EOL, got line
Was_Space:
	stosb				;stuff uuencoded line char
	dec	bp			;count down allowable length
	jnz	Next_Chr		;Ok, not yet

;This line is longer than 80 chars, so it CAN'T be a uuencoded line.
;Continue to gobble it up, throwing it away, until EOL,
;then flush and continue.
;This only happens for headers.  We never hit trailers at all.

Strip_Head:
	cmp	si,uuEndptr		;beyond uubuf data?
	jb	Strip_NoRead		;nope
	 call	Read_File		;refill the uubuf
Strip_NoRead:
	lodsb				;look for a LF
	cmp	al,LF			;LF yet?
	jne	Strip_Head		;nope, keep going w/this line

	mov	di,offset OUT_BUF	;clear DI to clear outptr
	jmp	Flush_Lin		;EOL, keep working thru raw
					;input buffer

;-------------------------------------------
;Hit CR, got a uuencoded line (DOS files).
;SI -> LF just past the CR.

Eol_CR:
	inc	si			;bump raw input buffer ptr past LF

;Hit LF EOL (Unix files).
;SI -> next raw buff char.

Eol_LF:
	mov	uuptr,si		;remember current raw buff ptr
	mov	di,outptr		;restore binary output ptr
	mov	si,offset LINE_IN	;ptr to inbuffer start
	ret				;done

Get_Line	ENDP

;-------------------------------------------
;Write a chunk of uudecoded data (if any) to output file.
Write_File	PROC	NEAR

	mov	dx,offset OUT_BUF	;output binary buffer start
	mov	cx,dx			;prepare to reinit outptr
	xchg	cx,outptr		;outptr=output buffer start,
					;CX=outptr
	sub	cx,dx			;-buffer start=buffer byte count 

;IF CX=0, there's no uudecoded data to write, just exit.
;If CX went below 0 (e.g., outptr pointed BELOW OUT_BUF start),
;we have an error of some sort (my code logic?).
;Ignore that also.  It'll get cleaned up later.

	jbe	Write_Good		;error
	 mov	bx,out_handle		;output file handle
	 mov	ah,40h			;write to file/device
	 int 	21h
	 jb	Out_Err			;write error
Write_Good:
	ret				;write done

;Output file write error
Out_Err:
	mov	dx,OFFSET err_out	;'Output file write error'
	mov	cx,ERR_OUT_LEN		;msg length
	jmp	short Fatal_Error	;common code, error value in AL

Write_File	ENDP

;-------------------------------------------
;Read a chunk of input (uuencoded) data into our uuencode buffer.
;I don't think we'll EVER try to read past EOF (since the 'end' line
;should've been detected and program terminated).
;Let's assume that 'read past EOF' is an error of some sort and die.
;('Coding by trial and error')

Read_File	PROC	NEAR

	mov	dx,offset UUBUFF	;read into uuencode input buffer
	mov	cx,offset UU200		;code space - 200H stack bytes
;v1.9	not	cx			;= remaining segment memory
	mov	bx,inp_handle		;input file handle
	mov	ah,3Fh			;read from file/device
	int 	21h
	jb	Inp_Err			;failed
	or	ax,ax			;read anything?
	jz	Read_EOF		;nope, EOF

	mov	si,dx			;point to input UUBUFF start
	add	ax,si			;chars read+UUBUFF start
	mov	uuEndptr,ax		;points beyond last UUBUFF char
	ret				;read done

Read_EOF:

;-------------------------------------------
;Input file read error.  Error value in AL
Inp_Err:
	mov	dx,OFFSET err_inp	;'Input file error'
	mov	cx,ERR_INP_LEN		;msg length
;Common code added here
Fatal_Error:
	push	ax			;save error in AL
	call	Say_Error		;common code
	pop	ax			;restore error in AL
	jmp	File_End_X		;terminate

Read_File	ENDP

;-------------------------------------------
;Unexpected End of File.  (No 'end')
End_Err		PROC	NEAR

	mov	dx,OFFSET err_end	;'End not found'
	mov	cx,ERR_END_LEN		;msg length
Say_Error:				;common code
	push	dx			;v2.0
	push	cx
	mov	dx,offset crlf		;Precede all err msgs w/CR/LF	v2.0
	mov	cx,CRLF_LEN
	call	ErrOut			;display CR/LF
	pop	cx			;restore orig msg len		v2.0
	pop	dx			;ptr to msg			v2.0
	call	ErrOut			;display it
	mov	dx,offset crlf		;Follow all err msgs w/CR/LF	v2.0
	mov	cx,CRLF_LEN

ErrOut:
	mov	bx,2			;Std ErrOut handle
	mov	ah,40h			;write to file/device
	int 	21h
	ret

End_Err		ENDP


;using pointers beyond runtime code and/or code end for various buffers.
;This does NOT take up any space in our program.

		EVEN

;v1.7 LINE_IN is not used until after Init,
;so it can overwrite this code and data.
LINE_IN	equ	$			;80 bytes long

;Some start-up data moved down here to minimize memory requirements.
msg_v1		DB	CR,LF,'This Program Requires DOS Version 2.0 '
		DB      'or higher.'
crlf		db	CR,LF,'$'
CRLF_LEN	EQU	2					;v2.0
pr_inp		DB	CR,LF,'Input path/file:  '
PR_INP_LEN	EQU	$-pr_inp
no_action	db	'No action'
NO_ACTION_LEN	equ	$-no_action

;v1.7 Some start-up code.
Init	proc	near

;First make sure we have DOS 2.0 or higher, or handles won't work.
	mov	ah,30h			;get DOS version
	int 	21h
	cmp	al,2			;2.0 or above?
	jae	Chk_CmdLine		;yep, ok
	 mov	dx,OFFSET msg_v1	;'DOS 2.0 or above'
Msg_Die:
	 mov	ah,9			;display string
	 int 	21h
	 mov	ax,4C01H		;terminate, ERRORLEVEL 1
	 int	21H

;Now check cmd line for uuencoded source file.
Chk_CmdLine:
	call	Parse_CmdLine		;get cmdline target filename	v1.8
	jnc	Open_Inp_Fil		;fine, got one			v1.8
					;DI -> AsciiZed filename
					;0 terminator.

;Let's be nice and prompt the user for an input filename
;v1.8	using normal buffered keyboard input:

;v2.0	First, display usage to the dummy.
	mov	dx,offset usage$	;'Usage: '
	mov	cx,USAGE_LEN		;nr chars to display
	call	Say_Error		;display to STDERR

	mov	dx,OFFSET pr_inp	;'Input/file name:' prompt
	mov	cx,PR_INP_LEN		;nr chars to display
	mov	bx,2			;Std ErrOut handle (always to con)
	mov	ah,40h			;write to file or device
	int 	21h

;Now get the user kbd input:

	mov	di,offset cmd_tail-1	;1 byte before PSP cmdline	v1.8
	mov	byte ptr [di],80	;tell DOS max of 80 chars	v1.8
	mov	dx,di			;DX -> buffer			v1.8
	mov	ah,0AH			;buffered kbd input svc		v1.8
	int	21H
	call	Parse_CmdLine		;parse the input		v1.8
	jnc	Open_Inp_Fil		;got input (already AsciiZed)	v1.8
					;try to open			v1.8
					;DI -> AsciiZ 0			v1.8
;Okay, he doesn't wanna play...
	 mov	dx,offset no_action	;'No action'			v2.0
	mov	cx,NO_ACTION_LEN	;length				v2.0
	mov	al,1			;ERRORLEVEL 1			v2.0
	jmp	Fatal_Error		;display msg, die		v2.0


Open_Inp_Fil:
	mov	dx,offset INP_FIL	;input file name buffer
	mov	ax,3D00h		;open file
	int 	21h
	jb	Open_Die		;failed, terminate w/error
	 mov	inp_handle,ax		;save input file handle
	 ret				;go uudecode

Open_Die:
	 jmp	Inp_Err			;input file open error, die
Init	endp


;v1.8 Command line processing subroutine

Parse_CmdLine	proc	near

	mov	si,offset cmd_tail	;move cmd line parm
	mov	di,offset INP_FIL	;to our filename buffer
	cld				;insure fwd
	lodsb				;cmd line length byte
	or	al,al			;nothing there?
	jz	PC_NoInput		;yep, nothing there

	mov	ah,20H			;get a handy space
Strip_Ct:
	lodsb				;next cmd line char
	cmp	al,ah			;gobble leading spaces,tabs, etc.
	jbe	Strip_Ct
Ct_Char:
	cmp	al,ah			;ctrl char? (e.g., CR)
	jbe	PC_Input		;yep, done

;v2.0	Check for a "-o" switch on command line

	cmp	al,'/'			;this kind of switch?
	jz	GotSwitch		;yep
	 cmp	al,'-'			;switch?
	 jnz	NotSwitch		;nope, must be name char
GotSwitch:
	mov	dx,ax			;save this char a second
	mov	ax,[si]			;snarf next 2 chars
	cmp	al,'?'			;-? or /?			v2.0
	jz	JustHelp		;yep, help and die		v2.0

	and	al,5FH			;mask 1st char to uppercase
	cmp	ax,' O'			;O and space means switch
	mov	ax,dx			;restore in case not
	jnz	NotSwitch		;nope, must be name

;v2.0	We have the overwrite switch

	not	overwrite		;toggle flag to TRUE
	inc	si			;bump past 'o'
	inc	si			;and past space
	lodsb				;next char should be name

NotSwitch:
;end of v2.0 changes
	stosb				;stuff filename byte
	lodsb				;snarf next cmdline char
	jmp	short Ct_Char		;and loop

PC_NoInput:
	stc				;no input, return CF set
	ret

PC_Input:
	mov	byte ptr [di],0		;Asciize filename input
	clc				;got input, return CF clear
	ret

JustHelp:
	mov	dx,offset usage$
	jmp	Msg_Die			;display, terminate

Parse_CmdLine	endp


		EVEN

;INP_FIL is used by Init startup, so it must sit below the code.
INP_FIL	equ	$			;80 bytes long,
					; input filename buffer.
					; Overwrites OUT_FIL buffer
					; and uuencode buffers.

;OUT_FIL, OUT_BUF, and UUBUFF aren't used until AFTER Init completes.
;They can overwrite Init code, startup data, INP_FIL filename buffer, etc.
;However, UUBUFF and LINE_IN ARE used to get the output filename OUT_FIL),
; so UUBUFF and LINE_IN can't overwrite OUT_FIL.

;LINE_IN needs 80 bytes:
OUT_FIL	equ	LINE_IN + 80		;15 bytes long,
					; output filename buffer.
					; Sits below LINE_IN,
					; overwrites Init code/data.
OUT_BUF	equ	LINE_IN + 80		;80 bytes long,
					; uudecoded data buffer.
					; Sits below LINE_IN,
					; overwrites OUT_FIL filename
					; and Init code/data.
;OUT_BUF needs 80 bytes
UUBUFF	equ	OUT_BUF + 80		; uuencoded file read buffer.
					; Sits below OUT_BUF,
					; uses remaining code space.
;UU200	equ	NOT(UUBUFF + 200H)	;200H bytes oughtta be enough	v1.9
UU200	equ	(offset cseg_ofs - offset UUBUFF) - 200H
					;for the stack.

logo	db	'UUDECODE v2.0',0
	db	'Originally by Theodore A. Kaldis',0
	db	'Thoroughly rehacked by David P Kirschbaum, Toad Hall',0

usage$	db	'UUDECODE [-?][-o] [d:][\path\]binary.UUE <RETURN>',CR,LF
	db	'Using the filename.typ in the "begin" line,',CR,LF
	db	'produces uudecoded filename.typ on current drive\path',CR,LF
	db	'(providing filename.typ doesn''t already exist).',CR,LF
	db	'-o switch forces overwrite of existing filename.typ',CR,LF
	db	'-? produces this help message.'

USAGE_LEN	equ	$ - offset usage$
	db	CR,LF,'$'					;v2.0
CSEG	ENDS
	END	Uudecode

[ RETURN TO DIRECTORY ]