; -------------------------------------------------------------------------- ;
; A very simple program that will show you how to use Idm.library.
; -------------------------------------------------------------------------- ;
;
; Copyright © 1997-1999 Andrew Bell, EMAIL: andrew@ab2000.prestel.co.uk
;
; This source and its binary is part of the Idm.library distribution package.
; You not allowed to distribute this source or binary separate from the
; main Idm.library package.
;
; -------------------------------------------------------------------------- ;
; Introduction:
;
; This program is used to stress the functions of Idm.library. It has
; since been replace by a new and more powerful program called GetType.
; You can get this from the Aminet at util/dir/GetType.lha.
;
; This program should not be treated as a fully working program. It is
; a test program. Some short cuts have been taken and some code may
; be considered illegal by the OS. Note: This source is nearly 2 years old.
; 
;
; The actual output is very ugly, but after all, this is one of the first
; programs I created that used Idm.library, so it was rushed.
;
; So now you can examine the source to see how Idm.library should be
; called. Beware: This program has NOT been tested on a 040 nor a 060.
;
; -------------------------------------------------------------------------- ;
; Compiling:
;
; For the best result use PhxAss v4.39+ by Frank Wille.
;
; I have also added some options for BAsm 2.9 (BarFly) by R.Schimdt.
;
; Both of these assemblers can be found on the Aminet. Some work might be
; needed to get this source to compile on other assemblers.
;
; -------------------------------------------------------------------------- ;
; History:
;
; 1.0 (12.Jun.97) - First REAL working version that got lost :)
; 1.1 (13.Jun.97) - Rewrite of first working version :)
; 1.2 (15.Jun.97) - Optimized version.
; 1.3 (21.Jun.97) - Bug fix
; 1.4 (22.Feb.99) - Source code cleaned up for release.
;
; -------------------------------------------------------------------------- ;
; Requirements:
;
; Amiga OS39+, MC68020+. Idm.library will pick-up on CPU type.
;
; -------------------------------------------------------------------------- ;
; Parameters
;
; Type "IdmScan c:" - to list filetypes in the C: drawer, etc.
; Type "IdmScan !"  - to list all known filetypes.
; Type "IdmScan ?"  - to view library information.
;
; All unknown filetypes are highlighted
; -------------------------------------------------------------------------- ;

		OUTPUT	IdmScan

		IFD	_PHXASS_
		OPT	3
		SYMDEBUG
		ENDC

		IFD	BARFLY
		BOPT	ue+,F+,x+,v+,wo-,ws-,w4-,O+,OG+,ODD+
		ENDC

VERSTAG		MACRO
		dc.b	0,"$VER: IdmScan 1.4 (22.2.99) Copyright © 1999 Andrew Bell",0
		cnop	0,2
		ENDM

		incdir	AInc:
		include	exec/libraries.i
		include	dos/dosextens.i
		include	libraries/Idm.i
		include	lvo/Idm_lib.i
		include	lvo/exec_lib.i
		include	lvo/dos_lib.i

		rsset	-4		; variable page
var_SysBase	rs.l	-1
var_DOSBase	rs.l	-1
var_IdmBase	rs.l	-1
var_ArgString	rs.l	-1
var_FIBObject	rs.l	-1
var_ObjLock	rs.l	-1
var_IdInfo	rs.l	-1
var_IOLen	rs.l	-1
var_LoadBuf	rs.l	-1
var_Handle	rs.l	-1
var_FileCnt	rs.l	-1
var_DirCnt	rs.l	-1
var_MatchCnt	rs.l	-1
var_SIZEOF	rs.l	-1


calldos		macro
		move.l	var_DOSBase(a5),a6
		jsr	_LVO\1(a6)
		endm

callsys		macro
		move.l	var_SysBase(a5),a6	; cached execbase = speed
		jsr	_LVO\1(a6)
		endm

callidm		macro
		move.l	var_IdmBase(a5),a6
		jsr	_LVO\1(a6)
		endm

callit		macro
		jsr	_LVO\1(a6)
		endm

Base:		link.w	a5,#var_SIZEOF		; Get variable page

		clr.b	-1(a0,d0.w)		; NULL-Terminate args.
		move.l	a0,var_ArgString(a5)	; Keep args
		move.l	(4).w,a6		; Get SysBase

		move.l	a6,var_SysBase(a5)

		moveq	#39,d0
		cmp.w	LIB_VERSION(a6),d0	; Old OS?
		bcs	Exit_Prg

		lea.l	_DosName(pc),a1		; Open dos.library 39+
		callit	OpenLibrary
		move.l	d0,var_DOSBase(a5)
		beq	Exit_Prg		; Fail?

		moveq	#0,d0			; Open Idm.library 0+
		lea.l	_IdmName(pc),a1
		callit	OpenLibrary
		move.l	d0,var_IdmBase(a5)
		beq	FailCDOS		; Fail?

		moveq	#-1,d7
		move.l	var_ArgString(a5),a0

		cmp.b	#'!',(a0)
		beq	DOINFOSTRING

		moveq	#0,d7
		cmp.b	#'?',(a0)
		bne	IgnoreINFO

DOINFOSTRING	move.l	d0,a6
		callit	IdmObtainLibInfo	; Get library info
		move.l	d0,d2
		beq	FailCIDM
		move.l	d0,a4

		addq.l	#4,d2			; Print info
		move.l	#InfoString,d1
		calldos	VPrintf

		tst.l	d7			; List entries?
		beq	.NoList

		move.l	IdmLI_IDList(a4),a3	; Get first node
		move.l	LH_HEAD(a3),a3

		moveq	#0,d3			; Reset counter

.Loop		move.l	#Listing,d1		; Print next entry in list
		move.l	LN_NAME(a3),-(sp)
		move.l	d3,-(sp)
		move.l	sp,d2
		callit	VPrintf
		addq.l	#8,sp

		moveq	#0,d0			; Control + C ?
		moveq	#SIGBREAKB_CTRL_C,d2
		bset	d2,d0
		callit	CheckSignal
		btst	d2,d0
		bne	.NoList

		addq.l	#1,d3			; Add counter

		move.l	LN_SUCC(a3),a3		; Get next
		tst.l	(a3)
		bne	.Loop

.NoList		move.l	a4,d0			; Free Lib info
		callidm	IdmFreeLibInfo
		bra	FailCIDM

IgnoreINFO	callidm	IdmAllocIdInfo		; Id Info
		move.l	d0,var_IdInfo(a5)
		beq	FailCIDM

point2		callit	IdmObtainIOLen		; Load length
		move.l	d0,var_IOLen(a5)

		moveq	#1,d1			; MEMF_CLEAR
		swap.w	d1
		callsys	AllocVec
		move.l	d0,var_LoadBuf(a5)	; Get IO buf
		beq	FailCIDM

		bsr	ScanObject		; Main

		move.l	var_LoadBuf(a5),a1	; Free IO buf
		callsys	FreeVec

		move.l	var_IdInfo(a5),a0
		callidm	IdmFreeIdInfo

FailCIDM

FailCDOS	move.l	var_DOSBase(a5),a1	; Close dos.library
		callsys	CloseLibrary

Exit_Prg	unlk	a5
		moveq	#0,d0
		rts

	**********************************************************************

ScanObject:	moveq	#DOS_FIB,d1			; Get FIB memory
		moveq	#0,d2
		calldos	AllocDosObject
		move.l	d0,var_FIBObject(a5)
		beq	Exit

		move.l	var_ArgString(a5),d1		; Lock object
		moveq	#SHARED_LOCK,d2
		callit	Lock
		move.l	d0,var_ObjLock(a5)
		beq	FailFreeObj

		move.l	d0,d1				; Examine object
		move.l	var_FIBObject(a5),d2
		callit	Examine
		tst.l	d0
		beq	FailFreeObj

		clr.l	var_FileCnt(a5)			; Init counters
		clr.l	var_DirCnt(a5)
		clr.l	var_MatchCnt(a5)

		*************************************************************

ScanLoop	move.l	var_ObjLock(a5),d1		; Next entry
		move.l	var_FIBObject(a5),d2
		calldos	ExNext
		tst.l	d0
		beq	Done

		move.l	var_FIBObject(a5),a0		; Entry type...
		tst.l	fib_DirEntryType(a0)
		bmi	IsAFile

		addq.l	#1,var_DirCnt(a5)

		pea.l	fib_FileName(a0)		; Display dir
		move.l	#OutStringDIR,d1
		move.l	sp,d2
		callit	VPrintf
		addq.l	#4,sp
		bra	ScanLoop

IsAFile		addq.l	#1,var_FileCnt(a5)

		move.l	var_ObjLock(a5),d1		; Get path
		move.l	#PathBuffer,d2
		move.l	#256,d3
		callit	NameFromLock
		tst.l	d0
		beq	ScanLoop

		move.l	#PathBuffer,d1
		move.l	var_FIBObject(a5),d2
		addq.l	#fib_FileName,d2
		move.l	#256,d3
		callit	AddPart
		tst.l	d0
		beq	ScanLoop

		move.l	#PathBuffer,d1			; Open file
		move.l	#MODE_OLDFILE,d2
		callit	Open
		move.l	d0,var_Handle(a5)
		beq	ScanLoop

		move.l	d0,d1
		move.l	var_LoadBuf(a5),d2
		move.l	var_IOLen(a5),d3
		callit	Read

		; TODO: Add check for ~NULL here

		; Remember: D0 is set to load length at this point.

point		move.l	var_IdInfo(a5),a0
		move.l	var_LoadBuf(a5),a1
		suba.l	a2,a2
		callidm	IdmIdentifyMem

		move.l	#MR_NULL,d3
		move.l	d3,d4

		move.l	d0,d2
		bne	MatchOK

		move.l	#Unknown,d2
		move.l	#B_ANSI,d3
		move.l	#E_ANSI,d4

		bra	NoMatch

MatchOK		addq.l	#1,var_MatchCnt(a5)

NoMatch		move.l	var_Handle(a5),d1
		calldos	Close

		move.l	var_FIBObject(a5),a0

		move.l	d4,-(sp)		; ANSI Highlight format END
		move.l	fib_Size(a0),-(sp)	; Length of file in bytes
		move.l	d2,-(sp)		; Id discription
		pea.l	fib_FileName(a0)	; Name of file
		move.l	d3,-(sp)		; ANSI Highlight format START

		move.l	#OutString,d1		; Print result
		move.l	sp,d2
		callit	VPrintf
		lea.l	20(sp),sp

		moveq	#0,d0			; Control + C ?
		moveq	#SIGBREAKB_CTRL_C,d2
		bset	d2,d0
		callit	CheckSignal
		btst	d2,d0
		beq	ScanLoop

		*************************************************************

Done		move.l	var_ObjLock(a5),d1
		callit	UnLock

FailFreeObj	moveq	#DOS_FIB,d1
		move.l	var_FIBObject(a5),d2
		calldos	FreeDosObject

Exit		bsr	ReportError		; In case of an error
		bne	Quit

		move.l	var_MatchCnt(a5),-(sp)	; Print scaninfo
		move.l	var_FileCnt(a5),-(sp)
		move.l	var_DirCnt(a5),-(sp)
		move.l	#Summary,d1
		move.l	sp,d2
		callit	VPrintf
		lea.l	12(sp),sp

Quit		rts

		*************************************************************

ReportError:	calldos	IoErr
		move.l	d0,d1
		beq	.Exit
		not.l	d0
		beq	.Exit
		moveq	#0,d2
		move.l	d1,-(sp)
		callit	PrintFault
		move.l	(sp)+,d1
.Exit		rts

		*************************************************************

_DosName	dc.b	"dos.library",0
_IdmName	dc.b	"Idm.library",0

OutString	dc.b	" %s%-28.28s - %-34.34s - %7lu%s",10,0
OutStringDIR	dc.b	"/%-28.28s - Directory",10,0

Unknown		dc.b	"Unable to identify file!",0

Listing		dc.b	"Filetype #%lu: %s",10,0

B_ANSI		dc.b	$9b,"7;33;41m",0	; Highlight begin
E_ANSI		dc.b	27,"[0m"		; Highlight end
MR_NULL		dc.b	0			; A zero

Summary		dc.b	10,"DIRS: %lu FILES: %lu MATCHED: %lu",10,0

		VERSTAG

InfoString	dc.b	10,"Information on Idm.library...",10,10
		dc.b	"   Version: %d",10
		dc.b	"  Revision: %d",10
		dc.b	" Amt Known: %lu",10
		dc.b	"   Id List: $%08lx",10
		dc.b	" IO Length: %ld",10
		dc.b	"     Res01: %d",10
		dc.b	"     Res02: %d",10
		dc.b	"    Max IO: %s",10,10,0

		*************************************************************

		section	Buffers,bss

PathBuffer	ds.b	512

