**************************************************************************
*		SOURCE DIRECTORY TIDY UPPER!? V.1
*		   BATFINK OF QUARTZ '92
*		FULLY PURE AND REENTRANT CODE!!!			
**************************************************************************
;Asm1.05(T.F.A)

	incdir	df0:include/

	include	exec/exec_lib.i
	
	include	libraries/dos_lib.i
	include	libraries/dosextens.i
	include	libraries/dos.i

Cr=$0a				;Code for case return

CALLOS	MACRO
	jsr	_LVO\1(a6)
	ENDM


	section	tidy,code
		
	move.l	d0,OnIce1
	move.l	a0,OnIce2		;Pull Argv and Argc on ice

	move.l	4,a6
	lea	DosLibName(pc),a1
	moveq	#0,d0			
	CALLOS	Openlibrary		;Open DOS library
	move.l	d0,Dosbase
	bne	Opened_Doslib
	move.l	#RETURN_FAIL,Return			
	bra	No_DosLib

Opened_Doslib:
	move.l	d0,a6
	CALLOS	Output
	move.l	d0,Stndout		;Get handle of console
	bne	Got_Console
	move.l	#RETURN_FAIL,Return	
	bra	No_Doslib		
Got_Console:
	CALLOS	Input
	move.l	d0,StndIn		;Get handle of console
	bne	Got_Console2
	move.l	#RETURN_FAIL,Return	
	bra	No_Doslib		
Got_Console2:

;------------------ PROCESS ARGUMENTS -------------------

	move.l	OnIce1(pc),d0
	move.l	OnIce2(pc),a0

	move.l	d0,d2			;D2 = DOSCMDLEN
	move.l	a0,a2			;A2 = DOSCMDBUF

	move.l	4,a6			;Ask for memory for the arguments
	move.l	#(4*4)+256,d0	
	move.l	#$10000,d1
	CALLOS	Allocmem		
	move.l	d0,Args_Memory
	bne	Args_Mem_Ok
	lea	Error_No_Mem(pc),a0
	bsr	Prtstr			
	move.l	#RETURN_FAIL,Return	
	bra	Exit_Prog

Args_Mem_Ok:
	move.l	d0,a3			;A3 = ARGV SLOTS
	move.l	a3,Argv_Slots
	move.l	d0,a1
	lea	4*4(a1),a1		;A1 = ARG BUFFER
	move.l	a1,Argv_Buffer
	
	lea	0(a2,d2.l),a0		;Null terminate arg, eat CTRL chars
stripjunk:				;yumm,yumm (burp!)
	cmp.b	#' ',-(a0)
	dbhi	d2,stripjunk
	clr.b	1(a0)			;Null terminate
	moveq	#0,d3

New_Arg:				;Start gathering args into buffer
	move.b	(a2)+,d1		
	beq	Parm_Exit
	cmp.b	#' ',d1			
	beq	New_Arg
	cmp.b	#9,d1			
	beq	New_Arg

	cmp.w	#4-1,d3			;Args Overun?
	beq	Parm_Exit

	move.l	a1,(a3)+		;Push adr of parm in argv slot
	addq.w	#1,d3			;Argument count +1
	cmp.b	#'"',d1			;Quotes?
	beq	Do_Quote
	move.b	d1,(a1)+		;Copy char in.
Next_Char:
	move.b	(a2)+,d1		;Null termination check
	beq	Parm_Exit
	cmp.b	#' ',d1
	beq	End_Arg
	move.b	d1,(a1)+
	bra	Next_Char
End_Arg:
	clr.b	(a1)+
	bra	New_Arg			;Next argument
Do_Quote:
	move.b	(a2)+,d1		;Process quotes
	beq	Parm_Exit
	cmp.b	#'"',d1
	beq	End_Arg
	cmp.b	#'*',d1			;* is a BCPL escape char
	bne	addquotechar
	move.b	(a2)+,d1
	move.b	d1,d2
	and.b	#$df,d2
	cmp.b	#'N',d2			;check for DOS newline
	bne	Check_Escape
	moveq	#10,d1			;got *n, turn into a newline
	bra	addquotechar
Check_Escape:
	cmp.b	#'E',d2			;Got *E
	bne	addquotechar
	moveq	#27,d1			;Turn into escape
Addquotechar:
	move.b	d1,(a1)+
	bra	Do_Quote
Parm_Exit:	
	clr.b	(a1)			;All done, null terminate args
	clr.l	(a3)	

;----------------- PRINT TITLE ------------------

	lea	Title(pc),a0
	bsr	Prtstr

;------------------ CHECK ARGUMENTS -------------

	cmp.w	#1,d3			
	beq	Args_Cnt_Valid
	lea	Error_Bad_Syntax(pc),a0
	bsr	Prtstr			;Print correct syntax
	move.l	#RETURN_ERROR,Return	
	bra	Exit_Prog

Args_Cnt_Valid:
	move.l	Argv_Slots(pc),a2
	move.l	(a2),a2			;^ Arg
	move.l	a2,a3
	bsr	LowCase			;Arg To Low Case
	move.l	a3,a0
	bsr	Strlen			;Sizeof Arg?
	lea	(a2,d0.w),a2		;^ E.O Arg
	cmp.b	#'s',-(a2)		;Check For .S suffix
	bne	BadFileName
	cmp.b	#'.',-(a2)
	beq	SuffixOk		
BadFileName:
	move.l	#RETURN_ERROR,Return
	lea	Error_Bad_Syntax(pc),a0	;Print error
	bsr	PrtStr
	bra	Exit_Prog

SuffixOk:
	moveq	#1,d0			
	lea	-1(a2),a0		;^ 0x
	bsr	GetNum
	move.l	d0,d2
	bpl	NumValid
	move.l	#RETURN_ERROR,Return
	lea	Error_Bad_Syntax(pc),a0
	bsr	Prtstr
	bra	Exit_Prog	

NumValid:
	moveq	#1,d0
	lea	-2(a2),a0		;x0
	bsr	GetNum			;Get Nxt Digit
	tst.l	d0
	bmi	ItsAChar
	subq.l	#2,a2			;A2=Start of suffix info e.g (xx,.S)
	mulu	#10,d0
	add.w	d0,d2
ItsAChar:				;D2=File Numbers
	move.w	d2,d7
	subq.w	#1,d7			;D7=Loop
	

;---------- Delete Loop ----------

	move.l	Dosbase(pc),a6
DelLoop:
	move.l	a3,d1			;^ Full FileName		
	CALLOS	DeleteFile
	tst.l	d0			;File Deleted?
	beq.b	.NoFile
	lea	Del_Text(pc),a0		;Print 'deleted:',filename
	bsr	PrtStr
	move.l	a3,a0
	bsr	PrtStr			
	lea	Cr_Text(pc),a0
	bsr	PrtStr

.NoFile:
	subq.w	#1,d2			;File Cnt.-1
	move.w	d2,d0
	cmp.b	#10,d0
	bge.b	.TwoChars
	add.b	#'0',d0
	move.b	d0,(a2)			;x
	move.b	#'.',1(a2)		;Insert .S,0
	move.b	#'s',2(a2)
	clr.b	3(a2)
	bra.b	.DoneDel
	
.TwoChars:
	divu	#10,d0
	add.b	#'0',d0
	move.b	d0,(a2)
	swap	d0
	add.b	#'0',d0
	move.b	d0,1(a2)		;xx
	move.b	#'.',2(a2)		;Insert .S,0
	move.b	#'s',3(a2)
	clr.b	4(a2)

.DoneDel:
	dbra	d7,DelLoop


;---------- Clean Up


Exit_prog:	
	move.l	4,a6			;Free up memory
	move.l	#(4*4)+256,d0	
	move.l	Args_Memory(pc),a1
	CALLOS	Freemem		
	move.l	Dosbase(pc),a1
	CALLOS	Closelibrary	
No_Doslib:
	move.l	Return(pc),d0		;Return code
	RTS				;* EXIT TO DOS *


;--------------------------------------------------------
;| 	PRINT STRING (A0=PTR TO NULL TERMINATED TXT)	|	
;--------------------------------------------------------

Prtstr:	
	movem.l	d2/d3/a6,-(sp)	
	moveq	#0,d3
.Prt1:
	tst.b	(a0,d3.l)		;Char=NULL ?
	beq.s	.Prt2			;Yes then eo txt
	addq.w	#1,d3		
	bra.s	.Prt1				
.Prt2:
	move.l	Dosbase(pc),a6
	move.l	Stndout,d1		
	move.l	a0,d2			;d2=ptr to txt d3=number of chars
	CALLOS	Write			;print message ;;
	movem.l	(sp)+,d2/d3/a6
        RTS

;----------------------------------------------------------------
;|	GET NUMBER (A0=PTR TO STRING D0=NUMBER OF DIGITS)	|
;|	RETURN WITH D0=NUMERICAL VALUE // (-1=Error)		|
;----------------------------------------------------------------

GETNUM:
	movem.l	d3/d7,-(sp)
	moveq	#0,d3		;Clr Error Flag
	tst.l	d0		
	bne.s	.Convert
	moveq	#-1,d0		;Error
	bra.s	.Exit_GetNum
.Convert:
	move.w	d0,d7
	subq.w	#1,d7		;Got Loop
	moveq	#0,d0
.GetDec_Loop:
	moveq	#0,d1
	move.b	(a0)+,d1	
	sub.b	#'0',d1		;Ascii => Numeric
	cmp.b	#10,d1		
	bcs	.Valid_Char
	moveq	#-1,d3		;Set Error
.Valid_Char:
	mulu	#10,d0
	add.w	d1,d0
	dbra	d7,.GetDec_Loop
	tst.l	d3		
	beq.s	.Exit_Getnum	;Error Flag Set?
	move.l	d3,d0		;Pass Return In D0
.Exit_GetNum:
	movem.l	(sp)+,d3/d7
	RTS	

;----------------------------------------------------------------
;|		LOWCASE (C STRING) (A0)				|
;|		CONVERT STRING CHARS ALL TO LOWER CASE.	 	|
;----------------------------------------------------------------

Lowcase:
	move.b	(a0)+,d0		;Get char
	beq.s	.Converted
	cmp.b	#'A',d0
	bcs.s	Lowcase
	cmp.b	#'Z',d0
	bhi.s	Lowcase
	add.b	#'a'-'A',d0
	move.b	d0,-1(a0)		;Put char back
	bra.s	Lowcase			
.Converted:
	RTS				

;--------------------------------------------------------
;|		SIZEOF STRING (C STRING) (A0)		|		
;|		RETURNS STRING LENGTH IN D0		|
;--------------------------------------------------------

Strlen:
	moveq	#0,d0
.Strlen_Loop:
	move.b	(a0)+,d1
	beq.s	.Got_Length
	addq	#1,d0
	bra	.Strlen_Loop
.Got_Length:RTS		

;-------- VARIABLES ---------

Dosbase:		dc.l	0
Stndout:		dc.l	0
StndIn:			dc.l	0
Args_Memory:		dc.l	0
ArgV_slots:		dc.l	0
ArgV_buffer:		dc.l	0
OnIce1:			dc.l	0
OnIce2:			dc.l	0
Return:			dc.l	RETURN_OK
		
DosLibName:	DOSNAME
		even

Error_No_Mem:	dc.b	'Unable to allocate sufficient memory.',cr,0
Del_Text:	dc.b	'Deleted File: ',0
cr_Text:	dc.b	cr,0

Error_Bad_Syntax:
	dc.b	$9b,'1;31;40',$6d,'Syntax:'
	dc.b	$9b,'0;31;40',$6d,' TidySdir <Directory:Filenamexx.S> ',cr,cr
 dc.b 'Function: (Please read TidySdir.doc):',cr
 dc.b 'Deletes all source file revisions below and including version xx',cr
 dc.b 'in the specified directory where xx is an integer between 1 and 99.',cr
 dc.b 'Version numbers can be stated as 0x or x. The .S suffix is essential',cr
 dc.b	cr,0
 
Title:		dc.b	cr,$9b,'0;31;43',$6d
		dc.b	'TidySDir V1.0:'
		dc.b	$9b,'0;31;40',$6d,' Coded By '
		dc.b	$9b,'1;31;40',$6d,'->> BaTfInK <<-'
		dc.b	$9b,'0;31;40',$6d,' Of '
		dc.b	$9b,'3;31;40',$6d,'Quartz.'
		dc.b	$9b,'0;31;40',$6d,cr
		dc.b	'61 Elmete Ave,Sherburn-In-Elmet,Nr Leeds,LS25-6EH,',cr
		dc.b	'ENGLAND. Tel. +44 0977 683578',cr,cr,0

 dc.b	'Hi Binary File Editor Freak!'
 dc.b	'Get A Life And Stop Fucking Around With My Program!.'
	
