;
;       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