;
; Program: MKDIR
; Author: Richard Conn
; Version: 3.2
; Date: 20 Nov 84
; Previous Versions: 3.1 (28 Aug 84), 3.0 (5 Mar 84)
;
version equ     32

;
;       MKDIR is used to edit existing named directory files and to
; create new ones.
;

;
; Basic Equates
;
z3env   SET     0f400h  ;address of ZCPR3 Environment
;
fcb     equ     5ch
tbuff   equ     80h
cr      equ     0dh
lf      equ     0ah

;
;  SYSLIB Routines
;
       ext     print,putud,getud,logud,retud,zfname,getenv
       ext     cout,crlf,compb,capine,pfn1
       ext     f$open,f$read,f$close
       ext     f$make,f$write,initfcb,f$delete,f$exist,gfa
       ext     bbline,padc,codend,sksp
       ext     hmovb,hfilb
       ext     sort
       ext     z3init,getndr,getwhl

;
; Environment Definition
;
       if      z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
       jmp     start
       db      'Z3ENV' ;This is a ZCPR3 Utility
       db      1       ;External Environment Descriptor
z3eadr:
       dw      z3env
start:
       lhld    z3eadr  ;pt to ZCPR3 environment
;
       else
;
; Internal ZCPR3 Environment Descriptor
;
       MACLIB  Z3BASE.LIB
       MACLIB  SYSENV.LIB
z3eadr:
       jmp     start
       SYSENV
start:
       lxi     h,z3eadr        ;pt to ZCPR3 environment
       endif

;
; Start of Program -- Initialize ZCPR3 Environment
;
       call    z3init  ;initialize the ZCPR3 Env and the VLIB Env
;
; Print Banner
;
       call    print   ;check quiet flag
       db      'MKDIR, Version '
       db      (version/10)+'0','.',(version mod 10)+'0'
       db      cr,lf,0
;
; Check for Wheel Powers
;
       call    getwhl  ;get wheel byte
       jnz     ndir0
       call    print
       db      ' Permission to Run MKDIR Denied - Not Wheel',0
       ret
;
; Check for Availability of Named Directory
;
ndir0:
       call    getndr  ;get location of directory
       jnz     ndir1
       call    print
       db      ' Named Directory Buffer Not Available',0
       ret
ndir1:
       xra     a       ; A=0
       sta     chflag  ; set no changes
       sta     flflag  ; set no file loaded
       sta     ecount  ; set no entries
       lda     fcb+1   ; check for help
       cpi     '/'
       jnz     start1
       call    print   ; print help message
       db      cr,lf,' MKDIR is used to read and edit named directory files.'
       db      cr,lf,'It is invoked by the following forms --'
       db      cr,lf
       db      cr,lf,'         MKDIR                   <-- Enter System'
       db      cr,lf,'         MKDIR dir:filename.typ  <-- Define File First'
       db      cr,lf,'         MKDIR //                        <-- Print this Help'
       db      cr,lf,0
       ret

start1:
       call    putud   ; save current dir for quick return
       lxi     h,dnfile        ; set default file name
       lxi     d,dfcb+1        ; copy into fcb
       mvi     b,11    ; 11 chars
       call    hmovb
       lxi     h,fcb+1 ; pt to fcb
       mov     a,m     ; get name
       cpi     ' '     ; no entry?
       jz      mkdir   ; enter system
       dcx     h       ; pt to name
       lxi     d,dfcb  ; store name in DFCB
       mvi     b,16    ; copy 16 chars
       call    hmovb
       jmp     loadf0  ; enter load file

;
;  Main Entry Point for Loading a File
;
loadfile:
       lxi     d,dfcb  ; set up default file name
       call    zfname  ; extract info
loadf0:
       call    retud   ; get UD in CB
       lda     dfcb    ; get disk
       ora     a       ; current?
       jz      loadf1
       dcr     a       ; A=0
       mov     b,a     ; disk in B
loadf1:
       lda     dfcb+13 ; get user
       mov     c,a     ; in C
       call    logud   ; log into UD to begin search
;
;  Entry Point for Loading File in DFCB
;
ffile:
       lxi     d,dfcb  ; pt to FCB
       call    initfcb ; init it
       call    f$open  ; try to open file
       jz      ffile1
       call    print
       db      cr,lf,'File ',0
       lxi     d,dfcb+1        ; print name
       call    pfn1
       call    print
       db      ' Not Found',0
       jmp     mkdir
ffile1:
       call    getnd   ; get max size of file
       mov     b,a     ; ... in B
       inr     b       ; add 1 for overflow
       call    codend  ; pt to scratch buffer
readf:
       lxi     d,dfcb  ; pt to FCB
       call    f$read  ; read next block
       jnz     readd   ; done if EOF
       push    b       ; save count
       mvi     b,128   ; copy 128 bytes
       lxi     d,tbuff ; ... from TBUFF
       xchg
       call    hmovb
       xchg            ; HL pts to next block to copy into
       pop     b       ; get count
       dcr     b       ; count down
       jnz     readf
       call    print
       db      cr,lf,'Named Directory File too Large for System',0
       call    getud   ; return home
       jmp     mkdir   ; reset parameters
readd:
       call    f$close ; close file
       call    getud   ; return home
;
; Fill in empty space at end of buffer
;
readd1:
       mov     a,b     ; get count
       cpi     1       ; done?
       jz      readd2
       push    b       ; save count
       mvi     b,128   ; fill 128 bytes with 0
       xra     a
       call    hfilb
       pop     b       ; get count
       dcr     b       ; count down
       jmp     readd1
readd2:
       mvi     a,0ffh
       mov     m,a     ; set EOF mark
       sta     flflag  ; set file loaded flag
;
; Determine Entry Count
;
       call    codend  ; pt to first entry
       mvi     b,0     ; set entry count
       lxi     d,18    ; size of entry
readd3:
       mov     a,m     ; get first char of next entry
       ora     a       ; done?
       jz      readd4
       inr     b       ; increment count
       dad     d       ; pt to next
       jmp     readd3
readd4:
       mov     a,b     ; set entry count
       sta     ecount
       jmp     mkdir1  ; enter MKDIR
;
;  Enter MKDIR System and Init Environ
;       Enter at MKDIR if no file loaded, enter at MKDIR1 if file loaded
;
mkdir:
       call    dinit0  ; init directory
       xra     a       ; A=0
       sta     ecount  ; set no entries present
       sta     flflag  ; set no file loaded
       sta     chflag  ; set no changes
mkdir1:
       call    print
       db      cr,lf,'MKDIR Command (? for Help)? ',0
       call    capine  ; get command
       lxi     d,mkdir1        ; set ret address
       push    d
       lxi     h,ctable        ; scan command table for it
       mov     c,a     ; command in C
mkdir2:
       mov     a,m     ; get command letter
       ora     a       ; end of table?
       jz      mkdirh
       cmp     c       ; match?
       jz      mkdir3
       inx     h       ; skip over address
       inx     h
       inx     h
       jmp     mkdir2
mkdir3:
       inx     h       ; get address in HL
       mov     a,m     ; low
       inx     h
       mov     h,m
       mov     l,a     ; HL is address of routine
       pchl            ; "call" routine
;
;  Print MKDIR Command Help
;
mkdirh:
       call    print
       db      cr,lf,'MKDIR Commands are --'
       db      cr,lf,' C -- Change Directory (Add/Rename/Delete Entries)'
       db      cr,lf,' I -- Initialize Directory'
       db      cr,lf,' P -- Print Directory'
       db      cr,lf,' R -- Read Directory File'
       db      cr,lf,' S -- Status of MKDIR Environment'
       db      cr,lf,' W -- Write Directory File'
       db      cr,lf,' X -- Exit Program'
       db      cr,lf,0
       ret
;
;  Command Table
;
ctable:
       db      'C'     ; change directory
       dw      change
       db      'I'     ; init directory
       dw      dinit
       db      'P'     ; print directory
       dw      pwd
       db      'R'     ; read file
       dw      read
       db      'S'     ; status
       dw      status
       db      'W'     ; write file
       dw      write
       db      'X'     ; exit
       dw      exit
       db      0       ; end of table
;
;  Status
;
status:
       call    print
       db      cr,lf,'** MKDIR Status **',cr,lf,cr,lf,0
       call    prec    ; print entry count
       call    print
       db      cr,lf,'Working File Name: ',0
       lxi     d,dfcb+1
       call    pfn1
       call    crlf    ; new line
       call    crlf
       lda     chflag  ; changes made?
       ora     a
       jnz     stat1
       call    print
       db      'No ',0
stat1:
       call    print
       db      'Changes made to Directory since Startup'
       db      cr,lf,0
       lda     flflag  ; file loaded?
       ora     a       ; 0=no
       jnz     stat2
       call    print
       db      'No ',0
stat2:
       call    print
       db      'File has been loaded',cr,lf,0
       ret

;
;  Init Directory
;
dinit:
       call    print
       db      cr,lf,' Are you sure you want to Initialize the Directory '
       db      '(Y/N/<CR>=N)? ',0
       call    capine  ; get response
       call    crlf
       cpi     'Y'     ; Yes is only valid reply
       rnz
dinit0:
       xra     a       ; A=0
       sta     ecount
       cma
       sta     chflag  ; set change flag
       call    getnd   ; get directory size
       mov     b,a     ; ... in B
       call    codend  ; pt to directory
dinit1:
       push    b       ; save counter
       xra     a       ; zero fill
       mvi     b,128   ; 128 bytes
       call    hfilb
       pop     b       ; get counter
       dcr     b       ; count down
       jnz     dinit1
       mvi     m,0ffh  ; store ending mark
       ret
;
;  Read File
;
read:
       pop     psw             ; clear stack
       call    getfname        ; get file name
       ora     a               ; none?
       jz      ffile           ; just find default file and load it
       jmp     loadfile        ; parse entry and load file
;
;  Get File Name from User
;
getfname:
       call    print
       db      cr,lf,'Name of File (<RETURN> = ',0
       call    retud   ; get current DU
       mov     a,b     ; print disk
       adi     'A'
       call    cout
       mov     a,c     ; print user
       call    padc
       call    print
       db      ': ',0
       lxi     d,dfcb+1        ; print default name
       call    pfn1
       call    print
       db      ')? ',0
       mvi     a,0ffh  ; capitalize
       call    bbline  ; get user input
       call    sksp    ; skip to non-blank
       mov     a,m
       ora     a       ; default?
       ret
;
;  Write File
;
write:
       call    getfname        ; get file name
       jz      write1
       lxi     d,dfcb  ; parse into DFCB
       call    zfname  ; parse file name
       call    retud   ; get current DU
       lda     dfcb    ; get disk
       ora     a       ; current?
       jz      write0
       dcr     a       ; adjust for A=0
       mov     b,a     ; ... in B
write0:
       lda     dfcb+13 ; get user
       mov     c,a     ; ... in C
       call    logud   ; log into new dir
write1:
       lxi     d,dfcb  ; open file for output
       call    initfcb
       call    f$exist ; does file exist?
       jz      wf0
       call    gfa     ; get file attributes
       ani     1       ; R/O?
       jz      wf0
       call    print
       db      cr,lf,'File is R/O',0
       jmp     getud   ; go home
wf0:
       call    f$make  ; open file
       inr     a       ; a was 0ffh if error
       jz      werr    ; write error and abort
       call    print
       db      cr,lf,'Writing Directory to Disk ... ',0
       call    getnd   ; get size of file
       mov     b,a     ; count in B
       call    codend  ; pt to start of buffer
wf1:
       push    b       ; save counter
       lxi     d,tbuff ; copy into buffer
       mvi     b,128   ; 128 bytes
       call    hmovb
       lxi     d,dfcb  ; pt to FCB
       call    f$write ; write block
       pop     b       ; get ptr
       jnz     werr
       dcr     b       ; count down
       jnz     wf1
       lxi     d,dfcb  ; pt to FCB
       call    f$close ; close file
       call    getud   ; go home
       xra     a       ; A=0
       sta     chflag  ; set no changes flag
       call    print
       db      'Done',0
       ret
werr:
       call    print
       db      cr,lf,'Error in Disk Write',0
       jmp     getud   ; go home
;
;  Exit from MKDIR
;
exit:
       pop     psw     ; clear stack
       lda     chflag  ; check for any changes
       ora     a       ; 0=No
       rz
       call    print
       db      cr,lf
       db      cr,lf,'Directory has changed since last Write'
       db      cr,lf,'Do you want to write Directory to Disk '
       db      '(Y/N)? ',0
       call    capine  ; get response
       call    crlf    ; new line
       cpi     'N'     ; no?
       cnz     write   ; write if not No
       ret
;
;  Change Directory Contents
;
change:
       call    setduok ; save old DUOK flag and set new one
       call    print
       db      cr,lf,'** MKDIR Change Mode **',0
ch0:
       call    print
       db      cr,lf,'Directory Entry (?<RETURN> for Help)? ',0
       mvi     a,0ffh  ; caps
       call    bbline  ; get user input
       call    sksp    ; skip to non-blank
       mov     a,m     ; get char
       ora     a       ; no input?
       jz      chprint ; done, so print directory
       mov     a,m     ; get first char
       cpi     'X'     ; Exit?
       jz      chexit  ; if so, sort and then exit
       cpi     '/'     ; help?
       jz      chhelp
       cpi     '?'     ; help?
       jnz     ch1
chhelp:
       call    print
       db      cr,lf
       db      cr,lf,'MKDIR Change Mode --'
       db      cr,lf,' You may issue the following commands at this point:'
       db      cr,lf
       db      cr,lf,'         DU:dirname      <-- Create/Rename Dir Entry'
       db      cr,lf,'         DU:             <-- Delete Dir Entry'
       db      cr,lf,'         <RETURN>        <-- Print Directory'
       db      cr,lf,'         X               <-- Exit'
       db      cr,lf,'         ?               <-- Print this Help'
       db      cr,lf,0
       jmp     ch0
chprint:
       call    dsort   ; use dsort routine
       call    pwd     ; use pwd routine
       jmp     ch0     ; continue
ch1:
       lxi     d,tfcb  ; extract user and disk info as well as name
       call    zfname  ; get info
       call    retud   ; get DU
       lda     tfcb    ; get disk
       ora     a       ; default?
       jz      ch2
       dcr     a
       mov     b,a     ; A=0
ch2:
       inr     b       ; A=1
       lda     tfcb+13 ; get user
       mov     c,a     ; ... in C
       mov     a,b     ; save as temp disk and user
       sta     tdisk
       mov     a,c
       sta     tuser
;
;  Scan Directory for Temp Disk and User
;
       call    codend  ; pt to first entry
scanud:
       mov     a,m     ; done?
       ora     a
       jz      scanud2
       inx     h       ; pt to name
       inx     h
       mov     a,m     ; get first char of name
       dcx     h
       dcx     h       ; pt to disk
       cpi     ' '     ; deleted entry?
       jz      scanud1
       mov     a,m     ; get disk
       cmp     b
       jnz     scanud1
       inx     h       ; pt to user
       mov     a,m     ; get user
       dcx     h       ; pt back
       cmp     c       ; compare it
       jz      udfound
scanud1:
       lxi     d,18    ; pt to next
       dad     d
       jmp     scanud
;
; DU not found
;
scanud2:
       lda     tfcb+1  ; delete?
       cpi     ' '     ; space if so
       jnz     addname
       call    print
       db      cr,lf,' DU not Found',0
       jmp     ch0
;
;  Found Possible Directory Entry
;
udfound:
       inx     h       ; found existing entry
       inx     h       ; pt to name
       lda     tfcb+1  ; delete?
       cpi     ' '     ; space if so
       jz      delname
;
;  Rename Function
;
       call    print
       db      cr,lf,' Renaming ',0
       mvi     b,8     ; 8 chars
       call    prhlb   ; print name
       push    h       ; save ptr to name
       call    etest   ; check for duplicate name
       pop     d       ; restore ptr to name
       jz      ch0     ; abort since duplicate
       lxi     h,tfcb+1        ; pt to new name
       mvi     b,8     ; 8 chars
       call    hmovb   ; copy
       mvi     a,0ffh  ; set change
       sta     chflag
       jmp     ch0
;
;  Add Function
;
addname:
       call    print
       db      cr,lf,' Adding ',0
       lxi     h,tfcb+1        ; print name of entry to add
       mvi     b,8
       call    prhlb
;
; Test for Duplicate Name
;
putname:
       call    etest   ; test for duplicate name
       jz      ch0     ; abort if duplicate
;
; Test to see if there is room for another entry
;
putn1:
       mvi     b,18    ; 18 bytes required for entry
       push    h       ; save ptr
putn2:
       mov     a,m     ; check for 0FFH
       cpi     0ffh
       jz      putn3
       inx     h       ; pt to next
       dcr     b
       jnz     putn2
       pop     h       ; get ptr to entry
       jmp     putn4   ; make entry
putn3:
       pop     psw     ; clear stack
       call    print
       db      cr,lf,'** Directory Full **',0
       jmp     ch0
;
; Make Directory Entry
;
putn4:
       mvi     a,0ffh  ; set change flag
       sta     chflag
       lda     tdisk   ; set disk and user
       mov     m,a
       inx     h
       lda     tuser
       mov     m,a
       inx     h
       lxi     d,tfcb+1        ; pt to new name
       xchg
       mvi     b,8     ; 8 chars
       call    hmovb   ; set new name
       call    password        ; enter password into buffer at DE
       lda     ecount  ; print count
       inr     a       ; increment entry count
       sta     ecount
       jmp     precount        ; print count
;
; Test for Duplicate Directory Name
;
etest:
       call    codend  ; pt to first entry
etest0:
       mov     a,m     ; done?
       ora     a
       jz      etest2
       inx     h       ; pt to name
       inx     h
       lxi     d,tfcb+1        ; pt to new name
       mvi     b,8     ; 8 chars
       call    compb   ; compare
       jnz     etest1
       call    crlf
       lxi     h,tfcb+1
       mvi     b,8     ; 8 chars
       call    prhlb   ; print dir name
       call    print
       db      ' is a Duplicate Name',0
       xra     a       ; return Z
       ret
;
; Last Entry was OK - Pt to Next
;
etest1:
       lxi     d,16    ; pt to next entry
       dad     d
       jmp     etest0
;
; No Duplicate Entries - Return NZ and HL pts to after last entry
;
etest2:
       dcr     a       ; set NZ
       ret
;
; Enter 8-char password into memory pted to by HL
;
password:
       push    d       ; save ptr
       call    print
       db      ' -- Password? ',0
       mvi     a,0ffh  ; caps
       call    bbline  ; get line from user
       call    crlf    ; new line
       mvi     b,8     ; 8 chars max
       pop     d       ; pt to destination
pword1:
       mov     a,m     ; get char
       ora     a       ; done?
       jz      pword2
       stax    d       ; put char
       inx     h       ; pt to next
       inx     d
       dcr     b       ; count down
       jnz     pword1
       ret
pword2:
       mvi     a,' '   ; rest are spaces
       stax    d       ; store space
       inx     d       ; pt to next
       dcr     b       ; count down
       jnz     pword2
       ret

;
;  Delete Function
;
delname:
       mvi     a,0ffh  ; change made
       sta     chflag
       call    print
       db      cr,lf,' Deleting ',0
       mvi     b,8     ; 8 chars
       call    prhlb
       mvi     m,' '   ; space fill
       call    dirpack ; pack directory
       call    print
       db      ' -- ',0
       lda     ecount  ; decrement entry count
       dcr     a
       sta     ecount
;
; Print Number of Remaining Entries in Directory
;
precount:
       call    prec    ; print count
       jmp     ch0
prec:
       lda     ecount  ; print remaining count
       call    padc
       call    print
       db      ' Entries in Directory',0
       ret
;
;  Pack Memory-Based Directory -- One Entry has been Deleted
;
dirpack:
       call    codend  ; get address of first entry
       mov     d,h     ; DE pts to it also
       mov     e,l
dirp0:
       mov     a,m     ; get first byte
       ora     a       ; done if zero
       jz      dirp2
       push    b       ; save counts
       inx     h       ; pt to name
       inx     h
       mov     a,m     ; get char
       dcx     h       ; pt back to disk
       dcx     h
       cpi     ' '     ; no entry if space
       jz      dirp1
       mvi     b,18    ; copy 18 bytes
       call    hmovb
       pop     b       ; get counts
       jmp     dirp0
dirp1:
       lxi     b,18    ; pt to next entry
       dad     b
       pop     b       ; get counts
       jmp     dirp0
dirp2:
       mvi     b,18    ; fill last entry with zeroes
       xra     a
       xchg            ; HL pts to last entry
       jmp     hfilb
;
;  Exit Change Routine
;
chexit:
       call    resduok ; restore DUOK flag and fall thru to DSORT
;
;  Sort Directory
;
dsort:
       lda     ecount  ; number of elements
       ora     a       ; any?
       rz              ; done if none
       sta     ssbcnt  ; set count
       call    codend  ; pt to first element
       shld    ssbstrt ; set starting address
       lxi     d,ssb   ; pt to sort specifiction block
       jmp     sort    ; sort
;
;  Sort Compare Routine
;
compare:
       push    h       ; don't change regs
       push    d
       ldax    d       ; compare disk
       cmp     m
       jnz     comp1
       inx     h       ; pt to user
       inx     d
       ldax    d       ; compare user
       cmp     m
comp1:
       pop     d       ; restore regs
       pop     h
       ret

;
; SETDUOK - Save Old DUOK Flag and Set Flag to TRUE
; RESDUOK - Restore Old DUOK Flag
;
setduok:
       push    h       ;save regs
       push    d
       call    getenv  ;get ptr to environment descriptor
       lxi     d,2EH   ;offset to DUOK Flag
       dad     d
       mov     a,m     ;get flag
       sta     duoksav ;save flag
       mvi     m,1     ;turn flag on
       pop     d       ;restore regs
       pop     h
       ret
resduok:
       push    h       ;save regs
       push    d
       call    getenv  ;get ptr to environment descriptor
       lxi     d,2EH   ;offset to DUOK Flag
       dad     d
       lda     duoksav ;get save flag
       mov     m,a     ;set flag
       pop     d       ;restore regs
       pop     h
       ret

;
; Print Names of Directory Elements
;
pwd:
       call    crlf    ; new line
       lda     ecount  ;check count first
       ora     a       ;no entries?
       jnz     pwd01
       call    print
       db      ' No Entries in Directory',0
       ret
;
; Print Header for Password Entries
;
pwd01:
       mvi     b,2     ;2 times
pwd0a:
       call    print
       db
       ' DU : DIR Name - Password    ',0
       dcr     b       ;count down
       jnz     pwd0a
       call    crlf
       mvi     b,2
pwd0b:
       call    print
       db      '----  --------   --------    ',0
       dcr     b       ;count down
       jnz     pwd0b
       call    crlf
;
; Begin Output Processing
;
       mvi     c,0     ;set entry count
       mvi     b,1     ;set disk 1
       call    codend  ;pt to buffer containing new directory
;
; Print Each Resident Command Name
;
pwd1:
       mov     a,m     ;get table entry
       ora     a       ;end of table?
       rz              ;exit
       cmp     b       ;same disk?
       jz      pwd2
;
; Advance to Next Set of Entries for New Disk
;
       mov     b,a     ;set new disk
       mov     a,c     ;get count
       ani     3       ;see if newline already given
       cnz     crlf    ;complete current line
       call    crlf    ;1 additional line
       mvi     c,0     ;reset count
pwd2:
       push    b       ;save counters
;
; Print DU:
;
       mov     a,m     ;get disk
       adi     '@'     ;convert to letter (A to P)
       call    cout
       inx     h       ;pt to user
       mov     a,m     ;get user
       call    padc    ;print user number
       call    print   ;print separator
       db      ': ',0
       inx     h       ;pt to name
;
; Print DIR
;
       call    prname  ;print name of directory
       call    print
       db      ' - ',0
       call    prname  ;print name of password
       pop     b       ;get counters
       inr     c       ;another entry
       push    b       ;save counters
;
; Print Separator
;
       call    print   ;print separator
       db      '    ',0
       pop     b       ;get counters
;
; New Line Counter
;
       inr     c       ;increment entry counter
       mov     a,c     ;check for done
       ani     3       ;every 4
       cz      crlf    ;new line
       jmp     pwd1
;
; Print 8-char name (directory or password) and advance ptr
;
prname:
       mvi     b,8     ;print name
prn1:
       mov     a,m     ;get char
       call    cout
       inx     h       ;pt to next
       dcr     b       ;count down
       jnz     prn1
       ret

;
;  Utilities
;

;
;  Print chars pted to by HL for B bytes
;
prhlb:
       push    h       ; save HL
prhlb1:
       mov     a,m     ; print chars
       inx     h       ; pt to next
       call    cout
       dcr     b       ; count down
       jnz     prhlb1
       pop     h       ; get HL
       ret

;
;  Compute Number of 128-byte blocks in Named Dir
;       Return with Number in A and HL pting to it
;
getnd:
       call    getndr  ; get ptr to NDR and number of entries in A
       push    h       ; save ptr
       mvi     h,0     ; HL = value
       mov     l,a
       dad     h       ; *2
       mov     d,h     ; DE = value * 2
       mov     e,l
       dad     h       ; *4
       dad     h       ; *8
       dad     h       ; *16
       dad     d       ; *18
       mov     a,h     ; /128
       rlc
       ani     0feh
       mov     h,a
       mov     a,l
       rlc
       ani     1
       ora     h       ; A = value * 18 / 128
       inr     a       ; +1
       pop     h       ; get ptr
       ret

;
;  Default File Name
;
dnfile:
       db      'NAMES   '
       db      'NDR'

;
;  Sort Specification Block
;
ssb:
ssbstrt:
       ds      2       ; start address of dir
ssbcnt:
       dw      0       ; number of records to sort
       dw      18      ; 18 bytes/record
       dw      compare ; compare routine
       dw      0       ; no ptr table
       db      0,0     ; don't use ptrs
;
;  Buffers
;
duoksav:
       ds      1       ; save value for DUOK flag
tdisk:
       ds      1       ; temp disk
tuser:
       ds      1       ; temp user
flflag:
       ds      1       ; file loaded flag
chflag:
       ds      1       ; dir changed flag
ecount:
       ds      1       ; entry count
crcnt:
       ds      1       ; new line count
tfcb:
       ds      36      ; temp FCB
dfcb:
       ds      36      ; Default FCB

       end