;/*
; *		DeluxeDirectory (written by Gerson Kurz)
; *		Asm-One'ified by 2-Cool/EX4
; */
FALSE		=	0
TRUE		=	1

version		MACRO
		dc.b	"3.5."
		ENDM

CALL		MACRO			printf for blank messages only
		IFGT	NARG-1
		move.l	\2,a6
		jsr	_LVO\1(a6)
		ELSE
		jsr	_LVO\1(a6)
		ENDC
		endm
		
PUSHALL		macro
		movem.l	d0-d7/a0-a6,-(sp)
		endm

PULLALL		macro
		movem.l	(sp)+,d0-d7/a0-a6	
		endm

PUSHR		macro
		move.l	\1,-(sp)
		endm

PULLR		macro
		move.l	(sp)+,\1
		endm

MAX_PATHSIZE	equ	1024

		incdir	'include:'
		include	'exec/exec.i'			_LVOxxx for exec.library
		include	'utility/utility.i'
		include	'dos/rdargs.i'			argument parsing
		include	'dos/dosasl.i'			file matching
		include	'dos/datetime.i'		date comparison
		include	'dos/dosextens.i'		filehandler structure
		include	'exec/libraries.i'		for OS2.0 check
		include	'utility/utility.i'
		include	'work:asm-one/include3.1/libraries/dos.i'			_LVOxxx for dos.library
		include	'work:asm-one/include3.1/libraries/dos_lib.i'			_LVOxxx for dos.library
		include	'work:asm-one/include3.1/libraries/utility_lib.i'			_LVOxxx for dos.library
		include	'includes:exec/exec_lib.i'	;_LVOxxx for exec.library

printf		MACRO			printf for blank messages only
		IFGT	NARG-1
		MOVE.L	#\2,D2		= arguments
		ELSE
		MOVEQ	#0,D2		no arguments needed
		ENDC
		MOVE.L	#\1,D1		= string
		PUSHR	a5		since a5 seems to be trashed by this function
		jsr	_LVOVPrintf(a6)	;print string to default output
		PULLR	a5		restore a5
		ENDM


printfc		MACRO
		move.l	#\2,d2
		move.l	#C_\1,d1			;set color message
		move.l	a5,-(sp)	store a5 again
		jsr	_LVOVPrintf(a6)	;print string to default output
		move.l	(sp)+,a5	restore a5
		ENDM

*-------------- Open DOS.LIBRARY for OS2.0 V36 or higher 

Begin:		move.l	4.w,a6				;get execbase
		lea	dos.name(pc),a1			;open dos.library V36++
		jsr	_LVOOldOpenLibrary(a6)		;open library
		move.l	d0,_DOSBase			;save base
		beq.w	DOSError			;yes, send message & quit

		lea	utility.name(pc),a1		;open util.library
		CALL	OldOpenLibrary			;open library
		move.l	d0,_UtilBase			;save base
		beq.w	CloseDOS			;yes, send message & quit

*-------------- Read and parse the arguments from the input stream

		move.l	#arg.template,d1		;template string for arguments
		move.l	#arg.dirs,d2			;first of the flags in a row [see definition]
		moveq	#0,d3				;no optional rdargs
		CALL	ReadArgs,_DOSBase		;read & parse arguments
		move.l	d0,arg.rdargs			;save adress to free memory
		beq.w	dos.error			;yes, display error

		tst.l	arg.help			;help selected ?
		bne.w	help				;yes, show help

*-------------- Check arguments for collisions & init argument defaults

		bsr.w	setupargs			;enter subroutine

*-------------- Setup NEWER/OLDER options if appropriate

		tst.l	arg.newer			;NEWER-keyword there ?
		beq.b	not.newer			;no, cancel

		move.l	arg.newer,a0			;get filename
		bsr.w	open.cmpfile			;open file and get date-string
		cmp.l	#FALSE,d0			;failure ?
		beq.w	dos.error			;yes, show dos-error		
not.newer	
		tst.l	arg.older			;OLDER-keyword there ?
		beq.b	not.older			;no, cancel
		move.l	arg.older,a0			;get filename
		bsr.w	open.cmpfile			;open file and get date-string
		cmp.l	#FALSE,d0			;failure ?
		beq.w	dos.error			;yes, show dos-error		
not.older
*-------------- Get current date [for head-display]

		lea	datetime,a4			;datetime buffer (from datetime.i)
		move.b	#FORMAT_DOS,dat_Format(a4)	;format type = standard DOS
		move.l	#StrDay.msg,dat_StrDay(a4)	;init day-msg
		move.l	#StrDate.msg,dat_StrDate(a4)	;init date-msg
		move.l	#StrTime.msg,dat_StrTime(a4)	;init time-msg
		clr.b	dat_Flags(a4)			;no substitute allowed
		move.l	a4,d1				;get copy to d1
		CALL	DateStamp,_DOSBase		;get current date

		move.l	a4,d1				;get another copy
		CALL	DateToStr			;get string from datestamp
		tst.l	d0				;error ?
		beq.w	dos.error			;yes, quit
		bsr.w	norm.dates			;check for 'DATES/NODATES' options

*-------------- Check SINCE/UPTO options

		tst.l	arg.since			;test SINCE keyword
		beq.b	not.since			;not valid
		move.l	arg.since,a1			;date-string
		bsr.w	get.cmpdate			;get date value
		tst.l	d0				;error ?
		beq.w	date.error			;yes, quit

not.since	tst.l	arg.upto			;test UPTO keyword
		beq.b	not.upto			;not valid
		move.l	arg.upto,a1			;date-string
		bsr.w	get.cmpdate			;get date value
		tst.l	d0				;error ?
		beq.b	date.error			;yes, quit
not.upto	
*-------------- Handle the multiple-directory strings

		move.l	arg.dirs,a4			;multiple DIR-strings
		lea.l	(a4),a0				;get current string
		bsr.w	show.volume			;show directory
		tst.l	(a4)				;are there any more ?
		beq.b	done				;no, done
		tst.l	4(a4)				;are there really no more ?>
		beq.b	done				;no, done
		addq.l	#4,a4				;next string
.loop		lea.l	(a4),a0				;get string
		bsr.w	show.volume			;show directory
		addq.l	#4,a4				;next string
		tst.l	(a4)				;done ?
		bne.b	.loop				;no loop

*-------------- Return to CLI/Shell environment

done		bsr.b	close.args			close parse arguments
		moveq	#RETURN_OK,d0			return value = OK
		rts					done !!

*-------------- Close arguments (routine basically frees all allocated memory )

close.args:	move.l	_DOSBase,d1
		beq.s	CloseUtil			;Is DOS Open
		move.l	d1,a6				;DOSBase in a6

		move.l	arg.rdargs,d1			;arguments
		beq.s	CloseUtil			;no, don't free them
		
		CALL	FreeArgs			;free arguments

CloseUtil:	move.l	_UtilBase,d0
		beq.s	CloseDOS
		move.l	d0,a1
		move.l	4.w,a6
		CALL	CloseLibrary

CloseDOS:	move.l	_DOSBase,d0
		beq.s	DOSError
		move.l	d0,a1
		move.l	4.w,a6
		CALL	CloseLibrary
DOSError:	moveq	#RETURN_FAIL,d0			;return = error
		rts					;done

*-------------- Display error if some date i/o failed

date.error	printf	dateerror.msg			special error message
		bsr.b	close.args			close arguments
		moveq	#RETURN_FAIL,d0			return = error
		rts					done

** Display DOS-error

dos.error	CALL	IoErr,_DOSBase			get io error
		move.l	d0,d1				copy error value
		move.l	#err.head,d2			error header = 'ERROR:'
		CALL	PrintFault			print errorstring

		bsr.b	close.args			close arguments
		moveq	#RETURN_FAIL,d0			return = error
		rts					done

help		printf	help.msg			show help message

		bsr.w	close.args			close arguments
		moveq	#RETURN_OK,d0			return = ok
		rts					done

** Show directory => a0: name of directory/file/pattern

show.volume	PUSHALL					save all registers
		clr.l	NROF_dirs 			clear directory counter
		clr.l	NROF_files			clear file counter
		clr.l	NROF_bytes 			clear byte counter
		clr.l	NROF_blocks			clear block counter
		lea	anchorpath,a1			anchor path
		lea	volname,a1			name of thee volume
		move.l	(a0),a0				get name
.1		move.b	(a0)+,d0			get next char
		move.b	d0,(a1)+			copy char
		bne.b	.1				no, loop
		move.l	#volname,d1			name of thee volume
		move.l	#SHARED_LOCK,d2			lock = shared (we're humble)
		CALL	Lock,_DOSBase			lock volume
		move.l	d0,d6				copy lock
		beq.b	.nodirlock			yes, quit
		move.l	d0,d1				get lock
		move.l	#fileinfoblock,d2		fileinfoblock
		CALL	Examine				examine file
		move.l	d6,d1				get lock
		CALL	UnLock				free lock

** This next part will be a little confusing if you read it, basically I try to
** see if the user specified a PATTERN (e.g. c:a*) or a DIRECTORY (c:). If it
** Is a directory, I have to AddPart a '/#?' to get all entrys of the directory,
** because MatchFirst/MatchNext() will think it has already done its job when it
** finds C:. Got that ??

		lea	fileinfoblock,a0		fileinfoblock 
		move.l	fib_DirEntryType(a0),d0	get type (dir/file)
		btst	#31,d0				=negative ?
		beq.b	.3				yep, is a directory
.nodirlock	lea	anchorpath,a0			anchor path
		move.l	a0,d2				get it
		move.l	#SIGBREAKF_CTRL_C,ap_BreakBits(a0) set breakbit = CTRL-C
		move.l	#volname,d1			name of volume
		CALL	MatchFirst			get first match
		tst.l	d0				test if error
		bne.w	vol.matcherror			yes, quit

		lea	anchorpath+ap_Info+fib_FileName,a0 get filename (rather volumename)
		tst.b	(a0)				is it there ?
		bne.b	.2				yo! continue
		move.l	#anchorpath,d1			else get path
		CALL	MatchEnd			and free it

.3		move.l	#volname,d1			volumename
		move.l	#addpart.msg,d2			'/#?',0
		move.l	#MAX_PATHSIZE,d3		maximum path = 1024
		CALL	AddPart,_DOSBase		here it is !
		cmp.l	#DOSFALSE,d0			error ?
		beq.w	vol.doserror			yep, quit

		lea	anchorpath,a0			anchorpath
		move.l	a0,d2				get a copy
		move.l	#SIGBREAKF_CTRL_C,ap_BreakBits(a0) set break = CTRL_C
		move.l	#volname,d1			name of volume
		CALL	MatchFirst,_DOSBase		find first match
		tst.l	d0				error ?
		bne.w	vol.matcherror			yo once again quit

.2		lea	volname,a0			name of volume
		move.l	#MAX_PATHSIZE-1,d0		size = 1024
.clearpath	clr.b	(a0)+				clear string
		dbra	d0,.clearpath			continue looping

** Now, we get the full pathname of the volume

		lea	anchorpath,a0			Path
		move.l	ap_Current(a0),a0		ptr to current item
		move.l	an_Lock(a0),d1			lock
		move.l	#volname,d2			name which will contain the path
		move.l	#MAX_PATHSIZE,d3		maximum = 1024
		CALL	NameFromLock,_DOSBase		get name from lock
		tst.l	d0				error ?
		beq.w	vol.doserror			yes, done

		jsr	GETDISKINFO			get INFO-like stuff

** Finally we start displaying ! (Yipee!)

		st.b	rowcount			rowcount = 1..3 etc
showdirectory	lea	(anchorpath),a4			anchorpath

** Check if HIDDEN-bit is set

		move.l	ap_Info+fib_Protection(a4),d0	get protection
		btst	#7,d0				check if hidden
		beq.b	.not.hidden			no, continue
		tst.l	(arg.nohidden)			dow have to ch
		bne.w	continue			no,continue
.not.hidden	

** Check if it is a Directory

		move.l	ap_Info+fib_DirEntryType(a4),d0 get entry type 
		clr.b	dirflag				not a directory [=default]
		btst	#31,d0				is negative ?
		bne.b	.1				yo, it's no directory
		move.b	#1,dirflag			else set flag
.1

** Now for several time-checks !

timecheck	tst.l	arg.today			TODAY keyword
		beq.b	.not_today			not specified
		bsr.w	checkdates			compare dates
		bne.w	continue			not equal => abort
.not_today	tst.l	arg.since			SINCE keyword
		beq.b	.not_since			not specified
		bsr.w	checkdates2			compare dates
		blo.w	continue			less => abort
.not_since	tst.l	arg.upto			UPTO keyword
		beq.b	.not_upto			not specified
		bsr.w	checkdates2			compare dates
		bhi.w	continue			higher => abort
.not_upto	tst.l	arg.newer			NEWER keyword
		beq.b	.not_newer			not specified
		bsr.w	checkdates2			compare dates
		blo.w	continue			less => abort
.not_newer	tst.l	arg.older			OLDER keyword
		beq.b	.not_older			not specified
		bsr.w	checkdates2			compare dates
		bhi.w	continue			higher => abort
.not_older

** Now for some thing which could be placed somewhere else,too but well,
** it's here and who cares anyway ?!

setreturn	lea	anchorpath,a4 			anchorpath
		lea	ap_Info+fib_FileName(a4),a1	get filename
		move.l	a1,(filename)			save if !!

		tst.l	arg.all				test if argument = all
		beq.w	nextfile			no, continue examination

** Yo, and here is the ALL-section, which needs some treatment with MatchNext()..

		tst.b	dirflag				is it a dir ?
		beq.w	nextfile			no, well done!

		bsr.w	getfull.fname			get full pathname

** Handle DIDDIR (directory has just been done, returning to parent level)

		move.b	ap_Flags(a4),d0			get anchorpath flags
		btst	#APB_DIDDIR,d0			DIR just DONE
		beq.b	apy				no, continue
		PUSHR	d0				save flags
		tst.l	arg.fullpath			fullpath ?
		bne.b	not1				yep, no need for [>(path)]
		tst.l	arg.list			list option ?
		bne.b	l1				no, display normal type
		bsr.w	checkdir.return			check for return

		printfc	diddir.msg2,filename
						;print norm-style message
		bra.b	not1				continue

l1		printfc	diddir.msg,filename		else print list-style
not1		PULLR	d0				restore flags
		bra.b	y2				continue

** DODIR says that we want to examine this directory (some strange guys will
** want to include a possible 'ASK' option here, but well it's YOUR problem really..

apy		bset	#APB_DODIR,d0			set flag = DODIR
		PUSHR	d0				save flags
		addq.l	#1,NROF_dirs			more of those dirs 
		tst.l	arg.fullpath			fullpath ?
		bne.b	yshow2 				yes, show it !
		tst.l	arg.list			list ?
		bne.b	yl2				yes, show it
		bsr.w	checkdir.return			else (possible) return
		printfc	dodir.msg2,filename		print [>(path)]
		bra.b	ynot2				continue
yshow2		printfc	fndir.msg,filename		special for 'fullpath all' mode
		bra.b	ynot2				continue
yl2		printf	dodir.msg,filename		print list-type 
ynot2		PULLR	d0				restore flags
y2		bclr	#APB_DIDDIR,d0			set flag [ so no errors ]
		move.b	d0,ap_Flags(a4)			save flags
		bra.w	nofileinfo			continue

** Analyze Flags

nextfile	

** Handle FILES/DIRS options

		tst.l	arg.filesonly			FILES option ?			
		beq.b	.1				no, continue
		tst.b	dirflag				chk if we have a directory
		bne.w	continue			yes, continue
.1		tst.l	arg.dirsonly			DIRS option ?			
		beq.b	.2				no, continue
		tst.b	dirflag				chk if we have a directory
		beq.w	continue			no, continue
.2

** Handle the LARGER/SMALLER options

		move.l	ap_Info+fib_Size(a4),d0		get size of file
		tst.l	arg.larger			LARGER option ?
		beq.b	not.larger			no continue
		move.l	arg.larger,a0			get argument
		move.l	(a0),d1				get argument size
		cmp.l	d1,d0				compare with current size
		bls.w	continue			quit if LARGER			
not.larger	tst.l	arg.smaller			SMALLER option ?
		beq.b	not.smaller			no continue
		move.l	arg.smaller,a0			get argument
		move.l	(a0),d1				get argument size
		cmp.l	d1,d0				compare with current size
		bhs.w	continue			quit if SMALLER			
not.smaller

** Display HEAD-message if appropriate

		tst.b	anyentry.flag			already HEADed ?
		bne.b	head.is.there			yo, continue
		printfc	head.msg,headname		print HEAD-msg
		st.b	anyentry.flag			set HEADed flag
head.is.there

** Display [RETURN] if needed

		tst.l	arg.fullpath			FULLPATH ?
		bne.b	.noreturn			yo, we don't need RETURNs
		addq.b	#1,rowcount			next row
		move.b	maxrows,d0			maxrows 
		cmp.b	rowcount,d0			compare ?
		bne.b	.noreturn			not yet
		clr.b	rowcount			reset
		printf	return.msg			print RETURN
.noreturn	

** Update counters for files,dirs,blocks and bytes (what's missing ? yes, BLEEPS! are missing)

		move.l	ap_Info+fib_NumBlocks(a4),d0	nr of blocks
		add.l	d0,NROF_blocks			shit I only got damn 68000
		move.l	ap_Info+fib_Size(a4),d0	size of the entry
		add.l	d0,NROF_bytes			add to total bytes
		tst.b	dirflag				is it a dir ?
		bne.b	.is.a.dir			yo 
		addq.l	#1,NROF_files			add nr of files
		bra.b	.is.nothing			continue
.is.a.dir	addq.l	#1,NROF_dirs			else add nr of dirs
.is.nothing	

** Do according to the type-flags (VERBOSE,SHORT,LIST or 'NORMAL')
		
		tst.l	arg.verbose			verbose ?
		bne.w	verbose.display			yes -> display verbose action
		tst.l	arg.short			short ?
		bne.w	short.display			yes -> display short action
		tst.l	arg.list			list ?
		bne.w	list.display			yes -> display list action

** 'NORMAL' display (not supplied as keyword really, this is the default choice

** (Note that the code may look a little bit confusing but a) you should know that
** by now, and b) I did it step after step so there are some -eh- inconsistencys

** (Hey, be glad that I commented this one! Just a few years ago I used not only
** to reduce my comments to lyrics from the songs I listend to while coding, I
** also used labels like 'OIUsXOJ' and 'shitFUCK' (case sensitive, of course)
** [and of course didn't use INCLUDEs but absolute hex offsets...] haha)

** (This is a nested IF-THEN-ELSE construct anyway)

		move.l	ap_Info+fib_Size(a4),filesize	; get size of thee file
		tst.l	arg.fullpath			is it full-path type ?
		bne.b	.fullpath.norm			yes, the show it
		tst.b	dirflag			directory ?
		bne.b	.1				yes, show it
		printf	nfile.msg,filename		display file
		bra.w	continue			done
.1		printfc	ndir.msg,filename		display directory
		bra.w	continue			done
.fullpath.norm	bsr.w	getfull.fname			get full pathname
		tst.b	dirflag			directory ?
		bne.b	.2				yes, show it
		printf	fnfile.msg,filename		display file
		bra.w	continue			done
.2		printfc	fndir.msg,filename		display directory
		bra.w	continue			done

** SHORT display
	
short.display	tst.b	dirflag			directory ?
		bne.b	.1				yes, show it
		printf	sfile.msg,filename		display file
		bra.w	continue			done
.1		printfc	sdir.msg,filename		display directory
		bra.w	continue			done

** LIST-lookalike display

list.display	bsr.w	getextinfo.1			get list-info
		tst.l	arg.fullpath			FULLPATH ?
		bne.b	.fullpath.list			yo, bring the noise
		tst.b	dirflag				directory ?		
		bne.b	.1				yes, show it
		printf	lfile.msg,filename		display file
		bra.w	.continue.list			done
.1		printfc	ldir.msg,filename		display directory
		bra.b	.continue.list			done
.fullpath.list	bsr.w 	getfull.fname			get full pathname
		tst.b	dirflag				directory ?
		bne.b	.2				yes, show it
		printf	flfile.msg,filename		display file
		bra.b	.continue.list2			continue
.2		printfc	fldir.msg,filename		display directory [this construct isn't 'clean' but it works]
.continue.list2	printfc	flinfo.msg,protstring		print info message
		tst.l	comment				comment ?	
		beq.w	continue			no continue
		printfc	fcomment.msg,comment		print comment
		bra.w	continue			continue

.continue.list	printfc	linfo.msg,protstring		protection ?
		tst.l	comment				comment ?	
		beq.w	continue			no continue
		printfc	comment.msg,comment		print comment
		bra.w	continue			continue

** VERBOSE-type display

verbose.display	bsr.w	getextinfo.1			get extended information

		lea	anchorpath,a4				;anchorpath
		move.l	ap_Info+fib_EntryType(a4),v_entrytype	; type of entry
		move.l	ap_Info+fib_DiskKey(a4),v_diskkey	; blockheader for entry

		bsr.w 	getfull.fname			get fullpath [default for VERBOSE]
		tst.b	dirflag 	       	    	directory ?		
		bne.b	.2				yes, show it
		printf	flfile.msg,filename		display file
		bra.b	.1				done
.2		printfc	fldir.msg,filename		display directory
.1		printfc	fvinfo.msg,protstring2		print x-tended information
		tst.l	comment				comment ?	
		beq.b	continue			no continue
		printfc	fcomment.msg,comment		print comment
		bra.w	continue			continue

continue

** Get next file

nofileinfo	move.l	#anchorpath,d1			get match-anchor 
		CALL	MatchNext,_DOSBase		next file
		tst.l	d0				error ?
		beq.w	showdirectory			no continue [this seems a strange returncode but it's true!]
		PUSHR	d0				save error code
		tst.l	arg.fullpath			FULLPATH ?
		bne.b	.noreturn			no, continue
		tst.b	anyentry.flag			any entry displayed ?
		beq.b	.noreturn			no, continue
		printf	return.msg			RETURN!
.noreturn	PULLR	d0				get error code
		cmp.l	#ERROR_NO_MORE_ENTRIES,d0	is it 'end of directory'
		bne.b	vol.matcherror			no, error !

** Quit subroutine

		move.l	#anchorpath,d1			match-anchor
		CALL	MatchEnd,_DOSBase		close it [freemem]
		tst.b	anyentry.flag			have there been any entrys ?
		beq.b	match				no, continue
		printfc	volinfo.msg,NROF_files		display info message
		bra.s	match2				continue
match:		printf	vol_noentry.msg,headname	print fault message
match2:		PULLALL					;restore registers
		rts					return


** Display DOS-Errormsg

vol.doserror	CALL	IoErr,_DOSBase			get IOerror
vol.matcherror	move.l	d0,d1				copy
		move.l	#err.head,d2			header ='ERROR:'
		CALL	PrintFault,_DOSBase		print error message
		PULLALL					restore registers
		rts					return

** Get ExtendedInformation #1

getextinfo.1	PUSHALL						;store registers
		move.l	ap_Info+fib_Size(a4),filesize		;size of file
		move.l	ap_Info+fib_NumBlocks(a4),nrofblocks	;nr of blocks
		move.l	ap_Info+fib_NumBlocks(a4),nrofblocks2	;copy #2
		move.l	ap_Info+fib_Protection(a4),d0		;protection 
		bsr.w	get.protstring			=> protection string

		lea	datetime,a0			date/time struct
		move.l	a0,d1				copy
		lea	ap_Info+fib_DateStamp(a4),a1	date of current entry
		move.l	(a1)+,(a0)+			copy days
		move.l	(a1)+,(a0)+			copy minutes
		move.l	(a1)+,(a0)+			copy tickx
		bsr.b	norm.dates			normative dates
		CALL	DateToStr,_DOSBase		get date/time string

		clr.l	comment				no comment [default]
		lea	ap_Info+fib_Comment(a4),a1	get comment string
		tst.b	(a1)				is there any ?
		beq.b	.nocomment			no,continue
		move.l	a1,comment			save comment
.nocomment	PULLALL					restore registers
		rts					return

** Set norm dates [handle DATES/NODATES option]

norm.dates	PUSHR	a0				save a0
		lea	datetime,a0			get date/time struct
		move.b	#DTB_SUBST+DTB_FUTURE,dat_Flags(a0) ;normal = substitute
		tst.l	arg.dates			test DATES
		beq.b	.1				not selected
		clr.b	dat_Flags(a0)			no substitution
.1:		PULLR	a0				restore a0
		rts					return


* This section deals with the argument conflict resolving. I don't comment
* it because a) I'm bored, b) it's 1.00 AM and c) you know it anyway

; 		argument hierarchy :
;		~~~~~~~~~~~~~~~~~~~~
;		1. fullpath
;		2. all
; 		3. verbose	x
;		4. list		x (all three mutual exclusive)
;		5. short	x
;		6. normal	x
;		7. all comparison flags, dont conflict with any of the above

;		further collisions :
;		~~~~~~~~~~~~~~~~~~~~
;		ALL<>(SHORT,NORMAL)
;		FULLPATH<>(SHORT,NORMAL)
;		HIDDEN<>NOHIDDEN
;		COLOR<>NOCOLOR
;		DATES<>NODATES
	
setupargs	tst.l	arg.fullpath
		beq.b	.not.fullpath
		clr.l	arg.short

.not.fullpath	tst.l	arg.all
		beq.b	.not.all
		clr.l	arg.short

.not.all	tst.l	arg.verbose
		beq.b	.not.verbose
		move.l	#1,arg.list
		move.l	#1,arg.fullpath
		clr.l	arg.short
		bra.b	setuprows

.not.verbose	tst.l	arg.list
		beq.b	setuprows
		clr.l	arg.short

setuprows	move.b	#3,maxrows
		tst.l	arg.short
		beq.b	.1

		move.b	#4,maxrows
.1:		tst.l	arg.list
		beq.b	.2
		move.b	#1,maxrows
.2:		tst.l	arg.fullpath
		beq.b	.4
		move.b	#1,maxrows
.4		tst.l	arg.since
		beq.b	.5
		clr.l	arg.upto
.5		tst.l	arg.smaller
		beq.b	.6
		clr.l	arg.larger
		move.l	#1,arg.filesonly
.6		tst.l	arg.larger
		beq.b	.7
		move.l	#1,arg.filesonly
.7		tst.l	arg.nohidden
		beq.b	.8
		clr.l	arg.hidden
.8		tst.l	arg.nodates
		beq.b	.9
		clr.l	arg.dates
.9		tst.l	arg.nocolor
		beq.b	.10
		clr.l	arg.color
.10		rts

** This subroutine analyzes the packet protection and copies it to thee protection string

get.protstring	movem.l	d0/a0-a1,-(sp)
		lea	protstring.data,a0
		move.l	a0,a1
		move.l	#"----",(a1)+
		move.l	#"----",(a1)+
		btst	#7,d0
		beq.b	.7
		move.b	#'h',(a0)
.7		btst	#6,d0
		beq.b	.6
		move.b	#'s',1(a0)
.6		btst	#5,d0
		beq.b	.5
		move.b	#'p',2(a0)
.5		btst	#4,d0
		beq.b	.4
		move.b	#'a',3(a0)
.4		btst	#3,d0
		bne.b	.3
		move.b	#'r',4(a0)
.3		btst	#2,d0
		bne.b	.2
		move.b	#'w',5(a0)
.2:		btst	#1,d0
		bne.b	.1
		move.b	#'e',6(a0)
.1:		btst	#0,d0
		bne.b	.10
		move.b	#'d',7(a0)
.10		movem.l	(sp)+,d0/a0-a1
		rts

** Get full pathname from a lock

getfull.fname	PUSHALL					store all registers
		lea	anchorpath,a0			anchor path
		move.l	ap_Current(a0),a0		current entry
		move.l	an_Lock(a0),d1			current lock
		move.l	#volname,d2			name to hold path
		move.l	#MAX_PATHSIZE,d3		size of buffer
		CALL	NameFromLock,_DOSBase		get name from lock

		move.l	#volname,d1			name to hold path
		lea	anchorpath,a0			anchor path
		lea	ap_Info+fib_FileName(a0),a0	filename
		move.l	a0,d2				get a ptr to tha filename
		move.l	#MAX_PATHSIZE,d3		size of buffer
		CALL	AddPart				get filename + volume = full path

		move.l	#volname,filename		store it to a internal pointer
		PULLALL					restore registers
		rts

checkdir.return	cmp.b	#-1,(rowcount)
		beq.b	.1
		printf	return.msg
		st.b	(rowcount)
.1:		rts
	
get.cmpdate	lea	Cmpdatetime,a4
		move.b	#FORMAT_DOS,dat_Format(a4)
		move.b	#DTB_SUBST+DTB_FUTURE,dat_Flags(a4)
		clr.l	dat_StrDay(a4)
		move.l	#CmpDate.msg,dat_StrDate(a4)
		clr.l	dat_StrTime(a4)

		lea	CmpDate.msg,a0
		move.l	#LEN_DATSTRING-1,d0
.1:		move.b	(a1)+,(a0)+
		dbra	d0,.1
		move.l	a4,d1
		CALL	StrToDate,_DOSBase
		rts

checkdates	lea	Cmpdatetime,a3
		move.l	a3,d1
		CALL	DateStamp,_DOSBase
checkdates2	lea	Cmpdatetime,a3		; compare(Cmpdatetime,datetime)
		move.l	(a3),d0
		lea	anchorpath,a4
		move.l	ap_Info+fib_DateStamp(a4),d1
		cmp.l	d0,d1
		rts

open.cmpfile	move.l	a0,d1
		move.l	#ACCESS_READ,d2
		CALL	Lock,_DOSBase
		tst.l	d0
		beq.b	.failed
		move.l	d0,d6
		move.l	d0,d1
		move.l	#compareblock,d2
		CALL	Examine
		cmp.l	#DOSFALSE,d0
		beq.b	.failed
		move.l	d6,d1
		CALL	UnLock

		lea	compareblock,a0
		lea	Cmpdatetime,a1
		move.l	fib_DateStamp(a0),ds_Days(a1)
		moveq	#TRUE,d0
		rts
.failed		moveq	#FALSE,d0
		rts

GETDISKINFO	PUSHALL
		move.l	#volname,d1
		move.l	#ACCESS_READ,d2
		CALL	Lock,_DOSBase
		move.l	d0,d6
		beq.w	.failed
		move.l	d0,d1
		move.l	#volumeinfoblock,d2
		CALL	Info
		move.l	d6,d1
		CALL	UnLock
		lea	volumeinfoblock,a3
		lea	info.shit(pc),a4

		move.l	_UtilBase,a6

		move.l	id_NumBlocks(a3),d0
		move.l	id_BytesPerBlock(a3),d1
		bsr.w	.1024
		move.b	d4,C_INFOsize1
		move.b	d4,C_INFOsize2

		move.l	id_NumBlocksUsed(a3),d0
		move.l	id_BytesPerBlock(a3),d1
		bsr.w	.1024
		move.b	d4,C_INFOused1
		move.b	d4,C_INFOused2

		move.l	id_NumBlocks(a3),d0
		move.l	id_NumBlocksUsed(a3),d1
		sub.l	d1,d0
		move.l	id_BytesPerBlock(a3),d1
		bsr.w	.1024
		move.b	d4,C_INFOfree1
		move.b	d4,C_INFOfree2

		move.l	id_NumBlocksUsed(a3),d0
		move.l	#100,d1
		CALL	UMult32
		move.l	id_NumBlocks(a3),d1
		CALL	UDivMod32
		move.l	d0,(a4)+

		move.l	id_NumSoftErrors(a3),(a4)+

		move.l	id_DiskState(a3),d0
		lea	status_validating(pc),a0
		cmp.l	#ID_VALIDATED,d0
		bne.b	.2
		lea	status_validated(pc),a0
.2:		cmp.l	#ID_WRITE_PROTECTED,d0
		bne.b	.3
		lea	status_writeprotected(pc),a0
.3		move.l	a0,(a4)+

		move.l	id_DiskType(a3),d0
		lea	type_unreadable(pc),a0
		cmp.l	#ID_NOT_REALLY_DOS,d0
		bne.b	.4
		lea	type_notreallydos(pc),a0
.4		cmp.l	#ID_DOS_DISK,d0
		bne.b	.5
		lea	type_dosdisk(pc),a0
.5		cmp.l	#ID_FFS_DISK,d0
		bne.b	.6
		lea	type_ffsdisk(pc),a0
.6		cmp.l	#ID_KICKSTART_DISK,d0
		bne.b	.7
		lea	type_kickstart(pc),a0
.7		move.l	a0,(a4)+
.failed		PULLALL
		rts

.1024		CALL	UMult32,_UtilBase
		move.l	#1024,d1
		CALL	UDivMod32
		move.b	#'k',d4
		cmp.l	#1024,d0
		bls.b	.1
		move.l	#1024,d1
		CALL	UDivMod32
		moveq	#'m',d4
.1:		move.l	d0,(a4)+
		rts

*		This one multiples d1.LONG! with d2.LONG! in d1.LONG
*		if both are only word-sized, MULU is beeing used...

ext.mulu	mulu.l	d1,d2
		rts
;		movem.l d1/d2,-(sp)
;		cmp.l	#$FFF,d2
;		bcc.b	.2
;		cmp.l	#$FFF,d0
;		bcc.b	.2
;		mulu	d2,d0
;		movem.l (sp)+,d1/d2
;		rts
;.2:		moveq	#0,d1
;		subq.l	#1,d2
;.1:		add.l	d0,d1
;		dbra	d2,.1
;		move.l	d1,d0
;		movem.l (sp)+,d1/d2
;		rts

dos.name	DOSNAME
utility.name	UTILITYNAME
dateerror.msg	dc.b	"invalid date/time specification",10,0
arg.template	dc.b	"DIR/M,ALL/S,VERBOSE/S,SHORT/S,LIST/S,"
		dc.b	"FULLPATH/S,COLOR/S,NOCOLOR/S,FILES/S,DIRS/S,"
		dc.b	"HIDDEN/S,NOHIDDEN/S,NEWER/K,OLDER/K,TODAY/S,"
		dc.b	"LARGER/K/N,SMALLER/K/N,SINCE/K,UPTO/K,"
		dc.b	"DATES/S,NODATES/S,HELP/S"
		dc.b	0
addpart.msg	dc.b	'#?',0

sfile.msg	dc.b	'%-18.18s ',0
sdir.msg	dc.b	$1b,'[1m%-18.18s ',$1b,'[0m',0

nfile.msg	dc.b	'%-16.16s%8ld ',0
ndir.msg	dc.b	'%-18.18s (DIR) ',0

fnfile.msg	dc.b	'%s (%ld Bytes)',10,0
fndir.msg	dc.b	'%s (Directory)',10,0
lfile.msg	dc.b	'%-27.27s %8ld ',0
ldir.msg	dc.b	'%-30.30s (DIR) ',0
flfile.msg	dc.b	'%s (%ld Bytes)',10,0
fldir.msg	dc.b	'%s (Directory)',10,0
linfo.msg	dc.b	'%s %-10.10s %s [%8ld]',0
comment.msg	dc.b	10,":'%s'",0
flinfo.msg	dc.b	'%s %-10.10s %s [%8ld]',10,0
fcomment.msg	dc.b	":'%s'",10,0
head.msg	dc.b	"Directory of %-41.41s at %-9.9s %s",10
		dc.b	'Size=%ld'
C_INFOsize1	dc.b	'kB Used=%ld'
C_INFOused1	dc.b	'kB Free=%ld'
C_INFOfree1	dc.b	'kB Full=%ld%% Errs=%ld Status=%s Type=%s',10,0
diddir.msg	dc.b	10,"[<'%s']",0
dodir.msg	dc.b	10,"[>'%s']",0 
diddir.msg2	dc.b	"[<'%s']",10,0
dodir.msg2	dc.b	"[>'%s']",10,0
return.msg	dc.b	10,0
fvinfo.msg	dc.b	'P:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:??',10,0
volinfo.msg	dc.b	"%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",10,0

; the colored messages :

C_sdir.msg	dc.b	$1b,'[33m%-18.18s ',$1b,'[0m',0 
C_ndir.msg	dc.b	$1b,'[33m%-18.18s (DIR) ',$1b,'[0m',0
C_fndir.msg	dc.b	$1b,'[33m%s (DIR)',$1b,'[0m',10,0
C_ldir.msg	dc.b	$1b,'[33m%-30.30s (DIR) ',0
C_fldir.msg	dc.b	$1b,'[33m%s (Directory)',10,0
C_linfo.msg	dc.b	'%s %-10.10s %s [%8ld]',$1b,'[0m',0
C_comment.msg	dc.b	10,$1b,"[32;7m:'%s'",$1b,"[0m",0
C_flinfo.msg	dc.b	'%s %-10.10s %s [%8ld]',$1b,'[0m',10,0
C_fcomment.msg	dc.b	$1b,"[32m:'%s'",$1b,"[0m",10,0
C_head.msg	dc.b	$1b,"[33;42mDirectory of ",$1b,"[1m%-41.41s"
		dc.b	$1b,"[0m",$1b,"[33;42m at %-9.9s %s",$1b,"[0m",10
		dc.b	$1b,'[1mSize=%ld'
C_INFOsize2	dc.b	'kB Used=%ld'
C_INFOused2	dc.b	'kB Free=%ld'
C_INFOfree2	dc.b	'kB Full=%ld%% Errs=%ld Status=%s Type=%s',$1b,'[0m',10,0

C_diddir.msg	dc.b	10,$1b,"[41;33m[<'%s']",$1b,"[0m",0
C_dodir.msg	dc.b	10,$1b,"[41;33m[>'%s']",$1b,"[0m",0
C_diddir.msg2	dc.b	$1b,"[41;33m[<'%s']",$1b,"[0m",10,0
C_dodir.msg2	dc.b	$1b,"[41;33m[>'%s']",$1b,"[0m",10,0
C_fvinfo.msg	dc.b	$1b,'[0mP:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:??',10,0
C_volinfo.msg	dc.b	$1b,"[1m%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",$1b,"[0m",10,0

; other messages

vol_noentry.msg dc.b "no more entries in directory",10,0

help.msg	dc.b	'Cat v1.00'
		dc.b	'Usage : CAT [directory(s)] [OPTIONS]',10
		dc.b	'Args  :         ALL - enter all subdirectorys',10
		dc.b	'            VERBOSE - be verbose as to the information given',10
		dc.b	'              SHORT - 4 entrys in a row, no filesizes',10
		dc.b	'               LIST - list-lookalike',10
		dc.b	'           FULLPATH - display full path of names',10
		dc.b	'              FILES - display files only',10
		dc.b	'               DIRS - display directorys only',10
		dc.b	'             HIDDEN - show hidden files [default]',10
		dc.b	'           NOHIDDEN - don''t show hidden files',10
		dc.b	'       NEWER=object - show files only newer or equal to this',10
		dc.b	'       OLDER=object - show files only older or equal to this',10
		dc.b	'              TODAY - show all files of today',10
		dc.b	'        LARGER=size - show all files larger than this',10
		dc.b	'       SMALLER=size - show all files smaller than this',10
		dc.b	'         SINCE=date - show all files since this day',10
		dc.b	'          UPTO=date - show all files upto this day',10
		dc.b	'              DATES - show real dates (don''t use ''Today'' etc.)',10
		dc.b	'            NODATES - use replace-strings if available [default]',10
		dc.b	0
err.head	dc.b	'ERROR:',0

		even
headname	dc.l	volname
		dc.l	StrDate.msg
		dc.l	StrTime.msg

info.shit	dc.l	0	; Size
		dc.l	0	; Used
		dc.l	0	; Free
		dc.l	0	; Full
		dc.l	0	; Errs
		dc.l	0	; Status
		dc.l	0	; type

status_validating dc.b	'VALIDATING',0
status_validated dc.b	'READ/WRITE',0
status_writeprotected dc.b 'READ',0

type_unreadable	dc.b	'BAD',0
type_notreallydos dc.b	'NDOS',0
type_dosdisk	dc.b	'DOS',0
type_ffsdisk	dc.b	'FFS',0
type_kickstart	dc.b	'KICK',0

		even

protstring	dc.l	protstring.data
		dc.l	StrDate.msg
		dc.l	StrTime.msg
nrofblocks	ds.l	1

protstring2	dc.l	protstring.data
		dc.l	StrDay.msg
		dc.l	StrDate.msg
		dc.l	StrTime.msg
nrofblocks2	ds.l	1
v_diskkey	ds.l	1
v_entrytype	ds.l	1

		SECTION	nirvana,BSS

BSS_START
arg.dirs	ds.l	1
arg.all		ds.l	1
arg.verbose	ds.l	1
arg.short	ds.l	1
arg.list	ds.l	1
arg.fullpath	ds.l	1
arg.color	ds.l	1
arg.nocolor	ds.l	1
arg.filesonly	ds.l	1
arg.dirsonly	ds.l	1
arg.hidden	ds.l	1
arg.nohidden	ds.l	1
arg.newer	ds.l	1
arg.older	ds.l	1
arg.today	ds.l	1
arg.larger	ds.l	1
arg.smaller	ds.l	1
arg.since	ds.l	1
arg.upto	ds.l	1
arg.dates	ds.l	1
arg.nodates	ds.l	1
arg.help	ds.l	1

_DOSBase	ds.l	1
_UtilBase	ds.l	1
arg.rdargs	ds.l	1
filename	ds.l	1
filesize	ds.l	1
comment		ds.l	1
NROF_files	ds.l	1
NROF_dirs	ds.l	1
NROF_bytes	ds.l	1
NROF_blocks	ds.l	1
anchorpath	ds.b	ap_SIZEOF
volname		ds.b	MAX_PATHSIZE
fileinfoblock	ds.b	fib_SIZEOF
datetime	ds.b	dat_SIZEOF
StrDay.msg	ds.b	LEN_DATSTRING
StrDate.msg	ds.b	LEN_DATSTRING
StrTime.msg	ds.b	LEN_DATSTRING
Cmpdatetime	ds.b	dat_SIZEOF
CmpDay.msg	ds.b	LEN_DATSTRING
CmpDate.msg	ds.b	LEN_DATSTRING
CmpTime.msg	ds.b	LEN_DATSTRING
rowcount	ds.b	1
dirflag		ds.b	1
maxrows		ds.b	1
anyentry.flag	ds.b	1
		even
protstring.data	ds.b	9
		cnop	0,4
compareblock	ds.b	fib_SIZEOF
		cnop	0,4
volumeinfoblock	ds.b	id_SIZEOF

BSS_SIZE	equ	*-BSS_START

		end

