home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR33 / A-R / LOADND12.LBR / LOADND.ZZ0 / LOADND.Z80
Text File  |  2000-06-30  |  29KB  |  1,008 lines

  1. ; Program: LOADND
  2. ; Log in a disk and update the ZCPR3 system NDR
  3.  
  4. ;LOADND is copyright by A. E. Hawley January 30, 1987.
  5. ;It may be freely distributed, but it must not be sold 
  6. ;either separately or as part of a package without the 
  7. ;written consent of the author.  The author may be reached 
  8. ;via electronic mail at the Ladera Z-Node in Los Angeles,
  9. ;213-670-9465, or through the Lillipute Z-Node in Chicago 
  10. ;at 312-649-1730.
  11. ;
  12. ;LOADND is released for beta test through the Z-system 
  13. ;users group Z-SIG on January 30, 1987 by the author.
  14.  
  15. ; Author: Al Hawley, Ladera Z-Node, (213) 670-9465
  16.  
  17. vers    equ    '1'
  18. rev    equ    '2'
  19. ; Version: 1.2  by AEH
  20. ; Version Date: 01/30/87
  21. ; Added error and activity reporting routines with QUIET flag response.
  22. ; Removed 'wired-in' options from code - put all in table near start
  23. ;   of pgm where they are marked for easy access with ZDM. Help screen
  24. ;   is automatically initialized to reflect any changes in option
  25. ;   designators as well as the name under which the program is invoked.
  26.  
  27. ; Version: 1.1
  28. ; Version Date: 12/26/86
  29. ; Previous versions: DSKNDR 1.1 (see LOADND.DOC)
  30. ;
  31. ; PROGRAM FUNCTION:
  32. ; Log in a disk and update the ZCPR3 system NDR
  33. ; to reflect the directory names for the new disk,
  34. ; if any. Gets directory names from a disk file like
  35. ; *.NDR or from filenames starting with some 
  36. ; defined character like '-'.
  37. ; See LOADND.DOC for details.
  38.  
  39. ;VERSION HISTORY
  40. ;
  41. ; LOADND V1.1   -   Name change only. Was DSKNDR 
  42. ;            New name better reflects function.
  43.  
  44. ;***************************************************
  45. ;THIS SOURCE FILE IS CODED TO ASSEMBLE WITH THE
  46. ; ZAS (FROM ECHELON) AND COMPATIBLE ASSEMBLERS.
  47. ; OTHERS MAY REQUIRE SOME TRANSLATION.
  48. ;***************************************************
  49.  
  50. ;The following tells ZAS to pass
  51. ;names of libraries to ZLINK. The link command line
  52. ;does not need to name the libraries
  53.  
  54.     .REQUEST Z3LIB,SYSLIB
  55.  
  56. ; External Z3LIB Routines
  57.     EXT    Z3INIT,GETNDR,GETEFCB,GETMDISK
  58.     EXT    GETWHL,GETQUIET
  59.  
  60. ; External SYSLIB Routines
  61.     EXT    CODEND,DBUFFER,DIRF,SUA,INITFCB
  62.     EXT    SETDMA,F$OPEN,F$READ,RETUD,LOGUD
  63.     EXT    MULHD,SSBINIT,SORT,COMPB
  64.     EXT    SKSP,SKNSP,PSTR,PRINT
  65. ;
  66. ; External VLIB Routines
  67. ;
  68. ; Other External Library Routines
  69. ;
  70. ; COMMON ASCII & SYSTEM DEFINITIONS
  71.     .xlist
  72.     .IN    SYSDEF
  73.     .list
  74. ;DEFINITIONS UNIQUE TO THIS PROGRAM
  75.  
  76. ENTLEN    equ    18    ; NDR Entry Len = 18 bytes
  77. DIRLEN    EQU    16    ; DIR Entry length returned by DIRF
  78. DIRLTR    EQU    '-'    ; 1st char of directory-name files
  79. KEEPDR    EQU    'A'-40H    ; Drive identifier for directory name
  80.             ; entries to RETAIN from the *.NDR file
  81.             ; read from the target disk.
  82.  
  83. ;***************************************************
  84. ;MACRO DEFINITIONS
  85.  
  86. ;load reg hl from the address in hl
  87. LDHLHL    MACRO
  88.     LD    A,(HL)
  89.     INC    HL
  90.     LD    H,(HL)
  91.     LD    L,A
  92.     ENDM
  93.  
  94. ;***************************************************
  95.  
  96. ;program code starts here..
  97.  
  98.     JP    START
  99.     DB    'Z3ENV'        ;This is a ZCPR3 Utility
  100.     DB    1        ;External Environment Descriptor
  101.  
  102. Z3EADR: DW    0FE00H        ;this is corrected by Z3INS
  103.  
  104. ;proctl: contain the default process option. possible values are:
  105. ;    0    if NDR file is present use it, else use marked files
  106. ;    1    if marked files present use them, else use NDR file
  107. ;    2    use marked files only (ignore NDR files)
  108. ;    3    use NDR file only (ignore marked files)
  109. proctl:    db    0        ;process control byte, default value
  110.     db    0        ;reserved for pgm use. do not change.
  111.  
  112.     DB    'DIRLTR>'    ;marker, for debugger change of...
  113. char1:    db    '-'        ; first char of dir-name files
  114.     db    ' NDROPT>'    ;marker, for option letter for NDR option
  115. char2:    db    'N'
  116.     db    ' KEEP>'        ;marker for drive designator of names
  117.                 ; to keep from the .NDR file
  118. keeper:    db    keepdr
  119.  
  120.     db    ' NDRFILE>'
  121. ndrfls:    db    0
  122.     db    '????????NDR'    ;11 char for .ndr file spec
  123.     db    ' DASHFILE>'
  124. dashfn:    db    0
  125.     db    '-??????????'    ;11 char ambiguous dash fn.ft
  126.  
  127. START:    LD    HL,(Z3EADR)    ;pt to ZCPR3 environment
  128.     CALL    Z3INIT        ;initialize the ZCPR3 Environment
  129.  
  130. ;***************************************************
  131. ;This is the main routine, from which all other
  132. ;functions are called.
  133.  
  134. MAIN:    ld    (stak), sp    ; save callers stack for exit
  135.     ld    sp, stak    ; set up local stack
  136.     call    init        ; test for z3env and sys NDR,
  137.                 ; initialize local ndr buffer
  138.                 ; store data for NDR, default disk
  139.  
  140.     call    parse        ;parse command tail
  141.     jp    z,help        ;help required. do it.
  142.  
  143.     call    copyin        ;get system NDR w/o tgt dr dirnames
  144.  
  145.     call    getdname    ;get dash- and *.ndr disk dir names
  146.  
  147.     call    case        ;copy dir names into local NDR buffer
  148.                 ;using procedure specified by options
  149.  
  150.     jr    z,exit        ;if z, no names were found, so abort.
  151.  
  152.     call    ndrsrt        ;sort the entries into D/U order
  153.  
  154.     call    copyout        ;copy local ndr buffer to system ndr
  155.  
  156. exit:    call    wrapup        ;deinitialization
  157.     ld    sp, (stak)    ;finished. return quietly (no warm boot)
  158.     ret
  159.  
  160. ;***************************************************
  161.  
  162. init:
  163.  
  164. ;validate the environment stored at the normal
  165. ; start of the program against the system env.
  166. ; by comparing the string 'Z3ENV' which must be
  167. ; in the location (pgm-start + 9) and environment
  168. ; address +3. Returns Z if the environment reference
  169. ; is valid, NZ if the strings don't match.
  170. ;enter with hl->env address
  171.     inc    hl        ;->'Z3ENV' in sys env.
  172.     inc    hl
  173.     inc    hl
  174.     ld    de,[z3eadr-6]    ;->local 'Z3ENV'
  175.     ld    b,5        ;compare 5 bytes
  176.     call    compb
  177.     ld    a,8        ;error code
  178.     jp    nz,exinit    ;if nz, pgm not installed
  179.  
  180. ; test for wheel. Only priviledged users modify the system.
  181.     call    getwhl
  182.     ld    a,6        ;error code
  183.     jp    z,exinit    ;deny use if no wheel
  184.  
  185. ; initial memory allocation
  186.     call    codend        ;set hl-> first free memory
  187.     ld    (freesp),hl    ;store in freespace pointer
  188.     ld    (bcb0),hl    ; setup bcb0 as local ndr buff
  189.  
  190. ; set up the default drive to process
  191.     call    retud        ;B=disk(0-15), C=user(0-31)
  192.     ld    a,b
  193.     inc    a        ;disk(1-16)
  194.     ld    (tgtdsk),a    ; the default drive
  195.     add    a,'A'-1        ; convert to ascii
  196.     ld    (tdrv),a    ; put ascii char in message
  197.     ld    (defdrv),a    ; ...and in help message
  198.  
  199. ; get Named Directory pointer, exit with error if none
  200.     call    getndr        ; get ndr addr & length
  201.     ld    (z3ndb),hl    ; store the address, and
  202.     ld    (ndblks),a    ; the max number of entries
  203.     ld    a,7        ; error code
  204.     jp    z,exinit    ; exit if no NDR
  205.  
  206. ; initialize Buffer Control Block 0 as the
  207. ; descriptor for the local buffer which will
  208. ; contain the copy of system NDR entries.
  209.  
  210.     ld    hl,(ndblks)    ; max number of blocks
  211.     ld    de,entlen    ; length of each block
  212.     ld    (bcb0+4),de    ; store in Buffer Control Block
  213.     call    mulhd        ; hl*de = buffer data bytes
  214.  
  215. ; The system NDR is a multiple of 128 bytes in length
  216.     ld    de,80h        ; round off to the
  217.     add    hl,de        ; ..next higher multiple
  218.     ld    a,l        ; ..of 128 bytes (80h)
  219.     and    a,80h
  220.     ld    l,a        ; hl = buffer length
  221. ; save this to avoid another calculation later
  222.     ld    (size0),hl    ; save for copyout:
  223.     push    hl        ; ..and for null fill
  224.     ld    de,(bcb0)    ; buffer start addr
  225.     push    de        ; ..and save for null fill
  226.     add    hl,de        ; loc for next buffer
  227.     ld    (bcb0+8),hl    ; save in Buf. Cntl. Blk.
  228.     ld    (freesp),hl    ; ..and for global use
  229.  
  230. ;initialize the buffer that will contain the
  231. ;local NDR image to nulls. Since subsequent
  232. ;operations do not disturb the unused portions
  233. ;of the buffer, its format is suitable for
  234. ;overlaying the system NDR once the entries are
  235. ;sorted in D,U order.
  236.     pop    hl        ;buffer start
  237.     pop    bc        ;buffer length
  238.     dec    bc        ;..for fill algorithm
  239.     ld    (hl),0        ;the first null
  240.     ld    d,h        ;make destination addr
  241.     ld    e,l
  242.     inc    de
  243.     ldir            ;chase the null through
  244.                 ;the buffer
  245.  
  246. ;initialize the first character of the ambiguous
  247. ; file name in the fcb used to get directory names
  248. ; Usually this character is a '-' (see equates, above).
  249.     ld    a,(char1)
  250.     ld    (dashfn+1),a
  251.  
  252. ;load the default option char(s) into the help message
  253.     ld    (opt0+1),a    ;use the same char for
  254.     ld    (opt1),a    ;..designating options
  255.     ld    (opt2),a
  256.     ld    a,(char2)    ;the option char for NDR file use
  257.     ld    (opt0),a
  258.     ld    (opt1+1),a
  259.     ld    (opt3),a
  260.  
  261. ;store the default option selection in the help message
  262.     ld    hl,optbl    ;list of locations in hlpmsg
  263.     ld    de,(proctl)    ;get default option number
  264.     add    hl,de
  265.     add    hl,de        ;index into the list
  266.     ldhlhl            ;get the address
  267.     ld    e,(hl)        ;get the letters, the
  268.     inc    hl
  269.     ld    d,(hl)        ;..second may be a space
  270.     ld    (defopt),de    ;store in the help msg
  271.  
  272. ;get the name under which this program was
  273. ; invoked and put it in the help message
  274. ; if this is the first invocation
  275.     ld    a,(myname)
  276.     cp    a,' '        ;space if first time
  277.     jr    nz,xinit    ;jmp if already done
  278.     call    getefcb
  279.     jr    z,xinit        ;jmp if no ext fcb
  280.     inc    hl        ;point to pgm name
  281.     ld    de,myname
  282.     ld    bc,8
  283.     ldir            ;transfer the name...
  284.  
  285. xinit:    xor    a
  286.     ld    (errflg),a
  287.     dec    a        ;mark successful return(-1, NZ)
  288.     ret
  289.  
  290. exinit:
  291.     ld    (errflg),a
  292.     jp    help
  293.  
  294. ;***************************************************
  295.  
  296. ;CASE: is the command dispatcher. It uses the option
  297. ; flag to control the use of disk-resident .ndr file
  298. ; or the marked files to build the new dir names for 
  299. ; the target disk.
  300. case:
  301.     ld    hl,cstbl
  302.     ld    bc,(proctl)    ;get option number
  303.     add    hl,bc
  304.     add    hl,bc
  305.     ld    a,(hl)
  306.     inc    hl
  307.     ld    h,(hl)
  308.     ld    l,a
  309.     jp    (hl)
  310.  
  311. cstbl:    dw    case00,case01,case02,case03
  312.  
  313. ;***************************************************
  314.  
  315. ; The CASExx routines fetch the new dir names
  316. ; and transfer them into the local copy of the
  317. ; system-resident Named directory buffer.
  318.  
  319. case00:    ;attempt to get names from an .ndr file
  320.     call    chkndr
  321.     jp    nz,ndrcpy    ;..and return nz (success)
  322.     ; fall through if no ndr, and...
  323. case02:    ;..get names from marked files on disk
  324.     call    dshcpy
  325.     ret        ;nz = success, z = no names
  326.  
  327. case01:    ;attempt marked files first
  328.     call    dshcpy
  329.     ret    nz    ;return if successful
  330.     ;else (no marked files) fall through, to..
  331.  
  332. case03:    ;..get names from .ndr file on target disk
  333.     call    chkndr
  334.     jp    nz,ndrcpy    ;..and return nz (success)
  335.     ret            ;z = no names
  336.  
  337. ;***************************************************
  338.  
  339. ;wrapup: set/reset system messages, disk system,
  340. ; and any other miscellaneous housecleaning
  341. ; before returning to the operating system.
  342.  
  343. wrapup:
  344.  
  345. ;>>> none required yet <<<
  346.  
  347.     ret
  348.  
  349. ;***************************************************
  350.  
  351. help:    ld    bc,(errflg)
  352.     ld    hl,hlpndx
  353.     add    hl,bc
  354.     add    hl,bc
  355.     ldhlhl
  356.     call    pstr
  357.     jp    exit
  358.  
  359. hlpndx:    dw    hlpmsg,em1,em2,em3,em4,em5
  360.     dw    em6,em7,em8,em9
  361.  
  362. ;***************************************************
  363.  
  364. ; parse: scan the command tail for command line options
  365. ; If the first argument does not start with '/', use its
  366. ; first character as the potential drive designator. If
  367. ; the drive designator is valid, store it for later use.
  368. ; If an argument starts with '/', use the following one
  369. ; or two characters to define the processing sequence to
  370. ; use in locating the new entries for the system NDR image.
  371. ; If invalid entry is found in either argument,
  372. ; return (Z) to indicate an error (and invoke help).
  373. ;  NOTE that commas in the command tail are converted to
  374. ; spaces; space(s) are then used to elimit arguments.
  375. ; Thus, arguments may not contain spaces or commas.
  376.  
  377. parse:    push    ix
  378.     ld    ix,opt0        ;->option characters in hlp
  379.     ld    hl,tbuf        ;point to command tail
  380.     ld    a,(hl)        ;get character count
  381.     or    a,a        ;test for null
  382.     jr    z,pdone        ;use defaults if no args
  383.  
  384.     inc    hl        ;point to arg string
  385.     call    ctosp        ;change commas to spaces
  386.     call    sksp        ;skip to first non-space
  387.     ld    a,(hl)
  388.     cp    '?'        ;help requested via '?' ?
  389.     jr    z,hexit
  390.     cp    '/'        ;options follow?
  391.     jr    z,options
  392.     call    drvtst        ;test for valid drive designator
  393.     jr    z,hexit        ;bad arg - return z for help
  394.     ld    (tdrv),a    ;save for progress message
  395.     sub    a,'A'-1        ;convert to 1...16
  396.     ld    (tgtdsk),a    ;store converted drive designator
  397.  
  398.     call    sknsp        ;skip to next space or eos
  399.     ld    a,(hl)
  400.     or    a,a        ;test for null
  401.     jr    z,pdone        ;no more arguments
  402.     call    sksp        ;skip to next non-space
  403.     ld    a,(hl)
  404.     cp    a,'/'        ;option ?
  405.     jr    nz,pdone    ;ignore if not option designator
  406. options:
  407.     inc    hl
  408.     ld    a,(hl)        ;get the option character
  409.     or    a        ;if 0, '/' was only char
  410.     jr    z,hexit        ;..and this is a help request
  411.     cp    '/'        ;help requested via '//'?
  412.     jr    z,hexit        ;errflg is still 0
  413.     cp    (ix)        ;NDR option char?
  414.     ld    bc,3        ;b=0, c=3(for option 'N')
  415.     jr    z,ndopt
  416.     ld    c,2
  417.     cp    (ix+1)        ;dashfile option char?
  418.     jr    z,dnopt
  419.     ld    a,9        ;error code 9 - options help
  420.     ld    (errflg),a
  421.     jr    hexit        ;bad option, use help exit
  422.  
  423. dnopt:    inc    hl
  424.     ld    a,(hl)        ;get possible second option letter
  425.     cp    (ix)        ;NDR option char?
  426.     jp    nz,savopt    ;no, option is case02
  427.     ld    c,1        ;yes, option is case01
  428.     jr    savopt
  429.  
  430. ndopt:    inc    hl
  431.     ld    a,(hl)        ;get possible second option letter
  432.     cp    (ix+1)        ;dashfile option char?
  433.     jp    nz,savopt    ;no, option is case03
  434.     ld    c,0        ;option nd=case00
  435.  
  436. savopt:    ld    (proctl),bc    ;save option in proc cntl word
  437.  
  438. pdone:    ld    hl,drives    ;tell what's happening
  439.     call    qpstr
  440.  
  441.     ld    a,(tgtdsk)    ;get drive (1...16)
  442.     dec    a        ;make 0...15
  443.     ld    b,a
  444.     call    logud        ;log it in
  445.  
  446. xparse:    xor    a        ;normal exit
  447.     dec    a
  448.     pop    ix
  449.     ret            ;return 0ff and nz (true)
  450.  
  451. hexit:    xor    a        ;exit for help screen
  452.     pop    ix
  453.     ret            ;bad option, z=call for help
  454.  
  455. ;***************************************************
  456.  
  457. ; scan a null terminated string pointed to by HL,
  458. ; replacing commas with spaces. This is used to
  459. ; make commas & spaces eqivalent in the command line.
  460.  
  461. ctosp:    push    hl
  462. ctosp0:    ld    a,(hl)        ;get a char
  463.     or    a,a        ;test for eos
  464.     jr    z,xctosp    ;done if null
  465.     cp    ','        ;comma?
  466.     jr    nz,ctosp1    ;skip if not
  467.     ld    (hl),' '    ;yes, replace with space
  468. ctosp1:    inc    hl        ;prepare for next char
  469.     jr    ctosp0
  470. xctosp:    pop    hl
  471.     ret
  472.  
  473. ;***************************************************
  474.  
  475. ;Test the character in Accum for valid drive
  476. ;designator which does not exceed the MAXDISK
  477. ;value obtained from the system environment.
  478. ;preserve all registers. Return zflag=nz for
  479. ;valid drive, and =z for invalid drive designator
  480.  
  481. drvtst:    push    bc
  482.     ld    c,a
  483.     sub    a,'A'        ;< 'A'?
  484.     jr    c,notdrv
  485.     ld    b,a        ;save it (range 0-15)
  486.     call    getmdisk    ;max disk (1-16) from sysenv
  487.     sub    a,b        ;maxdisk > requested disk?
  488.     jr    c,notdrv
  489.  
  490.     ld    a,c        ;return the character
  491.     pop    bc
  492.     or    a,a        ;drive ok, return NZ
  493.     ret
  494.  
  495. notdrv:    xor    a,a        ;return as if logic false(z)
  496.     ld    a,5        ;error code - bad drive
  497.     ld    (errflg),a
  498.     pop    bc
  499.     ret
  500.  
  501. ;***************************************************
  502.  
  503. ; copyin: copy the existing NDBuff into
  504. ; lclndr(buffer 0), ignoring target-disk entries
  505. ; Enter buffer data in bcb0 to permit access.
  506.  
  507. copyin:    push    ix
  508.     ld    ix,bcb0+2    ;for counting number of entries
  509. ;    ld    (ix),0        ;initialize
  510.     ld    de, (bcb0)
  511.     ld    hl, (z3ndb)    ; prepare copying, (hl) to (de)
  512.     jr    cpin02
  513.  
  514. cpin01:    ld    bc, entlen
  515.     ld    a, (tgtdsk)    ; is it for target disk?
  516.     cp    (hl)
  517.     jr    z, noload    ; don't load if yes.
  518.     ldir            ; no, load it.
  519.     inc    (ix)        ;count entries in bcb0+2
  520.     jr    cpin02
  521. noload:    add    hl, bc        ; incr. source addr
  522. cpin02:    xor    a        ; Disk == 0 means end
  523.     or    (hl)        ;end of ND entries?
  524.     jr    nz, cpin01    ;if no, get more
  525.  
  526. ;transfer complete. Now complete filling in the BCB
  527.     ld    (bcb0+6),de    ;save pointer to next avail. loc
  528.     pop    ix
  529.     ret
  530.  
  531. ;***************************************************
  532.  
  533. ;1) Get the disk directory names like *.NDR, if any,
  534. ; and store them in buffer 1. Allocate space via bcb1.
  535. ;2) Get file names marked as directory name files from
  536. ; the target disk for all user areas, if any exist.
  537. ; Store them in buffer 2. Allocate space via bcb2.
  538. ; These names are marked by <DIRLTR> as the first
  539. ; character of the filename. Translate the names in the
  540. ; buffer to ndr format, ready for potential transfer
  541. ; to 'lclndr'.
  542.  
  543. getdname:
  544. ;set up target fcb to select names like *.ndr
  545.     push    ix        ;save for possible system use
  546.     ld    de,ndrfls    ;specify *.ndr file names
  547.     ld    bc,dirlen    ;record size
  548.     ld    ix,bcb1        ;specify the buffer control block
  549.  
  550.     call    getsfn        ;GET Selected File Names from tgt disk
  551.  
  552. ;set up target fcb to select file names like '-???????'
  553.     ld    de,dashfn    ;specify <DIRLTR> filenames
  554.     ld    bc,dirlen    ;record size
  555.     ld    ix,bcb2        ;specify the buffer control block
  556.  
  557.     call    getsfn        ;GET Selected File Names from tgt disk
  558.  
  559.     pop    ix
  560.  
  561. ;translate to ndr format (D,U,FN). There isn't
  562. ;room for the Password field, so it's added later.
  563.     call    dtondr        ;translate dashfiles to ndr format
  564.     ret
  565.  
  566. ;***************************************************
  567.  
  568. ;dtondr: restructures the dash-filenames returned
  569. ;by dirf (in buffer 2) to conform to .ndr format
  570. ;on exit: A = 0 (empty buffer) or -1 (success)
  571. ; and with zflag set appropriately
  572. ; BC,DE,HL,IX are preserved
  573.  
  574. dtondr:    push    ix        ;preserve registers used
  575.     push    bc
  576.     push    de
  577.  
  578. ;setup initial parameters
  579.     ld    a,(bcb2+2)    ;number of entries
  580.     and    a,a        ;adjust zero flag
  581.     jr    z,dtondx    ;ret if empty with z
  582.     ld    b,a        ;transfer to B reg, for counting
  583.     ld    a,(tgtdsk)    ;get target drive
  584.     ld    c,a        ;.. in register c
  585.     ld    de,16        ;length of each record
  586.     ld    ix,(bcb2)    ;ix->dash file buffer
  587.  
  588. ;do the following for each record. There are B
  589. ;records to process.
  590. dtond1:    ld    a,(ix)        ;move user number to replace
  591.     ld    (ix+1),a    ;..the dash
  592.     ld    (ix),c        ;replace old user with drive
  593.     add    ix,de        ;point to next record
  594.     djnz    dtond1        ;repeat b times
  595. ;done. The first 9 bytes are in .ndr form
  596.     xor    a,a        ;mark successful
  597.     dec    a
  598. dtondx:    pop    de
  599.     pop    bc
  600.     pop    ix
  601.     ret
  602.  
  603. ;***************************************************
  604.  
  605. ;getsfn: gets file names from target disk which match
  606. ;the ambigous specification in the target fcb.
  607. ;Entry: (DE) = Target FCB
  608. ;   A = flag byte as follows:
  609. ;    bit(s)    Meaning when set (=1)
  610. ;    7    select non-system file names
  611. ;    6    select system file names
  612. ;    5    select all user areas
  613. ;    4 - 0    user area (0-31) to select
  614. ;        if bit 5 = 0
  615.  
  616. getsfn:
  617.     push    bc        ;record length
  618.     ld    (ix+4),c    ;save in buff cntl blk
  619.     ld    (ix+5),b
  620.     ld    hl,(freesp)    ;use next free memory
  621.     ld    a,11100000B    ;all files in all user areas
  622.     call    dirf        ;fetch names,put in buffer
  623. ;HL= address of the first selected dir item,
  624. ;BC= number of DIRLEN byte entries in this buffer
  625.  
  626.     ld    (ix+0),l    ;fill in the BCB
  627.     ld    (ix+1),h
  628.     ld    (ix+2),c
  629.     ld    (ix+3),b
  630.     pop    de        ;record length
  631.     call    incrbf        ;calc buffer end +1
  632.     ld    (ix+8),e    ;save in BCB
  633.     ld    (ix+9),d
  634.     ld    (ix+6),-1    ;mark buffer full
  635.     ld    (ix+7),-1
  636.     ret
  637.  
  638. ;***************************************************
  639.  
  640. ;incrbf: allocates next buffer starting addr
  641. ; ENTRY: HL = start of current buffer,
  642. ; BC = number of entries in current buffer
  643. ; DE = size of each entry in bytes
  644. ; EXIT: HL, BC are unchanged, DE = HL+(BC*DE)
  645.  
  646. incrbf:    push    hl
  647.     ld    h,b        ;setup for multiply
  648.     ld    l,c
  649.     call    mulhd        ;HL<-(entries)*(record size)
  650.     ex    de,hl        ;..in DE
  651.     pop    hl        ;get start addr
  652. ;    push    hl        ;get start addr
  653.     add    hl,de        ;add space used by entries
  654.     ex    de,hl        ;next buffer start in DE
  655.     ld    (freesp),de    ;update freespace pointer
  656. ;    pop    hl        ;recover start addr
  657.     ret
  658.  
  659. ;***************************************************
  660.  
  661. ;dshcpy: copy formatted dash names from the dirf
  662. ;buffer (buffer 2) to the lclndr buffer (buffer 0).
  663. ;Each du/name occupies 9 bytes, so append 9 spaces
  664. ;to provide the 8th byte of the name, and a blank
  665. ;password entry. BC,DE,HL are destroyed.
  666.  
  667. dshcpy:    push    ix        ;save - system may be using it
  668.     ld    ix,bcb0+2    ;use to count records copied
  669.     ld    de,(bcb0+6)    ;dest is next free space in lclndr
  670.     ld    hl,(bcb2)    ;source is dirf dash buffer
  671.     ld    a,(bcb2+2)    ;number of entries to copy
  672.     and    a,a
  673.     ld    b,a        ;for counting records
  674.     ld    a,2        ;error code, in case no records
  675.     jr    z,errdshx    ;return with no copy and z set
  676.  
  677. dshcp1:    call    roomck        ;space for more in destination?
  678.     jr    c,errdshx    ;cy set=no. error code 1 in reg A
  679.  
  680.     push    bc        ;save the record counter
  681.     ld    bc,9        ;load the byte counter
  682.     push    bc        ;..and save for further use
  683.     ldir            ;copy d,u, and 7-byte name
  684.     pop    bc
  685.     push    hl        ;save dash buffer pointer
  686.     ld    hl,space    ;now transfer 9 spaces
  687.     ldir
  688.     inc    (ix)        ;add one to count in bcb0
  689.     pop    hl        ;recover source pointer
  690.     ld    bc,7        ;sorce bytes to skip
  691.     add    hl,bc        ;point to next record
  692.     pop    bc        ;recover the record counter
  693.     djnz    dshcp1        ;repeat till all records copied
  694.  
  695.     ld    (bcb0+6),de    ;record next free loc in the buffer
  696.     xor    a,a        ;make a null (or logic false)
  697.     ld    (de),a        ;mark next entry null
  698.     ld    (errflg),a    ;reset error flag
  699.     pop    ix
  700.     ld    hl,mfmsg    ;report where update is from
  701.     call    qpstr
  702.     xor    a
  703.     dec    a        ; return logical true (nz)
  704.     ret
  705.  
  706. errdshx:            ; return false if dest. is full
  707.     ld    (errflg),a    ; or if nothing to copy
  708.     xor    a
  709.     pop    ix
  710.     ret
  711.  
  712. ;*************************************************************
  713. ;routine to locate .NDR files and, if found, load the
  714. ;first such file into memory for selective copy into
  715. ;the lclndr buffer. Load address is defined as buffer 3.
  716.  
  717. chkndr:    ld    a,(bcb1+2)    ;get number of entries
  718.     or    a,a        ;any entries?
  719.     ld    a,4        ;error code - no NDR file found
  720.     ld    (errflg),a
  721.     ret    z        ;z = return logical false
  722.  
  723. ;we have at least one .ndr file. Get the first.
  724.     ld    hl,(bcb1)    ;get user number
  725.     ld    a,(hl)
  726.     call    sua        ;set user area
  727.  
  728.     inc    hl        ;hl -> filename
  729.     ld    de,tfcb+1    ;use transient fcb
  730.     ld    bc,11        ;11 char in filename
  731.     ldir            ;copy to fcb
  732.  
  733.     ld    de,tfcb        ;initialize fcb
  734.     call    initfcb
  735.     ld    a,(tgtdsk)    ;use target drive
  736.     ld    (de),a
  737.  
  738.     call    f$open        ;open the .ndr file
  739.  
  740.     ld    hl,entlen
  741.     ld    (bcb3+4),hl    ;record length
  742.     ld    hl,(freesp)    ;set area to read to
  743.     ld    (bcb3),hl    ;buffer 3 start addr
  744.     call    setdma
  745.     ld    bc,128        ;constant for increment dma
  746.  
  747. rdndr1:    call    f$read        ;read 128 bytes
  748.     or    a
  749.     jr    nz,rdndrx    ;done, return logic true
  750.     add    hl,bc
  751.     call    setdma
  752.     jr    rdndr1        ;go get more until done
  753.  
  754. rdndrx:    ld    (bcb3+8),hl    ;end of buffer
  755.     ld    (freesp),hl    ;..and begin free memory
  756.     xor    a
  757.     ld    (errflg),a    ;show no error
  758.     dec    a        ;return nz
  759.     ret
  760.  
  761. ;***************************************************
  762.  
  763. ;ndrcpy: copy NDR entries from buffer 3
  764. ;starting at (bcb3) to the lclndr buffer. Copy
  765. ;only those entries whose Drive is keepdr, changing
  766. ;the drive designation to (tgtdsk) during the copy.
  767.  
  768. ndrcpy:    push    ix
  769.     ld    ix,bcb0+2    ; for counting number of entries
  770.     ld    de, (bcb0+6)    ; dest = next free loc in lclndr
  771.     ld    hl, (bcb3)    ; prepare copying, (hl) to (de)
  772.     ld    a,(ix)        ; save for test of records copied
  773.     ld    (temprc),a
  774.     jr    ndrcp2
  775.  
  776. ndrcp1:    call    roomck        ;space for more in destination?
  777.     jr    c,exndrcp    ;cy set=no. Acc=1 to force logic false
  778.  
  779.     ld    bc, entlen
  780.     ld    a, (keeper)    ; get drive number to retain
  781.     cp    (hl)        ; is this one to keep?
  782.     jr    nz, ndrcp3    ; don't load if no.
  783.     ld    a,(tgtdsk)    ; yes, get target drive
  784.     ld    (hl),a        ; ..and substitute drive
  785.     ldir            ; ..byte, then load it.
  786.     inc    (ix)        ; count entries in bcb0+2
  787.     jr    ndrcp2
  788. ndrcp3:    add    hl, bc        ; incr. source addr
  789. ndrcp2:    xor    a        ; Disk == 0 means end
  790.     or    (hl)        ; end of ND entries?
  791.     jr    nz, ndrcp1    ; if no, get more
  792.     ld    a,(temprc)    ; get starting number of entries
  793.     cp    a,(ix)        ; same as current number?
  794.     ld    a,3        ;error code - no entries for this drive
  795.     jr    z,exndrcp    ; yes, Nothing copied
  796.  
  797. ;transfer complete. Now complete filling in the BCB
  798. ; the value of the A reg. will be decremented to form
  799. ; either a logical true(0ffh) or false(00h) with flags set.
  800.  
  801. xndrcp:    ld    (bcb0+6),de    ;save pointer to next avail. loc
  802.     pop    ix
  803.     ld    hl,ndfmsg    ;report where update is from
  804.     call    qpstr
  805.     xor    a
  806.     ld    (errflg),a
  807.     dec    a        ; return logical true if no problems
  808.     ret
  809.  
  810. exndrcp:
  811.     ld    (errflg),a    ;save the error code
  812.     xor    a
  813.     ret            ; return false if dest. is full
  814.  
  815. temprc:    ds    1
  816.  
  817. ;***************************************************
  818.  
  819. ; roomck: compares the current number of entries in
  820. ; the lclndr with the maximum number allowed.
  821. ; on entry, IX points to current number of entries.
  822. ; on return, a=1 and carry is set if current number
  823. ; of entries equals or excedes the maximum allowed.
  824.  
  825. roomck:    ld    a,(ndblks)    ; get max # NDR entries
  826.     dec    a        ; for the compare
  827.     cp    a,(ix)        ; exceded by current yet?
  828.     ld    a,1        ; in case no room left
  829.     ret
  830.  
  831. ;***************************************************
  832.  
  833. ;ndrsrt: sets up the Sort Specification Block for
  834. ; sorting the local NDR image in d/u order, then
  835. ; calls dosort: for the actual buffer allocation
  836. ; and sorting.
  837.  
  838. ndrsrt:    push    hl
  839.     push    de
  840.     push    bc
  841.     ld    hl,bcb0
  842.     ld    de,ssb        ;Sort Specification Block
  843.     ld    bc,6
  844.     ldir            ;copy 1st 3 words from bcb0
  845.     ld    hl,(freesp)    ;tell where to work
  846.     ld    (ssb+8),hl
  847.     call    dosort        ;sort local NDR image
  848.     pop    bc
  849.     pop    de
  850.     pop    hl
  851.     ret
  852.  
  853. ;***************************************************
  854.  
  855. ; copyout: copy new NDR into NDBuff.
  856.  
  857. copyout:
  858.     ld    hl, (bcb0)    ; source is local NDR image
  859.     ld    de, (z3ndb)    ; dest is system NDR buffer
  860.     ld    bc, (size0)    ; buffer size, bytes
  861.     ldir
  862.     ret
  863.  
  864. ;***************************************************
  865.  
  866. ; dosort: is called to sort the contents of a
  867. ; buffer using memory space starting at addr in HL.
  868. ; Assumes the sort parameters in SSB: have been
  869. ; correctly entered therein.
  870. ; BC,DE,HL are preserved
  871.  
  872. dosort:    push    bc        ;save for caller
  873.     push    de
  874.     push    hl
  875.     ld    bc,(ssb)
  876.     push    bc        ;save for sort
  877.     ld    de,ssb
  878.     call    ssbinit        ;munches (ssb)
  879.     pop    bc
  880.     ld    (ssb),bc    ;restore (ssb)
  881.     call    sort
  882.     pop    hl
  883.     pop    de
  884.     pop    bc
  885.     ret
  886.  
  887. ;***************************************************
  888.  
  889. ;compdu: is referenced indirectly through the
  890. ;Sort Specification Block. It is the compare
  891. ;routine used by Sort (from Syslib)
  892.  
  893. compdu:    push    bc    ;preserve for caller
  894.     ld    b,2    ;number of bytes in comp vector
  895.     ex    de,hl    ;for ascending sort order
  896.     call    compb    ;vector compare routine
  897.     ex    de,hl
  898.     pop    bc
  899.     ret
  900.  
  901. ;***************************************************
  902.  
  903. qpstr:
  904. ;print a null terminated string if QUIET flag is off.
  905. ;on entry, hl->first char of string.
  906.     call    getquiet
  907.     ret    nz        ;quiet, please..
  908.     jp    pstr        ;print & return
  909.  
  910. ;***************************************************
  911. ;        MESSAGES
  912.  
  913. ;PROGRESS MESSAGES
  914. drives:    db    'Updating Directory Names for Drive: '
  915. tdrv:    db    'A',cr,lf,0
  916. mfmsg:    db    '..from marked files on that drive.'cr,lf,0
  917. ndfmsg:    db    '..from an NDR type file on that drive.'cr,lf,0
  918.  
  919. ;ERROR MESSAGES
  920. em1:    db '? 1 - Not enough room in the ndr buffer.'cr,lf,0
  921. em2:    db '? 2 - No marked filenames found on that drive.'cr,lf,0
  922. em3:    db '? 3 - No entries for that drive in the NDR file.'cr,lf,0
  923. em4:    db '? 4 - No NDR type files found on that drive.'cr,lf,0
  924. em5:    db '? 5 - Invalid drive requested.'cr,lf,0
  925. em6:    db 'Sorry - Wheel privileges are required for this pgm.'cr,lf,0
  926. em7:    db 'Can''t find System Named Directory!'cr,lf,0
  927. em8:    db 'This ZCPR3 program must be installed with Z3INS.'cr,lf,0
  928.  
  929. ;HELP SCREEN
  930.  
  931. hlpmsg:    db    tab,tab,'LOADND version ',vers,'.',rev,cr,lf,lf
  932.     db    'Update ZCPR3 Named Directory for <Drive> from',cr,lf
  933.     db    ' the disk in that Drive.',cr,lf,lf
  934.     db    'SYNTAX:   '
  935. myname:    db    ' LOADND '
  936.     db    ' [<Drive>[:]]  [/<option>]',cr,lf,lf
  937.     db    'The current defaults for DRIVE and OPTION are '
  938. defdrv:    db    ' , and /'
  939. defopt:    db    '  ',cr,lf
  940.     db '<Drive> is a disk designator (A,B, etc) (":" optional)',cr,lf
  941. em9:    db '<option> is one of the following:',cr,lf,lf
  942.     db tab
  943. opt0:    db    'ND = use NDR file if present, else use marked files',cr,lf
  944.     db tab
  945. opt1:    db    'DN = use marked files if present, else use NDR file',cr,lf
  946.     db tab
  947. opt2:    db    'D  = use marked files only (ignore NDR files)',cr,lf
  948.     db tab
  949. opt3:    db    'N  = use NDR file only (ignore marked files)',cr,lf
  950.     db lf
  951.     db 'If the first argument is / or // or ? this screen is displayed.',cr,lf
  952.     db lf
  953.     db    0
  954.  
  955. ;index table for option designators
  956. optbl:    dw    opt0,opt1,opt2,opt3
  957.  
  958. ;***************************************************
  959.  
  960. space:    ds    9, ' '
  961. errflg:    dw    0
  962. tgtdsk:    db    0        ;target disk
  963. z3ndb:    dw    0        ;system NDR address
  964. ndblks:    dw    0        ;sys NDR max number of entries
  965. freesp:    dw    0        ;start of free mem after buffer alloc
  966.  
  967. ;Sort Specification Block
  968. ;Controls operation of the SORT routine
  969.  
  970. ssb:    dw    0    ;addr of first record
  971.     dw    0    ;number of records to sort
  972.     dw    0    ;record size, bytes
  973.     dw    compdu    ;addr of compare routine to use
  974.     dw    0    ;addr of scratch area for sort
  975.     db    true    ;use pointers (false/no = don't)
  976.  
  977. ; Buffer Control Blocks - contain pointers and data
  978. ; for the dynamically allocated buffers
  979.  
  980. ; Buffer 0 - for copy of system NDR
  981. bcb0:    dw    0    ; buffer start address
  982.     dw    0    ; number of records/blocks
  983.     dw    0    ; number of bytes/(record/block)
  984.     dw    0    ; pointer to next loc in buffer
  985.     dw    0    ; next buffer start/freespace
  986.  
  987. size0:    dw    0    ;(bcb0+8) - (bcb0)
  988.  
  989. ;these have the same structure as bcb0: --
  990. bcb1:    ds    10,0    ; for Buffer 1 - for disk directory
  991.             ; listing of *.NDR files
  992.  
  993. bcb2:    ds    10,0    ; for Buffer 2 - for disk directory
  994.             ; listing of marked files
  995.  
  996. bcb3:    ds    10,0    ; for Buffer 3 - for contents of the
  997.             ; selected *.NDR file
  998.  
  999. ;***************************************************
  1000.  
  1001. stak_space:
  1002.     ds     64        ; This seems enough
  1003. stak:    dw     0
  1004.  
  1005. ;***************************************************
  1006.  
  1007.     end
  1008.