; /-----------------------------------------------------------------------/
; file:		uudecode.s
; function:	Decode something
; opcode:		
; part of:	Infitra
;
; comment:	Experimental
; author:		E Kuik
; /-----------------------------------------------------------------------/

.include "xlib.i"
.include "infitra.i"

.globl Ext_UUDecode
Ext_UUDecode:
	move.l	a0,a2
	Copy_str	a2,#Psource
	Copy_str	a2,#Upath
	bra	Do_decode
.globl UUDecode
UUDecode:
	lea	Upath,a0
	tst.b	(a0)
	bne	ndefp
	Copy_str	#Def_path,#Upath
	Merge_str	#Upath,#uuemask
ndefp:	Xrsc_gaddr #r_frstr,#Select_uuefile,alrt_id,a1
	Xfsel_inp Upath,Name,Psource,(a1),d0
	if_false	d0,Ext_UUE_abort	; No selection
; load the file
Do_decode:
	Fsfirst	#Psource,#0
	tst.l	d0
	bne	Ext_UUE_abort
	Fgetdta
	move.l	d0,a4
	move.l	26(a4),d5		; source file size
	add.l	#2,d5
	Xmalloc	#mx_prefttram,d5,d4
	beq	Xmem_error
	move.l	d4,a5
	Fopen	#0,#Psource
	move.w	d0,d6
	bmi	Fc_err
	Fread	a5,26(a4),d6
	tst.l	d0
	bmi	Xread_error
; now start encoding
	cmp.l	26(a4),d0
	bne	Xread_error
	clr.b	0(a5,d0.l)	; clear byte behind data
	Fclose	d6
; check if its a uuencoded file
	Find_str	#uuestart,a5
Sagain:	bne	NOT_UUE
; check if 'begin' is at line start
	lea	-11(a0),a2	; should be line break
	cmp.b	#13,(a2)
	beq	Correct
	cmp.b	#13,1(a2)
	beq	Correct
	cmp.b	#10,1(a2)
	beq	Correct
	move.l	a0,a2
	Find_str	#uuestart,a2
	bra	Sagain
Correct:	move.l	a0,a2
; get file name, remove leading space and path info (if there)
scan1:	move.b	(a0)+,d0
	beq	NOT_UUE
	cmp.b	#13,d0
	beq	lend1
	cmp.b	#10,d0
	bne	scan1
lend1:	lea	(a0),a3		; here starts the data (almost)
	move.b	#0,-1(a0)
	lea	-1(a0),a0
scan2:	move.b	-(a0),d0
	cmp.b	#$20,d0
	beq	lend2
	cmp.b	#"\",d0
	beq	lend2
	cmp.b	#"/",d0
	bne	scan2
lend2:	lea	1(a0),a2		; hello file name
	Copy_str	a2,#Bname
	Copy_str	#Upath,#Bpath
	End_str	#Bpath,a0
bkscan:	move.b	-(a0),d0
	cmp.b	#"\",d0
	beq	bslf
	cmp.b	#"/",d0
	bne	bkscan
bslf:	move.b	#0,(a0)
	Merge_str	#Bpath,#defmask
re_select:
	Xrsc_gaddr #r_frstr,#Select_binname,alrt_id,a1
	Xfsel_inp Bpath,Bname,Pdest,(a1),d0
	if_false	d0,err		; No selection
	Fsfirst	#Pdest,#0
	tst.l	d0
	bne	Fnexcist
	Alert	alrt_id,#Msg_Ferror3,#1,d0
	cmp.w	#3,d0
	beq	err
	cmp.w	#2,d0
	beq	re_select
	Fdelete	#Pdest
	tst.w	d0
	beq	Fnexcist
	Alert	alrt_id,#Msg_Ferror4,#1,d0
	cmp.w	#1,d0
	beq	re_select
	bra	err
Fnexcist:
	Fcreate	#$20,#Pdest
	move.w	d0,d7
	bmi	Xcreate_error
; adjust data pointer to data start
adj:	move.b	(a3),d0
	cmp.b	#$20,d0
	bge	At_start
	addq.l	#1,a3
	bra	adj
At_start:
	Get_mnutext #MSG_uuencode3,a2
	lea	msg1,a0
	move.l	a2,(a0)
	Get_mnutext #MSG_uuencode2,a2
	lea	msg2,a0
	move.l	a2,(a0)

	moveq	#0,d5		; bin file size
	moveq	#0,d6		; previous size
	move.l	a5,a1		; dest buff
	move.l	a3,a0		; source data
decode:	move.l	d5,d0
	sub.l	d6,d0
	bmi	ndspl
	beq	ndspl
	cmp.l	#8192,d0
	blt	ndspl
	move.l	d5,d6
	movem.l	a0-a1/a5/d5-d7,-(sp)
	Copy_str	msg1,#msg
	End_str	#msg,a0
	move.l	d5,d0
	lsr.l	#8,d0
	lsr.l	#2,d0
	moveq	#10,d1
	jsr	ltoa
	Merge_str	#msg,msg2
	Change_mnutext #msg
	movem.l	(sp)+,a0-a1/a5/d5-d7
ndspl:	bsr	Line_decode
sclend:	move.b	(a0)+,d0
	beq	_NOT_UUE
	cmp.b	#$20,d0
	bge	sclend
sclstr:	move.b	(a0)+,d0
	beq	_NOT_UUE
	cmp.b	#$20,d0
	blt	sclstr
	subq.l	#1,a0
	moveq	#0,d0
	move.b	(a0),d0
	rol.l	#8,d0
	move.b	1(a0),d0
	rol.l	#8,d0
	move.b	2(a0),d0
	and.l	#$00DFDFDF,d0	; to caps
	cmp.l	#"END",d0
	bne	decode
	Fwrite	a5,d5,d7
	tst.l	d0
	bmi	Xcreate_error
	cmp.l	d0,d5
	bne	Xcreate_error
	Fclose	d7
	Mfree	a5
	Def_mnutext
	Return	#true

_NOT_UUE:
	Fclose	d7
	Fdelete	Pdest
NOT_UUE:	Alert	alrt_id,#Not_UUE,#1,d0
	bra	err
Xcreate_error:
	Fclose	d7
	bra	Fc_err
Xread_error:
	Fclose	d6
Fc_err:	Alert	alrt_id,#Msg_Ferror5,#1,d0
err:	Mfree	a5
	bra	Ext_UUE_abort
Xmem_error:
	Alert	alrt_id,#Sysmemerr,#1,d0
Ext_UUE_abort:
	Return	#false



Line_decode:
; get the line length
	moveq	#0,d3
	move.b	(a0)+,d3
	sub.b	#$20,d3		; length of binairy line
	beq	Lready
	bmi	Lready
	add.l	d3,d5		; increase data size
Decode:	moveq	#3,d2
.Decode:	move.b	(a0)+,d1
	beq	.Decode		; null???
	bmi	.Decode		; illigal char!
	cmp.b	#$20,d1
	blt	.Decode		; illigal char!
	rol.l	#8,d0
	move.b	d1,d0
	dbra	d2,.Decode
	sub.l	#$20202020,d0	; remove mask
	moveq	#0,d1
; byte 1
	rol.l	#8,d0
	move.b	d0,d1		; 6 bit byte 1
	lsl.l	#6,d1
; byte 1 & 2
	rol.l	#8,d0
	or.b	d0,d1		; 2 bit byte 1 + 4 bit byte 2
	lsl.l	#6,d1
; byte 2 & 3
	rol.l	#8,d0
	or.b	d0,d1		; 4 bit byte 2 + 2 bit byte 3
	lsl.l	#6,d1
; byte 3
	rol.l	#8,d0
	or.b	d0,d1		; 6 bit byte 3
	rol.l	#8,d1
.rept 3
	rol.l	#8,d1
	move.b	d1,(a1)+
.endm
	subq.l	#3,d3
	beq	Lready		; this line is ready
	bpl	Decode
Lready:	rts

.data
uuemask:	dc.b	"\*.uue",0
defmask:	dc.b	"\*.*",0
uuestart:	dc.b	"begin 644",0

.bss
msg1:	ds.l	1
msg2:	ds.l	1
msg:	ds.b	64
Upath:	ds.b	pathsize
Name:	ds.b	32
Bpath:	ds.b	pathsize
Bname:	ds.b	32
Psource:	ds.b	pathsize+14
Pdest:	ds.b	pathsize+14
