.TITLE  'SORTED DIRECTORY MAP PROGRAM 2.1'
       .PABS
       .PHEX
       .LOC    0100H
BDOS    =       05H
FCB     =       5CH
;
       JMP     START
;
       .ASCII  '(FMAP 01/18/81)'
;       GOOD FOR DIRECTORIES TO 256 ENTRIES
;
START:  LXI     H,0
       DAD     SP
       SHLD    STACK
       LXI     SP,STACK
       LDA     FCB+16  ;2ND UNIT PARAM.
       ORA     A
       JZ      NODEST
       STA     MYFCB   ;CHG OUTPUT DRIVE
NODEST: LDA     FCB+17
       STA     FILESW  ;FLAG FOR FILE WRITE
       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
       LXI     H,FCB
       MVI     M,'?'   ;MATCH ALL ENTRIES
       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,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
       INX     H       ;TOTAL BLOCK COUNT
       SHLD    BLKCNT
;
OLDCPM: 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:    .ASCII  'FILENAME TYP U EX RC -----EXTENT-----'
       .ASCII  'VER. 2.1 1/18/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     A,M
       CPI     0E5H
       JZ      MORDIR
       MOV     C,A     ;SAVE USER
       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      NFEXIT
       LXI     H,ORDER
       LXI     D,TABLE
       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     FILESW
       CPI     'F'     ;46H
       JNZ     ENTRY
       LXI     D,MYFCB
       MVI     C,13H
       CALL    BDOS
       LXI     D,MYFCB
       MVI     C,16H
       CALL    BDOS
       INR     A
       JNZ     ENTRY
       CALL    ERXIT
       .ASCII  '++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     A,M
       ANA     A
       JZ      ENTRY2
       LXI     H,FILESW
       MOV     A,M
       ORI     1
       MOV     M,A
ENTRY2: XCHG
       JMP     PTONE3
;
WRDEXT: INX     H
       INR     B
       MOV     A,M
       CALL    XOB
       JMP     NXCLUS
;
PTONE3: MVI     B,8
       CALL    TYPEIT
       CALL    PERIOD
       MVI     B,3
       CALL    TYPEIT
       CALL    SEMIC
       MVI     B,1
       CALL    TYPEIT
       CALL    FILECR
       MOV     A,M
       CALL    XOB
       INX     H
       INX     H
       INX     H
       MOV     A,M
       CALL    XOB
       INX     H
       LXI     B,16<8+0 ;BYTES & SPACE FLG
EXTLP:  MOV     A,M
       MOV     E,A
       CALL    XO
       LDA     EXTMSK
       ORA     A
       JNZ     WRDEXT
       INR     C
       MOV     A,C
       ANI     1
       MOV     C,A
       CZ      SPACE
NXCLUS: INX     H
       DCR     B
       JNZ     EXTLP
       PUSH    H
       LXI     H,NFILE
       INR     M
       CALL    CR
       LDA     FILESW
       ANI     0FEH
       STA     FILESW
       LHLD    COUNT
       DCX     H
       SHLD    COUNT
       MOV     A,H
       ORA     L
       POP     H
       JNZ     ENTRY
;
DFEXIT: MVI     B,2
       LXI     H,ROOM1
       CALL    TYPEIT
       LHLD    BLKCNT
       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,8
       LXI     H,ROOM2
       CALL    TYPEIT
       CALL    FILECR
       CALL    CR
       LDA     NFILE
       MOV     L,A
       MVI     H,0
       CALL    OUTNUM
       LXI     D,NMSG
       CALL    WRCON
       LDA     FILESW
       ANI     0FEH
       CPI     'F'     ;46H
       STA     FILESW
       JNZ     EXIT
       MVI     A,1AH
       CALL    FILCHR
       CALL    WRSEC
       LXI     D,MYFCB
       MVI     C,10H
       CALL    BDOS
       JMP     EXIT
;
NMSG:   .ASCII  ' DIRECT. ENTRIES USED$'
;
NFEXIT: XRA     A
       STA     FILESW
       JMP     DFEXIT
;
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
       CALL    BDOS
       POP     H
       POP     D
       POP     B
       RET
;
WRCON:  MVI     C,9
       JMP     BDOS
;
TYPEIT: MOV     A,M
       CALL    FILCHR
       CALL    TYPE
       INX     H
       DCR     B
       JNZ     TYPEIT
       RET
;
SPACE:  MVI     A,' '   ;20H
       JMP     TYPE
;
SPACF:  MVI     A,' '   ;20H
FILC:   CALL    FILCHS
       JMP     TYPE
;
CR:     MVI     E,0DH
       MVI     C,2
       CALL    BDOS
       MVI     E,0AH
       MVI     C,2
       JMP     BDOS
;
TEMP:   .BLKB   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
       CPI     'F'     ;46H
       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
       .ASCII  '++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
       LDA     FILESW
       ORI     1
       STA     FILESW
       JMP     SPACE
;
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
;
       .BLKB   30
STACK:  .BLKB   2
NFILE:  .BYTE   0
ALLADR: .WORD   0       ;ALLOC VECT PTR
BLKCNT: .WORD   0
BLKSIZ: .BYTE   1       ;1.4 DEFAULT
NEXTT:  .WORD   TABLE
COUNT:  .WORD   0
EXTMSK: .BYTE   7       ;1.4 DEFAULT
ROOM1:  .ASCII  '[['
ROOM2:  .ASCII  ']].LFT;0'
SCOUNT: .WORD   0
OCOUNT: .WORD   0
CDSK:   .BYTE   0
SWITCH: .BYTE   0
FILESW: .BYTE   0C9H
BUFAD:  .WORD   80H
MYFCB:  .BYTE   1       ;DRIVE A DEFAULT
       .ASCII  'NAMES   SUB'
       .BYTE   0
       .BLKB   19
       .BYTE   0
ORDER:  .BLKB   512
;
TABLE:  .END