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 / ZSYS / SIMTEL20 / ZCPR3 / DIR14.LBR / DIR14.ZZ0 / DIR14.Z80
Text File  |  2000-06-30  |  37KB  |  1,619 lines

  1. ;
  2. ; program: dir
  3. ; author:  richard conn
  4. ; version:  1.0
  5. ; date: 23 mar 84
  6. ;
  7.  
  8. vers    equ    14        ; Added Print option  25 Dec 85  jww
  9.  
  10. ;vers    equ    13        ; Fixed fsize routine again  jww
  11.                 ;
  12. ;vers    equ    12        ;Added 'PUBLIC' support to permit
  13.                 ;wildcard viewing of public directories
  14.                 ;used by ZRDOS 1.2 dlw
  15. ;
  16. ;VERS    EQU    11        ; Changed manner of calculating disk size
  17.                 ; Using all0 and all1 instead of drm
  18.                 ; Added modified dirqs and fsize  jww
  19.                 ; Trial to list files vertically  jww
  20. ;
  21. ;vers    equ    10        ; release
  22. ;
  23. month    equ    1
  24. day    equ    22
  25. year    equ    86
  26. ;
  27. z3env    defl    0fe00h        ; Set zcpr3 environment descriptor address
  28. ;
  29. ; equates
  30. ;
  31. yes    equ    0ffh
  32. no    equ    0
  33. ;
  34. video    equ    yes        ; Enhanced video?
  35. vopt    equ    yes        ; Print signon and vers no
  36. vert    equ    yes        ; List files vertically (default)
  37. ;
  38. fcb    equ    5ch
  39. fcb2    equ    6ch
  40. ctrlc    equ    03h
  41. cr    equ    0dh
  42. lf    equ    0ah
  43. ;
  44. ; vlib, z3lib and syslib references
  45. ;
  46.     ext    z3vinit,tinit,stndout,stndend,bdos
  47.     ext    codend,retud,pfn1,dfree,dutdir,dparams
  48.     ext    crlf,cout,pafdc,phldc,phlfdc,z3log,fillb,getcrt,cin
  49.     ext    lcrlf,lout,lafdc,lhldc,lhlfdc,lfn1
  50.  
  51. ;
  52. ; environment definition
  53. ;
  54.      if    z3env ne 0
  55. ;
  56. ; external zcpr3 environment descriptor
  57. ;
  58.     jp    start
  59.     db    'Z3ENV'        ; This is a zcpr3 utility
  60.     db    1        ; External environment descriptor
  61. z3eadr:
  62.     dw    z3env
  63. start:
  64.     ld    hl,(z3eadr)    ; Pt to zcpr3 environment
  65. ;
  66.      else
  67. ;
  68. ; internal zcpr3 environment descriptor
  69. ;
  70.     maclib    z3base.lib
  71.     maclib    sysenv.lib
  72. z3eadr:
  73.     jp    start
  74.     sysenv
  75. start:
  76.     ld    hl,z3eadr    ; Pt to zcpr3 environment
  77.      endif
  78. ;
  79. ; start of program -- initialize zcpr3 environment
  80. ;
  81.     call    z3vinit        ; Initialize the zcpr3 env
  82.     call    tinit        ; Initialize the terminal
  83. ;
  84. ; make fcb wild if no entry
  85. ;
  86.     ld    hl,fcb+1    ; Pt to first char
  87.     ld    a,(hl)        ; Get it
  88.     cp    ' '        ; Check for space
  89.     ld    b,11        ; Prepare to set 11 bytes
  90.     ld    a,'?'        ; To "?"
  91.     call    z,fillb        ; Do it if space
  92. ;
  93. ; check for help
  94. ;
  95.     ld    de,fcb+1    ; Pt to first char of fcb
  96.     ld    a,(de)        ; Get first char of fcb
  97.     cp    '/'
  98.     jp    nz,doit
  99.     call    print
  100.     db    'DIR Vers '
  101.     db    [vers/10]+'0','.',[vers    mod 10]+'0',cr,lf
  102.     db    ' Syntax:  DIR dir:afn o',cr,lf
  103.     db    ' Options: A=All, S=Sys, H=Horiz, V=Vert, '
  104.     db    'P=Print, '
  105.     db    'T=File Type/Name Sor','t'+80h
  106.     ret
  107.  
  108. pcrlf:    ld    a,(prnt)
  109.     or    a
  110.     call    nz,lcrlf
  111.     jp    crlf
  112.  
  113. pcout:
  114.     push    af
  115.     ld    a,(prnt)
  116.     or    a
  117.     jp    z,pco0
  118.     pop    af
  119.     call    lout
  120.     jp    cout
  121. pco0:
  122.     pop    af
  123.     jp    cout
  124.  
  125. ppafdc:
  126.     push    af
  127.     ld    a,(prnt)
  128.     or    a
  129.     jp    z,ppa0
  130.     pop    af
  131.     call    lafdc
  132.     jp    pafdc
  133. ppa0:
  134.     pop    af
  135.     jp    pafdc
  136.  
  137. pphldc:
  138.     ld    a,(prnt)
  139.     or    a
  140.     call    nz,lhldc
  141.     jp    phldc
  142.  
  143. pphlfdc:
  144.     ld    a,(prnt)
  145.     or    a
  146.     call    nz,lhlfdc
  147.     jp    phlfdc
  148.  
  149. ppfn1:
  150.     ld    a,(prnt)
  151.     or    a
  152.     call    nz,lfn1
  153.     jp    pfn1
  154.  
  155. ;
  156. ; perform directory function
  157. ;
  158. doit:
  159.     dec    de        ; Pt to fcb
  160.     call    z3log        ; Log into dir
  161.     xor    a        ; Clear disk selection byte
  162.     ld    (de),a
  163. ;
  164. ; process options in fcb2
  165. ;
  166.     ld    hl,fcb2+1    ; Pt to options
  167.     ld    b,8        ; Allow for up to 8 options
  168.     ld    c,10000000b    ; Assume just normal files
  169. optloop:
  170.     ld    a,(hl)        ; Get next char
  171.     inc    hl        ; Advance
  172.     dec    b        ; Count down
  173.     jp    z,setdata    ; Done - set data
  174.     cp    ' '
  175.     jp    z,optloop
  176.     cp    'H'        ; Select horizontal listing
  177.     jp    z,sethoriz
  178.     cp    'V'        ; Select vertical listing
  179.     jp    z,setvert
  180.     cp    'T'        ; File type?
  181.     jp    z,settype
  182.     cp    'S'        ; System?
  183.     jp    z,setsys
  184.     cp    'P'        ; Print?
  185.     jp    z,setprnt
  186.     cp    'A'        ; System and normal?
  187.     jp    nz,optloop
  188. ;
  189. ; select both system and normal files
  190. ;
  191.     ld    a,11000000b    ; Normal and system files
  192.     jp    setsys1
  193. ;
  194. ; select printer output
  195. ;
  196. setprnt:
  197.     ld    a,yes
  198.     ld    (prnt),a
  199.     jp    optloop
  200. prnt:
  201.     db    no        ; Print option (default no)
  202. ;
  203. ; select horizontal listing
  204. ;
  205. sethoriz:
  206.     ld    a,yes
  207.     ld    (horiz),a
  208.     jp    optloop
  209. ;
  210. ; select vertical listing
  211. ;
  212. setvert:
  213.     ld    a,no
  214.     ld    (horiz),a
  215.     jp    optloop
  216. ;
  217. horiz:    db    not vert    ; Horizontal listing flag
  218. ;
  219. ; select file type/name alphabetization
  220. ;
  221. settype:
  222.     ld    a,c        ; Get flag
  223.     or    00100000b
  224.     ld    c,a
  225.     jp    optloop
  226. ;
  227. ; select just system files
  228. ;
  229. setsys:
  230.     ld    a,01000000b    ; System
  231. setsys1:
  232.     push    af
  233.     ld    a,c
  234.     and    00111111b    ; Mask out
  235.     ld    c,a
  236.     pop    af
  237.     or    c
  238.     ld    c,a
  239.     jp    optloop
  240. ;
  241. ; set selection byte in a
  242. ;
  243. setdata:
  244.     call    dparams        ; Init parameters
  245.     push    hl
  246.     push    de
  247.     push    bc
  248.     call    retud        ; Get du
  249.     ld    hl,(z3eadr)
  250.     ld    de,126        ; Offset to 'PUBLIC' masks
  251.     add    hl,de
  252.     ld    (public),hl    ; Save the mask address
  253.     ld    a,(hl)
  254.     or    a        ; Public user drive mask set?
  255.     jp    z,pub2
  256.     inc    hl        ; Bump pointer to user mask
  257.     ld    a,(hl)
  258.     or    a        ; Public user mask set?
  259.     jp    z,pub2
  260.     dec    hl        ; Go back and get the drive mask
  261.     ld    e,(hl)        ; Save in (E)
  262.     ld    a,b        ; Get current drive
  263.     inc    a
  264.     cp    9        ; PUBLIC drives can only be A - H
  265.     jr    nc,pub2
  266.     call    bitrel        ; Make current drive bit relative
  267.     jr    z,pub2        ; Returned Zero if not PUBLIC
  268.     ld    a,e
  269.     ld    (pubdrv),a    ; Save the public user drive mask
  270.     inc    hl        ; Bump address to public user mask
  271.     ld    e,(hl)
  272.     ld    a,c        ; Get current user
  273.     cp    9        ; PUBLIC users can only be 1 - 8
  274.     jr    nc,pub2
  275.     or    a
  276.     jr    z,pub2
  277.     call    bitrel
  278.     jr    z,pub2
  279.     ld    (pubflg),a    ; Set PUBLIC flag
  280.     ld    a,e
  281.     ld    (pubusr),a    ; Save public user mask
  282.     xor    a        ; Now clear PUBLIC masks
  283.     ld    (hl),a        ; So we can use a wildcard search
  284.     dec    hl        ; To fill the the directory buffer
  285.     ld    (hl),a
  286. pub2:    pop    bc        ; Original masks will be restored
  287.     pop    de        ; At program end.
  288.     pop    hl
  289.     call    codend        ; Pt to free area
  290.     ld    a,c        ; Selection in a
  291. ;
  292. ; load and sort directory
  293. ;
  294.     call    dirqs        ; Quick load
  295.     ld    (dirbeg),hl    ; Beginning of directory area
  296.     jp    nz,display
  297.     call    print
  298.     db    ' Ovf','l'+80h
  299.     jp    progend
  300. ;    RET
  301. ;
  302. ; display directory
  303. ;
  304. display:
  305.     push    hl        ; Save ptr to first entry
  306. ;
  307. ; init:
  308. ;    total of all file sizes
  309. ;    number of files displayed
  310. ;    line counter
  311. ;    entry counter
  312. ;
  313.      if    vopt        ; Signon and version
  314.     push    bc
  315.      if    video
  316.     call    stndout
  317.      endif
  318.     ld    c,22        ; Print 22 spaces
  319. dis0:    ld    a,' '
  320.     call    pcout
  321.     dec    c
  322.     jp    nz,dis0
  323.     call    print
  324.     db    'DIRectory Version '
  325.     db    vers/10+'0','.',vers mod 10+'0'
  326.     db    '  ',month/10+'0',month    mod 10+'0','/'
  327.     db    day/10+'0',day mod 10+'0','/'
  328.     db    year/10+'0',year mod 10+'0'
  329.     db    cr,lf+80h
  330.      if    video
  331.     call    stndend
  332.      endif
  333.     pop    bc
  334.      endif            ; Vopt
  335. ;
  336.     ld    hl,0        ; Set total size count
  337.     ld    (totcount),hl
  338.     ld    hl,fcount    ; Save file count
  339.     ld    (hl),c
  340.     inc    hl
  341.     ld    (hl),b        ; File count saved from bc
  342.     push    bc        ; Save file count
  343.     ld    h,b
  344.     ld    l,c        ; Move it to hl
  345.     ld    de,4
  346.     call    divide        ; Divide by four columns
  347.     jp    z,dis1
  348.     inc    bc        ; Round up if remainder from division
  349. dis1:    ld    h,b
  350.     ld    l,c        ; Quotient to hl
  351.     call    x16
  352.     ld    (lines),hl
  353.     pop    hl        ; Get file count
  354.     push    hl        ; And put it back
  355.     dec    hl        ; File count -1 points to last file
  356.     call    x16        ; Multiply by 16 chars/line
  357.     ex    de,hl        ; Directory size to de
  358.     ld    hl,(dirbeg)
  359.     add    hl,de
  360.     ld    (dirend),hl
  361.     pop    bc        ; Get file count
  362.     pop    hl        ; Pt to first entry
  363.     xor    a
  364.     ld    (lcount),a    ; Init line count
  365.     ld    (count),a    ; Init entry count
  366.     ld    a,b        ; Check for done
  367.     or    c
  368.     jp    z,prremain    ; Print remaining space on disk and exit
  369.     call    print
  370.     db    ' '+80h        ; Print first leading space
  371. ;
  372. ; loop to display file entries
  373. ;
  374. disploop:
  375. ;
  376. ; print separator if within a line
  377. ;
  378.     ld    a,(count)    ; See if new entry on line
  379.     and    3
  380.     jp    z,displ1
  381. ;
  382. ; print separator if entry is within a list
  383. ;
  384.      if    video
  385.     call    stndout
  386.      endif
  387.     call    print        ; Print separator
  388.     db    '|',' '+80h
  389.      if    video
  390.     call    stndend
  391.      endif
  392. ;
  393. ; print next entry
  394. ;
  395. displ1:
  396.     push    hl        ; Save key regs
  397.     push    bc        ; Hl pts to next entry, bc = count
  398. ;
  399. ; print file name
  400. ;
  401.     inc    hl        ; Pt to file name
  402.     ex    de,hl
  403.     call    ppfn1        ; Print file name
  404.     ex    de,hl
  405.     dec    hl        ; Pt to first byte of file entry
  406. ;
  407. ; print file size and increment total of all file sizes
  408. ;
  409.     push    hl        ; Save ptr to first byte of file entry
  410.     call    fsize        ; Compute file size (to de)
  411.     ld    hl,(totcount)    ; Increment total count
  412.     add    hl,de
  413.     ld    (totcount),hl
  414.     ex    de,hl
  415.     call    pphldc        ; Print file size
  416.     pop    hl        ; Get ptr to first byte of file entry
  417. ;
  418. ; check r/o byte
  419. ;
  420.     ld    b,' '        ; Assume r/w
  421.     ld    de,9        ; Pt to r/o
  422.     add    hl,de
  423.     ld    a,(hl)        ; Get r/o byte
  424.     and    80h        ; Look at it
  425.     jp    z,roout
  426.     ld    b,'r'        ; Set r/o
  427. roout:
  428.     ld    a,b        ; Get char
  429.     call    pcout
  430. ;
  431. ; increment entry count and issue new line if limit reached
  432. ;
  433.     ld    a,(count)    ; Increment entry count
  434.     inc    a
  435.     ld    (count),a
  436.     ld    a,(horiz)    ; Check horiz/vert listing
  437.     or    a
  438.     jp    z,displ2    ; Vertical listing
  439.     ld    a,(count)
  440.     and    3        ; New line?
  441.     call    z,newlin
  442.     jp    displ2
  443. ;
  444. ; new line - increment line count and issue page break if limit reached
  445. ;
  446. newlin:    call    prnl
  447.     ld    a,(lcount)    ; Count down lines
  448.     inc    a
  449.     ld    (lcount),a
  450.     call    getcrt        ; Get crt data
  451.     inc    hl        ; Pt to text line count
  452.     inc    hl
  453.     dec    a        ; Back up again
  454.     cp    (hl)        ; Compare
  455.     ret    nz
  456.     xor    a        ; Reset line count
  457.     ld    (lcount),a
  458.      if    video
  459.     call    stndout
  460.      endif
  461.     call    print
  462.     db    '  Pause -',' '+80h
  463.      if    video
  464.     call    stndend
  465.      endif
  466.     call    cin
  467.     call    prnl        ; Print new line with leading space
  468.     cp    ctrlc        ; Abort?
  469.     ret    nz
  470.     pop    af        ; Clear the rest of the stack
  471.     pop    af
  472.     pop    af
  473.     jp    progend
  474. ;    RET            ; To zcpr3
  475. ;
  476. ; advance to next entry
  477. ;
  478. displ2:
  479.     pop    bc        ; Restore count and ptr to current entry
  480.     pop    hl
  481.     ld    a,(horiz)    ; Check horiz/vert listing
  482.     or    a
  483.     jp    nz,disp2    ; Horizontal
  484.     ex    de,hl        ; Pointer to de
  485.     ld    hl,(lines)
  486.     add    hl,de        ; Point to next entry
  487.     ex    de,hl        ; New pointer to de
  488.     ld    hl,(dirend)
  489.     call    subde        ; Check if new ptr is within the directory
  490.     ex    de,hl        ; New pointer to hl
  491.     jp    nc,disp3    ; New pointer is ok
  492.     ld    hl,(dirbeg)    ; Otherwise start new line
  493.     ld    de,16        ; Next line
  494.     add    hl,de
  495.     ld    (dirbeg),hl    ; Save it
  496.     xor    a
  497.     ld    (count),a    ; Clear column count
  498.     push    hl
  499.     push    bc
  500.     call    newlin
  501.     pop    bc
  502.     pop    hl
  503.     jp    disp3
  504. disp2:    ld    de,16        ; Skip to next entry
  505.     add    hl,de
  506. disp3:    dec    bc        ; Count down
  507.     ld    a,b        ; Done?
  508.     or    c
  509.     jp    nz,disploop
  510.     ld    a,(count)    ; See if new line required
  511.     and    3
  512.     call    nz,pcrlf    ; New line if any entries on line
  513. ;
  514. ; print remaining space on disk and exit
  515. ;
  516. prremain:
  517. ;
  518. ; print du
  519. ;
  520.      if    video
  521.     call    stndout
  522.      endif
  523.     ld    a,(pubflg)    ; If PUBLIC
  524.     ld    b,3        ; Space over 3 spaces
  525.     or    a
  526.     jr    nz,gsp
  527.     ld    b,8        ; Space over 8 spaces
  528. gsp:    ld    a,' '
  529. spacer:
  530.     call    pcout
  531.     dec    b
  532.     jp    nz,spacer
  533.     call    retud        ; Get du in bc
  534.     ld    a,b        ; Print disk letter
  535.     add    'A'        ; Convert to ascii
  536.     call    pcout
  537.     ld    a,c        ; Print user number
  538.     call    ppafdc        ; Print floating
  539.     call    print        ; Print separator
  540.     db    ':'+80h
  541.     call    dutdir        ; See if matching dir
  542.     jp    z,prrem1
  543. ;
  544. ; print dir if any
  545. ;
  546.     ld    b,8        ; 8 chars max
  547. prrem0:
  548.     ld    a,(hl)        ; Get char
  549.     inc    hl        ; Pt to next
  550.     cp    ' '        ; Space?
  551.     call    nz,pcout    ; Echo char
  552.     dec    b        ; Count down
  553.     jp    nz,prrem0
  554. ;
  555. ; print file count
  556. ;
  557. prrem1:
  558.     ld    a,(pubflg)
  559.     or    a        ; PUBLIC directory?
  560.     jr    z,ovrpub
  561.     ld    a,' '
  562.     call    pcout
  563.     call    stndend
  564.     call    print        ; Print  public message
  565.     db    '[PUBLIC',']'+80h
  566.     call    stndout
  567. ovrpub:
  568.     ld    hl,(fcount)    ; Print number of files
  569.     call    print
  570.     db    ' --',' '+80h
  571.     call    pphlfdc
  572. ;
  573. ; print total of all file sizes
  574. ;
  575.     ld    hl,(totcount)    ; Print total count
  576.     call    print
  577.     db    ' files using',' '+80h
  578.     call    pphlfdc        ; Print as floating
  579. ;
  580. ; print amount of free space remaining
  581. ;
  582.     call    dfree        ; Compute amount of free space
  583.     ex    de,hl        ; In hl
  584.     call    print
  585.     db    'k ','('+80h
  586.     call    pphlfdc
  587.     call    print
  588.     db    'k remain of',' '+80h
  589.     call    dsize
  590.     call    pphlfdc
  591.     call    print
  592.     db    'k total',')'+80h
  593.      if    video
  594.     call    stndend
  595.      endif
  596.     ld    a,(prnt)
  597.     or    a
  598.     call    nz,lcrlf
  599. progend:
  600.     ld    a,(pubflg)    ; If PUBLIC restore masks
  601.     or    a
  602.     ret    z
  603.     ld    hl,(public)    ; Get 'PUBLIC' user mask address
  604.     ld    a,(pubdrv)    ; Restore PUBLIC masks
  605.     ld    (hl),a
  606.     inc    hl
  607.     ld    a,(pubusr)
  608.     ld    (hl),a
  609.     ret
  610. ;
  611. ; print new line with leading space
  612. ;
  613. prnl:
  614.     call    print
  615.     db    cr,lf,' '+80h    ; New line with leading space
  616.     ret
  617. ;
  618. ; print routine (string at return address) which is terminated by msb
  619. ;
  620. print:
  621.     ex    (sp),hl        ; Pt to string and save hl
  622.     push    af
  623. print1:
  624.     ld    a,(hl)        ; Get next char
  625.     and    7fh        ; Mask msb
  626.     call    pcout
  627.     ld    a,(hl)        ; Get next char
  628.     inc    hl        ; Pt to next
  629.     and    80h        ; Check msb
  630.     jp    z,print1
  631.     pop    af        ; Get a
  632.     ex    (sp),hl        ; Restore return address and hl
  633.     ret
  634. ;
  635. ; dsize returns the size of the current disk in hl (k)
  636. ;
  637. dsize:    push    de
  638.     push    bc
  639. ;
  640.     ld    c,31        ; Return dpb address in hl
  641.     call    bdos
  642.     inc    hl
  643.     inc    hl        ; Point to bls
  644.     ld    a,(hl)        ; Bls in a
  645.     ld    (bls),a
  646.     inc    hl
  647.     inc    hl
  648.     inc    hl        ; Point to dsm
  649.     ld    e,(hl)
  650.     inc    hl
  651.     ld    d,(hl)        ; Dsm in de
  652.     inc    de        ; Rel 1
  653.     push    de        ; Save dsm on stack
  654.     inc    hl        ; Point to drm
  655.     inc    hl
  656.     inc    hl        ; Point to all0
  657.     ld    d,(hl)
  658.     inc    hl        ; Point to all1
  659.     ld    e,(hl)
  660.     ex    de,hl        ; Allocation vector in hl
  661.     ld    de,-1        ; Clear a counter
  662. ds0:    inc    de
  663.     call    shlhl
  664.     jp    c,ds0
  665.     call    subde        ; Get complement of count
  666.     pop    de        ; Get dsm from stack
  667.     add    hl,de        ; Hl = groups available
  668.     ld    a,(bls)        ; Block shift factor
  669.     sub    3        ; From bls in a
  670.     jp    z,dsx
  671. dsiz0:    add    hl,hl
  672.     dec    a
  673.     jp    nz,dsiz0
  674. dsx:
  675.     pop    bc
  676.     pop    de
  677.     ret
  678. ;
  679. ; divide divides hl by de returning quotient in bc and remainder in hl
  680. ;  zero flag is set if no remainder
  681. ;
  682. divide:    ld    bc,0        ; Clear quotient
  683. div0:    call    subde        ; Subtract de from hl
  684.     jp    c,div1        ; Overflow
  685.     inc    bc        ; Increment quotient
  686.     jp    div0        ; Again..
  687. div1:    add    hl,de        ; Restore remainder in hl
  688.     ld    a,h        ; Check for remainder
  689.     or    l        ; Equal zero
  690.     ret
  691. ;
  692. ; subde subtracts de from hl returning carry set if de > hl
  693. ;
  694. subde:    ld    a,l
  695.     sub    e
  696.     ld    l,a
  697.     ld    a,h
  698.     sbc    a,d
  699.     ld    h,a
  700.     ret
  701. ;
  702. ; x16 simply shifts hl left four times
  703. ;
  704. x16:    add    hl,hl
  705.     add    hl,hl
  706.     add    hl,hl
  707.     add    hl,hl
  708.     ret
  709. ;
  710. ; shlhl shifts hl left into carry
  711. ;
  712. shlhl:    or    a        ; Reset carry
  713.     ld    a,l
  714.     rla
  715.     ld    l,a
  716.     ld    a,h
  717.     rla
  718.     ld    h,a
  719.     ret
  720. ;
  721. ; syslib module name:  sdirqs
  722. ; author:  richard conn
  723. ; part of syslib3 sdir series
  724. ; syslib version number:  3.0
  725. ; module version number:  1.4
  726. ; module entry points:
  727. ;    dirqs
  728. ; module external references:
  729. ;    none
  730. ;
  731.  
  732. ;*
  733. ;* equates
  734. ;*
  735. cpm    equ    0
  736. buff    equ    80h        ; Dma buffer
  737. esize    equ    16        ; 16 bytes/entry
  738.  
  739. ;*
  740. ;*  general-purpose directory select routine without sizing information
  741. ;*    this routine scans for the fcb pted to by de and loads all entries
  742. ;* which match it into the memory buffer pted to by hl.  on exit,
  743. ;* bc=number of files in buffer, and hl pts to first file in buffer.
  744. ;*    the directory buffer generated by dirq contains entries which may not
  745. ;* be used to compute the size of the files using the fsize routine.  the
  746. ;* dirqs routine is designed for this purpose.    the basic tradeoff between
  747. ;* the two routines is the dirq runs faster than dirqs, and this is noticable
  748. ;* if there is a significant number of files to be processed.
  749. ;*
  750. ;*    the dirq/dirqs routines are intended to be used in applications where
  751. ;* the only thing desired is a directory load of the current directory
  752. ;* (disk and user).  dirf/dirfs provide more flexibility at a greater cost
  753. ;* in terms of size.
  754. ;*
  755. ;*    input parameters:
  756. ;*    hl pts to buffer, de pts to fcb, a is select flag:
  757. ;*            bit 7 - select non-sys, bit 6 - select sys
  758. ;*            bit 5 - sort by file name and type (0) or other (1)
  759. ;*            bits 4-0 - unused
  760. ;*    output parameters:
  761. ;*    hl pts to first file in buffer
  762. ;*    bc = number of files
  763. ;*    a=0 and z flag set if tpa overflow
  764. ;*    de unchanged
  765. ;*
  766. dirqs:
  767.     push    de        ; Save ptr to fcb
  768.  
  769.     ld    (selflg),a    ; Save select flag for selection and alphabetization
  770.     ld    (hold),hl    ; Set ptr to hold buffer
  771.     ld    bc,36        ; Allow 36 bytes
  772.     add    hl,bc        ; Hl now points to temp fcb
  773.     ld    (tfcb),hl    ; Set ptr to temp fcb
  774.     add    hl,de        ; Hl now pts to scratch area
  775.  
  776.     push    de        ; Save ptr to fcb
  777.     call    dbuffer        ; Get ptrs
  778.     pop    de        ; Get ptr to fcb
  779.     push    hl        ; Save ptr to buffer
  780.     call    dirload        ; Load directory (fast load)
  781.     pop    hl        ; Get ptr to buffer
  782.  
  783.     pop    de        ; Get ptr to fcb
  784.  
  785.     ret    z        ; Abort if tpa overflow
  786.  
  787.     push    af        ; Save flag to indicate no tpa overflow
  788.     call    diralpha    ; Alphabetize
  789.     pop    af        ; Get psw (tpa overflow flag)
  790.     ret
  791.  
  792. ;*
  793. ;*  this routine accepts a base address for the dynamic buffers
  794. ;*    required, determines how much space is required for the buffers,
  795. ;*    and sets the order ptr to pt to the first and dirbuf to pt to
  796. ;*    the second (order space = dirmax*2 and dirbuf = dirmax * esize)
  797. ;*  on input, hl pts to available base
  798. ;*  on output, hl pts to dirbuf
  799. ;*    a=0 and zero flag set if ccp overrun
  800. ;*
  801. dbuffer:
  802.     ld    (order),hl    ; Pt to order table
  803.     call    dparams0    ; Get parameters
  804.     ld    hl,(dirmax)    ; Number of entries in dir
  805.     ex    de,hl        ; In de
  806.     ld    hl,(order)    ; Add to order base
  807.     add    hl,de        ; *1
  808.     call    memchk        ; Check for within range
  809.     add    hl,de        ; Hl pts to dirbuf
  810.     call    memchk        ; Check for within range
  811.     ld    (dirbuf),hl    ; Set ptr and hl pts to directory buffer
  812.     xor    a        ; Ok
  813.     dec    a        ; Set flags (nz)
  814.     ret
  815.  
  816. memchk:
  817.     push    hl        ; Save regs
  818.     push    de
  819.     ex    de,hl        ; Next address in de
  820.     ld    hl,(bdos+1)    ; Get address of bdos
  821.     ld    a,d        ; Check for page overrun
  822.     cp    h
  823.     jp    nc,memorun    ; Overrun if d>=h
  824.     pop    de
  825.     pop    hl
  826.     ret
  827. memorun:
  828.     pop    de        ; Restore
  829.     pop    hl
  830.     pop    af        ; Clear stack
  831.     xor    a        ; Return 0
  832.     ret
  833.  
  834. ;*
  835. ;*  this routine extracts disk parameter informaton from the dpb and
  836. ;*    stores this information in:
  837. ;*    blkshf    <-- block shift factor (1 byte)
  838. ;*    blkmsk    <-- block mask (1 byte)
  839. ;*    extent    <-- extent mask (1 byte) [not any more]
  840. ;*    blkmax    <-- max number of blocks on disk (2 bytes)
  841. ;*    dirmax    <-- max number of directory entries (2 bytes)
  842. ;*
  843. dparams0:
  844. ;*
  845. ;*  version 2.x or mp/m
  846. ;*
  847.     ld    c,31        ; 2.x or mp/m...request dpb
  848.     call    bdos
  849.     inc    hl
  850.     inc    hl
  851.     ld    a,(hl)        ; Get block shift
  852.     ld    (blkshf),a    ; Block shift factor
  853.     inc    hl        ; Get block mask
  854.     ld    a,(hl)
  855.     ld    (blkmsk),a    ; Block mask
  856.     inc    hl
  857.     inc    hl
  858.     ld    e,(hl)        ; Get max block number
  859.     inc    hl
  860.     ld    d,(hl)
  861.     ex    de,hl
  862.     inc    hl        ; Add 1 for max number of blocks
  863.     ld    (blkmax),hl    ; Maximum number of blocks
  864.     ex    de,hl
  865.     inc    hl
  866.     ld    e,(hl)        ; Get directory size
  867.     inc    hl
  868.     ld    d,(hl)
  869.     ex    de,hl
  870.     inc    hl        ; Add 1 for number of entries
  871.     ld    (dirmax),hl    ; Maximum number of directory entries
  872.     ret
  873.  
  874. ;*
  875. ;*  build directory table at dirbuf
  876. ;*    this is the optimal directory load routine; it only loads unique
  877. ;*        file names from disk, but the information is not sufficient
  878. ;*        to compute the file sizes
  879. ;*    on input, hl pts to directory buffer (16 x n max)
  880. ;*        de pts to fcb (only 12 bytes needed)
  881. ;*    on output, bc is num of files
  882. ;*        a=0 and zero flag set if tpa overflow
  883. ;*
  884. dirload:
  885.     ld    (dstart),hl    ; Set start of buffer area
  886.     inc    de        ; Pt to file name
  887.     ld    hl,(tfcb)    ; Pt to tfcb
  888.     ld    (hl),0        ; Select current disk
  889.     inc    hl        ; Pt to file name in tfcb
  890.     ld    b,11        ; 11 chars
  891. dlloop:
  892.     ld    a,(de)        ; Copy
  893.     ld    (hl),a
  894.     inc    hl        ; Pt to next
  895.     inc    de
  896.     dec    b        ; Count down
  897.     jp    nz,dlloop
  898.     ld    (hl),'?'    ; Select all extents
  899.     inc    hl        ; Pt to next char
  900.     ld    (hl),0
  901.     inc    hl
  902.     ld    (hl),'?'    ; And all modules
  903.     inc    hl
  904.     ld    b,21        ; 23 chars
  905.     xor    a        ; Zero rest of tfcb
  906. dlloop1:
  907.     ld    (hl),a        ; Store zero
  908.     inc    hl        ; Pt to next
  909.     dec    b        ; Count down
  910.     jp    nz,dlloop1
  911.  
  912. ;*
  913. ;*  this section of code initializes the counters used
  914. ;*
  915.     ld    hl,0        ; Hl=0
  916.     ld    (fcount0),hl    ; Total files on disk = 0
  917. ;*
  918. ;*  now we begin scanning for files to place into the memory buffer
  919. ;*
  920.     ld    c,17        ; Search for file
  921.     jp    dirlp1
  922. dirlp:
  923.     call    pentry        ; Place entry in dir
  924.     jp    z,dirovfl    ; Memory overflow error
  925.     ld    c,18        ; Search for next match
  926. dirlp1:
  927.     ld    hl,(tfcb)    ; Pt to fcb
  928.     ex    de,hl
  929.     call    bdos
  930.     cp    255        ; Done?
  931.     jp    nz,dirlp
  932. ;*
  933. ;*  now we are done with the load -- set up return values
  934. ;*
  935. dirdn:
  936.     xor    a        ; Load ok
  937.     dec    a        ; Set flags (nz)
  938. dirdnx:
  939.     ld    hl,(fcount0)    ; Get total number of files
  940.     ld    b,h        ; In bc
  941.     ld    c,l
  942.     ret
  943. ;*
  944. ;*  memory overflow error
  945. ;*
  946. dirovfl:
  947.     xor    a        ; Load error
  948.     jp    dirdnx
  949.  
  950. ;*
  951. ;*  pentry --
  952. ;*  place entry in directory buffer if not an erased entry
  953. ;*
  954. ;*  on input,  a=0-3 for adr index in buff of entry fcb
  955. ;*          fcount0=number of files in dir so far
  956. ;*  on output, fcount0=number of files in dir so far
  957. ;*          a=0 and zero flag set if memory overflow error
  958. ;*
  959. pentry:
  960.     rrca            ; Multiply by 32 for offset computation
  961.     rrca
  962.     rrca
  963.     and    60h        ; A=byte offset
  964.     ld    de,buff        ; Pt to buffer entry
  965.     ld    l,a        ; Let hl=offset
  966.     ld    h,0
  967.     add    hl,de        ; Hl=ptr to fcb
  968. ;*
  969. ;*  hl=adr of fcb in buff
  970. ;*
  971.     call    attest        ; Test attributes
  972.     jp    z,pedone    ; Skip if attribute not desired
  973.  
  974. ;*
  975. ;*  scan directory entries as loaded so far for another entry by the same
  976. ;*    name; if found, set that entry to be the entry with the larger ex
  977. ;*    and return with the zero flag set, indicating no new file; if not
  978. ;*    found, return with zero flag reset (nz)
  979. ;*
  980.     call    dupentry    ; Check for duplicate and select ex
  981.     jp    z,pedone    ; Skip if duplicate
  982.  
  983. ;*
  984. ;*  copy fcb pted to by hl into directory buffer
  985. ;*
  986.     ex    de,hl        ; Save ptr in de
  987.     ld    hl,(dirbuf)    ; Pt to next entry location
  988.     ex    de,hl        ; Hl pts to fcb, de pts to next entry location
  989.     ld    b,esize        ; Number of bytes/entry
  990.     call    sdmove        ; Copy fcb into memory buffer
  991.     ex    de,hl        ; Hl pts to next entry
  992.     ld    (dirbuf),hl    ; Set ptr
  993.     ex    de,hl        ; Ptr to next entry in de
  994.     ld    hl,(bdos+1)    ; Base address of bdos in hl
  995.     ld    a,h        ; Get base page of bdos
  996.     sub    9        ; Compute 1 page in front of base page of ccp
  997.     cp    d        ; Is ptr to next entry beyond this?
  998.     ret    z
  999.  
  1000. ;*  increment total number of files
  1001.     ld    hl,(fcount0)    ; Total files = total files + 1
  1002.     inc    hl
  1003.     ld    (fcount0),hl
  1004.  
  1005. ;*  done with pentry and no error
  1006. pedone:
  1007.     xor    a        ; No error
  1008.     dec    a        ; Set flags (nz)
  1009.     ret
  1010.  
  1011. ;*
  1012. ;*  check attributes of file entry pted to by hl against selflg
  1013. ;*    if system file and system attribute set, return nz
  1014. ;*    if normal file and normal attribute set, return nz
  1015. ;*
  1016. attest:
  1017.     push    hl        ; Save ptr
  1018.     ld    bc,10        ; Pt to system attribute
  1019.     add    hl,bc
  1020.     ld    a,(hl)        ; Get system attribute
  1021.     pop    hl        ; Restore ptr
  1022.     and    80h        ; Check for sys
  1023.     ld    a,(selflg)    ; Get selection flag
  1024.     jp    z,atdir
  1025.     and    01000000b    ; Check system attribute
  1026.     ret
  1027. atdir:
  1028.     and    10000000b    ; Check normal attribute
  1029.     ret
  1030.  
  1031. ;*
  1032. ;*  scan directory entries as loaded so far for another entry by the same
  1033. ;*    name; if found, set that entry to be the entry with the larger ex
  1034. ;*    and return with the zero flag set, indicating no new file; if not
  1035. ;*    found, return with zero flag reset (nz)
  1036. ;*  on input, hl pts to entry to scan for, fcount0 = number of entries so far,
  1037. ;*        and (dstart) = starting address of directory loaded
  1038. ;*  on output, a=0 and zero flag set if duplicate entry found; a=0ffh and nz
  1039. ;*        if no dup entry found
  1040. ;*        only hl not affected
  1041. ;*
  1042. dupentry:
  1043.     push    hl        ; Save ptr to entry to scan for
  1044.     ex    de,hl        ; Ptr in de
  1045.     ld    hl,(fcount0)    ; Check count
  1046.     ld    a,h        ; No entries?
  1047.     or    l
  1048.     jp    z,nodup        ; No duplicate entry return
  1049.     ld    b,h        ; Bc=number of entries
  1050.     ld    c,l
  1051.     ld    hl,(dstart)    ; Hl pts to first entry
  1052. dupeloop:
  1053.     push    bc        ; Save count
  1054.     push    hl        ; Save ptrs
  1055.     push    de
  1056.     inc    hl        ; Pt to fn
  1057.     inc    de
  1058.     ld    b,11        ; Compare fn and ft
  1059.     call    comp
  1060.     jp    nz,nodupl    ; Continue looking for another entry
  1061. ;  duplicate entries have been identified at this point
  1062.     ld    c,(hl)        ; Extent in low order
  1063.     inc    hl
  1064.     inc    hl
  1065.     ld    b,(hl)        ; Module in high order
  1066.     push    bc        ; Save entry size a moment
  1067.     ex    de,hl        ; Point hl to target
  1068.     ld    e,(hl)        ; Extent in low order
  1069.     inc    hl
  1070.     inc    hl
  1071.     ld    d,(hl)        ; Module in high order
  1072.     pop    hl        ; Dir in hl, target in de
  1073.     ex    de,hl
  1074.     call    subde        ; Subtract dir size from target size
  1075.     pop    de        ; Get ptrs
  1076.     pop    hl
  1077.     jp    c,dupsmall    ; Target is smaller
  1078. ;  new target is larger than stored entry
  1079.     ex    de,hl        ; Hl pts to target, de pts to dir entry
  1080.     ld    b,esize        ; Number of bytes to move
  1081.     call    sdmove        ; Move it
  1082. ;  new target is smaller than stored entry
  1083. dupsmall:
  1084.     pop    bc        ; Clear count from stack
  1085.     xor    a        ; Indicate dup found
  1086.     pop    hl        ; Restore ptr to entry to scan for
  1087.     ret
  1088. ;  no duplicate found; advance to next entry
  1089. nodupl:
  1090.     pop    de        ; Restore ptrs
  1091.     pop    hl
  1092.     ld    bc,esize    ; Hl pts to current entry in buffer, so add esize to it
  1093.     add    hl,bc
  1094.     pop    bc        ; Get count
  1095.     dec    bc        ; Count down
  1096.     ld    a,b        ; Check for done
  1097.     or    c
  1098.     jp    nz,dupeloop
  1099. ;  no duplicate found
  1100. nodup:
  1101.     xor    a        ; Indicate dup not found
  1102.     dec    a        ; Set flags (nz)
  1103.     pop    hl        ; Restore ptr to entry to scan for
  1104.     ret
  1105.  
  1106. ;*
  1107. ;*  diralpha -- alphabetizes directory pted to by hl; bc contains
  1108. ;*    the number of files in the directory and a = sort flag
  1109. ;*    (0=sort by file name/type, <>0 = sort by file type/name)
  1110. ;*
  1111. diralpha:
  1112.     ld    a,b        ; Any files?
  1113.     or    c
  1114.     ret    z
  1115.     push    hl        ; Save regs
  1116.     push    de
  1117.     push    bc
  1118.     ld    (dirbuf),hl    ; Save ptr to directory
  1119.     push    hl        ; Save hl
  1120.     ld    h,b        ; Hl=bc=file count
  1121.     ld    l,c
  1122.     ld    (n),hl        ; Set "N"
  1123.     pop    hl
  1124. ;*
  1125. ;*  shell sort --
  1126. ;*    this sort routine is adapted from "SOFTWARE TOOLS"
  1127. ;*    by kernigan and plaugher, page 106.  copyright, 1976, addison-wesley.
  1128. ;*  on entry, bc=number of entries
  1129. ;*
  1130. sort:
  1131.     ex    de,hl        ; Pointer to directory in de
  1132.     ld    hl,(order)    ; Pt to order table
  1133. ;*
  1134. ;*  set up order table; hl pts to next entry in order table, de pts to next
  1135. ;*    entry in directory, bc = number of elements remaining
  1136. ;*
  1137. sort1:
  1138.     ld    (hl),e        ; Store low-order address
  1139.     inc    hl        ; Pt to next order byte
  1140.     ld    (hl),d        ; Store high-order address
  1141.     inc    hl        ; Pt to next order entry
  1142.     push    hl        ; Save ptr
  1143.     ld    hl,esize    ; Hl=number of bytes/entry
  1144.     add    hl,de        ; Pt to next dir1 entry
  1145.     ex    de,hl        ; De pts to next entry
  1146.     pop    hl        ; Get ptr to order table
  1147.     dec    bc        ; Count down
  1148.     ld    a,b        ; Done?
  1149.     or    c
  1150.     jp    nz,sort1
  1151. ;*
  1152. ;*  this is the main sort loop for the shell sort in "SOFTWARE TOOLS" by k&p
  1153. ;*
  1154.  
  1155. ;*
  1156. ;*  shell sort from "SOFTWARE TOOLS" by kerninghan and plauger
  1157. ;*
  1158.     ld    hl,(n)        ; Number of items to sort
  1159.     ld    (gap),hl    ; Set initial gap to n for first division by 2
  1160.  
  1161. ;*  for (gap = n/2; gap > 0; gap = gap/2)
  1162. srtl0:
  1163.     or    a        ; Clear carry
  1164.     ld    hl,(gap)    ; Get previous gap
  1165.     ld    a,h        ; Rotate right to divide by 2
  1166.     rra
  1167.     ld    h,a
  1168.     ld    a,l
  1169.     rra
  1170.     ld    l,a
  1171.  
  1172. ;*  test for zero
  1173.     or    h
  1174.     jp    z,sdone        ; Done with sort if gap = 0
  1175.  
  1176.     ld    (gap),hl    ; Set value of gap
  1177.     ld    (idx),hl        ; Set i=gap for following loop
  1178.  
  1179. ;*  for (i = gap + 1; i <= n; i = i + 1)
  1180. srtl1:
  1181.     ld    hl,(idx)        ; Add 1 to i
  1182.     inc    hl
  1183.     ld    (idx),hl
  1184.  
  1185. ;*  test for i <= n
  1186.     ex    de,hl        ; I is in de
  1187.     ld    hl,(n)        ; Get n
  1188.     ld    a,l        ; Compare by subtraction
  1189.     sub    e
  1190.     ld    a,h
  1191.     sbc    a,d        ; Carry set means i > n
  1192.     jp    c,srtl0        ; Don't do for loop if i > n
  1193.  
  1194.     ld    hl,(idx)        ; Set j = i initially for first subtraction of gap
  1195.     ld    (j),hl
  1196.  
  1197. ;*  for (j = i - gap; j > 0; j = j - gap)
  1198. srtl2:
  1199.     ld    hl,(gap)    ; Get gap
  1200.     ex    de,hl        ; In de
  1201.     ld    hl,(j)        ; Get j
  1202.     ld    a,l        ; Compute j - gap
  1203.     sub    e
  1204.     ld    l,a
  1205.     ld    a,h
  1206.     sbc    a,d
  1207.     ld    h,a
  1208.     ld    (j),hl        ; J = j - gap
  1209.     jp    c,srtl1        ; If carry from subtractions, j < 0 and abort
  1210.     ld    a,h        ; J=0?
  1211.     or    l
  1212.     jp    z,srtl1        ; If zero, j=0 and abort
  1213.  
  1214. ;*  set jg = j + gap
  1215.     ex    de,hl        ; J in de
  1216.     ld    hl,(gap)    ; Get gap
  1217.     add    hl,de        ; J + gap
  1218.     ld    (jg),hl        ; Jg = j + gap
  1219.  
  1220. ;*  if (v(j) <= v(jg))
  1221.     call    icompare    ; J in de, jg in hl
  1222.  
  1223. ;*  ... then break
  1224.     jp    c,srtl1
  1225.  
  1226. ;*  ... else exchange
  1227.     ld    hl,(j)        ; Swap j, jg
  1228.     ex    de,hl
  1229.     ld    hl,(jg)
  1230.     call    iswap        ; J in de, jg in hl
  1231.  
  1232. ;*  end of inner-most for loop
  1233.     jp    srtl2
  1234.  
  1235. ;*
  1236. ;*  sort is done -- restructure dir1 in sorted order in place
  1237. ;*
  1238. sdone:
  1239.     ld    hl,(n)        ; Number of entries
  1240.     ld    b,h        ; In bc
  1241.     ld    c,l
  1242.     ld    hl,(order)    ; Ptr to ordered pointer table
  1243.     ld    (ptptr),hl    ; Set ptr ptr
  1244.     ld    hl,(dirbuf)    ; Ptr to unordered directory
  1245.     ld    (ptdir),hl    ; Set ptr dir buffer
  1246.  
  1247. ;*  find ptr to next dir1 entry
  1248. srtdn:
  1249.     ld    hl,(ptptr)    ; Pt to remaining pointers
  1250.     ex    de,hl        ; In de
  1251.     ld    hl,(ptdir)    ; Hl pts to next dir entry
  1252.     push    bc        ; Save count of remaining entries
  1253.  
  1254. ;*  find ptr table entry
  1255. srtdn1:
  1256.     ld    a,(de)        ; Get current pointer table entry value
  1257.     inc    de        ; Pt to high-order pointer byte
  1258.     cp    l        ; Compare against dir1 address low
  1259.     jp    nz,srtdn2    ; Not found yet
  1260.     ld    a,(de)        ; Low-order bytes match -- get high-order pointer byte
  1261.     cp    h        ; Compare against dir1 address high
  1262.     jp    z,srtdn3    ; Match found
  1263. srtdn2:
  1264.     inc    de        ; Pt to next ptr table entry
  1265.     dec    bc        ; Count down
  1266.     ld    a,c        ; End of table?
  1267.     or    b
  1268.     jp    nz,srtdn1    ; Continue if not
  1269.  
  1270. ;*  fatal error -- internal error; pointer table not consistent
  1271. ferr$ptr:
  1272.     ld    e,7        ; Ring bell
  1273.     ld    c,2        ; Output
  1274.     call    bdos
  1275.     jp    cpm
  1276.  
  1277. ;*  found the pointer table entry which points to the next unordered dir1 entry
  1278. ;*    make both pointers (ptr to next, ptr to current unordered dir1 entry)
  1279. ;*    point to same location (ptr to next dir1 entry to be ordered)
  1280. srtdn3:
  1281.     ld    hl,(ptptr)    ; Get ptr to next ordered entry
  1282.     dec    de        ; De pts to low-order pointer address
  1283.     ld    a,(hl)        ; Make ptr to next unordered dir1 pt to buffer for
  1284.     ld    (de),a        ; Dir1 entry to be moved to next unordered dir1 pos
  1285.     inc    hl        ; Pt to next ptr address
  1286.     inc    de
  1287.     ld    a,(hl)        ; Make high point similarly
  1288.     ld    (de),a
  1289.  
  1290. ;*  copy next unordered dir1 entry to hold buffer
  1291.     ld    b,esize        ; B=number of bytes/entry
  1292.     ld    hl,(hold)    ; Pt to hold buffer
  1293.     ex    de,hl
  1294.     ld    hl,(ptdir)    ; Pt to entry
  1295.     push    bc        ; Save b=number of bytes/entry
  1296.     call    sdmove
  1297.     pop    bc
  1298.  
  1299. ;*  copy to-be-ordered dir1 entry to next ordered dir1 position
  1300.     ld    hl,(ptptr)    ; Point to its pointer
  1301.     ld    e,(hl)        ; Get low-address pointer
  1302.     inc    hl
  1303.     ld    d,(hl)        ; Get high-address pointer
  1304.     ld    hl,(ptdir)    ; Destination address for next ordered dir1 entry
  1305.     ex    de,hl        ; Hl pts to entry to be moved, de pts to dest
  1306.     push    bc        ; Save b=number of bytes/entry
  1307.     call    sdmove
  1308.     pop    bc
  1309.     ex    de,hl        ; Hl pts to next unordered dir1 entry
  1310.     ld    (ptdir),hl    ; Set pointer for next loop
  1311.  
  1312. ;*  copy entry in hold buffer to loc previously held by latest ordered entry
  1313.     ld    hl,(ptptr)    ; Get ptr to ptr to the destination
  1314.     ld    e,(hl)        ; Get low-address pointer
  1315.     inc    hl
  1316.     ld    d,(hl)        ; High-address pointer
  1317.     ld    hl,(hold)    ; Hl pts to hold buffer, de pts to entry dest
  1318.     call    sdmove        ; B=number of bytes/entry
  1319.  
  1320. ;*  point to next entry in pointer table
  1321.     ld    hl,(ptptr)    ; Pointer to current entry
  1322.     inc    hl        ; Skip over it
  1323.     inc    hl
  1324.     ld    (ptptr),hl
  1325.  
  1326. ;*  count down
  1327.     pop    bc        ; Get counter
  1328.     dec    bc        ; Count down
  1329.     ld    a,c        ; Done?
  1330.     or    b
  1331.     jp    nz,srtdn
  1332.     pop    bc        ; Restore regs
  1333.     pop    de
  1334.     pop    hl
  1335.     ret            ; Done
  1336.  
  1337. ;*
  1338. ;*  swap (exchange) the pointers in the order table whose indexes are in
  1339. ;*    hl and de
  1340. ;*
  1341. iswap:
  1342.     push    hl        ; Save hl
  1343.     ld    hl,(order)    ; Address of order table - 2
  1344.     ld    b,h        ; In bc
  1345.     ld    c,l
  1346.     pop    hl
  1347.     dec    hl        ; Adjust index to 0...n-1 from 1...n
  1348.     add    hl,hl        ; Hl pts to offset address indicated by index
  1349.                 ; Of original hl (1, 2, ...)
  1350.     add    hl,bc        ; Hl now pts to pointer involved
  1351.     ex    de,hl        ; De now pts to pointer indexed by hl
  1352.     dec    hl        ; Adjust index to 0...n-1 from 1...n
  1353.     add    hl,hl        ; Hl pts to offset address indicated by index
  1354.                 ; Of original de (1, 2, ...)
  1355.     add    hl,bc        ; Hl now pts to pointer involved
  1356.     ld    c,(hl)        ; Exchange pointers -- get old (de)
  1357.     ld    a,(de)        ; -- get old (hl)
  1358.     ex    de,hl        ; Switch
  1359.     ld    (hl),c        ; Put new (hl)
  1360.     ld    (de),a        ; Put new (de)
  1361.     inc    hl        ; Pt to next byte of pointer
  1362.     inc    de
  1363.     ld    c,(hl)        ; Get old (hl)
  1364.     ld    a,(de)        ; Get old (de)
  1365.     ex    de,hl        ; Switch
  1366.     ld    (hl),c        ; Put new (de)
  1367.     ld    (de),a        ; Put new (hl)
  1368.     ret
  1369. ;*
  1370. ;*  icompare compares the entry pointed to by the pointer pointed to by hl
  1371. ;*    with that pointed to by de (1st level indirect addressing); on entry,
  1372. ;*    hl and de contain the numbers of the elements to compare (1, 2, ...);
  1373. ;*    on exit, carry set means ((de)) < ((hl)), zero set means ((hl)) = ((de)),
  1374. ;*    and non-zero and no-carry means ((de)) > ((hl))
  1375. ;*
  1376. icompare:
  1377.     push    hl        ; Save hl
  1378.     ld    hl,(order)    ; Address of order - 2
  1379.     ld    b,h        ; In bc
  1380.     ld    c,l
  1381.     pop    hl
  1382.     dec    hl        ; Adjust index to 0...n-1 from 1...n
  1383.     add    hl,hl        ; Double the element number to point to the ptr
  1384.     add    hl,bc        ; Add to this the base address of the ptr table
  1385.     ex    de,hl        ; Result in de
  1386.     dec    hl        ; Adjust index to 0...n-1 from 1...n
  1387.     add    hl,hl        ; Do the same with the original de
  1388.     add    hl,bc
  1389.     ex    de,hl
  1390.  
  1391. ;*
  1392. ;*  hl now points to the pointer whose index was in hl to begin with
  1393. ;*  de now points to the pointer whose index was in de to begin with
  1394. ;*    for example, if de=5 and hl=4, de now points to the 5th ptr and hl
  1395. ;* to the 4th pointer
  1396. ;*
  1397.     ld    c,(hl)        ; Bc is made to point to the object indexed to
  1398.     inc    hl        ; By the original hl
  1399.     ld    b,(hl)
  1400.     ex    de,hl
  1401.     ld    e,(hl)        ; De is made to point to the object indexed to
  1402.     inc    hl        ; By the original de
  1403.     ld    d,(hl)
  1404.     ld    h,b        ; Set hl = object pted to indirectly by bc
  1405.     ld    l,c
  1406.  
  1407. ;*
  1408. ;*  compare dir entry pted to by hl with that pted to by de;
  1409. ;*    no net effect on hl, de; ret w/carry set means de<hl
  1410. ;*    ret w/zero set means de=hl
  1411. ;*
  1412. cmp$entry:
  1413.     ld    a,(selflg)    ; Group by file type?
  1414.     and    00100000b
  1415.     jp    z,cmp$fn$ft
  1416. ;*
  1417. ;*  compare by file type and file name (in that order)
  1418. ;*
  1419.     push    hl
  1420.     push    de
  1421.     ld    bc,9        ; Pt to ft (8 bytes + 1 byte for user number)
  1422.     add    hl,bc
  1423.     ex    de,hl
  1424.     add    hl,bc
  1425.     ex    de,hl        ; De, hl now pt to their ft's
  1426.     ld    b,3        ; 3 bytes
  1427.     call    comp        ; Compare ft's
  1428.     pop    de
  1429.     pop    hl
  1430.     ret    nz        ; Continue if complete match
  1431.     ld    b,8        ; 8 bytes
  1432.     jp    cmp$ft1
  1433. ;*
  1434. ;*  compare by file name and file type (in that order)
  1435. ;*
  1436. cmp$fn$ft:
  1437.     ld    b,11        ; 11 bytes for fn and ft
  1438. cmp$ft1:
  1439.     push    hl
  1440.     push    de
  1441.     inc    hl        ; Pt to fn
  1442.     inc    de
  1443.     call    comp        ; Do comparison
  1444.     pop    de
  1445.     pop    hl
  1446.     ret
  1447. ;*
  1448. ;*  comp compares de w/hl for b bytes; ret w/carry if de<hl
  1449. ;*    msb is disregarded
  1450. ;*
  1451. comp:
  1452.     ld    a,(hl)        ; Get (hl)
  1453.     and    7fh        ; Mask msb
  1454.     ld    c,a        ; In c
  1455.     ld    a,(de)        ; Compare
  1456.     and    7fh        ; Mask msb
  1457.     cp    c
  1458.     ret    nz
  1459.     inc    hl        ; Pt to next
  1460.     inc    de
  1461.     dec    b        ; Count down
  1462.     jp    nz,comp
  1463.     ret
  1464.  
  1465. ;*
  1466. ;* copy from hl to de for b bytes
  1467. ;*
  1468. sdmove:
  1469.     ld    a,(hl)        ; Copy
  1470.     ld    (de),a
  1471.     inc    hl        ; Pt to next
  1472.     inc    de
  1473.     dec    b        ; Count down
  1474.     jp    nz,sdmove
  1475.     ret
  1476.  
  1477. ;*
  1478. ;*  buffers
  1479. ;*
  1480. hold:
  1481.     ds    2        ; Exchange hold buffer for fcb's
  1482. ptptr:
  1483.     ds    2        ; Pointer pointer
  1484. ptdir:
  1485.     ds    2        ; Directory pointer
  1486. idx:
  1487.     ds    2        ; Indexes for sort
  1488. j:
  1489.     ds    2
  1490. jg:
  1491.     ds    2
  1492. n:
  1493.     ds    2        ; Number of elements to sort
  1494. gap:
  1495.     ds    2        ; Binary gap size
  1496.  
  1497. tfcb:
  1498.     ds    2        ; Address of temporary fcb
  1499. dstart:
  1500.     ds    2        ; Pointer to first directory entry
  1501. fcount0:
  1502.     ds    2        ; Total number of files/number of selected files
  1503.  
  1504. blkshf:
  1505.     db    0        ; Block shift factor
  1506. blkmsk:
  1507.     db    0        ; Block mask
  1508. blkmax:
  1509.     dw    0        ; Max number of blocks
  1510. dirmax:
  1511.     dw    0        ; Max number of directory entries
  1512. selflg:
  1513.     db    0        ; File attribute flag
  1514. order:
  1515.     dw    0        ; Pointer to order table
  1516. dirbuf:
  1517.     dw    0        ; Pointer to directory
  1518.  
  1519. ;    end
  1520. ;
  1521. ; buffers
  1522. ;
  1523. count:    ds    1        ; Counter used in display
  1524. fcount:    ds    2        ; Number of files displayed
  1525. lcount:    ds    1        ; Line counter
  1526. totcount: ds    2        ; Total of sizes of all files
  1527. bls:    ds    1        ; Block shift factor
  1528. lines:    ds    2        ; Lines to be displayed
  1529. dirbeg:    ds    2        ; Beginning of directory area
  1530. dirend:    ds    2        ; End of directory area
  1531. pubflg:    db    0        ; Public user flag
  1532. public:    dw    0        ; Address of public du mask
  1533. pubdrv:    ds    1        ; Public Drive mask save area
  1534. pubusr:    ds    1        ; Public User mask save area
  1535. ;    end
  1536. ;
  1537. ; syslib module name:  sdir04
  1538. ; author:  richard conn
  1539. ; part of syslib3 sdir series
  1540. ; syslib version number:  3.0
  1541. ; module version number:  1.4
  1542. ; module entry points:
  1543. ;    fsize
  1544. ; module external references:
  1545. ;
  1546. ;
  1547.  
  1548. ;    include sdirhdr.lib
  1549.  
  1550. ;*
  1551. ;*  compute size of file whose last extent is pointed to by hl
  1552. ;*    file size is returned in de in k
  1553. ;*  note that the routine dparams must have been called before this routine
  1554. ;*    is used
  1555. ;*
  1556. fsize:
  1557.     push    bc        ; Save regs
  1558.     push    hl
  1559.     push    af
  1560.     ld    de,12        ; Point to extent
  1561.     add    hl,de
  1562.     ld    e,(hl)        ; Get extent #
  1563.     ld    d,0
  1564.     inc    hl        ; S1
  1565.     inc    hl        ; S2 is the module number (512 k)
  1566.     ld    a,(hl)        ; Get module #
  1567.     or    a        ; Reset carry
  1568.     rla
  1569.     rla
  1570.     rla
  1571.     rla
  1572.     rla            ; * 32 extents
  1573.     push    af
  1574.     or    e
  1575.     ld    e,a        ; Add to e
  1576.     pop    af
  1577.     jp    nc,fs0        ; Check high order bit
  1578.     inc    d        ; If carry
  1579. fs0:    inc    hl        ; Hl pts to record count field
  1580.     ld    a,(hl)        ; Get record count of last extent
  1581.     ex    de,hl
  1582.     add    hl,hl        ; Number of extents times 16k
  1583.     add    hl,hl
  1584.     add    hl,hl
  1585.     add    hl,hl
  1586.     ex    de,hl        ; Total size of previous extents in de
  1587.     ld    hl,blkmsk
  1588.     add    a,(hl)        ; Round last extent to block size
  1589.     rrca
  1590.     rrca            ; Convert from records to k
  1591.     rrca
  1592.     and    1fh
  1593.     ld    l,a        ; Add size of last extent to total of previous extents
  1594.     ld    h,0        ; Hl=size of last extent, de=total of previous extents
  1595.     add    hl,de        ; Hl=total file size in blocks
  1596.     ld    a,(blkmsk)    ; Get records/blk-1
  1597.     rrca
  1598.     rrca            ; Convert to k/blk
  1599.     rrca
  1600.     and    1fh
  1601.     cpl            ; Use to finish rounding
  1602.     and    l
  1603.     ld    l,a        ; Hl now equals the size of the file in k increments
  1604.     ex    de,hl        ; De=file size in k
  1605.     pop    af        ; Restore regs
  1606.     pop    hl
  1607.     pop    bc
  1608.     ret
  1609. ;
  1610. bitrel:    ld    d,a
  1611.     ld    a,80h
  1612. bitlp:    rlc    a
  1613.     dec    d
  1614.     jr    nz,bitlp
  1615.     and    a,e
  1616.     ret
  1617. ;
  1618.     end
  1619.