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 / FF10.LBR / FF10.ZZ0 / FF10.Z80
Text File  |  2000-06-30  |  35KB  |  1,485 lines

  1. ; PROGRAM:  FF (Find File)
  2. ; AUTHOR:  Jay Sage
  3. ; VERSION:  1.0
  4. ; DATE:  March 14, 1987
  5.  
  6.  
  7. ;            * * *   IMPORTANT NOTE   * * *
  8. ;
  9. ; This program is copyrighted 1987 by NAOG/ZSIG.  It may be copied and
  10. ; modified freely for personal use but may not be sold or distributed for a
  11. ; fee.  Modified versions must be submitted to and approved by NAOG/ZSIG
  12. ; before they may be distributed.  See the file ZSIGPOL1.DOC on Z-Nodes for
  13. ; the ZSIG policy on signing out and modifying programs.
  14.  
  15.  
  16. ; This program was derived from FINDF version 26.  FINDF was originally created
  17. ; by Richard Conn.  See the history in FINDF for a chronology of contributions
  18. ; by others, including Howard Goldstein, Joe Wright, Al Hawley, Rick Peterson,
  19. ; and Bruce Morgen.  I have given this program the new name FF so that it can
  20. ; develop in different directions without interfering with Echelon's need to
  21. ; support the utilities it provides with its commercial versions of Z-System.
  22.  
  23. ;=============================================================================
  24. ;
  25. ;        R E V I S I O N    H I S T O R Y
  26. ;
  27. ;=============================================================================
  28.  
  29. VERS    EQU    10
  30.  
  31. ; VERSION 1.0     Jay Sage    March 14, 1987
  32. ;
  33. ;    Added the DRVTBL configuration word at the beginning of the code.
  34. ;    This word contains a byte for each possible drive in a system.  When
  35. ;    the user has not indicated a specific drive to scan, each drive is
  36. ;    checked against this table and skipped if the bit is not set.  This
  37. ;    allows FF to work in systems with holes (e.g., drives A, B, and F)
  38. ;    in which the BIOS hangs when a drive is accessed that does not exist
  39. ;    or has no disk in it.  As distributed, FF has FFFFH in this word so
  40. ;    that all drives up to the max drive specified in the environment will
  41. ;    be scanned.
  42. ;
  43. ;    Added more flexibility to output paging.  The output can be paged
  44. ;    a line at a time by hitting the space bar or can be aborted at a page
  45. ;    break by hitting control-c
  46. ;
  47. ;    Enhanced syntax to allow specifying a list of drives to be scanned
  48. ;    in the option field.
  49. ;
  50. ;    Added code to set program error flag if no files found and to clear
  51. ;    the flag if files were found.  The number of files found is stored in
  52. ;    a configurable user register.  If the number is more than 255, the
  53. ;    value 255 is stored.  As distrubuted, register 0 is used.
  54.  
  55. ;    Added code to treat all file specs as ambiguous.  thus, "FF A"
  56. ;    is equivalent to "FF A*.*" and "FF A.B" is equivalent to "FF A*.B*".
  57. ;    This feature can be disabled with the E option.
  58. ;
  59. ;=============================================================================
  60. ;
  61. ;        D E F I N I T I O N S    S E C T I O N
  62. ;
  63. ;=============================================================================
  64.  
  65. Z3ENV    DEFL    0FE00H        ; ZCPR3 Environment address
  66.  
  67. ; System equates:
  68.  
  69. BOOT    EQU    0000H        ; CP/M warm boot jump vector
  70. BDOS    EQU    BOOT+05H    ; CP/M bdos call jump vector
  71. TBUFF    EQU    BOOT+80H    ; Disk I/O buffer
  72. FCB    EQU    BOOT+5CH    ; Default file control block
  73.  
  74. CR    EQU    'M'-'@'        ; Carriage return
  75. LF    EQU    'J'-'@'        ; Line feed
  76. TAB    EQU    'I'-'@'
  77. BELL    EQU    'G'-'@'        ; Bell character
  78. CTRLC    EQU    'C'-'@'        ; Abort
  79. CTRLS    EQU    'S'-'@'        ; Pause
  80.  
  81. ESIZE    EQU    12        ; 12 bytes/dir entry
  82.  
  83. MDOFF    EQU    2CH        ; Max drive offset in Z3ENV
  84. MUOFF    EQU    2DH        ; Max user offset in Z3ENV
  85.  
  86. RIGHTCH    EQU    '>'        ; Character to right of directory name
  87.  
  88. ; SYSLIB and Z3LIB Routines
  89.  
  90.     EXT    Z3INIT,GETWHL,CODEND,GETCRT
  91.     EXT    CST,CIN,COUT,CRLF,PRINT,PAFDC,DUNDR
  92.     EXT    PUTER2,PUTREG
  93.  
  94. ;=============================================================================
  95. ;
  96. ;            M A I N    C O D E    S E C T I O N
  97. ;
  98. ;=============================================================================
  99.  
  100.  
  101.     JP    START
  102.  
  103.     DB    'Z3ENV'        ; ZCPR3 ID
  104.     DB    1        ; External environment descriptor
  105. Z3EADR:
  106.     DW    Z3ENV
  107.  
  108.         ; Configuration area
  109.  
  110.     DEFB    'DRVTBL'
  111.  
  112. DRVTBL0:
  113.     ;    ABCDEFGH    ; Drives A..H
  114.     DB    11111111B
  115.     ;    IJKLMNOP    ; Drives I..P
  116.     DB    11111111B
  117.  
  118. Z3REG:                ; User register in which to return the number
  119.     DB    0        ; ..of files found (if > 9, disable)
  120.  
  121.  
  122. START:
  123.     LD    HL,(Z3EADR)    ; Point to ZCPR3 environment
  124.     PUSH    HL        ; Transfer pointer
  125.     POP    IX        ; ..to the X index register
  126.     CALL    Z3INIT        ; Initialize the ZCPR3 ENV
  127.     CALL    INIT        ; Initialize program
  128.     LD    (STACK),SP    ; Save stack (so cleanup not needed at end)
  129.     CALL    CODEND        ; Determine free space
  130.     LD    (FNTAB),HL    ; File name table
  131.     LD    DE,512        ; 1/2 K space
  132.     ADD    HL,DE
  133.     LD    (SCRATCH),HL    ; Beginning of scratch area
  134.     LD    SP,HL        ; And top of stack
  135.     CALL    GTBIOS        ; Get bios jump table
  136.     CALL    HELLO        ; Sign on message
  137.     CALL    HELPCHK        ; Check for and print help message
  138.     CALL    OPTCHK        ; Build file name table and process options
  139.     CALL    NEWLINE        ; New line
  140.     CALL    FIND        ; Do the searches
  141.     CALL    BYE        ; Sign off message
  142. RETURN:
  143.     LD    SP,(STACK)    ; Quiet return
  144.     RET
  145.  
  146. ;-----------------------------------------------------------------------------
  147.  
  148. ; SAY WHO WE ARE
  149.  
  150. HELLO:
  151.     CALL    PRINT
  152.     DB    CR,LF
  153.     DB    TAB,TAB,'Find File (FF) Version '
  154.     DB    [VERS/10]+'0','.',[VERS    MOD 10]+'0'
  155.     DB    ' [ZSIG]'
  156.     DB    0
  157.     RET
  158.  
  159. ;-----------------------------------------------------------------------------
  160.  
  161. ;  CHECK FOR HELP REQUEST
  162.  
  163. HELPCHK:
  164.     LD    HL,TBUFF+1    ; Look at command tail
  165.     CALL    SBLANK        ; Skip blanks
  166.     LD    A,(HL)        ; Get first byte
  167.     CP    '/'        ; Help?
  168.     JR    Z,HCK1
  169.     OR    A        ; Any argument at all?
  170.     RET    NZ        ; Go process it
  171.  
  172. ; IF NO FILE NAME IS SPECIFIED, ABORT WITH NOTICE
  173.  
  174. HCK1:
  175.     CALL    PRINT
  176.     DB    CR,LF,LF
  177.     DB    'Find all files matching a list of file '
  178.     DB    'specs on all drives, a specific '
  179.     DB    CR,LF
  180.     DB    'drive, or a list of drives.  All file '
  181.     DB    'specs are automatically made'
  182.     DB    CR,LF
  183.     DB    'wild ("A.B" -> "A*.B*").'
  184.     DB    CR,LF,LF
  185.     DB    '   Syntax:  FF [D: or DIR:]afn[,afn].. [d..][/o..]'
  186.     DB    CR,LF,LF
  187.     DB    TAB,'Options (d) before slash:'
  188.     DB    CR,LF
  189.     DB    TAB,TAB,'List of drives to scan'
  190.     DB    CR,LF,LF
  191.     DB    TAB,'Options (o) after slash:'
  192.     DB    CR,LF
  193.     DB    TAB,TAB,'E - Exact (no auto wildcarding)',cr,lf
  194.     DB    TAB,TAB,'P - No Paging',0
  195.     CALL    GETWHL
  196.     JR    Z,HCK2
  197.     CALL    PRINT
  198.     DB    CR,LF
  199.     DB    TAB,TAB,'S - Include SYS Files',0
  200. HCK2:
  201.     CALL    PRINT
  202.     DB    CR,LF,LF
  203.     DB    'Error flag set if no files found'
  204.     DB    0
  205.     LD    A,(Z3REG)    ; See if register used to store file number
  206.     CP    10
  207.     JR    NC,HCK3
  208.     LD    B,A        ; Save register number in B
  209.     CALL    PRINT
  210.     DB    '.  Number of files put in REG '
  211.     DB    0
  212.     LD    A,B
  213.     ADD    '0'
  214.     CALL    COUT
  215. HCK3:
  216.     CALL    PRINT
  217.     DB    '.'
  218.     DB    CR,LF
  219.     DB    'Auto-scanned drives are: '
  220.     DB    0
  221.  
  222.     LD    HL,(DRVTBL0)    ; Get drive map
  223.     LD    A,H        ; Swap H and L
  224.     LD    H,L
  225.     LD    L,A
  226.     LD    B,(IX+MDOFF)    ; Scan up to max drive only
  227.     LD    A,'A'        ; Initial drive letter
  228. HCK4:    ADD    HL,HL        ; High bit of HL into carry flag
  229.     CALL    C,COUT        ; Display drive letter if bit was set
  230.     INC    A        ; Advance to next drive letter
  231.     DJNZ    HCK4        ; Loop through drives
  232.  
  233.     CALL    PRINT
  234.     DB    '.',CR,LF,0
  235.  
  236.     JP    RETURN
  237.  
  238. ;-----------------------------------------------------------------------------
  239.  
  240. ; INITIALIZATION
  241.  
  242. INIT:
  243.     LD    HL,DATABEG    ; Zero out data area
  244.     LD    DE,DATABEG+1
  245.     LD    BC,DATAEND-DATABEG-1
  246.     LD    (HL),0        ; Seed value
  247.     LDIR            ; Fill 'em up
  248.  
  249.     CALL    GETCRT        ; Get data on current console
  250.     INC    HL        ; Point to full number of lines on screen
  251.     LD    A,(HL)
  252.     DEC    A        ; Reduce by one
  253.     LD    (LPS),A        ; Save in lines-per-screen location
  254.     LD    A,0FFH
  255.     LD    (NOFILFLAG),A    ; Set no-files-found flag
  256.     LD    (PAGEOPT),A    ; Paging option on
  257.     CALL    PUTER2        ; Set Z3 program error flag
  258.  
  259.     LD    A,1
  260.     LD    (LINECNT),A    ; Set initial line count
  261.     LD    A,20H
  262.     LD    (WILDCHR),A    ; Initially treat spaces as wildcards
  263.     LD    HL,(DRVTBL0)    ; Copy master drive table map
  264.     LD    (DRVTBL),HL    ; ..into working copy
  265.  
  266.     RET
  267.  
  268. ;-----------------------------------------------------------------------------
  269.  
  270. ; CHECKS FOR OPTIONS IN COMMAND LINE AND EXTRACTS FILE NAMES INTO
  271. ; TABLE
  272.  
  273. OPTCHK::
  274.         ; Process list of file specifications
  275.  
  276.     LD    DE,(FNTAB)    ; Pointer to file name table in DE
  277. FNLOOP:                ; Scan thru tbuff, building a file name table
  278.  
  279.     PUSH    DE        ; Save table ptr
  280.     CALL    GETFN        ; Extract file name
  281.     POP    DE
  282.     PUSH    HL
  283.     LD    HL,11        ; Pt to next table entry
  284.     ADD    HL,DE
  285.     EX    DE,HL
  286.     POP    HL
  287.     LD    A,(FNCOUNT)    ; Increment count
  288.     INC    A
  289.     LD    (FNCOUNT),A
  290.     LD    A,(HL)        ; Get terminating char
  291.     INC    HL        ; Pt to next
  292.     CP    ','        ; Another follows?
  293.     JR    NZ,OPTCK1    ; If not, on to second command-line token
  294.     LD    A,(HL)        ; Make sure list did not end with comma
  295.     CP    ' '+1
  296.     JR    NC,FNLOOP    ; If not, back for another file spec
  297.  
  298.         ; Process second command-line token
  299.  
  300. OPTCK1::
  301.     DEC    HL        ; Point back to delim
  302.     CALL    SBLANK        ; Skip to non-blank
  303.     LD    A,(HL)        ; Get option
  304.     CALL    DELCHK        ; Done if delim
  305.     RET    Z
  306.  
  307.     CP    '/'        ; See if non-drive option leadin '/'
  308.     JR    Z,OPTCK3    ; If so, branch now
  309.  
  310.         ; Process drive options
  311.  
  312.     XOR    A        ; Initialize for drive list
  313.     LD    DE,DRVTBL    ; Point to drive map
  314.     LD    (DE),A        ; Zero it out
  315.     INC    DE
  316.     LD    (DE),A
  317.     LD    (FCB),A        ; Nullify any drive from file spec list
  318.  
  319. OPTCK2::
  320.     LD    A,(HL)        ; Get drive letter
  321.     SUB    'A'        ; Convert to number in range 0..15
  322.     JR    C,OPTER        ; If less than 'A', it is an error
  323.     CP    16        ; If not less than 16, it is an error
  324.     JR    NC,OPTER
  325.     PUSH    HL        ; Save pointer to option list
  326.     CALL    SETDRV        ; Set bit in HL corresponding to drive
  327.     LD    DE,(DRVTBL)    ; Get the map so far
  328.     LD    A,D        ; Merge with new drives
  329.     OR    L        ; Drives 8..15
  330.     LD    D,A
  331.     LD    A,E
  332.     OR    H        ; Drives 0..7
  333.     LD    E,A
  334.     LD    (DRVTBL),DE    ; Store new drive map
  335.     POP    HL        ; Get pointer back
  336.     INC    HL        ; Get next character
  337.     LD    A,(HL)
  338.     CP    '/'        ; Non-drive option leadin?
  339.     JR    Z,OPTCK3    ; If so, take care of non-drive options
  340.     CALL    DELCHK        ; End of list?
  341.     RET    Z        ; Return if so
  342.     JR    OPTCK2        ; Else back for next drive
  343.  
  344.         ; Process non-drive options
  345.  
  346. OPTCK3::
  347.     INC    HL        ; Point to next option character
  348.     LD    A,(HL)        ; ..and get it
  349.     CALL    DELCHK        ; Delimiter?
  350.     RET    Z        ; If so, we are done
  351.     CP    'P'        ; Paging Toggle?
  352.     JR    Z,POPT
  353. CP    'E'        ; Exact mode toggle?
  354.     JR    Z,EOPT
  355.     CP    'S'        ; SYS files option?
  356.     JR    NZ,OPTER    ; If not, it's an option error
  357.                 ; Else fall through to SOPT
  358.  
  359. SOPT:
  360.     CALL    GETWHL
  361.     JR    Z,OPTER        ; If Z (wheel false), not allowed
  362.     LD    A,0FFH        ; Set flag
  363.     LD    (SYSTEM),A
  364.     JR    OPTCK3
  365.  
  366. EOPT:
  367.     LD    A,'?'
  368.     LD    (WILDCHR),A    ; Set "?" as only wildcard char
  369.     JR    OPTCK3
  370.  
  371. POPT:
  372.     XOR    A
  373.     LD    (PAGEOPT),A
  374.     JR    OPTCK3
  375.  
  376. OPTER:    CALL    PRINT
  377.     DB    BELL
  378.     DB    CR,LF
  379.     DB    'Invalid Option -- ',0
  380.     LD    A,(HL)
  381.     CALL    COUT
  382.     JP    HCK1
  383.  
  384.         ; Set bit in HL corresponding to drive number in A
  385.  
  386. SETDRV::
  387.     LD    HL,1        ; Seed value (drive 15)
  388.     CPL            ; Invert drive number
  389.     AND    0FH        ; ..so 0->15, 15->0
  390.     RET    Z        ; If zero, seed value is what we want
  391.     LD    B,A        ; Get count into B
  392. SETDRV1::
  393.     ADD    HL,HL        ; Shift bit left
  394.     DJNZ    SETDRV1        ; ..number of times in B
  395.     RET
  396.  
  397.         ; Extract file specification
  398.  
  399. GETFN:
  400.     PUSH    DE        ; Fill target fcb
  401.     LD    B,11        ; 11 bytes
  402.     LD    A,' '        ; Space fill
  403. GETFN0:
  404.     LD    (DE),A        ; Put space
  405.     INC    DE
  406.     DJNZ    GETFN0
  407.     POP    DE        ; Pt to entry again
  408.     CALL    SCANCOL        ; Scan for colon
  409.     LD    B,8        ; 8 chars max
  410.     CALL    GETFN1        ; Get and fill entry
  411.     LD    A,(HL)        ; Get char
  412.     CP    '.'        ; Delim?
  413.     RET    NZ        ; Done
  414.     INC    HL        ; Pt to after period
  415.     LD    B,3        ; 3 chars max and do it again
  416. GETFN1:
  417.     LD    A,(HL)        ; Get char
  418.     CP    '.'        ; End of field?
  419.     JR    Z,GETFN3
  420.     CALL    DELCHK        ; Check delimiter
  421.     RET    Z
  422.     CP    '*'        ; Wild?
  423.     JR    Z,GETFNQ
  424.     LD    (DE),A        ; Store char
  425.     INC    HL        ; Pt to next
  426.     INC    DE
  427.     DJNZ    GETFN1        ; Count down
  428. GETFN2:
  429.     LD    A,(HL)        ; Flush chars to delim
  430.     CALL    DELCHK        ; Check for delimiter
  431.     RET    Z
  432.     INC    HL        ; Pt to next
  433.     JR    GETFN2
  434. GETFN3:
  435.     INC    DE        ; Pt to after field
  436.     DJNZ    GETFN3        ; Count down
  437.     RET
  438. GETFNQ:
  439.     LD    A,'?'        ; Fill with question marks
  440.     LD    (DE),A
  441.     INC    DE
  442.     DJNZ    GETFNQ
  443.     JR    GETFN2        ; Skip to delim
  444. DELCHK:
  445.     OR    A        ; End of line?
  446.     RET    Z
  447.     CP    '.'        ; End of field?
  448.     RET    Z
  449.     CP    ','        ; End of entry?
  450.     RET    Z
  451.     CP    ' '
  452.     RET
  453. SBLANK:
  454.     LD    A,(HL)        ; Skip to non-blank
  455.     CP    ' '
  456.     RET    NZ
  457.     INC    HL
  458.     JR    SBLANK
  459. SCANCOL:
  460.     PUSH    DE        ; Save table ptr
  461.     PUSH    HL        ; Save ptr
  462. SCOL1:
  463.     LD    A,(HL)        ; Get char
  464.     INC    HL        ; Pt to next
  465.     CP    ':'        ; Colon?
  466.     JR    Z,SCOLX
  467.     CALL    DELCHK        ; Check for delimiter
  468.     JR    NZ,SCOL1
  469. SCOL2:
  470.     POP    HL        ; Restore
  471.     POP    DE
  472.     RET
  473. SCOLX:
  474.     EX    DE,HL        ; De pts to after colon
  475.     POP    HL        ; Get old ptr
  476.     EX    DE,HL        ; Replace it
  477.     POP    DE        ; Get table ptr
  478.     RET
  479.  
  480. ;-----------------------------------------------------------------------------
  481.  
  482. ; LOOK THROUGH DIRECTORY
  483.  
  484. FIND:    LD    A,(FCB)        ; Disk selection, Zero if all disks
  485.     LD    (DISK),A    ; Remember it
  486.     OR    A
  487.     JR    Z,FIND0
  488.     DEC    A        ; Offset so A=0
  489.     LD    (FCB),A
  490. FIND0:    CALL    NXTDISK        ; Get info the first time
  491. FIND1:    RET    Z        ; Abort if error
  492. FIND2:    CALL    NXTSEC        ; Get a directory sector
  493.     JR    Z,FIND3        ; Returns zero flag if no more
  494.     CALL    CHKENT        ; Check it out
  495.     JR    FIND2        ; Keep it up till done
  496. FIND3:    CALL    DIRALPHA    ; Sort entries
  497.     CALL    PRFILES        ; Print sorted entries
  498.     LD    A,(ECOUNT)    ; Check count of files listed
  499.     AND    1        ; If odd, then
  500.     CALL    NZ,NEWLINE    ; ..terminate last line
  501.     LD    A,(DISK)
  502.     OR    A
  503.     RET    NZ
  504.     LD    A,(FCB)        ; Next disk
  505.     INC    A
  506.     LD    (FCB),A
  507.     JR    FIND0
  508.  
  509. ;-----------------------------------------------------------------------------
  510.  
  511. ; SIGN OFF
  512.  
  513. BYE:
  514.     LD    A,(Z3REG)    ; Get register to use for file count
  515.     CP    10        ; If not in range 0..9, skip
  516.     JR    NC,BYE2
  517.     LD    B,A        ; Save register number in B
  518.     LD    HL,(TCOUNT)    ; Get total file count
  519.     LD    A,H        ; See if count is > 255
  520.     OR    A
  521.     LD    A,255        ; Preset for maximum possible value
  522.     JR    NZ,BYE1
  523.     LD    A,L        ; If < 256, use value in L
  524. BYE1:
  525.     CALL    PUTREG        ; Save value in A in register in B
  526.     
  527. BYE2:
  528.     LD    A,(NOFILFLAG)    ; Get no-file-found flag
  529.     CALL    PUTER2        ; Store in Z3 program error flag
  530.     OR    A        ; If flag reset, files were found
  531.     JR    Z,BYE3        ; ..so we return without message
  532.     CALL    PRINT        ; ..else we report to user
  533.     DB    CR,LF,' NO Files Found',0
  534. BYE3:
  535.     LD    C,13        ; Reset system
  536.     CALL    BDOS
  537.     JP    RETURN
  538.  
  539. ;-----------------------------------------------------------------------------
  540.  
  541. ; CHECKS THE CURRENT 4 DIRECTORY ENTRIES AGAINST ARGUMENT
  542. ; STORES MATCHING NAMES IN TABLE
  543.  
  544. CHKENT:
  545.     LD    B,4        ; Number of entries per sector
  546.     LD    HL,TBUFF    ; Beginning of buffer
  547. CKLUP:
  548.     PUSH    BC
  549.     LD    A,(HL)
  550.     CP    0E5H        ; Check for unused
  551.     JR    Z,CKINC
  552.  
  553.     LD    E,(IX+MUOFF)    ; Check for > maxuser from ENV
  554.     INC    E        ; To make cp easy
  555.     CP    A,E        ; > maxuser?
  556.     JR    NC,CKINC    ; Yes, if nc
  557.  
  558.     XOR    A        ; A=0
  559.     LD    (CLPFLG),A    ; Set flag for no entries found
  560.     LD    A,(FNCOUNT)    ; Get number of file names to look thru
  561.     LD    B,A        ; In b
  562.     PUSH    HL
  563.     LD    HL,(FNTAB)    ; Pt to table
  564.     EX    DE,HL        ; In de
  565.     POP    HL
  566. CKLUP1:
  567.     PUSH    BC        ; Save count
  568.     PUSH    HL        ; Save beginning address
  569.     PUSH    DE
  570.     CALL    COMPAR        ; Compare with argument and save if match
  571.     POP    DE
  572.     LD    HL,11        ; Pt to next entry
  573.     ADD    HL,DE
  574.     EX    DE,HL
  575.     POP    HL
  576.     POP    BC
  577.     DJNZ    CKLUP1        ; Count down
  578. CKINC:
  579.     POP    BC
  580.     LD    DE,32        ; Length of entry
  581.     ADD    HL,DE
  582.     DJNZ    CKLUP
  583.     LD    HL,(DIRMAX)
  584.     DEC    HL        ; Reduce sectors left
  585.     LD    (DIRMAX),HL
  586.     LD    HL,(SECTOR)    ; Point to next sector
  587.     INC    HL
  588.     LD    (SECTOR),HL
  589.     EX    DE,HL
  590.     LD    HL,(MAXSEC)    ; Reached limit?
  591.     LD    A,H        ; Check high
  592.     CP    D
  593.     RET    NZ
  594.     LD    A,L        ; Check low
  595.     CP    E
  596.     RET    NZ
  597.     LD    HL,(TRACK)    ; Next track
  598.     INC    HL
  599.     LD    (TRACK),HL
  600.     LD    HL,0
  601.     LD    (SECTOR),HL
  602.     RET
  603.  
  604. ;-----------------------------------------------------------------------------
  605.  
  606. ; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT; RNZ IF NOT MATCHED
  607. ;  DE PTS TO TABLE ENTRY TO COMPARE TO
  608.  
  609. COMPAR:
  610.     LD    A,(CLPFLG)    ; Get found flag
  611.     OR    A        ; 0=no
  612.     RET    NZ
  613.     LD    (TEMP),HL    ; Hold pointer in case of match
  614.     INC    HL
  615.     EX    DE,HL
  616.     LD    B,11
  617. CMPR1:
  618.     LD    A,(DE)        ; Get directory entry character
  619.     AND    7FH        ; Strip any flags
  620.     CP    (HL)
  621.     JR    Z,CMPR2
  622.     LD    A,(WILDCHR)    ; Get alternate wildcard char
  623.     CP    (HL)
  624.     JR    Z,CMPR2
  625.     LD    A,(HL)
  626.     CP    '?'
  627.     RET    NZ
  628. CMPR2:
  629.     INC    DE
  630.     INC    HL        ; Bump to next character
  631.     DJNZ    CMPR1        ; Loop for 11 characters
  632.     PUSH    DE        ; Save entry ptr
  633.     LD    A,(DE)        ; Get extent in b
  634.     LD    B,A
  635.     LD    A,(EXTENT)    ; Get extent mask
  636.     CP    B
  637.     POP    DE        ; Get entry ptr
  638.     JR    C,CMPR4        ; No match
  639.     LD    A,(SYSTEM)    ; Include system files?
  640.     OR    A        ; 0=no
  641.     JR    NZ,CMPR3
  642.     DEC    DE        ; Back up 2 bytes
  643.     DEC    DE
  644.     LD    A,(DE)        ; Get t2
  645.     AND    80H        ; Check for sys
  646.     RET    NZ
  647. CMPR3:
  648.     LD    HL,(TEMP)    ; Check for user limit
  649.     LD    A,31        ; Max user
  650.     CP    (HL)        ; Beyond max?
  651.     JR    C,CMPR4
  652.     LD    HL,(FCOUNT)    ; Increment count
  653.     INC    HL
  654.     LD    (FCOUNT),HL
  655.     LD    HL,(DSTART)    ; Get ptr to next entry
  656.     EX    DE,HL
  657.     LD    HL,(TEMP)
  658.     LD    B,ESIZE        ; Copy entry
  659.     CALL    MOVE
  660.     EX    DE,HL
  661.     LD    (DSTART),HL    ; Ptr to next entry
  662.     EX    DE,HL
  663.     LD    HL,(BDOS+1)    ; Check for memory overflow
  664.     LD    A,H
  665.     SUB    10        ; Below ccp
  666.     CP    D        ; Pt beyond limit?
  667.     JR    C,MOVFL
  668.     XOR    A
  669.     LD    (NOFILFLAG),A    ; Reset no-files-found flag
  670.     RET            ; Returns 'zero' flag set for match
  671. CMPR4:
  672.     LD    A,0FFH        ; No match
  673.     OR    A
  674.     RET
  675. MOVFL:
  676.     CALL    PRINT
  677.     DB    CR,LF,'ABORT -- Not Enough Memory for Buffers',0
  678.     JP    RETURN
  679.  
  680. ;-----------------------------------------------------------------------------
  681.  
  682. ;  ADVANCE TO NEXT DISK
  683.  
  684. NXTDISK:
  685.     LD    BC,TBUFF    ; Set dma address
  686.     CALL    SETDMA
  687. NXTDISK0:
  688.     LD    A,(FCB)
  689.     LD    C,A        ; Save drive in C
  690.  
  691.     CP    A,(IX+MDOFF)    ; Check against maxdrive in ENV
  692.     JR    C,NXTDISK1    ; Jump if OK
  693.     XOR    A        ; Else set zero flag and return
  694.     RET
  695.  
  696. NXTDISK1:
  697.     LD    A,(DISK)    ; See if specific drive requested
  698.     OR    A
  699.     JR    NZ,NXTDISK3    ; If so, skip table check
  700.  
  701.     LD    HL,(DRVTBL)    ; Check against table of available drives
  702.     LD    A,H        ; Swap H and L to get bit order right
  703.     LD    H,L
  704.     LD    L,A
  705.     LD    B,C        ; Use drive as count in B
  706.     INC    B        ; Shift count range from 0-15 to 1-16
  707.  
  708. NXTDISK2:            ; Shift appropriate bit into carry
  709.     ADD    HL,HL    
  710.     DJNZ    NXTDISK2
  711.  
  712.     JR    C,NXTDISK3    ; If drive enabled, proceed
  713.     LD    A,C        ; Else get drive back
  714.     INC    A        ; Increment it
  715.     LD    (FCB),A        ; Install in FCB
  716.     JR    NXTDISK0    ; Go back to process it
  717.  
  718. NXTDISK3:
  719.     LD    B,0
  720.     LD    E,B        ; Force bios to re-log disk
  721.     LD    HL,0
  722.     CALL    SELDSK        ; Make sure drive is
  723.     LD    A,H        ; Selected
  724.     OR    L
  725.     RET    Z        ; Error return
  726.     LD    (DPH),HL    ; Save the address
  727.     LD    DE,10        ; Pt to dpb
  728.     ADD    HL,DE
  729.     LD    E,(HL)        ; Get dpb address in hl
  730.     INC    HL
  731.     LD    D,(HL)
  732.     EX    DE,HL
  733.     LD    E,(HL)        ; Number of sectors/track
  734.     INC    HL        ; As 2-byte quantity in de
  735.     LD    D,(HL)
  736.     INC    HL
  737.     EX    DE,HL
  738.     LD    (MAXSEC),HL    ; Set max sectors/track
  739.     EX    DE,HL
  740.     INC    HL
  741.     INC    HL
  742.     LD    A,(HL)        ; Get exm
  743.     LD    (EXTENT),A
  744.     INC    HL        ; Pt to drm
  745.     INC    HL
  746.     INC    HL
  747.     LD    E,(HL)        ; Get number of
  748.     INC    HL        ; Directory entries
  749.     LD    D,(HL)
  750.     EX    DE,HL
  751.     INC    HL        ; Account for - 1
  752.     LD    (DSTART),HL    ; Save number of directory entries
  753.     CALL    SHFHL2        ; Shift 'hl' right 2
  754.     LD    (DIRMAX),HL    ; Save number directory sectors
  755.     LD    HL,5        ; Now point to system
  756.     ADD    HL,DE        ; Track offset
  757.     LD    A,(HL)        ; Pick up number of
  758.     INC    HL
  759.     LD    H,(HL)
  760.     LD    L,A
  761.     LD    (TRACK),HL
  762.     LD    HL,0
  763.     LD    (SECTOR),HL
  764.  
  765. TEST:
  766.     CALL    NEWLINE        ; Skip one extra line between disks
  767.     CALL    PRINT
  768.     DB    'Disk ',0
  769.     LD    A,(FCB)
  770.     ADD    'A'
  771.     CALL    COUT
  772.     CALL    PRINT
  773.     DB    ' --',CR,LF,0
  774.     CALL    CHKPAGE        ; Check for paging
  775.     LD    HL,(SCRATCH)    ; Pt to scratch area
  776.     LD    (ORDER),HL    ; Address of order table
  777.     EX    DE,HL
  778.     LD    HL,(DSTART)    ; Get number of directory entries
  779.     ADD    HL,HL        ; Double for number of bytes in order table
  780.     ADD    HL,DE        ; Pt to first byte of dirbuf
  781.     LD    (DIRBUF),HL    ; Set ptr
  782.     LD    (DSTART),HL    ; Set loop ptr
  783.     LD    HL,0        ; Set file count
  784.     LD    (FCOUNT),HL
  785.     XOR    A        ; Set count
  786.     LD    (ECOUNT),A
  787.     CPL            ; Flip
  788.     OR    A        ; Ok to continue
  789.     RET
  790.  
  791. ;-----------------------------------------------------------------------------
  792.  
  793. ; GET BIOS JUMPS VECTORS FOR EASY REFERENCE
  794.  
  795. GTBIOS:
  796.     LD    HL,(BOOT+1)    ; Points to bios jump table+3
  797.     LD    DE,WBOOT    ; Where we will keep a copy
  798.     LD    B,16*3        ; Move 48 bytes and fall thru to move
  799.                 ; Fall through to MOVE routine
  800.  
  801. ;-----------------------------------------------------------------------------
  802.  
  803. ; GENERAL PURPOSE MOVE ROUTINE FROM 'HL' TO 'DE' FOR COUNT
  804. ; GIVEN IN B REGISTER
  805.  
  806. MOVE:
  807.     LD    A,(HL)        ; Get a byte
  808.     LD    (DE),A        ; Put a byte
  809.     INC    DE        ; Increment to next
  810.     INC    HL
  811.     DJNZ    MOVE        ; Count down
  812.     RET
  813.  
  814. ;-----------------------------------------------------------------------------
  815.  
  816. ; READS NEXT SECTOR (GROUP OF FOUR DIRECTORY ENTRIES)
  817. ; RETURNS WITH ZERO FLAG SET IF NO MORE
  818.  
  819. NXTSEC:
  820.     LD    HL,(DIRMAX)    ; See if more sectors
  821.     LD    A,H
  822.     OR    L
  823.     RET    Z        ; Returns zero flag if no more
  824.     LD    HL,(TRACK)    ; Set track
  825.     LD    B,H
  826.     LD    C,L
  827.     CALL    SETTRK
  828.     LD    HL,(SECTOR)    ; Set sector
  829.     LD    B,H
  830.     LD    C,L
  831.     CALL    TRNSLT
  832.     CALL    SETSEC
  833.     CALL    READ        ; Read a sector
  834.     AND    1        ; Reverse sense of error flag
  835.     XOR    1        ; Returns with zero flag set
  836.     RET            ; If bad read
  837.  
  838. ;-----------------------------------------------------------------------------
  839.  
  840. ; PRINT FILES IN DIRBUF
  841.  
  842. PRFILES:
  843.     LD    HL,(FCOUNT)    ; Get count
  844.     LD    A,H        ; Any?
  845.     OR    L
  846.     RET    Z
  847.     LD    B,H        ; Count in bc
  848.     LD    C,L
  849.     LD    HL,(DIRBUF)    ; Pt to first one
  850. PRFLOOP:
  851.     PUSH    BC        ; Save count
  852.     PUSH    HL        ; Save ptr
  853.     CALL    PRINTFCB    ; Print fcb
  854.     CALL    CST        ; Check for abort character
  855.     JR    NZ,PRFL1    ; If not, go on
  856.     CALL    CIN        ; See if character is control-c
  857.     CP    CTRLC
  858.     JR    Z,PRFL2
  859. PRFL1:
  860.     POP    HL        ; Get regs back
  861.     POP    BC
  862.     LD    DE,ESIZE    ; Pt to next
  863.     ADD    HL,DE
  864.     DEC    BC        ; Count down
  865.     LD    A,B
  866.     OR    C
  867.     JR    NZ,PRFLOOP
  868.     RET
  869.  
  870. PRFL2:
  871.     CALL    PRINT
  872.     DB    CR,LF
  873.     DB    ' +++ aborted +++',CR,LF,0
  874.     JP    BYE3        ; Reset disk system and return
  875.  
  876. ;------------------------------------------------------------------------------
  877.  
  878. ; FCB PRINTING ROUTINE
  879.  
  880. PRINTFCB:
  881.     CALL    PRINT        ; 4 spaces
  882.     DB    '   ',0
  883.     LD    A,(FCB)        ; Get drive
  884.     LD    B,A        ; Save in B
  885.     INC    B        ; ..offset to A = 1
  886.     ADD    A,'A'        ; Convert to character
  887.     CALL    COUT
  888.     LD    A,(HL)        ; Get user number
  889.     PUSH    HL        ; Save pointer
  890.     LD    C,A        ; Save in C
  891.     CALL    PAFDC        ; Print it
  892.     CALL    DUNDR        ; Convert DU to NDR
  893.     LD    B,9        ; Spaces to skip if no NDR
  894.     JR    Z,PRFCB2    ; Jump if no named directory
  895.  
  896.         ; Named directory display
  897.  
  898.     LD    A,':'        ; Print the colon separator
  899.     CALL    COUT
  900.     INC    HL        ; Skip over disk in NDR
  901.     INC    HL        ; Skip over user in NDR
  902.     LD    B,8        ; Length of name
  903. PRFCB1:    LD    A,(HL)        ; Get character
  904.     CP    ' '        ; Look for space
  905.     JR    Z,PRFCB2    ; Don't print spaces
  906.     CALL    COUT
  907.     INC    HL
  908.     DJNZ    PRFCB1
  909.  
  910. PRFCB2:
  911.     LD    A,RIGHTCH    ; Print ending '>'
  912.     CALL    COUT
  913.     POP    HL        ; Restore pointed to file buffer
  914.     LD    A,(HL)        ; Get user number again
  915.     CP    10        ; Set carry of only one digit
  916.     LD    A,0        ; Increment B if carry set
  917.     ADC    A,B
  918.     INC    A        ; One extra space in any case
  919.     LD    B,A        ; Save count in B
  920.     LD    A,' '        ; Pad with spaces for alignment
  921. PRFCB3:
  922.     CALL    COUT
  923.     DJNZ    PRFCB3
  924.  
  925.     INC    HL        ; Point to name of file
  926. PR0:
  927.     LD    B,8
  928.     CALL    PR1
  929.     LD    A,'.'
  930.     CALL    COUT
  931.     LD    B,3
  932.     CALL    PR1
  933.     LD    HL,(TCOUNT)    ; Get total file count
  934.     INC    HL        ; Increment it
  935.     LD    (TCOUNT),HL    ; Save new value
  936.     LD    A,(ECOUNT)    ; Increment count of files
  937.     INC    A        ; ..found on this drive
  938.     LD    (ECOUNT),A
  939.     AND    1        ; If evenEvery 2
  940.     JR    Z,NEWLINE    ; ..make new line
  941.     CALL    PRINT        ; ..else space to second column
  942.     DB    '      ',0
  943.     RET
  944.  
  945. ;-----------------------------------------------------------------------------
  946.  
  947. ; PRINT A CRLF AND KEEP COUNT OF LINES ON PAGE, STOPPING WHEN PAGE IS FULL
  948.  
  949. NEWLINE:
  950.     CALL    CRLF
  951.  
  952. ; Check for end of page of display
  953.  
  954. CHKPAGE:
  955.     LD    A,(PAGEOPT)    ; See if paging in effect
  956.     OR    A
  957.     RET    Z        ; Return if option not set
  958.     LD    A,(LPS)        ; Get lines-per-screen value
  959.     LD    B,A        ; ..into B
  960.     LD    A,(LINECNT)    ; Get count of lines on page
  961.     INC    A
  962.     LD    (LINECNT),A
  963.     CP    B
  964.     RET    C        ; Return if less than full page
  965.  
  966.         ; Pause for page
  967.  
  968.     CALL    PRINT
  969. BEG1:    DB    ' [sp=line ^c=abort other=page] '
  970. END1:    DB    0
  971.     CALL    CIN
  972.     LD    C,A        ; Save user character
  973.     LD    A,CR        ; Back to beginning of line
  974.     CALL    COUT
  975.     LD    A,' '        ; Overwrite message with spaces
  976.     LD    B,END1-BEG1
  977. CHKP1:    CALL    COUT
  978.     DJNZ    CHKP1
  979.  
  980.     LD    A,C        ; Retrieve user response
  981.     CP    CTRLC        ; If control-c
  982.     JP    Z,PRFL2        ; ..abort
  983.     CP    ' '        ; See if space
  984.     JR    NZ,CHKP2
  985.     LD    A,(LINECNT)    ; ..decrement line count
  986.     DEC    A
  987.     JR    CHKP3
  988. CHKP2:
  989.     XOR    A            ; Reset line count
  990. CHKP3:
  991.     LD    (LINECNT),A
  992.     LD    A,CR
  993.     JP    COUT
  994.  
  995. PR1:
  996.     LD    A,(HL)
  997.     AND    7FH
  998.     CALL    COUT
  999.     INC    HL
  1000.     DJNZ    PR1
  1001.     RET
  1002.  
  1003. ;-----------------------------------------------------------------------------
  1004.  
  1005. ; SHIFT REGS 'HL' RIGHT 2 BITS LOGICAL
  1006.  
  1007. SHFHL2:
  1008.     CALL    SHFHL        ; Rotate right 1 bit and fall thru
  1009. SHFHL:
  1010.     XOR    A        ; Clear carry
  1011.     LD    A,H
  1012.     RRA            ; Shifted bit in carry
  1013.     LD    H,A
  1014.     LD    A,L
  1015.     RRA
  1016.     LD    L,A
  1017.     RET
  1018.  
  1019. ;-----------------------------------------------------------------------------
  1020.  
  1021. ; TRANSLATE REG 'BC' FROM LOGICAL TO PHYSICAL SECTOR NUMBER
  1022.  
  1023. TRNSLT:
  1024.     LD    HL,(DPH)    ; Get ptr to dph
  1025.     LD    E,(HL)        ; Get address of xlt
  1026.     INC    HL
  1027.     LD    D,(HL)
  1028.     CALL    SECTRAN        ; Use bios routine
  1029.     LD    C,L        ; Return value in bc
  1030.     LD    B,H
  1031.     RET
  1032.  
  1033. ;-----------------------------------------------------------------------------
  1034.  
  1035. ;  DIRALPHA -- ALPHABETIZES DIRECTORY PTED TO BY HL; BC CONTAINS
  1036. ;    THE NUMBER OF FILES IN THE DIRECTORY
  1037.  
  1038. DIRALPHA:
  1039.     LD    HL,(FCOUNT)    ; Get file count
  1040.     LD    A,H        ; Any files?
  1041.     OR    L
  1042.     RET    Z
  1043.     LD    (N),HL        ; Set "N"
  1044.     LD    B,H        ; Bc=count
  1045.     LD    C,L
  1046.     LD    HL,(DIRBUF)    ; Pt to directory
  1047.  
  1048. ;  SHELL SORT --
  1049. ;    THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
  1050. ;    BY KERNIGAN AND PLAUGHER, PAGE 106.  COPYRIGHT, 1976, ADDISON-WESLEY.
  1051. ;  ON ENTRY, BC=NUMBER OF ENTRIES AND HL=ADDRESS OF FIRST ENTRY
  1052.  
  1053. SORT:
  1054.     EX    DE,HL        ; Pointer to directory in de
  1055.     LD    HL,(ORDER)    ; Pt to order table
  1056.  
  1057. ;  SET UP ORDER TABLE; HL PTS TO NEXT ENTRY IN ORDER TABLE, DE PTS TO NEXT
  1058. ;    ENTRY IN DIRECTORY, BC = NUMBER OF ELEMENTS REMAINING
  1059.  
  1060. SORT1:
  1061.     LD    (HL),E        ; Store low-order address
  1062.     INC    HL        ; Pt to next order byte
  1063.     LD    (HL),D        ; Store high-order address
  1064.     INC    HL        ; Pt to next order entry
  1065.     PUSH    HL        ; Save ptr
  1066.     LD    HL,ESIZE    ; Hl=number of bytes/entry
  1067.     ADD    HL,DE        ; Pt to next dir1 entry
  1068.     EX    DE,HL        ; De pts to next entry
  1069.     POP    HL        ; Get ptr to order table
  1070.     DEC    BC        ; Count down
  1071.     LD    A,B        ; Done?
  1072.     OR    C
  1073.     JR    NZ,SORT1
  1074.  
  1075. ;  THIS IS THE MAIN SORT LOOP FOR THE SHELL SORT IN "SOFTWARE TOOLS" BY K&P
  1076.  
  1077.  
  1078.  
  1079. ;  SHELL SORT FROM "SOFTWARE TOOLS" BY KERNINGHAN AND PLAUGER
  1080.  
  1081.     LD    HL,(N)        ; Number of items to sort
  1082.     LD    (GAP),HL    ; Set initial gap to n for first division by 2
  1083.  
  1084. ;  FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
  1085.  
  1086. SRTL0:
  1087.     OR    A        ; Clear carry
  1088.     LD    HL,(GAP)    ; Get previous gap
  1089.     LD    A,H        ; Rotate right to divide by 2
  1090.     RRA
  1091.     LD    H,A
  1092.     LD    A,L
  1093.     RRA
  1094.     LD    L,A
  1095.  
  1096. ;  TEST FOR ZERO
  1097.  
  1098.     OR    H
  1099.     JR    Z,SDONE        ; Done with sort if gap = 0
  1100.  
  1101.     LD    (GAP),HL    ; Set value of gap
  1102.     LD    (K),HL        ; Set k=gap for following loop
  1103.  
  1104. ;  FOR (K = GAP + 1; K <= N; K = K + 1)
  1105.  
  1106. SRTL1:
  1107.     LD    HL,(K)        ; Add 1 to k
  1108.     INC    HL
  1109.     LD    (K),HL
  1110.  
  1111. ;  TEST FOR K <= N
  1112.  
  1113.     EX    DE,HL        ; K is in de
  1114.     LD    HL,(N)        ; Get n
  1115.     LD    A,L        ; Compare by subtraction
  1116.     SUB    E
  1117.     LD    A,H
  1118.     SBC    A,D        ; Carry set means k > n
  1119.     JR    C,SRTL0        ; Don't do for loop if k > n
  1120.  
  1121.     LD    HL,(K)        ; Set j = k initially for first subtraction of gap
  1122.     LD    (J),HL
  1123.  
  1124. ;  FOR (J = K - GAP; J > 0; J = J - GAP)
  1125.  
  1126. SRTL2:
  1127.     LD    HL,(GAP)    ; Get gap
  1128.     EX    DE,HL        ; In de
  1129.     LD    HL,(J)        ; Get j
  1130.     LD    A,L        ; Compute j - gap
  1131.     SUB    E
  1132.     LD    L,A
  1133.     LD    A,H
  1134.     SBC    A,D
  1135.     LD    H,A
  1136.     LD    (J),HL        ; J = j - gap
  1137.     JR    C,SRTL1        ; If carry from subtractions, j < 0 and abort
  1138.     LD    A,H        ; J=0?
  1139.     OR    L
  1140.     JR    Z,SRTL1        ; If zero, j=0 and abort
  1141.  
  1142. ;  SET JG = J + GAP
  1143.  
  1144.     EX    DE,HL        ; J in de
  1145.     LD    HL,(GAP)    ; Get gap
  1146.     ADD    HL,DE        ; J + gap
  1147.     LD    (JG),HL        ; Jg = j + gap
  1148.  
  1149. ;  IF (V(J) <= V(JG))
  1150.  
  1151.     CALL    ICOMPARE    ; J in de, jg in hl
  1152.  
  1153. ;  ... THEN BREAK
  1154.  
  1155.     JR    C,SRTL1
  1156.  
  1157. ;  ... ELSE EXCHANGE
  1158.  
  1159.     LD    HL,(J)        ; Swap j, jg
  1160.     EX    DE,HL
  1161.     LD    HL,(JG)
  1162.     CALL    ISWAP        ; J in de, jg in hl
  1163.  
  1164. ;  END OF INNER-MOST FOR LOOP
  1165.  
  1166.     JR    SRTL2
  1167.  
  1168.  
  1169. ;  SORT IS DONE -- RESTRUCTURE DIR1 IN SORTED ORDER IN PLACE
  1170.  
  1171. SDONE:
  1172.     LD    HL,(N)        ; Number of entries
  1173.     LD    B,H        ; In bc
  1174.     LD    C,L
  1175.     LD    HL,(ORDER)    ; Ptr to ordered pointer table
  1176.     LD    (PTPTR),HL    ; Set ptr ptr
  1177.     LD    HL,(DIRBUF)    ; Ptr to unordered directory
  1178.     LD    (PTDIR),HL    ; Set ptr dir buffer
  1179.  
  1180. ;  FIND PTR TO NEXT DIR1 ENTRY
  1181.  
  1182. SRTDN:
  1183.     LD    HL,(PTPTR)    ; Pt to remaining pointers
  1184.     EX    DE,HL        ; In de
  1185.     LD    HL,(PTDIR)    ; Hl pts to next dir entry
  1186.     PUSH    BC        ; Save count of remaining entries
  1187.  
  1188. ;  FIND PTR TABLE ENTRY
  1189.  
  1190. SRTDN1:
  1191.     LD    A,(DE)        ; Get current pointer table entry value
  1192.     INC    DE        ; Pt to high-order pointer byte
  1193.     CP    L        ; Compare against dir1 address low
  1194.     JR    NZ,SRTDN2    ; Not found yet
  1195.     LD    A,(DE)        ; Low-order bytes match -- get high-order pointer byte
  1196.     CP    H        ; Compare against dir1 address high
  1197.     JR    Z,SRTDN3    ; Match found
  1198. SRTDN2:
  1199.     INC    DE        ; Pt to next ptr table entry
  1200.     DEC    BC        ; Count down
  1201.     LD    A,C        ; End of table?
  1202.     OR    B
  1203.     JR    NZ,SRTDN1    ; Continue if not
  1204.  
  1205. ;  FATAL ERROR -- INTERNAL ERROR; POINTER TABLE NOT CONSISTENT
  1206.  
  1207. FERR$PTR:
  1208.     CALL    PRINT
  1209.     DB    0DH,0AH,'DIRALPHA -- Pointer Error',0
  1210.     JP    RETURN
  1211.  
  1212. ;  FOUND THE POINTER TABLE ENTRY WHICH POINTS TO THE NEXT UNORDERED DIR1 ENTRY
  1213. ;    MAKE BOTH POINTERS (PTR TO NEXT, PTR TO CURRENT UNORDERED DIR1 ENTRY)
  1214. ;    POINT TO SAME LOCATION (PTR TO NEXT DIR1 ENTRY TO BE ORDERED)
  1215.  
  1216. SRTDN3:
  1217.     LD    HL,(PTPTR)    ; Get ptr to next ordered entry
  1218.     DEC    DE        ; De pts to low-order pointer address
  1219.     LD    A,(HL)        ; Make ptr to next unordered dir1 pt to buffer for
  1220.     LD    (DE),A        ; Dir1 entry to be moved to next unordered dir1 pos
  1221.     INC    HL        ; Pt to next ptr address
  1222.     INC    DE
  1223.     LD    A,(HL)        ; Make high point similarly
  1224.     LD    (DE),A
  1225.  
  1226. ;  COPY NEXT UNORDERED DIR1 ENTRY TO HOLD BUFFER
  1227.  
  1228.     LD    B,ESIZE        ; B=number of bytes/entry
  1229.     LD    HL,(PTDIR)    ; Pt to entry
  1230.     LD    DE,HOLD        ; Pt to hold buffer
  1231.     PUSH    BC        ; Save b=number of bytes/entry
  1232.     CALL    MOVE
  1233.     POP    BC
  1234.  
  1235. ;  COPY TO-BE-ORDERED DIR1 ENTRY TO NEXT ORDERED DIR1 POSITION
  1236.  
  1237.     LD    HL,(PTPTR)    ; Point to its pointer
  1238.     LD    E,(HL)        ; Get low-address pointer
  1239.     INC    HL
  1240.     LD    D,(HL)        ; Get high-address pointer
  1241.     LD    HL,(PTDIR)    ; Destination address for next ordered dir1 entry
  1242.     EX    DE,HL        ; Hl pts to entry to be moved, de pts to dest
  1243.     PUSH    BC        ; Save b=number of bytes/entry
  1244.     CALL    MOVE
  1245.     POP    BC
  1246.     EX    DE,HL        ; Hl pts to next unordered dir1 entry
  1247.     LD    (PTDIR),HL    ; Set pointer for next loop
  1248.  
  1249. ;  COPY ENTRY IN HOLD BUFFER TO LOC PREVIOUSLY HELD BY LATEST ORDERED ENTRY
  1250.  
  1251.     LD    HL,(PTPTR)    ; Get ptr to ptr to the destination
  1252.     LD    E,(HL)        ; Get low-address pointer
  1253.     INC    HL
  1254.     LD    D,(HL)        ; High-address pointer
  1255.     LD    HL,HOLD        ; Hl pts to hold buffer, de pts to entry dest
  1256.     CALL    MOVE        ; B=number of bytes/entry
  1257.  
  1258. ;  POINT TO NEXT ENTRY IN POINTER TABLE
  1259.  
  1260.     LD    HL,(PTPTR)    ; Pointer to current entry
  1261.     INC    HL        ; Skip over it
  1262.     INC    HL
  1263.     LD    (PTPTR),HL
  1264.  
  1265. ;  COUNT DOWN
  1266.  
  1267.     POP    BC        ; Get counter
  1268.     DEC    BC        ; Count down
  1269.     LD    A,C        ; Done?
  1270.     OR    B
  1271.     JR    NZ,SRTDN
  1272.     RET            ; Done
  1273.  
  1274.  
  1275. ;  SWAP (Exchange) the pointers in the ORDER table whose indexes are in
  1276. ;    HL and DE
  1277.  
  1278. ISWAP:
  1279.     PUSH    HL        ; Save hl
  1280.     LD    HL,(ORDER)    ; Address of order table - 2
  1281.     LD    B,H        ; In bc
  1282.     LD    C,L
  1283.     POP    HL
  1284.     DEC    HL        ; Adjust index to 0...n-1 from 1...n
  1285.     ADD    HL,HL        ; Hl pts to offset address indicated by index
  1286.                 ; Of original hl (1, 2, ...)
  1287.     ADD    HL,BC        ; Hl now pts to pointer involved
  1288.     EX    DE,HL        ; De now pts to pointer indexed by hl
  1289.     DEC    HL        ; Adjust index to 0...n-1 from 1...n
  1290.     ADD    HL,HL        ; Hl pts to offset address indicated by index
  1291.                 ; Of original de (1, 2, ...)
  1292.     ADD    HL,BC        ; Hl now pts to pointer involved
  1293.     LD    C,(HL)        ; Exchange pointers -- get old (de)
  1294.     LD    A,(DE)        ; -- get old (hl)
  1295.     EX    DE,HL        ; Switch
  1296.     LD    (HL),C        ; Put new (hl)
  1297.     LD    (DE),A        ; Put new (de)
  1298.     INC    HL        ; Pt to next byte of pointer
  1299.     INC    DE
  1300.     LD    C,(HL)        ; Get old (hl)
  1301.     LD    A,(DE)        ; Get old (de)
  1302.     EX    DE,HL        ; Switch
  1303.     LD    (HL),C        ; Put new (de)
  1304.     LD    (DE),A        ; Put new (hl)
  1305.     RET
  1306.  
  1307. ;-----------------------------------------------------------------------------
  1308.  
  1309. ; ICOMPARE compares the entry pointed to by the pointer pointed to by HL
  1310. ; with that pointed to by DE (1st level indirect addressing); on entry,
  1311. ; HL and DE contain the numbers of the elements to compare (1, 2, ...);
  1312. ; on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
  1313. ; and Non-Zero and No-Carry means ((DE)) > ((HL))
  1314.  
  1315. ICOMPARE:
  1316.     PUSH    HL        ; Save hl
  1317.     LD    HL,(ORDER)    ; Address of order - 2
  1318.     LD    B,H        ; In bc
  1319.     LD    C,L
  1320.     POP    HL
  1321.     DEC    HL        ; Adjust index to 0...n-1 from 1...n
  1322.     ADD    HL,HL        ; Double the element number to point to the ptr
  1323.     ADD    HL,BC        ; Add to this the base address of the ptr table
  1324.     EX    DE,HL        ; Result in de
  1325.     DEC    HL        ; Adjust index to 0...n-1 from 1...n
  1326.     ADD    HL,HL        ; Do the same with the original de
  1327.     ADD    HL,BC
  1328.     EX    DE,HL
  1329.  
  1330.  
  1331. ; HL NOW POINTS TO THE POINTER WHOSE INDEX WAS IN HL TO BEGIN WITH
  1332. ; DE NOW POINTS TO THE POINTER WHOSE INDEX WAS IN DE TO BEGIN WITH
  1333. ; FOR EXAMPLE, IF DE=5 AND HL=4, DE NOW POINTS TO THE 5TH PTR AND HL
  1334. ; TO THE 4TH POINTER
  1335.  
  1336.     LD    C,(HL)        ; Bc is made to point to the object indexed to
  1337.     INC    HL        ; By the original hl
  1338.     LD    B,(HL)
  1339.     EX    DE,HL
  1340.     LD    E,(HL)        ; De is made to point to the object indexed to
  1341.     INC    HL        ; By the original de
  1342.     LD    D,(HL)
  1343.     LD    H,B        ; Set hl = object pted to indirectly by bc
  1344.     LD    L,C
  1345.  
  1346.  
  1347. ; COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
  1348. ; NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
  1349. ; RET W/ZERO SET MEANS DE=HL
  1350.  
  1351. CMP$ENTRY:
  1352.  
  1353. ;  COMPARE BY FILE NAME, FILE TYPE, EXTENSION, AND USER NUM (IN THAT ORDER)
  1354.  
  1355.     PUSH    HL
  1356.     PUSH    DE
  1357.     INC    HL        ; Pt to fn
  1358.     INC    DE
  1359.     LD    B,11        ; Compare fn, ft
  1360.     CALL    COMP
  1361.     POP    DE
  1362.     POP    HL
  1363.     RET    NZ
  1364.     LD    A,(DE)        ; Compare user number
  1365.     CP    (HL)
  1366.     RET
  1367.  
  1368. ;  COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
  1369. ;    MSB IS DISREGARDED
  1370.  
  1371. COMP:
  1372.     LD    A,(HL)        ; Get (hl)
  1373.     AND    7FH        ; Mask msb
  1374.     LD    C,A        ; In c
  1375.     LD    A,(DE)        ; Compare
  1376.     AND    7FH        ; Mask msb
  1377.     CP    C
  1378.     RET    NZ
  1379.     INC    HL        ; Pt to next
  1380.     INC    DE
  1381.     DJNZ    COMP        ; Count down
  1382.     RET
  1383.  
  1384. ; Uninitialized data area
  1385.  
  1386.     DSEG
  1387.  
  1388. ;  SORT BUFFERS
  1389.  
  1390. DATABEG:            ; Marker for data area
  1391.  
  1392. ORDER:
  1393.     DS    2        ; Ptr to order table
  1394. DIRBUF:
  1395.     DS    2        ; Pointer to directory
  1396. DSTART:
  1397.     DS    2        ; Pointer to first directory entry
  1398. FCOUNT:
  1399.     DS    2        ; Total number of files/number of selected files
  1400. HOLD:
  1401.     DS    ESIZE        ; Exchange hold buffer for fcb's
  1402. PTPTR:
  1403.     DS    2        ; Pointer pointer
  1404. PTDIR:
  1405.     DS    2        ; Directory pointer
  1406. K:
  1407.     DS    2        ; Indexes for sort
  1408. J:
  1409.     DS    2
  1410. JG:
  1411.     DS    2
  1412. N:
  1413.     DS    2        ; Number of elements to sort
  1414. GAP:
  1415.     DS    2        ; Binary gap size
  1416.  
  1417. ; THIS IS THE WORKING COPY OF THE BIOS JUMP TABLE
  1418.  
  1419. WBOOT:    DS    3
  1420. CONST:    DS    3
  1421. CONIN:    DS    3
  1422. CONOUT:    DS    3
  1423. LIST:    DS    3
  1424. PUNCH:    DS    3
  1425. READER:    DS    3
  1426. HOME:    DS    3
  1427. SELDSK:    DS    3
  1428. SETTRK:    DS    3
  1429. SETSEC:    DS    3
  1430. SETDMA:    DS    3
  1431. READ:    DS    3
  1432. WRITE:    DS    3
  1433. LISTST:    DS    3
  1434. SECTRAN:DS    3
  1435.  
  1436. STACK:
  1437.     DS    2        ; Location of stack
  1438.  
  1439. ; DATA AREAS
  1440.  
  1441. FNCOUNT:
  1442.     DS    1        ; Number of file names found
  1443. CLPFLG:    DS    1        ; 0 for no match locally
  1444. SYSTEM:    DS    1        ; 0 if no system files
  1445.  
  1446.                 ; Next two must be in this order
  1447. TCOUNT:    DS    2        ; Total count of files (2 bytes)
  1448. ECOUNT:    DS    1        ; Count of entries printed - 1
  1449.  
  1450. NOFILFLAG:
  1451.     DS    1        ; No-file-found flag
  1452. TEMP:    DS    2        ; Temp storage for fcb print
  1453.  
  1454. ;  DISK PARAMETER DATA
  1455.  
  1456. DISK:    DS    1        ; Disk to search, Zero for all disks.
  1457. DPH:    DS    2        ; Address of dph
  1458. DIRMAX:    DS    2        ; Number of sectors in directory =
  1459.                 ;   MAXIMUM NUMBER OF DIRECTORY ENTRIES
  1460.                 ;   DIVIDED BY 4 (ENTRIES PER SECTOR)
  1461. EXTENT:    DS    1        ; Extent mask
  1462. MAXSEC:    DS    2        ; Maximum number of sectors/track
  1463. SECTOR:    DS    2        ; Current sector number
  1464. TRACK:    DS    2        ; Track number of directory
  1465.  
  1466. FNTAB:    DS    2        ; File name table
  1467.  
  1468. SCRATCH:
  1469.     DS    2        ; Scratch area
  1470.  
  1471. LPS:
  1472.     DS    1        ; Lines-per-screen value
  1473. LINECNT:
  1474.     DS    1        ; Current line count
  1475. PAGEOPT:
  1476.     DS    1
  1477. WILDCHR:
  1478.     DS    1        ; Alternate wildcard char (<sp> or "?")
  1479. DRVTBL:
  1480.     DS    2        ; Working copy of drive map
  1481.  
  1482. DATAEND:            ; Marker for end of data
  1483.  
  1484.     END
  1485.