;***************************************************************************;
;									    ;
;				   FILMAP				    ;
;			      Directory Command				    ;
;									    ;
;***************************************************************************;
;Copyright (C) 1986 by UltraSoft.  All Rights Reserved.
;
;Written by: David Pallmann
;
;What it does:
;
;	FILMAP is (yet another) directory command.  You can use ^R and ^T to
;	scan back and forth through the directory.  This utility was written
;	for the AMUS M68-SIG as an example of how to use our wildcard scanner,
;	WLDSCN.
;
;How to assemble FILMAP:
;
;	1. Make sure you have (1) FILMAP.M68 (2) WLDSCN.M68 (3) WLDSYM.M68
;	2. Assemble WLDSCN.M68 to create WLDSCN.OBJ (uses WLDSYM.M68)
;	3. Assemble FILMAP with the command .M68 FILMAP
;	4. Link FILMAP with the command .LNKLIT FILMAP,WLDSCN
;
;How to use it:
;
;	It's just like DIR - enter a filespec, or even a blank line.  Examples:
;		.FILMAP		.FILMAP ALL:*.BAS[]	.FILMAP *.CMD
;
;Edit History:
;1.0	17-Jul-86 created. /DFP
;1.0A	19-Jul-86 force octal mode. /DFP
;1.1	02-Aug-86 remove dependence on UltraSoft universals. /DFP

	VMAJOR=1
	VMINOR=1

	SEARCH	SYS
	SEARCH	SYSSYM
	SEARCH	TRM

;dedicated registers

	MEM=A5				; impure index
	WILD=A4				; wildscan DDB index
	BASE=A3				; base of file specs in memory
	INDEX=A1			; current filespec pointer
	COUNT=D5			; number of files in memory
	CURR=D4				; current file number

;impure area used by FILMAP

	.OFINI
	.OFDEF	BUFFER,30.
	.OFDEF	LSTDEV,2		; last device displayed
	.OFDEF	LSTDRV,2		; last drive displayed
	.OFDEF	LSTPPN,2		; last PPN displayed
	.OFSIZ	MEMSIZ

;the following structure is used to remember the directory information in
;memory

	.OFINI
	.OFDEF	F.DEV,2			; device code
	.OFDEF	F.DRV,2			; drive number
	.OFDEF	F.PPN,2			; PPN
	.OFDEF	F.FIL,4			; filename
	.OFDEF	F.EXT,2			; extension
	.OFDEF	F.BLK,2			; size in blocks
	.OFSIZ	F.SIZ

;macro definitions
;
;	CURSOR {row},{col} is the same as PRINT TAB(row,col); in BASIC
;	TCALL {code} is the same as PRINT TAB(-1,code) in BASIC
;	CLS clears the screen (-1,0);
;	CLREOL clears to end of line (-1,9);
;	LOW sets low intensity (-1,11);
;	HIGH sets high intensity (-1,12);
;	GRAFIX turns on graphics mode (-1,23);
;	TEXT turn off graphics mode (-1,24);
;	REVERS turns on reverse video (-1,32);
;	NORMAL turns off reverse video (-1,33);
;	HLINE outputs a horizontal graphics line (-1,46);

DEFINE	CURSOR	ROW,COL
	MOVB	ROW,D1
	ROLW	D1,#8.
	MOVB	COL,D1
	TCRT
	ENDM

DEFINE	TCALL	CODE
	MOVW	#-1_8.+CODE,D1
	TCRT
	ENDM

DEFINE CLS=TCALL 0
DEFINE CLREOL=TCALL 9.
DEFINE LOW=TCALL 11.
DEFINE HIGH=TCALL 12.
DEFINE GRAFIX=TCALL 23.
DEFINE TEXT=TCALL 24.
DEFINE REVERS=TCALL 32.
DEFINE NORMAL=TCALL 33.
DEFINE HLINE=TCALL 46.

;These macros are used to call WLDSCN, the wildcard directory scanner
;These are defined in WLDSCN.UNV as well

DEFINE	WINIT
	IF	NDF,W.INIT,EXTERN W.INIT
	CALL	W.INIT
	ENDM

DEFINE	WSPEC	EXT
	IF	NDF,W.SPEC,EXTERN W.SPEC
	CALL	W.SPEC
	IF	B,EXT,ASCII /???/
	IF	NB,EXT,ASCII /'EXT/
	BYTE	0
	ENDM

DEFINE	WSCAN
	IF	NDF,W.SCAN,EXTERN W.SCAN
	CALL	W.SCAN
	ENDM

;start of code

START:	PHDR	-1,PV$RPD!PV$RSM,PH$REE!PH$REU	; program header

INIT:	GETIMP	MEMSIZ,MEM		; allocate local memory
	WINIT				; initialize WLDSCN (sets up A4)
	USRFRE	BASE			; point to free memory to file table
	MOV	BASE,INDEX		; set index to table base
	CLR	COUNT			; clear file count

SETOCT:	JOBIDX	A6			; index user's JCB		[1.0A]
	ANDW	#^C<J.HEX>,JOBTYP(A6)	; force OCTAL radix		[1.0A]

CMDLIN:	BYP				; bypass leading cmd line spaces
	WSPEC				; process wildcard file specification
	JNE	EXIT			; branch on invalid spec
	USREND	A2			; index end of free memory
	SUB	#10,A2			; subtract 8 bytes for good measure

LOAD:	CTRLC	EXIT			; branch on ^C
	WSCAN				; get next file that matches spec
	JNE	CKZERO			;  no more - branch
	MOVW	D.DEV(WILD),F.DEV(INDEX); copy spec
	MOVW	D.DRV(WILD),F.DRV(INDEX);  from wildscan
	MOVW	D.PPN(WILD),F.PPN(INDEX);   DDB @A4 to
	MOV	D.FIL(WILD),F.FIL(INDEX);    our internal
	MOVW	D.EXT(WILD),F.EXT(INDEX);     table
	INC	COUNT			; add one to file count
	JOBIDX	A0			; index user's JCB again
	TSTW	F.DEV(INDEX)		; defaulted device code?
	BNE	10$			;  no
	MOVW	JOBDEV(A0),F.DEV(INDEX)	;  yes - use log device code
10$:	TSTW	F.DRV(INDEX)		; defaulted drive number?
	BPL	20$			;  no
	MOVW	JOBDRV(A0),F.DRV(INDEX)	; yes - use log device code
20$:	TSTW	F.PPN(INDEX)		; defaulted PPN?
	BNE	30$			;  no
	MOVW	JOBUSR(A0),F.PPN(INDEX)	;  yes - use log account number
30$:	ADD	#F.SIZ,INDEX		; point index to next table entry
	CMP	INDEX,A2		; are we out of memory?
	JLT	LOAD			;  no
	TYPECR	%Couldn't fit entire directory in memory ; yes - say so

CKZERO:	TST	COUNT			; any files selected?
	BNE	SETTRM			;  yeah
	TYPECR	%No such files		;  nope
	EXIT				; exit

SETTRM:	JOBIDX	A6			; index JCB
	MOV	JOBTRM(A6),A6		; get TCB address
	ORW	#T$IMI!T$ECS,T.STS(A6)	; force image mode, disable echo

;home display to beginning of directory(ies) in memory

HOME:	MOV	BASE,INDEX		; set index to table base
	CLR	CURR			; clear current file index

;display current page

DISPLY:	CLRW	LSTDEV(MEM)		; forget about
	CLRW	LSTDRV(MEM)		;  previously displayed
	CLRW	LSTPPN(MEM)		;   data
	CLS				; clear screen
	HIGH				; high intensity
	MOV	INDEX,A0		; copy table index
	MOV	CURR,D0			; copy file index
	MOV	#1,D2			; set row
10$:	MOV	#1,D3			; set column
20$:	JOBIDX	A6			; index JCB
	MOV	JOBTRM(A6),A6		; get TCB address
	TST	T.ICC(A6)		; any characters entered?
	JNE	GETCHR			;  yes - abort screen display
	CMP	D2,#24.			; at row 24?
	BGE	30$			;  yes - done w/display
	CTRLC	EXIT			; branch on ^C
	CURSOR	D2,D3			; address cursor
	CALL	DISFIL			; display file
	CMP	D2,#23.			; at end of screen?
	JGT	30$			;  yes
	INC	D0			; inc temp file count
	CMP	D0,COUNT		; past end of table?
	BGE	30$			;  yes
	ADD	#F.SIZ,A0		; advance to next entry
	ADD	#13.,D3			; advance column
	CMP	D3,#68.			; past end of line?
	BLT	20$			;  no
	INC	D2			; advance row
	BR	10$			; branch
30$:	TST	CURR			; are we at start of table?
	BNE	SELECT			;  yes - branch
	CMP	D0,COUNT		; are we at end of table?
	JGE	FINISH			;  yes - branch

SELECT:	CURSOR	#24.,#1
	HIGH
	TYPE	B
	LOW
	TYPE	<ack, >
	HIGH
	TYPE	F
	LOW
	TYPE	<orward, >
	HIGH
	TYPE	Q
	LOW
	TYPE	<uit: >

GETCHR:	KBD	FINISH
	UCS
	LEA	A0,CMDTBL
	MOV	#-2,D0
10$:	TSTB	@A0
	JEQ	DISPLY
	ADD	#2,D0
	CMMB	(A0)+,D1
	BNE	10$
	MOVW	JMPTBL[~D0],D0
	JMP	JMPTBL[~D0]

JMPTBL:	WORD	BACK-JMPTBL
	WORD	END-JMPTBL
	WORD	FORWRD-JMPTBL
	WORD	TOHOME-JMPTBL
	WORD	FINISH-JMPTBL
	WORD	BACK-JMPTBL
	WORD	END-JMPTBL
	WORD	FORWRD-JMPTBL
	WORD	TOHOME-JMPTBL
	WORD	FINISH-JMPTBL

CMDTBL:	BYTE	'B
	BYTE	'E
	BYTE	'F
	BYTE	'H
	BYTE	'Q
	BYTE	'R-'@
	BYTE	'E-'@
	BYTE	'T-'@
	BYTE	'^-'@
	BYTE	'[-'@
	BYTE	0
	EVEN

FINISH:	CURSOR	#24.,#1
	CLREOL

EXIT:	HIGH
	EXIT

TOHOME:	JMP	HOME

END:	MOV	BASE,INDEX
	MOV	COUNT,D0
	MUL	D0,#F.SIZ
	ADD	D0,INDEX
	SUB	#20.*5*F.SIZ,INDEX
	MOV	COUNT,CURR
	SUB	#20.*5,CURR
	CMP	CURR,#1
	JGE	DISPLY
	JMP	HOME

BACK:	SUB	#20.*5,CURR
	SUB	#20.*5*F.SIZ,INDEX
	CMP	CURR,#1
	JGE	DISPLY
	JMP	HOME

FORWRD:	MOV	INDEX,A6
	MOV	CURR,D6
	ADD	#20.*5*F.SIZ,A6
	ADD	#20.*5,D6
	CMP	D6,COUNT
	JGE	SELECT
	MOV	A6,INDEX
	MOV	D6,CURR
	JMP	DISPLY

DISFIL:	PUSH	A1
	CMMW	F.DEV(A0),LSTDEV(MEM)
	BNE	10$
	CMMW	F.DRV(A0),LSTDRV(MEM)
	BNE	10$
	CMMW	F.PPN(A0),LSTPPN(MEM)
	BEQ	20$
10$:	CALL	POS
	CMP	D2,#23.
	JGT	30$
	MOVW	F.DEV(A0),LSTDEV(MEM)
	MOVW	F.DRV(A0),LSTDRV(MEM)
	MOVW	F.PPN(A0),LSTPPN(MEM)
20$:	LEA	A2,BUFFER(MEM)
	LEA	A1,F.FIL(A0)
	UNPACK
	UNPACK
	MOVB	#'.,(A2)+
	UNPACK
	CLRB	@A2
	TTYL	BUFFER(MEM)
30$:	POP	A1
	RTN

POS:	SAVE	D0
	CMPB	D3,#1
	BEQ	10$
	INC	D2
	MOV	#1,D3
10$:	INC	D2
	CMP	D2,#23.
	JGT	POSRTN
	CURSOR	D2,D3
	GRAFIX
	MOV	#31.,D0
20$:	HLINE
	SOB	D0,20$
	TEXT
	TYPE	<  >
	CALL	DISPPN
	TYPE	< >
	NORMAL
	MOV	#31.,D0
	GRAFIX
30$:	HLINE
	SOB	D0,30$
	TEXT
	CURSOR	D2,#32.
	REVERS
	INC	D2
	MOV	#1,D3
	CURSOR	D2,D3
POSRTN:	REST	D0
	RTN

DISPPN:	LEA	A2,BUFFER(MEM)
	LEA	A1,F.DEV(A0)
	UNPACK
	CLR	D1
	MOVW	F.DRV(A0),D1
	DCVT	0,OT$MEM
	MOVB	#':,(A2)+
	MOVB	#'[,(A2)+
	CLR	D1
	MOVB	F.PPN+1(A0),D1
	OCVT	0,OT$MEM
	MOVB	#<',>,(A2)+
	MOVB	F.PPN(A0),D1
	OCVT	0,OT$MEM
	MOVB	#'],(A2)+
	CLRB	@A2
	TTYL	BUFFER(MEM)
	RTN

TRIM:	CMMB	-(A2),#40
	BEQ	TRIM
	INC	A2
	RTN

	END