;
;	MAJOR REVISION OF FMAP3 BY:
;		RICHARD GOLDBERG
;		LAWRENCEVILLE, NJ
;		(609) 896-0241
;
;	1. UNLIMITED NUMBER OF DIRECTORY ENTRIES
;	2. COMMAND LINE OPTIONS ARE:
;		M - CREATES NAMES.SUB FILE SUITABLE FOR USE WITH
;			THE MODEM PROGRAM IN THE FORMAT OF:
;			$1 $2 $3FILENAME.TYP
;		P - CREATES NAMES.SUB FILE SUITABLE FOR USE WITH
;			PIP IN THE FORMAT OF:
;			$1 $2FILENAME.TYP$3
;		N - CREATES NAMES.SUB FILE WHICH CONTAINS REQUESTED
;			FILENAMES.
;		F - CREATES NAMES.SUB FILE WHICH CONTAINS ALL FILENAMES
;			ON DISK FOLLOWED BY ";" AND USER NUMBER.
;		U - LIST ALL FILENAMES ON DISK ON THE CONSOLE
;	3. PROGRAM WILL AUTOMATICALLY LIST ALL FCB INFORMATION
;		ON THE CONSOLE. TO INHIBIT THIS LISTING USE OPTION
;		"N" IN CONJUCTION WITH ONE OF THE OPTIONS LISTED ABOVE.
;	4. THE SOURCE DRIVE WILL BE THE DEFAULT DRIVE UNLESS THE 
;		REQUESTED FILENAME IS PRECEDED BY A DRIVE ID.
;	5. THE OUTPUT DRIVE WILL BE THE DEFAULT DRIVE UNLESS THE 
;		OPTIONS ARE PRECEDED BY A DRIVE ID.
;	6. EXAMPLES:
;		FMAP4 *.ASM MN   CREATES NAMES.SUB FILE OF ALL ".ASM"
;				 FILES FOR THE CURRENT USER WITH NO
;				 CONSOLE LISTING.
;		FMAP4 C:*.* B:F  CREATES NAMES.SUB FILE ON DRIVE B: OF
;				 ALL THE FILES ON DRIVE C: AND LISTS
;				 ALL OF THE FCB INFO ON THE CONSOLE.
;		FMAP4            LISTS ALL OF THE FCB INFO ON THE CONSOLE
;				 OF ALL THE FILES IN THE CURRENT USER
;				 ON THE CURRENT DRIVE.
;
	ORG	0100H
BDOS	EQU	05H
FCB	EQU	5CH
;
	JMP	START
;
	DB	'(FMAP 08/03/81)'
;
START:	LXI	H,0
	DAD	SP
	SHLD	STACK
	LXI	SP,STACK
	LXI	H,FCB+1	;CHECK IF FILENAME WAS GIVEN
	MOV	A,M
	CPI	' '
	JNZ	FILEG
	MVI	B,11	;FILL NAME AND TYPE WITH '?'
FILL:	MVI	M,'?'
	INX	H
	DCR	B
	JNZ	FILL
FILEG:	LDA	FCB+16	;2ND UNIT PARAM.
	ORA	A
	JZ	NODEST
	STA	MYFCB	;CHG OUTPUT DRIVE
NODEST:	LDA	FCB+17
	MOV	C,A	;OPTION IN C
	CPI	' '
	JZ	NOOPT	;NO OPTION GIVEN
	LXI	H,OPTION ;POINT TO TABLE OF OPTIONS
	MOV	A,M	;A=NUMBER OF OPTIONS
	INX	H
	MOV	B,A
	MVI	D,1	;COUNTER
OPLOOP:	MOV	A,M
	CMP	C	;RIGHT OPTION?
	JZ	FOUND
	INX	H
	INR	D
	DCR	B
	JNZ	OPLOOP
	CALL	ERXIT
	DB	'++ILLEGAL OPTION$'

FOUND:	MOV	A,D
	STA	OPTNUM	;SAVE OPTION NUMBER
	XRA	A
	STA	FILESW
NOOPT:	MVI	C,25	;FIND LOGGED DISK
	CALL	BDOS
	STA	CDSK
	LDA	FCB
	ORA	A
	JNZ	FSPEC2	;NO DRIVE SPEC'D
	LDA	CDSK
	INR	A
FSPEC2:	DCR	A	;ADJ FOR INPUT RNG
	MOV	E,A
	MVI	C,14	;SELECT DRIVE WANTED
	CALL	BDOS
	LDA	FCB+18	;GET SECONDARY OPTION
	CPI	'N'	;NO LISTING ON CONSOLE?
	JNZ	FSPEC3
	LXI	H,CONSW
	DCR	M	;MAKE NON-ZERO
FSPEC3:	LXI	H,FCB
	MVI	M,0
	LDA	OPTNUM
	CPI	4	;"M", "P" OR "N" OPTION?
	JC	FSPEC4
	MVI	M,'?'	;MATCH ALL ENTRIES
	LXI	H,ALLUSR
	DCR	M	;MAKE NON-ZERO
	CPI	4	;"F" OPTION?
	JZ	FSPEC4
	XRA	A
	STA	OPTNUM
FSPEC4:	MVI	C,27	;GET ALLOC VECT
	CALL	BDOS
	SHLD	ALLADR	;SAVE ALLOC PNTR.
	MVI	C,12	;FIND REVISION
	CALL	BDOS
	ORA	A
	JZ	OLDCPM	;BEFORE 2.0 USE DFLTS
	MVI	C,32	;GET USER NUMBER
	MVI 	E,0FFH
	CALL	BDOS
	STA	USER	;SAVE IN MEMORY
	MVI	C,31	;GET DPB ADDRESS
	CALL	BDOS
	INX	H
	INX	H
	INX	H
	MOV	A,M	;GET BLM
	INR	A	;MAKE SECTORS/BLOCK
	RRC
	RRC
	RRC		;DIVIDE BY 8 FOR KB/BLK
	ANI	1FH
	STA	BLKSIZ	;SIZE IN KBYTES
	INX	H
	MOV	A,M	;EXTENT MASK
	STA	EXTMSK
	LDA	BLKSIZ	;RESTORE SIZE
	INX	H
	MOV	E,M
	INX	H
	MOV	D,M	;DSM
	XCHG		;TOTAL BLOCK COUNT
	SHLD	BLKCNT
	XCHG
	INX	H
	MOV	E,M	;DRM
	INX	H
	MOV	D,M
	INX	D
	XCHG
	SHLD	DIR
;
OLDCPM:	LHLD	DIR	;# OF DIRECTORY ENTRIES
	LXI	D,ORDER
	XCHG
	DAD	D
	DAD	D
	SHLD	TABLE	;STARTING ADDR OF FCB TABLE
	SHLD	NEXTT
	MVI	C,17	;SRCH FIRST
	LXI	D,FCB
	CALL	BDOS
	INR	A
	PUSH	PSW
	LXI	D,TTL
	CALL	WRCON
	CALL	CR
	POP	PSW
	JMP	SOME
;
TTL:	DB	'FILENAME TYP U EX RC -----EXTENT-----'
	DB	'VER. 1.0 08/03/81$'
MORDIR:	MVI	C,12H
	LXI	D,FCB
	CALL	BDOS
	INR	A
	JZ	SPRINT
SOME:	DCR	A
	ANI	3
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	LXI	H,80H
	ADD	L
	MOV	L,A
	MOV	C,M	;SAVE USER
	LDA	ALLUSR
	ORA	A	;"U" OR "F" OPTION
	JNZ	SOME1
	LDA	USER	;GET CURRENT USER #
	CMP	C	;IS FILE IN CURRENT USER?
	JNZ	MORDIR
SOME1:	MVI	A,0E5H	;CHECK FOR DELETED FILES
	CMP	C
	JZ	MORDIR
	INX	H
	XCHG
	LHLD	NEXTT
	MVI	B,11	; NAME
TMOVE1:	LDAX	D
	ANI	7FH
	MOV	M,A
	INX	D
	INX	H
	DCR	B
	JNZ	TMOVE1
	MOV	M,C	;USER
	INX	H
	MVI	B,20	;OTHER BYTES
TMOVE2:	LDAX	D
	MOV	M,A
	INX	D
	INX	H
	DCR	B
	JNZ	TMOVE2
	SHLD	NEXTT
	LHLD	COUNT
	INX	H
	SHLD	COUNT
	JMP	MORDIR
;
SPRINT:	LHLD	COUNT
	SHLD	OCOUNT
	SHLD	SCOUNT
	MOV	A,H
	ORA	L
	JZ	DFEXIT
	LHLD	TABLE
	XCHG
	LXI	H,ORDER
	LXI	B,32
BLDORD:	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	XCHG
	DAD	B
	XCHG
	PUSH	H
	LHLD	OCOUNT
	DCX	H
	SHLD	OCOUNT
	MOV	A,H
	ORA	L
	POP	H
	JNZ	BLDORD
	LHLD	COUNT
	DCX	H
	MOV	A,H
	ORA	L
	JZ	DONE
SORT:	XRA	A
	STA	SWITCH
	LHLD	SCOUNT
	DCX	H
	SHLD	TEMP
	SHLD	SCOUNT
	MOV	A,H
	ORA	L
	JZ	DONE
	LXI	H,ORDER
SORTLP:	CALL	COMPR
	CM	SWAP
	INX	H
	INX	H
	PUSH	H
	LHLD	TEMP
	DCX	H
	SHLD	TEMP
	MOV	A,H
	ORA	L
	POP	H
	JNZ	SORTLP
	LDA	SWITCH
	ORA	A
	JNZ	SORT
DONE:	LXI	H,ORDER
	SHLD	NEXTT
	LDA	CDSK
	MOV	E,A
	MVI	C,14	;SEL DSK
	CALL	BDOS	;ORIG DRIVE
	LDA	OPTNUM
	ORA	A
	JZ	ENTRY
	LXI	D,MYFCB
	MVI	C,13H
	CALL	BDOS
	LXI	D,MYFCB
	MVI	C,16H
	CALL	BDOS
	INR	A
	JNZ	ENTRY
	CALL	ERXIT
	DB	'++FILE MAKE ERROR$'
ENTRY:	MVI	C,11	;CONS STAT
	CALL	BDOS
	DCR	A
	JZ	ABORT
	LHLD	NEXTT
	MOV	E,M
	INX	H
	MOV	D,M	;DE=ADDR OF ENTRY
	INX	H
	SHLD	NEXTT
	LXI	H,11	;USER OFFSET
	DAD	D
	MOV	A,M	;USER BYTE
	ADI	90H
	DAA
	ACI	40H
	DAA
	MOV	M,A	;NOW ASCII
	INX	H
	MOV	B,M	;EXTENT NUMBER
	LDA	EXTMSK
	CMP	B
	JP	ENTRY2	;SKIP IF EXTMSK >= EXTENT #
	MVI	A,0FFH
	STA	FILESW
ENTRY2:	XCHG
	JMP	PTONE3
;
PTONE3:	PUSH	H
	LDA	OPTNUM	;GET OPTION NUMBER
	ORA	A
	JZ	PTONE4
	CPI	3	;OPTION F?
	JNC	PTONE4
	PUSH	PSW
	MVI	B,5
	LXI	H,FMSG1
	CALL	FTYPE	;OUTPUT "$1 $2" TO FILE
	POP	PSW
	DCR	A	;OPTION M?
	JNZ	PTONE4	;NO, THEN SKIP NEXT PART
	MVI	A,' '
	CALL	FILCHS	;OUTPUT BLANK
	LXI	H,FMSG2
	MVI	B,2
	CALL	FTYPE	;OUTPUT "$3" TO FILE
PTONE4:	POP	H
	MVI	B,8
	CALL	TYPEIT
	CALL	PERIOD
	MVI	B,3
	CALL	TYPEIT
	LDA	OPTNUM	;GET OPTION #
	CPI	2	;OPTION "P"?
	JNZ	PTONE5	;NO, THEN SKIP THIS
	PUSH	H
	PUSH	PSW
	LXI	H,FMSG2
	MVI	B,2
	CALL	FTYPE	;OUTPUT "$3" TO FILE
	POP	PSW
	POP	H
PTONE5:	CPI	4	;OPTION "F"
	CNZ	FILECR
	CALL	SEMIC
	MVI	B,1
	CALL	TYPEIT
	CALL	FILECR
	CALL	SPACE
	MOV	A,M
	CALL	XOB
	INX	H
	INX	H
	INX	H
	MOV	A,M
	CALL	XOB
	INX	H
	LXI	B,1000H ;BYTES & SPACE FLG
EXTLP:	LDA	BLKCNT+1
	ORA	A	;CHECK IF GROUP # IS 1 OR 2 BYTES
	JZ	EXT1
	DCR	B
	MOV	E,M	;SAVE LOW ORDER BYTE
	INX	H
	MOV	A,M
	CALL	XO	;PRINT HIGH ORDER BYTE
	MOV	A,E
	JMP	EXT2
EXT1:	MOV	A,M
EXT2:	CALL	XOB	;PRINT BYTE AND BLANK
NXCLUS:	INX	H
	DCR	B
	JNZ	EXTLP
	PUSH	H
	LHLD	NFILE
	INX	H
	SHLD	NFILE
	CALL	CR
	XRA	A
	STA	FILESW
NX1:	LHLD	COUNT
	DCX	H
	SHLD	COUNT
	MOV	A,H
	ORA	L
	POP	H
	JNZ	ENTRY
;
DFEXIT:	MVI	A,0FFH
	STA	FILESW
	INR	A
	STA	CONSW
	LHLD	BLKCNT
	INX	H
	MOV	D,H
	MOV	E,L	;TOTAL COUNTER IN DE
	PUSH	H	;LEFT COUNTER ON STK
	LHLD	ALLADR
LP3:	MVI	B,8	;BIT COUNT
	MOV	A,M	;ALLOC BYTE
	XTHL		;SAVE PTR,GET LEFT CNT
LP2:	RLC		;BIT TO CY
	JNC	LP1	;UNUSED BLK
	DCX	H	;COUNT OFF
LP1:	DCX	D	;DECR TOTAL
	MOV	C,A
	MOV	A,D
	ORA	E
	JZ	CNTDUN	;FINISHED SCAN
	MOV	A,C	;RESTORE
	DCR	B
	JNZ	LP2
	XTHL
	INX	H	;STEP TBL PTR
	JMP	LP3
;
CNTDUN:	XCHG		;COUNT IN DE
	POP	H	;CLEAR UP STACK
	LDA	BLKSIZ
	CALL	MPY8	;CALC IN KB
	CALL	OUTNUM
	MVI	B,11
	LXI	H,ROOM1
	CALL	TYPEIT
	CALL	FILECR
	CALL	CR
	LHLD	NFILE
	CALL	OUTNUM
	LXI	D,NMSG
	CALL	WRCON
	LDA	OPTNUM
	ORA	A
	JZ	EXIT
	XRA	A
	STA	FILESW
	MVI	A,1AH
	CALL	FILCHR
	CALL	WRSEC
	LXI	D,MYFCB
	MVI	C,10H
	CALL	BDOS
	JMP	EXIT
;
NMSG:	DB	' DIRECT. ENTRIES USED$'
;
DIVIDE:	XRA	A
	MVI	B,10H
DIV01:	DAD	H
	RAL
	CMP	C
	JC	DIV02
	SUB	C
	INX	H
DIV02:	DCR	B
	JNZ	DIV01
	RET
;
MPY8:	LXI	H,0
MPY81:	ORA	A
	RZ
	RAR
	JNC	MPY01
	DAD	D
MPY01:	XCHG
	DAD	H
	XCHG
	JMP	MPY81
;
OUTNUM:	MVI	D,0
	MVI	C,10	;RADIX
OUTN01:	CALL	DIVIDE
	PUSH	PSW
	INR	D
	MOV	A,H
	ORA	L
	JNZ	OUTN01
	MOV	B,D
OUTN02:	POP	PSW
	CALL	NIBBL
	DCR	B
	JNZ	OUTN02
	RET
;
XOB:	CALL	XO
	JMP	SPACE
;
XO:	PUSH	PSW
	RAR
	RAR
	RAR
	RAR
	CALL	NIBBL
	POP	PSW
;
NIBBL:	ANI	0FH
	ADI	90H
	DAA
	ACI	40H
	DAA
	JMP	FILC
;
TYPE:	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,A
	MVI	C,2
	LDA	CONSW
	ORA	A
	CZ	BDOS
	POP	H
	POP	D
	POP	B
	RET
;
WRCON:	LDA	CONSW
	ORA	A
	RNZ
	MVI	C,9
	JMP	BDOS
;
TYPEIT:	MOV	A,M
	CALL	FILCHR
	CALL	TYPE
	INX	H
	DCR	B
	JNZ	TYPEIT
	RET
;
FTYPE:	MOV	A,M
	CALL	FILCHS
	INX	H
	DCR	B
	JNZ	FTYPE
	RET
;
SPACE:	MVI	A,' '	;20H
	JMP	TYPE
;
SPACF:	MVI	A,' '	;20H
FILC:	CALL	FILCHS
	JMP	TYPE
;
CR:	MVI	A,0DH
	MVI	C,2
	CALL	TYPE
	MVI	A,0AH
	JMP	TYPE
;
TEMP:	DS	2
;
ERXIT:	POP	D
	MVI	C,9
	JMP	CALLB
;
ABORT:	MVI	C,1
CALLB:	CALL	BDOS
EXIT:	LHLD	STACK
	SPHL
	RET
;
FILCHR:	CPI	' '	;20H
	RZ
FILCHS:	PUSH	PSW
	LDA	FILESW
	ORA	A
	JNZ	NOFILE
	POP	PSW
	PUSH	PSW
	PUSH	H
	LHLD	BUFAD
	MOV	M,A
	INX	H
	SHLD	BUFAD
	MOV	A,H
	DCR	A
	CZ	WRSEC
	POP	H
NOFILE:	POP	PSW
	RET
;
WRSEC:	PUSH	B
	PUSH	D
	LXI	D,MYFCB
	MVI	C,15H
	CALL	BDOS
	ORA	A
	JZ	WROK
	CALL	ERXIT
	DB	'++WRITE ERROR$'
WROK:	LXI	H,80H
	SHLD	BUFAD
	POP	D
	POP	B
	RET
;
PERIOD:	MVI	A,'.'	;2EH
CHCOM:	CALL	FILCHR
	JMP	SPACE
;
SEMIC:	MVI	A,';'
	JMP	CHCOM
;
FILECR:	MVI	A,0DH
	CALL	FILCHR
	MVI	A,0AH
	CALL	FILCHR
	MVI	A,0FFH
	STA	FILESW
	RET
;
COMPR:	PUSH	H
	MOV	E,M
	INX	H
	MOV	D,M
	INX	H
	MOV	C,M
	INX	H
	MOV	B,M
	XCHG
CMPLP:	LDAX	B
	CMP	M
	INX	H
	INX	B
	JZ	CMPLP
	POP	H
	RET
;
SWAP:	MVI	A,1
	STA	SWITCH
	MOV	C,M
	INX	H
	PUSH	H
	MOV	B,M
	INX	H
	MOV	E,M
	MOV	M,C
	INX	H
	MOV	D,M
	MOV	M,B
	POP	H
	MOV	M,D
	DCX	H
	MOV	M,E
	RET
;
	DS	30
STACK:	DS	2
NFILE:	DW	0
ALLADR:	DW	0	;ALLOC VECT PTR
BLKCNT:	DW	0
BLKSIZ:	DB	1	;1.4 DEFAULT
TABLE:	DW	0
NEXTT:	DW	0
COUNT:	DW	0
EXTMSK:	DB	0	;1.4 DEFAULT
DIR:	DW	64	;1.4 DEFAULT
USER:	DB	0	;1.4 DEFAULT
ALLUSR:	DB	0
ROOM1:	DB	'K REMAINING'
SCOUNT:	DW	0
OCOUNT:	DW	0
CDSK:	DB	0
SWITCH:	DB	0
FILESW:	DB	0FFH
CONSW:	DB	0
OPTNUM:	DB	0
OPTION:	DB	5,'MPNFU'
FMSG1:	DB	'$1 $2'
FMSG2:	DB	'$3'
BUFAD:	DW	80H
MYFCB:	DB	0	;DEFAULT DRIVE
	DB	'NAMES   SUB'
	DB	0
	DS	19
	DB	0
ORDER	EQU	$

	END
